NOTICE: By continued use of this site you understand and agree to the binding Terms of Service and Privacy Policy.
let characterClassElement, planetTypeElement, serverLangElement, serverEconomySpeedElement, planetElement, metalBoxElement; characterClassElement = document.querySelector("#characterclass .sprite"); planetTypeElement = document.querySelector('head meta[name="ogame-planet-type"]'); serverLangElement = document.querySelector('head meta[name="ogame-language"]'); serverEconomySpeedElement = document.querySelector('head meta[name="ogame-universe-speed"]'); planetElement = document.querySelector(".smallplanet .active"); metalBoxElement = document.querySelector("#metal_box"); // ==UserScript== // @name OGLightOpti2 // @namespace OGLightOpti2 // @version 5.2.2 // @description OGLight script for OGame // @author Oz // @license MIT // @copyright 2019, Oz // @match https://*.ogame.gameforge.com/game/* // @updateURL https://openuserjs.org/meta/zahkor/OGLightOpti2.meta.js // @downloadURL https://openuserjs.org/install/zahkor/OGLightOpti2.user.js // @grant GM_addStyle // @grant GM_getValue // @grant GM_setValue // @grant GM_xmlhttpRequest // @grant GM_getTab // @grant GM_saveTab // @run-at document-start // ==/UserScript== let oglRedirection = localStorage.getItem("ogl-redirect"); function goodbyeTipped() { if ("undefined" != typeof Tipped) for (var [ key ] of Object.entries(Tipped)) Tipped[key] = function() { return !1; }; else requestAnimationFrame(() => goodbyeTipped()); } -1 < oglRedirection?.indexOf("https") && (void 0 !== window?.GM_addStyle && GM_addStyle(` body { background:#000 !important; } body * { display:none !important; } `), setTimeout(() => window.location.replace(oglRedirection)), localStorage.setItem("ogl-redirect", !1)), goodbyeTipped(), unsafeWindow?.ogl && (unsafeWindow.ogl = null); let updateOGLBody = () => { document.body.setAttribute("data-minipics", localStorage.getItem("ogl_minipics") || !1), document.body.setAttribute("data-menulayout", localStorage.getItem("ogl_menulayout") || 0), document.body.setAttribute("data-colorblind", localStorage.getItem("ogl_colorblind") || !1); }, betaVersion = (document.body ? updateOGLBody() : new MutationObserver(function() { document.body && (updateOGLBody(), this.disconnect()); }).observe(document, { childList: !0 }), "-b36"), oglVersion = "5.2.2"; void 0 === window?.GM_getTab && (window.GM_getTab = tab => { tab(JSON.parse(GM_getValue("ogl_tab") || "{}")); }), void 0 === window?.GM_saveTab && (window.GM_saveTab = data => { GM_setValue("ogl_tab", JSON.stringify(data || {})); }), void 0 === window?.GM_addStyle && (window.GM_addStyle = css => { var style = document.createElement("style"); style.setAttribute("type", "text/css"), style.textContent = css, document.head.appendChild(style); }), void 0 === window?.GM_info && (window.GM_info = {}, window.GM_info.script = {}, window.GM_info.script.name = "OGLight IOS", window.GM_info.script.version = oglVersion, window.GM_info.script.downloadURL = "https://openuserjs.org/install/nullNaN/OGLight.user.js"), void 0 === window?.GM_xmlhttpRequest && (window.GM_xmlhttpRequest = () => {}); class OGLight { constructor(params) { var cookieAccounts = document.cookie.match(/prsess\_([0-9]+)=/g), cookieAccounts = cookieAccounts[cookieAccounts.length - 1].replace(/\D/g, ""); this.DBName = cookieAccounts + "-" + window.location.host.split(".")[0], this.db = this.load(), !GM_getValue(this.DBName) && GM_getValue(window.location.host) && (GM_setValue(this.DBName, GM_getValue(window.location.host)), GM_deleteValue(window.location.host), window.location.reload()), this.db.lastServerUpdate = this.db.lastServerUpdate || 0, this.db.lastEmpireUpdate = this.db.lastEmpireUpdate || 0, this.db.lastLFBonusUpdate = this.db.lastLFBonusUpdate || 0, this.db.lastProductionQueueUpdate = this.db.lastProductionQueueUpdate || 0, this.db.udb = this.db.udb || {}, this.db.pdb = this.db.pdb || {}, this.db.tdb = this.db.tdb || {}, this.db.myPlanets = this.db.myPlanets || {}, this.db.dataFormat = this.db.dataFormat || 0, this.db.tags = 13 == Object.keys(this.db.tags || {}).length ? this.db.tags : { red: !0, orange: !0, yellow: !0, lime: !0, green: !0, blue: !0, dblue: !0, violet: !0, magenta: !0, pink: !0, brown: !0, gray: !0, none: !1 }, this.db.lastPinTab = this.db.lastPinTab || "miner", this.db.shipsCapacity = this.db.shipsCapacity || {}, this.db.spytableSort = this.db.spytableSort || "total", this.db.lastTaggedInput = this.db.lastTaggedInput || [], this.db.lastPinnedList = this.db.lastPinnedList || [], this.db.initialTime = this.db.initialTime || Date.now(), this.db.fleetLimiter = this.db.fleetLimiter || { data: {}, jumpgateData: {}, shipActive: !1, resourceActive: !1, jumpgateActive: !1 }, this.db.keepEnoughCapacityShip = this.db.keepEnoughCapacityShip || 200, this.db.keepEnoughCapacityShipJumpgate = this.db.keepEnoughCapacityShipJumpgate || 200, this.db.spyProbesCount = this.db.spyProbesCount || 6, this.db.configState = this.db.configState || { fleet: !0, general: !0, expeditions: !0, stats: !0, messages: !0, data: !0, PTRE: !0, interface: !0 }, this.db.options = this.db.options || {}, this.db.options.defaultShip = this.db.options.defaultShip || 202, this.db.options.defaultMission = this.db.options.defaultMission || 3, this.db.options.resourceTreshold = this.db.options.resourceTreshold || 3e5, this.db.options.ignoreConsumption = this.db.options.ignoreConsumption || !1, this.db.options.ignoreExpeShipsLoss = this.db.options.ignoreExpeShipsLoss || !1, this.db.options.useClientTime = this.db.options.useClientTime || !1, this.db.options.displayMiniStats = void 0 !== this.db.options.displayMiniStats ? this.db.options.displayMiniStats : "day", this.db.options.collectLinked = this.db.options.collectLinked || !1, this.db.options.expeditionValue = this.db.options.expeditionValue || 0, this.db.options.expeditionBigShips = this.db.options.expeditionBigShips || [ 204, 205, 206, 207, 215 ], this.db.options.expeditionRandomSystem = this.db.options.expeditionRandomSystem || 0, this.db.options.expeditionRedirect = this.db.options.expeditionRedirect || !1, this.db.options.expeditionShipRatio = Math.min(this.db.options.expeditionShipRatio, 100), this.db.options.displayPlanetTimers = !1 !== this.db.options.displayPlanetTimers, this.db.options.reduceLargeImages = this.db.options.reduceLargeImages || !1, this.db.options.colorblindMode = this.db.options.colorblindMode || !1, this.db.options.showMenuResources = this.db.options.showMenuResources || 0, this.db.options.autoCleanReports = this.db.options.autoCleanReports || !1, this.db.options.tooltipDelay = !1 !== this.db.options.tooltipDelay ? Math.max(this.db.options.tooltipDelay, 100) : 400, this.db.options.spyIndicatorDelay = this.db.options.spyIndicatorDelay || 36e5, this.db.options.debugMode = this.db.options.debugMode || !1, this.db.options.sim = this.db.options.sim || !1, this.db.options.boardTab = !1 !== this.db.options.boardTab, this.db.options.msu = this.db.options.msu || "3:2:1", this.db.options.disablePlanetTooltips = this.db.options.disablePlanetTooltips || !1, this.db.options.displaySpyTable = !1 !== this.db.options.displaySpyTable, this.db.options.shortcutsOnRight = this.db.options.shortcutsOnRight || !1, this.db.options.sidePanelOnLeft = this.db.options.sidePanelOnLeft || !1, this.db.options.keyboardActions = this.db.options.keyboardActions || {}, this.db.options.keyboardActions.menu = this.db.options.keyboardActions.menu || "²", this.db.options.keyboardActions.previousPlanet = this.db.options.keyboardActions.previousPlanet || "i", this.db.options.keyboardActions.nextPlanet = this.db.options.keyboardActions.nextPlanet || "o", this.db.options.keyboardActions.nextPinnedPosition = this.db.options.keyboardActions.nextPinnedPosition || "m", this.db.options.keyboardActions.fleetRepeat = this.db.options.keyboardActions.fleetRepeat || "p", this.db.options.keyboardActions.fleetSelectAll = this.db.options.keyboardActions.fleetSelectAll || "a", this.db.options.keyboardActions.fleetReverseAll = this.db.options.keyboardActions.fleetReverseAll || "r", this.db.options.keyboardActions.fleetQuickCollect = this.db.options.keyboardActions.fleetQuickCollect || "q", this.db.options.keyboardActions.expeditionSC = this.db.options.keyboardActions.expeditionSC || "s", this.db.options.keyboardActions.expeditionLC = this.db.options.keyboardActions.expeditionLC || "l", this.db.options.keyboardActions.expeditionPF = this.db.options.keyboardActions.expeditionPF || "f", this.db.options.keyboardActions.quickRaid = this.db.options.keyboardActions.quickRaid || "t", this.db.options.keyboardActions.fleetResourcesSplit = this.db.options.keyboardActions.fleetResourcesSplit || "2-9", this.db.options.keyboardActions.galaxyUp = this.db.options.keyboardActions.galaxyUp || ("fr" == window.location.host.split(/[-.]/)[1] ? "z" : "w"), this.db.options.keyboardActions.galaxyLeft = this.db.options.keyboardActions.galaxyLeft || ("fr" == window.location.host.split(/[-.]/)[1] ? "q" : "a"), this.db.options.keyboardActions.galaxyDown = this.db.options.keyboardActions.galaxyDown || "s", this.db.options.keyboardActions.galaxyRight = this.db.options.keyboardActions.galaxyRight || "d", this.db.options.keyboardActions.galaxyReload = this.db.options.keyboardActions.galaxyReload || "f", this.db.options.keyboardActions.galaxySpySystem = this.db.options.keyboardActions.galaxySpySystem || "r", this.db.options.keyboardActions.backFirstFleet = this.db.options.keyboardActions.backFirstFleet || "f", this.db.options.keyboardActions.backLastFleet = this.db.options.keyboardActions.backLastFleet || "l", this.db.options.keyboardActions.discovery = this.db.options.keyboardActions.discovery || "u", this.db.options.keyboardActions.showMenuResources = this.db.options.keyboardActions.showMenuResources || "v", "loading" !== document.readyState ? this.init(params.cache) : document.onreadystatechange = () => { "loading" === document.readyState || this.isReady || (this.isReady = !0, this.init(params.cache)); }; } init(cache) { document.body.classList.add("oglight"), this.db.options.showMenuResources && CSSManager.miniMenu(this.db.options.showMenuResources), this.db.options.reduceLargeImages && CSSManager.miniImage(this.db.options.reduceLargeImages), CSSManager.sidePanelLeft(this.db.options.sidePanelOnLeft), this.id = GM_getValue("ogl_id") || !1, this.version = -1 < GM_info.script.version.indexOf("b") ? oglVersion + betaVersion : oglVersion, this.tooltipEvent = new Event("tooltip"), this.isMobile = /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent), this.mode = parseInt(new URLSearchParams(window.location.search).get("oglmode")) || 0, this.page = new URL(window.location.href).searchParams.get("component") || new URL(window.location.href).searchParams.get("page"), this.resourcesKeys = { metal: "metal", crystal: "crystal", deut: "deuterium", food: "food", population: "population", energy: "energy", darkmatter: "darkmatter" }, this.shipsList = [ 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 213, 214, 215, 218, 219 ], this.fretShips = [ 202, 203, 209, 210, 219 ], this.ptreKey = localStorage.getItem("ogl-ptreTK") || !1, this.planetType = document.querySelector('head meta[name="ogame-planet-type"]').getAttribute("content"), this.flagsList = [ "friend", "rush", "danger", "skull", "fridge", "star", "trade", "money", "ptre", "none" ], this.server = {}, this.server.id = window.location.host.replace(/\D/g, ""), this.server.name = document.querySelector('head meta[name="ogame-universe-name"]').getAttribute("content"), this.server.lang = document.querySelector('head meta[name="ogame-language"]').getAttribute("content"), this.server.economySpeed = parseInt( document.querySelector('head meta[name="ogame-universe-speed"]').getAttribute("content")), this.server.peacefulFleetSpeed = parseInt( document.querySelector('head meta[name="ogame-universe-speed-fleet-peaceful"]').getAttribute("content")), this.server.holdingFleetSpeed = parseInt( document.querySelector('head meta[name="ogame-universe-speed-fleet-holding"]').getAttribute("content")), this.server.warFleetSpeed = parseInt( document.querySelector('head meta[name="ogame-universe-speed-fleet-war"]').getAttribute("content")), 300 == this.server.id && "en" == this.server.lang || (this.account = {}, this.account.id = document.querySelector('head meta[name="ogame-player-id"]').getAttribute("content"), this.account.class = document.querySelector("#characterclass .sprite")?.classList.contains("miner") ? 1 : document.querySelector("#characterclass .sprite")?.classList.contains("warrior") ? 2 : 3, this.account.name = document.querySelector('head meta[name="ogame-player-name"]').getAttribute("content"), this.account.rank = document.querySelector('#bar a[href*="searchRelId"]')?.parentNode.innerText.replace(/\D/g, ""), this.account.lang = /oglocale=([a-z]+);/.exec(document.cookie)[1], this.db.serverData = this.db.serverData || {}, this.db.serverData.serverFullID = this.db.serverData.serverFullID || this.server.id + this.server.lang, this.db.serverData.localTimeZoneOffsetInMinutes = 0 !== unsafeWindow.localTimeZoneOffsetInMinutes && (unsafeWindow.localTimeZoneOffsetInMinutes || this.db.serverData.localTimeZoneOffsetInMinutes) || 0, this.db.serverData.serverTimeZoneOffsetInMinutes = 0 !== unsafeWindow.serverTimeZoneOffsetInMinutes && (unsafeWindow.serverTimeZoneOffsetInMinutes || this.db.serverData.serverTimeZoneOffsetInMinutes) || 0, this.db.serverData.metal = unsafeWindow.loca?.LOCA_ALL_METAL || this.db.serverData.metal || "Metal", this.db.serverData.crystal = unsafeWindow.loca?.LOCA_ALL_CRYSTAL || this.db.serverData.crystal || "Crystal", this.db.serverData.deut = unsafeWindow.loca?.LOCA_ALL_DEUTERIUM || this.db.serverData.deut || "Deut", this.db.serverData.food = unsafeWindow.loca?.LOCA_ALL_FOOD || this.db.serverData.food || "Food", this.db.serverData.dm = unsafeWindow.LocalizationStrings?.darkMatter || this.db.serverData.dm || "Darkmatter", this.db.serverData.energy = unsafeWindow.resourcesBar?.resources?.energy.tooltip.split("|")[0] || this.db.serverData.energy || "Energy", this.db.serverData.conso = unsafeWindow.loca?.LOCA_FLEET_FUEL_CONSUMPTION || this.db.serverData.conso || "Conso", this.db.serverData.noob = unsafeWindow.loca?.LOCA_GALAXY_PLAYER_STATUS_N || this.db.serverData.noob || "n", this.db.serverData.vacation = unsafeWindow.loca?.LOCA_GALAXY_PLAYER_STATUS_U || this.db.serverData.vacation || "v", this.db.serverData.inactive = unsafeWindow.loca?.LOCA_GALAXY_PLAYER_STATUS_I || this.db.serverData.inactive || "i", this.db.serverData.inactiveLong = unsafeWindow.loca?.LOCA_GALAXY_PLAYER_STATUS_I_LONG || this.db.serverData.inactiveLong || "I", this.db.serverData.banned = unsafeWindow.loca?.LOCA_GALAXY_PLAYER_STATUS_G || this.db.serverData.banned || "b", this.db.serverData.population = "Population", this.db.serverData.item = "Item", this.db.serverData.topScore = this.db.serverData.topScore || 0, this.db.serverData.probeCargo = this.db.serverData.probeCargo || 0, this.db.serverData.debrisFactor = this.db.serverData.debrisFactor || 30, this.db.serverData.probeCargo || (this.fretShips = [ 202, 203, 209, 219 ]), this.account.lang != this.db.userLang && "fleetdispatch" != this.page && "intro" != this.page ? window.location.href = `https://${window.location.host}/game/index.php?page=ingame&component=fleetdispatch` : ("intro" != this.page && (this.db.userLang = this.account.lang), this.cache = cache || {}, -1 < window.location.href.indexOf("&relogin=1") && (this.cache = {}), this.updateJQuerySettings(), "empire" != this.page ? (this.id && this.id[0] || (cache = [ crypto.randomUUID(), 0 ], GM_setValue("ogl_id", cache), this.id), this.loadPlanetList(), new PopupManager(this), this.checkDataFormat(), new LangManager(this), new TimeManager(this), new FetchManager(this), this.getPlanetData(), this.getServerData(), new UIManager(this), new ShortcutManager(this), new TopbarManager(this), new FleetManager(this), new TooltipManager(this), new NotificationManager(this), new StatsManager(this), new GalaxyManager(this), new MessageManager(this), this.PTRE = new PTRE(this), new HighscoreManager(this), new MovementManager(this), new TechManager(this), new JumpgateManager(this), new EmpireManager(this), this.excludeFromObserver = [ "OGameClock", "resources_metal", "resources_crystal", "resources_deuterium", "smallplanet", "resources_food", "resources_population", "resources_energy", "resources_darkmatter", "mmoNewsticker", "mmoTickShow", "tempcounter", "counter-eventlist", "js_duration", "ogl_tooltip", "ogl_tooltipTriangle", "ogl_ready", "ogl_addedElement" ], Util.observe(document.body, { childList: !0, subtree: !0, attributes: !0 }, mutation => { Array.from(mutation.target.classList).some(r => this.excludeFromObserver.includes(r)) || this.excludeFromObserver.includes(mutation.target.id) || this.excludeFromObserver.some(r => mutation.target.id.startsWith(r)) || (mutation.target.classList.contains("ui-dialog") && mutation.target.querySelector(".detail_msg") ? Util.runAsync(this._message.checkDialog, this._message) : "stat_list_content" == mutation.target.getAttribute("id") && document.querySelector("#stat_list_content #ranks") ? (Util.runAsync(this._ui.updateHighscore, this._ui), Util.runAsync(this._ui.updateStatus, this._ui)) : "right" != mutation.target.id || document.querySelector(".ogl_topbar") || (this.getPlanetData(!0), this._topbar.load(), this._ui.load(!0), this._movement.load(!0), this._topbar.checkUpgrade())); }, this), cache = `<ul class="ogl_universeInfoTooltip"> <li>Economy:<div>x${this.server.economySpeed}</div></li> <li>Debris:<div>${this.db.serverData.debrisFactor}%</div></li> <hr> <li>Peaceful fleets:<div>x${this.server.peacefulFleetSpeed}</div></li> <li>Holding fleets:<div>x${this.server.holdingFleetSpeed}</div></li> <li>War fleets:<div>x${this.server.warFleetSpeed}</div></li> </ul>`, ( document.querySelector("#pageReloader") || document.querySelector("#logoLink")).classList.add("tooltipBottom"), ( document.querySelector("#pageReloader") || document.querySelector("#logoLink")).setAttribute("title", cache), document.querySelector("#pageContent").appendChild(Util.addDom("div", { class: "ogl_universeName", child: this.server.name + "." + this.server.lang })), this.checkPTRECompatibility(), this.db.serverData.serverFullID != this.server.id + this.server.lang && (this.db.serverData.serverFullID = !1, this.ogl.db.lastPTREAPIUpdate = 0, this.ogl.db.tdb = {}, this.ogl.db.pdb = {}, this.ogl.db.udb = {}, this.ogl.db.lastPinnedList = [], this.ogl.db.quickRaidList = [], window.location.reload())) : (this._fleet = new FleetManager(this), this._empire = new EmpireManager(this)), window.addEventListener("beforeunload", () => { this.save(); }))); } load(data) { return "string" == typeof (data = data || GM_getValue(this.DBName) || {}) ? JSON.parse(data) : data; } save(data, unload) { if ("empire" != this.page) try { data && "object" == typeof data && (this.db = data), GM_saveTab({ cache: this.cache }), GM_setValue(this.DBName, JSON.stringify(this.db)); } catch (error) { this.readyToUnload = !0; } } getServerData() { (!this.db.serverData.topScore || Date.now() > this.db.lastServerUpdate + 36e5) && this._fetch.pending.push({ url: `https://${window.location.host}/api/serverData.xml`, callback: data => { data = new DOMParser().parseFromString(data, "text/html"); this.db.serverData.topScore = parseInt(Number(data.querySelector("topscore").innerText)), this.db.serverData.probeCargo = parseInt(data.querySelector("probeCargo").innerText), this.db.serverData.debrisFactor = 100 * parseFloat(data.querySelector("debrisFactor").innerText), this.db.serverData.researchSpeed = parseInt(data.querySelector("researchDurationDivisor").innerText), this.db.lastServerUpdate = Date.now(); } }); } getPlanetData() { var currentID = document.querySelector('head meta[name="ogame-planet-id"]').getAttribute("content"), planetExist = (this.currentPlanet = {}, this.currentPlanet.dom = {}, this.currentPlanet.dom.element = document.querySelector(".smallplanet .active"), this.currentPlanet.dom.list = Array.from(document.querySelectorAll(".smallplanet")), !!this.db.myPlanets?.[currentID]); this.db.noFetch ? this.db.noFetch = !1 : ((!this.db.lastLFBonusUpdate || Date.now() > this.db.lastLFBonusUpdate + 24e4 && "fleetdispatch" != this.page) && setTimeout(() => this._fetch.fetchLFBonuses(), planetExist ? 2e4 : 0), (!this.db.lastEmpireUpdate || Date.now() > this.db.lastEmpireUpdate + 18e4 && "fleetdispatch" != this.page) && setTimeout(() => this._fetch.fetchEmpire(), planetExist ? 1e4 : 0), (!this.db.lastProductionQueueUpdate || Date.now() > this.db.lastProductionQueueUpdate + 1e4 && "fleetdispatch" != this.page) && setTimeout(() => this._fetch.fetchProductionQueue(), planetExist ? 3e3 : 0)), this.db.myPlanets[currentID] = this.db.myPlanets[currentID] || {}, this.currentPlanet.obj = this.db.myPlanets[currentID], this.currentPlanet.obj.type = document.querySelector('head meta[name="ogame-planet-type"]').getAttribute("content"), this.currentPlanet.obj.metal = Math.floor(resourcesBar.resources.metal?.amount || 0), this.currentPlanet.obj.crystal = Math.floor(resourcesBar.resources.crystal?.amount || 0), this.currentPlanet.obj.deut = Math.floor(resourcesBar.resources.deuterium?.amount || 0), this.currentPlanet.obj.energy = Math.floor(resourcesBar.resources.energy?.amount || 0), this.currentPlanet.obj.food = Math.floor(resourcesBar.resources.food?.amount || 0), this.currentPlanet.obj.population = Math.floor(resourcesBar.resources.population?.amount || 0), this.currentPlanet.obj.lifeform = document.querySelector("#lifeform .lifeform-item-icon")?.className.replace(/\D/g, ""), this.currentPlanet.obj.lastRefresh = this._time.serverTime, [ "metal", "crystal", "deut" ].forEach(resource => { var storage, prod = resourcesBar.resources[resource.replace("deut", "deuterium")].production, box = (0 < prod && (this.currentPlanet.obj["prod" + resource] = prod), document.querySelector(`#${resource.replace("deut", "deuterium")}_box`)); "moon" == this.currentPlanet.obj.type || box.querySelector(".ogl_resourceBoxStorage") || (storage = this.currentPlanet.obj[resource + "Storage"], storage = 0 < (prod *= 3600) ? Math.floor((storage - this.currentPlanet.obj[resource]) / prod) || 0 : 1 / 0, resource = Math.max(0, Math.floor(storage / 24)), prod = Math.max(0, Math.floor(storage % 24)), storage = 365 < resource ? "> 365" + LocalizationStrings.timeunits.short.day : "" + resource + LocalizationStrings.timeunits.short.day + " " + prod + LocalizationStrings.timeunits.short.hour, Util.addDom("div", { class: "ogl_resourceBoxStorage", child: storage, parent: box })); }), document.querySelectorAll(".planetlink, .moonlink").forEach(planet => { let id = new URLSearchParams(planet.getAttribute("href")).get("cp").split("#")[0]; this.db.myPlanets[id] = this.db.myPlanets[id] || {}, [ "metal", "crystal", "deut" ].forEach(resourceName => { var resource = this.db.myPlanets[id]?.[resourceName] || 0, storage = this.db.myPlanets[id]?.[resourceName + "Storage"] || 0, div = planet.querySelector(".ogl_available") || Util.addDom("span", { class: "ogl_available", parent: planet }), div = (Util.addDom("span", { class: "ogl_" + resourceName, parent: div, child: Util.formatToUnits(resource, 0) }), planet.querySelector(".ogl_available .ogl_" + resourceName)); div.innerHTML = Util.formatToUnits(resource, 1), storage <= resource && planet.classList.contains("planetlink") ? div.classList.add("ogl_danger") : .9 * storage <= resource && planet.classList.contains("planetlink") ? div.classList.add("ogl_warning") : (div.classList.remove("ogl_warning"), div.classList.remove("ogl_danger")); }), this.addRefreshTimer(id, planet), this.db.options.displayPlanetTimers || document.querySelector("#planetList").classList.add("ogl_alt"), this.cache.toSend && 3 !== this.mode && delete this.cache.toSend, planet.classList.contains("planetlink") ? (planet.classList.add("tooltipLeft"), planet.classList.remove("tooltipRight"), planet.querySelector(".planet-koords").innerHTML = `<span class="ogl_hidden">[</span>${planet.querySelector(".planet-koords").textContent.slice(1, -1)}<span class="ogl_hidden">]</span>`) : (planet.classList.add("tooltipRight"), planet.classList.remove("tooltipLeft")); }); } addRefreshTimer(id, source) { let timerDom = Util.addDom("div", { class: "ogl_refreshTimer", parent: source }), update = () => { var timer = serverTime.getTime() - (this.db.myPlanets[id]?.lastRefresh || 1), timer = Math.min(Math.floor(timer / 6e4), 60); timerDom.innerText = timer.toString(), timerDom.style.color = 30 < timer ? "#ef7676" : 15 < timer ? "#d99c5d" : "#67ad7d"; }; update(), setInterval(() => update(), 6e4); } updateJQuerySettings() { let self = this; $(document).on("ajaxSend", function(event, xhr, settings) { 0 <= settings.url.indexOf("page=messages&tab=") && 20 != new URLSearchParams(settings.url).get("tab") && self._message.spytable && self._message.spytable.classList.add("ogl_hidden"); }), $(document).on("ajaxSuccess", function(event, xhr, settings) { if (0 <= settings.url.indexOf("action=getMessagesList")) { var tabID = parseInt(new URLSearchParams(settings.data).get("activeSubTab")) || -1; self._message.tabID = tabID, Util.runAsync(() => self._message.check()); } else if (0 <= settings.url.indexOf("action=flagDeleted")) { let messageID = parseInt(new URLSearchParams(settings.data).get("messageId")) || -1; self._message.reportList && Util.removeFromArray(self._message.reportList, self._message.reportList.findIndex(e => e.id == messageID)); } else if (0 <= settings.url.indexOf("action=fetchGalaxyContent")) self._galaxy.check(JSON.parse(xhr.responseText)); else if (0 <= settings.url.indexOf("action=checkTarget")) document.querySelector("#planetList").classList.remove("ogl_notReady"); else if (0 <= settings.url.indexOf("component=eventList") && settings.url.indexOf("asJson=1") < 0) { tabID = new DOMParser().parseFromString(xhr.responseText, "text/html"); self._movement.check(tabID), self._movement.eventLoaded = !0; } else if (0 <= settings.url.indexOf("action=miniFleet")) { var tabID = xhr.responseJSON, xhr = new URLSearchParams(settings.data), mission = xhr.get("mission"), galaxy = xhr.get("galaxy"), system = xhr.get("system"), position = xhr.get("position"), type = xhr.get("type"); let uid = xhr.get("uid"); xhr = xhr.get("popup"); let status = tabID.response.success ? "done" : "fail"; token = tabID.newAjaxToken, updateOverlayToken("phalanxSystemDialog", tabID.newAjaxToken), updateOverlayToken("phalanxDialog", tabID.newAjaxToken), getAjaxEventbox(), refreshFleetEvents(!0); var itemIndex = self._fleet.miniFleetQueue.findIndex(e => e.uid == uid), item = self._fleet.miniFleetQueue.find(e => e.uid == uid); -1 < itemIndex && self._fleet.miniFleetQueue.splice(itemIndex, 1), "fail" == status ? item.retry < 2 ? (item.uid = crypto.randomUUID(), item.retry++, self._fleet.miniFleetQueue.push(item)) : (self._notification.addToQueue(`[${galaxy}:${system}:${position}] ` + tabID.response.message, !1), document.querySelectorAll(`[data-spy-coords="${galaxy}:${system}:${position}:${type}"]`).forEach(e => e.setAttribute("data-spy", status))) : (6 == mission && self.db.pdb[galaxy + `:${system}:` + position] && (self.db.pdb[galaxy + `:${system}:` + position].spy = self.db.pdb[galaxy + `:${system}:` + position].spy || [], 1 == type ? self.db.pdb[galaxy + `:${system}:` + position].spy[0] = serverTime.getTime() : 3 == type && (self.db.pdb[galaxy + `:${system}:` + position].spy[1] = serverTime.getTime())), document.querySelectorAll(`[data-spy-coords="${galaxy}:${system}:${position}:${type}"]`).forEach(e => e.setAttribute("data-spy", status)), $("#slotUsed").html(tsdpkt(tabID.response.slots)), setShips("probeValue", tsdpkt(tabID.response.probes)), setShips("recyclerValue", tsdpkt(tabID.response.recyclers)), setShips("missileValue", tsdpkt(tabID.response.missiles))), xhr && 6 != mission && (tabID.response.success ? fadeBox(tabID.response.message + " " + tabID.response.coordinates.galaxy + ":" + tabID.response.coordinates.system + ":" + tabID.response.coordinates.position, !tabID.response.success) : fadeBox(tabID.response.message, !0)), 0 < self._fleet.miniFleetQueue.length && setTimeout(() => self._fleet.sendNextMiniFleet(), 500); } else 0 <= settings.url.indexOf("page=highscoreContent") && self._highscore.check(); }), $.ajaxSetup({ beforeSend: function(xhr) { 0 <= this.url.indexOf("action=checkTarget") && !self?._fleet?.firstLoadCancelled ? window.fleetDispatcher && (fleetDispatcher.fetchTargetPlayerDataTimeout = null, self._fleet.firstLoadCancelled = !0, xhr.abort()) : 0 <= this.url.indexOf("action=fetchGalaxyContent") ? (self._galaxy.xhr && self._galaxy.xhr.abort(), self._galaxy.xhr = xhr) : 0 <= this.url.indexOf("action=getMessagesList") && (self._message.xhr && self._message.xhr.abort(), self._message.xhr = xhr); } }); } checkPTRECompatibility() { var json; serverTime.getTime() > this.id[1] + 864e5 && (json = { ogl_id: this.id[0] || "-", version: this.version || "-", script_name: GM_info.script.name || "-", script_namespace: GM_info.script.downloadURL || "-" }, this.PTRE.postPTRECompatibility(json)); } createPlayer(id) { return this.db.udb[id] = { uid: parseInt(id) }, this.db.udb[id]; } removeOldPlanetOwner(coords, newUid) { Object.values(this.db.udb).filter(e => -1 < e.planets?.indexOf(coords)).forEach(old => { var index; old.uid != newUid && (index = this.db.udb[old.uid].planets.indexOf(coords), this.db.udb[old.uid].planets.splice(index, 1), this.db.udb[old.uid].planets.length < 1 && delete this.db.udb[old.uid], this.db.udb[old.uid]) && document.querySelector(".ogl_side.ogl_active") && this.db.currentSide == old.uid && document.querySelector(".ogl_side.ogl_active") && this.db.currentSide == old.uid && this._topbar.openPinnedDetail(old.uid); }); } checkDataFormat() { var legacyDBName; this.db.dataFormat < 10 && (legacyDBName = `ogl_test_${this.server.id}-${this.server.lang}_` + this.account.id, (0 < (legacyDBName = JSON.parse(GM_getValue(legacyDBName) || "{}")).pinnedList?.length || 0 < legacyDBName.positions?.length) && confirm("Do you want to import v4 pinned targets ?") ? (this._popup.open(Util.addDom("div", { child: '<div>importing v4 targets, please wait...</div><hr><div class="ogl_loading"></div>' })), legacyDBName.pinnedList.forEach(id => { this.db.lastPinnedList = Array.from(new Set([ id, ...this.db.lastPinnedList ])); }), 30 < this.db.lastPinnedList.length && (this.db.lastPinnedList.length = 30), legacyDBName.positions.filter(position => position.color).forEach(position => { this.db.tdb[position.rawCoords] = { tag: position.color.replace("half", "") }; }), this.db.dataFormat = 10, this._popup.close(), window.location.reload()) : this.db.dataFormat = 10), this.db.dataFormat < 12 && (document.querySelectorAll(".planetlink, .moonlink").forEach(planet => { planet = new URLSearchParams(planet.getAttribute("href")).get("cp").split("#")[0]; this.db.myPlanets[planet] && delete this.db.myPlanets[planet].todolist; }), this.cache && delete this.cache.toSend, this.db.dataFormat = 12), this.db.dataFormat < 14 && (this.db.initialTime = Date.now(), this.db.stats = {}, this.cache.raid = {}, this.db.dataFormat = 14), this.db.dataFormat < 15 && (Object.entries(this.db.stats || {}).forEach(entry => { var midnight, date; -1 < entry[0].indexOf("-") || (midnight = parseInt(entry[0]), entry = entry[1], date = `${(date = new Date(midnight)).getFullYear()}-${date.getMonth()}-` + date.getDate(), this.db.stats[date]) || (this.db.stats[date] = entry, delete this.db.stats[midnight]); }), this.db.dataFormat = 15), this.db.dataFormat < 16 && (Object.entries(this.db.stats || {}).forEach(entry => { var oldKey = entry[0].split("-"); let newMonth = parseInt(oldKey[1]) + 1, newYear = parseInt(oldKey[0]); 12 < newMonth && (newMonth = 1, newYear++); var entry = entry[1], key = `${newYear}-${newMonth}-` + oldKey[2]; delete this.db.stats[oldKey.join("-")], this.db.stats[key] = entry; }), this.db.dataFormat = 16), this.db.dataFormat < 17 && (this.db.options.msu = "3:2:1", this.db.dataFormat = 17); } calcExpeditionMax() { var treshold = [ { topScore: 1e4, base: 10, max: 4e4 }, { topScore: 1e5, base: 125, max: 5e5 }, { topScore: 1e6, base: 300, max: 12e5 }, { topScore: 5e6, base: 450, max: 18e5 }, { topScore: 25e6, base: 600, max: 24e5 }, { topScore: 5e7, base: 750, max: 3e6 }, { topScore: 75e6, base: 900, max: 36e5 }, { topScore: 1e8, base: 1050, max: 42e5 }, { topScore: 1 / 0, base: 1250, max: 5e6 } ].find(e => e.topScore >= this.db.serverData.topScore); let maxResources = (3 == this.account.class ? 3 * treshold.max * this.server.economySpeed : 2 * treshold.max) * (1 + (this.db.lfBonuses?.Characterclasses3?.bonus || 0) / 100) * (1 + (this.db.lfBonuses?.ResourcesExpedition?.bonus || 0) / 100); return this.db.options.expeditionValue && (maxResources = 1 <= this.db.options.expeditionValue.toString().indexOf("%") ? Math.ceil(maxResources * this.db.options.expeditionValue.replace(/\D/g, "") / 100) : this.db.options.expeditionValue), { max: Math.round(maxResources), treshold: treshold }; } loadPlanetList() { this.account.planets = [], document.querySelectorAll(".smallplanet").forEach(line => { var planet = {}; planet.id = new URLSearchParams(line.querySelector(".planetlink")?.getAttribute("href"))?.get("cp")?.split("#")?.[0] || -1, planet.moonID = new URLSearchParams(line.querySelector(".moonlink")?.getAttribute("href"))?.get("cp")?.split("#")?.[0] || -1, planet.coords = line.querySelector(".planet-koords").textContent.slice(1, -1), planet.isCurrent = line.classList.contains("hightlightPlanet") || line.classList.contains("hightlightMoon"), planet.currentType = planet.isCurrent && line.classList.contains("hightlightPlanet") ? "planet" : !(!planet.isCurrent || !line.classList.contains("hightlightMoon")) && "moon", this.account.planets.push(planet); }), this.account.planets.getNext = offset => Util.reorderArray(this.account.planets, this.account.planets.findIndex(e => e.isCurrent))?.[(offset || 0) + 1] || this.account.planets[0], this.account.planets.getNextWithMoon = offset => Util.reorderArray(this.account.planets.filter(e => -1 < e.moonID), this.account.planets.filter(e => -1 < e.moonID).findIndex(e => e.isCurrent))?.[(offset || 0) + 1] || this.account.planets[0], this.account.planets.getPrev = offset => Util.reorderArray(this.account.planets, this.account.planets.findIndex(e => e.isCurrent), !0)?.[offset || 0] || this.account.planets[0], this.account.planets.getPrevWithMoon = offset => Util.reorderArray(this.account.planets.filter(e => -1 < e.moonID), this.account.planets.filter(e => -1 < e.moonID).findIndex(e => e.isCurrent), !0)?.[offset || 0] || this.account.planets[0], this.account.planets.getCurrent = () => this.account.planets.find(e => e.isCurrent) || this.account.planets[0], this.account.planets.getByCoords = coords => this.account.planets.find(e => coords == e.coords); } } GM_getTab(params => unsafeWindow.ogl = new OGLight(params)); class Manager { constructor(ogl) { this.ogl = ogl, (this.ogl["_" + this.constructor.name.toLowerCase().replace("manager", "")] = this).load && this.load(); } } class LangManager extends Manager { load() { this.raw = { metal: "Metal", crystal: "Crystal", deut: "Deuterium", artefact: "Artefact", dm: "Dark Matter", 202: "Small Cargo", 203: "Large Cargo", 204: "Light Fighter", 205: "Heavy Fighter", 206: "Cruiser", 207: "Battleship", 208: "Colony Ship", 209: "Recycler", 210: "Espionage Probe", 211: "Bomber", 212: "Solar Satellite", 213: "Destroyer", 214: "Deathstar", 215: "Battlecruiser", 216: "Trade Ship", 217: "Crawler", 218: "Reaper", 219: "Pathfinder", 220: "Trade Ship" }, this.en = { ship: "Ships", item: "Item", other: "Other", resource: "Resources", battle: "Battle", blackhole: "Black hole", early: "Early", late: "Late", trader: "Trader", nothing: "Nothing", pirate: "Pirates", alien: "Aliens", duration: "Duration", defaultShip: "Default ship type", defaultMission: "Default mission type", useClientTime: "Use client time", displayMiniStats: "Stats range", displaySpyTable: "Display spy table", displayPlanetTimers: "Display planets timer", disablePlanetTooltips: "Disable planets menu tooltips", showMenuResources: "Planets menu layout", reduceLargeImages: "Fold large images", ignoreExpeShips: "Ignore ships found in expeditions", ignoreExpeShipsLoss: "Ignore ships lost in expeditions", ignoreConsumption: "Ignore fleet consumption", resourceTreshold: "Resource treshold", tooltipDelay: "Tooltip delay (ms)", galaxyUp: "Next galaxy", galaxyDown: "Previous galaxy", galaxyLeft: "Previous system", galaxyRight: "Next system", previousPlanet: "Previous planet", nextPlanet: "Next planet", nextPinnedPosition: "Next pinned position", fleetRepeat: "Repeat last fleet", fleetSelectAll: "<div>Select all ships (fleet1)<hr>Select all resources (fleet2)</div>", expeditionSC: "Small cargo expedition", expeditionLC: "Large cargo expedition", expeditionPF: "Pathfinder expedition", galaxySpySystem: "System spy", collectLinked: "Collect to linked planet/moon", keyboardActions: "Keyboard settings", expeditionValue: "Expedition value", expeditionValueTT: "<ul><li>The custom value aimed by your expeditions</li><li>Set it to <b>0</b> to use the default calculated value</li><li>You can use <b>%</b> to aim a percent of the calculated value</li></ul>", expeditionBigShips: "Allowed biggest ships", expeditionRandomSystem: "Random system", expeditionShipRatio: "Ships found value (%)", fleetLimiter: "Fleet limiter", fleetLimiter: "Substract the amount of ships defined in your profile limiter", fleetLimiterTT: "Chose the amount of ships / resources to keep on your planets", menu: "Toggle OGLight menu", quickRaid: "Quick raid", attackNext: "Attack next planet", autoCleanReports: "Auto clean reports", noCurrentPin: "Error, no target pinned", backFirstFleet: "Back first fleet", backLastFleet: "Back last fleet sent", fleetReverseAll: "Reverse selection", fleetResourcesSplit: "Split ships/resources", manageData: "Manage OGLight data", profileButton: "Profile limiters", limiters: "Limiters", expeditionRedirect: "Redirect to the next planet/moon", playerProfile: "Player profile", topReportDetails: "Top report details", reportFound: "Top report", discovery: "Send a discovery", collectResources: "Collect resources", accountSummary: "Account summary", stats: "Stats", taggedPlanets: "Tagged planets", pinnedPlayers: "Pinned players", oglSettings: "OGLight settings", coffee: "Buy me a coffee", syncEmpire: "Sync empire data", repeatQueue: "Repeat the amount above in a new queue X time.<br>This operation can take a while", spyPlanet: "Spy this planet", spyMoon: "Spy this moon", resourceLimiter: "Substract the amount of resources defined in your profile limiter", forceKeepCapacity: "Keep enough capacity on you planet to move your resources (has priority over limiters)", forceIgnoreFood: "Ignore food (has priority over limiters)", resetStats: "Reset stats", resetTaggedPlanets: "Reset tagged planets", resetPinnedPlayers: "Reset pinned players", resetAll: "Reset all data", resetStatsLong: "Do you really want to reset OGLight stats data ?", resetTaggedPlanetsLong: "Do you really want to reset OGLight tagged planets data ?", resetPinnedPlayersLong: "Do you really want to reset OGLight pinned players data ?", resetAllLong: "Do you really want to reset all OGLight data ?", reportBlackhole: "Report a black hole", reportBlackholeLong: "Do you really want to add this black hole ?", emptyPlayerList: "There is no player in this list", debugMode: "Debug mode", sim: "Battle sim", converter: "Battle converter", siblingPlanetMoon: "Sibling planet / moon", oglMessageDone: "This message has been red by OGLight", ptreMessageDone: "activity sent to PTRE", boardTab: "Display board news", msu: "Metal standard unit", notifyNoProbe: "Feature disabled :(", shortcutsOnRight: "Display shortcuts under the planet menu", ptreTeamKey: "Team key", ptreLogs: "Display PTRE errors", ptreActivityImported: "activity imported to PTRE", ptreActivityAlreadyImported: "activity already imported to PTRE", ptreSyncTarget: "Sync with PTRE", ptreManageTarget: "Manage on PTRE", colorblindMode: "Colorblind mode", fleetQuickCollect: "Quick collect this planet resources", sidePanelOnLeft: "Side panel on left", galaxyReload: "Reload galaxy" }, this.fr = { ship: "Vaisseaux", item: "Item", other: "Autre", resource: "Ressources", battle: "Combat", blackhole: "Trou noir", early: "Avance", late: "Retard", trader: "Marchand", nothing: "Rien", pirate: "Pirates", alien: "Aliens", duration: "Durée", defaultShip: "Type de vaisseau par défaut", defaultMission: "Type de mission par défaut", useClientTime: "Utiliser l'heure du client", displayMiniStats: "Fourchette", displaySpyTable: "Afficher le tableau d'espio", displayPlanetTimers: "Afficher les timers des planètes", disablePlanetTooltips: "Cacher les tooltips du menu des planètes", showMenuResources: "Affichage du menu des planètes", reduceLargeImages: "Réduire les grandes images", ignoreExpeShips: "Ignorer les vaisseaux trouvés en expédition", ignoreExpeShipsLoss: "Ignorer les vaisseaux perdus en expédition", ignoreConsumption: "Ignorer la consommation des flottes", resourceTreshold: "Seuil de ressources", tooltipDelay: "Délai des tooltips (ms)", galaxyUp: "Galaxie suivante", galaxyDown: "Galaxie précédente", galaxyLeft: "Système précédent", galaxyRight: "Système suivant", previousPlanet: "Planète précédente", nextPlanet: "Planète suivante", nextPinnedPosition: "Position épinglée suivante", fleetRepeat: "Répéter la dernière flotte", fleetSelectAll: "<div>Selectionner tous les vaisseaux (fleet1)<hr>Selectionner toutes les ressources (fleet2)</div>", expeditionSC: "Expédition au petit transporteur", expeditionLC: "Expédition au grand transporteur", expeditionPF: "Expédition à l'éclaireur", galaxySpySystem: "Espionnage du système", collectLinked: "Rapatrier vers les planètes/lunes liée", keyboardActions: "Raccourcis clavier", expeditionValue: "Valeur max. expédition", expeditionValueTT: "<ul><li>La valeur visée par les expédition</li><li>Laisser à <b>0</b> pour utiliser la valeur calculée par OGLight</li><li>Vous pouvez mettre une valeur fixe pour viser un montant précis</li><li>Vous pouvez utiliser <b>%</b> pour viser un pourcentage de la valeur calculée</li><ul>", expeditionBigShips: "Gros vaisseaux autorisés", expeditionRandomSystem: "Système aléatoire", expeditionShipRatio: "Valeur vaisseaux trouvés (%)", fleetLimiter: "Limiteur de flotte", fleetLimiter: "Soustraire le nombre de vaisseaux indiqué dans le limiteur", fleetLimiterTT: "Choisir le nombre de vaisseau et la quantité de ressources à garder sur les planètes/lunes", menu: "Afficher/masquer le menu OGLight", quickRaid: "Raid rapide", attackNext: "Attaquer la planète suivante", autoCleanReports: "Nettoyage automatique des rapports", noCurrentPin: "Pas de cible épinglée actuellement", backFirstFleet: "Rappeler la prochaine flotte", backLastFleet: "Rappeler la dernière flotte envoyée", fleetReverseAll: "Inverser la sélection", fleetResourcesSplit: "Diviser les vaisseaux/ressources", manageData: "Gestion des données OGLight", profileButton: "Configuration des limiteurs", limiters: "Limiteurs", expeditionRedirect: "Rediriger vers la planète/lune suivante", playerProfile: "Profil du joueur", topReportDetails: "Détails du meilleur rapport", reportFound: "Meilleur rapport", discovery: "Envoyer une exploration", collectResources: "Rapatrier les ressources", accountSummary: "Résumé du compte", stats: "Statistiques", taggedPlanets: "Planètes marquées", pinnedPlayers: "Joueurs épinglés", oglSettings: "Configuration d'OGLight", coffee: "Buy me a coffee", syncEmpire: "Synchroniser les données de l'empire", repeatQueue: "Répéter le nombre ci-dessus dans une nouvelle file X fois.<br>Cette opération peut prendre un moment", spyPlanet: "Espionner cette planète", spyMoon: "Espionner cette lune", resourceLimiter: "Soustraire le montant de ressources indiqué dans le limiteur", forceKeepCapacity: "Garder assez de capacité sur la planète pour bouger les ressources (a la priorité sur le limiteur)", forceIgnoreFood: "Ignorer la nourriture (a la priorité sur le limiteur)", resetStats: "Réinitialiser stats", resetTaggedPlanets: "Réinitialiser les planètes marquées", resetPinnedPlayers: "Réinitialiser les joueurs épinglés", resetAll: "Réinitialiser toutes les données OGLight", resetStatsLong: "Voulez-vous vraiment réinitialiser les stats ?", resetTaggedPlanetsLong: "Voulez-vous vraiment réinitialiser les planètes marquées ?", resetPinnedPlayersLong: "Voulez-vous vraiment réinitialiser les joueurs épinglés ?", resetAllLong: "Voulez-vous vraiment réinitialiser toutes les données OGLight ?", reportBlackhole: "Signaler un trou noir", reportBlackholeLong: "Voulez vous vraiment ajouter ce trou noir ?", emptyPlayerList: "Cette liste de joueurs est vide", debugMode: "Mode debug", sim: "Simulateur de combat", converter: "Convertisseur de combat", siblingPlanetMoon: "Planète / lune liée", oglMessageDone: "Ce message a été traité par OGLight", ptreMessageDone: "Activité envoyée à PTRE", boardTab: "Afficher les annonces du board", msu: "Metal standard unit", notifyNoProbe: "Fonctionnalité desactivée :(", shortcutsOnRight: "Raccourcis sous le menu des planètes", ptreTeamKey: "Team key", ptreLogs: "Afficher les erreurs PTRE", ptreActivityImported: "Activité importée dans PTRE", ptreActivityAlreadyImported: "Activité déjà importée dans PTRE", ptreSyncTarget: "Synchroniser avec PTRE", ptreManageTarget: "Gérer sur PTRE", colorblindMode: "Mode daltonien", fleetQuickCollect: "Collecte rapide des ressources de cette planète", sidePanelOnLeft: "Panneau latéral à gauche", galaxyReload: "Recharger la galaxie" }, this.de = { ship: "Schiffe", item: "Item", other: "Sonstiges", resource: "Ressourcen", battle: "Kampf", blackhole: "Schwarzes Loch", early: "Verfrühung", late: "Verspätung", trader: "Händler", nothing: "Nichts", pirate: "Piraten", alien: "Aliens", duration: "Dauer", defaultShip: "Standard Schiff", defaultMission: "Standard Mission", useClientTime: "Nutze Clientzeit", displayMiniStats: "Zeige Statistik Bereich", displaySpyTable: "Zeige Spionagetabelle", displayPlanetTimers: "Zeige Planetentimer", disablePlanetTooltips: "Deaktiviere Planetenmenü Tooltip", showMenuResources: "Planeten Menü-Anordnung", reduceLargeImages: "Klappe große Bilder zu", ignoreExpeShips: "Ignoriere Schiffsfunde in Expeditionen", ignoreExpeShipsLoss: "Ignoriere Flottenverluste in Expeditionen", ignoreConsumption: "Ignoriere Treibstoffverbrauch", resourceTreshold: "Ressourcen Grenzwert", tooltipDelay: "Tooltip Verzögerung (ms)", galaxyUp: "Nächste Galaxie", galaxyDown: "Vorherige Galaxie", galaxyLeft: "Vorheriges System", galaxyRight: "Nächstes System", previousPlanet: "Vorheriger Planet", nextPlanet: "Nächster Planet", nextPinnedPosition: "Nächste angepinnte Position", fleetRepeat: "Wiederhole letzte Flotte", fleetSelectAll: "<div>Wähle alle Schiffe (flotte1)<hr>Wähle alle Ressourcen (flotte2)</div>", expeditionSC: "Kleiner Transporter Expedition", expeditionLC: "Großer Transporter Expedition", expeditionPF: "Pathfinder Expedition", galaxySpySystem: "System Spionage", collectLinked: "Sammle zu verlinktem Planet/Mond", keyboardActions: "Tastatureinstellungen", expeditionValue: "Expedition Maximalwert", expeditionValueTT: "Benutzerdefinierter Maximalwert für Expeditionen.<br> Setze ihn auf <b>0</b> um berechnete Werte zu verwenden.", expeditionBigShips: "Erlaubtes größtes Schiff", expeditionRandomSystem: "Zufälliges System", expeditionShipRatio: "Schiffsfund Wert(%)", fleetLimiter: "Flottenbegrenzer", fleetLimiter: "Subtrahiere Anzahl der Schiffe die im Profilmaximalwert definiert sind.", fleetLimiterTT: "Wähle die Anzahl an Schiffen / Ressourcen die auf dem Planeten bleiben sollen", menu: "OGLight Einstellungen", quickRaid: "Schnell-Angriff", attackNext: "Attackiere nächsten Planeten", autoCleanReports: "Automatische Spionagebericht-Bereinigung", noCurrentPin: "Fehler: Kein angepinntes Ziel", backFirstFleet: "Ziehe erste Flotte zurück", backLastFleet: "Ziehe letzte Flotte zurück", fleetReverseAll: "Auswahl umkehren", fleetResourcesSplit: "Teile Schiffe/Ressourcen", manageData: "Verwalte OGLight Daten", profileButton: "Profil Maximalwerte", limiters: "Maximalwerte", expeditionRedirect: "Zum nächsten Planet/Mond weiterleiten", playerProfile: "Spielerprofil", topReportDetails: "Informationen oberster Bericht", reportFound: "oberster Bericht", discovery: "Sende Erkundung", collectResources: "Ressourcen zusammenziehen", accountSummary: "Accountzusammenfassung", stats: "Statistiken", taggedPlanets: "Getaggte Planeten", pinnedPlayers: "Angepinnte Spieler", oglSettings: "OGLight Einstellungen", coffee: "Unterstütze mich", syncEmpire: "Synchronisiere Imperiumsdaten", repeatQueue: "Wiederhole Anzahl in neuer Schleife X mal.<br>Diese Option kann etwas dauern.", spyPlanet: "Spioniere diesen Planeten", spyMoon: "Spioniere diesen Mond", resourceLimiter: "Subtrahiere Anzahl der Ressourcen die im Profilmaximalwert definiert sind.", forceKeepCapacity: "Genügend Ladekapazität zurückhalten, um Rohstoffe zu transportieren (hat Priorität über definierten Grenzwerten)", forceIgnoreFood: "Ignoriere Nahrung (hat Priorität über definierten Grenzwerten)", resetStats: "Setze Statistik zurück", resetTaggedPlanets: "Setze getaggte Planeten zurück", resetPinnedPlayers: "Setze angepinnte Spieler zurück", resetAll: "Setze alle Daten zurück", resetStatsLong: "Möchtest du wirklich die OGL Daten zurücksetzen?", resetTaggedPlanetsLong: "Möchtest du wirklich die getaggten Planeten zurücksetzen?", resetPinnedPlayersLong: "Möchtest du wirklich die Spielerdaten zurücksetzen?", resetAllLong: "Möchtest du wirklich alle OGL Daten zurücksetzen?", reportBlackhole: "Melde schwarzes Loch", reportBlackholeLong: "Möchtest du dieses Schwarze Loch wirklich hinzufügen?", emptyPlayerList: "Es ist kein Spieler in der Liste", debugMode: "Debug Modus", sim: "Kampfsimulator", siblingPlanetMoon: "Verknüpfter Planet / Mond", oglMessageDone: "Diese Nachricht wurde von OGLight gelesen", boardTab: "Zeige Forum Neuigkeiten an", msu: "Metall Standardeinheit (MSE)", notifyNoProbe: "Funktion deaktiviert :(", shortcutsOnRight: "Zeige Kurzmenü unter Planeten", ptreTeamKey: "PTRE Team Key", ptreLogs: "Zeige PTRE Fehler", ptreActivityImported: "Aktivität zu PTRE importiert", ptreActivityAlreadyImported: "Aktivität bereits im PTRE", ptreSyncTarget: "Synchronisiere mit PTRE", ptreManageTarget: "Verwalte auf PTRE" }, this.gr = { ship: "Πλοία", item: "Αντικείμενο", other: "Άλλο", resource: "Πόροι", battle: "Μάχη", blackhole: "Μαύρη τρύπα", early: "Νωρίς", late: "Αργά", trader: "Εμπόριο", nothing: "Τίποτα", pirate: "Πειρατές", alien: "Άλιεν ", duration: "Διάρκεια", defaultShip: "Προεπιλογή πλοίου", defaultMission: "Προεπιλεγμένη αποστολή", useClientTime: "Χρήση ρολογιού OGlight", displayMiniStats: "Εύρος στατιστικών", displaySpyTable: "Πίνακας κατασκοπείας", displayPlanetTimers: "Χρόνος δραστηριότητας", disablePlanetTooltips: "Απενεργοποίηση μενού πλανητών", showMenuResources: "Διάταξη μενού πλανητών", reduceLargeImages: "Μικρότερες εικόνες", ignoreExpeShips: "Αγνόησε πλοία που βρέθηκαν σε αποστολές", ignoreExpeShipsLoss: "Αγνόησε πλοία που χάθηκαν σε αποστολές", ignoreConsumption: "Αγνόησε την κατανάλωση πλοίων", resourceTreshold: "Ανώτατο όριο πόρων", tooltipDelay: "Καθυστέρηση επεξήγησης (ms)", galaxyUp: "Επόμενος γαλαξίας", galaxyDown: "Προηγούμενος γαλαξίας", galaxyLeft: "Προηγούμενο σύστημα", galaxyRight: "Επόμενο σύστημα", previousPlanet: "Προηγούμενος πλανήτης", nextPlanet: "Επόμενος πλανήτης", nextPinnedPosition: "Επόμενη καρφιτσωμένη θέση", fleetRepeat: "Επανάληψη τελευταίου στόλου", fleetSelectAll: "<div>Επιλογή όλων των πλοίων (fleet1)<hr>Επιλογή όλων των πόρων (fleet2)</div>", expeditionSC: "Αποστολή με μικρά μεταγωγικά", expeditionLC: "Αποστολή με μεγάλα μεταγωγικά", expeditionPF: "Αποστολή με pathfinder", galaxySpySystem: "Κατασκοπεία συστήματος", collectLinked: "Συλλογή στο συνδεδεμένο πλανήτη/φεγγάρι", keyboardActions: "Ρυθμίσεις πληκτρολογίου", expeditionValue: "Αξία αποστολής", expeditionValueTT: "Προσαρμοσμένη αξία των αποστολών.<br> Ρύθμιση σε <b>0</b> για να χρησιμοποιηθεί η προεπιλεγμένη τιμή", expeditionBigShips: "Επιτρέπονται μεγαλύτερα πλοία", expeditionRandomSystem: "Τυχαίο σύστημα", expeditionShipRatio: "Αξία πλοίων που βρέθηκαν (%)", fleetLimiter: "Περιοριστής στόλου", fleetLimiter: "Αφαιρέστε τον αριθμό των πλοίων που ορίζεται στον περιοριστή ", fleetLimiterTT: "Επιλέξτε την ποσότητα πλοίων / πόρων που θα παραμείνουν στον πλανήτη", menu: "Εναλλαγή μενού OGLight", quickRaid: "Γρήγορη επιδρομή", attackNext: "Επίθεση στον επόμενο πλανήτη", autoCleanReports: "Αυτόματο σβήσιμο αναφορών", noCurrentPin: "Σφάλμα, δεν καρφιτσώθηκε στόχος", backFirstFleet: "Επιστροφή πρώτος στόλος", backLastFleet: "Επιστροφή τελευταίος στόλος", fleetReverseAll: "Αντίστροφη επιλογή", fleetResourcesSplit: "Διαχωρισμός πλοίων/πόρων", manageData: "Διαχείριση δεδομένων OGLight", profileButton: "Προφίλ περιορισμού", limiters: "Περιορισμοί", expeditionRedirect: "Ανακατεύθυνση στον επόμενο πλανήτη/φεγγάρι", playerProfile: "Προφίλ παίχτη", topReportDetails: "Λεπτομέρειες κορυφαίας αναφοράς", reportFound: "Κορυφαία αναφορά", discovery: "Μαζική Αποστολή Ανιχνευτικών Σκαφών", collectResources: "Συλλογή πόρων", accountSummary: "Περίληψη λογαριασμού", stats: "Στατιστικά", taggedPlanets: "Πλανήτες με ετικέτα", pinnedPlayers: "Καρφιτσωμένοι παίκτες", oglSettings: "Ρυθμίσεις OGLight", coffee: "Buy me a coffee", syncEmpire: "Συγχρονισμός δεδομένων", repeatQueue: "Επανέλαβε το παραπάνω ποσό σε νέα ουρά X χρόνο.<br>Αυτή η λειτουργία μπορεί να διαρκέσει λίγο", spyPlanet: "Κατασκοπεία αυτού του πλανήτη", spyMoon: "Κατασκοπεία αυτού του φεγγαριού", resourceLimiter: "Αφαιρέστε το ποσό των πόρων που ορίζονται στον περιοριστή ", forceKeepCapacity: "Διατηρήστε αρκετή ποσότητα στον πλανήτη σας για να μεταφέρετε τους πόρους σας(has priority over limiters)", forceIgnoreFood: "Αγνόησε την τροφή (has priority over limiters)", resetStats: "Επαναφορά στατιστικών", resetTaggedPlanets: "Επαναφορά πλανητών με ετικέτα", resetPinnedPlayers: "Επαναφορά καρφιτσωμένων παικτών ", resetAll: "Επαναφορά όλων των δεδομένων", resetStatsLong: "Θέλετε να επαναφέρετε τα δεδομένα των στατιστικών του OGLight;", resetTaggedPlanetsLong: "Θέλετε να επαναφέρετε τα δεδομένα πλανητών με ετικέτα του OGLight;", resetPinnedPlayersLong: "Θέλετε να επαναφέρετε τα δεδομένα των καρφιτσωμένων παικτών του OGLight;", resetAllLong: "Θέλετε να επαναφέρετε όλα τα δεδομένα του OGLight;", reportBlackhole: "Ανάφερε μια μαύρη τρύπα", reportBlackholeLong: "Θέλετε να προσθέσετε αυτή την μαύρη τρύπα;", emptyPlayerList: "Δεν υπάρχει παίχτης σε αυτή τη λίστα", debugMode: "Εντοπισμός σφαλμάτων", sim: "Προσομοιωτής μάχης", siblingPlanetMoon: "Αδελφός πλανήτης / φεγγάρι", oglMessageDone: "Αυτό το μήνυμα διαβάστηκε από το OGLight", boardTab: "Εμφάνιση πίνακα ειδήσεων", msu: "Αξια σε Μέταλλο", notifyNoProbe: "Απενεργοποιημένη δυνατότητα :(", shortcutsOnRight: "Εμφάνιση συντομεύσεων κάτω από τους πλανήτες", ptreTeamKey: "Team key", ptreLogs: "Εμφάνισε PTRE σφάλματα", ptreActivityImported: "δραστηριότητα εισήχθη στο PTRE", ptreActivityAlreadyImported: "δραστηριότητα που έχει ήδη εισαχθεί PTRE", ptreSyncTarget: "Συγχρονισμός με PTRE", ptreManageTarget: "Διαχείριση PTRE" }; } find(key, isRaw) { return "darkmatter" == key && (key = "dm"), isRaw && this.raw[key] ? this.raw[key] : this[this.ogl.account.lang] && this[this.ogl.account.lang][key] ? this[this.ogl.account.lang][key] : this.ogl.db.serverData[key] || this.en[key] || "TEXT_NOT_FOUND"; } } class TimeManager extends Manager { load() { if (this.units = LocalizationStrings.timeunits.short, this.serverTimeZoneOffset = 6e4 * this.ogl.db.serverData.serverTimeZoneOffsetInMinutes, this.clientTimeZoneOffset = 6e4 * serverTime.getTimezoneOffset(), this.UTC = serverTime.getTime() + this.serverTimeZoneOffset, this.serverTime = serverTime.getTime(), this.clientTime = this.UTC - this.clientTimeZoneOffset, this.observeList = [ ".OGameClock", ".ogl_backTimer", ".ogl_backWrapper" ], this.updateList = [ ".OGameClock", ".arrivalTime", ".absTime", ".nextabsTime", ".ui-dialog .msg_date" ], this.productionBoxes = { restTimebuilding: "productionboxbuildingcomponent", restTimeresearch: "productionboxresearchcomponent", restTimeship2: "productionboxshipyardcomponent", restTimelfbuilding: "productionboxlfbuildingcomponent", restTimelfresearch: "productionboxlfresearchcomponent", mecha: "productionboxextendedshipyardcomponent" }, "fleetdispatch" == this.ogl.page) { let lastLoop = 0, arrivalDom, backDom; document.querySelectorAll("#fleet2 #arrivalTime, #fleet2 #returnTime").forEach((e, index) => { 0 == index ? arrivalDom = Util.addDom("div", { class: "ogl_missionTime ogl_arrival", parent: e.parentNode, child: "loading..." }) : backDom = Util.addDom("div", { class: "ogl_missionTime ogl_return", parent: e.parentNode, child: "loading..." }), e.remove(); }), this.timeLoop = noLoop => { var arrival, duration, timeObj = this.getObj(); unsafeWindow.fleetDispatcher && (timeObj.server != lastLoop || noLoop) && (duration = 1e3 * (fleetDispatcher.getDuration() || 0), arrival = new Date(duration + (this.ogl.db.options.useClientTime ? timeObj.client : timeObj.server)), duration = new Date(15 == fleetDispatcher.mission ? 2 * duration + (this.ogl.db.options.useClientTime ? timeObj.client : timeObj.server) + 36e5 * fleetDispatcher.expeditionTime : 5 == fleetDispatcher.mission ? 2 * duration + (this.ogl.db.options.useClientTime ? timeObj.client : timeObj.server) + 36e5 * fleetDispatcher.holdingTime : 2 * duration + (this.ogl.db.options.useClientTime ? timeObj.client : timeObj.server)), arrivalDom.setAttribute("data-output-date", arrival.toLocaleDateString("de-DE", { day: "2-digit", month: "2-digit", year: "numeric" })), arrivalDom.setAttribute("data-output-time", arrival.toLocaleTimeString("de-DE")), backDom.setAttribute("data-output-date", duration.toLocaleDateString("de-DE", { day: "2-digit", month: "2-digit", year: "numeric" })), backDom.setAttribute("data-output-time", duration.toLocaleTimeString("de-DE")), lastLoop = timeObj.server), noLoop || requestAnimationFrame(() => this.timeLoop()); }, this.timeLoop(); } var ping = (performance.timing.responseEnd - performance.timing.requestStart) / 1e3, li = Util.addDom("li", { class: "ogl_ping", child: ping + " s", parent: document.querySelector("#bar ul") }); 2 <= ping ? li.classList.add("ogl_danger") : 1 <= ping && li.classList.add("ogl_warning"), Util.runAsync(this.update, this), Util.runAsync(this.observe, this); } update(self, domTarget) { (self = self || this).updateList.forEach(element => { (domTarget ? [ domTarget ] : document.querySelectorAll(element + ":not(.ogl_updated)")).forEach(target => { target.classList.add("ogl_updated"); var timeObj = self.getObj(self.dateStringToTime(target.innerText)), date = new Date(self.ogl.db.options.useClientTime ? timeObj.client : timeObj.server); 5 < target.innerText.split(/\.|:| /).length && (target.setAttribute("data-output-date", date.toLocaleDateString("de-DE", { day: "2-digit", month: "2-digit", year: "numeric" })), target.setAttribute("data-time-utc", timeObj.utc), target.setAttribute("data-time-server", timeObj.server), target.setAttribute("data-time-client", timeObj.client)), target.setAttribute("data-output-time", date.toLocaleTimeString("de-DE")); }); }); } observe(self) { (self = self || this).observeList.forEach(element => { document.querySelectorAll(element + ":not(.ogl_observed)").forEach(target => { target.classList.add("ogl_observed"); var action = () => { var timeObj = self.getObj(self.dateStringToTime(target.innerText)), date = new Date(self.ogl.db.options.useClientTime ? timeObj.client : timeObj.server); target.setAttribute("data-output-date", date.toLocaleDateString("de-DE", { day: "2-digit", month: "2-digit", year: "numeric" })), target.setAttribute("data-output-time", date.toLocaleTimeString("de-DE")), target.setAttribute("data-time-utc", timeObj.utc), target.setAttribute("data-time-server", timeObj.server), target.setAttribute("data-time-client", timeObj.client); }; action(), Util.observe(target, { childList: !0 }, action); }); }); } getObj(time, timeSource) { timeSource = timeSource || "server", time = time || ("server" == timeSource ? serverTime : localTime).getTime(); var timezone = {}; return timezone.serverOffset = 6e4 * -this.ogl.db.serverData.serverTimeZoneOffsetInMinutes, timezone.clientOffset = 6e4 * -this.ogl.db.serverData.localTimeZoneOffsetInMinutes, "server" == timeSource ? (timezone.client = time - timezone.serverOffset + timezone.clientOffset, timezone.server = time, timezone.utc = time - timezone.serverOffset) : (timezone.client = time, timezone.server = time - timezone.clientOffset + timezone.serverOffset, timezone.utc = time - timezone.clientOffset), timezone; } convertTimestampToDate(timestamp, full) { timestamp = new Date(timestamp); let target = Util.addDom("time", { child: timestamp.toLocaleTimeString("de-DE") }); return target = full ? Util.addDom("time", { child: timestamp.toLocaleDateString("de-DE", { day: "2-digit", month: "2-digit", year: "numeric" }) + " " + timestamp.toLocaleTimeString("de-DE") }) : target; } updateMovements() { let initialTime = new Date(); document.querySelectorAll("[data-mission-type]").forEach(fleet => { if (!fleet.querySelector(".ogl_backTimer")) { let backButton = fleet.querySelector(".reversal_time a"); if (backButton) { let domElement = Util.addDom("div", { class: "ogl_backTimer ogl_button", parent: fleet.querySelector(".ogl_resourcesBlock"), onclick: () => backButton.click() }), time = backButton.getAttribute("data-tooltip-title") || backButton.getAttribute("title"); if (time) { time = (time = (time = (time = time.replace("<br>", " ")).replace(/ \.$/, "")).trim().replace(/[ \.]/g, ":")).split(":"), time = new Date(`${time[4]}-${time[3]}-${time[2]}T${time[5]}:${time[6]}:` + time[7]).getTime(), this.updateBackTimer(initialTime, time, domElement); let wrapper = Util.addDom("div"), interval = (Util.addDom("div", { class: "ogl_backWrapper", parent: wrapper, child: domElement.innerText }), backButton.addEventListener("tooltip", () => backButton._tippy.setContent(wrapper)), setInterval(() => { document.body.contains(fleet) ? this.updateBackTimer(initialTime, time, domElement) : clearInterval(interval); }, 500)); } } } }); } updateBackTimer(initialTime, time, domElement) { time = this.getObj(time), initialTime = new Date() - initialTime, time = new Date(time.server + 2 * initialTime); domElement.innerText = time.toLocaleDateString("de-DE") + " " + time.toLocaleTimeString("de-DE"); } dateStringToTime(str) { return 2 == (str = (str = (str = str.split(/\.|:| /)).length <= 5 ? [ "01", "01", "2000" ].concat(str) : str).map(e => e.padStart(2, "0")))[2].length && (str[2] = "20" + str[2]), new Date(str[2] + `-${str[1]}-${str[0]}T${str[3]}:${str[4]}:` + str[5]).getTime(); } timeToHMS(time) { return new Date(time).toLocaleTimeString("de-DE", { hour12: !1 }); } } class FetchManager extends Manager { load() { this.fetched = { empire0: 1, empire1: 1, lf: 1, prod: 1 }, this.apiCooldown = 6048e5, this.pending = [], setInterval(() => this.resolve(), 500); } resolve() { var inProgress; this.pending.length < 1 || (inProgress = this.pending.splice(0, 7), Promise.all(inProgress.map(promise => fetch(promise.url).then(response => response.text()).then(text => ({ result: text, callback: promise.callback })))).then(reqs => { reqs.forEach(req => { req.callback(req.result); }); })); } fetchEmpire() { this.ogl._topbar.syncBtn.classList.add("ogl_active"), this.fetched.empire0 = 0; for (let i = this.fetched.empire1 = 0; i <= 1; i++) fetch(`https://${window.location.host}/game/index.php?page=ajax&component=empire&ajax=1&planetType=${i}&asJson=1`, { headers: { "X-Requested-With": "XMLHttpRequest" } }).then(response => response.json()).then(result => { this.ogl._empire.update(JSON.parse(result.mergedArray), i), this.ogl.save(), this.fetched["empire" + i] = 1, Object.values(this.fetched).indexOf(0) < 0 && this.ogl._topbar.syncBtn.classList.remove("ogl_active"); }); } fetchLFBonuses() { this.ogl._topbar.syncBtn.classList.add("ogl_active"), this.fetched.lf = 0, fetch(`https://${window.location.host}/game/index.php?page=ajax&component=lfbonuses`, { headers: { "X-Requested-With": "XMLHttpRequest" } }).then(response => response.text()).then(result => { result = new DOMParser().parseFromString(result, "text/html"); result.querySelector(".lfsettingsContentWrapper") && (this.ogl._empire.getLFBonuses(result), this.ogl.db.lastLFBonusUpdate = Date.now(), this.fetched.lf = 1, Object.values(this.fetched).indexOf(0) < 0) && this.ogl._topbar.syncBtn.classList.remove("ogl_active"); }); } fetchProductionQueue() { this.ogl._topbar.syncBtn.classList.add("ogl_active"), this.fetched.prod = 0, fetch(`https://${window.location.host}/game/index.php?page=ajax&component=productionqueue&ajax=1`, { headers: { "X-Requested-With": "XMLHttpRequest" } }).then(response => response.text()).then(result => { let xml = new DOMParser().parseFromString(result, "text/html"), hasResearch = xml.querySelector(".research time"); document.querySelectorAll(".planetlink, .moonlink").forEach(planet => { var key, level, entry, id = new URLSearchParams(planet.getAttribute("href")).get("cp").split("#")[0], times = { baseBuilding: xml.querySelector("time.building" + id), ship: xml.querySelector("time.ship" + id), lfBuilding: xml.querySelector("time.lfbuilding" + id), lfResearch: xml.querySelector("time.lfresearch" + id), mechaShip: xml.querySelector("time.ship_2nd" + id) }; this.ogl.db.myPlanets[id].upgrades = this.ogl.db.myPlanets[id].upgrades || {}; for ([ key ] of Object.entries(times)) times[key] ? (level = times[key].closest(".productionDetails")?.querySelector(".productionLevel")?.innerText?.replace(/\D/g, "") || "0", (entry = {}).name = times[key].closest(".productionDetails").querySelector(".productionName").childNodes[0].textContent, entry.lvl = parseInt(level), entry.end = 1e3 * parseInt(times[key].getAttribute("data-end")), entry.type = key, this.ogl.db.myPlanets[id].upgrades[key] = [ entry ]) : this.ogl.db.myPlanets[id].upgrades[key] = [], hasResearch || delete this.ogl.db.myPlanets[id].upgrades.baseResearch; }), this.ogl._topbar.checkUpgrade(), this.ogl.db.lastProductionQueueUpdate = Date.now(), this.fetched.prod = 1, Object.values(this.fetched).indexOf(0) < 0 && this.ogl._topbar.syncBtn.classList.remove("ogl_active"); }); } fetchPlayerAPI(id, name, afterAjax) { if (id) { let player = this.ogl.db.udb[id] || this.ogl.createPlayer(id); player.uid = player.uid || id, player.api = player.api || 0, player.planets = player.planets || [], player.name = name || player.name, serverTime.getTime() - player.api > this.apiCooldown ? this.pending.push({ url: `https://${window.location.host}/api/playerData.xml?id=` + player.uid, callback: data => { var xml = new DOMParser().parseFromString(data, "text/html"); if (xml.querySelector("playerdata")) { let apiTime = 1e3 * parseInt(xml.querySelector("playerdata").getAttribute("timestamp")); player.name || (player.name = xml.querySelector("playerdata").getAttribute("name")), player.score = player.score || {}, player.score.global = Math.floor(xml.querySelector('positions position[type="0"]').getAttribute("score")), player.score.economy = Math.floor(xml.querySelector('positions position[type="1"]').getAttribute("score")), player.score.research = Math.floor(xml.querySelector('positions position[type="2"]').getAttribute("score")), player.score.lifeform = Math.floor(xml.querySelector('positions position[type="8"]').getAttribute("score")), player.score.military = Math.floor(xml.querySelector('positions position[type="3"]').getAttribute("score")), player.score.globalRanking = Math.floor(xml.querySelector('positions position[type="0"]').innerText), player.score.economyRanking = Math.floor(xml.querySelector('positions position[type="1"]').innerText), player.score.researchRanking = Math.floor(xml.querySelector('positions position[type="2"]').innerText), player.score.lifeformRanking = Math.floor(xml.querySelector('positions position[type="8"]').innerText), player.score.militaryRanking = Math.floor(xml.querySelector('positions position[type="3"]').innerText), player.api = apiTime, xml.querySelectorAll("planet").forEach((element, index) => { var pid = element.getAttribute("id"), coords = element.getAttribute("coords"), element = element.querySelector("moon")?.getAttribute("id"), planet = (this.ogl.db.pdb[coords] = this.ogl.db.pdb[coords] || {}, this.ogl.db.pdb[coords]); planet.api = planet.api || 0, planet.api <= apiTime && (planet.uid = player.uid, planet.pid = pid, planet.mid = element, planet.coo = coords, planet.api = apiTime, 0 == index) && (planet.home = !0), player.planets.indexOf(coords) < 0 && player.planets.push(coords); }), player.planets.forEach((coords, index) => { this.ogl.db.pdb[coords]?.api < apiTime && (player.planets.splice(index, 1), this.ogl.db.pdb[coords].uid == player.uid) && delete this.ogl.db.pdb[coords]; }), afterAjax && afterAjax(); } else this.ogl.db.currentSide == player.uid && (delete this.ogl.db.udb[id], xml = Util.addDom("div"), Util.addDom("div", { parent: xml, class: "material-icons ogl_back", child: "arrow_back", onclick: () => { this.ogl._topbar.openPinned(); } }), Util.addDom("div", { parent: xml, child: data }), this.ogl._ui.openSide(xml, player.uid)); } }) : afterAjax && afterAjax(!1); } } } class UIManager extends Manager { load(reloaded) { document.querySelector("#planetList").classList.add("ogl_ogameDiv"), document.querySelector(".ogl_side") || (this.side = Util.addDom("div", { class: "ogl_side " + (this.ogl.db.currentSide ? "ogl_active" : ""), parent: document.body })), document.querySelector(".ogl_recap") || (this.resourceDiv = Util.addDom("div", { class: "ogl_recap", parent: document.querySelector("#planetList") }), Util.addDom("div", { class: "ogl_icon ogl_metal", parent: this.resourceDiv, child: "0" }), Util.addDom("div", { class: "ogl_icon ogl_crystal", parent: this.resourceDiv, child: "0" }), Util.addDom("div", { class: "ogl_icon ogl_deut", parent: this.resourceDiv, child: "0" }), Util.addDom("div", { class: "ogl_icon ogl_msu", parent: this.resourceDiv, child: "0" })), reloaded || (Util.addDom("li", { before: document.querySelector("#bar .OGameClock"), child: document.querySelector("#countColonies").innerText }), this.checkImportExport(), this.updateLeftMenu(), this.updateFooter()), this.attachGlobalClickEvent(reloaded), this.displayResourcesRecap(), this.groupPlanets(), "highscore" != this.ogl.page || reloaded || (this.updateHighscore(), this.updateStatus()); } openSide(dom, pin, buttonSource) { var closeBtn = Util.addDom("div", { class: "material-icons ogl_close", child: "close", onclick: () => { this.side.classList.remove("ogl_active"), delete this.ogl.db.currentSide, this.ogl._shortcut.load(), this.ogl._shortcut.updateShortcutsPosition(); } }); buttonSource && this.ogl.db.currentSide == pin && !this.side.querySelector(".ogl_loading") ? closeBtn.click() : (this.side.innerText = "", this.side.appendChild(closeBtn), this.side.appendChild(dom), this.side.classList.add("ogl_active"), this.lastOpenedSide != pin && this.ogl._shortcut.load(), this.ogl.db.currentSide = pin, this.lastOpenedSide = pin, this.ogl._shortcut.updateShortcutsPosition(), document.querySelectorAll(".ogl_inputCheck").forEach(e => Util.formatInput(e)), this.ogl._tooltip && this.ogl._tooltip.initTooltipList(this.side.querySelectorAll(getTooltipSelector()))); } attachGlobalClickEvent(reloaded) { reloaded || (document.addEventListener("keyup", event => { var activeElement = document.activeElement.tagName; "INPUT" != activeElement && "TEXTAREA" != activeElement || document.activeElement.classList.contains("ogl_inputCheck") && Util.formatInput(document.activeElement); }), document.querySelectorAll(".planetlink, .moonlink").forEach(target => { target.addEventListener("pointerenter", event => { var coords, type; unsafeWindow.fleetDispatcher && this.ogl._fleet?.isReady && document.body.classList.contains("ogl_destinationPicker") && (fleetDispatcher.fetchTargetPlayerDataTimeout || (coords = event.target.closest(".smallplanet").querySelector(".planet-koords").innerText.split(":"), event = (3 == (type = event.target.classList.contains("moonlink") ? 3 : 1) ? event.target.querySelector(".icon-moon") : event.target.querySelector(".planetPic")).getAttribute("alt"), document.querySelector("#galaxy").value = fleetDispatcher.targetPlanet.galaxy, document.querySelector("#system").value = fleetDispatcher.targetPlanet.system, document.querySelector("#position").value = fleetDispatcher.targetPlanet.position, fleetDispatcher.targetPlanet.type = type, fleetDispatcher.targetPlanet.galaxy = coords[0], fleetDispatcher.targetPlanet.system = coords[1], fleetDispatcher.targetPlanet.position = coords[2], fleetDispatcher.targetPlanet.name = event, fleetDispatcher.refresh())); }), target.addEventListener("pointerleave", () => { /Android|iPhone/i.test(navigator.userAgent) || unsafeWindow.fleetDispatcher && this.ogl._fleet?.isReady && document.body.classList.contains("ogl_destinationPicker") && ( document.querySelector("#galaxy").value = fleetDispatcher.realTarget.galaxy, document.querySelector("#system").value = fleetDispatcher.realTarget.system, document.querySelector("#position").value = fleetDispatcher.realTarget.position, fleetDispatcher.targetPlanet.galaxy = fleetDispatcher.realTarget.galaxy, fleetDispatcher.targetPlanet.system = fleetDispatcher.realTarget.system, fleetDispatcher.targetPlanet.position = fleetDispatcher.realTarget.position, fleetDispatcher.targetPlanet.type = fleetDispatcher.realTarget.type, fleetDispatcher.targetPlanet.name = fleetDispatcher.realTarget.name, fleetDispatcher.refresh()); }); }), document.addEventListener("click", event => { if ("svg" != event.target.tagName && "path" != event.target.tagName) { var coords; if (event.target.getAttribute("data-galaxy") && (coords = event.target.getAttribute("data-galaxy").split(":"), "galaxy" === this.ogl.page ? (galaxy = coords[0], system = coords[1], loadContentNew(galaxy, system)) : (coords = `https://${window.location.host}/game/index.php?page=ingame&component=galaxy&galaxy=${coords[0]}&system=` + coords[1], event.ctrlKey ? window.open(coords, "_blank") : window.location.href = coords)), (event.target.classList.contains("planetlink") || event.target.classList.contains("moonlink") || event.target.closest(".planetlink, .moonlink")) && document.body.classList.contains("ogl_destinationPicker")) { event.preventDefault(); let coords = event.target.closest(".smallplanet").querySelector(".planet-koords").innerText.split(":"); var type = event.target.closest(".planetlink, .moonlink").classList.contains("moonlink") ? 3 : 1, name = (3 == type ? event.target.closest(".smallplanet").querySelector(".icon-moon") : event.target.closest(".smallplanet").querySelector(".planetPic")).getAttribute("alt"), planet = this.ogl.account.planets.getByCoords(coords.join(":")), planet = 3 == type ? planet.moonID : planet.id; if (document.body.classList.contains("ogl_initHarvest")) { var firstSource = this.ogl.account.planets.getCurrent(), firstSource = "moon" == firstSource.currentType ? firstSource.moonID : firstSource.id; window.location.href = `https://${window.location.host}/game/index.php?page=ingame&component=fleetdispatch&galaxy=${coords[0]}&system=${coords[1]}&position=${coords[2]}&type=${type}&oglmode=1&ogldestinationid=${planet}&oglfirstsourceid=${firstSource}&ogldestinationtype=` + (3 == type ? "moon" : "planet"); } else { if (!unsafeWindow.fleetDispatcher || !this.ogl._fleet?.isReady) return; fleetDispatcher.targetPlanet.type = type, fleetDispatcher.targetPlanet.galaxy = coords[0], fleetDispatcher.targetPlanet.system = coords[1], fleetDispatcher.targetPlanet.position = coords[2], fleetDispatcher.targetPlanet.name = name, fleetDispatcher.refresh(), this.ogl._fleet.setRealTarget(JSON.parse(JSON.stringify(fleetDispatcher.targetPlanet))), "fleet1" == fleetDispatcher.currentPage ? fleetDispatcher.focusSubmitFleet1() : "fleet2" == fleetDispatcher.currentPage && (fleetDispatcher.focusSendFleet(), fleetDispatcher.updateTarget()); } } event.target.getAttribute("data-api-code") && (navigator.clipboard.writeText(event.target.getAttribute("data-api-code")), fadeBox("API code copied")), event.target.classList.contains("js_actionKillAll") && 20 == ogame?.messages?.getCurrentMessageTab() && (ogl.cache.reports = {}); } })); } openFleetProfile() { var container = Util.addDom("div", { class: "ogl_keeper" }), leftSide = (Util.addDom("h2", { child: "Limiters", parent: container }), Util.addDom("div", { parent: container })); let limitResourceLabel = Util.addDom("label", { class: "ogl_limiterLabel tooltip", "data-limiter-type": "resource", title: this.ogl._lang.find("resourceLimiter"), parent: leftSide, child: "Resources" }); var limitResourceCheckbox = Util.addDom("input", { type: "checkbox", parent: limitResourceLabel, onclick: () => { this.ogl.db.fleetLimiter.resourceActive = !this.ogl.db.fleetLimiter.resourceActive, this.ogl._fleet.updateLimiter(), document.querySelectorAll(`[data-limiter-type="${limitResourceLabel.getAttribute("data-limiter-type")}"] input`).forEach(e => e.checked = this.ogl.db.fleetLimiter.resourceActive); } }); let resourceContainer = Util.addDom("div", { parent: leftSide, class: "ogl_resourceLimiter" }), limitShipLabel = (Util.addDom("br", { parent: leftSide }), Util.addDom("label", { class: "ogl_limiterLabel tooltip", "data-limiter-type": "ship", title: this.ogl._lang.find("fleetLimiter"), parent: leftSide, child: "Ships" })); var limitShipCheckbox = Util.addDom("input", { type: "checkbox", parent: limitShipLabel, onclick: () => { this.ogl.db.fleetLimiter.shipActive = !this.ogl.db.fleetLimiter.shipActive, this.ogl._fleet.updateLimiter(), document.querySelectorAll(`[data-limiter-type="${limitShipLabel.getAttribute("data-limiter-type")}"] input`).forEach(e => e.checked = this.ogl.db.fleetLimiter.shipActive); } }); let fleetContainer = Util.addDom("div", { parent: leftSide, class: "ogl_shipLimiter" }), limitJumpgateLabel = (Util.addDom("br", { parent: leftSide }), Util.addDom("label", { class: "ogl_limiterLabel tooltip", "data-limiter-type": "jumpgate", title: this.ogl._lang.find("fleetLimiter"), parent: leftSide, child: "Jumpgate" })); var limitJumpgateCheckbox = Util.addDom("input", { type: "checkbox", parent: limitJumpgateLabel, onclick: () => { this.ogl.db.fleetLimiter.jumpgateActive = !this.ogl.db.fleetLimiter.jumpgateActive, this.ogl._jumpgate.updateLimiter(), document.querySelectorAll(`[data-limiter-type="${limitJumpgateLabel.getAttribute("data-limiter-type")}"] input`).forEach(e => e.checked = this.ogl.db.fleetLimiter.jumpgateActive); } }); let jumpgateContainer = Util.addDom("div", { parent: leftSide, class: "ogl_jumpgateLimiter" }); return this.ogl.db.fleetLimiter.resourceActive && (limitResourceCheckbox.checked = !0), this.ogl.db.fleetLimiter.shipActive && (limitShipCheckbox.checked = !0), this.ogl.db.fleetLimiter.jumpgateActive && (limitJumpgateCheckbox.checked = !0), Object.keys(this.ogl.resourcesKeys).concat(this.ogl.shipsList).forEach(id => { if ("population" != id && "darkmatter" != id && "energy" != id) { var parent = isNaN(id) ? resourceContainer : fleetContainer, parent = Util.addDom("div", { parent: parent, class: "ogl_icon ogl_" + id, "data-id": id }); let input = Util.addDom("input", { class: "ogl_inputCheck", parent: parent, value: this.ogl.db.fleetLimiter.data[id] || 0, oninput: () => { setTimeout(() => { this.ogl.db.fleetLimiter.data[id] = parseInt(input.value.replace(/\D/g, "")) || 0, this.ogl._fleet.updateLimiter(!0); }, 200); } }); if (!isNaN(id)) { parent = Util.addDom("div", { parent: jumpgateContainer, class: "ogl_icon ogl_" + id, "data-id": id }); let jumpgateInput = Util.addDom("input", { class: "ogl_inputCheck", parent: parent, value: this.ogl.db.fleetLimiter.jumpgateData[id] || 0, oninput: () => { setTimeout(() => { this.ogl.db.fleetLimiter.jumpgateData[id] = parseInt(jumpgateInput.value.replace(/\D/g, "")) || 0, this.ogl._fleet.updateLimiter(); }, 200); } }); } } }), container.querySelectorAll(".ogl_inputCheck").forEach(e => Util.formatInput(e)), container; } openKeyboardActions() { let container = Util.addDom("div", { class: "ogl_keyboardActions" }), changes = {}; return Util.addDom("h2", { parent: container, child: this.ogl._lang.find("keyboardActions") }), Object.entries(this.ogl.db.options.keyboardActions).forEach(key => { var label = Util.addDom("label", { parent: container, child: "" + this.ogl._lang.find(key[0]) }); let input = Util.addDom("input", { maxlength: "1", type: "text", value: key[1], parent: label, onclick: () => { input.value = "", input.select(); }, onblur: () => { "" == input.value && (input.value = key[1]); }, onkeyup: event => { "enter" != event.key.toLowerCase() && (changes[key[0]] = event.key.toLowerCase(), input.value = event.key.toLowerCase()); } }); "fleetResourcesSplit" == key[0] && (input.classList.add("ogl_disabled"), input.disabled = !0); }), Util.addDom("button", { parent: container, class: "ogl_button", child: "save", onclick: () => { Object.entries(changes).forEach(key => { this.ogl.db.options.keyboardActions[key[0]] = changes[key[0]], window.location.reload(); }); } }), container; } openExpeditionFiller() { let container = Util.addDom("div", { class: "ogl_expeditionFiller" }); return Util.addDom("h2", { parent: container, child: this.ogl._lang.find("expeditionBigShips") }), [ 204, 205, 206, 207, 215, 211, 213, 218 ].forEach(shipID => { let item = Util.addDom("div", { class: "ogl_icon ogl_" + shipID, parent: container, onclick: () => { -1 < this.ogl.db.options.expeditionBigShips.indexOf(shipID) ? (this.ogl.db.options.expeditionBigShips = this.ogl.db.options.expeditionBigShips.filter(a => a !== shipID), item.classList.remove("ogl_active")) : (this.ogl.db.options.expeditionBigShips.push(shipID), item.classList.add("ogl_active")); } }); -1 < this.ogl.db.options.expeditionBigShips.indexOf(shipID) && item.classList.add("ogl_active"); }), container; } openDataManager() { var container = Util.addDom("div", { class: "ogl_manageData" }), grid = (Util.addDom("h2", { parent: container, child: this.ogl._lang.find("manageData") }), Util.addDom("div", { class: "ogl_grid", parent: container })); Util.addDom("label", { class: "ogl_button", for: "ogl_import", child: "Import data", parent: grid }); let importButton = Util.addDom("input", { id: "ogl_import", class: "ogl_hidden", accept: "application/JSON", type: "file", parent: grid, onchange: () => { var file = importButton.files[0]; let reader = new FileReader(); reader.onload = () => { let json, error; try { json = JSON.parse(reader.result); } catch (e) { error = "cannot read file"; } !error && json && 10 < json.dataFormat ? (this.ogl.db = json, document.location.reload()) : this.ogl._notification.addToQueue("Error, " + (error || "wrong data format"), !1); }, reader.readAsText(file); } }); return Util.addDom("a", { class: "ogl_button", download: `oglight_${this.ogl.server.name}_${this.ogl.server.lang}_` + serverTime.getTime(), child: "Export data", parent: grid, href: URL.createObjectURL(new Blob([ JSON.stringify(this.ogl.db) ], { type: "application/json" })) }), Util.addDom("hr", { parent: grid }), Util.addDom("div", { class: "ogl_button ogl_danger", child: this.ogl._lang.find("resetStats") + ' <i class="material-icons">donut_large</i>', parent: grid, onclick: () => { confirm(this.ogl._lang.find("resetStatsLong")) && (this.ogl.cache.raids = {}, this.ogl.db.stats = {}, window.location.reload(), this.ogl.db.initialTime = Date.now()); } }), Util.addDom("div", { class: "ogl_button ogl_danger", child: this.ogl._lang.find("resetTaggedPlanets") + ' <i class="material-icons">stroke_full</i>', parent: grid, onclick: () => { confirm(this.ogl._lang.find("resetTaggedPlanetsLong")) && (this.ogl.db.tdb = {}, this.ogl.db.quickRaidList = [], window.location.reload()); } }), Util.addDom("div", { class: "ogl_button ogl_danger", child: this.ogl._lang.find("resetPinnedPlayers") + ' <i class="material-icons">push_pin</i>', parent: grid, onclick: () => { confirm(this.ogl._lang.find("resetPinnedPlayersLong")) && (this.ogl.db.lastStatusUpdate = 0, this.ogl.db.lastGlobalScoreUpdate = 0, this.ogl.db.pdb = {}, this.ogl.db.udb = {}, this.ogl.db.lastPinnedList = [], this.ogl.db.quickRaidList = [], window.location.reload()); } }), Util.addDom("div", { class: "ogl_button ogl_danger", child: this.ogl._lang.find("resetAll"), parent: grid, onclick: () => { confirm(this.ogl._lang.find("resetAllLong")) && (this.ogl.cache = {}, this.ogl.db = {}, window.location.reload(), this.ogl.db.initialTime = Date.now()); } }), container; } groupPlanets() { let lastCoords = 0, group = 1; document.querySelectorAll(".smallplanet").forEach(planet => { var newCoords = Util.coordsToID(planet.querySelector(".planet-koords").innerText).slice(0, -3); lastCoords === newCoords ? planet.setAttribute("data-group", group) : planet.previousElementSibling?.getAttribute("data-group") && group++, lastCoords = newCoords; }); } checkImportExport() { (this.ogl.db.nextImportExport || 0) < Date.now() && document.querySelector(".menubutton[href*=traderOverview]").classList.add("ogl_active"), window.addEventListener("beforeunload", () => { var tomorow, textTarget = document.querySelector(".bargain_text"), button = document.querySelector(".import_bargain.hidden"); textTarget && button ? (button = new Date(serverTime.getTime()), tomorow = new Date(serverTime.getTime() + 864e5), textTarget.innerText.match(/\d+/g) ? this.ogl.db.nextImportExport = new Date(button.getFullYear(), button.getMonth(), button.getDate(), textTarget.innerText.match(/\d+/g)[0], 0, 0).getTime() : this.ogl.db.nextImportExport = new Date(tomorow.getFullYear(), tomorow.getMonth(), tomorow.getDate(), 0, 0, 1).getTime(), this.ogl.save()) : textTarget && "" == textTarget.innerText && (this.ogl.db.nextImportExport = serverTime.getTime(), this.ogl.save()); }); } getPlayerStatus(id, status) { status = status ? { status: status } : this.ogl.db.udb[id]; if (status) return { statusClass: id = this.ogl._highscore.tagToNameList[status.status], statusTag: "status_abbr_inactive" === id ? this.ogl.db.serverData.inactive : "status_abbr_longinactive" === id ? this.ogl.db.serverData.inactiveLong : "status_abbr_banned" === id ? this.ogl.db.serverData.banned : "status_abbr_vacation" === id && this.ogl.db.serverData.vacation }; } turnIntoPlayerLink(id, dom, name, status) { dom.closest(".ogl_spyLine") || (dom.setAttribute("title", "loading..."), dom.classList.add("tooltipUpdate"), dom.classList.add("tooltipRight"), dom.classList.add("tooltipClose")), (status || this.ogl.db.udb?.[id]?.status) && (dom.className = dom.className.replaceAll(/status_abbr_[a-zA-Z]+/g, ""), status = this.getPlayerStatus(id, status), dom.setAttribute("data-status-tag", status.statusTag), dom.classList.add(status.statusClass)), dom.addEventListener("click", event => { dom.closest(".ogl_spyLine") || id == this.ogl.account.id || event.ctrlKey || (event.preventDefault(), this.ogl._topbar.openPinnedDetail(id)); }), dom.addEventListener("tooltip", () => { var loading = Util.addDom("div", { child: '<div class="ogl_loading"></div>' }); dom._tippy.setContent(loading), this.ogl._fetch.fetchPlayerAPI(id, name, () => { setTimeout(() => { dom._tippy.setContent(this.getPlayerTooltip(id)), document.querySelector(".ogl_pinDetail") && this.ogl.db.currentSide == id && this.ogl._topbar.openPinnedDetail(id); }, 100); }); }); } getPlayerTooltip(id) { let player = this.ogl.db.udb[id]; var page = Math.ceil(player.score.globalRanking / 100), page = Util.addDom("div", { class: "ogl_playerData", child: ` <h1 class="${this.ogl._highscore.tagToNameList[player.status] || "status_abbr_active"}">${player.name} <a href="https://${window.location.host}/game/index.php?page=highscore&site=${page}&searchRelId=${id}">#${player.score.globalRanking}</a></h1> <div class="ogl_grid"> <div class="ogl_tagSelector material-icons"></div> <div class="ogl_leftSide"> <div class="ogl_actions"></div> <div class="ogl_score"> <div class="ogl_line"><i class="material-icons">trending_up</i><div>${Util.formatNumber(player.score.global)}</div></div> <div class="ogl_line"><i class="material-icons">diamond</i><div>${Util.formatNumber(player.score.economy)}</div></div> <div class="ogl_line"><i class="material-icons">science</i><div>${Util.formatNumber(player.score.research)}</div></div> <div class="ogl_line"><i class="material-icons">genetics</i><div>${Util.formatNumber(player.score.lifeform)}</div></div> <div class="ogl_line"><i class="material-icons">rocket_launch</i><div>${Util.formatNumber(Util.getPlayerScoreFD(player.score, "fleet"))}</div></div> <div class="ogl_line"><i class="material-icons">security</i><div>${Util.formatNumber(Util.getPlayerScoreFD(player.score, "defense"))}</div></div> <div class="ogl_line"><i class="material-icons">schedule</i><div>${new Date(player.api).toLocaleDateString("de-DE", { day: "2-digit", month: "2-digit", year: "numeric" })}</div></div> </div> </div> <div class="ogl_planetStalk"></div> </div>` }), writeIcon = Util.addDom("div", { child: "edit", class: "material-icons ogl_button", parent: page.querySelector(".ogl_actions"), onclick: () => { document.querySelector("#chatBar") || (window.location.href = `https://${window.location.host}/game/index.php?page=chat&playerId=` + player.uid); } }); document.querySelector("#chatBar") && (writeIcon.classList.add("js_openChat"), writeIcon.setAttribute("data-playerId", player.uid)), Util.addDom("a", { child: "account-plus", class: "material-icons ogl_button overlay", parent: page.querySelector(".ogl_actions"), href: `https://${window.location.host}/game/index.php?page=ingame&component=buddies&action=7&id=${player.uid}&ajax=1`, onclick: () => { tippy.hideAll(); } }), Util.addDom("div", { child: "block", class: "material-icons ogl_button", parent: page.querySelector(".ogl_actions"), onclick: () => { window.location.href = `https://${window.location.host}/game/index.php?page=ignorelist&action=1&id=` + player.uid; } }), Util.addDom("div", { child: "query_stats", class: "material-icons ogl_button", parent: page.querySelector(".ogl_actions"), onclick: () => { window.open(Util.genMmorpgstatLink(this.ogl, player.uid), "_blank"); } }), id != this.ogl.account.id && Util.addDom("div", { child: "arrow_forward", class: "material-icons ogl_button", parent: page.querySelector(".ogl_actions"), onclick: () => { this.ogl._topbar.openPinnedDetail(player.uid); } }); let planetList = page.querySelector(".ogl_planetStalk"), lastCoords = 0, group = 1; if (player.planets.sort((a, b) => Util.coordsToID(a) - Util.coordsToID(b)).forEach((planet, index) => { var coords = planet.split(":"), index = Util.addDom("div", { parent: planetList, child: `<div>${index + 1}</div><div data-galaxy="${coords[0]}:${coords[1]}">${planet}</div>` }), newCoords = Util.coordsToID(coords).slice(0, -3); lastCoords === newCoords ? index.setAttribute("data-group", group) : index.previousElementSibling?.getAttribute("data-group") && group++, lastCoords = newCoords, this.ogl.db.pdb[planet]?.home && index.classList.add("ogl_home"), unsafeWindow.galaxy == coords[0] && unsafeWindow.system == coords[1] && index.querySelector("[data-galaxy]").classList.add("ogl_active"), this.addSpyIcons(index, coords), this.ogl._ui.addTagButton(index, coords, !0); }), player.uid != this.ogl.account.id) { let tagSelector = page.querySelector(".ogl_tagSelector"); Object.keys(this.ogl.db.tags).forEach(tag => { Util.addDom("div", { parent: tagSelector, "data-tag": tag, onclick: () => { player.planets.forEach(planet => { planet = Util.coordsToID(planet.split(":")); "none" != tag ? (this.ogl.db.tdb[planet] = { tag: tag }, document.querySelectorAll(`.ogl_tagPicker[data-raw="${planet}"]`).forEach(e => e.setAttribute("data-tag", tag))) : this.ogl.db.tdb[planet] && (delete this.ogl.db.tdb[planet], document.querySelectorAll(`.ogl_tagPicker[data-raw="${planet}"]`).forEach(e => e.removeAttribute("data-tag"))); }); } }); }); } return page; } addPinButton(element, id) { var player = this.ogl.db.udb[id]; let div = Util.addDom("div", { title: "loading...", class: "ogl_flagPicker material-icons tooltipLeft tooltipClick tooltipClose tooltipUpdate", "data-uid": id, parent: element, ontooltip: event => { div._tippy.setContent(tooltip); }, onclick: event => { event.shiftKey && (event.preventDefault(), "none" == this.ogl.db.lastPinUsed && this.ogl.db.udb[id] ? (delete this.ogl.db.udb[id].pin, document.querySelectorAll(`.ogl_flagPicker[data-uid="${id}"]`).forEach(e => { e.removeAttribute("data-flag"), e.innerText = ""; })) : (this.ogl.db.udb[id] = this.ogl.db.udb[id] || this.ogl.createPlayer(id), this.ogl.db.udb[id].pin = this.ogl.db.lastPinUsed, document.querySelectorAll(`.ogl_flagPicker[data-uid="${id}"]`).forEach(e => { e.setAttribute("data-flag", this.ogl.db.lastPinUsed); }))); } }), tooltip = Util.addDom("div", { class: "ogl_flagSelector material-icons" }); this.ogl.flagsList.forEach(pin => { "ptre" == pin && !this.ogl.ptreKey || Util.addDom("div", { "data-flag": pin, parent: tooltip, onclick: () => { "none" == pin && this.ogl.db.udb[id] ? (delete this.ogl.db.udb[id].pin, document.querySelectorAll(`.ogl_flagPicker[data-uid="${id}"]`).forEach(e => { e.removeAttribute("data-flag"), e.innerText = ""; })) : (this.ogl.db.udb[id] = this.ogl.db.udb[id] || this.ogl.createPlayer(id), this.ogl.db.udb[id].pin = pin, document.querySelectorAll(`.ogl_flagPicker[data-uid="${id}"]`).forEach(e => { e.setAttribute("data-flag", pin); })), "none" != (this.ogl.db.lastPinUsed = pin) && this.ogl._topbar.openPinnedDetail(id), tippy.hideAll(); } }); }), player?.pin && div.setAttribute("data-flag", player.pin); } addTagButton(element, coords, disabled) { let raw = Util.coordsToID(coords); coords = this.ogl.db.tdb[raw]; let div = Util.addDom("div", { title: "loading...", class: "ogl_tagPicker material-icons tooltipLeft tooltipClick tooltipClose tooltipUpdate", "data-raw": raw, parent: element, ontooltip: event => { disabled || div._tippy.setContent(tooltip); }, onclick: event => { event.shiftKey && !disabled && ("none" == this.ogl.db.lastTagUsed && this.ogl.db.tdb[raw] ? (delete this.ogl.db.tdb[raw], document.querySelectorAll(`.ogl_tagPicker[data-raw="${raw}"]`).forEach(e => e.removeAttribute("data-tag"))) : (this.ogl.db.tdb[raw] = this.ogl.db.tdb[raw] || {}, this.ogl.db.tdb[raw].tag = this.ogl.db.lastTagUsed, document.querySelectorAll(`.ogl_tagPicker[data-raw="${raw}"]`).forEach(e => e.setAttribute("data-tag", this.ogl.db.lastTagUsed)))); } }), tooltip = Util.addDom("div", { class: "ogl_tagSelector material-icons" }); Object.keys(this.ogl.db.tags).forEach(tag => { Util.addDom("div", { "data-tag": tag, parent: tooltip, onclick: () => { "none" == tag && this.ogl.db.tdb[raw] ? (delete this.ogl.db.tdb[raw], document.querySelectorAll(`.ogl_tagPicker[data-raw="${raw}"]`).forEach(e => e.removeAttribute("data-tag"))) : (this.ogl.db.tdb[raw] = this.ogl.db.tdb[raw] || {}, this.ogl.db.tdb[raw].tag = tag, document.querySelectorAll(`.ogl_tagPicker[data-raw="${raw}"]`).forEach(e => e.setAttribute("data-tag", tag))), this.ogl.db.lastTagUsed = tag, tippy.hideAll(); } }); }), coords?.tag && div.setAttribute("data-tag", coords.tag); } addSpyIcons(parent, coords, uniqueType, displayActivity) { var planetIcon, activityDom; if (coords = "string" == typeof coords ? coords.split(":") : coords, "planet" != uniqueType && uniqueType || (planetIcon = Util.addDom("div", { class: "material-icons ogl_spyIcon", "data-spy-coords": `${coords[0]}:${coords[1]}:${coords[2]}:1`, child: "language", parent: parent, onclick: e => window.location.href = `https://${window.location.host}/game/index.php?page=ingame&component=fleetdispatch&galaxy=${coords[0]}&system=${coords[1]}&position=${coords[2]}&type=1` }), lastPlanetSpy = this.ogl.db.pdb[`${coords[0]}:${coords[1]}:` + coords[2]]?.spy?.[0] || 0, serverTime.getTime() - lastPlanetSpy < this.ogl.db.options.spyIndicatorDelay && (planetIcon.setAttribute("data-spy", "recent"), planetIcon.setAttribute("title", "recently spied")), displayActivity && (lastPlanetSpy = this.ogl.db.pdb[`${coords[0]}:${coords[1]}:` + coords[2]]?.acti || [], isRecent = serverTime.getTime() - lastPlanetSpy[2] < 36e5, activityDom = Util.addDom("span", { parent: planetIcon, child: isRecent ? lastPlanetSpy[0] : "?" }), "*" == lastPlanetSpy[0] && isRecent ? activityDom.classList.add("ogl_danger") : 60 == lastPlanetSpy[0] && isRecent ? activityDom.classList.add("ogl_ok") : activityDom.classList.add("ogl_warning")), Object.values(ogl.cache.movements).flat().find(e => e.to.coords == `${coords[0]}:${coords[1]}:` + coords[2] && !e.to.isMoon && 1 == e.mission && !e.isBack) && planetIcon.classList.add("ogl_attacked")), "moon" == uniqueType || !uniqueType && this.ogl.db.pdb[`${coords[0]}:${coords[1]}:` + coords[2]]?.mid) { var lastPlanetSpy = 0 < this.ogl.db.pdb[`${coords[0]}:${coords[1]}:` + coords[2]]?.mid ? Util.addDom("div", { class: "material-icons ogl_spyIcon", "data-spy-coords": `${coords[0]}:${coords[1]}:${coords[2]}:3`, child: "bedtime", parent: parent, onclick: e => window.location.href = `https://${window.location.host}/game/index.php?page=ingame&component=fleetdispatch&galaxy=${coords[0]}&system=${coords[1]}&position=${coords[2]}&type=3` }) : Util.addDom("div", { parent: parent }), isRecent = this.ogl.db.pdb[`${coords[0]}:${coords[1]}:` + coords[2]]?.spy?.[1] || 0; if (serverTime.getTime() - isRecent < this.ogl.db.options.spyIndicatorDelay && (lastPlanetSpy.setAttribute("data-spy", "recent"), lastPlanetSpy.setAttribute("title", "recently spied")), displayActivity && -1 < this.ogl.db.pdb[`${coords[0]}:${coords[1]}:` + coords[2]]?.mid) { let activity = this.ogl.db.pdb[`${coords[0]}:${coords[1]}:` + coords[2]]?.acti || [], isRecent = serverTime.getTime() - activity[2] < 36e5, activityDom = Util.addDom("span", { parent: lastPlanetSpy, child: isRecent ? activity[1] : "?" }); "*" == activity[1] && isRecent ? activityDom.classList.add("ogl_danger") : 60 == activity[1] && isRecent ? activityDom.classList.add("ogl_ok") : activityDom.classList.add("ogl_warning"); } Object.values(ogl.cache.movements).flat().find(e => e.to.coords == `${coords[0]}:${coords[1]}:` + coords[2] && e.to.isMoon && 1 == e.mission && !e.isBack) && lastPlanetSpy.classList.add("ogl_attacked"); } uniqueType || this.ogl.db.pdb[`${coords[0]}:${coords[1]}:` + coords[2]]?.mid || Util.addDom("div", { parent: parent }); } updateLeftMenu() { var leftMenu = document.querySelector("#menuTable"), version = oglVersion, oglBlock = Util.addDom("li", { parent: leftMenu }); Util.addDom("span", { parent: oglBlock, class: "menu_icon ogl_leftMenuIcon", child: '<a class="tooltipRight" href="https://openuserjs.org/scripts/nullNaN/OGLight" target="_blank"><i class="material-icons">oglight_simple</i></a>' }); Util.addDom("a", { parent: oglBlock, class: "menubutton tooltipRight", href: "https://board.fr.ogame.gameforge.com/index.php?thread/722955-oglight/", target: "_blank", child: `<span class="textlabel">OGLight ${version}</span>` }), this.ogl.ptreKey && (oglBlock = Util.addDom("li", { parent: leftMenu }), Util.addDom("span", { parent: oglBlock, class: "menu_icon ogl_leftMenuIcon ogl_ptreActionIcon", child: '<a class="tooltipRight" title="PTRE last request status" href="#"><i class="material-icons">sync_alt</i></a>', onclick: () => this.ogl.PTRE.displayLogs() }), Util.addDom("a", { parent: oglBlock, class: "menubutton tooltipRight", href: "https://ptre.chez.gg/", target: "_blank", child: '<span class="textlabel">PTRE</span>' })); } updateFooter() { var footer = document.querySelector("#siteFooter .fright"), lang = [ "fr", "de", "en", "es", "pl", "it", "ru", "ar", "mx", "tr", "fi", "tw", "gr", "br", "nl", "hr", "sk", "cz", "ro", "us", "pt", "dk", "no", "se", "si", "hu", "jp", "ba" ].indexOf(this.ogl.server.lang); footer.innerHTML += ` | <a target="_blank" href="https://www.mmorpg-stat.eu/0_fiche_joueur.php?pays=${lang}&ftr=${this.ogl.account.id}.dat&univers=_${this.ogl.server.id}">Mmorpg-stat</a> | <a target="_blank" href="https://ogotcha.oplanet.eu/${this.ogl.server.lang}">Ogotcha</a> | <a>OGL ${this.ogl.version}</a> `; } updateHighscore() { return; } updateStatus() { return; } displayScoreDiff(highscore) { return; } displayStatus(highscore) {} displayResourcesRecap() { this.resources = {}, this.resources.total = { metal: 0, crystal: 0, deut: 0, msu: 0 }, this.resources.prod = { metal: 0, crystal: 0, deut: 0, msu: 0 }, this.resources.fly = { metal: 0, crystal: 0, deut: 0 }, this.resources.ground = { metal: 0, crystal: 0, deut: 0 }, this.resources.todo = { metal: 0, crystal: 0, deut: 0 }, document.querySelectorAll(".planetlink, .moonlink").forEach(planet => { let id = new URLSearchParams(planet.getAttribute("href")).get("cp").split("#")[0]; [ "metal", "crystal", "deut" ].forEach(resourceName => { this.resources.total[resourceName] += this.ogl.db.myPlanets[id]?.[resourceName] || 0, this.resources.ground[resourceName] += this.ogl.db.myPlanets[id]?.[resourceName] || 0, this.resources.prod[resourceName] += this.ogl.db.myPlanets[id]?.["prod" + resourceName] || 0; }), Object.values(this.ogl.db.myPlanets[id]?.todolist || {}).forEach(entry => { Object.values(entry || {}).forEach(todo => { todo.cost && (this.resources.todo.metal += todo.cost.metal, this.resources.todo.crystal += todo.cost.crystal, this.resources.todo.deut += todo.cost.deut); }); }); }), Object.entries(this.ogl.cache?.movements || {}).forEach(entry => { entry[1].forEach(line => { [ "metal", "crystal", "deut" ].forEach(resourceName => { this.resources.total[resourceName] += line[resourceName] || 0, this.resources.fly[resourceName] += line[resourceName] || 0; }); }); }); var msuValue = this.ogl.db.options.msu; this.resources.total.msu = Util.getMSU(this.resources.total.metal, this.resources.total.crystal, this.resources.total.deut, msuValue), this.resources.prod.metal = Math.floor(3600 * this.resources.prod.metal * 24), this.resources.prod.crystal = Math.floor(3600 * this.resources.prod.crystal * 24), this.resources.prod.deut = Math.floor(3600 * this.resources.prod.deut * 24), this.resources.prod.msu = Util.getMSU(this.resources.prod.metal, this.resources.prod.crystal, this.resources.prod.deut, msuValue), this.resourceDiv.querySelector(".ogl_metal").innerHTML = `<span>${Util.formatToUnits(this.resources.total.metal)}</span><span>+${Util.formatToUnits(Math.floor(this.resources.prod.metal, 1))}</span>`, this.resourceDiv.querySelector(".ogl_crystal").innerHTML = `<span>${Util.formatToUnits(this.resources.total.crystal)}</span><span>+${Util.formatToUnits(Math.floor(this.resources.prod.crystal, 1))}</span>`, this.resourceDiv.querySelector(".ogl_deut").innerHTML = `<span>${Util.formatToUnits(this.resources.total.deut)}</span><span>+${Util.formatToUnits(Math.floor(this.resources.prod.deut, 1))}</span>`, this.resourceDiv.querySelector(".ogl_msu").innerHTML = `<span>${Util.formatToUnits(this.resources.total.msu)}</span><span>+${Util.formatToUnits(Math.floor(this.resources.prod.msu, 1))}</span>`, this.recapReady || (this.recapReady = !0, this.resourceDiv.addEventListener("click", () => { var container = Util.addDom("div", { class: "ogl_resourcesDetail" }); container.innerHTML = ` <div> <h3 class="material-icons">precision_manufacturing</h3> <h4>Construction</h4> <div class="ogl_metal">+${Util.formatToUnits(this.resources.prod.metal)}</div> <div class="ogl_crystal">+${Util.formatToUnits(this.resources.prod.crystal)}</div> <div class="ogl_deut">+${Util.formatToUnits(this.resources.prod.deut)}</div> </div> <div> <h3 class="material-icons">format_list_bulleted</h3> <h4>Todolist</h4> <div class="ogl_metal ogl_todoDays">${Util.formatToUnits(this.resources.todo.metal)} <span>(${Math.ceil(Math.max(0, this.resources.todo.metal - this.resources.total.metal) / this.resources.prod.metal)}${LocalizationStrings.timeunits.short.day})</span></div> <div class="ogl_crystal ogl_todoDays">${Util.formatToUnits(this.resources.todo.crystal)} <span>(${Math.ceil(Math.max(0, this.resources.todo.crystal - this.resources.total.crystal) / this.resources.prod.crystal)}${LocalizationStrings.timeunits.short.day})</span></div> <div class="ogl_deut ogl_todoDays">${Util.formatToUnits(this.resources.todo.deut)} <span>(${Math.ceil(Math.max(0, this.resources.todo.deut - this.resources.total.deut) / this.resources.prod.deut)}${LocalizationStrings.timeunits.short.day})</span></div> </div> <div> <h3 class="material-icons">globe_uk</h3> <h4>Planet / moon</h4> <div class="ogl_metal">${Util.formatToUnits(this.resources.ground.metal)}</div> <div class="ogl_crystal">${Util.formatToUnits(this.resources.ground.crystal)}</div> <div class="ogl_deut">${Util.formatToUnits(this.resources.ground.deut)}</div> </div> <div> <h3 class="material-icons">send</h3> <h4>Flying</h4> <div class="ogl_metal">${Util.formatToUnits(this.resources.fly.metal)}</div> <div class="ogl_crystal">${Util.formatToUnits(this.resources.fly.crystal)}</div> <div class="ogl_deut">${Util.formatToUnits(this.resources.fly.deut)}</div> </div> <div> <h3 class="material-icons">sigma</h3> <h4>Total</h4> <div class="ogl_metal">${Util.formatToUnits(this.resources.total.metal)}</div> <div class="ogl_crystal">${Util.formatToUnits(this.resources.total.crystal)}</div> <div class="ogl_deut">${Util.formatToUnits(this.resources.total.deut)}</div> </div> `, this.ogl._popup.open(container); })); } } class TopbarManager extends Manager { load(reloaded) { this.topbar = Util.addDom("div", { class: "ogl_topbar", prepend: document.querySelector("#planetList") }), Util.addDom("i", { class: "material-icons tooltip", child: "conversion_path", title: this.ogl._lang.find("collectResources"), parent: this.topbar, onclick: e => { this.ogl.db.harvestCoords = !1, document.body.classList.toggle("ogl_destinationPicker"), document.body.classList.toggle("ogl_initHarvest"); } }), Util.addDom("i", { class: "material-icons tooltip", child: "account_balance", parent: this.topbar, title: this.ogl._lang.find("accountSummary"), onclick: () => this.openAccount() }), Util.addDom("i", { class: "material-icons tooltip", child: "stroke_full", parent: this.topbar, title: this.ogl._lang.find("taggedPlanets"), onclick: () => this.openTagged(!0) }), Util.addDom("i", { class: "material-icons tooltip", child: "push_pin", parent: this.topbar, title: this.ogl._lang.find("pinnedPlayers"), onclick: () => this.openPinned(!0) }), Util.addDom("i", { class: "material-icons tooltip", child: "settings", parent: this.topbar, title: this.ogl._lang.find("oglSettings"), onclick: () => this.openSettings(!0) }), Util.addDom("a", { parent: this.topbar, class: "material-icons tooltip", child: "favorite", title: this.ogl._lang.find("coffee"), target: "_blank", href: "https://ko-fi.com/O4O22XV69" }), this.syncBtn = Util.addDom("i", { class: "material-icons tooltip", child: "directory_sync", title: this.ogl._lang.find("syncEmpire"), parent: this.topbar, onclick: () => { this.ogl._fetch.fetchValue = 0, this.ogl._fetch.fetchLFBonuses(), this.ogl._fetch.fetchEmpire(), this.ogl._fetch.fetchProductionQueue(); } }), reloaded || (isNaN(this.ogl.db.currentSide) ? "settings" == this.ogl.db.currentSide ? this.openSettings() : "pinned" == this.ogl.db.currentSide ? this.openPinned() : "tagged" == this.ogl.db.currentSide && this.openTagged() : this.openPinnedDetail(this.ogl.db.currentSide)), Util.addDom("button", { class: "ogl_button", child: this.ogl._lang.find("siblingPlanetMoon"), parent: this.topbar, onclick: () => { var nextID; this.ogl.currentPlanet.obj.planetID || this.ogl.currentPlanet.obj.moonID ? window.location.href = `https://${window.location.host}/game/index.php?page=ingame&component=fleetdispatch&oglmode=2` : (nextID = "planet" == this.ogl.planetType ? this.ogl.currentPlanet.dom.nextWithMoon.getAttribute("id").replace("planet-", "") : this.ogl.currentPlanet.dom.nextWithMoon.querySelector(".moonlink").getAttribute("href").match(/cp=(\d+)/)[1], window.location.href = `https://${window.location.host}/game/index.php?page=ingame&component=fleetdispatch&cp=${nextID}&oglmode=2`); } }); } openAccount() { let container = Util.addDom("div", { class: "ogl_empire" }); var count = document.querySelectorAll(".smallplanet").length; let stack = { fieldUsed: 0, fieldMax: 0, fieldLeft: 0, temperature: 0, metal: 0, crystal: 0, deut: 0, prodmetal: 0, prodcrystal: 0, proddeut: 0 }; Util.addDom("div", { class: "ogl_invisible", parent: container }), Util.addDom("div", { class: "ogl_invisible", parent: container }), Util.addDom("div", { class: "ogl_invisible", parent: container }), Util.addDom("div", { class: "ogl_invisible", parent: container }), Util.addDom("div", { class: "ogl_invisible", parent: container }), Util.addDom("div", { class: "ogl_invisible", parent: container }), Util.addDom("div", { class: "ogl_invisible", parent: container }), Util.addDom("div", { class: "ogl_icon ogl_metal", parent: container }), Util.addDom("div", { class: "ogl_icon ogl_crystal", parent: container }), Util.addDom("div", { class: "ogl_icon ogl_deut", parent: container }), Util.addDom("div", { child: "Coords", parent: container }), Util.addDom("div", { child: "P", parent: container }), Util.addDom("div", { child: "M", parent: container }), Util.addDom("div", { child: "Name", parent: container }), Util.addDom("div", { child: "Fields", parent: container }), Util.addDom("div", { child: "T°c", parent: container }), Util.addDom("div", { child: "LF", parent: container }); var metalStack = Util.addDom("div", { class: "ogl_metal", parent: container }), crystalStack = Util.addDom("div", { class: "ogl_crystal", parent: container }), deutStack = Util.addDom("div", { class: "ogl_deut", parent: container }); document.querySelectorAll(".smallplanet").forEach(line => { var id = line.getAttribute("id").replace("planet-", ""), id = this.ogl.db.myPlanets[id], name = line.querySelector(".planet-name").innerText, coordDiv = Util.addDom("div", { parent: container, "data-galaxy": id.coords, child: id.coords }), coordDiv = (line.getAttribute("data-group") && coordDiv.setAttribute("data-group", line.getAttribute("data-group")), Util.addDom("a", { parent: container, href: line.querySelector(".planetlink").getAttribute("href"), child: Util.addDom("img", { src: line.querySelector(".planetPic").getAttribute("src") }) }), line.querySelector(".moonlink") ? Util.addDom("a", { parent: container, href: line.querySelector(".moonlink").getAttribute("href"), child: Util.addDom("img", { src: line.querySelector(".moonlink img").getAttribute("src") }) }) : Util.addDom("div", { class: "ogl_invisible", parent: container }), Util.addDom("div", { parent: container, child: name }), Util.addDom("div", { parent: container, child: `${id.fieldUsed}/${id.fieldMax} (<span>${id.fieldMax - id.fieldUsed}</span>)` }), stack.fieldUsed += id.fieldUsed, stack.fieldMax += id.fieldMax, stack.fieldLeft += id.fieldMax - id.fieldUsed, Util.addDom("div", { parent: container, child: id.temperature + 40 + "°C" })), line = (stack.temperature += id.temperature + 40, 110 <= id.temperature ? coordDiv.style.color = "#af644d" : 10 <= id.temperature ? coordDiv.style.color = "#af9e4d" : -40 <= id.temperature ? coordDiv.style.color = "#4daf67" : -140 <= id.temperature ? coordDiv.style.color = "#4dafa6" : coordDiv.style.color = "#4d79af", Util.addDom("div", { class: "ogl_icon ogl_lifeform" + (id.lifeform || 0), parent: container }), Util.addDom("div", { class: "ogl_metal", parent: container, child: `<strong>${id[1]}</strong><small>+${Util.formatToUnits(Math.round(3600 * (id.prodmetal || 0) * 24))}</small>` })), name = (id.upgrades?.baseBuilding?.[0]?.name.trim() == this.ogl.db.serverData[1] && serverTime.getTime() < id.upgrades?.baseBuilding?.[0]?.end && (line.querySelector("strong").innerHTML += `<span>${id[1] + 1}</span>`), Util.addDom("div", { class: "ogl_crystal", parent: container, child: `<strong>${id[2]}</strong><small>+${Util.formatToUnits(Math.round(3600 * (id.prodcrystal || 0) * 24))}</small>` })), coordDiv = (id.upgrades?.baseBuilding?.[0]?.name.trim() == this.ogl.db.serverData[2] && serverTime.getTime() < id.upgrades?.baseBuilding?.[0]?.end && (name.querySelector("strong").innerHTML += `<span>${id[2] + 1}</span>`), Util.addDom("div", { class: "ogl_deut", parent: container, child: `<strong>${id[3]}</strong><small>+${Util.formatToUnits(Math.round(3600 * (id.proddeut || 0) * 24))}</small>` })); stack.metal += id[1], stack.crystal += id[2], stack.deut += id[3], stack.prodmetal += id.prodmetal || 0, stack.prodcrystal += id.prodcrystal || 0, stack.proddeut += id.proddeut || 0, id.upgrades?.baseBuilding?.[0]?.name.trim() == this.ogl.db.serverData[3] && serverTime.getTime() < id.upgrades?.baseBuilding?.[0]?.end && (coordDiv.querySelector("strong").innerHTML += `<span>${id[3] + 1}</span>`); }), metalStack.innerHTML = `<strong>${(stack.metal / count).toFixed(1)}</strong><small>+${Util.formatToUnits(Math.round(3600 * (stack.prodmetal || 0) * 24))}</small>`, crystalStack.innerHTML = `<strong>${(stack.crystal / count).toFixed(1)}</strong><small>+${Util.formatToUnits(Math.round(3600 * (stack.prodcrystal || 0) * 24))}</small>`, deutStack.innerHTML = `<strong>${(stack.deut / count).toFixed(1)}</strong><small>+${Util.formatToUnits(Math.round(3600 * (stack.proddeut || 0) * 24))}</small>`, this.ogl._popup.open(container, !0); } openStats() { Util.runAsync(() => this.ogl._stats.buildStats(!1, !1)).then(e => this.ogl._popup.open(e, !0)); } openSettings(buttonSource) { let container = Util.addDom("div", { class: "ogl_config", child: '<h2>Settings<i class="material-icons">settings</i></h2>' }), subContainer; [ "defaultShip", "defaultMission", "profileButton", "resourceTreshold", "msu", "sim", "converter", "useClientTime", "keyboardActions", "showMenuResources", "shortcutsOnRight", "sidePanelOnLeft", "disablePlanetTooltips", "reduceLargeImages", "colorblindMode", "displayPlanetTimers", "expeditionValue", "expeditionRandomSystem", "expeditionRedirect", "expeditionBigShips", "expeditionShipRatio", "ignoreExpeShipsLoss", "ignoreConsumption", "displaySpyTable", "boardTab", "ptreTeamKey", "ptreLogs", "manageData", "debugMode" ].forEach(opt => { var isBoolean = typeof this.ogl.db.options[opt] == typeof !0, isNumber = typeof this.ogl.db.options[opt] != typeof [] && ("number" == typeof this.ogl.db.options[opt] || Number(this.ogl.db.options[opt])); this.ogl.db.options[opt], "defaultShip" == opt ? subContainer = "fleet" : "resourceTreshold" == opt ? subContainer = "general" : "showMenuResources" == opt ? subContainer = "interface" : "expeditionValue" == opt ? subContainer = "expeditions" : "expeditionShipRatio" == opt ? subContainer = "stats" : "displaySpyTable" == opt ? subContainer = "messages" : "ptreTeamKey" == opt ? subContainer = "PTRE" : "manageData" == opt && (subContainer = "data"); let currentContainer, label = (container.querySelector(`[data-container="${subContainer}"]`) ? currentContainer = container.querySelector(`[data-container="${subContainer}"]`) : (currentContainer = Util.addDom("div", { parent: container, "data-container": subContainer }), this.ogl.db.configState[subContainer] && currentContainer.classList.add("ogl_active"), Util.addDom("h3", { parent: currentContainer, child: subContainer, onclick: () => { currentContainer.classList.contains("ogl_active") ? (currentContainer.classList.remove("ogl_active"), this.ogl.db.configState[currentContainer.getAttribute("data-container")] = !1) : (currentContainer.classList.add("ogl_active"), this.ogl.db.configState[currentContainer.getAttribute("data-container")] = !0); } })), Util.addDom("label", { parent: currentContainer, "data-label": "" + this.ogl._lang.find(opt), "data-opt": opt })); var tooltip = this.ogl._lang.find(opt + "TT"); if ("TEXT_NOT_FOUND" != tooltip && (label.classList.add("tooltipLeft"), label.setAttribute("title", `<div class="ogl_settingsTooltip">${tooltip}</div>`)), "defaultShip" == opt) this.ogl.fretShips.forEach(shipID => { var div = Util.addDom("div", { parent: label, class: "ogl_icon ogl_" + shipID, onclick: (event, element) => { this.ogl.db.options.defaultShip = shipID, label.querySelector(".ogl_active")?.classList.remove("ogl_active"), element.classList.add("ogl_active"), "fleetdispatch" == this.ogl.page && (document.querySelectorAll("#fleet1 .ogl_fav").forEach(e => e.classList.add("ogl_grayed")), document.querySelector(`[data-technology="${this.ogl.db.options.defaultShip}"]`)?.classList.remove("ogl_grayed"), this.ogl._fleet.updateLimiter(), 1 === this.ogl.mode || 2 === this.ogl.mode ? (this.ogl.fretShips.forEach(shipID => fleetDispatcher.selectShip(shipID, 0)), fleetDispatcher.selectShip(this.ogl.db.options.defaultShip, this.ogl._fleet.shipsForResources()), fleetDispatcher.selectMaxAll()) : 3 === this.ogl.mode && this.ogl.cache.toSend && (this.ogl.fretShips.forEach(shipID => fleetDispatcher.selectShip(shipID, 0)), this.ogl._fleet.prefillTodolistCargo())); } }); this.ogl.db.options.defaultShip == shipID && div.classList.add("ogl_active"); }); else if ("defaultMission" == opt) [ 3, 4, 8 ].forEach(missionID => { var div = Util.addDom("div", { parent: label, class: "ogl_icon ogl_mission" + missionID, onclick: (event, element) => { this.ogl.db.options.defaultMission = missionID, label.querySelector(".ogl_active")?.classList.remove("ogl_active"), element.classList.add("ogl_active"); } }); this.ogl.db.options.defaultMission == missionID && div.classList.add("ogl_active"); }); else if ("profileButton" == opt) label.innerHTML = '<button class="material-icons">transit_enterexit</button>', label.querySelector("button").addEventListener("click", () => { Util.runAsync(() => this.ogl._ui.openFleetProfile()).then(e => this.ogl._popup.open(e)); }); else if ("msu" == opt) { label.classList.add("tooltipLeft"), label.setAttribute("title", "Format:<br>metal:crystal:deut"); let input = Util.addDom("input", { type: "text", placeholder: "m:c:d", value: this.ogl.db.options[opt], parent: label, oninput: () => { input.value && !/^[0-9]*[.]?[0-9]+:[0-9]*[.]?[0-9]+:[0-9]*[.]?[0-9]+$/.test(input.value) ? input.classList.add("ogl_danger") : (input.classList.remove("ogl_danger"), this.ogl.db.options[opt] = input.value.match(/^[0-9]*[.]?[0-9]+:[0-9]*[.]?[0-9]+:[0-9]*[.]?[0-9]+$/)[0]); } }); } else if ("showMenuResources" == opt) { label.innerHTML = ""; let select = Util.addDom("select", { parent: label, class: "dropdownInitialized", onchange: () => { this.ogl.db.options[opt] = parseInt(select.value), localStorage.setItem("ogl_menulayout", this.ogl.db.options[opt]), document.body.setAttribute("data-menulayout", select.value); } }); [ "All", "Coords", "Resources" ].forEach((entry, index) => { entry = Util.addDom("option", { parent: select, child: entry, value: index }); this.ogl.db.options[opt] == index && (entry.selected = !0); }); } else if (isBoolean && "sim" != opt) if ("boardTab" == opt && "fr" != this.ogl.server.lang) label.remove(); else { let input = Util.addDom("input", { type: "checkbox", parent: label, onclick: () => { this.ogl.db.options[opt] = !this.ogl.db.options[opt], input.checked = this.ogl.db.options[opt], "ignoreExpeShipsLoss" == opt && this.ogl.db.options.displayMiniStats || "ignoreConsumption" == opt && this.ogl.db.options.displayMiniStats ? this.ogl._stats.miniStats() : "displayPlanetTimers" == opt ? document.querySelector("#planetList").classList.toggle("ogl_alt") : "reduceLargeImages" == opt ? (localStorage.setItem("ogl_minipics", this.ogl.db.options[opt]), document.body.setAttribute("data-minipics", this.ogl.db.options[opt])) : "colorblindMode" == opt ? (localStorage.setItem("ogl_colorblind", this.ogl.db.options[opt]), document.body.setAttribute("data-colorblind", this.ogl.db.options[opt])) : "displaySpyTable" == opt && this.ogl._message?.spytable && 20 == this.ogl._message?.tabID ? this.ogl.db.options[opt] ? this.ogl._message.spytable.classList.remove("ogl_hidden") : this.ogl._message.spytable.classList.add("ogl_hidden") : "sidePanelOnLeft" == opt && document.body.setAttribute("data-sidepanel", this.ogl.db.options[opt]); } }); this.ogl.db.options[opt] && (input.checked = !0); } else if (isNumber || "expeditionValue" == opt) { let input = Util.addDom("input", { class: "ogl_inputCheck", type: "text", value: this.ogl.db.options[opt], parent: label, oninput: () => { setTimeout(() => { "expeditionShipRatio" == opt && (parseInt(input.value.replace(/\D/g, "")) < 0 ? input.value = 0 : 100 < parseInt(input.value.replace(/\D/g, "")) && (input.value = 100)); let newValue; "true" == input.getAttribute("data-allowPercent") && 0 <= input.value.toLowerCase().indexOf("%") ? (newValue = parseInt(input.value.replace(/\D/g, "")) || !1) && (newValue += "%") : newValue = parseInt(input.value.replace(/\D/g, "")) || !1, this.ogl.db.options[opt] = newValue, "expeditionShipRatio" == opt && this.ogl._stats.miniStats(); }, 200); } }); "expeditionValue" == opt && (input.setAttribute("data-allowPercent", !0), input.classList.add("ogl_placeholder"), input.setAttribute("placeholder", `(${Util.formatNumber(this.ogl.calcExpeditionMax().max)})`)); } else if ("keyboardActions" == opt) label.innerHTML = '<button class="material-icons">keyboard_alt</button>', label.querySelector("button").addEventListener("click", () => { Util.runAsync(() => this.ogl._ui.openKeyboardActions()).then(e => this.ogl._popup.open(e)); }); else if ("sim" == opt || "converter" == opt) { tooltip = "sim" == opt ? Util.simList : Util.converterList; label.innerHTML = ""; let select = Util.addDom("select", { parent: label, class: "dropdownInitialized", child: '<option value="false" selected disabled>-</option>', onchange: () => { this.ogl.db.options[opt] = select.value; } }); Object.entries(tooltip).forEach(entry => { var selectOption = Util.addDom("option", { parent: select, child: entry[0], value: entry[0] }); this.ogl.db.options[opt] == entry[0] && (selectOption.selected = !0); }); } else if ("expeditionBigShips" == opt) label.innerHTML = '<button class="material-icons">rocket</button>', label.querySelector("button").addEventListener("click", () => { Util.runAsync(() => this.ogl._ui.openExpeditionFiller()).then(e => this.ogl._popup.open(e)); }); else if ("displayMiniStats" == opt) label.innerHTML = '<div class="ogl_choice" data-limiter="day">D</div><div class="ogl_choice" data-limiter="week">W</div><div class="ogl_choice" data-limiter="month">M</div>', label.querySelectorAll("div").forEach(button => { button.addEventListener("click", () => { this.ogl.db.options[opt] = button.getAttribute("data-limiter"), this.ogl._stats.miniStats(), label.querySelector(".ogl_active") && label.querySelector(".ogl_active").classList.remove("ogl_active"), button.classList.add("ogl_active"); }), button.getAttribute("data-limiter") == this.ogl.db.options[opt] && button.classList.add("ogl_active"); }); else if ("ptreTeamKey" == opt) { label.classList.add("tooltipLeft"), label.setAttribute("title", "Format:<br>TM-XXXX-XXXX-XXXX-XXXX"); let input = Util.addDom("input", { type: "password", placeholder: "TM-XXXX-XXXX-XXXX-XXXX", value: localStorage.getItem("ogl-ptreTK") || "", parent: label, oninput: () => { !input.value || 18 == input.value.replace(/-/g, "").length && 0 == input.value.indexOf("TM") ? (input.classList.remove("ogl_danger"), localStorage.setItem("ogl-ptreTK", input.value), this.ogl.ptreKey = input.value) : input.classList.add("ogl_danger"); }, onfocus: () => input.type = "text", onblur: () => input.type = "password" }); } else "ptreLogs" == opt ? (label.innerHTML = '<button class="material-icons">bug</button>', label.querySelector("button").addEventListener("click", () => { this.ogl.PTRE.displayLogs(); })) : "manageData" == opt && (label.innerHTML = '<button class="material-icons">database</button>', label.querySelector("button").addEventListener("click", () => { Util.runAsync(() => this.ogl._ui.openDataManager()).then(e => this.ogl._popup.open(e)); })); }), this.ogl._ui.openSide(container, "settings", buttonSource); } openPinned(buttonSource) { this.ogl._ui.openSide(Util.addDom("div", { class: "ogl_loading" }), "pinned", buttonSource), Util.runAsync(() => { var container = Util.addDom("div", { class: "ogl_pinned", child: '<h2>Pinned players<i class="material-icons">push_pin</i></h2>' }); let tabs = Util.addDom("div", { class: "ogl_tabs ogl_flagSelector material-icons", parent: container }), list = Util.addDom("div", { class: "ogl_list", parent: container }), recentTab = (this.ogl.flagsList.forEach(pin => { if ("none" != pin) { let tab = Util.addDom("div", { parent: tabs, "data-flag": pin, onclick: () => { var actionList; list.innerText = "", tabs.querySelector("[data-flag].ogl_active")?.classList.remove("ogl_active"), tab.classList.add("ogl_active"), "ptre" == (this.ogl.db.lastPinTab = pin) && this.ogl.ptreKey && (actionList = Util.addDom("div", { class: "ogl_grid", parent: list }), Util.addDom("button", { class: "ogl_button", child: this.ogl._lang.find("ptreSyncTarget"), parent: actionList, onclick: () => { this.ogl.PTRE.syncTargetList(); } }), Util.addDom("button", { class: "ogl_button", child: this.ogl._lang.find("ptreManageTarget"), parent: actionList, onclick: () => { window.open(this.ogl.PTRE.manageSyncedListUrl, "_blank"); } }), Util.addDom("hr", { parent: list })), Object.values(this.ogl.db.udb).filter(u => u.pin == this.ogl.db.lastPinTab).sort((a, b) => a.score?.globalRanking - b.score?.globalRanking).forEach(player => { player.uid && this.addPinnedItemToList(player, list); }), list.querySelector("[data-uid]") || list.querySelector(".ogl_button") || (list.innerHTML = `<p class="ogl_emptyList">${this.ogl._lang.find("emptyPlayerList")}</p>`); } }); pin == this.ogl.db.lastPinTab && tab.click(); } }), Util.addDom("div", { "data-flag": "recent", parent: tabs, onclick: () => { this.ogl.db.lastPinTab = "recent", list.innerText = "", tabs.querySelector("[data-flag].ogl_active")?.classList.remove("ogl_active"), recentTab.classList.add("ogl_active"), this.ogl.db.lastPinnedList.forEach(id => { id = this.ogl.db.udb[id]; id?.uid && this.addPinnedItemToList(id, list); }), list.querySelector("[data-uid]") || (list.innerText = this.ogl._lang.find("emptyPlayerList")); } })); return "recent" == this.ogl.db.lastPinTab && recentTab.click(), container; }).then(container => this.ogl._ui.openSide(container, "pinned", buttonSource)); } addPinnedItemToList(player, list) { let item = Util.addDom("div", { parent: list }); list = Util.addDom("span", { class: "tooltipLeft tooltipClose tooltipUpdate " + (player.status || "status_abbr_active"), parent: item, child: "string" == typeof player.name ? player.name : "?" }), this.ogl._ui.turnIntoPlayerLink(player.uid, list), list = Math.max(1, Math.ceil((player.score?.globalRanking || 100) / 100)), list = Util.addDom("a", { class: "ogl_ranking", href: `https://${window.location.host}/game/index.php?page=highscore&site=${list}&searchRelId=` + player.uid, child: "#" + player.score?.globalRanking || "?" }); Util.addDom("div", { parent: item, child: list.outerHTML }), this.ogl._ui.addPinButton(item, player.uid), Util.addDom("i", { class: "material-icons", parent: item, child: "delete", onclick: () => { this.ogl.db.lastPinnedList.splice(this.ogl.db.lastPinnedList.findIndex(e => e == player.uid), 1), item.remove(), delete this.ogl.db.udb[player.uid].pin; } }); } openPinnedDetail(id, update) { id = parseInt(id), this.ogl._ui.openSide(Util.addDom("div", { class: "ogl_loading" }), id); let updateSide = () => { let player = this.ogl.db.udb[id]; if (player) { var container = Util.addDom("div", { class: "ogl_pinDetail" }), title = (Util.addDom("div", { parent: container, class: "material-icons ogl_back", child: "arrow_back", onclick: () => { this.openPinned(); } }), Util.addDom("h2", { class: player.status || "status_abbr_active", parent: container, child: player.name })), score = Util.addDom("div", { class: "ogl_score", parent: container }), actions = Util.addDom("div", { class: "ogl_actions", parent: container }); let list = Util.addDom("div", { class: "ogl_list", parent: container }); this.ogl._ui.addPinButton(title, id); var writeIcon = Util.addDom("div", { child: "edit", class: "material-icons ogl_button", parent: actions, onclick: () => { document.querySelector("#chatBar") || (window.location.href = `https://${window.location.host}/game/index.php?page=chat&playerId=` + id); } }), writeIcon = ( document.querySelector("#chatBar") && (writeIcon.classList.add("js_openChat"), writeIcon.setAttribute("data-playerId", id)), Util.addDom("a", { child: "account-plus", class: "material-icons ogl_button overlay", parent: container.querySelector(".ogl_actions"), href: `https://${window.location.host}/game/index.php?page=ingame&component=buddies&action=7&id=${id}&ajax=1`, onclick: () => { tippy.hideAll(); } }), Util.addDom("div", { child: "block", class: "material-icons ogl_button", parent: actions, onclick: () => { window.location.href = `https://${window.location.host}/game/index.php?page=ignorelist&action=1&id=` + id; } }), Util.addDom("div", { child: "query_stats", class: "material-icons ogl_button", parent: actions, onclick: () => { window.open(Util.genMmorpgstatLink(this.ogl, id), "_blank"); } }), Util.addDom("div", { child: "ptre", class: "material-icons ogl_button", parent: actions, onclick: () => { this.ogl.PTRE.getPlayerInfo({ name: player.name, id: id }); } }), Util.addDom("div", { child: "sync", class: "material-icons ogl_button", parent: actions, onclick: () => { this.ogl.PTRE.getPlayerPositions({ name: player.name, id: id }); } }), this.ogl.db.lastPinnedList = Array.from(new Set([ id, ...this.ogl.db.lastPinnedList ].map(Number))), 30 < this.ogl.db.lastPinnedList.length && (this.ogl.db.lastPinnedList.length = 30), update || (Util.addDom("div", { class: "ogl_loading", parent: container }), this.ogl._ui.openSide(container, id), this.ogl.PTRE.getPlayerPositions({ name: player.name, id: id })), Math.max(1, Math.ceil((player.score?.globalRanking || 100) / 100))), actions = Util.addDom("a", { class: "ogl_ranking", href: `https://${window.location.host}/game/index.php?page=highscore&site=${writeIcon}&searchRelId=` + player.uid, child: "#" + player.score?.globalRanking || "?" }); title.innerHTML = player.name + " " + actions.outerHTML, this.ogl._ui.addPinButton(title, id), score.innerHTML = ` <div class="ogl_line"><i class="material-icons">trending_up</i><div>${Util.formatNumber(player.score?.global)}</div></div> <div class="ogl_line"><i class="material-icons">diamond</i><div>${Util.formatNumber(player.score?.economy)}</div></div> <div class="ogl_line"><i class="material-icons">science</i><div>${Util.formatNumber(player.score?.research)}</div></div> <div class="ogl_line"><i class="material-icons">genetics</i><div>${Util.formatNumber(player.score?.lifeform)}</div></div> <div class="ogl_line"><i class="material-icons">rocket_launch</i><div>${Util.formatNumber(Util.getPlayerScoreFD(player.score, "fleet"))}</div></div> <div class="ogl_line"><i class="material-icons">security</i><div>${Util.formatNumber(Util.getPlayerScoreFD(player.score, "defense"))}</div></div> `; let lastCoords = 0, group = 1, index = 1; player.planets.sort((a, b) => Util.coordsToID(a) - Util.coordsToID(b)).forEach(planetID => { var date, dateDiff, hourDiff, line, newCoords, planetID = this.ogl.db.pdb[planetID]; planetID && (date = new Date(planetID.api), dateDiff = Math.floor((serverTime.getTime() - date) / 864e5), hourDiff = Math.round((serverTime.getTime() - date % 864e5) % 36e5 / 6e4), line = Util.addDom("div", { parent: list }), planetID.home && line.classList.add("ogl_home"), newCoords = Util.coordsToID(planetID.coo).slice(0, -3), lastCoords === newCoords ? line.setAttribute("data-group", group) : line.previousElementSibling?.getAttribute("data-group") && group++, lastCoords = newCoords, Util.addDom("div", { child: index, parent: line }), Util.addDom("div", { child: planetID.coo, parent: line, "data-galaxy": planetID.coo }), Util.addDom("div", { class: "tooltip", title: "Debris<br>" + Util.formatNumber(planetID.debris || 0), child: Util.formatToUnits(planetID.debris || 0), parent: line }), this.ogl._ui.addSpyIcons(line, planetID.coo.split(":"), !1, !0), newCoords = dateDiff || 0 === dateDiff ? 0 < dateDiff ? "" + dateDiff + LocalizationStrings.timeunits.short.hour + " ago" : "" + hourDiff + LocalizationStrings.timeunits.short.minute + " ago" : "?", planetID = Util.addDom("date", { class: "tooltipLeft", child: newCoords, title: `<span>${date.toLocaleDateString("de-DE", { day: "2-digit", month: "2-digit", year: "numeric" })}</span> <span>${date.toLocaleTimeString("de-DE")}</span>`, parent: line }), 5 <= dateDiff ? planetID.classList.add("ogl_danger") : 3 <= dateDiff && planetID.classList.add("ogl_warning"), index += 1); }), this.ogl._ui.openSide(container, id), setTimeout(() => this.ogl._shortcut.load(), 50), this.ogl._galaxy.checkCurrentSystem(); } }; Util.runAsync(() => { this.ogl._fetch.fetchPlayerAPI(id, !1, () => updateSide()); }); } openTagged(buttonSource) { this.ogl._ui.openSide(Util.addDom("div", { class: "ogl_loading" }), "tagged"), Util.runAsync(() => { var container = Util.addDom("div", { class: "ogl_tagged", child: '<h2>Tagged planets<i class="material-icons">stroke_full</i></h2>' }); let tabs = Util.addDom("div", { class: "ogl_tabs ogl_tagSelector material-icons", parent: container }); var inputs = Util.addDom("div", { class: "ogl_actions", parent: container }); Util.addDom("hr", { parent: container }); let list = Util.addDom("div", { class: "ogl_list", parent: container, child: '<p class="ogl_emptyList">Select a galaxy/system range</p>' }), buildList = () => { var start = Util.coordsToID(`${gStart.value}:${sStart.value}:000`), end = Util.coordsToID(`${gEnd.value}:${sEnd.value}:000`), start = this.getTaggedItems(start, end); if (list.innerText = "", start.length < 1) Util.addDom("p", { child: "No result", parent: list }); else { let nextTargetFound = !1, newList = []; start.forEach((item, index) => { let coords = item.match(/.{1,3}/g).map(Number).join(":"); var item = Util.coordsToID(coords), line = Util.addDom("div", { parent: list }); Util.addDom("div", { child: index + 1, parent: line }), Util.addDom("div", { child: coords, "data-galaxy": coords, parent: line }); let target = Util.addDom("div", { class: "material-icons tooltip ogl_nextQuickTarget", title: "Select as next quick raid target", child: "swords", parent: line, onclick: () => { var start = Util.coordsToID(coords), end = Util.coordsToID(`${gEnd.value}:${sEnd.value}:000`); this.getTaggedItems(start, end, !0), this.ogl.db.quickRaidList = this.tmpRaidList, this.ogl._notification.addToQueue(`You can now use [${this.ogl.db.options.keyboardActions.quickRaid}] on fleet page to attack next target`, !0), setTimeout(() => this.ogl._shortcut.load(), 50), list.querySelectorAll(".ogl_nextQuickTarget.ogl_active").forEach(e => e.classList.remove("ogl_active")), target.classList.add("ogl_active"); } }); this.ogl.db.quickRaidList && this.ogl.db.quickRaidList?.[0] == item && (target.classList.add("ogl_active"), nextTargetFound = !0), nextTargetFound && newList.push(item), this.ogl._ui.addSpyIcons(line, coords), this.ogl._ui.addTagButton(line, coords); }), this.ogl.db.quickRaidList = nextTargetFound ? newList : []; } }; Object.keys(this.ogl.db.tags).forEach(tag => { if ("none" != tag) { let tab = Util.addDom("div", { parent: tabs, "data-tag": tag, onclick: () => { this.ogl.db.tags[tag] ? (this.ogl.db.tags[tag] = !1, tab.classList.add("ogl_off")) : (this.ogl.db.tags[tag] = !0, tab.classList.remove("ogl_off")); } }); this.ogl.db.tags[tag] || tab.classList.add("ogl_off"); } }); var currentCoords = this.ogl.currentPlanet.obj.coords.split(":"); let gStart = Util.addDom("input", { type: "text", min: "1", max: "10", parent: inputs, value: this.ogl.db.lastTaggedInput[0] || currentCoords[0], onblur: e => e.target.value = e.target.value || 1, oninput: () => saveInput() }), sStart = Util.addDom("input", { type: "text", min: "1", max: "499", parent: inputs, value: this.ogl.db.lastTaggedInput[1] || currentCoords[1], onblur: e => e.target.value = e.target.value || 1, oninput: () => saveInput() }), gEnd = (Util.addDom("div", { class: "material-icons", child: "arrow_right_alt", parent: inputs }), Util.addDom("input", { type: "text", min: "1", max: "10", parent: inputs, value: this.ogl.db.lastTaggedInput[2] || 1, onblur: e => e.target.value = e.target.value || 1, oninput: () => saveInput() })), sEnd = Util.addDom("input", { type: "text", min: "1", max: "499", parent: inputs, value: this.ogl.db.lastTaggedInput[3] || 1, onblur: e => e.target.value = e.target.value || 1, oninput: () => saveInput() }), ignoreNoobButton = Util.addDom("label", { class: "status_abbr_noob", parent: inputs, child: this.ogl._lang.find("noob") + '<input class="ogl_hidden" type="checkbox">', onclick: () => { setTimeout(() => { this.ogl.db.lastTaggedInput[4] = ignoreNoobButton.querySelector("input").checked, this.ogl.db.lastTaggedInput[4] ? ignoreNoobButton.classList.remove("ogl_off") : ignoreNoobButton.classList.add("ogl_off"), buildList(); }, 50); } }), ignoreVacationButton = Util.addDom("label", { class: "status_abbr_vacation", parent: inputs, child: this.ogl._lang.find("vacation") + '<input class="ogl_hidden" type="checkbox">', onclick: () => { setTimeout(() => { this.ogl.db.lastTaggedInput[5] = ignoreVacationButton.querySelector("input").checked, this.ogl.db.lastTaggedInput[5] ? ignoreVacationButton.classList.remove("ogl_off") : ignoreVacationButton.classList.add("ogl_off"), buildList(); }, 50); } }), saveInput = (Util.addDom("div", { class: "material-icons ogl_button", parent: inputs, child: "search", onclick: () => buildList() }), this.ogl.db.lastTaggedInput[0] && this.ogl.db.lastTaggedInput[1] && this.ogl.db.lastTaggedInput[2] && this.ogl.db.lastTaggedInput[3] && buildList(), this.ogl.db.lastTaggedInput[4] ? ignoreNoobButton.querySelector("input").checked = !0 : ignoreNoobButton.classList.add("ogl_off"), this.ogl.db.lastTaggedInput[5] ? ignoreVacationButton.querySelector("input").checked = !0 : ignoreVacationButton.classList.add("ogl_off"), () => { this.timeout && clearTimeout(this.timeout), this.ogl.db.lastTaggedInput[0] = gStart.value, this.ogl.db.lastTaggedInput[1] = sStart.value, this.ogl.db.lastTaggedInput[2] = gEnd.value, this.ogl.db.lastTaggedInput[3] = sEnd.value; }); return container; }).then(container => { this.ogl._ui.openSide(container, "tagged", buttonSource), setTimeout(() => this.ogl._shortcut.load(), 50); }); } getTaggedItems(rawStart, rawEnd, newFlag) { rawStart = parseInt(rawStart), rawEnd = parseInt(rawEnd); let displayNoob = this.ogl.db.lastTaggedInput[4], displayVacation = this.ogl.db.lastTaggedInput[5]; return newFlag || (rawStart <= rawEnd ? rawEnd += 15 : rawStart += 15), this.tmpRaidList = Object.keys(this.ogl.db.tdb).sort((a, b) => rawStart <= rawEnd ? a - b : b - a).filter(position => { var coords = position.match(/.{1,3}/g).map(Number).join(":"), coords = this.ogl.db.udb[this.ogl.db.pdb[coords]?.uid]?.status; return this.ogl.db.tags[this.ogl.db.tdb[position].tag] && (rawStart <= rawEnd ? rawStart <= position && position <= rawEnd : position <= rawStart && rawEnd <= position) && (displayNoob || !coords || !displayNoob && coords?.indexOf("n") < 0) && (displayVacation || !coords || !displayVacation && coords?.indexOf("v") < 0 && coords?.indexOf("b") < 0); }), this.tmpRaidList; } checkUpgrade() { this.PlanetBuildingtooltip = this.PlanetBuildingtooltip || {}, document.querySelectorAll(".planetlink, .moonlink").forEach(planet => { planet.querySelector(".ogl_buildIconList") && planet.querySelector(".ogl_buildIconList").remove(); let id = new URLSearchParams(planet.getAttribute("href")).get("cp").split("#")[0]; planet.classList.contains("moonlink"); this.PlanetBuildingtooltip[id] = Util.addDom("ul", { class: "ogl_buildList" }); let hasBaseBuilding = !1, hasBaseShip = !1, hasLFBuilding = !1; this.ogl.db.myPlanets[id] = this.ogl.db.myPlanets[id] || {}, Object.values(this.ogl.db.myPlanets[id].upgrades || {}).forEach(upgradeType => { let ready = !1; upgradeType?.id || upgradeType.forEach(upgrade => { serverTime.getTime() < upgrade.end && (ready || (ready = !0, Util.addDom("li", { parent: this.PlanetBuildingtooltip[id], child: `<i class="material-icons">fiber_manual_record</i><span class="ogl_slidingText" data-text="${upgrade.name}"></span><i class="material-icons">east</i><b>${upgrade.lvl}</b>` }), "baseBuilding" == upgrade.type || "baseResearch" == upgrade.type ? hasBaseBuilding = !0 : "ship" == upgrade.type || "def" == upgrade.type || "mechaShip" == upgrade.type ? hasBaseShip = !0 : "lfBuilding" != upgrade.type && "lfResearch" != upgrade.type || (hasLFBuilding = !0))); }); }); planet = Util.addDom("div", { class: "ogl_buildIconList", parent: planet }); hasBaseBuilding && Util.addDom("div", { class: "ogl_buildIcon material-icons", child: "stat_0", parent: planet }), hasBaseShip && Util.addDom("div", { class: "ogl_buildIcon ogl_baseShip material-icons", child: "stat_0", parent: planet }), hasLFBuilding && Util.addDom("div", { class: "ogl_buildIcon ogl_lfBuilding material-icons", child: "stat_0", parent: planet }); }); } } class FleetManager extends Manager { load() { if (this.validationReady = !0, this.miniFleetQueue = [], this.updateSpyFunctions(), "fleetdispatch" == this.ogl.page) { this.totalCapacity = 0, this.capacityWrapper = Util.addDom("div", { class: "capacityProgress", parent: document.querySelector("#fleet1 .content"), onclick: () => document.querySelector(".ogl_requiredShips .ogl_" + this.ogl.db.options.defaultShip).click() }), this.capacityBar = Util.addDom("progress", { "data-capacity": "", max: 100, value: 0, parent: this.capacityWrapper }), this.resOnPlanet = { metal: "metalOnPlanet", crystal: "crystalOnPlanet", deut: "deuteriumOnPlanet", food: "foodOnPlanet" }, this.cargo = { metal: "cargoMetal", crystal: "cargoCrystal", deut: "cargoDeuterium", food: "cargoFood" }, this.initialTarget = JSON.parse(JSON.stringify(targetPlanet)); let initInterval = setInterval(() => { var params; unsafeWindow.fleetDispatcher && (this.setRealTarget(this.initialTarget), fleetDispatcher.targetPlanet = fleetDispatcher.realTarget, this.initialResOnPlanet = { metal: fleetDispatcher.metalOnPlanet, crystal: fleetDispatcher.crystalOnPlanet, deut: fleetDispatcher.deuteriumOnPlanet, food: fleetDispatcher.foodOnPlanet }, this.initialShipsOnPlanet = JSON.parse(JSON.stringify(fleetDispatcher.shipsOnPlanet)), this.overwrited || this.overwrite(), fleetDispatcher.fetchTargetPlayerDataTimeout || (unsafeWindow.shipsData && fleetDispatcher?.fleetHelper?.shipsData ? (this.init(), clearInterval(initInterval)) : (params = {}, fleetDispatcher.appendShipParams(params), fleetDispatcher.appendTargetParams(params), fleetDispatcher.appendTokenParams(params), params.union = fleetDispatcher.union, $.post(fleetDispatcher.checkTargetUrl, params, response => { response = JSON.parse(response); fleetDispatcher.fleetHelper.shipsData = response.shipsData, fleetDispatcher.updateToken(response.newAjaxToken), this.init(), clearInterval(initInterval); })))); }, 50); } } overwrite() { this.overwrited = !0, fleetDispatcher.fleetHelper.getShipData = shipID => fleetDispatcher?.fleetHelper?.shipsData?.[shipID] || shipsData[shipID], fleetDispatcher.refreshDataAfterAjax = data => { let ownPlanet = Object.values(ogl.db.myPlanets).find(e => e.coords == `${data.targetPlanet.galaxy}:${data.targetPlanet.system}:` + data.targetPlanet.position); fleetDispatcher.setOrders(data.orders), fleetDispatcher.mission = 0, fleetDispatcher.setTargetInhabited(data.targetInhabited), fleetDispatcher.setTargetPlayerId(data.targetPlayerId), fleetDispatcher.setTargetPlayerName(data.targetPlayerName), fleetDispatcher.setTargetIsStrong(data.targetIsStrong), fleetDispatcher.setTargetIsOutlaw(data.targetIsOutlaw), fleetDispatcher.setTargetIsBuddyOrAllyMember(data.targetIsBuddyOrAllyMember), fleetDispatcher.setTargetPlayerColorClass(data.targetPlayerColorClass), fleetDispatcher.setTargetPlayerRankIcon(data.targetPlayerRankIcon), fleetDispatcher.setPlayerIsOutlaw(data.playerIsOutlaw), fleetDispatcher.targetPlanet.galaxy = data.targetPlanet.galaxy, fleetDispatcher.targetPlanet.system = data.targetPlanet.system, fleetDispatcher.targetPlanet.position = data.targetPlanet.position, fleetDispatcher.targetPlanet.type = data.targetPlanet.type, fleetDispatcher.targetPlanet.name = data.targetPlanet.name, this.setRealTarget(JSON.parse(JSON.stringify(fleetDispatcher.targetPlanet))), !data.targetOk && this.isQuickRaid && this.ogl.db.quickRaidList.shift(), setTimeout(() => { var hasMission = -1 < (fleetDispatcher.getAvailableMissions() || []).indexOf(fleetDispatcher.mission); !hasMission && this.lastMissionOrder && -1 < (fleetDispatcher.getAvailableMissions() || []).indexOf(this.lastMissionOrder) ? fleetDispatcher.mission = this.lastMissionOrder : ownPlanet ? hasMission || "fleet2" != fleetDispatcher.currentPage || 1 != (fleetDispatcher.getAvailableMissions() || []).length ? !hasMission && -1 < (fleetDispatcher.getAvailableMissions() || []).indexOf(this.ogl.db.options.defaultMission) ? fleetDispatcher.mission = this.ogl.db.options.defaultMission : hasMission && (fleetDispatcher.mission = this.lastMissionOrder) : fleetDispatcher.mission = fleetDispatcher.getAvailableMissions()[0] : 2 == data.targetPlanet.type ? fleetDispatcher.mission = 8 : fleetDispatcher.union ? fleetDispatcher.mission = 2 : fleetDispatcher.mission = 1, fleetDispatcher.refresh(); }, 50), 0 < fleetDispatcher.cargoMetal + fleetDispatcher.cargoCrystal + fleetDispatcher.cargoDeuterium && JSON.stringify(fleetDispatcher.realTarget) == JSON.stringify(fleetDispatcher.currentPlanet) && this.setRealTarget(fleetDispatcher.realTarget, { type: 1 == fleetDispatcher.realTarget.type ? 3 : 1 }); }, fleetDispatcher.selectShip = (shipId, number) => { var shipsAvailable = fleetDispatcher.getNumberOfShipsOnPlanet(shipId), input = document.querySelector(`[data-technology="${shipId}"] input`); 0 === shipsAvailable || shipsAvailable < number && ! document.querySelector(`[data-technology="${shipId}"]`)?.classList.contains("ogl_notEnough") ? input?.classList.add("ogl_flashNotEnough") : input.classList.remove("ogl_flashNotEnough"), (number = Math.min(shipsAvailable, number)) <= 0 ? fleetDispatcher.removeShip(shipId) : fleetDispatcher.hasShip(shipId) ? fleetDispatcher.updateShip(shipId, number) : fleetDispatcher.addShip(shipId, number), Util.formatInput(input, !1, !0), fleetDispatcher.refresh(); }, fleetDispatcher.trySubmitFleet1 = () => { "fleet1" == fleetDispatcher.currentPage && (fleetDispatcher.targetPlanet = fleetDispatcher.realTarget, !1 === fleetDispatcher.validateFleet1() ? this.validationReady = !0 : fleetDispatcher.switchToPage("fleet2")); }, Util.overWrite("refresh", fleetDispatcher, !1, () => { var totalResources = fleetDispatcher.metalOnPlanet + fleetDispatcher.crystalOnPlanet + fleetDispatcher.deuteriumOnPlanet + fleetDispatcher.foodOnPlanet, percentCapacity = (this.totalCapacity = this.totalCapacity || 1, Math.floor(fleetDispatcher.getCargoCapacity() / this.totalCapacity * 100) || 0), percentResources = Math.floor(fleetDispatcher.getCargoCapacity() / totalResources * 100) || 0, percentRequired = Math.floor(totalResources / this.totalCapacity * 100) || 0, percentRequired = (this.capacityBar.style.setProperty("--capacity", `linear-gradient(to right, #641717, #938108 ${.8 * percentRequired}%, #055c54 ${percentRequired}%)`), this.capacityWrapper.style.setProperty("--currentCapacityPercent", Math.min(94, percentCapacity) + "%"), this.capacityWrapper.setAttribute("data-percentResources", Math.min(100, percentResources)), this.capacityWrapper.setAttribute("data-rawCargo", `${Util.formatNumber(fleetDispatcher.getCargoCapacity())} / ${Util.formatNumber(this.totalCapacity)} - (req. ${Util.formatNumber(totalResources)})`), this.capacityBar.setAttribute("max", 100), this.capacityBar.setAttribute("value", percentCapacity), document.querySelector(".show_fleet_apikey")); percentRequired && (percentRequired.classList.add("tooltipClose"), percentRequired.classList.add("tooltipClick")), this.ogl._time.timeLoop && this.ogl._time.timeLoop(!0); }), Util.overWrite("updateTarget", fleetDispatcher, () => { document.querySelector("#planetList").classList.add("ogl_notReady"); }), fleetDispatcher.hasEnoughFuel = () => (this.initialResOnPlanet?.deut || fleetDispatcher.deuteriumOnPlanet) >= fleetDispatcher.getConsumption(), Util.overWrite("selectMission", fleetDispatcher, !1, () => { this.lastMissionOrder = fleetDispatcher.mission, document.querySelector("#fleet2").setAttribute("data-selected-mission", fleetDispatcher.mission); }), Util.overWrite("switchToPage", fleetDispatcher, () => { fleetDispatcher.getFreeCargoSpace() < 0 && fleetDispatcher.cargoFood && (fleetDispatcher.selectMinFood(), fleetDispatcher.selectMaxFood()), fleetDispatcher.getFreeCargoSpace() < 0 && fleetDispatcher.cargoMetal && (fleetDispatcher.selectMinMetal(), fleetDispatcher.selectMaxMetal()), fleetDispatcher.getFreeCargoSpace() < 0 && fleetDispatcher.cargoCrystal && (fleetDispatcher.selectMinCrystal(), fleetDispatcher.selectMaxCrystal()), fleetDispatcher.getFreeCargoSpace() < 0 && fleetDispatcher.cargoDeuterium && (fleetDispatcher.selectMinDeuterium(), fleetDispatcher.selectMaxDeuterium()); }, () => { "fleet2" == fleetDispatcher.currentPage ? (document.body.classList.add("ogl_destinationPicker"), fleetDispatcher.focusSendFleet()) : "fleet1" == fleetDispatcher.currentPage && (document.body.classList.remove("ogl_destinationPicker"), fleetDispatcher.focusSubmitFleet1()); }), Util.overWrite("stopLoading", fleetDispatcher, () => { "fleet2" == fleetDispatcher.currentPage && (this.validationReady = !0); }), fleetDispatcher.submitFleet2 = force => { if (this.sent) return !0; this.sent = !0, fleetDispatcher.realTarget && (fleetDispatcher.targetPlanet.galaxy = fleetDispatcher.realTarget.galaxy, fleetDispatcher.targetPlanet.system = fleetDispatcher.realTarget.system, fleetDispatcher.targetPlanet.position = fleetDispatcher.realTarget.position, fleetDispatcher.targetPlanet.type = fleetDispatcher.realTarget.type, fleetDispatcher.targetPlanet.name = fleetDispatcher.realTarget.name, fleetDispatcher.refresh()), fleetDispatcher.realSpeedPercent && (fleetDispatcher.speedPercent = fleetDispatcher.realSpeedPercent), force = force || !1; let self = this, that = fleetDispatcher; var params = {}; self.ajaxSuccess || (fleetDispatcher.appendTokenParams(params), fleetDispatcher.appendShipParams(params), fleetDispatcher.appendTargetParams(params), fleetDispatcher.appendCargoParams(params), fleetDispatcher.appendPrioParams(params), params.mission = fleetDispatcher.mission, params.speed = fleetDispatcher.speedPercent, params.retreatAfterDefenderRetreat = !0 === fleetDispatcher.retreatAfterDefenderRetreat ? 1 : 0, params.lootFoodOnAttack = !0 === fleetDispatcher.lootFoodOnAttack ? 1 : 0, params.union = fleetDispatcher.union, force && (params.force = force), params.holdingtime = fleetDispatcher.getHoldingTime(), fleetDispatcher.startLoading(), $.post(fleetDispatcher.sendFleetUrl, params, function(response) { response = JSON.parse(response); !0 === response.success ? (fadeBox(response.message, !1), $("#sendFleet").removeAttr("disabled"), self.fleetSent(response.redirectUrl)) : (setTimeout(() => self.sent = !1, 500), response.responseArray && response.responseArray.limitReached && !response.responseArray.force ? (that.updateToken(response.newAjaxToken || ""), errorBoxDecision(that.loca.LOCA_ALL_NETWORK_ATTENTION, that.locadyn.localBashWarning, that.loca.LOCA_ALL_YES, that.loca.LOCA_ALL_NO, function() { that.submitFleet2(!0); })) : (that.displayErrors(response.errors), that.updateToken(response.newAjaxToken || ""), $("#sendFleet").removeAttr("disabled"), that.stopLoading())); })); }, Util.overWrite("refreshTargetPlanet", fleetDispatcher, () => { if (fleetDispatcher.union) { fleetDispatcher.mission = 2, fleetDispatcher.refresh(); let acsEndTime = 1e3 * (Object.values(fleetDispatcher.unions).find(a => a.id == fleetDispatcher.union)?.time || 0); if (acsEndTime) { if ( document.querySelector(".ogl_acsInfo")) return; Util.addDom("hr", { prepend: document.querySelector("#fleetBriefingPart1") }); var liMax = Util.addDom("li", { class: "ogl_acsInfo", child: "Allowed max. duration:", prepend: document.querySelector("#fleetBriefingPart1") }), liOffset = Util.addDom("li", { class: "ogl_acsInfo", child: "ACS offset:", prepend: document.querySelector("#fleetBriefingPart1") }); let spanMax = Util.addDom("span", { class: "ogl_warning value", parent: liMax }), spanOffset = Util.addDom("span", { class: "value", parent: liOffset }); clearInterval(this.acsInterval), this.acsInterval = setInterval(() => { var fleetDurationLeft, acsDurationLeft, acsDurationTreshold, delta; fleetDispatcher.getDuration() && (fleetDurationLeft = 1e3 * fleetDispatcher.getDuration(), acsDurationTreshold = .3 * (acsDurationLeft = acsEndTime - serverTime.getTime() - 1e3 * timeZoneDiffSeconds), delta = fleetDurationLeft - acsDurationLeft, spanOffset.className = "value", acsDurationLeft + acsDurationTreshold < fleetDurationLeft ? (spanOffset.textContent = " too late", spanOffset.classList.add("ogl_danger")) : acsDurationLeft < fleetDurationLeft ? (spanOffset.textContent = " +" + new Date(delta).toISOString().slice(11, 19), spanOffset.classList.add("ogl_warning")) : (spanOffset.textContent = " +00:00:00", spanOffset.classList.add("ogl_ok")), spanMax.textContent = " " + new Date(acsDurationLeft + acsDurationTreshold).toISOString().slice(11, 19)); }, 333); } } fleetDispatcher.mission || ((liMax = new URLSearchParams(window.location.search)).get("mission") ? fleetDispatcher.mission = liMax.get("mission") : fleetDispatcher.mission = this.ogl.db.options.defaultMission, fleetDispatcher.refresh()); }); } init() { if (this.isReady = !0, document.querySelector(".planetlink.active, .moonlink.active")?.classList.add("ogl_disabled"), this.addLimiters(), 1 === this.ogl.mode || 2 === this.ogl.mode || 5 === this.ogl.mode ? this.prepareRedirection() : 3 === this.ogl.mode && this.ogl.cache.toSend ? this.prefillTodolistCargo() : this.ogl.db.harvestCoords = void 0, ! document.querySelector("#fleet1 #warning")) { if (this.updateSpeedBar(), this.ogl.shipsList.forEach(shipID => { var data, tech; fleetDispatcher.fleetHelper.shipsData?.[shipID] && (data = fleetDispatcher.fleetHelper.shipsData[shipID], tech = document.querySelector(`[data-technology="${shipID}"]`), this.ogl.db.shipsCapacity[shipID] = data.cargoCapacity || data.baseCargoCapacity, tech) && tech.setAttribute("title", ` <div class="ogl_shipDataInfo"> <div class="ogl_icon ogl_${shipID}">${data.name}</div><hr> <i class="material-icons">send</i> Amount : <b>${Util.formatNumber(parseInt(tech.querySelector(".amount").getAttribute("data-value")))}</b><br> <i class="material-icons">package-variant-closed</i> Capacity : <b>${Util.formatNumber(data.cargoCapacity || data.baseCargoCapacity)}</b><br> <i class="material-icons">mode_heat</i> Consumption : <b>${Util.formatNumber(data.fuelConsumption)}</b><br> <i class="material-icons">speed</i> Speed : <b>${Util.formatNumber(data.speed)}</b> </div> `); }), fleetDispatcher.selectMission(parseInt(fleetDispatcher.mission) || parseInt(this.ogl.db.options.defaultMission)), fleetDispatcher.speedPercent = fleetDispatcher.speedPercent || 10, fleetDispatcher.realSpeedPercent = fleetDispatcher.speedPercent, 1 === this.ogl.mode || 2 === this.ogl.mode ? (fleetDispatcher.selectShip(this.ogl.db.options.defaultShip, this.shipsForResources()), fleetDispatcher.selectMaxAll()) : 5 === this.ogl.mode && fleetDispatcher.expeditionCount < fleetDispatcher.maxExpeditionCount && this.selectExpedition(this.ogl.db.lastExpeditionShip || this.ogl.db.options.defaultShip), 8 == fleetDispatcher.mission && (fleetDispatcher.targetPlanet.type = 2), fleetDispatcher.refresh(), fleetDispatcher.focusSubmitFleet1(), document.querySelector(".secondcol")) { Util.runAsync(() => { document.querySelector("#sendall").classList.add("material-icons"), document.querySelector("#sendall").innerText = "chevron-double-right", document.querySelector("#resetall").classList.add("material-icons"), document.querySelector("#resetall").innerText = "exposure_zero"; }); let sender = Util.addDom("div", { title: "loading...", child: "cube-send", class: "material-icons tooltipRight tooltipClose tooltipClick tooltipUpdate", parent: document.querySelector(".secondcol"), ontooltip: () => { let container = Util.addDom("div", { class: "ogl_resourcesPreselection" }), resources = [ "metal", "crystal", "deut", "food" ]; resources.forEach(resourceName => { var item = Util.addDom("div", { class: "ogl_icon ogl_" + resourceName, parent: container, onclick: () => { input.value = input.value == fleetDispatcher[this.resOnPlanet[resourceName]] ? 0 : fleetDispatcher[this.resOnPlanet[resourceName]], fleetDispatcher[this.cargo[resourceName]] = input.value, input.dispatchEvent(new Event("input")); } }); let input = Util.addDom("input", { type: "text", parent: item, onclick: e => { e.stopPropagation(); }, oninput: () => { Util.formatInput(input, () => { input.value = Math.min(fleetDispatcher[this.resOnPlanet[resourceName]], parseInt(input.value.replace(/\D/g, "")) || 0), fleetDispatcher[this.cargo[resourceName]] = input.value, input.value = parseInt(input.value.replace(/\D/g, "") || 0).toLocaleString("fr-FR"); }); } }); }), Util.addDom("hr", { parent: container }), Util.addDom("div", { class: "ogl_button ogl_formValidation", child: "OK", parent: container, onclick: () => { let total = 0; container.querySelectorAll("input").forEach(input => { total += parseInt(input.value.replace(/\D/g, "")) || 0; }), 0 < total && fleetDispatcher.selectShip(this.ogl.db.options.defaultShip, this.shipsForResources(!1, total)), container.querySelectorAll("input").forEach((input, index) => fleetDispatcher[this.cargo[resources[index]]] = parseInt(input.value.replace(/\D/g, "") || 0)), fleetDispatcher.refresh(), setTimeout(() => fleetDispatcher.focusSubmitFleet1(), 50), tippy.hideAll(); } }), sender._tippy ? sender._tippy.setContent(container) : this.ogl._tooltip.update(container), setTimeout(() => container.querySelector("input").focus(), 100); } }); Util.addDom("div", { title: this.ogl._lang.find("fleetQuickCollect"), child: "local_shipping", class: "material-icons tooltip ogl_quickCollectBtn", parent: document.querySelector(".secondcol"), onclick: () => { document.querySelector(".ogl_requiredShips .ogl_" + this.ogl.db.options.defaultShip)?.click(); } }); } document.querySelectorAll("#fleet2 .resourceIcon").forEach(icon => { Util.addDom("div", { class: "ogl_reverse material-icons", child: "repeat", parent: icon, onclick: e => { var type = icon.classList.contains("metal") ? "metal" : icon.classList.contains("crystal") ? "crystal" : icon.classList.contains("deuterium") ? "deut" : "food"; fleetDispatcher[this.cargo[type]] = Math.min(fleetDispatcher[this.resOnPlanet[type]] - fleetDispatcher[this.cargo[type]], fleetDispatcher.getFreeCargoSpace()), fleetDispatcher.refresh(); } }); }), this.ogl.mode || (this.hasBeenInitialized = !0); } } setRealTarget(obj, forceParam) { obj.galaxy = forceParam?.galaxy || obj.galaxy, obj.system = forceParam?.system || obj.system, obj.position = forceParam?.position || obj.position, obj.type = forceParam?.type || obj.type, obj.name = forceParam?.name || obj.name, fleetDispatcher.realTarget = obj, document.querySelector("#galaxy").value = fleetDispatcher.realTarget.galaxy, document.querySelector("#system").value = fleetDispatcher.realTarget.system, document.querySelector("#position").value = fleetDispatcher.realTarget.position, fleetDispatcher.targetPlanet.galaxy = fleetDispatcher.realTarget.galaxy, fleetDispatcher.targetPlanet.system = fleetDispatcher.realTarget.system, fleetDispatcher.targetPlanet.position = fleetDispatcher.realTarget.position, fleetDispatcher.targetPlanet.type = fleetDispatcher.realTarget.type, document.querySelectorAll(".smallplanet").forEach(planet => { var coords = planet.querySelector(".planet-koords").innerText.split(":"); planet.querySelector(".ogl_currentDestination")?.classList.remove("ogl_currentDestination"), fleetDispatcher.realTarget.galaxy == coords[0] && fleetDispatcher.realTarget.system == coords[1] && fleetDispatcher.realTarget.position == coords[2] && (coords = 1 == fleetDispatcher.realTarget.type ? planet.querySelector(".planetlink") : 3 == fleetDispatcher.realTarget.type && planet.querySelector(".moonlink")) && coords.classList.add("ogl_currentDestination"); }); } fleetSent(defaultRedirection) { if (!this.ajaxSuccess) { this.ajaxSuccess = !0, this.ogl.db.previousFleet = {}, this.ogl.db.previousFleet.shipsToSend = fleetDispatcher.shipsToSend, this.ogl.db.previousFleet.speedPercent = fleetDispatcher.speedPercent, this.ogl.db.previousFleet.targetPlanet = JSON.parse(JSON.stringify(fleetDispatcher.targetPlanet)), this.ogl.db.previousFleet.mission = fleetDispatcher.mission, this.ogl.db.previousFleet.expeditionTime = fleetDispatcher.expeditionTime, this.ogl.db.previousFleet.cargoMetal = fleetDispatcher.cargoMetal, this.ogl.db.previousFleet.cargoCrystal = fleetDispatcher.cargoCrystal, this.ogl.db.previousFleet.cargoDeuterium = fleetDispatcher.cargoDeuterium, this.ogl.db.previousFleet.cargoFood = fleetDispatcher.cargoFood; var conso = parseInt(parseFloat(fleetDispatcher.getConsumption() || 0)), stats = (this.ogl.currentPlanet.obj.metal -= Math.min(this.initialResOnPlanet.metal, fleetDispatcher.cargoMetal), this.ogl.currentPlanet.obj.crystal -= Math.min(this.initialResOnPlanet.crystal, fleetDispatcher.cargoCrystal), this.ogl.currentPlanet.obj.deut -= Math.min(this.initialResOnPlanet.deut, fleetDispatcher.cargoDeuterium + conso), this.ogl.currentPlanet.obj.food -= Math.min(this.initialResOnPlanet.food, fleetDispatcher.cargoFood), this.ogl._stats.getDayStats(serverTime.getTime())); if (stats.conso = (stats.conso || 0) + Math.min(this.initialResOnPlanet.deut, conso), this.isQuickRaid && this.ogl.db.quickRaidList.shift(), 5 === this.ogl.mode && 15 !== fleetDispatcher.mission && this.ogl.db.options.expeditionRedirect && (this.ogl.mode = 0), 1 != this.ogl.mode && 2 != this.ogl.mode && 5 != this.ogl.mode && this.prepareRedirection(), 1 === this.ogl.mode || 2 === this.ogl.mode || 5 === this.ogl.mode && this.ogl.db.options.expeditionRedirect) this.ogl._shortcut.redirectToPlanet(1); else if (5 === this.ogl.mode) this.ogl._shortcut.redirectToPlanet(0); else if (3 === this.ogl.mode && this.ogl.cache.toSend) { let cumul = [ 0, 0, 0 ]; var stats = new URLSearchParams(window.location.search); stats.get("substractMode") && stats.get("targetid") && (conso = stats.get("targetid"), cumul[0] -= this.ogl.db.myPlanets[conso]?.metal || 0, cumul[1] -= this.ogl.db.myPlanets[conso]?.crystal || 0, cumul[2] -= this.ogl.db.myPlanets[conso]?.deut || 0), this.ogl.cache.toSend.forEach(build => { var id = new URLSearchParams(window.location.search).get("targetid"), cost = this.ogl.db.myPlanets[id].todolist[build.id][build.level].cost; for (let i = 0; i < 3; i++) { var res = 2 === i ? "deut" : 1 === i ? "crystal" : "metal", cargo = 2 == i ? "cargoDeuterium" : 1 == i ? "cargoCrystal" : "cargoMetal", cargo = Math.min(fleetDispatcher[cargo] - cumul[i], build.cost[res]); cumul[i] += cargo, cost[res] -= cargo; } build.amount && cost.metal + cost.crystal + cost.deut <= 0 && delete this.ogl.db.myPlanets[id].todolist[build.id][build.level], Object.values(this.ogl.db.myPlanets[id].todolist[build.id]).length < 1 && delete this.ogl.db.myPlanets[id].todolist[build.id]; }), window.location.href = defaultRedirection; } else 4 === this.ogl.mode ? (stats = parseInt(new URLSearchParams(window.location.search).get("oglmsg")) || 0, this.ogl.cache.reports[stats] && (this.ogl.cache.reports[stats].attacked = !0), window.location.href = this.ogl._shortcut.getRedirectionLink({ component: "messages" })) : window.location.href = defaultRedirection; this.ogl.save(); } } addLimiters() { var limiterContainer = document.querySelector("#fleetdispatchcomponent"), limiterContainer = Util.addDom("fieldset", { parent: limiterContainer }), limitResourceLabel = (Util.addDom("legend", { parent: limiterContainer, child: '<i class="material-icons">settings</i> Settings' }), Util.addDom("label", { class: "ogl_limiterLabel tooltip", "data-limiter-type": "resource", title: this.ogl._lang.find("resourceLimiter"), parent: limiterContainer, child: "Limit resources" })), limitResourceLabel = Util.addDom("input", { type: "checkbox", parent: limitResourceLabel, onclick: () => { this.ogl.db.fleetLimiter.resourceActive = !this.ogl.db.fleetLimiter.resourceActive, this.updateLimiter(); } }), limitShipLabel = Util.addDom("label", { class: "ogl_limiterLabel tooltip", "data-limiter-type": "ship", title: this.ogl._lang.find("fleetLimiter"), parent: limiterContainer, child: "Limit ships" }), limitShipLabel = Util.addDom("input", { type: "checkbox", parent: limitShipLabel, onclick: () => { this.ogl.db.fleetLimiter.shipActive = !this.ogl.db.fleetLimiter.shipActive, this.updateLimiter(); } }), limitFoodLabel = Util.addDom("label", { class: "ogl_limiterLabel tooltip", title: this.ogl._lang.find("forceIgnoreFood"), parent: limiterContainer, child: "Ignore Food" }), limitFoodLabel = Util.addDom("input", { type: "checkbox", parent: limitFoodLabel, onclick: () => { this.ogl.db.fleetLimiter.ignoreFood = !this.ogl.db.fleetLimiter.ignoreFood, this.updateLimiter(); } }); let keepLabel = Util.addDom("div", { class: "ogl_limiterGroup tooltip", title: this.ogl._lang.find("forceKeepCapacity"), parent: limiterContainer, child: 'Locked <i class="material-icons">blocked</i>' }); [ 202, 203, 219, 200 ].forEach(shipID => { let item = Util.addDom("div", { class: "ogl_icon ogl_" + shipID, parent: keepLabel, onclick: () => { keepLabel.querySelector(".ogl_active")?.classList.remove("ogl_active"), item.classList.add("ogl_active"), this.ogl.db.keepEnoughCapacityShip = shipID, this.updateLimiter(); } }); this.ogl.db.keepEnoughCapacityShip == shipID && item.classList.add("ogl_active"); }), this.ogl.db.fleetLimiter.resourceActive && (limitResourceLabel.checked = !0), this.ogl.db.fleetLimiter.shipActive && (limitShipLabel.checked = !0), this.ogl.db.fleetLimiter.ignoreFood && (limitFoodLabel.checked = !0), this.updateLimiter(); } updateLimiter() { unsafeWindow.fleetDispatcher && (this.totalCapacity = 0, fleetDispatcher.shipsOnPlanet.forEach((entry, index) => { let forced = 0; this.ogl.db.keepEnoughCapacityShip == entry.id && 1 !== this.ogl.mode && 2 !== this.ogl.mode && (forced = this.shipsForResources(entry.id)), this.ogl.db.fleetLimiter.shipActive && this.ogl.db.fleetLimiter.data[entry.id] ? entry.number = Math.max(0, this.initialShipsOnPlanet.find(e => e.id == entry.id).number - Math.max(this.ogl.db.fleetLimiter.data[entry.id], forced)) : entry.number = this.initialShipsOnPlanet.find(e => e.id == entry.id).number - forced, fleetDispatcher.shipsToSend.find(e => e.id == entry.id)?.number >= entry.number && fleetDispatcher.selectShip(entry.id, entry.number); var text, techDom = document.querySelector(`[data-technology="${entry.id}"]`); techDom && (techDom.querySelector(".ogl_maxShip")?.remove(), (text = Util.addDom("div", { class: "ogl_maxShip", parent: techDom })).innerHTML = `<b>-${Util.formatToUnits(this.ogl.db.fleetLimiter.shipActive ? Math.max(this.ogl.db.fleetLimiter.data[entry.id], forced) : forced)}</b>`, text.addEventListener("click", () => { Util.runAsync(() => this.ogl._ui.openFleetProfile()).then(e => this.ogl._popup.open(e)); }), this.ogl.db.fleetLimiter.shipActive || this.ogl.db.keepEnoughCapacityShip == entry.id || text.classList.add("ogl_hidden"), entry.number <= 0 ? (techDom.classList.add("ogl_notEnough"), fleetDispatcher.removeShip(entry.id)) : techDom.classList.remove("ogl_notEnough"), this.totalCapacity += this.ogl.db.shipsCapacity[entry.id] * entry.number), document.querySelectorAll(".ogl_flashNotEnough").forEach(e => { 0 == e.value && e.classList.remove("ogl_flashNotEnough"); }); }), [ "metal", "crystal", "deut", "food" ].forEach(resourceName => { this.ogl.db.fleetLimiter.resourceActive ? fleetDispatcher[this.resOnPlanet[resourceName]] = Math.max(0, this.initialResOnPlanet[resourceName] - (this.ogl.db.fleetLimiter.data[resourceName] || 0)) : fleetDispatcher[this.resOnPlanet[resourceName]] = Math.max(0, this.initialResOnPlanet[resourceName]), "food" == resourceName && this.ogl.db.fleetLimiter.ignoreFood && (fleetDispatcher[this.resOnPlanet[resourceName]] = 0), fleetDispatcher[this.cargo[resourceName]] = Math.min(fleetDispatcher[this.cargo[resourceName]], fleetDispatcher[this.resOnPlanet[resourceName]]); var text, techDom = document.querySelector("#fleet2 #resources ." + resourceName?.replace("deut", "deuterium")); techDom && (techDom.querySelector(".ogl_maxShip")?.remove(), (text = Util.addDom("div", { class: "ogl_maxShip", parent: techDom })).innerHTML = `<b>-${Util.formatToUnits(this.ogl.db.fleetLimiter.resourceActive ? this.ogl.db.fleetLimiter.data[resourceName] : 0, 0)}</b>`, text.addEventListener("click", () => { Util.runAsync(() => this.ogl._ui.openFleetProfile()).then(e => this.ogl._popup.open(e)); }), techDom.parentNode.querySelector("input").classList.add("ogl_inputCheck")); }), fleetDispatcher.refresh(), this.updateRequiredShips(), initTooltips()); } updateRequiredShips() { let requiredShips = document.querySelector(".ogl_requiredShips") || Util.addDom("span", { class: "ogl_requiredShips", parent: document.querySelector("#civilships #civil") || document.querySelector("#warning") }); requiredShips.innerText = "", this.ogl.fretShips.forEach(shipID => { let amount = this.shipsForResources(shipID); var item = Util.addDom("div", { class: "tooltip ogl_required ogl_icon ogl_" + shipID, title: Util.formatNumber(amount), parent: requiredShips, child: Util.formatToUnits(amount), onclick: () => { fleetDispatcher.selectShip(shipID, amount), fleetDispatcher.selectMaxAll(), fleetDispatcher.refresh(), fleetDispatcher.focusSubmitFleet1(); } }); (fleetDispatcher.shipsOnPlanet.find(e => e.id == shipID)?.number || 0) < amount && item.classList.add("ogl_notEnough"); }), fleetDispatcher.shipsOnPlanet.forEach((entry, index) => { let shipID = entry.id; var domElement = document.querySelector(`[data-technology="${shipID}"]`); if (domElement) { domElement = domElement.querySelector(".ogl_shipFlag") || Util.addDom("div", { class: "ogl_shipFlag", parent: domElement }); if (domElement.innerText = "", Util.addDom("div", { class: "ogl_reverse material-icons tooltip", title: "Reverse selection", child: "repeat", parent: domElement, onclick: e => { e.stopPropagation(); e = fleetDispatcher.shipsOnPlanet.find(e => e.id == entry.id)?.number - (fleetDispatcher.findShip(entry.id)?.number || 0); fleetDispatcher.selectShip(entry.id, e), fleetDispatcher.refresh(); } }), -1 < this.ogl.fretShips.indexOf(shipID)) { let favIcon = Util.addDom("div", { class: "material-icons ogl_fav tooltip", title: "Default ship", child: "star", parent: domElement, onclick: () => { this.ogl.db.options.defaultShip = shipID, "settings" == this.ogl.db.currentSide && this.ogl.fretShips.forEach(sid => { document.querySelector('.ogl_config [data-opt="defaultShip"] .ogl_' + sid).classList.remove("ogl_active"), sid == shipID && document.querySelector('.ogl_config [data-opt="defaultShip"] .ogl_' + sid).classList.add("ogl_active"); }), document.querySelectorAll("#fleet1 .ogl_fav").forEach(e => e.classList.add("ogl_grayed")), favIcon.classList.remove("ogl_grayed"), this.updateLimiter(), 1 === this.ogl.mode || 2 === this.ogl.mode ? (this.ogl.fretShips.forEach(sid => fleetDispatcher.selectShip(sid, 0)), fleetDispatcher.selectShip(this.ogl.db.options.defaultShip, this.shipsForResources()), fleetDispatcher.selectMaxAll()) : 3 === this.ogl.mode && this.ogl.cache.toSend && (this.ogl.fretShips.forEach(sid => fleetDispatcher.selectShip(sid, 0)), this.prefillTodolistCargo()); } }); if (this.ogl.db.options.defaultShip != shipID && favIcon.classList.add("ogl_grayed"), -1 < [ 202, 203, 219, 200 ].indexOf(shipID)) { let forcedIcon = Util.addDom("div", { class: "material-icons ogl_shipLock tooltip", title: "Locked ship", child: "blocked", parent: domElement, onclick: () => { (this.ogl.db.keepEnoughCapacityShip == shipID ? (this.ogl.db.keepEnoughCapacityShip = 200, document.querySelectorAll("#fleet1 .ogl_shipLock").forEach(e => e.classList.add("ogl_grayed")), document.querySelectorAll(".ogl_limiterGroup .ogl_active").forEach(e => e.classList.remove("ogl_active")), document.querySelector(".ogl_limiterGroup .ogl_200")) : (this.ogl.db.keepEnoughCapacityShip = shipID, document.querySelectorAll("#fleet1 .ogl_shipLock").forEach(e => e.classList.add("ogl_grayed")), forcedIcon.classList.remove("ogl_grayed"), document.querySelectorAll(".ogl_limiterGroup .ogl_active").forEach(e => e.classList.remove("ogl_active")), document.querySelector(".ogl_limiterGroup .ogl_" + shipID))).classList.add("ogl_active"), this.updateLimiter(); } }); this.ogl.db.keepEnoughCapacityShip != shipID && forcedIcon.classList.add("ogl_grayed"); } } } }), document.querySelector(".ogl_popup.ogl_active") || fleetDispatcher.focusSubmitFleet1(); } shipsForResources(shipID, resource) { return shipID = shipID || this.ogl.db.options.defaultShip, -1 === (resource = 0 === resource ? 0 : resource || -1) && (unsafeWindow.fleetDispatcher ? [ "metal", "crystal", "deut", "food" ].forEach(resourceName => resource += fleetDispatcher[this.resOnPlanet[resourceName]]) : [ "metal", "crystal", "deut", "food" ].forEach(resourceName => resource += this.ogl.currentPlanet?.obj?.[resourceName])), Math.ceil(resource / this.ogl.db.shipsCapacity[shipID]) || 0; } selectExpedition(shipID) { if (!fleetDispatcher.fetchTargetPlayerDataTimeout) { this.ogl.mode = 5, fleetDispatcher.resetShips(), fleetDispatcher.resetCargo(); var coords = [ fleetDispatcher.currentPlanet.galaxy, fleetDispatcher.currentPlanet.system, fleetDispatcher.currentPlanet.position ], expeditionData = this.ogl.calcExpeditionMax(); let amount = Math.max(this.ogl.db.options.expeditionValue ? 0 : Math.ceil(expeditionData.treshold.base / { 202: 1, 203: 3, 219: 5.75 }[shipID]), this.shipsForResources(shipID, expeditionData.max)), fillerID = 0, randomSystem = ([ 218, 213, 211, 215, 207, 206, 205, 204 ].forEach(filler => { 0 <= this.ogl.db.options.expeditionBigShips.indexOf(filler) && 0 == fillerID && 0 < document.querySelector(`.technology[data-technology="${filler}"] .amount`)?.getAttribute("data-value") && (fillerID = filler); }), fleetDispatcher.shipsOnPlanet.forEach(ship => { ship.id == shipID ? fleetDispatcher.selectShip(ship.id, amount) : (ship.id == fillerID && shipID != fillerID || 210 == ship.id || 219 == ship.id && 219 != shipID) && fleetDispatcher.selectShip(ship.id, 1); }), Math.round(Math.random() * this.ogl.db.options.expeditionRandomSystem) * (Math.round(Math.random()) ? 1 : -1) + coords[1]); 500 <= randomSystem && (randomSystem -= 499), this.setRealTarget(fleetDispatcher.realTarget, { galaxy: coords[0], system: randomSystem, position: 16, type: 1, name: fleetDispatcher.loca.LOCA_EVENTH_ENEMY_INFINITELY_SPACE }), fleetDispatcher.selectMission(15), fleetDispatcher.expeditionTime = 1, fleetDispatcher.updateExpeditionTime(), fleetDispatcher.refresh(), fleetDispatcher.focusSubmitFleet1(), this.ogl.db.lastExpeditionShip = shipID, this.prepareRedirection(); } } updateSpeedBar() { document.querySelector("#speedPercentage").addEventListener("mousemove", event => { document.querySelector("#speedPercentage").querySelectorAll(".selected").forEach(e => e.classList.remove("selected")), document.querySelector("#speedPercentage").querySelector(`[data-step="${fleetDispatcher.realSpeedPercent}"]`).classList.add("selected"); }), document.querySelector("#speedPercentage").addEventListener("click", e => { e.target.getAttribute("data-step") && ( document.querySelector("#speedPercentage .bar").style.width = e.target.offsetLeft + e.target.offsetWidth + "px", document.querySelector("#speedPercentage").querySelectorAll(".selected").forEach(e => e.classList.remove("selected")), e.target.classList.add("selected"), fleetDispatcher.speedPercent = e.target.getAttribute("data-step"), fleetDispatcher.realSpeedPercent = e.target.getAttribute("data-step"), fleetDispatcher.refresh()), fleetDispatcher.realSpeedPercent = fleetDispatcher.speedPercent, fleetDispatcher.setFleetPercent(fleetDispatcher.speedPercent), fleetDispatcher.cargoDeuterium + fleetDispatcher.getConsumption() >= fleetDispatcher.getDeuteriumOnPlanetWithoutConsumption() && (fleetDispatcher.cargoDeuterium = 0, fleetDispatcher.selectMaxDeuterium(), fleetDispatcher.refresh()), fleetDispatcher.focusSendFleet(); }); } prefillTodolistCargo() { let curmulRes = [ 0, 0, 0 ]; var maxRes = [ 0, 0, 0 ], urlParams = (this.ogl.cache.toSend.forEach(build => { curmulRes[0] = curmulRes[0] + build.cost.metal, curmulRes[1] = curmulRes[1] + build.cost.crystal, curmulRes[2] = curmulRes[2] + build.cost.deut; }), maxRes[0] = Math.min(fleetDispatcher.metalOnPlanet, curmulRes[0]), maxRes[1] = Math.min(fleetDispatcher.crystalOnPlanet, curmulRes[1]), maxRes[2] = Math.min(fleetDispatcher.deuteriumOnPlanet, curmulRes[2]), maxRes = maxRes[0] + maxRes[1] + maxRes[2], new URLSearchParams(window.location.search)); urlParams.get("substractMode") && urlParams.get("targetid") && (urlParams = urlParams.get("targetid"), curmulRes[0] = Math.max(curmulRes[0] - (this.ogl.db.myPlanets[urlParams]?.metal || 0), 0), curmulRes[1] = Math.max(curmulRes[1] - (this.ogl.db.myPlanets[urlParams]?.crystal || 0), 0), curmulRes[2] = Math.max(curmulRes[2] - (this.ogl.db.myPlanets[urlParams]?.deut || 0), 0)), urlParams = curmulRes[0] + curmulRes[1] + curmulRes[2], fleetDispatcher.selectShip(this.ogl.db.options.defaultShip, this.shipsForResources(this.ogl.db.options.defaultShip, Math.min(urlParams, maxRes))), 0 < fleetDispatcher.shipsToSend.length && (fleetDispatcher.cargoMetal = Math.min(curmulRes[0], fleetDispatcher.metalOnPlanet), fleetDispatcher.cargoCrystal = Math.min(curmulRes[1], fleetDispatcher.crystalOnPlanet), fleetDispatcher.cargoDeuterium = Math.min(curmulRes[2], fleetDispatcher.deuteriumOnPlanet), fleetDispatcher.refresh()); } prepareRedirection() { if (!this.redirectionReady || this.ogl.mode) return void (this.redirectionReady = !0); } sendNextMiniFleet() { if (!(this.miniFleetQueue.length < 1)) { let item = this.miniFleetQueue[0], params = { mission: item.order, galaxy: item.galaxy, system: item.system, position: item.position, type: item.type, shipCount: item.ships || this.ogl.db.spyProbesCount, token: token, uid: item.uid, popup: item.popup }; item.additionalParams && "object" == typeof item.additionalParams && Object.keys(item.additionalParams).map(key => { params[key] || (params[key] = item.additionalParams[key]); }), $.ajax(miniFleetLink, { data: params, dataType: "json", type: "POST" }); } } updateSpyFunctions() { sendShips = (order, galaxy, system, planet, planettype, shipCount, additionalParams, popup) => { var item = {}, shipCount = (item.order = order, item.galaxy = galaxy, item.system = system, item.position = planet, item.type = planettype, item.ships = shipCount, item.additionalParams = additionalParams, item.retry = 0, item.uid = crypto.randomUUID(), item.popup = popup || !1, document.querySelectorAll(`[onclick*="sendShips(${order}, ${galaxy}, ${system}, ${planet}, ${planettype}"]:not([data-spy-coords])`).forEach(e => { e.setAttribute("data-spy-coords", galaxy + `:${system}:${planet}:` + planettype); }), document.querySelectorAll(`[data-spy-coords="${galaxy}:${system}:${planet}:${planettype}"]`).forEach(e => e.setAttribute("data-spy", "prepare")), this.miniFleetQueue.length < 1); this.miniFleetQueue.push(item), shipCount && this.sendNextMiniFleet(); }, sendShipsWithPopup = (order, galaxy, system, planet, planettype, shipCount, additionalParams) => { sendShips(order, galaxy, system, planet, planettype, shipCount, additionalParams, !0); }; } checkSendShips() { document.querySelectorAll('[onclick*="sendShips(6"]:not([data-spy-coords]), [onclick*="sendShipsWithPopup(6"]:not([data-spy-coords])').forEach(element => { var matches = element.getAttribute("onclick").match(/(?<=sendShips[WithPopup]*?\()(.*?)(?=\))/); matches && (matches = matches[0].match(/\d+/g), element.setAttribute("data-spy-coords", matches[1] + `:${matches[2]}:${matches[3]}:` + matches[4]), matches = this.ogl.db.pdb[`${matches[1]}:${matches[2]}:` + matches[3]]?.spy?.[1 == matches[4] ? 0 : 1] || 0, serverTime.getTime() - matches < this.ogl.db.options.spyIndicatorDelay) && element.setAttribute("data-spy", "recent"); }), document.querySelectorAll('[onclick*="sendShips(8"]:not([data-spy-coords]), [onclick*="sendShipsWithPopup(8"]:not([data-spy-coords])').forEach(element => { var matches = element.getAttribute("onclick").match(/[sendShips|sendShipsWithPopup]\((\d|,| )+\)/); matches && (matches = matches[0].match(/\d+/g), element.setAttribute("data-spy-coords", matches[1] + `:${matches[2]}:${matches[3]}:` + matches[4])); }); } updateSystemSpy() { let self = this; document.querySelector(".spysystemlink").addEventListener("click", event => { event.preventDefault(), event.stopPropagation(); let shortcutButton = document.querySelector('[data-key-id="galaxySpySystem"]'); event = event.target.getAttribute("data-target-url"); if (event) { let hasError = !1; shortcutButton?.setAttribute("data-spy", "prepare"), $.post(event, { galaxy: $("#galaxy_input").val(), system: $("#system_input").val(), token: token }, "json").done(function(json) { json = JSON.parse(json); token = json.newAjaxToken, updateOverlayToken("phalanxDialog", json.newAjaxToken), updateOverlayToken("phalanxSystemDialog", json.newAjaxToken), json.count || (self.ogl._notification.addToQueue(json.text, !1), hasError = !0), json.planets.forEach(params => { document.querySelectorAll(`[data-spy-coords="${params.galaxy}:${params.system}:${params.position}:${params.type}"]`).forEach(e => e.setAttribute("data-spy", "done")), self.ogl.db.pdb[params.galaxy + `:${params.system}:` + params.position] && (self.ogl.db.pdb[params.galaxy + `:${params.system}:` + params.position].spy = self.ogl.db.pdb[params.galaxy + `:${params.system}:` + params.position].spy || [], 1 == params.type ? self.ogl.db.pdb[params.galaxy + `:${params.system}:` + params.position].spy[0] = serverTime.getTime() : self.ogl.db.pdb[params.galaxy + `:${params.system}:` + params.position].spy[1] = serverTime.getTime()); }), hasError ? shortcutButton?.setAttribute("data-spy", "fail") : shortcutButton?.setAttribute("data-spy", "done"); }); } }); } } class GalaxyManager extends Manager { init() { this.isReady || (this.isReady = !0, this.unloadSystem(), submitForm()); } load() { if ("galaxy" == this.ogl.page && unsafeWindow.galaxy) { this.galaxy = galaxy, this.system = system; let loader = document.querySelector("#galaxyLoading"); loader.setAttribute("data-currentposition", this.galaxy + ":" + this.system), Util.overWrite("loadContentNew", unsafeWindow, (g, s) => { this.unloadSystem(), loader.setAttribute("data-currentPosition", g + ":" + s), tippy.hideAll(); }), submitForm(), this.ogl._fleet.updateSystemSpy(); } } check(data) { if (data.success && data.system) { this.galaxy = data.system.galaxy, this.system = data.system.system, galaxy = this.galaxy, system = this.system, document.querySelector("#galaxy_input").value = this.galaxy, document.querySelector("#system_input").value = this.system; let ptrePositions = {}, ptreActivities = {}, getActivity = (this.ogl.db.spyProbesCount = data.system.settingsProbeCount || 0, element => 15 == element.activity.showActivity ? "*" : element.activity.idleTime || 60); data.system.galaxyContent.forEach(line => { var position = line.position; let debris = { metal: 0, crystal: 0, deut: 0, total: 0 }, row = document.querySelector("#galaxyRow" + position); if (16 == position) debris.metal = parseInt(line.planets.resources.metal.amount), debris.crystal = parseInt(line.planets.resources.crystal.amount), debris.deut = parseInt(line.planets.resources.deuterium.amount), debris.total = debris.metal + debris.crystal + debris.deut, this.updateDebrisP16(debris, row); else { var player, planet, coords = `${this.galaxy}:${this.system}:` + position, playerID = parseInt(99999 == line.player.playerId ? -1 : line.player.playerId), playerName = line.player.playerName, playerStatus = Array.from(row.querySelector('.cellPlayerName span[class*="status_"]')?.classList || []).filter(e => e.startsWith("status_"))[0], playerStatus = this.ogl._highscore.nameToTagList[playerStatus], isOwn = playerID == this.ogl.account.id, rank = line.player.highscorePositionPlayer; let activities = [], planetID = -1, moonID = -1, moonSize = -1; row.querySelector(".cellDebris").classList.remove("ogl_important"), line.planets.forEach(element => { 1 == element.planetType ? (activities[0] = getActivity(element), planetID = element.isDestroyed ? -1 : parseInt(element.planetId)) : 2 == element.planetType ? (debris.metal = parseInt(element.resources.metal.amount), debris.crystal = parseInt(element.resources.crystal.amount), debris.deut = parseInt(element.resources.deuterium.amount), debris.total = debris.metal + debris.crystal + debris.deut, this.updateDebris(debris, row)) : 3 == element.planetType && (activities[1] = getActivity(element), moonID = element.isDestroyed ? -1 : parseInt(element.planetId), moonSize = parseInt(element.size)); }), line.player.isAdmin || (line = this.ogl.db.pdb[coords] || { pid: -1, mid: -1 }, this.ogl.ptreKey && (ptrePositions[coords] = {}, ptrePositions[coords].teamkey = this.ogl.ptreKey, ptrePositions[coords].galaxy = this.galaxy, ptrePositions[coords].system = this.system, ptrePositions[coords].position = position, ptrePositions[coords].timestamp_ig = serverTime.getTime(), ptrePositions[coords].old_player_id = line.uid || -1, ptrePositions[coords].timestamp_api = line?.api || -1, ptrePositions[coords].old_name = line?.name || !1, ptrePositions[coords].old_rank = line?.score?.globalRanking || -1, ptrePositions[coords].old_score = line?.score?.global || -1, ptrePositions[coords].old_fleet = line?.score?.military || -1, playerID < 0 && line.pid != planetID ? (ptrePositions[coords].id = -1, ptrePositions[coords].player_id = -1, ptrePositions[coords].name = !1, ptrePositions[coords].rank = -1, ptrePositions[coords].score = -1, ptrePositions[coords].fleet = -1, ptrePositions[coords].status = !1, ptrePositions[coords].moon = { id: -1 }) : playerID < 0 && delete ptrePositions[coords]), line.pid != planetID && (this.ogl.removeOldPlanetOwner(coords, playerID), delete this.ogl.db.pdb[coords]), 0 < playerID && (this.ogl.db.pdb[coords] = this.ogl.db.pdb[coords] || {}, player = this.ogl.db.udb[playerID] || this.ogl.createPlayer(playerID), planet = this.ogl.db.pdb[coords], !this.ogl.ptreKey || line.pid == planetID && (line.mid || -1) == moonID ? delete ptrePositions[coords] : (ptrePositions[coords].id = planetID, ptrePositions[coords].player_id = playerID, ptrePositions[coords].name = playerName || !1, ptrePositions[coords].rank = rank || -1, ptrePositions[coords].score = player.score?.global || -1, ptrePositions[coords].fleet = player.score?.military || -1, ptrePositions[coords].status = playerStatus, -1 < moonID && (ptrePositions[coords].moon = {}, ptrePositions[coords].moon.id = moonID, ptrePositions[coords].moon.size = moonSize), console.log(coords + ` | ${line.pid} -> ${planetID} | ${line.mid} -> ` + moonID)), planet.uid = playerID, planet.pid = planetID, planet.mid = moonID, planet.coo = coords, player.uid = playerID, player.name = playerName, player.status = playerStatus, player.liveUpdate = serverTime.getTime(), player.score = player.score || {}, player.score.globalRanking = rank, player.planets = player.planets || [], player.planets.indexOf(coords) < 0 && player.planets.push(coords), this.updateRow(player, row, isOwn, coords), player.pin || -1 < this.ogl.db.lastPinnedList.indexOf(playerID)) && this.ogl.db.pdb[coords] && (this.ogl.db.pdb[coords].api = serverTime.getTime(), this.ogl.db.pdb[coords].acti = [ activities[0], activities[1], serverTime.getTime() ], this.ogl.db.pdb[coords].debris = debris.total, document.querySelector(".ogl_side.ogl_active") && this.ogl.db.currentSide == playerID && this.ogl._topbar.openPinnedDetail(playerID), this.ogl.ptreKey) && (ptreActivities[coords] = {}, ptreActivities[coords].id = planetID, ptreActivities[coords].player_id = playerID, ptreActivities[coords].teamkey = this.ogl.ptreKey, ptreActivities[coords].mv = "v" == playerStatus, ptreActivities[coords].activity = activities[0], ptreActivities[coords].galaxy = this.galaxy, ptreActivities[coords].system = this.system, ptreActivities[coords].position = position, ptreActivities[coords].main = this.ogl.db.pdb[coords].home || !1, ptreActivities[coords].cdr_total_size = debris.total, -1 < moonID) && (ptreActivities[coords].moon = {}, ptreActivities[coords].moon.id = moonID, ptreActivities[coords].moon.activity = activities[1])); } }), 0 < Object.keys(ptrePositions).length && this.ogl.PTRE.postPositions(ptrePositions), 0 < Object.keys(ptreActivities).length && this.ogl.PTRE.postActivities(ptreActivities), this.checkCurrentSystem(); var data = document.querySelector(".ctGalaxyFooter .ogl_lastGalaxyRefresh") || Util.addDom("div", { class: "ogl_lastGalaxyRefresh tooltip", after: document.querySelector(".ctGalaxyFooter #colonized"), title: "Last galaxy refresh" }), timeObj = this.ogl._time.getObj(); data.innerText = "", data.appendChild(this.ogl._time.convertTimestampToDate(this.ogl.db.options.useClientTime ? timeObj.client : timeObj.server)); } else this.ogl._notification.addToQueue(`Error, cannot fetch [${this.galaxy}:${this.system}] data`); } updateRow(player, row, isOwn, coords) { var page = Math.max(1, Math.ceil(player.score.globalRanking / 100)); this.ogl._ui.turnIntoPlayerLink(player.uid, row.querySelector('.cellPlayerName [class*="status_abbr"]'), player.name, player.status), Util.addDom("a", { class: "ogl_ranking", parent: row.querySelector(".cellPlayerName"), href: `https://${window.location.host}/game/index.php?page=highscore&site=${page}&searchRelId=` + player.uid, child: "#" + player.score.globalRanking }), isOwn || (this.ogl._ui.addPinButton(row.querySelector(".cellPlayerName"), player.uid), this.ogl._ui.addTagButton(row.querySelector(".cellPlanetName"), coords)), player.uid == this.ogl.db.currentSide && row.querySelector(".cellPlayerName").classList.add("ogl_active"); } updateDebris(debris, row) { if (0 < debris.total) { var row = row.querySelector(".microdebris"), ships = (row.classList.remove("debris_1"), row.querySelector('[onclick*="sendShips(8"]')), row = Util.addDom("div", { parent: row }); if (ships) { let params = ships.getAttribute("onclick").match(/\d+/g).map(Number); row.setAttribute("data-spy-coords", `${params[1]}:${params[2]}:${params[3]}:2`), row.addEventListener("click", () => sendShips(params[0], params[1], params[2], params[3], params[4], params[5])); } row.innerHTML = Util.formatToUnits(debris.total, 0), debris.total >= this.ogl.db.options.resourceTreshold && row.closest(".cellDebris").classList.add("ogl_important"); } } updateDebrisP16(debris, row) { if (0 < debris.total) { let content = row.querySelectorAll(".ListLinks li"); var scouts = (content = content[0] ? content : document.querySelectorAll("#debris16 .ListLinks li"))[3], action = content[4]; ( document.querySelector(".expeditionDebrisSlotBox .ogl_expeditionRow") || Util.addDom("div", { class: "ogl_expeditionRow", parent: document.querySelector(".expeditionDebrisSlotBox") })).innerHTML = ` <div> <div class="material-icons">debris</div> </div> <div class="ogl_expeditionDebris"> <div class="ogl_icon ogl_metal">${Util.formatToUnits(debris.metal)}</div> <div class="ogl_icon ogl_crystal">${Util.formatToUnits(debris.crystal)}</div> <div class="ogl_icon ogl_deut">${Util.formatToUnits(debris.deut)}</div> <div class="ogl_expeditionText">${scouts.innerText}</div> <div class="ogl_expeditionText">${action.outerHTML}</div> </div> `, debris.total >= this.ogl.db.options.resourceTreshold && document.querySelector(".ogl_expeditionRow").classList.add("ogl_important"); } row.classList.remove("ogl_hidden"); } unloadSystem() { document.querySelector("#galaxyRow16") && ( document.querySelector(".ogl_expeditionRow") && document.querySelector(".ogl_expeditionRow").remove(), document.querySelector("#galaxyRow16").classList.remove("ogl_important")); for (let i = 1; i < 16; i++) document.querySelectorAll(`#galaxyRow${i} .galaxyCell:not(.cellPosition)`).forEach(e => { e.innerText = "", e.classList.remove("ogl_important"), e.classList.remove("ogl_active"); }), document.querySelector("#galaxyRow" + i).className = "galaxyRow ctContentRow empty_filter filtered_filter_empty"; } checkCurrentSystem() { document.querySelectorAll("[data-galaxy]").forEach(element => { var coords = element.getAttribute("data-galaxy").split(":"); this.galaxy == coords[0] && this.system == coords[1] ? element.classList.add("ogl_active") : element.classList.remove("ogl_active"); }), this.ogl._tooltip && this.ogl._tooltip.initTooltipList(document.querySelectorAll("#galaxyContent .tooltipClick, #galaxyContent .ownPlayerRow")); } } class JumpgateManager extends Manager { load() { this.initialRel = {}, Util.overWrite("initJumpgate", unsafeWindow, !1, () => { this.check(); }), Util.overWrite("initPhalanx", unsafeWindow, !1, () => { this.checkPhalanx(); }), this.saveTimer(), this.displayTimer(); } check() { var parent = document.querySelector("#jumpgate"); if (parent && !parent.querySelector(".ogl_limiterLabel")) { document.querySelectorAll("#jumpgate .ship_input_row").forEach(line => { var shipID; line.previousElementSibling.classList.contains("tdInactive") || (shipID = (line = line.querySelector("input")).getAttribute("id").replace("ship_", ""), this.initialRel[shipID] = parseInt(line.getAttribute("rel"))); }); var parent = Util.addDom("fieldset", { parent: document.querySelector("#jumpgateForm .ship_selection_table") }), limitShipLabel = (Util.addDom("legend", { parent: parent, child: "Settings" }), Util.addDom("label", { class: "ogl_limiterLabel", parent: parent, child: "Ships" })), limitShipLabel = Util.addDom("input", { type: "checkbox", parent: limitShipLabel, onclick: () => { this.ogl.db.fleetLimiter.jumpgateActive = !this.ogl.db.fleetLimiter.jumpgateActive, this.updateLimiter(); } }); let keepLabel = Util.addDom("div", { class: "ogl_limiterGroup", parent: parent, child: "Force (jumpgate)" }); [ 202, 203, 219, 200 ].forEach(shipID => { let item = Util.addDom("div", { class: "ogl_icon ogl_" + shipID, parent: keepLabel, onclick: () => { keepLabel.querySelector(".ogl_active")?.classList.remove("ogl_active"), item.classList.add("ogl_active"), this.ogl.db.keepEnoughCapacityShipJumpgate = shipID, this.updateLimiter(); } }); this.ogl.db.keepEnoughCapacityShipJumpgate == shipID && item.classList.add("ogl_active"); }), this.ogl.db.fleetLimiter.jumpgateActive && (limitShipLabel.checked = !0), this.updateLimiter(); } } updateLimiter() { if ( document.querySelector("#jumpgate") && ! document.querySelector("#jumpgateNotReady")) { let sendAllJson = {}; document.querySelectorAll("#jumpgate .ship_input_row").forEach(line => { if (!line.previousElementSibling.classList.contains("tdInactive")) { var input = line.querySelector("input"), shipID = input.getAttribute("id").replace("ship_", ""); let forced = 0; this.ogl.db.keepEnoughCapacityShipJumpgate == shipID && (forced = this.ogl._fleet.shipsForResources(shipID)); var keeped = Math.max(forced, this.ogl.db.fleetLimiter.jumpgateActive && this.ogl.db.fleetLimiter.jumpgateData[shipID] || 0), amount = Math.max(0, this.initialRel[shipID] - keeped), input = (input.setAttribute("rel", amount), input.value > amount && (input.value = amount), line.previousElementSibling.querySelector(".quantity").setAttribute("onclick", `toggleMaxShips('#jumpgateForm', ${shipID}, ${amount})`), line.previousElementSibling.querySelector("a").setAttribute("onclick", `toggleMaxShips('#jumpgateForm', ${shipID}, ${amount})`), line.querySelector(".ogl_keepRecap") || Util.addDom("div", { parent: line, class: "ogl_keepRecap" })); input.innerText = "-" + keeped, input.addEventListener("click", () => { Util.runAsync(() => this.ogl._ui.openFleetProfile()).then(e => this.ogl._popup.open(e)); }), sendAllJson[shipID] = amount; } }), document.querySelector("#jumpgate #sendall").setAttribute("onclick", `setMaxIntInput("#jumpgateForm", ${JSON.stringify(sendAllJson)})`); } } checkPhalanx() { var parent = document.querySelector("#phalanxWrap"), parent = Util.addDom("div", { prepend: parent, child: "<span>Last update:</span><br>", class: "ogl_phalanxLastUpdate" }); let clock = document.querySelector(".OGameClock").cloneNode(!0), refresh = (clock.className = "", parent.appendChild(clock), Util.addDom("span", { parent: parent, child: " - <b>0s</b>" })); setInterval(() => { var currentTime = parseInt( document.querySelector(".OGameClock").getAttribute("data-time-server")), refreshTime = parseInt(clock.getAttribute("data-time-server")); refresh.innerHTML = ` - <b>${Math.round((currentTime - refreshTime) / 1e3)}s</b>`; }, 1e3); } saveTimer() { let calcTimer = level => (.25 * Math.pow(level, 2) - 7.57 * level + 67.34) / this.ogl.server.warFleetSpeed * 6e4; jumpgateDone = a => { var originID, originLevel, destinationLevel, now; (a = $.parseJSON(a)).status && (planet = a.targetMoon, $(".overlayDiv").dialog("destroy"), originID = this.ogl.currentPlanet.obj.id, originLevel = this.ogl.currentPlanet.dom.element.parentNode.querySelector(".moonlink").getAttribute("data-jumpgatelevel"), destinationLevel = document.querySelector(`.moonlink[href*="${jumpGateTargetId}"]`).getAttribute("data-jumpgatelevel"), now = serverTime.getTime(), this.ogl.db.myPlanets[originID].jumpgateTimer = now + calcTimer(originLevel), this.ogl.db.myPlanets[jumpGateTargetId].jumpgateTimer = now + calcTimer(destinationLevel)), errorBoxAsArray(a.errorbox), void 0 !== a.newToken && setNewTokenData(a.newToken); }; } displayTimer() { document.querySelectorAll(".moonlink").forEach(moon => { var targetDom = moon.parentNode.querySelector(".ogl_sideIconInfo") || Util.addDom("div", { class: "ogl_sideIconInfo tooltip", title: "Jumpgate not ready", parent: moon.parentNode }); let moonID = moon.getAttribute("href").match(/cp=(\d+)/)[1]; if (this.ogl.db.myPlanets[moonID]?.jumpgateTimer > serverTime.getTime()) { let updateTimer = () => new Date(this.ogl.db.myPlanets[moonID].jumpgateTimer - (serverTime.getTime() + 36e5)).toLocaleTimeString([], { minute: "2-digit", second: "2-digit" }), div = Util.addDom("div", { class: "ogl_jumpgateTimer", parent: targetDom, child: updateTimer() }), interval = setInterval(() => { this.ogl.db.myPlanets[moonID].jumpgateTimer <= serverTime.getTime() ? (clearInterval(interval), div.remove()) : div.innerText = updateTimer(); }, 1e3); } }); } } class TooltipManager extends Manager { load() { this.openTimeout, this.lastSender, this.lastActiveSender, this.shouldWait = !1, unsafeWindow.tippy && Util.overWrite("initTooltips", unsafeWindow, null, () => { this.initTooltipList(document.querySelectorAll(getTooltipSelector())); }), this.tooltip = Util.addDom("div", { class: "ogl_tooltip", parent: document.body }), document.querySelector("#metal_box")?.getAttribute("title") || getAjaxResourcebox(), unsafeWindow.tippy ? initTooltips() : this.init(); } initTooltipList(nodeList) { nodeList.forEach(element => { element._tippy?.oglTooltipReady || (element.title && !element.getAttribute("data-tooltip-title") && element.setAttribute("data-tooltip-title", element.title), element.removeAttribute("title"), element._tippy || tippy(element, { content: element.getAttribute("data-tooltip-title"), allowHTML: !0, appendTo: document.body, zIndex: 1000001, placement: element.classList.contains("tooltipBottom") ? "bottom" : element.classList.contains("tooltipRight") ? "right" : element.classList.contains("tooltipLeft") ? "left" : "top", interactive: element.getAttribute("data-tooltip-interactive") || !1, maxWidth: 400 }), element._tippy && (element._tippy.setProps({ animation: "pop", delay: [ element.classList.contains("tooltipClick") ? 0 : 400, null ], duration: [ 100, 0 ], interactive: !(!element.classList.contains("tooltipClose") && !element.classList.contains("tooltipRel")), trigger: element.classList.contains("tooltipClick") ? "click focus" : "mouseenter focus", onShow: instance => { tippy.hideAll(); let content = instance.props.content || element.getAttribute("data-tooltip-title"); if (element.classList.contains("planetlink") ? content = this.updatePlanetMenuTooltip(instance, "planet") || content : element.classList.contains("moonlink") ? content = this.updatePlanetMenuTooltip(instance, "moon") || content : "string" == typeof content && 0 <= content.indexOf('class="fleetinfo"') && (content = this.updateFleetTooltip(instance)), !content || !1 === content || "" === content) return !1; content && instance.setContent(content), element.classList.contains("tooltipUpdate") && element.dispatchEvent(this.ogl.tooltipEvent), instance.popper.classList.add("ogl_noTouch"); }, onTrigger: instance => { tippy.hideAll(), element.removeAttribute("title"); }, onShown: instance => { instance.popper.classList.remove("ogl_noTouch"); } }), element._tippy.oglTooltipReady = !0, element.classList.add("ogl_ready"))); }); } updatePlanetMenuTooltip(instance, refType) { if (this.ogl.db.options.disablePlanetTooltips) return !1; if (!instance.oglContentInjected) if ("planet" == refType) { instance.setProps({ placement: "left" }); var planetID = instance.reference.parentNode.getAttribute("id").replace("planet-", ""), name = instance.reference.querySelector(".planet-name").innerText, data = this.ogl.db.myPlanets[planetID]; let div = Util.addDom("div", { class: "ogl_planetTooltip" }); var links = new DOMParser().parseFromString(instance.props.content, "text/html").querySelectorAll("a"); if (data) return data?.lifeform && Util.addDom("div", { parent: div, class: "ogl_icon ogl_lifeform" + data.lifeform }), div.appendChild(instance.reference.querySelector(".planetPic").cloneNode()), Util.addDom("h3", { parent: div, child: `<span data-galaxy="${data.coords}">[${data.coords}]</span><br>` + name }), Util.addDom("div", { class: "ogl_textCenter", parent: div, child: data.fieldUsed + "/" + data.fieldMax }), Util.addDom("div", { class: "ogl_textCenter", parent: div, child: data.temperature + 40 + "°c" }), Util.addDom("hr", { parent: div }), Util.addDom("div", { class: "ogl_mineRecap", child: `<span class='ogl_metal'>${data[1]}</span> <span class='ogl_crystal'>${data[2]}</span> <span class='ogl_deut'>${data[3]}</span>`, parent: div }), this.ogl._topbar?.PlanetBuildingtooltip[planetID] && div.appendChild(this.ogl._topbar?.PlanetBuildingtooltip[planetID]), Util.addDom("hr", { parent: div }), links.forEach(e => div.appendChild(e)), instance.oglContentInjected = !0, div.outerHTML; } else if ("moon" == refType) { instance.setProps({ placement: "right" }); let planetID = new URLSearchParams(instance.reference.getAttribute("href")).get("cp").split("#")[0], name = instance.reference.querySelector(".icon-moon").getAttribute("alt"), data = this.ogl.db.myPlanets[planetID], div = Util.addDom("div", { class: "ogl_planetTooltip" }), links = new DOMParser().parseFromString(instance.props.content, "text/html").querySelectorAll("a"); if (data) return div.appendChild(instance.reference.querySelector(".icon-moon").cloneNode()), Util.addDom("h3", { parent: div, child: `<span data-galaxy="${data.coords}">[${data.coords}]</span><br>` + name }), Util.addDom("div", { class: "ogl_textCenter", parent: div, child: data.fieldUsed + "/" + data.fieldMax }), Util.addDom("hr", { parent: div }), this.ogl._topbar?.PlanetBuildingtooltip[planetID] && div.appendChild(this.ogl._topbar?.PlanetBuildingtooltip[planetID]), links.forEach(e => div.appendChild(e)), instance.oglContentInjected = !0, div.outerHTML; } } updateFleetTooltip(instance) { var sender = instance.reference, instance = new DOMParser().parseFromString(instance.props.content, "text/html"); let origin = (sender.closest(".eventFleet")?.querySelector(".coordsOrigin") || sender.closest(".fleetDetails")?.querySelector(".originData a"))?.innerText.slice(1, -1), div = Util.addDom("div", { class: "ogl_fleetDetail" }), rawText = "", trashsimData = { ships: {} }; if (instance.querySelectorAll("tr").forEach(line => { let name = line.querySelector("td")?.innerText.replace(":", ""); var val, key = Object.entries(this.ogl.db.serverData).find(entry => entry[1] === name)?.[0], line = line.querySelector(".value")?.innerText.replace(/\.|,| /g, ""); key && line && ("metal" == key && Util.addDom("hr", { parent: div }), val = "metal" == key || "crystal" == key || "deut" == key || "food" == key ? Util.formatNumber(parseInt(line)) : Util.formatToUnits(line), Util.addDom("div", { parent: div, class: "ogl_icon ogl_" + key, child: val }), trashsimData.ships[key] = { count: line }, rawText += `${name}: ${Util.formatNumber(parseInt(line))}\n`); }), 0 < rawText.length) { sender = Util.addDom("span", { parent: div, class: "ogl_fullgrid" }); Util.addDom("hr", { parent: sender }); let btn = Util.addDom("button", { class: "ogl_button", parent: sender, child: '<span class="material-icons">content-copy</span><span>Copy</span>', onclick: () => { navigator.clipboard.writeText(rawText), btn.classList.remove("material-icons"), btn.innerText = "Copied!"; } }); origin && Util.addDom("div", { class: "ogl_button", parent: sender, child: '<span class="material-icons">letter_s</span><span>Simulate</span>', onclick: () => { Array.from(document.querySelectorAll(".planet-koords")).find(e => e.innerText == origin) ? window.open(Util.genTrashsimLink(this.ogl, !1, trashsimData, !1, !1), "_blank") : (trashsimData.planet = { galaxy: origin.split(":")[0], system: origin.split(":")[1], position: origin.split(":")[2] }, window.open(Util.genTrashsimLink(this.ogl, !1, !1, trashsimData, !0), "_blank")); } }); } return 0 < rawText.length && div; } } class NotificationManager extends Manager { load() { this.data = {}, this.blocks = [], this.interval, this.hideTimer = 5e3, this.step = 200, this.currentValue = this.hideTimer, this.start = 0, this.timeLeft = this.hideTimer, this.elapsedInterval, this.notification = Util.addDom("div", { class: "ogl_notification", parent: document.body, onmouseenter: () => { clearInterval(this.interval); }, onmouseleave: () => { this.interval = setInterval(() => this.updateClock(), this.step); }, onclick: () => { this.close(); } }), this.clock = Util.addDom("progress", { parent: this.notification, min: 0, max: this.hideTimer, value: this.currentValue }), this.content = Util.addDom("div", { parent: this.notification }); } open() { this.content.innerText = "", this.ogl._message.events?.mission && (this.ogl._message.events.mission = 0); let data = {}, blockCount = 0; var timeObj; if (this.blocks.forEach(block => { let icon = Util.addDom("i"); var timeObj; 0 < block.success ? icon = Util.addDom("i", { class: "material-icons ogl_ok", child: "done" }) : block.success < 0 && (icon = Util.addDom("i", { class: "material-icons ogl_danger", child: "alert" })), block.data && Object.entries(block.data).forEach(entry => { data[entry[0]] = (data[entry[0]] || 0) + (entry[1] || 0); }), block.message ? (timeObj = this.ogl._time.getObj(block.time), timeObj = this.ogl._time.timeToHMS(this.ogl.db.options.useClientTime ? timeObj.client : timeObj.server), timeObj = Util.addDom("div", { class: "ogl_notificationLine", child: icon.outerHTML + `<b class="ogl_notificationTimer">[${timeObj}]</b>` + block.message, prepend: this.content }), block.success < 0 && timeObj.classList.add("ogl_danger")) : blockCount++; }), 0 < blockCount && (timeObj = this.ogl._time.getObj(), timeObj = this.ogl._time.timeToHMS(this.ogl.db.options.useClientTime ? timeObj.client : timeObj.server), Util.addDom("div", { class: "ogl_notificationLine", child: `<b class="ogl_notificationTimer">[${timeObj}]</b>` + blockCount + " mission(s) added", prepend: this.content })), 0 < Object.keys(data).length) { let hasResources = !1, hasShips = !1, hasLifeforms = !1, hasExpeditions = !1, grid = Util.addDom("div", { class: "ogl_grid", prepend: this.content }); [ "metal", "crystal", "deut", "dm" ].forEach(type => { data[type] && (Util.addDom("div", { class: "ogl_icon ogl_" + type, child: Util.formatToUnits(data[type]), parent: grid }), hasResources = !0); }), hasResources && Util.addDom("hr", { parent: grid }), this.ogl.shipsList.forEach(type => { data[type] && (Util.addDom("div", { class: "ogl_icon ogl_" + type, child: Util.formatToUnits(data[type]), parent: grid }), hasShips = !0); }), hasShips && Util.addDom("hr", { parent: grid }), [ "artefact", "lifeform1", "lifeform2", "lifeform3", "lifeform4" ].forEach(type => { data[type] && (Util.addDom("div", { class: "ogl_icon ogl_" + type, child: Util.formatToUnits(data[type]), parent: grid }), hasLifeforms = !0); }), hasLifeforms && Util.addDom("hr", { parent: grid }), [ "blackhole", "trader", "early", "late", "pirate", "alien" ].forEach(type => { data[type] && (Util.addDom("div", { "data-resultType": type, class: "ogl_icon ogl_" + type, child: Util.formatToUnits(data[type]), parent: grid }), hasExpeditions = !0); }), hasExpeditions && Util.addDom("hr", { parent: grid }); } this.currentValue = this.hideTimer, this.notification.classList.add("ogl_active"), clearInterval(this.interval), this.interval = setInterval(() => this.updateClock(), this.step); } addToQueue(message, success, data) { this.blocks.push({ time: serverTime.getTime(), message: message, data: data, success: success = !0 === success ? 1 : !1 === success ? -1 : 0 }), this.blocks.sort((a, b) => a.time - b.time), this.blocks = this.blocks.filter(e => serverTime.getTime() < e.time + this.hideTimer), this.open(); } updateClock() { this.currentValue -= this.step, this.clock.value = this.currentValue, this.currentValue < 0 && this.close(); } close() { clearInterval(this.interval), this.notification.classList.remove("ogl_active"); } } class PopupManager extends Manager { load() { this.popup = Util.addDom("div", { class: "ogl_popup", parent: document.body }), this.popup.addEventListener("click", event => { event.target === this.popup && this.close(); }); } open(dom, canShare) { tippy.hideAll(), this.popup.innerText = "", dom && (Util.addDom("div", { class: "ogl_close material-icons", child: "close-thick", prepend: dom, onclick: () => { this.close(); } }), canShare && Util.addDom("div", { class: "ogl_share material-icons", child: "camera", prepend: dom, onclick: event => { event.target.classList.add("ogl_disabled"), Util.takeScreenshot(this.popup.querySelector("div"), event.target, `ogl_${this.ogl.server.id}_${this.ogl.server.lang}_empire_` + serverTime.getTime()); } }), this.popup.appendChild(dom), this.popup.classList.add("ogl_active"), initTooltips()); } close() { this.popup.classList.remove("ogl_active"); } updatePosition() { var div = this.popup; div.style.top = visualViewport.offsetTop + "px", div.style.height = visualViewport.height - 25 + "px", div.style.left = visualViewport.offsetLeft + "px", div.style.width = visualViewport.width + "px"; } } class MessageManager extends Manager { load() { this.ogl.cache.reports = this.ogl.cache.reports || {}, this.ogl.cache.raids = this.ogl.cache.raids || {}, this.ogl.cache.counterSpies = this.ogl.cache.counterSpies || [], this.ogl.db.spytableFilters = this.ogl.db.spytableFilters || { age: "ASC", rawCoords: !1, playerName: !1, wave1: !1, fleetValue: !1, defValue: !1 }, this.filterOrder = { age: "DESC", rawCoords: "ASC", playerName: "ASC", wave1: "DESC", fleetValue: "DESC", defValue: "DESC" }, this.checkBoard(), "messages" === this.ogl.page && (this.tokenReady = !0, this.deleteQueue = [], this.updateStatsTimeout, this.loopQueueTimeout, this.events = { mission: 0 }, this.hasNewEntry = !1, this.nextTarget, Util.overWrite("paginatorPrevious", unsafeWindow.ogame.messages, !1, () => { 20 != this.tabID && this.check(); }), Util.overWrite("paginatorNext", unsafeWindow.ogame.messages, !1, () => { 20 != this.tabID && this.check(); }), Util.overWrite("paginatorFirst", unsafeWindow.ogame.messages, !1, () => { 20 != this.tabID && this.check(); }), Util.overWrite("paginatorLast", unsafeWindow.ogame.messages, !1, () => { 20 != this.tabID && this.check(); })); } loopDeleteQueue() { this.deleteQueue.length, this.deleteMessage(), setTimeout(() => this.loopDeleteQueue(), 300); } check() { let ptreCounterSpies = {}; let isTrash = document.querySelector(".tabsWrapper .innerTabItem.active.trashcan"); this.reportList = [], 0 <= [ 11, 12, 20, 21, 22, 23, 24 ].indexOf(this.tabID) && (new DOMParser().parseFromString(ogame.messages.content.join(""), "text/html").querySelectorAll(".msg").forEach(msg => { var raw = msg.querySelector(".rawMessageData"); if (raw) { let message = {}; message.id = msg.getAttribute("data-msg-id"), message.globalTypeID = raw.dataset.rawMessagetype, message.date = this.ogl._time.getObj(1e3 * parseInt(raw.dataset.rawTimestamp || raw.dataset.rawDatetime || 0), "client"), message.api = raw.dataset.rawHashcode; var dom = document.querySelector(`[data-msg-id="${message.id}"]`); if (dom && (this.ogl._time.update(!1, dom.querySelector(".msgDate:not(.ogl_updated)")), dom.querySelector(".icon_apikey")) && message.api && dom.querySelector(".icon_apikey").setAttribute("data-api-code", message.api), 20 != this.tabID && 25 != this.tabID || !this.ogl.db.options.displaySpyTable || isTrash) if (21 == this.tabID) { if (message.coords = raw.dataset.rawCoords, message.defenderSpace = JSON.parse(raw.dataset.rawDefenderspaceobject || "{}"), message.fleets = JSON.parse(raw.dataset.rawFleets || "{}"), message.rounds = JSON.parse(raw.dataset.rawCombatrounds || "{}"), message.result = JSON.parse(raw.dataset.rawResult || "{}"), message.gain = { metal: 0, crystal: 0, deut: 0 }, message.shipLost = {}, message.resultType = "raid", message.isOwnPlanet = message.defenderSpace.owner?.id == this.ogl.account.id, message.probeOnly = !1, message.api && 35 != message.globalTypeID) { let ownFleets = message.fleets?.filter(fleet => fleet.player?.id == this.ogl.account.id).map(fleet => fleet.fleetId); var ownSides = message.fleets?.filter(fleet => fleet.player?.id == this.ogl.account.id).map(fleet => fleet.side), lastRound = message.rounds[message.rounds.length - 1], ownSides = (message.isAttacker = 0 <= ownSides.indexOf("attacker"), message.isDefender = 0 <= ownSides.indexOf("defender"), message.isWinner = 0 <= ownSides.indexOf(message.result.winner), message.noWinner = "none" == message.result.winner, message.isWinner && message.isAttacker && (message.gain.metal = message.result.loot.resources.find(line => "metal" == line.resource)?.amount, message.gain.crystal = message.result.loot.resources.find(line => "crystal" == line.resource)?.amount, message.gain.deut = message.result.loot.resources.find(line => "deuterium" == line.resource)?.amount), message.isWinner || message.noWinner || !message.isOwnPlanet || (message.gain.metal = -message.result.loot.resources.find(line => "metal" == line.resource)?.amount, message.gain.crystal = -message.result.loot.resources.find(line => "crystal" == line.resource)?.amount, message.gain.deut = -message.result.loot.resources.find(line => "deuterium" == line.resource)?.amount), message.fleets?.filter(fleet => "attacker" == fleet.side).map(fleet => fleet.combatTechnologies).reduce((acc, obj) => ({ ...acc, ...obj }), {})), defenderShips = message.fleets?.filter(fleet => "defender" == fleet.side).map(fleet => fleet.combatTechnologies).reduce((acc, obj) => ({ ...acc, ...obj }), {}); 1 == Object.values(ownSides).length && 210 == ownSides[0].technologyId && message.gain.metal + message.gain.crystal + message.gain.deut == 0 && (message.probeOnly = !0), 1 == Object.values(defenderShips).length && 210 == defenderShips[0].technologyId && message.gain.metal + message.gain.crystal + message.gain.deut == 0 && (message.probeOnly = !0), lastRound && lastRound.fleets.forEach(fleet => { 0 <= ownFleets.indexOf(fleet.fleetId) && fleet.technologies.forEach(tech => { tech.destroyedTotal && (message.shipLost[-tech.technologyId] = tech.destroyedTotal); }); }), message.isDefender && message.isOwnPlanet && message.result.repairedTechnologies.forEach(repaired => { message.shipLost[-repaired.technologyId] -= repaired.amount; }), message.result?.debris?.resources && (message.debris = {}, message.result.debris.resources.forEach(e => { 0 < e.remaining && (message.debris[e.resource?.replace("deuterium", "deut")] = e.remaining); })), dom && Util.addDom("div", { class: "ogl_messageButton tooltip", title: "Convert this battle", parent: dom.querySelector("message-footer-actions"), child: "C", onclick: () => window.open(Util.genConverterLink(this.ogl, message.api), "_blank") }), message.resultType && (this.summarize(message), message.probeOnly || this.statify(message)); } } else if (22 == this.tabID) { message.lifeform = parseInt(raw.dataset.rawLifeform || 0), message.expeditionResult = raw.dataset.rawExpeditionresult, message.resources = JSON.parse(raw.dataset.rawResourcesgained?.replace("deuterium", "deut")?.replace("darkMatter", "dm") || "{}"), message.artefact = parseInt(raw.dataset.rawArtifactsfound || 0), message.lfXP = parseInt(raw.dataset.rawLifeformgainedexperience || 0), message.ships = {}, message.delay = JSON.parse(raw.dataset.rawNavigation || '{ "returnTimeAbsoluteIncreaseHours":0, "returnTimeMultiplier":1 }'), message.item = JSON.parse(raw.dataset.rawItemsgained || "{}"), message.depletion = parseInt(raw.dataset.rawDepletion || 0), message.size = parseInt((raw.dataset.rawSize || raw.dataset.rawArtifactssize || "-1").replace("normal", "2").replace("big", "1").replace("huge", "0")), message.shipLost = {}; for (var [ lossID, amount ] of Object.entries(JSON.parse(raw.dataset.rawShipslost || "{}"))) message.shipLost[-lossID] = amount; ownSides = [ "nothing", "trader", "blackhole", "lifeform" ]; 61 == message.globalTypeID ? 0 < message.artefact ? message.resultType = "artefact" : 0 < message.lfXP ? message.resultType = "lifeform" : message.resultType = "nothing" : "ressources" == message.expeditionResult ? message.resultType = "resource" : "darkmatter" == message.expeditionResult ? message.resultType = "darkmatter" : "nothing" == message.expeditionResult ? message.resultType = "nothing" : "shipwrecks" == message.expeditionResult ? message.resultType = "ship" : "trader" == message.expeditionResult ? message.resultType = "trader" : "items" == message.expeditionResult ? message.resultType = "item" : "fleetLost" == message.expeditionResult ? message.resultType = "blackhole" : "navigation" == message.expeditionResult && message.delay.returnTimeMultiplier < 1 ? message.resultType = "early" : "navigation" == message.expeditionResult && (1 < message.delay.returnTimeMultiplier || 0 < message.delay.returnTimeAbsoluteIncreaseHours) ? message.resultType = "late" : "combatPirates" == message.expeditionResult ? message.resultType = "pirate" : "combatAliens" == message.expeditionResult && (message.resultType = "alien"), Object.entries(JSON.parse(raw.dataset.rawTechnologiesgained || "{}")).forEach(ship => { message.ships[ship[0]] = ship[1].amount; }), message.gain = { ...message.resources, ...message.ships, artefact: message.artefact, ["lifeform" + message.lifeform]: message.lfXP, resultType: message.resultType }, message.resultType && (0 <= ownSides.indexOf(message.resultType) && (message.size = -1), this.summarize(message), this.statify(message)); } else 23 != this.tabID && 24 != this.tabID || (message.coords = raw.dataset.rawCoords, message.debris = JSON.parse(raw.dataset.rawRecycledresources || "{}"), message.cargo = JSON.parse(raw.dataset.rawCargo || "{}"), message.gain = {}, Object.entries(message.debris).forEach(entry => { 0 < entry[1] && (message.gain[entry[0].replace("deuterium", "deut")] = entry[1], message.resultType = "debris"); }), message.debris = !1, Object.entries(message.cargo).forEach(entry => { 0 < entry[1] && (message.gain[entry[0].replace("deuterium", "deut")] = entry[1], message.resultType = "cargo"); }), message.resultType && (this.summarize(message), 24 == this.tabID) && this.statify(message)); else { if (this.spytable = document.querySelector(".ogl_spytable"), this.spytable ? this.spytable.classList.remove("ogl_hidden") : (this.spytable = Util.addDom("div", { class: "ogl_spytable", before: document.querySelector("#filteredHeadersRow") }), Util.addDom("div", { class: "ogl_spyHeader", parent: this.spytable, child: ` <b class="ogl_textCenter">#</b> <b class="material-icons" data-filter="age">schedule</b> <b class="ogl_textCenter">*</b> <b class="ogl_textCenter"> </b> <b data-filter="rawCoords">coords</b> <b data-filter="playerName">name</b> <b data-filter="wave1">loot</b> <b class="material-icons" data-filter="fleetValue">rocket_launch</b> <b class="material-icons" data-filter="defValue">security</b> <b></b> `, onclick: event => { let filter = event.target.getAttribute("data-filter"); filter && (document.querySelectorAll(".ogl_spyHeader .ogl_active").forEach(e => e.classList.remove("ogl_active")), event.target.classList.add("ogl_active"), Object.keys(this.ogl.db.spytableFilters).forEach(key => { filter.replace("DESC", "") == key ? "ASC" == this.ogl.db.spytableFilters[key] ? this.ogl.db.spytableFilters[key] = "DESC" : "DESC" == this.ogl.db.spytableFilters[key] ? this.ogl.db.spytableFilters[key] = "ASC" : this.ogl.db.spytableFilters[key] = this.filterOrder[key] : this.ogl.db.spytableFilters[key] = !1; }), this.createSpyTable()); } }).querySelector(`[data-filter="${Object.keys(this.ogl.db.spytableFilters).find(e => e && this.ogl.db.spytableFilters[e]) || "age"}"]`)?.classList.add("ogl_active")), message.playerID = raw.dataset.rawTargetplayerid, message.planetID = raw.dataset.rawTargetplanetid, message.isCounterSpy = message.playerID == this.ogl.account.id, message.playerName = raw.dataset.rawPlayername, message.playerStatus = this.ogl._highscore.nameToTagList[Array.from(msg.querySelector('.playerName span[class*="status_"]')?.classList || []).filter(e => e.startsWith("status_"))[0]], message.targetType = 1 == raw.dataset.rawTargetplanettype ? "planet" : "moon", message.targetTypeID = raw.dataset.rawTargetplanettype, message.coords = raw.dataset.rawCoordinates, message.rawCoords = Util.coordsToID(message.coords), message.age = 1e3 * parseInt(raw.dataset.rawReportage), message.isActive = parseInt(raw.dataset.rawActive), message.activity = parseInt(raw.dataset.rawActivity), message.resources = parseInt(raw.dataset.rawResources), message.metal = parseInt(raw.dataset.rawMetal), message.crystal = parseInt(raw.dataset.rawCrystal), message.deut = parseInt(raw.dataset.rawDeuterium), message.hiddenFleet = 1 == raw.dataset.rawHiddenships, message.hiddenDef = 1 == raw.dataset.rawHiddendef, message.fleet = "-" == raw.dataset.rawFleet ? {} : JSON.parse(raw.dataset.rawFleet || "{}"), message.def = "-" == raw.dataset.rawDefense ? {} : JSON.parse(raw.dataset.rawDefense || "{}"), message.loot = parseInt(raw.dataset.rawLoot), message.fleetValue = 0, message.defValue = 0, message.isAttacked = msg.querySelector(".fleetAction.fleetHostile"), (-1 == message.activity || !message.isActive && message.activity < 15) && (message.activity = 60), message.isCounterSpy) { let uid = Util.addDom("div", { child: msg.querySelector(".player").getAttribute("title") || msg.querySelector(".player").dataset.tooltipTitle }).querySelector("[data-playerid]").dataset.playerid; this.ogl.cache.counterSpies.indexOf(message.id) < 0 && msg.querySelector(".msgTitle a") && (lastRound = [ (defenderShips = new URLSearchParams(msg.querySelector(".msgTitle a").getAttribute("href"))).get("galaxy") || "0", defenderShips.get("system") || "0", defenderShips.get("position") || "0" ], ownSides = message.id, ptreCounterSpies[ownSides] = {}, ptreCounterSpies[ownSides].player_id = uid, ptreCounterSpies[ownSides].teamkey = this.ogl.ptreKey, ptreCounterSpies[ownSides].galaxy = lastRound[0], ptreCounterSpies[ownSides].system = lastRound[1], ptreCounterSpies[ownSides].position = lastRound[2], ptreCounterSpies[ownSides].spy_message_ts = parseInt(message.date.client), ptreCounterSpies[ownSides].moon = {}, ptreCounterSpies[ownSides].activity = "*", ptreCounterSpies[ownSides].moon.activity = "*"); raw = document.querySelector(`[data-msg-id="${message.id}"]`); if (raw && !raw.querySelector(".ogl_checked")) { msg = Util.addDom("div", { class: "material-icons ogl_checked ogl_mainIcon tooltip", child: "ptre", title: this.ogl._lang.find("ptreMessageDone"), parent: raw.querySelector("message-footer-actions") }); let name = raw.querySelector(".player").innerText; this.ogl._ui.turnIntoPlayerLink(uid, raw.querySelector(".player")), this.ogl.ptreKey && msg.addEventListener("click", () => { this.ogl.PTRE.getPlayerInfo({ name: name, id: uid }); }); } } else this.ogl.db.udb[message.playerID] && (this.ogl.db.udb[message.playerID].name = message.playerName, this.ogl.db.udb[message.playerID].status = message.playerStatus, this.ogl.db.udb[message.playerID].liveUpdate = serverTime.getTime()); let currentRes = message.resources, currentRenta = 0; for (let i = 1; i < 7; i++) currentRes -= currentRenta, currentRenta = Math.floor(currentRes * message.loot / 100), message["wave" + i] = currentRenta; if (message.hiddenFleet) message.fleetValue = -1; else for (let [ techID, value ] of Object.entries(message.fleet)) 200 < techID && techID < 300 && Object.entries(Datafinder.getTech(Math.abs(techID))).forEach(x => message.fleetValue += x[1] * value); if (message.hiddenDef) message.defValue = -1; else for (let [ techID, value ] of Object.entries(message.def)) 400 < techID && techID < 500 && Object.entries(Datafinder.getTech(Math.abs(techID))).forEach(x => message.defValue += x[1] * value); message.playerID != ogl.account.id && this.reportList.push(message), dom && !message.isCounterSpy && (dom.querySelector(".ogl_tagPicker") || (defenderShips = Util.addDom("div", { class: "ogl_messageButton", parent: dom.querySelector("message-footer-actions") }), this.ogl._ui.addTagButton(defenderShips, message.coords)), dom.querySelector(".ogl_trashsim") || Util.addDom("div", { class: "ogl_messageButton material-icons ogl_trashsim tooltip", title: "Simulate", parent: dom.querySelector("message-footer-actions"), child: "letter_s", onclick: () => window.open(Util.genTrashsimLink(this.ogl, message.api), "_blank") }), dom.querySelector(".ogl_ptreBtn") || this.ogl.ptreKey && Util.addDom("div", { class: "ogl_messageButton material-icons ogl_ptreBtn tooltip", title: "Send this report to PTRE", parent: dom.querySelector("message-footer-actions"), child: "ptre", onclick: () => this.ogl.PTRE.postSpyReport(message.api) })); } } }), 20 == this.tabID && this.ogl.db.options.displaySpyTable && !isTrash ? this.createSpyTable() : this.spytable && this.spytable.classList.add("ogl_hidden"), 21 != this.tabID && 22 != this.tabID && 24 != this.tabID || this.ogl._stats.miniStats(), 0 < Object.keys(ptreCounterSpies).length) && this.ogl.PTRE.postActivities(ptreCounterSpies), initTooltips(); } summarize(message) { let messageDom = document.querySelector(`[data-msg-id="${message.id}"]`); if (messageDom) { messageDom.querySelector(".ogl_battle") && messageDom.querySelector(".ogl_battle").remove(), messageDom.querySelector(".ogl_checked") || Util.addDom("div", { class: "material-icons ogl_checked ogl_mainIcon tooltip", child: "oglight_simple", title: this.ogl._lang.find("oglMessageDone"), parent: messageDom.querySelector("message-footer-actions") }); var sizes, tooltipContent = Util.addDom("ul", { class: "ogl_battleTooltip" }); let recap = Util.addDom("div", { class: "ogl_battle", "data-resultType": message.resultType || "unknown", before: messageDom.querySelector(".msg_actions"), onclick: () => { recap.classList.contains("ogl_clickable") && messageDom.querySelector(".msgContent").classList.toggle("ogl_hidden"); } }), gainSum = Object.values(message.gain).reduce((a, b) => parseInt(a) || 0 + parseInt(b) || 0, 0), gains = { ...message.gain }; if (Object.entries(message.shipLost || {}).forEach(entry => { !isNaN(entry[0]) && entry[0] < 0 && Object.entries(Datafinder.getTech(-entry[0])).forEach(res => gains[res[0]] = (gains[res[0]] || 0) - res[1] * entry[1]); }), Object.entries(gains).forEach(entry => { isNaN(entry[1]) || 0 === entry[1] ? 0 == gainSum && isNaN(entry[1]) && Util.addDom("div", { class: "ogl_icon ogl_" + entry[0], child: this.ogl._lang.find(entry[1]), parent: recap }) : Util.addDom("div", { class: "ogl_icon ogl_" + entry[0], child: Util.formatToUnits(entry[1], !1, !0), parent: recap }); }), message.debris && (message.debris.metal || 0) + (message.debris.crystal || 0) + (message.debris.deut || 0) != 0) { let recapDebris = Util.addDom("div", { class: "ogl_battle ogl_clickable", "data-resultType": "debris", before: messageDom.querySelector(".msg_actions"), onclick: () => messageDom.querySelector(".msgContent").classList.toggle("ogl_hidden") }); Object.entries(message.debris).forEach(entry => { isNaN(entry[1]) || 0 === entry[1] || Util.addDom("div", { class: "ogl_icon ogl_" + entry[0], child: Util.formatToUnits(entry[1]), parent: recapDebris }); }); } gains.metal + gains.crystal + gains.deut == 0 && Util.addDom("div", { class: "ogl_icon", child: "-", parent: recap }), message.resultType && (recap.classList.add("ogl_clickable"), 41 != message.globalTypeID && 61 != message.globalTypeID || messageDom.querySelector(".msgContent").classList.add("ogl_hidden")), message.item?.[0] && (recap.classList.add("tooltip"), tooltipContent.appendChild(Util.addDom("li", { child: `Item : <b class="ogl_highlight">${message.item?.[0].name}</b>` }))), 0 <= message.size && (sizes = { 0: "Extraordinary", 1: "Especial", 2: "Normal" }, recap.classList.add("tooltip"), tooltipContent.appendChild(Util.addDom("li", { child: `Size : <b data-size-value="${message.size}">${sizes[message.size]}</b>` })), recap.setAttribute("data-size", message.size)), 0 < message.depletion && (recap.classList.add("tooltip"), tooltipContent.appendChild(Util.addDom("li", { child: `Depletion value : <b data-depletion-value="${message.depletion}">${message.depletion}</b>` })), recap.setAttribute("data-depletion", message.depletion)), "" != tooltipContent.innerText && (recap.title = tooltipContent.innerHTML); } } statify(message) { var isP16 = 16 == (message.coords || "0:0:0").split(":")[2], isPiralien = 25 == message.globalTypeID && isP16, type = isPiralien ? "expe" : 32 == message.globalTypeID && isP16 ? "debris16" : 41 == message.globalTypeID ? "expe" : 61 == message.globalTypeID ? "discovery" : 25 == message.globalTypeID ? "raid" : 32 == message.globalTypeID && "debris", isP16 = (41 == message.globalTypeID || 61 == message.globalTypeID) && message.resultType; if (type) { var stats = this.ogl._stats.getDayStats(message.date.server); if (!(-1 < stats.ids?.indexOf(message.id))) { var gainID, amount, sign, gid, notificationData = {}; message.id && (stats.ids = stats.ids || [], stats.ids.push(message.id)), stats[type] = stats[type] || {}, isPiralien || (stats[type].count = (stats[type].count || 0) + 1), isP16 && (stats[type].occurence = stats[type].occurence || {}, stats[type].occurence[isP16] = (stats[type].occurence[isP16] || 0) + 1), message.shipLost && (message.gain = { ...message.gain, ...message.shipLost }); for ([ gainID, amount ] of Object.entries(message.gain)) isNaN(amount) || 0 == amount ? "resultType" == gainID && (notificationData[amount] = (notificationData[amount] || 0) + 1) : (sign = !isNaN(gainID) && gainID < 0 ? -1 : 1, notificationData[gid = isNaN(gainID) ? gainID : Math.abs(gainID)] = (notificationData[gid] || 0) + amount * sign, stats[type].gain = stats[type].gain || {}, stats[type].gain[gainID] = (stats[type].gain[gainID] || 0) + ("?" == amount ? 1 : amount)); document.querySelector("#ogame-tracker-menu") || this.ogl._notification.addToQueue(!1, void 0, notificationData); } } } addToSpyTable(message, wrapper) { if (!this.spytable.querySelector(`[data-id="${message.id}"]`)) { var delta = serverTime.getTime() - message.date.server, bonusFleetSpeed = 1 == this.ogl.server.warFleetSpeed ? .42 : 0; let bonusCargo = 1 + .042 * Math.ceil(delta / 36e5) + bonusFleetSpeed, messageDom = document.querySelector(`[data-msg-id="${message.id}"]`); delta = this.ogl._fleet.shipsForResources(this.ogl.db.options.defaultShip, Math.round(message.wave1 * bonusCargo)); let age = 0, line = (age = 864e5 < message.age ? Math.floor(message.age / 864e5) + LocalizationStrings.timeunits.short.day : 36e5 < message.age ? Math.floor(message.age / 36e5) + LocalizationStrings.timeunits.short.hour : Math.floor(message.age / 6e4) + LocalizationStrings.timeunits.short.minute, Util.addDom("div", { class: "ogl_spyLine", "data-id": message.id, parent: wrapper })); bonusFleetSpeed = Util.addDom("div", { parent: line }); let more = Util.addDom("div", { parent: line, class: "ogl_more ogl_hidden" }), coords = message.coords.split(":"); for (let i = 1; i < 7; i++) { let currentLoot = message["wave" + i], subLine = Util.addDom("div", { parent: more, child: `<div>${Util.formatToUnits(currentLoot)}</div>` }); this.ogl.fretShips.forEach(shipID => { var shipsCount = this.ogl._fleet.shipsForResources(shipID, currentLoot * bonusCargo); Util.addDom("a", { class: "ogl_icon ogl_" + shipID, parent: subLine, child: shipsCount.toLocaleString("de-DE") || "0", href: `https://${window.location.host}/game/index.php?page=ingame&component=fleetdispatch&galaxy=${coords[0]}&system=${coords[1]}&position=${coords[2]}&type=${message.targetTypeID}&mission=1&am${shipID}=${shipsCount}&oglmode=4&oglLazy=true` }); }); } var wrapper = message.activity < 15 ? "*" : message.activity.toString().replace("60", "-"), time = this.ogl.db.options.useClientTime ? message.date.client : message.date.server, time = (Util.addDom("span", { parent: bonusFleetSpeed, class: "ogl_textCenter" }), Util.addDom("span", { child: age, parent: bonusFleetSpeed, class: "ogl_textCenter tooltip", title: this.ogl._time.convertTimestampToDate(time, !0).innerHTML }), Util.addDom("span", { child: wrapper, parent: bonusFleetSpeed, class: "ogl_textCenter" })), wrapper = Util.addDom("span", { parent: bonusFleetSpeed }), coordsDiv = Util.addDom("span", { child: `<span data-galaxy="${message.coords}">${message.coords}</<span>`, parent: bonusFleetSpeed }), name = Util.addDom("a", { child: message.playerName, parent: bonusFleetSpeed, class: "overlay", href: `https://${window.location.host}/game/index.php?page=componentOnly&component=messagedetails&messageId=` + message.id }), delta = Util.addDom("a", { child: Util.formatToUnits(message.wave1), parent: bonusFleetSpeed, class: "ogl_textRight ogl_loot", href: `https://${window.location.host}/game/index.php?page=ingame&component=fleetdispatch&galaxy=${coords[0]}&system=${coords[1]}&position=${coords[2]}&type=${message.targetTypeID}&mission=1&am${this.ogl.db.options.defaultShip}=${delta}&oglmode=4` }), fleet = Util.addDom("span", { child: Util.formatToUnits(message.fleetValue, 0).replace("-1", "?"), parent: bonusFleetSpeed, class: "ogl_textRight" }), def = Util.addDom("span", { child: Util.formatToUnits(message.defValue, 0).replace("-1", "?"), parent: bonusFleetSpeed, class: "ogl_textRight" }), bonusFleetSpeed = Util.addDom("span", { class: "ogl_actions", parent: bonusFleetSpeed }), wrapper = (this.addSpyIcons(wrapper, message.coords, message.targetType), this.ogl._ui.addTagButton(coordsDiv, message.coords), this.ogl._ui.turnIntoPlayerLink(message.playerID, name, message.playerName), message.activity < 15 ? time.classList.add("ogl_danger") : message.activity < 60 && time.classList.add("ogl_warning"), message.wave1 >= this.ogl.db.options.resourceTreshold && delta.classList.add("ogl_important"), 0 != message.fleetValue && (fleet.style.background = "linear-gradient(192deg, #622a2a, #3c1717 70%)"), 0 != message.defValue && (def.style.background = "linear-gradient(192deg, #622a2a, #3c1717 70%)"), this.nextTarget || 0 != message.fleetValue || 0 != message.defValue || message.isAttacked || (this.nextTarget = message), Util.addDom("div", { class: "ogl_button material-icons ogl_moreButton tooltip", title: "more waves", parent: bonusFleetSpeed, child: "more_horiz", onclick: () => more.classList.toggle("ogl_hidden") }), Util.addDom("a", { class: "ogl_button material-icons tooltip", title: "attack this position !", parent: bonusFleetSpeed, child: "target", href: `https://${window.location.host}/game/index.php?page=ingame&component=fleetdispatch&galaxy=${coords[0]}&system=${coords[1]}&position=${coords[2]}&type=${message.targetTypeID}&mission=1` })); return message.isAttacked && Util.addDom("div", { class: "fleetAction fleetHostile", parent: wrapper }), Util.addDom("div", { class: "ogl_button material-icons tooltip", title: "Simulate", parent: bonusFleetSpeed, child: "letter_s", onclick: () => window.open(Util.genTrashsimLink(this.ogl, message.api), "_blank") }), this.ogl.ptreKey && Util.addDom("div", { class: "ogl_button material-icons tooltip", title: "Send this report to PTRE", parent: bonusFleetSpeed, child: "ptre", onclick: () => this.ogl.PTRE.postSpyReport(message.api) }), Util.addDom("div", { class: "ogl_button material-icons", parent: bonusFleetSpeed, child: "close", onclick: () => { $.ajax({ url: getAsJsonUrl + "&action=flagDeleted", data: { token: token, messageIds: Array.isArray(message.id) ? message.id : [ message.id ] }, type: "POST", dataType: "json", success: data => { token = data.newAjaxToken, "failure" === data.status ? showNotification(data.errors[0].message, "error") : (messageDom && messageDom.remove(), line.remove()); }, error: data => { showNotification(data.errors[0].message, "error"); } }); } }), line; } } createSpyTable() { let wrapper = Util.addDom("div", { class: "ogl_lineWrapper" }); this.spytable?.querySelector(".ogl_lineWrapper")?.remove(), this.nextTarget = !1; var filter = Object.entries(this.ogl.db.spytableFilters).find(e => 0 != e[1]); let isDesc = "DESC" == filter[1], filterKey = filter[0]; this.reportList.sort(function(a, b) { return !a[filterKey = null != !a[filterKey] && null != !b[filterKey] ? filterKey : "age"] && 0 != a[filterKey] || !b[filterKey] && 0 != b[filterKey] ? a - b : isDesc && isNaN(a[filterKey]) ? b[filterKey].localeCompare(a[filterKey]) : !isDesc && isNaN(a[filterKey]) ? a[filterKey].localeCompare(b[filterKey]) : isDesc && !isNaN(a[filterKey]) ? b[filterKey] - a[filterKey] : a[filterKey] - b[filterKey]; }).forEach(message => { this.addToSpyTable(message, wrapper); }), this.spytable?.appendChild(wrapper), initTooltips(); } checkDialog() { if (!(serverTime.getTime() - this.dialogDelay < 500)) { this.dialogDelay = serverTime.getTime(); var dialog = document.querySelector(".ui-dialog"), id = dialog.querySelector(".detail_msg")?.getAttribute("data-msg-id"), isCombat = dialog.querySelector("[data-combatreportid]"), isSpy = dialog.querySelector('[data-message-type="10"]'); if (id && isCombat && !dialog.querySelector(".ogl_messageButton")) { isCombat = dialog.querySelector(".icon_apikey"); let api = (isCombat.getAttribute("data-tooltip-title") || isCombat.getAttribute("title") || isCombat.getAttribute("data-title") || isCombat.getAttribute("data-api-code")).match(/cr-[a-z0-9-]*/)[0]; isCombat.setAttribute("data-api-code", api), Util.addDom("div", { class: "ogl_messageButton tooltip", title: "Convert this battle", parent: dialog.querySelector(".msg_actions"), child: "C", onclick: () => window.open(Util.genConverterLink(this.ogl, api), "_blank") }); } else if (id && isSpy && !dialog.querySelector(".ogl_messageButton")) { isCombat = new URLSearchParams(dialog.querySelector(".msg_title a")?.href), id = [ isCombat.get("galaxy") || "0", isCombat.get("system") || "0", isCombat.get("position") || "0" ]; let apiButton = dialog.querySelector(".icon_apikey"), api = (apiButton.getAttribute("data-tooltip-title") || apiButton.getAttribute("title") || apiButton.getAttribute("data-title") || apiButton.getAttribute("data-api-code")).match(/sr-[a-z0-9-]*/)[0]; apiButton.setAttribute("data-api-code", api), dialog.querySelector(".ogl_tagPicker") || (isSpy = Util.addDom("div", { class: "ogl_messageButton", parent: dialog.querySelector(".msg_actions") }), this.ogl._ui.addTagButton(isSpy, id)), dialog.querySelector(".ogl_trashsim") || Util.addDom("div", { class: "ogl_messageButton material-icons ogl_trashsim tooltip", parent: dialog.querySelector(".msg_actions"), child: "letter_s", onclick: () => window.open(Util.genTrashsimLink(this.ogl, api), "_blank") }), !dialog.querySelector(".ogl_ptre") && this.ogl.ptreKey && Util.addDom("div", { class: "ogl_messageButton material-icons tooltip", parent: dialog.querySelector(".msg_actions"), child: "ptre", onclick: () => this.ogl.PTRE.postSpyReport(api) }); } } } addBoardTab() { let div = Util.addDom("div", { class: "ogl_boardMessageTab", parent: document.querySelector(".mainTabs") }); Util.addDom("div", { class: "tabImage", parent: div, child: Util.addDom("div", { class: "material-icons", child: "menu_book" }) }), Util.addDom("div", { class: "tabLabel", parent: div, child: "Board.fr" }); let newMessagesCount = Util.addDom("div", { class: "newMessagesCount ogl_hidden", parent: div, child: this.ogl.db.lastBoardPosts[0] }); 0 < this.ogl.db.lastBoardPosts[0] && newMessagesCount.classList.remove("ogl_hidden"), div.addEventListener("click", () => { var wrapper = document.querySelector("#messagewrapper"); wrapper.innerText = ""; let inner = Util.addDom("div", { id: "oglBoardTab", class: "messagesHolder", parent: wrapper, child: '<div class="ogl_wrapperloading"><div class="ogl_loading"></div></div>' }); document.querySelectorAll(".mainTabs .marker").forEach(e => e.classList.remove("marker")), div.classList.add("marker"), GM_xmlhttpRequest({ method: "GET", url: "https://board.fr.ogame.gameforge.com/index.php?board-feed/101/", onload: result => { result = new DOMParser().parseFromString(result.responseText, "text/xml").querySelectorAll("item"); inner.innerText = "", result.forEach((item, index) => { var rawDate = new Date(item.querySelector("pubDate").textContent), date = rawDate.toLocaleDateString("de-DE", { day: "2-digit", month: "2-digit", year: "numeric" }), time = rawDate.toLocaleTimeString("de-DE"), msg = Util.addDom("div", { class: "msg", parent: inner }); Util.addDom("span", { class: "msg_title blue_txt", parent: msg, child: `${item.querySelector("title").textContent}<br><i>@${item.getElementsByTagName("dc:creator")[0].textContent}</i>`, onclick: () => { window.open(item.querySelector("link").textContent, "_blank"); } }), Util.addDom("span", { class: "msg_date fright ogl_CustomMessagedate", parent: msg, child: date + " " + time }), Util.addDom("div", { class: "msg_content", parent: msg, child: item.getElementsByTagName("content:encoded")[0].textContent }), 0 == index && (this.ogl.db.lastBoardPosts[1] = rawDate.getTime()); }), this.ogl._time.updateList.push(".ogl_CustomMessagedate"), this.ogl.db.lastBoardPosts[0] = 0, this.ogl.db.lastBoardPosts[2] = Date.now(), newMessagesCount.classList.add("ogl_hidden"); } }); }); } checkBoard() { var count; "undefined" != typeof GM_xmlhttpRequest && "fr" == this.ogl.server.lang && this.ogl.db.options.boardTab && (this.ogl.db.lastBoardPosts = this.ogl.db.lastBoardPosts || [ 0, 0, 0 ], Date.now() > this.ogl.db.lastBoardPosts[2] + 36e5 ? GM_xmlhttpRequest({ method: "GET", url: "https://board.fr.ogame.gameforge.com/index.php?board-feed/101/", onload: result => { var result = new DOMParser().parseFromString(result.responseText, "text/xml"); this.ogl.db.lastBoardPosts[0] = 0, result.querySelectorAll("item").forEach((item, index) => { item = new Date(item.querySelector("pubDate").textContent).getTime(); item > this.ogl.db.lastBoardPosts[1] && this.ogl.db.lastBoardPosts[0]++, 0 == index && (this.ogl.db.lastBoardPosts[1] = item); }), 0 < this.ogl.db.lastBoardPosts[0] && ((result = document.querySelector(".comm_menu.messages .new_msg_count") || Util.addDom("span", { class: "new_msg_count totalMessages news" })).innerText = parseInt(result?.innerText || 0) + this.ogl.db.lastBoardPosts[0]), this.ogl.db.lastBoardPosts[2] = Date.now(), "messages" == this.ogl.page && this.addBoardTab(); } }) : (0 < this.ogl.db.lastBoardPosts[0] && ((count = document.querySelector(".comm_menu.messages .new_msg_count") || Util.addDom("span", { class: "new_msg_count totalMessages news", parent: document.querySelector(".comm_menu.messages") })).innerText = parseInt(count?.innerText || 0) + this.ogl.db.lastBoardPosts[0]), "messages" == this.ogl.page && this.addBoardTab())); } addSpyIcons(parent, coords, uniqueType, displayActivity) { var planetIcon; if (coords = "string" == typeof coords ? coords.split(":") : coords, "planet" != uniqueType && uniqueType || (planetIcon = Util.addDom("div", { class: "material-icons ogl_spyIcon tooltip", title: this.ogl._lang.find("spyPlanet"), "data-spy-coords": `${coords[0]}:${coords[1]}:${coords[2]}:1`, child: "language", parent: parent, onclick: e => sendShips(6, coords[0], coords[1], coords[2], 1) }), lastPlanetSpy = this.ogl.db.pdb[`${coords[0]}:${coords[1]}:` + coords[2]]?.spy?.[0] || 0, serverTime.getTime() - lastPlanetSpy < this.ogl.db.options.spyIndicatorDelay && (planetIcon.setAttribute("data-spy", "recent"), planetIcon.setAttribute("title", "recently spied")), displayActivity && (lastPlanetSpy = this.ogl.db.pdb[`${coords[0]}:${coords[1]}:` + coords[2]]?.acti || [], isRecent = serverTime.getTime() - lastPlanetSpy[2] < 36e5, planetIcon = Util.addDom("span", { parent: planetIcon, child: isRecent ? lastPlanetSpy[0] : "?" }), "*" == lastPlanetSpy[0] && isRecent ? planetIcon.classList.add("ogl_danger") : 60 == lastPlanetSpy[0] && isRecent ? planetIcon.classList.add("ogl_ok") : planetIcon.classList.add("ogl_warning"))), "moon" == uniqueType || !uniqueType && this.ogl.db.pdb[`${coords[0]}:${coords[1]}:` + coords[2]]?.mid) { var lastPlanetSpy = 0 < this.ogl.db.pdb[`${coords[0]}:${coords[1]}:` + coords[2]]?.mid ? Util.addDom("div", { class: "material-icons ogl_spyIcon tooltip", title: this.ogl._lang.find("spyMoon"), "data-spy-coords": `${coords[0]}:${coords[1]}:${coords[2]}:3`, child: "bedtime", parent: parent, onclick: e => sendShips(6, coords[0], coords[1], coords[2], 3) }) : Util.addDom("div", { parent: parent }), isRecent = this.ogl.db.pdb[`${coords[0]}:${coords[1]}:` + coords[2]]?.spy?.[1] || 0; if (serverTime.getTime() - isRecent < this.ogl.db.options.spyIndicatorDelay && (lastPlanetSpy.setAttribute("data-spy", "recent"), lastPlanetSpy.setAttribute("title", "recently spied")), displayActivity && -1 < this.ogl.db.pdb[`${coords[0]}:${coords[1]}:` + coords[2]]?.mid) { let activity = this.ogl.db.pdb[`${coords[0]}:${coords[1]}:` + coords[2]]?.acti || [], isRecent = serverTime.getTime() - activity[2] < 36e5, activityDom = Util.addDom("span", { parent: lastPlanetSpy, child: isRecent ? activity[1] : "?" }); "*" == activity[1] && isRecent ? activityDom.classList.add("ogl_danger") : 60 == activity[1] && isRecent ? activityDom.classList.add("ogl_ok") : activityDom.classList.add("ogl_warning"); } } uniqueType || this.ogl.db.pdb[`${coords[0]}:${coords[1]}:` + coords[2]]?.mid || Util.addDom("div", { parent: parent }); } } class MovementManager extends Manager { load(reload) { this.ogl.cache.movements = this.ogl.cache.movements || {}, setTimeout(() => { this.eventLoaded || refreshFleetEvents(!0); }, 100), "movement" != this.ogl.page || reload || (unsafeWindow.timerHandler.pageReloadAlreadyTriggered = !0, this.updateMovement()); } addFleetIcon(data, parent, reversed) { var targetClass = reversed ? "ogl_sideIconBottom" : "ogl_sideIconTop", targetClass = parent.querySelector("." + targetClass) || Util.addDom("div", { class: targetClass, parent: parent }); Util.addDom("div", { class: "material-icons ogl_fleetIcon ogl_mission" + data[0].mission, parent: targetClass, "data-list": data.length, onclick: () => { let container = Util.addDom("div", { class: "ogl_sideFleetTooltip" }), cumul = { metal: 0, crystal: 0, deut: 0 }, total = (data.forEach(line => { var fleetImg = reversed ? "https://gf2.geo.gfsrv.net/cdn47/014a5d88b102d4b47ab5146d4807c6.gif" : "https://gf2.geo.gfsrv.net/cdnd9/f9cb590cdf265f499b0e2e5d91fc75.gif"; let shipAmount = 0, domLine = (Object.keys(line).filter(element => parseInt(element)).forEach(shipID => shipAmount += line[shipID]), Util.addDom("div", { class: `ogl_mission${line.mission} ogl_sideFleetIcon`, child: `<div class="material-icons">${line.from.isMoon ? "bedtime" : "language"}</div><div>[${line.from.coords}]</div><span>${Util.formatToUnits(shipAmount)}</span><img src="${fleetImg}"><div class="material-icons">${8 == line.mission ? "debris" : line.to.isMoon ? "bedtime" : "language"}</div><div>[${line.to.coords}]</div>`, parent: container })); [ "metal", "crystal", "deut" ].forEach(res => { Util.addDom("div", { class: "ogl_icon ogl_" + res, parent: domLine, child: Util.formatToUnits(line[res] || 0) }), cumul[res] += line[res]; }); fleetImg = this.ogl._time.getObj(line.arrivalTime, "client"), fleetImg = this.ogl.db.options.useClientTime ? fleetImg.client : fleetImg.server; domLine.prepend(this.ogl._time.convertTimestampToDate(fleetImg)); }), Util.addDom("div", { class: "ogl_sideFleetIcon", child: "<span></span><span></span><span></span><span></span><span></span><span></span><span></span>", parent: container })); [ "metal", "crystal", "deut" ].forEach(res => Util.addDom("div", { class: "ogl_icon ogl_" + res, parent: total, child: Util.formatToUnits(cumul[res] || 0) })), this.ogl._popup.open(container); } }); } updateMovement() { let emptyData = !1; 0 < document.querySelectorAll("#movementcomponent .reversal a").length && (document.querySelectorAll("#movementcomponent .reversal a")[0].setAttribute("data-key-color", "orange"), Array.from(document.querySelectorAll("#movementcomponent .reversal a")).sort((a, b) => parseInt(b.closest(".fleetDetails").getAttribute("id").replace("fleet", "")) - parseInt(a.closest(".fleetDetails").getAttribute("id").replace("fleet", "")))[0].setAttribute("data-key-color", "violet")), document.querySelectorAll(".route a").forEach((route, index) => { route.classList.add("tooltipRight"); var parent = route.closest(".fleetDetails"); let resourcesBlock = Util.addDom("div", { class: "ogl_resourcesBlock" }); var timeBlockRight, timeBlock = Util.addDom("div", { class: "ogl_timeBlock" }), actionsBlock = Util.addDom("div", { class: "ogl_actionsBlock" }), route = document.querySelector("#" + route.getAttribute("rel")); route ? (route.querySelectorAll(".fleetinfo tr").forEach(subline => { if (subline.querySelector("td") && subline.querySelector(".value")) { let name = subline.querySelector("td").innerText.replace(":", ""); var key = Object.entries(this.ogl.db.serverData).find(entry => entry[1] === name)[0], subline = parseInt(subline.querySelector(".value").innerText.replace(/\.|,| /g, "")), formattedValue = Util.formatToUnits(subline, 0); subline && (isNaN(key) ? "metal" == key ? Util.addDom("div", { class: "ogl_icon ogl_" + key, child: formattedValue, prepend: resourcesBlock }) : "crystal" == key ? Util.addDom("div", { class: "ogl_icon ogl_" + key, child: formattedValue, after: resourcesBlock.querySelector(".ogl_metal") }) : "deut" == key ? Util.addDom("div", { class: "ogl_icon ogl_" + key, child: formattedValue, after: resourcesBlock.querySelector(".ogl_crystal") }) : "food" == key && Util.addDom("div", { class: "ogl_icon ogl_" + key, child: formattedValue, after: resourcesBlock.querySelector(".ogl_deut") }) : Util.addDom("div", { class: "ogl_icon ogl_" + key, child: formattedValue, parent: resourcesBlock })); } }), 18 == parent.getAttribute("data-mission-type") && (Util.addDom("div", { class: "ogl_icon ogl_metal", child: 0, prepend: resourcesBlock }), Util.addDom("div", { class: "ogl_icon ogl_crystal", child: 0, prepend: resourcesBlock }), Util.addDom("div", { class: "ogl_icon ogl_deut", child: 0, prepend: resourcesBlock }), Util.addDom("div", { class: "ogl_icon ogl_food", child: 0, prepend: resourcesBlock })), route = Util.addDom("div", { class: "ogl_timeBlockLeft", parent: timeBlock }), timeBlockRight = Util.addDom("div", { class: "ogl_timeBlockRight", parent: timeBlock }), route.appendChild(parent.querySelector(".timer")), route.appendChild(parent.querySelector(".absTime")), route.appendChild(parent.querySelector(".originData")), route.querySelector(".originData").appendChild(route.querySelector(".originCoords")), timeBlockRight.appendChild(parent.querySelector(".destinationData")), timeBlockRight.querySelector(".destinationData").appendChild(timeBlockRight.querySelector(".destinationPlanet")), parent.querySelector(".nextabsTime") ? timeBlockRight.appendChild(parent.querySelector(".nextabsTime")) : Util.addDom("div", { child: "-", parent: timeBlockRight }), parent.querySelector(".nextTimer") ? timeBlockRight.appendChild(parent.querySelector(".nextTimer")) : Util.addDom("div", { child: "-", parent: timeBlockRight }), Util.addDom("div", { class: "ogl_icon ogl_mission" + parent.getAttribute("data-mission-type"), prepend: actionsBlock }), actionsBlock.appendChild(parent.querySelector(".route a")), parent.querySelector(".fedAttack") && actionsBlock.appendChild(parent.querySelector(".fedAttack")), parent.querySelector(".sendMail") && actionsBlock.appendChild(parent.querySelector(".sendMail")), parent.prepend(resourcesBlock), parent.prepend(timeBlock), parent.prepend(actionsBlock)) : emptyData = !0; }), emptyData || this.ogl._time.updateMovements(); } check(xml) { let movements = {}, ignored = []; xml.querySelectorAll("#eventContent tbody tr").forEach(line => { var dest, tooltip = Util.addDom("div", { child: (line.querySelector(".icon_movement .tooltip") || line.querySelector(".icon_movement_reserve .tooltip"))?.getAttribute("title") }); let movement = {}; if (movement.id = parseInt(line.getAttribute("id").replace("eventRow-", "")), movement.mission = line.getAttribute("data-mission-type"), movement.isBack = "true" === line.getAttribute("data-return-flight"), movement.arrivalTime = 1e3 * parseInt(line.getAttribute("data-arrival-time")), movement.isBack || ignored.push(movement.id + 1), !(-1 < ignored.indexOf(movement.id))) { movement.from = {}, movement.from.anotherPlayer = !Boolean(Array.from(document.querySelectorAll("#planetList .planet-koords")).find(p => p.innerText === line.querySelector(".coordsOrigin").innerText.trim().slice(1, -1))), movement.from.isMoon = Boolean(line.querySelector(".originFleet figure.moon")), movement.from.coords = line.querySelector(".coordsOrigin").innerText.trim().slice(1, -1), movement.to = {}, movement.to.anotherPlayer = !Boolean(Array.from(document.querySelectorAll("#planetList .planet-koords")).find(p => p.innerText === line.querySelector(".destCoords").innerText.trim().slice(1, -1))), movement.to.isMoon = Boolean(line.querySelector(".destFleet figure.moon")), movement.to.coords = line.querySelector(".destCoords").innerText.trim().slice(1, -1), 1 != movement.mission && 6 != movement.mission && 9 != movement.mission || !movement.from.anotherPlayer || (dest = Array.from(document.querySelectorAll("#planetList .planet-koords")).find(p => p.innerText === line.querySelector(".destCoords").innerText.trim().slice(1, -1))) && (dest = dest.closest(".smallplanet"), (movement.to.isMoon ? dest.querySelector(".moonlink") : dest.querySelector(".planetlink")).classList.add("ogl_attacked")), tooltip.querySelectorAll(".fleetinfo tr").forEach(subline => { if (subline.querySelector("td") && subline.querySelector(".value")) { let name = subline.querySelector("td").innerText.replace(":", ""); var key = Object.entries(this.ogl.db.serverData).find(entry => entry[1] === name)?.[0], subline = subline.querySelector(".value").innerText.replace(/\.|,| /g, ""); key && (movement[key] = Number(subline)); } }); let target; (target = movement.isBack ? movement.from.coords + ":B" : movement.to.anotherPlayer ? movement.from.coords : movement.from.anotherPlayer ? movement.to.coords + ":B" : movement.to.coords) && (movements[target] = movements[target] || [], movements[target].push(movement)); } }), this.ogl.cache.movements = movements, document.querySelectorAll(".smallplanet").forEach(planet => { var coords = planet.querySelector(".planet-koords").innerText; planet.querySelectorAll(".ogl_fleetIcon").forEach(e => e.remove()), this.ogl.cache?.movements?.[coords] && this.addFleetIcon(this.ogl.cache.movements[coords], planet), this.ogl.cache?.movements?.[coords + ":B"] && this.addFleetIcon(this.ogl.cache.movements[coords + ":B"], planet, !0); }), Util.runAsync(() => { this.ogl._ui.displayResourcesRecap(), this.ogl._tech.checkTodolist(), this.ogl._time.updateMovements(), initTooltips(); }); } } class HighscoreManager extends Manager { load() { this.rankingDBName = this.ogl.DBName + "-highscore", this.ogl.db.lastPTREAPIUpdate = this.ogl.db.lastPTREAPIUpdate || 0, this.tagToNameList = { n: "status_abbr_active", v: "status_abbr_vacation", I: "status_abbr_longinactive", i: "status_abbr_inactive", b: "status_abbr_banned", a: "status_abbr_admin", HONORABLE: "status_abbr_honorableTarget" }, this.nameToTagList = Object.fromEntries(Object.entries(this.tagToNameList).map(e => e.reverse())), this.nameToServerTagList = { status_abbr_inactive: this.ogl.db.serverData.inactive, status_abbr_longinactive: this.ogl.db.serverData.inactiveLong, status_abbr_banned: this.ogl.db.serverData.banned, status_abbr_vacation: this.ogl.db.serverData.vacation, status_abbr_active: !1, status_abbr_honorableTarget: "HONORABLE" }, this.turnApiStatusToName = status => status = -1 < status.indexOf("v") ? "status_abbr_vacation" : -1 < status.indexOf("I") ? "status_abbr_longinactive" : -1 < status.indexOf("i") ? "status_abbr_inactive" : -1 < status.indexOf("b") ? "status_abbr_banned" : "status_abbr_active", "highscore" == this.ogl.page && this.check(); } check() { 216e5 < serverTime.getTime() - this.ogl.db.lastPTREAPIUpdate ? this.ogl.PTRE.getRank({}, data => { 1 == data?.code && (GM_setValue(this.rankingDBName, JSON.stringify(data)), this.ogl.db.lastPTREAPIUpdate = serverTime.getTime()), this.loadData(); }) : this.loadData(); } loadData() { let typesList = { 0: "global", 1: "economy", 2: "research", 3: "military", 8: "lifeform" }; if (1 === currentCategory && typesList[currentType]) { document.querySelector("#stat_list_content").setAttribute("data-category", currentCategory), document.querySelector("#stat_list_content").setAttribute("data-type", currentType); let data = JSON.parse(GM_getValue(this.rankingDBName) || "{}"); var ts = data?.ranks_array?.[0]?.timestamp; ts && (ts = Math.floor(Math.abs(serverTime.getTime() - 1e3 * parseInt(ts)) / 36e5), document.querySelector("#ranks td.score").innerText += ` (Δ ${ts}${LocalizationStrings.timeunits.short.hour})`), document.querySelectorAll("#ranks tbody tr").forEach(line => { let id = parseInt(line.getAttribute("id").replace(/\D/g, "")); var scoreDiff, domPlayerName = line.querySelector(".playername"), ranking = parseInt(line.querySelector(".position").innerText.replace(/\D/g, "")), name = -1 < domPlayerName.innerText.indexOf("...") && this.ogl.db.udb[id]?.name ? this.ogl.db.udb[id]?.name : domPlayerName.innerText.trim(), score = line.querySelector(".score"), currentScore = parseInt(score.innerText.replace(/\D/g, "")), oldData = data?.ranks_array?.find(e => e.player_id == id); oldData && 0 == currentType && (scoreDiff = currentScore - parseInt(oldData?.total_score || "0"), score = Util.addDom("div", { class: "ogl_oldScore", child: `<em>${Util.formatNumber(new Intl.NumberFormat("de-DE", { signDisplay: "exceptZero" }).format(scoreDiff))}</em>`, parent: score }), 0 < scoreDiff ? score.classList.add("ogl_ok") : scoreDiff < 0 && score.classList.add("ogl_danger")), domPlayerName.innerText = name, this.ogl.db.udb[id]?.score?.[typesList[currentType]] && (this.ogl.db.udb[id].score[typesList[currentType]] = currentScore), this.ogl.db.udb[id]?.score?.[typesList[currentType] + "Ranking"] && (this.ogl.db.udb[id].score[typesList[currentType] + "Ranking"] = ranking), this.ogl.db.udb[id] && name.indexOf("...") < 0 && (this.ogl.db.udb[id].name = name); let status = ""; status = this.ogl.db.udb[id] && oldData && (this.ogl.db.udb[id]?.liveUpdate || 0) < 1e3 * oldData.timestamp ? (this.ogl.db.udb[id].status = this.nameToTagList[this.turnApiStatusToName(oldData.status)], this.ogl.db.udb[id].status) : this.ogl.db.udb[id] ? this.ogl.db.udb[id].status : oldData?.status ? this.nameToTagList[this.turnApiStatusToName(oldData.status)] : "n", this.ogl._ui.turnIntoPlayerLink(id, domPlayerName, !1, status), this.ogl._ui.addPinButton(line.querySelector(".highscoreNameFieldWrapper"), id); }), initTooltips(); } } } class ShortcutManager extends Manager { load() { document.querySelector(".ogl_shortcuts")?.remove(), document.querySelector(".ogl_shortCutWrapper")?.remove(), this.keyList = {}, this.shortCutWrapper = Util.addDom("div", { class: "ogl_shortCutWrapper", child: "<div></div>" }), this.shortcutDiv = Util.addDom("div", { class: "ogl_shortcuts", parent: this.ogl.db.options.shortcutsOnRight ? document.querySelector("#rechts") : this.shortCutWrapper }), this.locked = !1, this.loaded || (document.addEventListener("keydown", event => { var activeElement = document.activeElement, tooltipVisible = document.querySelector('.tippy-box[data-state="visible"]'), tooltipValidationButton = document.querySelector(".tippy-box .ogl_formValidation"), popupVisible = document.querySelector(".ogl_popup.ogl_active"), activeElement = "INPUT" == activeElement.tagName || "TEXTAREA" == activeElement.tagName; if (!event.repeat) { if ("enter" == event.key.toLowerCase() && tooltipVisible && tooltipValidationButton) return void tooltipValidationButton.click(); if ("escape" == event.key.toLowerCase() && popupVisible && !activeElement) return void this.ogl._popup.close(); } activeElement || !this.keyList[event.key.toLowerCase()] || this.locked || event.ctrlKey || event.shiftKey ? activeElement || isNaN(event.key) || !this.keyList["2-9"] || this.locked || event.ctrlKey || event.shiftKey || (this.locked = !0, this.keyList["2-9"](event.key)) : (this.locked = !0, this.keyList[event.key.toLowerCase()]()); }), document.addEventListener("keyup", () => this.locked = !1), visualViewport.addEventListener("resize", () => this.updateShortcutsPosition()), visualViewport.addEventListener("scroll", () => this.updateShortcutsPosition())), this.loaded = !0, this.add("menu", () => ( document.querySelector(".ogl_side.ogl_active .ogl_config") ? (this.ogl._ui.side.classList.remove("ogl_active"), delete this.ogl.db.currentSide) : this.ogl._topbar.openSettings(), !1)), this.add("showMenuResources", () => (this.ogl.db.options.showMenuResources++, 2 < this.ogl.db.options.showMenuResources && (this.ogl.db.options.showMenuResources = 0), localStorage.setItem("ogl_menulayout", this.ogl.db.options.showMenuResources), document.body.setAttribute("data-menulayout", this.ogl.db.options.showMenuResources), !1)), this.add("previousPlanet", () => { localStorage.setItem("ogl-redirect", !1), document.body.classList.remove("ogl_destinationPicker"), this.redirectToPlanet(-1); }), this.add("nextPlanet", () => { localStorage.setItem("ogl-redirect", !1), document.body.classList.remove("ogl_destinationPicker"), this.redirectToPlanet(1); }), isNaN(this.ogl.db.currentSide) && "tagged" != this.ogl.db.currentSide || ! document.querySelector(".ogl_side.ogl_active") || this.add("nextPinnedPosition", () => { if (!isNaN(this.ogl.db.currentSide) && document.querySelector(".ogl_side.ogl_active")) { var arr = Array.from(document.querySelectorAll(".ogl_pinDetail [data-galaxy]")), index = arr.findLastIndex(e => e.classList.contains("ogl_active")), arr = Util.reorderArray(arr, index)[1]; arr && arr.click(); } else if ("tagged" == this.ogl.db.currentSide && document.querySelector(".ogl_side.ogl_active")) { let arr = Array.from(document.querySelectorAll(".ogl_tagged [data-galaxy]")), index = arr.findLastIndex(e => e.classList.contains("ogl_active")), target = Util.reorderArray(arr, index)[1]; target && target.click(); } else fadeBox(this.ogl._lang.find("noCurrentPin"), !0); return !1; }), "fleetdispatch" == this.ogl.page ? (Util.addDom("div", { class: "ogl_separator", parent: this.shortcutDiv }), this.add("expeditionSC", () => { "fleet1" == fleetDispatcher.currentPage && this.ogl._fleet.selectExpedition(202); }, "fleet"), this.add("expeditionLC", () => { "fleet1" == fleetDispatcher.currentPage && this.ogl._fleet.selectExpedition(203); }, "fleet"), this.add("expeditionPF", () => { "fleet1" == fleetDispatcher.currentPage && this.ogl._fleet.selectExpedition(219); }, "fleet"), this.add("fleetRepeat", () => { if (!this.ogl._fleet.isReady) return !1; "fleet1" == fleetDispatcher.currentPage && (fleetDispatcher.resetShips(), Object.values(this.ogl.db.previousFleet.shipsToSend).forEach(ship => fleetDispatcher.selectShip(ship.id, ship.number))), this.ogl._fleet.setRealTarget(fleetDispatcher.realTarget, { galaxy: this.ogl.db.previousFleet.targetPlanet.galaxy, system: this.ogl.db.previousFleet.targetPlanet.system, position: this.ogl.db.previousFleet.targetPlanet.position, type: this.ogl.db.previousFleet.targetPlanet.type, name: this.ogl.db.previousFleet.targetPlanet.name }), fleetDispatcher.selectMission(this.ogl.db.previousFleet.mission), fleetDispatcher.cargoMetal = this.ogl.db.previousFleet.cargoMetal, fleetDispatcher.cargoCrystal = this.ogl.db.previousFleet.cargoCrystal, fleetDispatcher.cargoDeuterium = this.ogl.db.previousFleet.cargoDeuterium, fleetDispatcher.realSpeedPercent = this.ogl.db.previousFleet.speedPercent, fleetDispatcher.speedPercent = this.ogl.db.previousFleet.speedPercent, "fleet2" == fleetDispatcher.currentPage && fleetDispatcher.fetchTargetPlayerData(), 15 == fleetDispatcher.mission && ( document.querySelector("#fleet2 #expeditiontime").value = this.ogl.db.previousFleet.expeditionTime, document.querySelector("#fleet2 #expeditiontimeline .dropdown a").innerText = this.ogl.db.previousFleet.expeditionTime, fleetDispatcher.updateExpeditionTime()), fleetDispatcher.setFleetPercent(fleetDispatcher.realSpeedPercent), Object.values( document.querySelector("#speedPercentage"))[0].percentageBarInstance.setValue(fleetDispatcher.realSpeedPercent), fleetDispatcher.refresh(), fleetDispatcher.focusSubmitFleet1(); }, "fleet"), this.add("fleetSelectAll", () => { if (!this.ogl._fleet.isReady) return !1; "fleet1" == fleetDispatcher.currentPage ? fleetDispatcher.selectAllShips() : "fleet2" == fleetDispatcher.currentPage && fleetDispatcher.selectMaxAll(), fleetDispatcher.refresh(); }, "fleet"), this.ogl.db.quickRaidList && 0 < this.ogl.db.quickRaidList.length && this.add("quickRaid", () => { if (!this.ogl._fleet.isReady) return !1; var target, amount; "fleet1" == fleetDispatcher.currentPage && (fleetDispatcher.resetShips(), this.ogl._fleet.isQuickRaid = !0, target = this.ogl.db.quickRaidList[0].match(/.{1,3}/g).map(Number), amount = this.ogl._fleet.shipsForResources(this.ogl.db.options.defaultShip, this.ogl.db.options.resourceTreshold), fleetDispatcher.selectShip(this.ogl.db.options.defaultShip, amount), fleetDispatcher.realTarget.galaxy = target[0], fleetDispatcher.realTarget.system = target[1], fleetDispatcher.realTarget.position = target[2], fleetDispatcher.realTarget.type = 1, fleetDispatcher.selectMission(1), fleetDispatcher.targetPlanet.name = "Quick raid " + target.join(":"), fleetDispatcher.cargoMetal = 0, fleetDispatcher.cargoCrystal = 0, fleetDispatcher.cargoDeuterium = 0, fleetDispatcher.mission = 1, fleetDispatcher.speedPercent = 10, fleetDispatcher.refresh(), fleetDispatcher.focusSubmitFleet1()); }, "fleet"), this.add("fleetReverseAll", () => { if (!this.ogl._fleet.isReady) return !1; "fleet1" == fleetDispatcher.currentPage ? (fleetDispatcher.shipsOnPlanet.forEach(ship => { var delta = ship.number - (fleetDispatcher.findShip(ship.id)?.number || 0); fleetDispatcher.selectShip(ship.id, delta), fleetDispatcher.refresh(); }), fleetDispatcher.refresh(), fleetDispatcher.focusSubmitFleet1()) : "fleet2" == fleetDispatcher.currentPage && ([ "metal", "crystal", "deut", "food" ].forEach(type => { fleetDispatcher[this.ogl._fleet.cargo[type]] = Math.min(fleetDispatcher[this.ogl._fleet.resOnPlanet[type]] - fleetDispatcher[this.ogl._fleet.cargo[type]], fleetDispatcher.getFreeCargoSpace()); }), fleetDispatcher.refresh()); }, "fleet"), this.add("fleetResourcesSplit", keyNumber => { if (!this.ogl._fleet.isReady) return !1; if (this.keyNumberClickFleet1 = this.keyNumberClickFleet1 || 0, this.keyNumberClickFleet2 = this.keyNumberClickFleet2 || 0, "fleet1" == fleetDispatcher.currentPage) isNaN(keyNumber) && (keyNumber = 2 + this.keyNumberClickFleet1), this.keyNumberClickFleet2 = this.keyNumberClickFleet1, this.keyNumberClickFleet1++, 7 < this.keyNumberClickFleet1 && (this.keyNumberClickFleet1 = 0), 0 == keyNumber ? fleetDispatcher.resetShips() : fleetDispatcher.shipsOnPlanet.forEach(ship => fleetDispatcher.selectShip(ship.id, Math.ceil(ship.number / keyNumber))); else if ("fleet2" == fleetDispatcher.currentPage) { isNaN(keyNumber) && (keyNumber = 2 + this.keyNumberClickFleet2), this.keyNumberClickFleet2++, 7 < this.keyNumberClickFleet2 && (this.keyNumberClickFleet2 = 0); let fleetDispatcherResources = [ "metalOnPlanet", "crystalOnPlanet", "deuteriumOnPlanet" ]; 0 == keyNumber ? fleetDispatcher.resetCargo() : document.querySelectorAll("#fleet2 #resources .res_wrap").forEach((resource, index) => { var cargoType = [ "cargoMetal", "cargoCrystal", "cargoDeuterium" ]; let currentMax = fleetDispatcher[fleetDispatcherResources[index]]; 2 == index && (currentMax -= fleetDispatcher.getConsumption()), fleetDispatcher[cargoType[index]] = Math.max(Math.ceil(currentMax / keyNumber), 0), resource.querySelector("input").value = fleetDispatcher[cargoType[index]]; }); } fleetDispatcher.refresh(); }), this.add("fleetQuickCollect", () => { if (!this.ogl._fleet.isReady) return !1; document.querySelector(".ogl_requiredShips .ogl_" + this.ogl.db.options.defaultShip)?.click(); }), Util.addDom("div", { class: "ogl_shortcut ogl_button", "data-key": "enter", child: '<span class="material-icons">subdirectory_arrow_left</span>', parent: this.shortcutDiv, onclick: () => { if (!this.ogl._fleet.isReady) return !1; document.querySelector("#fleetdispatchcomponent").dispatchEvent(new KeyboardEvent("keypress", { keyCode: 13 })); } })) : "messages" == this.ogl.page ? (Util.addDom("div", { class: "ogl_separator", parent: this.shortcutDiv }), this.add("enter", () => { this.ogl._message.nextTarget && document.querySelector(`.ogl_spyLine[data-id="${this.ogl._message.nextTarget.id}"] .ogl_loot`).click(); })) : "galaxy" == this.ogl.page ? (Util.addDom("div", { class: "ogl_separator", parent: this.shortcutDiv }), this.add("galaxyUp", () => (submitOnKey("ArrowUp"), !1)), this.add("galaxyLeft", () => (submitOnKey("ArrowLeft"), !1)), this.add("galaxyDown", () => (submitOnKey("ArrowDown"), !1)), this.add("galaxyRight", () => (submitOnKey("ArrowRight"), !1)), this.add("galaxyReload", () => (submitForm(), !1)), this.add("galaxySpySystem", () => ( document.querySelector(".spysystemlink").click(), !1)), this.add("discovery", () => sendSystemDiscoveryMission())) : "movement" == this.ogl.page && (Util.addDom("div", { class: "ogl_separator", parent: this.shortcutDiv }), this.add("backFirstFleet", () => { document.querySelector('#movementcomponent .reversal a[data-key-color="orange"]') && document.querySelector('#movementcomponent .reversal a[data-key-color="orange"]').click(); }, !1, "orange"), this.add("backLastFleet", () => { document.querySelector('#movementcomponent .reversal a[data-key-color="violet"]') && document.querySelector('#movementcomponent .reversal a[data-key-color="violet"]').click(); }, !1, "violet")), this.ogl.db.options.shortcutsOnRight || document.body.appendChild(this.shortCutWrapper), this.updateShortcutsPosition(); } add(id, callback, type, color) { let key = this.ogl.db.options.keyboardActions[id], callBackWithMessage = ("enter" == id && (key = id, id = "attackNext"), params => { !1 !== callback(params) && this.ogl._notification.addToQueue(this.ogl._lang.find(id)); }); color = Util.addDom("div", { "data-key": key, "data-key-color": color, "data-key-id": id, class: "ogl_shortcut ogl_button tooltip", parent: this.shortcutDiv, title: this.ogl._lang.find(id), child: key.replace("enter", '<span class="material-icons">subdirectory_arrow_left</span>'), onclick: () => callBackWithMessage() }); "quickRaid" == id && (color.innerText += ` (${this.ogl.db.quickRaidList.length})`), this.keyList[key] = params => { ("fleet" != type || this.ogl._fleet.isReady && unsafeWindow.fleetDispatcher && !fleetDispatcher.fetchTargetPlayerDataTimeout) && callBackWithMessage(params); }; } updateShortcutsPosition() { var div; this.ogl.db.options.shortcutsOnRight || ((div = this.shortCutWrapper).style.top = visualViewport.offsetTop + "px", div.style.height = visualViewport.height - 25 / window.visualViewport.scale + "px", div.style.left = visualViewport.offsetLeft + "px", div.style.width = visualViewport.width + "px", this.shortcutDiv.style.gridGap = 7 / window.visualViewport.scale + "px", div.querySelectorAll(".ogl_shortcut").forEach(e => e.style.zoom = 1 / visualViewport.scale)); } redirectToPlanet(direction) { var url = new URLSearchParams(window.location.search), urlParams = {}, url = (urlParams.page = url.get("page"), urlParams.component = url.get("component"), urlParams.ogldestinationtype = url.get("ogldestinationtype"), urlParams.ogldestinationid = url.get("ogldestinationid"), urlParams.oglfirstsourceid = url.get("oglfirstsourceid"), urlParams.galaxy = url.get("galaxy"), urlParams.system = url.get("system"), urlParams.position = url.get("position"), urlParams.type = url.get("type"), this.ogl.account.planets.getCurrent()), url = urlParams.destination || url.currentType; let nextPlanet = this.ogl.account.planets.getNext(), nextPlanetWithMoon = this.ogl.account.planets.getNextWithMoon(), prevPlanet = this.ogl.account.planets.getPrev(), prevPlanetWithMoon = this.ogl.account.planets.getPrevWithMoon(); urlParams.ogldestinationid == nextPlanet.id && (nextPlanet = this.ogl.account.planets.getNext(1)), urlParams.ogldestinationid == nextPlanetWithMoon.moonID && (nextPlanetWithMoon = this.ogl.account.planets.getNextWithMoon(1)), urlParams.ogldestinationid == prevPlanet.id && (prevPlanet = this.ogl.account.planets.getPrev(1)), urlParams.ogldestinationid == prevPlanetWithMoon.moonID && (prevPlanetWithMoon = this.ogl.account.planets.getPrevWithMoon(1)); var key, value, params = {}; params.page = urlParams.page, urlParams.component && (params.component = urlParams.component), params.cp = 1 == direction ? "moon" == url ? nextPlanetWithMoon.moonID : nextPlanet.id : "moon" == url ? prevPlanetWithMoon.moonID : prevPlanet.id, 0 === direction && delete params.cp, this.ogl.mode && (params.oglmode = this.ogl.mode), urlParams.ogldestinationtype && (params.ogldestinationtype = urlParams.ogldestinationtype); for ([ key, value ] of Object.entries(urlParams)) value && (params[key] = value); 0 === direction || !this.ogl.mode || urlParams.oglfirstsourceid != nextPlanet.id && urlParams.oglfirstsourceid != nextPlanetWithMoon.moonID ? window.location.href = this.getRedirectionLink(params) : window.location.href = this.getRedirectionLink({ component: "overview", cp: params.cp }); } getRedirectionLink(params) { (params = params || {}).page = params.page || "ingame"; let link = `https://${window.location.host}/game/index.php?page=` + params.page; for (var [ key, value ] of Object.entries(params)) "page" != key && (link += `&${key}=` + value); return link; } } class TechManager extends Manager { load() { var urlTech; this.ogl.currentPlanet.obj.todolist = this.ogl.currentPlanet.obj.todolist || {}, this.initialLevel = 0, this.levelOffset = 0, this.detailCumul = {}, this.checkProductionBoxes(), unsafeWindow.technologyDetails && (technologyDetails.show = technologyId => { this.xhr && this.xhr.abort(); let wrapper = document.querySelector("#technologydetails_wrapper"), content = wrapper.querySelector("#technologydetails_content"); content.querySelector(".ogl_loading") || (content.innerHTML = '<div class="ogl_wrapperloading"><div class="ogl_loading"></div></div>'), wrapper.classList.add("ogl_active"), this.xhr = $.ajax({ url: technologyDetails.technologyDetailsEndpoint, data: { technology: technologyId } }).done(data => { data = JSON.parse(data); "failure" === data.status ? technologyDetails.displayErrors(data.errors) : (content.innerText = "", $("#technologydetails_content").append(data.content[data.target]), this.check(technologyId, wrapper)); }); }, technologyDetails.hide = () => { document.querySelector("#technologydetails_wrapper").classList.remove("ogl_active"), technologyDetails.id = !1, technologyDetails.lvl = !1; }, urlTech = new URLSearchParams(window.location.search).get("openTech")) && technologyDetails.show(urlTech), document.querySelectorAll("#technologies .technology[data-technology]").forEach(tech => { var id = tech.getAttribute("data-technology"); this.ogl.db.serverData[id] = tech.getAttribute("aria-label") || id, this.ogl.db.options.debugMode && Util.addDom("div", { style: "background:rgba(0,0,0,.8); position:relative; top:20px; text-align:center;", child: "#" + id, parent: tech.querySelector(".icon") }); }), this.ogl._topbar.checkUpgrade(), Util.overWrite("reload_page", unsafeWindow, url => { this.ogl.db.noFetch = !0; }); } check(id, details) { details.querySelector(".shipyardSelection") && details.querySelector(".sprite_large").appendChild(details.querySelector(".shipyardSelection")); var actions = Util.addDom("div", { parent: details.querySelector(".sprite") || details.querySelector(".sprite_large"), class: "ogl_actions" }); let data = Datafinder.getTech(id), amount = (this.levelOffset = 0, this.initialLevel = parseInt(details.querySelector(".information .level")?.getAttribute("data-value") || 0), details.querySelector("#build_amount")); if ( document.querySelector(`#technologies .technology[data-technology="${id}"] .targetlevel`)?.getAttribute("data-value") >= this.initialLevel && (this.initialLevel += 1), amount) { amount.addEventListener("input", () => { setTimeout(() => { let value = parseInt(amount.value) || 0; amount.value = Math.min(99999, value), amount.value && setTimeout(() => this.displayLevel(id, value, data, details)); }, 100); }), amount.setAttribute("onkeyup", "checkIntInput(this, 1, 99999);event.stopPropagation();"), amount.parentNode.querySelector(".maximum") && amount.parentNode.querySelector(".maximum").addEventListener("click", () => amount.dispatchEvent(new Event("input"))), Util.addDom("div", { parent: actions, class: "material-icons ogl_button", child: "format_list_bulleted_add", onclick: e => { this.todoData = {}; var number = amount.value && 0 < amount.value ? amount.value : 1, data = this.getTechData(id, number, this.ogl.currentPlanet.obj.id); this.todoData[id] = {}, this.todoData[id].amount = parseInt(number) || 0, this.todoData[id].id = id, this.todoData[id].metal = data.target.metal, this.todoData[id].crystal = data.target.crystal, this.todoData[id].deut = data.target.deut, this.addToTodolist(this.todoData); } }); var queueDiv = Util.addDom("div", { parent: details.querySelector(".build_amount"), class: "ogl_queueShip" }); let btn10 = Util.addDom("div", { parent: queueDiv, title: this.ogl._lang.find("repeatQueue"), class: "ogl_button ogl_queue10 tooltip", child: "Repeat x", onclick: () => { btn10.classList.add("ogl_disabled"), input10.classList.add("ogl_disabled"); let upgrade = () => { fetch(scheduleBuildListEntryUrl + (`&technologyId=${id}&amount=${amount.value || 1}&mode=1&token=` + token), { headers: { "X-Requested-With": "XMLHttpRequest" } }).then(response => response.json()).then(result => { var buildLeft = parseInt(input10.value?.replace(/\D/g, "") || 0) - 1; input10.value = buildLeft, token = result.newAjaxToken, window.stop(), 0 < buildLeft ? upgrade() : (btn10.classList.remove("ogl_disabled"), input10.classList.remove("ogl_disabled")); }); }; upgrade(); } }), input10 = Util.addDom("input", { type: "number", min: 0, max: 100, value: 1, parent: queueDiv, oninput: () => { var value = parseInt(input10.value?.replace(/\D/g, "") || 0), min = parseInt(input10.getAttribute("min")), max = parseInt(input10.getAttribute("max")); input10.value = Math.min(Math.max(value, min), max); } }); details.querySelector(".build-it_wrap .upgrade[disabled]") && (btn10.classList.add("ogl_disabled"), input10.classList.add("ogl_disabled")); } else 407 != id && 408 != id && (Util.addDom("div", { parent: actions, class: "material-icons ogl_button", child: "chevron_left", onclick: () => { this.levelOffset > 1 - this.initialLevel && (this.levelOffset--, this.displayLevel(id, this.initialLevel + this.levelOffset, data, details)); } }), Util.addDom("div", { parent: actions, class: "material-icons ogl_button", child: "close", onclick: () => { this.levelOffset = 0, this.displayLevel(id, this.initialLevel, data, details); } }), Util.addDom("div", { parent: actions, class: "material-icons ogl_button", child: "chevron_right", onclick: () => { this.levelOffset++, this.displayLevel(id, this.initialLevel + this.levelOffset, data, details); } })), Util.addDom("div", { parent: actions, class: "material-icons ogl_button", child: "format_list_bulleted_add", onclick: e => { if (0 <= this.levelOffset) { e.target.classList.add("ogl_active"), this.todoData = {}; for (let i = this.initialLevel; i <= this.initialLevel + this.levelOffset; i++) { var data = this.getTechData(id, i, this.ogl.currentPlanet.obj.id); this.todoData[i] = {}, this.todoData[i].level = i, this.todoData[i].id = id, this.todoData[i].metal = data.target.metal, this.todoData[i].crystal = data.target.crystal, this.todoData[i].deut = data.target.deut; } this.addToTodolist(this.todoData); } else this.ogl._notification.addToQueue("Cannot lock previous levels", !1); } }); this.displayLevel(id, this.initialLevel, data, details); } displayLevel(id, lvl, data, details) { let techData = this.getTechData(id, lvl, this.ogl.currentPlanet.obj.id), cumul = {}; this.detailCumul[id] = this.detailCumul[id] || {}, this.detailCumul[id][lvl] = this.detailCumul[id][lvl] || {}; for (var [ costID, cost ] of Object.entries(techData.target || {})) this.detailCumul[id][lvl][costID] = cost; for (var [ cumulLvl, cumulCost ] of Object.entries(this.detailCumul[id] || {})) cumulLvl >= this.initialLevel && cumulLvl <= this.initialLevel + this.levelOffset && Object.entries(cumulCost).forEach(entry => { "energy" == entry[0] || "population" == entry[0] ? cumul[entry[0]] = entry[1] : cumul[entry[0]] = (cumul[entry[0]] || 0) + entry[1]; }); unsafeWindow.technologyDetails && (technologyDetails.id = id, technologyDetails.lvl = lvl), this.ogl.db.options.debugMode && !details.querySelector("[data-debug]") && (details.querySelector(".build_duration time").setAttribute("data-debug", details.querySelector(".build_duration time").innerText), details.querySelector(".information .level") && details.querySelector(".information .level").setAttribute("data-debug", details.querySelector(".information .level").innerText), details.querySelector(".costs .metal") && details.querySelector(".costs .metal").setAttribute("data-debug", details.querySelector(".costs .metal").innerText), details.querySelector(".costs .crystal") && details.querySelector(".costs .crystal").setAttribute("data-debug", details.querySelector(".costs .crystal").innerText), details.querySelector(".costs .deuterium") && details.querySelector(".costs .deuterium").setAttribute("data-debug", details.querySelector(".costs .deuterium").innerText), details.querySelector(".costs .energy") && details.querySelector(".costs .energy").setAttribute("data-debug", details.querySelector(".costs .energy").innerText), details.querySelector(".costs .population") && details.querySelector(".costs .population").setAttribute("data-debug", details.querySelector(".costs .population").innerText), details.querySelector(".additional_energy_consumption .value") && details.querySelector(".additional_energy_consumption .value").setAttribute("data-debug", details.querySelector(".additional_energy_consumption .value").innerText), details.querySelector(".energy_production .value")) && details.querySelector(".energy_production .value").setAttribute("data-debug", details.querySelector(".energy_production .value").innerText); let costsWrapper = details.querySelector(".ogl_costsWrapper") || Util.addDom("div", { class: "ogl_costsWrapper", parent: details.querySelector(".costs") }); costsWrapper.innerText = "", details.querySelector(".build_duration time").innerText = techData.target.timeresult, details.querySelector(".additional_energy_consumption .value") && ((element = details.querySelector(".additional_energy_consumption .value")).classList.add("tooltip"), 217 == id && (techData.target.conso = parseInt(element.getAttribute("data-value")) * (lvl || 1)), element.setAttribute("title", Util.formatNumber(techData.target.conso)), element.innerHTML = Util.formatToUnits(techData.target.conso, !1, !0)), details.querySelector(".energy_production .value") && (details.querySelector(".energy_production .value").innerHTML = `<span class="bonus">+${Util.formatToUnits(techData.target.prodEnergy, !1, !0)}</span>`), details.querySelector(".information .level") && (details.querySelector(".information .level").innerHTML = lvl - 1 + ` <i class="material-icons">east</i> <b>${lvl}</b>`, this.ogl.currentPlanet.obj.todolist[id]?.[lvl] ? details.querySelector(".ogl_actions .ogl_button:last-child").classList.add("ogl_active") : details.querySelector(".ogl_actions .ogl_button:last-child").classList.remove("ogl_active")), details.querySelector(".required_population") && details.querySelector(".required_population span").setAttribute("data-formatted", Util.formatToUnits(details.querySelector(".required_population span").getAttribute("data-value"), 0).replace(/<[^>]+>/g, "")); var element = Util.addDom("div", { class: "ogl_icon", parent: costsWrapper }); Util.addDom("div", { parent: element }), Util.addDom("div", { parent: element, child: Math.max(lvl, 1) }), details.querySelector(".build_amount") || 407 == id || 408 == id || Util.addDom("div", { parent: element, child: this.initialLevel - 1 + ' <i class="material-icons">east</i> ' + (this.initialLevel + this.levelOffset) }), Util.addDom("div", { parent: element, class: "material-icons", child: "globe" }); let rawText; [ "metal", "crystal", "deut", "energy", "population" ].forEach(resource => { var diff, line; details.querySelector(".costs ." + resource.replace("deut", "deuterium")) && (diff = details.querySelector(".build_amount") ? (this.ogl.currentPlanet.obj[resource] || 0) - (techData.target[resource] || 0) : (this.ogl.currentPlanet.obj[resource] || 0) - (cumul[resource] || 0), line = Util.addDom("div", { class: "ogl_icon ogl_" + resource, parent: costsWrapper }), Util.addDom("div", { class: "tooltip", title: Util.formatNumber(techData.target[resource]), parent: line, child: Util.formatToUnits(techData.target[resource], 2) }), details.querySelector(".build_amount") || Util.addDom("div", { parent: line, class: "ogl_text tooltip", title: Util.formatNumber(cumul[resource]), child: Util.formatToUnits(cumul[resource], 2) }), diff < 0 ? Util.addDom("div", { parent: line, class: "ogl_danger tooltip", title: Util.formatNumber(diff), child: Util.formatToUnits(diff, 2) }) : Util.addDom("div", { parent: line, class: "ogl_ok material-icons", child: "check" }), rawText = (rawText ? rawText + " | " : "") + Util.formatNumber(cumul[resource]) + " " + this.ogl._lang.find(resource)); }), details.querySelector(".costs").addEventListener("click", () => { navigator.clipboard.writeText(rawText), fadeBox("Price copied"); }); var element = this.ogl.db.options.msu, msuline = Util.addDom("div", { class: "ogl_icon ogl_msu", parent: costsWrapper }), msu = Util.getMSU(techData.target.metal, techData.target.crystal, techData.target.deut, element), msu = (Util.addDom("div", { class: "tooltip", title: Util.formatNumber(msu), parent: msuline, child: Util.formatToUnits(msu, 2) }), Util.getMSU(cumul.metal, cumul.crystal, cumul.deut, element)); details.querySelector(".build_amount") || Util.addDom("div", { parent: msuline, class: "ogl_text tooltip", title: Util.formatNumber(msu), child: Util.formatToUnits(msu, 2) }), initTooltips(); } addToTodolist(data) { this.ogl.currentPlanet.obj.todolist = this.ogl.currentPlanet.obj.todolist || {}, Object.values(data).forEach(entry => { var todolist = this.ogl.currentPlanet.obj.todolist, entryLvl = entry.level || Date.now() + performance.now(); todolist[entry.id] = todolist[entry.id] || {}, todolist[entry.id][entryLvl] = todolist[entry.id][entryLvl] || {}, todolist[entry.id][entryLvl].id = entry.id, todolist[entry.id][entryLvl].amount = entry.amount || 0, todolist[entry.id][entryLvl].level = entryLvl, todolist[entry.id][entryLvl].cost = { metal: entry.metal, crystal: entry.crystal, deut: entry.deut }; }), this.checkTodolist(); } checkTodolist() { document.querySelectorAll(".planetlink, .moonlink").forEach(planet => { let isMoon = planet.classList.contains("moonlink"); var targetClass; isMoon ? planet.parentNode.querySelectorAll(".ogl_todoIcon.ogl_moon").forEach(i => i.remove()) : planet.parentNode.querySelectorAll(".ogl_todoIcon.ogl_planet").forEach(i => i.remove()); let id = new URLSearchParams(planet.getAttribute("href")).get("cp").split("#")[0], len = 0, icon; Object.values(this.ogl.db.myPlanets[id]?.todolist || {}).forEach((building, index) => { 0 == index && (icon = Util.addDom("div", { class: "material-icons ogl_todoIcon", child: "format_list_bulleted", onclick: () => { this.openTodolist(this.ogl.db.myPlanets[id].todolist, planet.parentNode.querySelector(".planet-koords").innerText + ":" + (isMoon ? 3 : 1), id); } })), Object.values(building).forEach(line => { len++, (line.cost?.metal || 0) + (line.cost?.crystal || 0) + (line.cost?.deut || 0) <= 0 && icon.classList.add("ogl_ok"); }); }), icon && (targetClass = isMoon ? "ogl_sideIconBottom" : "ogl_sideIconTop", targetClass = planet.parentNode.querySelector("." + targetClass) || Util.addDom("div", { class: targetClass, parent: planet.parentNode }), isMoon ? icon.classList.add("ogl_moon") : icon.classList.add("ogl_planet"), icon.setAttribute("data-list", len), targetClass.appendChild(icon)); }); let requireUpdate = !1; document.querySelectorAll(".technology[data-technology]").forEach(techDom => { let techID = techDom.getAttribute("data-technology"), techLvL = techDom.querySelector(".targetlevel") || techDom.querySelector(".level"); techLvL && (techLvL = parseInt(techLvL.getAttribute("data-value")), Object.keys(this.ogl.currentPlanet.obj.todolist?.[techID] || {}).forEach(key => { techLvL >= parseInt(key) && (delete this.ogl.currentPlanet.obj.todolist[techID][key], Object.values(this.ogl.currentPlanet.obj.todolist[techID]).length < 1) && (delete this.ogl.currentPlanet.obj.todolist[techID], requireUpdate = !0); })); }), requireUpdate && this.checkTodolist(); } openTodolist(data, coords, id) { let toSend = {}; coords = coords.split(":"); let container = Util.addDom("div", { class: "ogl_todoList", child: `<h2>Todolist ${1 == coords[3] ? "planet" : "moon"} [${coords[0]}:${coords[1]}:${coords[2]}]</h2>` }), leftDiv = Util.addDom("div", { parent: container }), rightDiv = Util.addDom("div", { parent: container, class: "ogl_actions" }), totalReq = {}, totalSelected = {}, updateHeader = (blockData, header, content, footer, block) => { setTimeout(() => { var checkedCount = content.querySelectorAll("input:checked").length, maxCount = Object.keys(blockData).length; let blockID = Object.values(blockData)[0]?.id; maxCount ? (header.innerHTML = this.ogl.db.serverData[blockID], header.innerHTML += ` (<b>${checkedCount}</b>/${maxCount})`, checkedCount != maxCount && footer && footer.querySelector("input:checked") && (footer.querySelector("input:checked").checked = !1), 0 < Object.entries(toSend).length ? sendButton.classList.remove("ogl_disabled") : sendButton.classList.add("ogl_disabled"), updateTotal()) : (block.remove(), Object.keys(toSend).filter(k => k.startsWith(blockID + "_")).forEach(k => delete toSend[k]), delete this.ogl.db.myPlanets[id].todolist[blockID], this.checkTodolist()); }); }, updateTotal = () => { totalDiv.innerHTML = ` <div class="ogl_grid"> <div class="ogl_icon"><div class="material-icons">sigma</div><div>Required</div><div>Selected</div></div> <div class="ogl_icon ogl_metal"><div>${Util.formatToUnits(totalReq.metal || 0)}</div><div>${Util.formatToUnits(totalSelected.metal || 0)}</div></div> <div class="ogl_icon ogl_crystal"><div>${Util.formatToUnits(totalReq.crystal || 0)}</div><div>${Util.formatToUnits(totalSelected.crystal || 0)}</div></div> <div class="ogl_icon ogl_deut"><div>${Util.formatToUnits(totalReq.deut || 0)}</div><div>${Util.formatToUnits(totalSelected.deut || 0)}</div></div> </div> `; }, updateFooter = (footer, content, cumul) => { setTimeout(() => { footer.innerHTML = ""; var line = Util.addDom("div", { class: "ogl_line ogl_blockRecap", parent: footer, child: ` <div>all</div> <div class="ogl_icon ogl_metal">${Util.formatToUnits(cumul.metal, 2)}</div> <div class="ogl_icon ogl_crystal">${Util.formatToUnits(cumul.crystal, 2)}</div> <div class="ogl_icon ogl_deut">${Util.formatToUnits(cumul.deut, 2)}</div> <label></label> ` }); let input = Util.addDom("input", { type: "checkbox", parent: line.querySelector("label"), oninput: () => { input.checked ? content.querySelectorAll("input").forEach(input => { 1 != input.checked && input.click(); }) : content.querySelectorAll("input").forEach(input => { 1 == input.checked && input.click(); }); } }); Util.addDom("button", { class: "material-icons", parent: line, child: "cube-send", onclick: () => { content.querySelectorAll("input").forEach(input => { 1 != input.checked && input.click(); }), setTimeout(() => container.querySelector(".ogl_button").click(), 50); } }), Util.addDom("button", { class: "material-icons ogl_removeTodo", parent: line, child: "close", onclick: () => { content.querySelectorAll(".ogl_removeTodo").forEach(button => { button.click(); }), setTimeout(() => updateTotal(), 10); } }); }); }, url = (Object.values(data).forEach(blockData => { let block = Util.addDom("div", { class: "ogl_tech", parent: leftDiv }), header = Util.addDom("h3", { parent: block, onclick: () => block.classList.toggle("ogl_active") }), content = Util.addDom("div", { parent: block }), footer = Util.addDom("footer", { parent: block }), cumul = {}; Object.values(blockData).forEach(todo => { var displayedCell = todo.amount || todo.level; let key = todo.id + "_" + todo.level, line = Util.addDom("div", { class: "ogl_line", "data-parent": this.ogl.db.serverData[todo.id], parent: content, child: ` <div>${displayedCell}</div><div class="ogl_icon ogl_metal">${Util.formatToUnits(todo.cost?.metal, 2)}</div> <div class="ogl_icon ogl_crystal">${Util.formatToUnits(todo.cost?.crystal, 2)}</div> <div class="ogl_icon ogl_deut">${Util.formatToUnits(todo.cost?.deut, 2)}</div> <label></label> ` }), input = (cumul.metal = (cumul.metal || 0) + (todo.cost?.metal || 0), cumul.crystal = (cumul.crystal || 0) + (todo.cost?.crystal || 0), cumul.deut = (cumul.deut || 0) + (todo.cost?.deut || 0), totalReq.metal = (totalReq.metal || 0) + (todo.cost?.metal || 0), totalReq.crystal = (totalReq.crystal || 0) + (todo.cost?.crystal || 0), totalReq.deut = (totalReq.deut || 0) + (todo.cost?.deut || 0), Util.addDom("input", { type: "checkbox", parent: line.querySelector("label"), oninput: () => { input.checked ? (toSend[key] = todo, input.setAttribute("data-clicked", performance.now()), totalSelected.metal = (totalSelected.metal || 0) + (todo.cost?.metal || 0), totalSelected.crystal = (totalSelected.crystal || 0) + (todo.cost?.crystal || 0), totalSelected.deut = (totalSelected.deut || 0) + (todo.cost?.deut || 0)) : (delete toSend[key], input.removeAttribute("data-clicked"), totalSelected.metal = (totalSelected.metal || 0) - (todo.cost?.metal || 0), totalSelected.crystal = (totalSelected.crystal || 0) - (todo.cost?.crystal || 0), totalSelected.deut = (totalSelected.deut || 0) - (todo.cost?.deut || 0)), leftDiv.querySelectorAll("label").forEach(e => e.removeAttribute("data-order")), Array.from(leftDiv.querySelectorAll(".ogl_tech > div input:checked")).sort((a, b) => a.getAttribute("data-clicked") - b.getAttribute("data-clicked")).forEach((e, index) => { e.parentNode.setAttribute("data-order", index + 1); }), updateHeader(blockData, header, content, footer, block); } })); Util.addDom("button", { class: "material-icons", parent: line, child: "cube-send", onclick: () => { input.click(), setTimeout(() => container.querySelector(".ogl_button").click(), 50); } }), Util.addDom("button", { class: "material-icons ogl_removeTodo", parent: line, child: "close", onclick: () => { line.remove(), cumul.metal = (cumul.metal || 0) - (todo.cost?.metal || 0), cumul.crystal = (cumul.crystal || 0) - (todo.cost?.crystal || 0), cumul.deut = (cumul.deut || 0) - (todo.cost?.deut || 0), totalSelected.metal = (totalSelected.metal || 0) - (todo.cost?.metal || 0), totalSelected.crystal = (totalSelected.crystal || 0) - (todo.cost?.crystal || 0), totalSelected.deut = (totalSelected.deut || 0) - (todo.cost?.deut || 0), delete toSend[key], delete this.ogl.db.myPlanets[id].todolist[todo.id][todo.level], Object.keys(this.ogl.db.myPlanets[id].todolist[todo.id] || {}).length <= 0 && (delete this.ogl.db.myPlanets[id].todolist[todo.id], block.remove()), Object.keys(ogl.db.myPlanets[id].todolist || {}).length <= 0 && (this.ogl.db.myPlanets[id].todolist = {}, this.ogl._popup.close()), Array.from(leftDiv.querySelectorAll(".ogl_tech > div input:checked")).sort((a, b) => a.getAttribute("data-clicked") - b.getAttribute("data-clicked")).forEach((e, index) => { e.parentNode.setAttribute("data-order", index + 1); }), unsafeWindow.technologyDetails && id == this.ogl.currentPlanet.obj.id && document.querySelector("#technologydetails .ogl_actions .ogl_active") && document.querySelector("#technologydetails .ogl_actions .ogl_active").classList.remove("ogl_active"), updateHeader(blockData, header, content, footer, block), updateFooter(footer, content, cumul), this.checkTodolist(); } }); }), updateHeader(blockData, header, content, footer, block), updateFooter(footer, content, cumul); }), `https://${window.location.host}/game/index.php?page=ingame&component=fleetdispatch&galaxy=${coords[0]}&system=${coords[1]}&position=${coords[2]}&oglmode=3&targetid=${id}&type=` + coords[3]), sendButton = Util.addDom("button", { class: "ogl_button ogl_disabled", parent: rightDiv, child: 'Send selection <i class="material-icons">cube-send</i>', onclick: () => { this.ogl.cache.toSend = Object.values(toSend), substractButton.querySelector("input").checked && (url += "&substractMode=true"), window.location.href = url, rightDiv.querySelectorAll(".ogl_button").forEach(e => e.classList.add("ogl_disabled")); } }), substractButton = (Util.addDom("button", { class: "ogl_button", parent: rightDiv, child: 'Send all <i class="material-icons">cube-send</i>', onclick: () => { leftDiv.querySelectorAll("input").forEach(input => { 1 != input.checked && input.click(); }), setTimeout(() => { this.ogl.cache.toSend = Object.values(toSend), rightDiv.querySelectorAll(".ogl_button").forEach(e => e.classList.add("ogl_disabled")), substractButton.querySelector("input").checked && (url += "&substractMode=true"), window.location.href = url; }, 100); } }), Util.addDom("button", { class: "ogl_button ogl_removeTodo", parent: rightDiv, child: 'Remove all <i class="material-icons">close</i>', onclick: () => { this.ogl.db.myPlanets[id].todolist = {}, this.ogl._popup.close(), this.checkTodolist(), unsafeWindow.technologyDetails && id == this.ogl.currentPlanet.obj.id && document.querySelector("#technologydetails .ogl_actions .ogl_active") && document.querySelector("#technologydetails .ogl_actions .ogl_active").classList.remove("ogl_active"); } }), Util.addDom("label", { class: "ogl_button", parent: rightDiv, child: '<input type="checkbox">Substract planet resources' })), totalDiv = Util.addDom("div", { class: "ogl_totalRequired", parent: rightDiv }); this.ogl._popup.open(container); } getTechData(id, level, planetID) { if (id) { var data = Datafinder.getTech(id), planetData = this.ogl.db.myPlanets[planetID] || {}; let baseLabs = [], bestLabs = 0, labRequired = { 113: 1, 120: 1, 121: 4, 114: 7, 122: 4, 115: 1, 117: 2, 118: 7, 106: 3, 108: 1, 124: 3, 123: 10, 199: 12, 109: 4, 110: 6, 111: 2 }; document.querySelectorAll(".smallplanet").forEach(line => { var line = line.getAttribute("id").replace("planet-", ""), colo = this.ogl.db.myPlanets[line]; colo && planetID != line && colo[31] >= labRequired[id] && baseLabs.push(colo[31]); }), baseLabs.sort((a, b) => b - a), (baseLabs = baseLabs.slice(0, Math.min(baseLabs.length, planetData[123]))).length && (bestLabs = baseLabs.reduce((a, b) => a + b)); var planet = {}, tech = (planet.lifeform = planetData.lifeform || 0, this.totalLab = (planetData[31] || 0) + bestLabs, {}), data = (tech.id = id, tech.isBaseBuilding = tech.id < 100, tech.isBaseResearch = 100 < tech.id && tech.id <= 199, tech.isBaseShip = 200 < tech.id && tech.id <= 299, tech.isBaseDef = 400 < tech.id && tech.id <= 599, tech.isLfBuilding = 11100 < tech.id && tech.id <= 11199 || 12100 < tech.id && tech.id <= 12199 || 13100 < tech.id && tech.id <= 13199 || 14100 < tech.id && tech.id <= 14199, tech.isLfResearch = 11200 < tech.id && tech.id <= 11299 || 12200 < tech.id && tech.id <= 12299 || 13200 < tech.id && tech.id <= 13299 || 14200 < tech.id && tech.id <= 14299, tech.base = {}, tech.base.metal = data.metal || 0, tech.base.crystal = data.crystal || 0, tech.base.deut = data.deut || 0, tech.base.energy = data.energy || 0, tech.base.duration = data.durationbase || 0, tech.base.conso = data.conso || 0, tech.base.population = data.bonus1BaseValue || 0, tech.factor = {}, tech.factor.price = data.priceFactor || 2, tech.factor.duration = data.durationfactor || 2, tech.factor.energy = data.energyFactor || data.energyIncreaseFactor || 2, tech.factor.population = data.bonus1IncreaseFactor || 2, tech.bonus = {}, tech.bonus.price = 0, tech.bonus.duration = 0, tech.bonus.classDuration = 0, tech.bonus.eventDuration = 0, tech.bonus.technocrat = 0, tech.bonus.engineer = 0, tech.bonus.conso = 0, tech.bonus.prodEnergy = 0, 1 == this.ogl.account.class && (tech.bonus.prodEnergy += .1), 2 == this.ogl.db.allianceClass && (tech.bonus.prodEnergy += .05), 2 == planet.lifeform ? (tech.bonus.prodEnergy += planetData[12107] * Datafinder.getTech(12107).bonus1BaseValue / 100, tech.bonus.conso += planetData[12107] * Datafinder.getTech(12107).bonus2BaseValue / 100, tech.isLfBuilding && (tech.bonus.price += planetData[12108] * Datafinder.getTech(12108).bonus1BaseValue / 100, tech.bonus.duration += planetData[12108] * Datafinder.getTech(12108).bonus2BaseValue / 100)) : 3 == planet.lifeform && (tech.bonus.prodEnergy += planetData[13107] * Datafinder.getTech(13107).bonus1BaseValue / 100, tech.isBaseShip || tech.isBaseDef) && (tech.bonus.duration += planetData[13106] * Datafinder.getTech(13106).bonus1BaseValue / 100), tech.isBaseResearch && document.querySelector(".technology .acceleration") && (tech.bonus.eventDuration += parseInt( document.querySelector(".technology .acceleration").getAttribute("data-value")) / 100), tech.isBaseResearch && 3 == this.ogl.account.class && (tech.bonus.classDuration += .25 * (1 + (this.ogl.db.lfBonuses?.Characterclasses3?.bonus || 0) / 100)), tech.isBaseResearch && document.querySelector("#officers .technocrat.on") && (tech.bonus.technocrat += .25), document.querySelector("#officers .engineer.on") && (tech.bonus.engineer += .1), tech.isLfResearch && (1 == planet.lifeform ? (tech.bonus.price += planetData[11103] * Datafinder.getTech(11103).bonus1BaseValue / 100, tech.bonus.duration += planetData[11103] * Datafinder.getTech(11103).bonus2BaseValue / 100) : 2 == planet.lifeform ? (tech.bonus.price += planetData[12103] * Datafinder.getTech(12103).bonus1BaseValue / 100, tech.bonus.duration += planetData[12103] * Datafinder.getTech(12103).bonus2BaseValue / 100) : 3 == planet.lifeform ? (tech.bonus.price += planetData[13103] * Datafinder.getTech(13103).bonus1BaseValue / 100, tech.bonus.duration += planetData[13103] * Datafinder.getTech(13103).bonus2BaseValue / 100) : 4 == planet.lifeform && (tech.bonus.price += planetData[14103] * Datafinder.getTech(14103).bonus1BaseValue / 100, tech.bonus.duration += planetData[14103] * Datafinder.getTech(14103).bonus2BaseValue / 100), tech.bonus.price += (this.ogl.db.lfBonuses?.LfResearch?.cost || 0) / 100, tech.bonus.duration += (this.ogl.db.lfBonuses?.LfResearch?.duration || 0) / 100), 2 != planet.lifeform || 1 != tech.id && 2 != tech.id && 3 != tech.id && 4 != tech.id && 12 != tech.id && 12101 != tech.id && 12102 != tech.id || (tech.bonus.price += planetData[12111] * Datafinder.getTech(12111).bonus1BaseValue / 100), (tech.isBaseResearch || tech.isBaseDef || tech.isBaseShip) && (tech.bonus.price += (this.ogl.db.lfBonuses?.[tech.id]?.cost || 0) / 100, tech.bonus.duration += (this.ogl.db.lfBonuses?.[tech.id]?.duration || 0) / 100), tech.target = {}, tech.isBaseBuilding || tech.isBaseResearch ? (data = Math.floor(tech.base.metal * Math.pow(tech.factor.price, level - 1)), planet = Math.floor(tech.base.crystal * Math.pow(tech.factor.price, level - 1)), rawDeut = Math.floor(tech.base.deut * Math.pow(tech.factor.price, level - 1)), tech.target.metal = Math.floor(data * (1 - tech.bonus.price)), tech.target.crystal = Math.floor(planet * (1 - tech.bonus.price)), tech.target.deut = Math.floor(rawDeut * (1 - tech.bonus.price)), tech.target.energy = Math.floor(tech.base.energy * Math.pow(tech.factor.energy, level - 1)), 1 != tech.id && 2 != tech.id || (tech.target.conso = Math.ceil(10 * level * Math.pow(1.1, level)) - Math.ceil(10 * (level - 1) * Math.pow(1.1, level - 1))), 3 == tech.id && (tech.target.conso = Math.ceil(20 * level * Math.pow(1.1, level)) - Math.ceil(20 * (level - 1) * Math.pow(1.1, level - 1))), 4 == tech.id && (tech.target.prodEnergy = Math.floor(20 * level * Math.pow(1.1, level)) - Math.floor(20 * (level - 1) * Math.pow(1.1, level - 1))), 12 == tech.id && (tech.target.prodEnergy = Math.floor(30 * level * Math.pow(1.05 + .01 * (planetData[113] || 0), level)) - Math.floor(30 * (level - 1) * Math.pow(1.05 + .01 * (planetData[113] || 0), level - 1))), tech.target.duration = tech.isBaseBuilding ? (data + planet) / (2500 * Math.max(41 == id || 42 == id || 43 == id || 15 == id ? 1 : 4 - level / 2, 1) * (1 + (14 == id ? this.initialLevel + this.levelOffset - 1 : planetData[14]) || 0) * Math.pow(2, (15 == id ? this.initialLevel + this.levelOffset - 1 : planetData[15]) || 0)) * 3600 * 1e3 : (data + planet) / (1e3 * (1 + (planetData[31] || 0) + bestLabs)) * 3600 * 1e3) : tech.isLfBuilding || tech.isLfResearch ? (tech.target.metal = Math.floor(Math.floor(tech.base.metal * Math.pow(tech.factor.price, level - 1) * level) * (1 - tech.bonus.price)), tech.target.crystal = Math.floor(Math.floor(tech.base.crystal * Math.pow(tech.factor.price, level - 1) * level) * (1 - tech.bonus.price)), tech.target.deut = Math.floor(Math.floor(tech.base.deut * Math.pow(tech.factor.price, level - 1) * level) * (1 - tech.bonus.price)), tech.target.energy = Math.floor(Math.floor(level * tech.base.energy * Math.pow(tech.factor.energy, level) * (1 - tech.bonus.price))), tech.target.population = Math.floor(Math.floor(tech.base.population * Math.pow(tech.factor.population, level - 1) * (1 - tech.bonus.price))), tech.target.conso = level < 2 ? Math.floor(level * tech.base.energy) : Math.floor(Math.floor(level * tech.base.energy * Math.pow(tech.factor.energy, level) - (level - 1) * tech.base.energy * Math.pow(tech.factor.energy, level - 1))), tech.target.duration = tech.isLfBuilding ? Math.floor(level * tech.base.duration * 1e3 * (1 / ((1 + (planetData[14] || 0)) * Math.pow(2, planetData[15] || 0))) * Math.pow(tech.factor.duration, level)) : Math.floor(level * tech.base.duration * 1e3 * Math.pow(tech.factor.duration, level))) : (tech.isBaseShip || tech.isBaseDef) && (tech.target.metal = tech.base.metal * (rawDeut = level || 1), tech.target.crystal = tech.base.crystal * rawDeut, tech.target.deut = tech.base.deut * rawDeut, tech.target.duration = (tech.base.metal + tech.base.crystal) / 5e3 * (2 / (1 + planetData[21] || 0)) * Math.pow(.5, planetData[15] || 0) * 3600 * 1e3, 212 == tech.id) && (tech.target.prodEnergy = Math.floor(((planetData.temperature + 40 + planetData.temperature) / 2 + 160) / 6) * rawDeut), this.ogl.db.options.debugMode && console.log(JSON.parse(JSON.stringify(tech))), tech.target.prodEnergy = Math.floor(tech.target.prodEnergy * (1 + tech.bonus.prodEnergy + tech.bonus.engineer)) || 0, tech.target.conso = -Math.ceil(tech.target.conso * (1 - tech.bonus.conso)) || 0, tech.target.duration = tech.target.duration / (this.ogl.server.economySpeed * (tech.isBaseResearch ? this.ogl.db.serverData.researchSpeed : 1)) * (1 - tech.bonus.eventDuration) * (1 - tech.bonus.classDuration) * (1 - tech.bonus.technocrat) * (1 - Math.min(tech.bonus.duration, .99)), tech.target.duration = Math.max(tech.target.duration, 1e3), (tech.isBaseShip || tech.isBaseDef) && (tech.target.duration = 1e3 * Math.floor(tech.target.duration / 1e3), tech.target.duration = Math.max(tech.target.duration, 1e3) * (level || 1)), tech.target.duration / 1e3), planet = Math.floor(data / 604800), planetData = Math.floor(data % 604800 / 86400), rawDeut = Math.floor(data % 86400 / 3600), level = Math.floor(data % 3600 / 60), data = Math.floor(data % 60); let displayed = 0; return tech.target.timeresult = "", 0 < planet && displayed < 3 && (tech.target.timeresult += "" + planet + LocalizationStrings.timeunits.short.week + " ", displayed++), 0 < planetData && displayed < 3 && (tech.target.timeresult += "" + planetData + LocalizationStrings.timeunits.short.day + " ", displayed++), 0 < rawDeut && displayed < 3 && (tech.target.timeresult += "" + rawDeut + LocalizationStrings.timeunits.short.hour + " ", displayed++), 0 < level && displayed < 3 && (tech.target.timeresult += "" + level + LocalizationStrings.timeunits.short.minute + " ", displayed++), 0 < data && displayed < 3 && (tech.target.timeresult += "" + data + LocalizationStrings.timeunits.short.second, displayed++), tech; } } checkProductionBoxes() { this.ogl.currentPlanet.obj.upgrades = this.ogl.currentPlanet.obj.upgrades || {}, Object.entries(this.ogl._time.productionBoxes).forEach(box => { if ( document.querySelector(`#${box[1]} time`)) { let techType = "productionboxbuildingcomponent" == box[1] ? "baseBuilding" : "productionboxresearchcomponent" == box[1] ? "baseResearch" : "productionboxshipyardcomponent" == box[1] ? "ship" : "productionboxlfbuildingcomponent" == box[1] ? "lfBuilding" : "productionboxlfresearchcomponent" == box[1] ? "lfResearch" : "productionboxextendedshipyardcomponent" == box[1] ? "mechaShip" : "unknown", coords = document.querySelector(`#${[ box[1] ]} .first .queuePic`).parentNode.getAttribute("onclick")?.match(/[([0-9:]+]/)?.[0]?.slice(1, -1), itemEndTime = 0, len = document.querySelectorAll(`#${[ box[1] ]} .queuePic`).length; document.querySelectorAll(`#${[ box[1] ]} .queuePic`).forEach((item, index) => { var id = new URLSearchParams(item.parentNode.href).get("openTech") || item.parentNode?.getAttribute("onclick")?.match(/([0-9]+)/)[0]; if (id) { var item = item.closest(".first")?.parentNode?.querySelector(".level")?.innerText.match(/\d+/)[0] || item.closest(".first")?.querySelector(".shipSumCount")?.innerText || item.parentNode.innerText, data = this.getTechData(id, item, this.ogl.currentPlanet.obj.id), data = 0 == index ? 1e3 * parseInt( document.querySelector(`#${[ box[1] ]} time.countdown`).getAttribute("data-end")) || serverTime.getTime() + data.target.duration : data.target.duration; if (itemEndTime += data, 0 == index) { var data = this.ogl._time.getObj(itemEndTime), div = document.querySelector(`#${[ box[1] ]} .content`), data = this.ogl.db.options.useClientTime ? data.client : data.server, data = (div.classList.add("ogl_" + techType), `<span>${new Date(data).toLocaleDateString("de-DE", { day: "2-digit", month: "2-digit", year: "numeric" })}</span> ` + new Date(data).toLocaleTimeString("de-DE")); Util.addDom("time", { class: "ogl_timeBox", prepend: div.querySelector(".build-faster").parentNode, child: data }), "baseResearch" == techType && ((div = {}).name = this.ogl.db.serverData[id] || id, div.lvl = item, div.end = itemEndTime, div.type = techType, coords && coords != this.ogl.currentPlanet.obj.coords ? (data = Object.values(this.ogl.db.myPlanets).find(e => e.coords == coords && "planet" == e.type).id, this.ogl.db.myPlanets[data].upgrades = this.ogl.db.myPlanets[data].upgrades || [], this.ogl.db.myPlanets[data].upgrades[techType] = [ div ]) : coords == this.ogl.currentPlanet.obj.coords && "moon" != this.ogl.currentPlanet.obj.type && (this.ogl.currentPlanet.obj.upgrades = this.ogl.currentPlanet.obj.upgrades || [], this.ogl.currentPlanet.obj.upgrades[techType] = [ div ])); } else if (index == len - 1) { let timeObj = this.ogl._time.getObj(itemEndTime), div = document.querySelector(`#${[ box[1] ]} .content`), endDate = this.ogl.db.options.useClientTime ? timeObj.client : timeObj.server, content = (div.classList.add("ogl_" + techType), `<span>${new Date(endDate).toLocaleDateString("de-DE", { day: "2-digit", month: "2-digit", year: "numeric" })}</span> ` + new Date(endDate).toLocaleTimeString("de-DE")); Util.addDom("time", { class: "ogl_timeBox", parent: div, child: content }); } } }); } }); } } class StatsManager extends Manager { load() { this.ogl.db.stats = this.ogl.db.stats || {}, this.types = [ "raid", "expe", "discovery", "debris", "debris16", "blackhole" ], this.data = {}, this.miniStats(); } getKey(time) { time = new Date(time); return `${time.getFullYear()}-${time.getMonth() + 1}-` + time.getDate(); } getKeyDay(oldKey, newDay) { oldKey = new Date(oldKey); return this.getKey(new Date(oldKey.getFullYear(), oldKey.getMonth(), newDay, 0, 0, 0)); } getKeysPrevMonth(oldKey) { oldKey = new Date(oldKey); return [ this.getKey(new Date(oldKey.getFullYear(), oldKey.getMonth() - 1, 1, 0, 0, 0)), this.getKey(new Date(oldKey.getFullYear(), oldKey.getMonth(), 0, 23, 59, 59)) ]; } getKeysNextMonth(oldKey) { oldKey = new Date(oldKey); return [ this.getKey(new Date(oldKey.getFullYear(), oldKey.getMonth() + 1, 1, 0, 0, 0)), this.getKey(new Date(oldKey.getFullYear(), oldKey.getMonth() + 2, 0, 23, 59, 59)) ]; } getDayStats(time) { time = this.getKey(time); return this.ogl.db.stats[time] = this.ogl.db.stats[time] || {}, this.ogl.db.stats[time]; } getData(key) { let data = this.ogl.db.stats[key], ids = [ "metal", "crystal", "deut", "dm", "artefact", "blackhole", 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 217, 218, 219, 401, 402, 403, 404, 405, 406, 407, 408 ], result = { total: { metal: 0, crystal: 0, deut: 0, dm: 0, artefact: 0, msu: 0 }, expe: {}, raid: {} }; this.types.forEach(type => { result[type] = result[type] || {}; for (let [ gainID, amount ] of Object.entries(data?.[type]?.gain || {})) { var shipData, shipFactor, sign; -1 < ids.findIndex(e => e == gainID || e == -gainID) && (isNaN(gainID) ? (result.total[gainID] = (result.total[gainID] || 0) + amount, "raid" != type && "debris" != type || (result.raid[gainID] = (result.raid[gainID] || 0) + amount), "expe" != type && "debris16" != type && "blackhole" != type || (result.expe[gainID] = (result.expe[gainID] || 0) + amount)) : (shipData = Datafinder.getTech(Math.abs(gainID)), shipFactor = "expe" == type && 0 < parseInt(gainID) ? this.ogl.db.options.expeditionShipRatio / 100 : 1, (sign = 0 < parseInt(gainID) ? 1 : -1) < 0 && ("expe" == type || "blackhole" == type) && this.ogl.db.options.ignoreExpeShipsLoss || (result.total.metal = (result.total.metal || 0) + (shipData.metal || 0) * amount * shipFactor * sign, result.total.crystal = (result.total.crystal || 0) + (shipData.crystal || 0) * amount * shipFactor * sign, result.total.deut = (result.total.deut || 0) + (shipData.deut || 0) * amount * shipFactor * sign, "expe" != type && "blackhole" != type || (result.expeShip = result.expeShip || {}, result.expeShip[Math.abs(gainID)] = (result.expeShip[Math.abs(gainID)] || 0) + amount * sign), "raid" != type && "debris" != type || (result.raid.metal = (result.raid.metal || 0) + (shipData.metal || 0) * amount * shipFactor * sign, result.raid.crystal = (result.raid.crystal || 0) + (shipData.crystal || 0) * amount * shipFactor * sign, result.raid.deut = (result.raid.deut || 0) + (shipData.deut || 0) * amount * shipFactor * sign), "expe" != type && "debris16" != type && "blackhole" != type) || (result.expe.metal = (result.expe.metal || 0) + (shipData.metal || 0) * amount * shipFactor * sign, result.expe.crystal = (result.expe.crystal || 0) + (shipData.crystal || 0) * amount * shipFactor * sign, result.expe.deut = (result.expe.deut || 0) + (shipData.deut || 0) * amount * shipFactor * sign))); } for (var [ typeID, amount ] of Object.entries(data?.[type]?.occurence || {})) result[type + "Occurence"] = result[type + "Occurence"] || {}, result[type + "Occurence"][typeID] = (result[type + "Occurence"][typeID] || 0) + amount; result[type].count = (result[type].count || 0) + (data?.[type]?.count || 0); }), result.conso = (result.conso || 0) + (data?.conso || 0), this.ogl.db.options.ignoreConsumption || (result.total.deut -= result.conso); key = this.ogl.db.options.msu; return result.total.msu = Util.getMSU(result.total.metal, result.total.crystal, result.total.deut, key), result.expe.msu = Util.getMSU(result.expe.metal, result.expe.crystal, result.expe.deut, key), result.raid.msu = Util.getMSU(result.raid.metal, result.raid.crystal, result.raid.deut, key), result; } miniStats() { var now = serverTime, startDate = new Date(now.getFullYear(), now.getMonth(), now.getDate(), 0, 0, 0), now = new Date(now.getFullYear(), now.getMonth(), now.getDate(), 23, 59, 59), data = this.getData(this.getKey(startDate.getTime())), startDate = (this.miniDiv || (this.miniDiv = Util.addDom("div", { class: "ogl_miniStats ogl_ogameDiv", parent: document.querySelector("#links"), onclick: event => { event.target.classList.contains("ogl_blackHoleButton") || Util.runAsync(() => this.buildStats()).then(e => this.ogl._popup.open(e, !0)); } })), this.miniDiv.innerText = "", new Date(startDate).toLocaleString("default", { day: "numeric", month: "long", year: "numeric" })), now = new Date(now).toLocaleString("default", { day: "numeric", month: "long", year: "numeric" }), startDate = startDate == now ? startDate : startDate + "➜<br>" + now; Util.addDom("h3", { class: "ogl_header", child: startDate, parent: this.miniDiv }); let content = Util.addDom("div", { parent: this.miniDiv }); Object.entries(data.total).forEach(entry => { Util.addDom("div", { class: "ogl_icon ogl_" + entry[0], parent: content, child: `<span>${Util.formatToUnits(entry[1], 1, !0)}</span>` }); }); } buildStats(keyStart, keyEnd) { let now = serverTime; keyStart = keyStart || this.getKey(new Date(now.getFullYear(), now.getMonth(), now.getDate(), 0, 0, 0).getTime()), keyEnd = keyEnd || this.getKey(new Date(now.getFullYear(), now.getMonth(), now.getDate(), 23, 59, 59).getTime()); var dayEnd = new Date(keyEnd), monthEnd = new Date(dayEnd.getFullYear(), dayEnd.getMonth() + 1, 0, 23, 59, 59), dayEnd = Util.addDom("div", { class: "ogl_stats" }), month = Util.addDom("div", { parent: dayEnd, class: "ogl_statsMonth" }); Util.addDom("div", { parent: month, class: "ogl_button", child: LocalizationStrings?.timeunits?.short?.day || "D", onclick: () => { Util.runAsync(() => this.buildStats()).then(e => this.ogl._popup.open(e, !0)); } }), Util.addDom("div", { parent: month, class: "ogl_button", child: LocalizationStrings?.timeunits?.short?.week || "W", onclick: () => { let currentMonthStart = this.getKey(new Date(now.getFullYear(), now.getMonth(), now.getDate() - 6, 0, 0, 0).getTime()), currentMonthEnd = this.getKey(new Date(now.getFullYear(), now.getMonth(), now.getDate(), 0, 0, 0).getTime()); Util.runAsync(() => this.buildStats(currentMonthStart, currentMonthEnd)).then(e => this.ogl._popup.open(e, !0)); } }), Util.addDom("div", { parent: month, class: "ogl_button", child: LocalizationStrings?.timeunits?.short?.month || "M", onclick: () => { let currentMonthStart = this.getKey(new Date(now.getFullYear(), now.getMonth(), 1, 0, 0, 0).getTime()), currentMonthEnd = this.getKey(new Date(now.getFullYear(), now.getMonth() + 1, 0, 23, 59, 59).getTime()); Util.runAsync(() => this.buildStats(currentMonthStart, currentMonthEnd)).then(e => this.ogl._popup.open(e, !0)); } }), Util.addDom("div", { parent: month, class: "ogl_button", child: "All", onclick: () => { var initialTime = new Date(this.ogl.db.initialTime); let currentMonthStart = this.getKey(new Date(initialTime.getFullYear(), initialTime.getMonth(), initialTime.getDate(), 0, 0, 0).getTime()), currentMonthEnd = this.getKey(new Date(now.getFullYear(), now.getMonth() + 1, 0, 23, 59, 59).getTime()); Util.runAsync(() => this.buildStats(currentMonthStart, currentMonthEnd)).then(e => this.ogl._popup.open(e, !0)); } }), Util.addDom("div", { parent: month, class: "ogl_separator" }), Util.addDom("div", { parent: month, class: "ogl_button material-icons", child: "arrow-left-thick", onclick: () => { let prevMonth = this.getKeysPrevMonth(keyEnd); Util.runAsync(() => this.buildStats(prevMonth[0], prevMonth[1])).then(e => this.ogl._popup.open(e, !0)); } }), Util.addDom("div", { parent: month, child: monthEnd.toLocaleString("default", { month: "short", year: "numeric" }) }), Util.addDom("div", { parent: month, class: "ogl_button material-icons", child: "arrow-right-thick", onclick: () => { let nextMonth = this.getKeysNextMonth(keyEnd); Util.runAsync(() => this.buildStats(nextMonth[0], nextMonth[1])).then(e => this.ogl._popup.open(e, !0)); } }); let first, initial, reset = () => { initial && dateBar && (dateBar.querySelectorAll("[data-day]").forEach(e => e.classList.remove("ogl_selected")), initial.forEach(e => e.classList.add("ogl_selected"))); }; var dataset = []; let subDataset = [], bars = [], dateBar = Util.addDom("div", { parent: dayEnd, class: "ogl_dateBar", onmouseup: () => { this.isMoving = !1; var selected = dateBar.querySelectorAll("[data-day].ogl_selected"); if (!selected || selected.length < 2) reset(), initial.forEach(e => e.classList.add("ogl_selected")); else { let start = this.getKeyDay(keyEnd, selected[0].getAttribute("data-day")), end = this.getKeyDay(keyEnd, selected[selected.length - 1].getAttribute("data-day")); Util.runAsync(() => this.buildStats(start, end)).then(e => this.ogl._popup.open(e, !0)); } }, onmousedown: e => { initial = dateBar.querySelectorAll("[data-day].ogl_selected"), this.isMoving = !0, dateBar.querySelectorAll("[data-day]").forEach(b => b.classList.remove("ogl_selected")), e.target.getAttribute("data-day") && (first = parseInt(e.target.getAttribute("data-day"))), e.target.parentNode.getAttribute("data-day") && (first = parseInt(e.target.parentNode.getAttribute("data-day"))); }, onmouseleave: () => { this.isMoving = !1, first = !1, reset(); } }), details = Util.addDom("div", { parent: dayEnd, class: "ogl_statsDetails" }), highest = 0, lowest = 0; for (let i = 1; i <= monthEnd.getDate(); i++) { let barKey = this.getKeyDay(keyEnd, i), data = this.getData(barKey), bar = (data.total?.msu < lowest && (lowest = data.total?.msu || 0), data.total?.msu > highest && (highest = data.total?.msu || 0), dataset.push(data), Util.addDom("div", { class: "ogl_item", parent: dateBar, "data-day": i, "data-value": data.total?.msu || 0, onclick: () => { bars.forEach(e => e.classList.remove("ogl_selected")), bar.classList.add("ogl_selected"), this.displayDetails([ data ], details, barKey, barKey), initial = dateBar.querySelectorAll("[data-day].ogl_selected"); }, onmouseenter: () => { if (this.isMoving && (first = first || parseInt(bar.getAttribute("data-day")), this.isMoving)) { let current = parseInt(bar.getAttribute("data-day")); dateBar.querySelectorAll("[data-day]").forEach(b => { var num1, num2, dataDay = parseInt(b.getAttribute("data-day")); dataDay = dataDay, num1 = current, num2 = first, dataDay >= Math.min(num1, num2) && dataDay <= Math.max(num1, num2) ? b.classList.add("ogl_selected") : b.classList.remove("ogl_selected"); }); } } })); bars.push(bar), Date.parse(barKey) >= Date.parse(keyStart) && Date.parse(barKey) <= Date.parse(keyEnd) && bar.classList.add("ogl_selected"); } let timeStart = new Date(keyStart).getTime(), timeEnd = new Date(keyEnd).getTime(); if (Object.keys(this.ogl.db.stats).filter(stat => { var date = new Date(stat).getTime(); date >= timeStart && date <= timeEnd && subDataset.push(this.getData(stat)); }), bars.forEach(bar => { var value = parseInt(bar.getAttribute("data-value")), height = 0 < (height = Math.ceil(Math.abs(value) / (Math.max(Math.abs(highest), Math.abs(lowest)) / 100))) ? Math.max(height, 5) : 0, color = 0 < value ? "#35cf95" : "#e14848"; Util.addDom("div", { parent: bar }).style.background = `linear-gradient(to top, ${color} ${height}%, #0e1116 ${height}%)`, 0 != value && bar.classList.add("ogl_active"); }), subDataset.length < 1) { let emptyData = {}; this.types.forEach(type => emptyData[type] = {}), emptyData.total = {}, subDataset.push(emptyData); } return this.displayDetails(subDataset, details, keyStart, keyEnd), dayEnd; } displayDetails(dataset, parent, keyStart, keyEnd) { parent.innerText = ""; var start = new Date(keyStart).toLocaleString("default", { day: "numeric", month: "long", year: "numeric" }), end = new Date(keyEnd).toLocaleString("default", { day: "numeric", month: "long", year: "numeric" }), keyStart = keyStart == keyEnd ? start : start + " -> " + end; Util.addDom("h3", { child: keyStart, parent: parent }); let data = dataset.reduce((acc, item) => (Object.entries(item).forEach(([ key, value ]) => { "object" == typeof value ? (acc[key] = acc[key] || {}, Object.entries(value).forEach(([ k, v ]) => acc[key][k] = (acc[key][k] || 0) + v)) : acc[key] = (acc[key] || 0) + value; }), acc), {}), shipTable = (parent.appendChild(this.buildPie(data.expeOccurence)), Util.addDom("div", { parent: parent, class: "ogl_shipTable" })), sumTable = ([ 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 213, 214, 215, 218, 219 ].forEach(shipId => { Util.addDom("div", { class: "ogl_icon ogl_" + shipId, parent: shipTable, child: Util.formatToUnits(data?.expeShip?.[shipId] || "-", !1, !0) }); }), Util.addDom("div", { parent: parent, class: "ogl_sumTable" })), header = Util.addDom("div", { parent: sumTable }); [ "", "send", "metal", "crystal", "deut", "msu", "dm", "artefact" ].forEach(resource => { "send" == resource ? Util.addDom("div", { class: "ogl_textCenter ogl_icon material-icons", child: "send", parent: header }) : Util.addDom("div", { class: "ogl_icon ogl_" + resource, parent: header }); }), [ "expe", "raid", "conso", "u", "total" ].forEach(type => { var typeLabel = "u" == type ? "average" : type; let line = Util.addDom("div", { parent: sumTable, child: `<div>${typeLabel}</div>` }); var typeLabel = {}, missions = (typeLabel.expe = data.expe.count + data.debris16.count, typeLabel.raid = data.raid.count + data.debris.count, typeLabel.total = data.debris.count + data.debris16.count + data.expe.count + data.raid.count + data.discovery.count, Util.addDom("div", { parent: line, child: Util.formatToUnits(typeLabel[type] || "-", !1, !0) })); typeLabel[type] && (typeLabel = "expe" == type ? `<div>Expedition: ${data.expe.count}</div><div>Debris p16: ${data.debris16.count}</div>` : "raid" == type ? `<div>Raid: ${data.raid.count}</div><div>Debris: ${data.debris.count}</div>` : "total" == type ? `<div>Expedition: ${data.expe.count}</div> <div>Debris p16: <span>${data.debris16.count}</span></div> <div>Raid: <span>${data.raid.count}</span></div> <div>Debris: <span>${data.debris.count}</span></div> <div>Discovery: <span>${data.discovery.count}</span></div>` : "", missions.classList.add("tooltip"), missions.setAttribute("title", typeLabel)); let uResources = data.debris.count + data.debris16.count + data.expe.count + data.raid.count, uDM = data.expe.count, uArtefacts = data.discovery.count; [ "metal", "crystal", "deut", "msu", "dm", "artefact" ].forEach(resource => { if ("u" == type) { let value = 0; "metal" == resource || "crystal" == resource || "deut" == resource || "msu" == resource ? value = data.total[resource] / uResources : "dm" == resource ? value = data.total[resource] / uDM : "artefact" == resource && (value = data.total[resource] / uArtefacts), Util.addDom("div", { class: "ogl_" + resource, parent: line, child: Util.formatToUnits(Math.floor(isFinite(value) ? value : 0), !1, !0) }); } else "conso" == type && "deut" == resource ? Util.addDom("div", { class: "ogl_" + resource, parent: line, child: Util.formatToUnits(-data.conso || 0, !1, !0) }) : "conso" == type && "msu" == resource ? Util.addDom("div", { class: "ogl_" + resource, parent: line, child: Util.formatToUnits(Util.getMSU(0, 0, -data.conso, this.ogl.db.options.msu), !1, !0) }) : Util.addDom("div", { class: "ogl_" + resource, parent: line, child: Util.formatToUnits(data[type]?.[resource] || 0, !1, !0) }); }); }), initTooltips(); } buildPie(occurencesExpeDetail) { let pie = Util.addDom("div", { class: "ogl_pie" }); if (!occurencesExpeDetail || Object.keys(occurencesExpeDetail || {}).length < 1) return pie.innerHTML = '<div class="ogl_noExpe"><span class="material-icons">compass</span>No expedition data</div>', pie; let cumulAngle = 1.5 * Math.PI; var colors = { nothing: "#ddd", resource: "#86edfd", darkmatter: "#b58cdb", ship: "#1dd1a1", battle: "#ffd60b", item: "#bf6c4d", blackhole: "#818181", duration: "#df5252", trader: "#ff7d30" }, pieData = {}; pieData.resource = occurencesExpeDetail.resource || 0, pieData.darkmatter = occurencesExpeDetail.darkmatter || 0, pieData.ship = occurencesExpeDetail.ship || 0, pieData.nothing = occurencesExpeDetail.nothing || 0, pieData.blackhole = occurencesExpeDetail.blackhole || 0, pieData.trader = occurencesExpeDetail.trader || 0, pieData.item = occurencesExpeDetail.item || 0, pieData.battle = (occurencesExpeDetail.pirate || 0) + (occurencesExpeDetail.alien || 0), pieData.duration = (occurencesExpeDetail.early || 0) + (occurencesExpeDetail.late || 0); let size = 256, center = size / 2, radius = size / 2, slices = []; let drawPie = hoveredSlice => { ctx.clearRect(0, 0, size, size), slices.forEach(slice => { ctx.beginPath(), ctx.arc(center, center, radius, slice.startAngle, slice.endAngle), ctx.lineTo(center, center), ctx.closePath(), ctx.fillStyle = slice.title == hoveredSlice?.title ? "white" : slice.color, ctx.fill(); }), ctx.fillStyle = "rgba(0,0,0,.5)", ctx.beginPath(), ctx.arc(size / 2, size / 2, size / 2.7, 0, 2 * Math.PI, !1), ctx.fill(), ctx.fillStyle = "#1b212a", ctx.beginPath(), ctx.arc(size / 2, size / 2, size / 3, 0, 2 * Math.PI, !1), ctx.fill(), pie.setAttribute("data-pie", (hoveredSlice ? this.ogl._lang.find(hoveredSlice.title) + "\r\n" : "") + (hoveredSlice ? hoveredSlice.percent + "%" : total + "\r\nExpeditions")), legend.querySelectorAll(".ogl_active").forEach(e => e.classList.remove("ogl_active")), hoveredSlice && legend.querySelector(`[data-entry="${hoveredSlice.title}"]`).classList.add("ogl_active"); }, canvas = Util.addDom("canvas", { parent: pie, width: size, height: size, onmouseout: () => { drawPie(), canvas.classList.remove("ogl_interactive"); } }), ctx = canvas.getContext("2d", { willReadFrequently: !0 }), legend = Util.addDom("div", { parent: pie, class: "ogl_pieLegendContainer", onmouseleave: () => drawPie() }); var title, value, slice, pieData = Object.entries(pieData || {}); let total = Object.values(occurencesExpeDetail || {}).reduce((accumulator, e) => accumulator + Math.max(0, e), 0); pie.setAttribute("data-pie", total); for ([ title, value ] of pieData.sort((a, b) => b[1] - a[1])) 0 < value && ((slice = {}).title = title, slice.value = value, slice.percent = (value / total * 100).toFixed(2), slice.startAngle = cumulAngle, slice.angle = value / total * 2 * Math.PI, slice.endAngle = cumulAngle + slice.angle, slice.color = colors[title], slices.push(slice), cumulAngle = slice.endAngle, Util.addDom("div", { class: "ogl_pieLegend", "data-resultType": slice.title, "data-entry": slice.title, parent: legend, child: `<div>${this.ogl._lang.find(title)}</div><span>${Util.formatToUnits(value)}</span><i>${slice.percent}%</i>` })); return drawPie(), legend.querySelectorAll(".ogl_pieLegend").forEach(line => { line.addEventListener("mouseenter", () => { var slice = slices.find(slice => slice.title == line.getAttribute("data-entry")); drawPie(slice); }); }), pie; } addBlackHoleButton() { Util.addDom("button", { class: "ogl_button material-icons tooltip ogl_blackHoleButton", title: this.ogl._lang.find("reportBlackhole"), parent: this.miniDiv, child: "skull", onclick: () => { this.ogl._popup.open(Util.addDom("div", { child: '<div class="ogl_loading"></div>' })); let container = Util.addDom("div", { class: "ogl_keeper ogl_blackhole" }), wrapper = (Util.addDom("h2", { child: this.ogl._lang.find("reportBlackhole"), parent: container }), Util.addDom("div", { class: "ogl_shipLimiter", parent: container })); [ 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 213, 214, 215, 218, 219 ].forEach(shipID => { var item = Util.addDom("div", { class: "ogl_icon ogl_" + shipID, parent: wrapper }); Util.addDom("input", { class: "ogl_inputCheck", "data-ship": shipID, parent: item }); }), Util.addDom("div", { class: "ogl_button", child: "Add", parent: container, onclick: () => { if (confirm(this.ogl._lang.find("reportBlackholeLong"))) { let result = {}; result.date = new Date(), result.messageType = "blackhole", result.gain = {}, container.querySelectorAll("input").forEach(input => { var shipID = parseInt(input.getAttribute("data-ship")), input = parseInt(input.value.replace(/\D/g, "")) || 0; isNaN(shipID) || isNaN(input) || (result.gain[-shipID] = input); }), this.ogl._message.updateStats(result), this.ogl._popup.close(); } } }), this.ogl._popup.open(container); } }); } } class EmpireManager extends Manager { load() { if (this.getLFBonuses(), this.getAllianceClass(), "empire" == this.ogl.page) { unsafeWindow.jumpGateLink = `https://${window.location.host}/game/index.php?page=ajax&component=jumpgate&overlay=1&ajax=1`; let updateDone = !(unsafeWindow.jumpGateLoca = { LOCA_STATION_JUMPGATE_HEADLINE: "Jumpgate" }), planetData, planetName; Util.observe(document.body, { childList: !0, subtree: !0, attributes: !0 }, mutation => { !updateDone && mutation.target.classList.contains("box-end") && mutation.target.closest(".summary") && mutation.target.closest(".groupresources") ? "none" == document.querySelector("#loading").style.display && (updateDone = !0, this.update( document.querySelector("#mainContent script").innerText, new URLSearchParams(window.location.search).get("planetType"), !0), document.querySelectorAll(".planet").forEach(planet => { let data = this.ogl.db.myPlanets[planet.id.replace("planet", "")]; data && Util.addDom("div", { class: "material-icons ogl_empireJumpgate", child: "jump_to_element", parent: planet.querySelectorAll(".row")[1], onclick: e => { e.preventDefault(), planetData = data, planetName = planet.querySelector(".planetname").getAttribute("title") || planet.querySelector(".planetname").innerText, document.querySelector(".ui-dialog")?.remove(), setTimeout(() => openJumpgate(), 5); } }); })) : mutation.target.classList.contains("ui-dialog") && document.querySelector("#jumpgate") && ( document.querySelector("#jumpgateNotReady") || ( document.querySelector(".currentlySelected") ? ((mutation = document.querySelector(".currentlySelected a")).setAttribute("data-value", planetData.planetID || planetData.moonID), mutation.innerText = `${planetName} [${planetData.coords}]`) : document.querySelector("#selecttarget select").value = this.ogl.db.myPlanets[planetData.planetID].moonID, mutation = [ planetData.metal, planetData.crystal, planetData.deut, planetData.food ], this.ogl.db.fleetLimiter.resourceActive && (mutation[0] = Math.max(0, mutation[0] - (this.ogl.db.fleetLimiter.data.metal || 0)), mutation[1] = Math.max(0, mutation[1] - (this.ogl.db.fleetLimiter.data.crystal || 0)), mutation[2] = Math.max(0, mutation[2] - (this.ogl.db.fleetLimiter.data.deut || 0)), mutation[3] = Math.max(0, mutation[3] - (this.ogl.db.fleetLimiter.data.food || 0))), mutation = mutation[0] + mutation[1] + mutation[2] + mutation[3], document.querySelector(`[name="ship_${this.ogl.db.options.defaultShip}"]`).value = this.ogl._fleet.shipsForResources(this.ogl.db.options.defaultShip, Math.max(0, mutation)))); }); } } update(data, type, fromEmpire) { this.ogl.db.lastEmpireUpdate = Date.now(); let allowedEntries = [ "id", "metal", "crystal", "deuterium", "energy", "food", "population", "fieldUsed", "fieldMax", "planetID", "moonID" ]; (data = fromEmpire ? JSON.parse(data.match(/{(.*)}/g)[1]) : data).planets?.forEach(planet => { this.ogl.db.myPlanets[planet.id] = this.ogl.db.myPlanets[planet.id] || {}, this.ogl.db.myPlanets[planet.id].type = 0 === type ? "planet" : "moon", Object.entries(planet).forEach(entry => { 0 <= entry[0].indexOf("html") || ("temperature" === entry[0] ? this.ogl.db.myPlanets[planet.id][entry[0]] = parseInt(entry[1].match(/[-|0-9]+/g, "")[0]) : Number(entry[0]) || 0 <= entry[0].indexOf("Storage") || allowedEntries.includes(entry[0]) ? this.ogl.db.myPlanets[planet.id][entry[0].replace("deuterium", "deut")] = parseInt(entry[1]) : "coordinates" === entry[0] ? this.ogl.db.myPlanets[planet.id].coords = entry[1].slice(1, -1) : "production" === entry[0] && (this.ogl.db.myPlanets[planet.id].prodMetal = entry[1].hourly[0] / 3600, this.ogl.db.myPlanets[planet.id].prodCrystal = entry[1].hourly[1] / 3600, this.ogl.db.myPlanets[planet.id].prodDeut = entry[1].hourly[2] / 3600)); }); }), this.ogl.currentPlanet && (this.ogl.currentPlanet.obj = this.ogl.db.myPlanets[ document.querySelector('head meta[name="ogame-planet-id"]')?.getAttribute("content")]), document.querySelectorAll(".planetlink, .moonlink").forEach(planet => { let id = new URLSearchParams(planet.getAttribute("href")).get("cp").split("#")[0]; [ "metal", "crystal", "deut" ].forEach(resourceName => { var resource = this.ogl.db.myPlanets[id]?.[resourceName] || 0, storage = this.ogl.db.myPlanets[id]?.[resourceName + "Storage"] || 0, selector = planet.querySelector(".ogl_available .ogl_" + resourceName); selector ? (selector.innerHTML = Util.formatToUnits(resource, 1), storage <= resource && planet.classList.contains("planetlink") ? selector.classList.add("ogl_danger") : .9 * storage <= resource && planet.classList.contains("planetlink") ? selector.classList.add("ogl_warning") : (selector.classList.remove("ogl_warning"), selector.classList.remove("ogl_danger"))) : planet.querySelector(".ogl_available .ogl_" + resourceName) && (planet.querySelector(".ogl_available .ogl_" + resourceName).innerHTML = Util.formatToUnits(resource, 1)); }); }), this.ogl._ui && Util.runAsync(() => this.ogl._ui.displayResourcesRecap()); } getLFBonuses(source) { var htmlSource = source || document; !source && "lfbonuses" != this.ogl.page || (this.ogl.db.lfBonuses = {}, htmlSource.querySelectorAll("bonus-item-content-holder > [data-toggable]").forEach(item => { var id = item.getAttribute("data-toggable").replace(/subcategory|Ships|Defenses|CostAndTime/g, ""); let regex = new RegExp(`[0-9|-]+(${LocalizationStrings.decimalPoint}[0-9]+)?`, "g"); var isBaseResearch = 100 < id && id <= 199, isBaseShip = 200 < id && id <= 299, isBaseDef = 400 < id && id <= 499, lfBonuses = {}; let bonuses = []; if (item.querySelectorAll("bonus-item").forEach(bonus => { bonus = (bonus.innerText.match(regex) || []).map(e => "-" == e ? 0 : parseFloat(e.replace(LocalizationStrings.decimalPoint, "."))); bonuses.push(bonus); }), 0 == bonuses.length) { let value = (item.innerText.match(regex) || [])[0]; value = value && "-" != value ? parseFloat(value.replace(LocalizationStrings.decimalPoint, ".")) : 0, lfBonuses.bonus = value; } isBaseShip ? (lfBonuses.armor = bonuses[0][0], lfBonuses.shield = bonuses[1][0], lfBonuses.weapon = bonuses[2][0], lfBonuses.speed = bonuses[3][0], lfBonuses.cargo = bonuses[4][0], lfBonuses.fuel = bonuses[5][0]) : isBaseDef ? (lfBonuses.armor = bonuses[0][0], lfBonuses.shield = bonuses[1][0], lfBonuses.weapon = bonuses[2][0]) : !isBaseResearch && "LfResearch" != id || (lfBonuses.cost = bonuses[0][0], lfBonuses.duration = bonuses[1][0]), this.ogl.db.lfBonuses[id] = lfBonuses; })), !source && "lfbonuses" != this.ogl.page && "lfsettings" != this.ogl.page || (this.ogl.db.lfBonuses = this.ogl.db.lfBonuses || {}, htmlSource.querySelectorAll("lifeform-item, .lifeform-item").forEach(item => { var lifeform = item.querySelector(".lifeform-item-icon").className.replace(/lifeform-item-icon| /g, ""), item = item.querySelector(".currentlevel").innerText.replace(/\D/g, "") / 10; this.ogl.db.lfBonuses[lifeform] = { bonus: item }; })); } getAllianceClass() { "alliance" == this.ogl.page && setTimeout(() => { var sprite = alliance.allianceContent[0].querySelector("#allyData .allianceclass.sprite"); sprite ? (sprite = (Array.from(sprite.classList).filter(element => allianceClassArr.includes(element)) || [ "neutral" ])[0], sprite = allianceClassArr.indexOf(sprite), this.ogl.db.allianceClass = sprite) : this.getAllianceClass(); }, 1e3); } } class Util { static get simList() { return { battlesim: "https://battlesim.logserver.net/", "simulator.ogame-tools": "https://simulator.ogame-tools.com/" }; } static get converterList() { return { ogotcha: "https://ogotcha.oplanet.eu/", topraider: "https://topraider.eu/index.php", "ogame.tools": "https://battleconvertor.fr" }; } static overWrite(fn, context, before, after, newParam1, newParam2) { let old = context[fn], locked = !1; context[fn] = function(param1, param2) { (locked = before && "function" == typeof before ? before(newParam1 || param1, newParam2 || param2) : locked) || old.call(context, newParam1 || param1, newParam2 || param2), after && "function" == typeof after && !locked && after(newParam1 || param1, newParam2 || param2); }; } static drawLine(svg, parent, element1, element2) { var x1, x2; unsafeWindow.fleetDispatcher && fleetDispatcher.realTarget && (fleetDispatcher.targetPlanet.galaxy != fleetDispatcher.realTarget.galaxy || fleetDispatcher.targetPlanet.system != fleetDispatcher.realTarget.system || fleetDispatcher.targetPlanet.position != fleetDispatcher.realTarget.position || fleetDispatcher.targetPlanet.type != fleetDispatcher.realTarget.type) || (svg.querySelector("line")?.remove(), element1 && element2 && element1 != element2 && (element1 = element1.querySelector(".planetPic, .icon-moon"), element2 = element2.querySelector(".planetPic, .icon-moon"), x1 = Math.round(element1.getBoundingClientRect().left + element1.getBoundingClientRect().width / 2 - parent.getBoundingClientRect().left) - 2, element1 = Math.round(element1.getBoundingClientRect().top + element1.getBoundingClientRect().height / 2 - parent.getBoundingClientRect().top), x2 = Math.round(element2.getBoundingClientRect().left + element2.getBoundingClientRect().width / 2 - parent.getBoundingClientRect().left) - 2, element2 = Math.round(element2.getBoundingClientRect().top + element2.getBoundingClientRect().height / 2 - parent.getBoundingClientRect().top), parent.appendChild(svg), parent = document.createElementNS("http://www.w3.org/2000/svg", "line"), svg.appendChild(parent), parent.classList.add("ogl_line"), parent.setAttribute("x1", x1), parent.setAttribute("y1", element1), parent.setAttribute("x2", x2), parent.setAttribute("y2", element2), parent.setAttribute("stroke-dasharray", "7 5"))); } static coordsToID(arr) { return ("string" == typeof arr ? arr.split(":").map(x => x.padStart(3, "0")) : arr.map(x => x.padStart(3, "0"))).join(""); } static removeFromArray(arr, index) { arr.splice(index, 1); } static formatNumber(number) { return (number || "0").toLocaleString("de-DE"); } static formatToUnits(value, forced, colored) { if (value = ((value = Math.round(value || 0)) || 0).toString().replace(/[\,\. ]/g, ""), isNaN(value)) return value; let precision = 0; value = parseInt(value), precision = 0 == value || 0 === forced || value < 1e3 && -1e3 < value ? 0 : 1 === forced || value < 1e6 && -1e6 < value ? 1 : 2; var forced = Intl.NumberFormat("fr-FR", { notation: "compact", minimumFractionDigits: precision, maximumFractionDigits: precision }).format(value).match(/[a-zA-Z]+|[0-9,-]+/g), result = forced[0].replace(/,/g, "."), forced = forced[1]?.replace("Md", "G").replace("Bn", "T") || "", result = Util.addDom("span", { class: "ogl_unit", child: `<span>${result}</span><span class="ogl_suffix">${forced}</span>` }); return value < 0 && colored && result.classList.add("ogl_danger"), result.outerHTML; } static formatFromUnits(value) { if (!value) return 0; let offset = 3 * ((value = value.toLowerCase()).split(LocalizationStrings.thousandSeperator).length - 1); LocalizationStrings.thousandSeperator == LocalizationStrings.decimalPoint && (offset = 0); var splitted = value.match(/\d+/g)[0].length; return value = -1 < value.indexOf(LocalizationStrings.unitMilliard.toLowerCase()) ? (value = (value = value.replace(LocalizationStrings.unitMilliard.toLowerCase(), "")).replace(/[\,\. ]/g, "")).padEnd(9 + offset + splitted, "0") : -1 < value.indexOf(LocalizationStrings.unitMega.toLowerCase()) ? (value = (value = value.replace(LocalizationStrings.unitMega.toLowerCase(), "")).replace(/[\,\. ]/g, "")).padEnd(6 + offset + splitted, "0") : -1 < value.indexOf(LocalizationStrings.unitKilo.toLowerCase()) ? (value = (value = value.replace(LocalizationStrings.unitKilo.toLowerCase(), "")).replace(/[\,\. ]/g, "")).padEnd(3 + offset + splitted, "0") : value.replace(/[\,\. ]/g, ""), parseInt(value); } static formatInput(input, callback, canBeEmpty) { setTimeout(() => { if (input.value && 0 != input.value || !input.classList.contains("ogl_placeholder")) { input.value = input.value.slice(0, input.selectionStart) + input.value.slice(input.selectionEnd); var oldLength = input.value.length; let mult = 1; 0 <= input.value.toLowerCase().indexOf("k") ? mult = 1e3 : 0 <= input.value.toLowerCase().indexOf("m") ? mult = 1e6 : 0 <= input.value.toLowerCase().indexOf("g") && (mult = 1e9); var cursorPosition = input.selectionStart; let formattedValue; "true" == input.getAttribute("data-allowPercent") && 0 <= input.value.toLowerCase().indexOf("%") ? (formattedValue = Math.min(parseInt(input.value?.replace(/\D/g, "") || 0), 100).toString(), formattedValue += "%") : formattedValue = (formattedValue = (parseInt(input.value?.replace(/\D/g, "") || 0) * mult).toString()).replace(/\B(?=(\d{3})+(?!\d))/g, " "), input.value = formattedValue, cursorPosition += input.value.length > oldLength ? 1 : input.value.length < oldLength ? -1 : 0, input.setSelectionRange(cursorPosition, cursorPosition), 0 == input.value && canBeEmpty && (input.value = ""), callback && callback(); } else input.value = ""; }, 5); } static reorderArray(arr, index, reversed) { arr = arr.slice(index, arr.length).concat(arr.slice(0, index)); return reversed ? arr.reverse() : arr; } static observe(element, options, callback, oglObj) { options = options || {}, new MutationObserver(mutations => { oglObj && "progress" !== mutations[0].target.tagName.toLowerCase() && (Util.runAsync(oglObj._time.update, oglObj._time), Util.runAsync(oglObj._time.observe, oglObj._time), document.querySelector('[onclick*="sendShips(6"]:not([data-spy-coords]), [onclick*="sendShipsWithPopup(6"]:not([data-spy-coords])')) && Util.runAsync(oglObj._fleet.checkSendShips, oglObj._fleet); for (let i = 0; i < mutations.length; i++) callback(mutations[i]); }).observe(element, options); } static addDom(tag, params) { params = params || {}; let element = document.createElement(tag); return element.classList.add("ogl_addedElement"), Object.entries(params).forEach(param => { var isIgnored = "before" === param[0] || "prepend" === param[0] || "parent" === param[0] || "after" === param[0], isContent = "child" === param[0], isListener = param[0].startsWith("on"); !isContent && !isListener && !isIgnored ? (element.setAttribute(param[0], param[1]), "class" == param[0] && -1 < param[1].indexOf("material-icons") && element.classList.add("notranslate")) : isListener ? element.addEventListener(param[0].toLowerCase().slice(2), event => { param[1](event, element); }) : isContent && (typeof param[1] == typeof {} ? element.appendChild(param[1]) : "string" != typeof param[1] && "number" != typeof param[1] || (element.innerHTML = param[1].toString())); }), params.parent ? params.parent.appendChild(element) : params.before ? params.before.parentNode.insertBefore(element, params.before) : params.after ? params.after.after(element) : params.prepend && params.prepend.prepend(element), element; } static runAsync(fn, scope) { return new Promise(resolve => { setTimeout(() => { resolve(scope ? scope[fn.toString().split("(")[0]]() : fn(scope)); }); }); } static takeScreenshot(element, button, name, retry) { var rect; "undefined" == typeof html2canvas ? fetch("https://cdn.jsdelivr.net/npm/html2canvas@1.0.0-rc.5/dist/html2canvas.min.js", { method: "get", headers: { Accept: "application/json" } }).then(response => response.text()).then(result => { 3 < (retry = (retry || 0) + 1) || (document.head.appendChild(Util.addDom("script", { type: "text/javascript", child: result })), Util.takeScreenshot(element, button, name)); }) : (rect = element.getBoundingClientRect(), html2canvas(element, { backgroundColor: null, useCORS: !0, ignoreElements: e => e.classList.contains("ogl_close") || e.classList.contains("ogl_share"), x: rect.x, y: rect.y, scrollX: 0, scrollY: 0, width: rect.width, height: rect.height, windowWidth: document.documentElement.offsetWidth, windowHeight: document.documentElement.offsetHeight }).then(canvas => { canvas = canvas.toDataURL(); Util.addDom("a", { download: name, href: canvas }).click(), button.classList.remove("ogl_disabled"); })); } static hash(str) { return [ ...str ].reduce((string, char) => Math.imul(31, string) + char.charCodeAt(0) | 0, 0); } static getMSU(metal, crystal, deut, ratio) { return ratio = ratio.split(":"), Math.ceil((metal || 0) + (crystal || 0) * ratio[0] / ratio[1] + (deut || 0) * ratio[0]); } static getPlayerScoreFD(score, type) { var defense; return score ? (defense = Math.max(score.military - (score.global - score.economy - score.research - score.lifeform), 0), score = score.military - defense, "defense" == type ? defense : score) : "?"; } static genTrashsimLink(ogl, apiKey, attacker, defender, meAsDefender) { attacker && [ "metal", "crystal", "deut", "food" ].forEach(e => { attacker.ships?.[e] && delete attacker.ships?.[e]; }); var coords = ogl.currentPlanet.obj.coords.split(":"); let jsonData = { 0: [ { planet: { galaxy: coords[0], system: coords[1], position: coords[2] }, class: ogl.account.class, characterClassesEnabled: !0, allianceClass: ogl.db.allianceClass || 0, research: {}, ships: attacker?.ships || {} } ], 1: [ { planet: defender?.planet || {}, research: {}, ships: defender?.ships || {} } ] }; [ 109, 110, 111, 114, 115, 117, 118 ].forEach(techID => { jsonData[0][0].research[techID] = { level: ogl.currentPlanet.obj[techID] || 0 }; }), console.log(jsonData[0][0].research), meAsDefender || (2 == ogl.account.class && (jsonData[0][0].research[109].level = (jsonData[0][0].research[109].level || 0) + 2, jsonData[0][0].research[110].level = (jsonData[0][0].research[110].level || 0) + 2, jsonData[0][0].research[111].level = (jsonData[0][0].research[111].level || 0) + 2), 1 == ogl.db.allianceClass && (jsonData[0][0].research[109].level = (jsonData[0][0].research[109].level || 0) + 1, jsonData[0][0].research[110].level = (jsonData[0][0].research[110].level || 0) + 1, jsonData[0][0].research[111].level = (jsonData[0][0].research[111].level || 0) + 1), jsonData[0][0].lifeformBonuses = jsonData[0][0].lifeformBonuses || {}, jsonData[0][0].lifeformBonuses.BaseStatsBooster = jsonData[0][0].lifeformBonuses.BaseStatsBooster || {}, ogl.shipsList.forEach(shipID => { jsonData[0][0].lifeformBonuses.BaseStatsBooster[shipID] = jsonData[0][0].lifeformBonuses.BaseStatsBooster[shipID] || {}, Object.entries(ogl.db.lfBonuses?.[shipID] || { weapon: 0, shield: 0, armor: 0, cargo: 0, speed: 0, fuel: 0 }).forEach(entry => { "fuel" == entry[0] && 0 != entry[1] ? jsonData[0][0].lifeformBonuses.ShipFuelConsumption = Math.abs(entry[1] / 100) : jsonData[0][0].lifeformBonuses.BaseStatsBooster[shipID][entry[0]] = entry[1] / 100; }); }), jsonData[0][0].lifeformBonuses.CharacterClassBooster = {}, jsonData[0][0].lifeformBonuses.CharacterClassBooster[ogl.account.class] = (ogl.db.lfBonuses?.["Characterclasses" + ogl.account.class]?.bonus || 0) / 100), jsonData = btoa(JSON.stringify(jsonData)); coords = "us" == ogl.account.lang ? "en" : "ar" == ogl.account.lang ? "es" : ogl.account.lang, defender = ogl.db.options.sim && Util.simList[ogl.db.options.sim] ? ogl.db.options.sim : Object.keys(Util.simList)[Math.floor(Math.random() * Object.keys(Util.simList).length)], meAsDefender = Util.simList[defender]; return apiKey ? meAsDefender + coords + "?SR_KEY=" + apiKey + "#prefill=" + jsonData : meAsDefender + coords + "#prefill=" + jsonData; } static genConverterLink(ogl, apiKey) { var lang = "us" == ogl.account.lang ? "en" : "ar" == ogl.account.lang ? "es" : ogl.account.lang, ogl = ogl.db.options.converter && Util.converterList[ogl.db.options.converter] ? ogl.db.options.converter : Object.keys(Util.converterList)[Math.floor(Math.random() * Object.keys(Util.converterList).length)], link = Util.converterList[ogl]; return "ogotcha" == ogl ? "" + link + lang + `?CR_KEY=${apiKey}&utm_source=OGLight` : "topraider" == ogl ? link + `?CR_KEY=${apiKey}&lang=` + lang : "ogame.tools" == ogl ? link + "?CR_KEY=" + apiKey : void 0; } static genOgotchaLink(ogl, apiKey) { return `https://ogotcha.universeview.be/${"us" == ogl.account.lang ? "en" : "ar" == ogl.account.lang ? "es" : ogl.account.lang}?CR_KEY=${apiKey}&utm_source=OGLight`; } static genTopRaiderLink(ogl, apiKey) { return `https://topraider.eu/index.php?CR_KEY=${apiKey}&lang=` + ("us" == ogl.account.lang ? "en" : "ar" == ogl.account.lang ? "es" : ogl.account.lang); } static genMmorpgstatLink(ogl, playerID) { return `https://www.mmorpg-stat.eu/0_fiche_joueur.php?pays=${[ "fr", "de", "en", "es", "pl", "it", "ru", "ar", "mx", "tr", "fi", "tw", "gr", "br", "nl", "hr", "sk", "cz", "ro", "us", "pt", "dk", "no", "se", "si", "hu", "jp", "ba" ].indexOf(ogl.server.lang)}&ftr=${playerID}.dat&univers=_` + ogl.server.id; } } class PTRE { constructor(ogl) { this.ogl = ogl, this.url = "https://ptre.chez.gg/scripts/", this.playerPositionsDelay = 36e5, this.manageSyncedListUrl = "https://ptre.chez.gg/?page=players_list"; } request(page, init) { let params = {}, options = {}; document.querySelector(".ogl_ptreActionIcon i") && (this.ogl.ptreNotificationIconTimeout && clearTimeout(this.ogl.ptreNotificationIconTimeout), document.querySelector(".ogl_ptreActionIcon i").className = "material-icons ogl_warning", document.querySelector(".ogl_ptreActionIcon i").classList.add("ogl_active")), Object.entries(init).forEach(obj => { 0 === obj[0].indexOf("_") ? options[obj[0].replace("_", "")] = obj[1] : params[obj[0]] = obj[1]; }), params.tool = "oglight", params.team_key = this.ogl.ptreKey, params.country = this.ogl.server.lang, params.univers = this.ogl.server.id, params.version = this.ogl.version; init = params ? "?" + new URLSearchParams(params).toString() : ""; return fetch("" + this.url + page + init, options).then(response => response.json()).then(data => (this.ogl.ptreNotificationIconTimeout = setTimeout(() => this.notify(data.message, data.code, data.message_verbose), 100), Promise.resolve(data))); } notify(message, code, verbose) { document.querySelector(".ogl_ptreActionIcon i") && ( document.querySelector(".ogl_ptreActionIcon i").className = "material-icons", document.querySelector(".ogl_ptreActionIcon i").classList.remove("ogl_active"), 1 != code ? (this.log(code, verbose || message), document.querySelector(".ogl_ptreActionIcon i").classList.add("ogl_danger")) : document.querySelector(".ogl_ptreActionIcon i").classList.add("ogl_ok")); } log(code, message) { var id = serverTime.getTime(); this.ogl.cache.ptreLogs = this.ogl.cache.ptreLogs || [], this.ogl.cache.ptreLogs.push({ code: code, message: message, id: id }), 10 < this.ogl.cache.ptreLogs.length && this.ogl.cache.ptreLogs.shift(); } displayLogs() { let container = Util.addDom("div", { class: "ogl_log" }); 0 < this.ogl.cache.ptreLogs?.length ? (this.ogl.cache.ptreLogs.forEach(log => { var time = this.ogl._time.convertTimestampToDate(log.id); Util.addDom("div", { child: `<div>${time.outerHTML}</div><div>${log.code}</div><div>${log.message}</div>`, prepend: container }); }), Util.addDom("div", { child: "<div>time</div><div>error code</div><div>message</div>", prepend: container })) : Util.addDom("div", { child: "empty", parent: container }), Util.addDom("div", { child: "<h2>PTRE errors</h2>", prepend: container }), this.ogl._popup.open(container, !0); } postPositions(postData) { this.request("api_galaxy_import_infos.php", { _method: "POST", _body: JSON.stringify(postData) }); } postActivities(postData) { this.request("oglight_import_player_activity.php", { _method: "POST", _body: JSON.stringify(postData) }).then(data => { 1 == data.code && Object.keys(postData).forEach(id => { var parent = document.querySelector(`.msg[data-msg-id="${id}"] .msg_title`); parent && ! document.querySelector(`.msg[data-msg-id="${id}"] .ogl_checked`) && Util.addDom("div", { class: "material-icons ogl_checked tooltipLeft ogl_ptre", child: "ptre", title: this.ogl._lang.find("ptreActivityImported"), parent: parent }), "messages" == this.ogl.page && this.ogl.cache.counterSpies.push(id); }); }); } postPTRECompatibility(postData) { this.request("oglight_update_version.php", { _method: "POST", _body: JSON.stringify(postData) }).then(data => { 1 == data.code && (this.ogl.id[1] = serverTime.getTime(), GM_setValue("ogl_id", this.ogl.id)); }); } postSpyReport(apiKey) { this.request("oglight_import.php", { _method: "POST", sr_id: apiKey }).then(data => { this.ogl._notification.addToQueue("PTRE: " + data.message_verbose, 1 == data.code); }); } syncTargetList() { let json = []; Object.values(this.ogl.db.udb).filter(u => "ptre" == u.pin).forEach(player => { json.push({ id: player.uid, pseudo: player.name }); }), this.request("api_sync_target_list.php", { _method: "POST", _body: JSON.stringify(json) }).then(data => { 1 == data.code && (data.targets_array.forEach(playerData => { var id = parseInt(playerData.player_id), id = this.ogl.db.udb[id] || this.ogl.createPlayer(id); id.name = playerData.pseudo, id.pin || (id.pin = "ptre"); }), document.querySelector(".ogl_side.ogl_active")) && "ptre" == this.ogl.db.lastPinTab && this.ogl._topbar.openPinned(), this.ogl._notification.addToQueue("PTRE: " + data.message, 1 == data.code); }); } getPlayerInfo(player, frame) { let container = Util.addDom("div", { class: "ogl_ptreContent", child: '<div class="ogl_loading"></div>' }); this.ogl._popup.open(container), frame = frame || "week", this.request("oglight_get_player_infos.php", { _method: "GET", player_id: player.id, pseudo: player.name, input_frame: frame }).then(data => { if (1 == data.code) { var arrData = JSON.parse(data.activity_array?.activity_array || "{}"); let checkData = JSON.parse(data.activity_array?.check_array || "{}"); container.innerHTML = ` <h3>${player.name}</h3> <div class="ogl_ptreActivityBlock"> <div class="ogl_frameSelector"></div> <div class="ogl_ptreActivities"><span></span><div></div></div> </div> <div class="ogl_ptreBestReport"> <div>${this.ogl._lang.find("reportFound")} (${new Date(1e3 * data.top_sr_timestamp).toLocaleDateString("fr-FR")})</div> <div> <div class="ogl_fleetDetail"></div> <b><i class="material-icons">rocket_launch</i>${Util.formatToUnits(data.top_sr_fleet_points)} pts</b> </div> <div> <a class="ogl_button" target="_blank" href="${data.top_sr_link}">${this.ogl._lang.find("topReportDetails")}</a> <a class="ogl_button" target="_blank" href="https://ptre.chez.gg/?country=${this.ogl.server.lang}&univers=${this.ogl.server.id}&player_id=${player.id}">${this.ogl._lang.find("playerProfile")}</a> </div> </div> <!--<ul class="ogl_ptreLegend"> <li><u>Green circle</u>: no activity detected & fully checked</li> <li><u>Green dot</u>: no activity detected</li> <li><u>Red dot</u>: multiple activities detected</li> <li><u>Transparent dot</u>: not enough planet checked</li> </ul>--> `, Object.entries({ last24h: "Last 24h", "2days": "2 days", "3days": "3 days", week: "Week", "2weeks": "2 weeks", month: "Month" }).forEach(range => { var button = Util.addDom("button", { class: "ogl_button", child: range[1], parent: container.querySelector(".ogl_frameSelector"), onclick: () => { this.getPlayerInfo(player, range[0]); } }); range[0] == frame && button.classList.add("ogl_active"); }), 1 == data.activity_array.succes && arrData.forEach((line, index) => { if (!isNaN(line[1])) { var div = Util.addDom("div", { class: "tooltip", child: `<div>${line[0]}</div>` }), dot = div.appendChild(Util.addDom("span", { class: "ogl_ptreDotStats" })).appendChild(Util.addDom("div", { "data-acti": line[1], "data-check": checkData[index][1] })), dotValue = line[1] / data.activity_array.max_acti_per_slot * 100 * 7, dotValue = 30 * Math.ceil(dotValue / 30); dot.style.color = `hsl(${Math.max(0, 100 - dotValue)}deg 75% 40%)`, dot.style.opacity = checkData[index][1] + "%"; let title; dotValue = Math.max(0, 100 - dotValue); title = 100 === dotValue ? "- No activity detected" : 60 <= dotValue ? "- A few activities detected" : 40 <= dotValue ? "- Some activities detected" : "- A lot of activities detected", 100 == checkData[index][1] ? title += "<br>- Perfectly checked" : 75 <= checkData[index][1] ? title += "<br>- Nicely checked" : 50 <= checkData[index][1] ? title += "<br>- Decently checked" : title = 0 < checkData[index][1] ? "Poorly checked" : "Not checked", div.setAttribute("title", title), 100 === checkData[index][1] && 0 == line[1] && dot.classList.add("ogl_active"), container.querySelector(".ogl_ptreActivities > div").appendChild(div); } }), data.fleet_json && this.ogl.shipsList.forEach(shipID => { var shipData = data.fleet_json.find(e => e.ship_type == shipID); shipData && Util.addDom("div", { class: "ogl_icon ogl_" + shipID, child: Util.formatToUnits(shipData.count), parent: container.querySelector(".ogl_fleetDetail") }); }), this.ogl._popup.open(container, !0); } else container.innerHTML = data.message + '<hr><a target="_blank" href="https://ptre.chez.gg/?page=splash">More informations here</a>'; }); } getPlayerPositions(playerData) { let updateList = () => { document.querySelector(".ogl_pinDetail") && this.ogl.db.currentSide == playerData.id && this.ogl._topbar.openPinnedDetail(playerData.id, !0); }, player = this.ogl.db.udb[playerData.id] || this.ogl.createPlayer(playerData.player_id); this.ogl._fetch.fetchPlayerAPI(playerData.id, playerData.name, () => { this.ogl.ptreKey && serverTime.getTime() - (player.ptre || 0) > this.playerPositionsDelay ? this.request("api_galaxy_get_infos.php", { _method: "GET", player_id: playerData.id }).then(data => { 1 == data.code && (updateList(), player.ptre = serverTime.getTime(), data.galaxy_array.forEach(ptrePlanet => { var oglPlanet = this.ogl.db.pdb[ptrePlanet.coords] || {}; (oglPlanet.api || 0) < ptrePlanet.timestamp_ig && (oglPlanet.uid = ptrePlanet.player_id, oglPlanet.pid = ptrePlanet.id, oglPlanet.mid = ptrePlanet.moon?.id || -1, oglPlanet.coo = ptrePlanet.coords, oglPlanet.acti = [ "60", "60", ptrePlanet.timestamp_ig ], this.ogl.removeOldPlanetOwner(ptrePlanet.coords, ptrePlanet.player_id), player.planets && player.planets.indexOf(ptrePlanet.coords) < 0 && player.planets.push(ptrePlanet.coords), this.ogl.db.pdb[ptrePlanet.coords] = oglPlanet, document.querySelector(".ogl_pinDetail")) && this.ogl.db.currentSide == ptrePlanet.player_id && this.ogl._topbar.openPinnedDetail(this.ogl.db.currentSide); })), this.ogl._notification.addToQueue("PTRE: " + data.message, 1 == data.code); }) : updateList(); }); } getRank(params, callback) { this.request("api_get_ranks.php", { _method: "GET", country: (params = params || {}).country || this.ogl.server.lang, univers: params.univers || this.ogl.server.id, timestamp: params.timestamp || -1 }).then(data => { callback && callback(data); }); } } class Datafinder { static getTech(id) { return { 1: { metal: 60, crystal: 15, deut: 0, priceFactor: 1.5 }, 2: { metal: 48, crystal: 24, deut: 0, priceFactor: 1.6 }, 3: { metal: 225, crystal: 75, deut: 0, priceFactor: 1.5 }, 4: { metal: 75, crystal: 30, deut: 0, priceFactor: 1.5 }, 12: { metal: 900, crystal: 360, deut: 180, priceFactor: 1.8 }, 14: { metal: 400, crystal: 120, deut: 200 }, 15: { metal: 1e6, crystal: 5e5, deut: 1e5 }, 21: { metal: 400, crystal: 200, deut: 100 }, 22: { metal: 1e3, crystal: 0, deut: 0 }, 23: { metal: 1e3, crystal: 500, deut: 0 }, 24: { metal: 1e3, crystal: 1e3, deut: 0 }, 31: { metal: 200, crystal: 400, deut: 200 }, 33: { metal: 0, crystal: 5e4, deut: 1e5, energy: 1e3, energyFactor: 2 }, 34: { metal: 2e4, crystal: 4e4, deut: 0 }, 36: { metal: 200, crystal: 0, deut: 50, energy: 50, priceFactor: 5, energyFactor: 2.5 }, 41: { metal: 2e4, crystal: 4e4, deut: 2e4 }, 42: { metal: 2e4, crystal: 4e4, deut: 2e4 }, 43: { metal: 2e6, crystal: 4e6, deut: 2e6 }, 44: { metal: 2e4, crystal: 2e4, deut: 1e3 }, 106: { metal: 200, crystal: 1e3, deut: 200 }, 108: { metal: 0, crystal: 400, deut: 600 }, 109: { metal: 800, crystal: 200, deut: 0 }, 110: { metal: 200, crystal: 600, deut: 0 }, 111: { metal: 1e3, crystal: 0, deut: 0 }, 113: { metal: 0, crystal: 800, deut: 400 }, 114: { metal: 0, crystal: 4e3, deut: 2e3 }, 115: { metal: 400, crystal: 0, deut: 600 }, 117: { metal: 2e3, crystal: 4e3, deut: 600 }, 118: { metal: 1e4, crystal: 2e4, deut: 6e3 }, 120: { metal: 200, crystal: 100, deut: 0 }, 121: { metal: 1e3, crystal: 300, deut: 100 }, 122: { metal: 2e3, crystal: 4e3, deut: 1e3 }, 123: { metal: 24e4, crystal: 4e5, deut: 16e4 }, 124: { metal: 4e3, crystal: 8e3, deut: 4e3, priceFactor: 1.75 }, 199: { metal: 0, crystal: 0, deut: 0, energy: 3e5, priceFactor: 3, energyFactor: 3, durationFactor: 1 }, 202: { metal: 2e3, crystal: 2e3, deut: 0 }, 203: { metal: 6e3, crystal: 6e3, deut: 0 }, 204: { metal: 3e3, crystal: 1e3, deut: 0 }, 205: { metal: 6e3, crystal: 4e3, deut: 0 }, 206: { metal: 2e4, crystal: 7e3, deut: 2e3 }, 207: { metal: 45e3, crystal: 15e3, deut: 0 }, 208: { metal: 1e4, crystal: 2e4, deut: 1e4 }, 209: { metal: 1e4, crystal: 6e3, deut: 2e3 }, 210: { crystal: 1e3, deut: 0 }, 211: { metal: 5e4, crystal: 25e3, deut: 15e3 }, 212: { metal: 0, crystal: 2e3, deut: 500 }, 213: { metal: 6e4, crystal: 5e4, deut: 15e3 }, 214: { metal: 5e6, crystal: 4e6, deut: 1e6 }, 215: { metal: 3e4, crystal: 4e4, deut: 15e3 }, 217: { metal: 2e3, crystal: 2e3, deut: 1e3 }, 218: { metal: 85e3, crystal: 55e3, deut: 2e4 }, 219: { metal: 8e3, crystal: 15e3, deut: 8e3 }, 401: { metal: 2e3, crystal: 0, deut: 0 }, 402: { metal: 1500, crystal: 500, deut: 0 }, 403: { metal: 6e3, crystal: 2e3, deut: 0 }, 404: { metal: 2e4, crystal: 15e3, deut: 2e3 }, 405: { metal: 5e3, crystal: 3e3, deut: 0 }, 406: { metal: 5e4, crystal: 5e4, deut: 3e4 }, 407: { metal: 1e4, crystal: 1e4, deut: 0 }, 408: { metal: 5e4, crystal: 5e4, deut: 0 }, 502: { metal: 8e3, crystal: 0, deut: 2e3 }, 503: { metal: 12e3, crystal: 2500, deut: 1e4 }, 11101: { type: "building", lifeform: "human", metal: 7, crystal: 2, deut: 0, priceFactor: 1.2, bonus1BaseValue: 210, bonus1IncreaseFactor: 1.21, bonus2BaseValue: 16, bonus2IncreaseFactor: 1.2, bonus3Value: 9, bonus3IncreaseFactor: 1.15, durationfactor: 1.21, durationbase: 40 }, 11102: { type: "building", lifeform: "human", metal: 5, crystal: 2, deut: 0, energy: 8, priceFactor: 1.23, energyIncreaseFactor: 1.02, bonus1BaseValue: 10, bonus1IncreaseFactor: 1.15, bonus2BaseValue: 10, bonus2IncreaseFactor: 1.14, durationfactor: 1.25, durationbase: 40 }, 11103: { type: "building", lifeform: "human", metal: 2e4, crystal: 25e3, deut: 1e4, energy: 10, priceFactor: 1.3, energyIncreaseFactor: 1.08, bonus1BaseValue: .25, bonus1IncreaseFactor: 1, bonus1Max: .25, bonus2BaseValue: 2, bonus2IncreaseFactor: 1, bonus2Max: .99, durationfactor: 1.25, durationbase: 16e3 }, 11104: { type: "building", lifeform: "human", metal: 5e3, crystal: 3200, deut: 1500, energy: 15, priceFactor: 1.7, energyIncreaseFactor: 1.25, bonus1BaseValue: 2e7, bonus1IncreaseFactor: 1.1, bonus2BaseValue: 1, bonus2IncreaseFactor: 1, durationfactor: 1.6, durationbase: 16e3 }, 11105: { type: "building", lifeform: "human", metal: 5e4, crystal: 4e4, deut: 5e4, energy: 30, priceFactor: 1.7, energyIncreaseFactor: 1.25, bonus1BaseValue: 1e8, bonus1IncreaseFactor: 1.1, bonus2BaseValue: 1, bonus2IncreaseFactor: 1, durationfactor: 1.7, durationbase: 64e3 }, 11106: { type: "building", lifeform: "human", metal: 9e3, crystal: 6e3, deut: 3e3, energy: 40, priceFactor: 1.5, energyIncreaseFactor: 1.1, bonus1BaseValue: 1.5, bonus1IncreaseFactor: 1, durationfactor: 1.3, durationbase: 2e3 }, 11107: { type: "building", lifeform: "human", metal: 25e3, crystal: 13e3, deut: 7e3, priceFactor: 1.09, bonus1BaseValue: 1, bonus1IncreaseFactor: 1, bonus2BaseValue: 1, bonus2IncreaseFactor: 1, bonus2Max: .8, bonus3Value: .8, bonus3IncreaseFactor: 1, durationfactor: 1.17, durationbase: 12e3 }, 11108: { type: "building", lifeform: "human", metal: 5e4, crystal: 25e3, deut: 15e3, energy: 80, priceFactor: 1.5, energyIncreaseFactor: 1.1, bonus1BaseValue: 1.5, bonus1IncreaseFactor: 1, bonus2BaseValue: 1, bonus2IncreaseFactor: 1, durationfactor: 1.2, durationbase: 28e3 }, 11109: { type: "building", lifeform: "human", metal: 75e3, crystal: 2e4, deut: 25e3, energy: 50, priceFactor: 1.09, energyIncreaseFactor: 1.02, bonus1BaseValue: 1.5, bonus1IncreaseFactor: 1, bonus2BaseValue: 1.5, bonus2IncreaseFactor: 1, durationfactor: 1.2, durationbase: 4e4 }, 11110: { type: "building", lifeform: "human", metal: 15e4, crystal: 3e4, deut: 15e3, energy: 60, priceFactor: 1.12, energyIncreaseFactor: 1.03, bonus1BaseValue: 5, bonus1IncreaseFactor: 1, durationfactor: 1.2, durationbase: 52e3 }, 11111: { type: "building", lifeform: "human", metal: 8e4, crystal: 35e3, deut: 6e4, energy: 90, priceFactor: 1.5, energyIncreaseFactor: 1.05, bonus1BaseValue: .5, bonus1IncreaseFactor: 1, bonus1Max: 1, durationfactor: 1.3, durationbase: 9e4 }, 11112: { type: "building", lifeform: "human", metal: 25e4, crystal: 125e3, deut: 125e3, energy: 100, priceFactor: 1.15, energyIncreaseFactor: 1.02, bonus1BaseValue: 3, bonus1IncreaseFactor: 1, bonus1Max: .9, durationfactor: 1.2, durationbase: 95e3 }, 11201: { type: "tech 1", lifeform: "human", metal: 5e3, crystal: 2500, deut: 500, priceFactor: 1.3, bonus1BaseValue: 1, bonus1IncreaseFactor: 1, durationfactor: 1.2, durationbase: 1e3 }, 11202: { type: "tech 2", lifeform: "human", metal: 7e3, crystal: 1e4, deut: 5e3, priceFactor: 1.5, bonus1BaseValue: .06, bonus1IncreaseFactor: 1, durationfactor: 1.3, durationbase: 2e3 }, 11203: { type: "tech 3", lifeform: "human", metal: 15e3, crystal: 1e4, deut: 5e3, priceFactor: 1.3, bonus1BaseValue: .5, bonus1IncreaseFactor: 1, durationfactor: 1.3, durationbase: 2500 }, 11204: { type: "tech 4", lifeform: "human", metal: 2e4, crystal: 15e3, deut: 7500, priceFactor: 1.3, bonus1BaseValue: .1, bonus1IncreaseFactor: 1, bonus1Max: .5, bonus2BaseValue: .2, bonus2IncreaseFactor: 1, bonus2Max: .99, durationfactor: 1.3, durationbase: 3500 }, 11205: { type: "tech 5", lifeform: "human", metal: 25e3, crystal: 2e4, deut: 1e4, priceFactor: 1.3, bonus1BaseValue: 4, bonus1IncreaseFactor: 1, durationfactor: 1.2, durationbase: 4500 }, 11206: { type: "tech 6", lifeform: "human", metal: 35e3, crystal: 25e3, deut: 15e3, priceFactor: 1.5, bonus1BaseValue: .1, bonus1IncreaseFactor: 1, bonus1Max: .99, durationfactor: 1.3, durationbase: 5e3 }, 11207: { type: "tech 7", lifeform: "human", metal: 7e4, crystal: 4e4, deut: 2e4, priceFactor: 1.3, bonus1BaseValue: .1, bonus1IncreaseFactor: 1, bonus1Max: .5, bonus2BaseValue: .2, bonus2IncreaseFactor: 1, bonus2Max: .99, durationfactor: 1.3, durationbase: 8e3 }, 11208: { type: "tech 8", lifeform: "human", metal: 8e4, crystal: 5e4, deut: 2e4, priceFactor: 1.5, bonus1BaseValue: .06, bonus1IncreaseFactor: 1, durationfactor: 1.3, durationbase: 6e3 }, 11209: { type: "tech 9", lifeform: "human", metal: 32e4, crystal: 24e4, deut: 1e5, priceFactor: 1.5, bonus1BaseValue: .3, bonus1IncreaseFactor: 1, durationfactor: 1.4, durationbase: 6500 }, 11210: { type: "tech 10", lifeform: "human", metal: 32e4, crystal: 24e4, deut: 1e5, priceFactor: 1.5, bonus1BaseValue: .3, bonus1IncreaseFactor: 1, durationfactor: 1.4, durationbase: 7e3 }, 11211: { type: "tech 11", lifeform: "human", metal: 12e4, crystal: 3e4, deut: 25e3, priceFactor: 1.5, bonus1BaseValue: .1, bonus1IncreaseFactor: 1, bonus1Max: .99, durationfactor: 1.3, durationbase: 7500 }, 11212: { type: "tech 12", lifeform: "human", metal: 1e5, crystal: 4e4, deut: 3e4, priceFactor: 1.3, bonus1BaseValue: .1, bonus1IncreaseFactor: 1, bonus1Max: .5, bonus2BaseValue: .2, bonus2IncreaseFactor: 1, bonus2Max: .99, durationfactor: 1.3, durationbase: 1e4 }, 11213: { type: "tech 13", lifeform: "human", metal: 2e5, crystal: 1e5, deut: 1e5, priceFactor: 1.3, bonus1BaseValue: .1, bonus1IncreaseFactor: 1, bonus1Max: .5, bonus2BaseValue: .2, bonus2IncreaseFactor: 1, bonus2Max: .99, durationfactor: 1.3, durationbase: 8500 }, 11214: { type: "tech 14", lifeform: "human", metal: 16e4, crystal: 12e4, deut: 5e4, priceFactor: 1.5, bonus1BaseValue: .3, bonus1IncreaseFactor: 1, durationfactor: 1.4, durationbase: 9e3 }, 11215: { type: "tech 15", lifeform: "human", metal: 16e4, crystal: 12e4, deut: 5e4, priceFactor: 1.5, bonus1BaseValue: .3, bonus1IncreaseFactor: 1, durationfactor: 1.4, durationbase: 9500 }, 11216: { type: "tech 16", lifeform: "human", metal: 32e4, crystal: 24e4, deut: 1e5, priceFactor: 1.5, bonus1BaseValue: .3, bonus1IncreaseFactor: 1, durationfactor: 1.4, durationbase: 1e4 }, 11217: { type: "tech 17", lifeform: "human", metal: 3e5, crystal: 18e4, deut: 12e4, priceFactor: 1.5, bonus1BaseValue: .2, bonus1IncreaseFactor: 1, bonus1Max: .99, durationfactor: 1.3, durationbase: 11e3 }, 11218: { type: "tech 18", lifeform: "human", metal: 5e5, crystal: 3e5, deut: 2e5, priceFactor: 1.2, bonus1BaseValue: .3, bonus1IncreaseFactor: 1, bonus1Max: .99, durationfactor: 1.3, durationbase: 13e3 }, 12101: { type: "building", lifeform: "rocktal", metal: 9, crystal: 3, deut: 0, priceFactor: 1.2, bonus1BaseValue: 150, bonus1IncreaseFactor: 1.216, bonus2BaseValue: 12, bonus2IncreaseFactor: 1.2, bonus3Value: 5, bonus3IncreaseFactor: 1.15, durationfactor: 1.21, durationbase: 40 }, 12102: { type: "building", lifeform: "rocktal", metal: 7, crystal: 2, deut: 0, energy: 10, priceFactor: 1.2, energyIncreaseFactor: 1.03, bonus1BaseValue: 8, bonus1IncreaseFactor: 1.15, bonus2BaseValue: 6, bonus2IncreaseFactor: 1.14, durationfactor: 1.21, durationbase: 40 }, 12103: { type: "building", lifeform: "rocktal", metal: 4e4, crystal: 1e4, deut: 15e3, energy: 15, priceFactor: 1.3, energyIncreaseFactor: 1.1, bonus1BaseValue: .25, bonus1IncreaseFactor: 1, bonus1Max: .25, bonus2BaseValue: 2, bonus2IncreaseFactor: 1, bonus2Max: .99, durationfactor: 1.25, durationbase: 16e3 }, 12104: { type: "building", lifeform: "rocktal", metal: 5e3, crystal: 3800, deut: 1e3, energy: 20, priceFactor: 1.7, energyIncreaseFactor: 1.35, bonus1BaseValue: 16e6, bonus1IncreaseFactor: 1.14, bonus2BaseValue: 1, bonus2IncreaseFactor: 1, durationfactor: 1.6, durationbase: 16e3 }, 12105: { type: "building", lifeform: "rocktal", metal: 5e4, crystal: 4e4, deut: 5e4, energy: 60, priceFactor: 1.65, energyIncreaseFactor: 1.3, bonus1BaseValue: 9e7, bonus1IncreaseFactor: 1.1, bonus2BaseValue: 1, bonus2IncreaseFactor: 1, durationfactor: 1.7, durationbase: 64e3 }, 12106: { type: "building", lifeform: "rocktal", metal: 1e4, crystal: 8e3, deut: 1e3, energy: 40, priceFactor: 1.4, energyIncreaseFactor: 1.1, bonus1BaseValue: 2, bonus1IncreaseFactor: 1, durationfactor: 1.3, durationbase: 2e3 }, 12107: { type: "building", lifeform: "rocktal", metal: 2e4, crystal: 15e3, deut: 1e4, priceFactor: 1.2, bonus1BaseValue: 1.5, bonus1IncreaseFactor: 1, bonus2BaseValue: .5, bonus2IncreaseFactor: 1, bonus2Max: .4, durationfactor: 1.25, durationbase: 16e3 }, 12108: { type: "building", lifeform: "rocktal", metal: 5e4, crystal: 35e3, deut: 15e3, energy: 80, priceFactor: 1.5, energyIncreaseFactor: 1.3, bonus1BaseValue: 1, bonus1IncreaseFactor: 1, bonus1Max: .5, bonus2BaseValue: 1, bonus2IncreaseFactor: 1, bonus2Max: .5, durationfactor: 1.4, durationbase: 4e4 }, 12109: { type: "building", lifeform: "rocktal", metal: 85e3, crystal: 44e3, deut: 25e3, energy: 90, priceFactor: 1.4, energyIncreaseFactor: 1.1, bonus1BaseValue: 2, bonus1IncreaseFactor: 1, durationfactor: 1.2, durationbase: 4e4 }, 12110: { type: "building", lifeform: "rocktal", metal: 12e4, crystal: 5e4, deut: 2e4, energy: 90, priceFactor: 1.4, energyIncreaseFactor: 1.1, bonus1BaseValue: 2, bonus1IncreaseFactor: 1, durationfactor: 1.2, durationbase: 52e3 }, 12111: { type: "building", lifeform: "rocktal", metal: 25e4, crystal: 15e4, deut: 1e5, energy: 120, priceFactor: 1.8, energyIncreaseFactor: 1.3, bonus1BaseValue: .5, bonus1IncreaseFactor: 1, bonus1Max: .5, durationfactor: 1.3, durationbase: 9e4 }, 12112: { type: "building", lifeform: "rocktal", metal: 25e4, crystal: 125e3, deut: 125e3, energy: 100, priceFactor: 1.5, energyIncreaseFactor: 1.1, bonus1BaseValue: .6, bonus1IncreaseFactor: 1, bonus1Max: .3, durationfactor: 1.3, durationbase: 95e3 }, 12201: { type: "tech 1", lifeform: "rocktal", metal: 1e4, crystal: 6e3, deut: 1e3, priceFactor: 1.5, bonus1BaseValue: .25, bonus1IncreaseFactor: 1, durationfactor: 1.3, durationbase: 1e3 }, 12202: { type: "tech 2", lifeform: "rocktal", metal: 7500, crystal: 12500, deut: 5e3, priceFactor: 1.5, bonus1BaseValue: .08, bonus1IncreaseFactor: 1, durationfactor: 1.3, durationbase: 2e3 }, 12203: { type: "tech 3", lifeform: "rocktal", metal: 15e3, crystal: 1e4, deut: 5e3, priceFactor: 1.5, bonus1BaseValue: .08, bonus1IncreaseFactor: 1, durationfactor: 1.3, durationbase: 2500 }, 12204: { type: "tech 4", lifeform: "rocktal", metal: 2e4, crystal: 15e3, deut: 7500, priceFactor: 1.3, bonus1BaseValue: .4, bonus1IncreaseFactor: 1, durationfactor: 1.4, durationbase: 3500 }, 12205: { type: "tech 5", lifeform: "rocktal", metal: 25e3, crystal: 2e4, deut: 1e4, priceFactor: 1.5, bonus1BaseValue: .08, bonus1IncreaseFactor: 1, durationfactor: 1.3, durationbase: 4500 }, 12206: { type: "tech 6", lifeform: "rocktal", metal: 5e4, crystal: 5e4, deut: 2e4, priceFactor: 1.5, bonus1BaseValue: .25, bonus1IncreaseFactor: 1, durationfactor: 1.3, durationbase: 5e3 }, 12207: { type: "tech 7", lifeform: "rocktal", metal: 7e4, crystal: 4e4, deut: 2e4, priceFactor: 1.5, bonus1BaseValue: .08, bonus1IncreaseFactor: 1, durationfactor: 1.3, durationbase: 5500 }, 12208: { type: "tech 8", lifeform: "rocktal", metal: 16e4, crystal: 12e4, deut: 5e4, priceFactor: 1.5, bonus1BaseValue: .3, bonus1IncreaseFactor: 1, durationfactor: 1.4, durationbase: 6e3 }, 12209: { type: "tech 9", lifeform: "rocktal", metal: 75e3, crystal: 55e3, deut: 25e3, priceFactor: 1.5, bonus1BaseValue: .15, bonus1IncreaseFactor: 1, bonus1Max: .5, bonus2BaseValue: .3, bonus2IncreaseFactor: 1, bonus2Max: .99, durationfactor: 1.3, durationbase: 6500 }, 12210: { type: "tech 10", lifeform: "rocktal", metal: 85e3, crystal: 4e4, deut: 35e3, priceFactor: 1.5, bonus1BaseValue: .08, bonus1IncreaseFactor: 1, durationfactor: 1.3, durationbase: 7e3 }, 12211: { type: "tech 11", lifeform: "rocktal", metal: 12e4, crystal: 3e4, deut: 25e3, priceFactor: 1.5, bonus1BaseValue: .08, bonus1IncreaseFactor: 1, durationfactor: 1.3, durationbase: 7500 }, 12212: { type: "tech 12", lifeform: "rocktal", metal: 1e5, crystal: 4e4, deut: 3e4, priceFactor: 1.5, bonus1BaseValue: .08, bonus1IncreaseFactor: 1, durationfactor: 1.3, durationbase: 8e3 }, 12213: { type: "tech 13", lifeform: "rocktal", metal: 2e5, crystal: 1e5, deut: 1e5, priceFactor: 1.2, bonus1BaseValue: .1, bonus1IncreaseFactor: 1, bonus1Max: .5, bonus2BaseValue: .1, bonus2IncreaseFactor: 1, durationfactor: 1.3, durationbase: 8500 }, 12214: { type: "tech 14", lifeform: "rocktal", metal: 22e4, crystal: 11e4, deut: 11e4, priceFactor: 1.3, bonus1BaseValue: .1, bonus1IncreaseFactor: 1, bonus1Max: .5, bonus2BaseValue: .2, bonus2IncreaseFactor: 1, bonus2Max: .99, durationfactor: 1.3, durationbase: 9e3 }, 12215: { type: "tech 15", lifeform: "rocktal", metal: 24e4, crystal: 12e4, deut: 12e4, priceFactor: 1.3, bonus1BaseValue: .1, bonus1IncreaseFactor: 1, bonus1Max: .5, bonus2BaseValue: .2, bonus2IncreaseFactor: 1, bonus2Max: .99, durationfactor: 1.3, durationbase: 9500 }, 12216: { type: "tech 16", lifeform: "rocktal", metal: 25e4, crystal: 25e4, deut: 25e4, priceFactor: 1.4, bonus1BaseValue: .5, bonus1IncreaseFactor: 1, durationfactor: 1.4, durationbase: 1e4 }, 12217: { type: "tech 17", lifeform: "rocktal", metal: 5e5, crystal: 3e5, deut: 2e5, priceFactor: 1.5, bonus1BaseValue: .2, bonus1IncreaseFactor: 1, bonus1Max: .5, bonus2BaseValue: .2, bonus2IncreaseFactor: 1, bonus2Max: .99, durationfactor: 1.3, durationbase: 13e3 }, 12218: { type: "tech 18", lifeform: "rocktal", metal: 3e5, crystal: 18e4, deut: 12e4, priceFactor: 1.7, bonus1BaseValue: .2, bonus1IncreaseFactor: 1, durationfactor: 1.4, durationbase: 11e3 }, 13101: { type: "building", lifeform: "mecha", metal: 6, crystal: 2, deut: 0, priceFactor: 1.21, bonus1BaseValue: 500, bonus1IncreaseFactor: 1.205, bonus2BaseValue: 24, bonus2IncreaseFactor: 1.2, bonus3Value: 22, bonus3IncreaseFactor: 1.15, durationfactor: 1.22, durationbase: 40 }, 13102: { type: "building", lifeform: "mecha", metal: 5, crystal: 2, deut: 0, energy: 8, priceFactor: 1.18, energyIncreaseFactor: 1.02, bonus1BaseValue: 18, bonus1IncreaseFactor: 1.15, bonus2BaseValue: 23, bonus2IncreaseFactor: 1.12, durationfactor: 1.2, durationbase: 48 }, 13103: { type: "building", lifeform: "mecha", metal: 3e4, crystal: 2e4, deut: 1e4, energy: 13, priceFactor: 1.3, energyIncreaseFactor: 1.08, bonus1BaseValue: .25, bonus1IncreaseFactor: 1, bonus1Max: .25, bonus2BaseValue: 2, bonus2IncreaseFactor: 1, bonus2Max: .99, durationfactor: 1.25, durationbase: 16e3 }, 13104: { type: "building", lifeform: "mecha", metal: 5e3, crystal: 3800, deut: 1e3, energy: 10, priceFactor: 1.8, energyIncreaseFactor: 1.2, bonus1BaseValue: 4e7, bonus1IncreaseFactor: 1.1, bonus2BaseValue: 1, bonus2IncreaseFactor: 1, durationfactor: 1.6, durationbase: 16e3 }, 13105: { type: "building", lifeform: "mecha", metal: 5e4, crystal: 4e4, deut: 5e4, energy: 40, priceFactor: 1.8, energyIncreaseFactor: 1.2, bonus1BaseValue: 13e7, bonus1IncreaseFactor: 1.1, bonus2BaseValue: 1, bonus2IncreaseFactor: 1, durationfactor: 1.7, durationbase: 64e3 }, 13106: { type: "building", lifeform: "mecha", metal: 7500, crystal: 7e3, deut: 1e3, priceFactor: 1.3, bonus1BaseValue: 2, bonus1IncreaseFactor: 1, bonus1Max: .99, durationfactor: 1.3, durationbase: 2e3 }, 13107: { type: "building", lifeform: "mecha", metal: 35e3, crystal: 15e3, deut: 1e4, energy: 40, priceFactor: 1.5, energyIncreaseFactor: 1.05, bonus1BaseValue: 1, bonus1IncreaseFactor: 1, bonus1Max: 1, bonus2BaseValue: .3, bonus2IncreaseFactor: 1, durationfactor: 1.4, durationbase: 16e3 }, 13108: { type: "building", lifeform: "mecha", metal: 5e4, crystal: 2e4, deut: 3e4, energy: 40, priceFactor: 1.07, energyIncreaseFactor: 1.01, bonus1BaseValue: 2, bonus1IncreaseFactor: 1, bonus2BaseValue: 2, bonus2IncreaseFactor: 1, durationfactor: 1.17, durationbase: 12e3 }, 13109: { type: "building", lifeform: "mecha", metal: 1e5, crystal: 1e4, deut: 3e3, energy: 80, priceFactor: 1.14, energyIncreaseFactor: 1.04, bonus1BaseValue: 2, bonus1IncreaseFactor: 1, bonus2BaseValue: 6, bonus2IncreaseFactor: 1, durationfactor: 1.3, durationbase: 4e4 }, 13110: { type: "building", lifeform: "mecha", metal: 1e5, crystal: 4e4, deut: 2e4, energy: 60, priceFactor: 1.5, energyIncreaseFactor: 1.1, bonus1BaseValue: 2, bonus1IncreaseFactor: 1, durationfactor: 1.2, durationbase: 52e3 }, 13111: { type: "building", lifeform: "mecha", metal: 55e3, crystal: 5e4, deut: 3e4, energy: 70, priceFactor: 1.5, energyIncreaseFactor: 1.05, bonus1BaseValue: .4, bonus1IncreaseFactor: 1, bonus1Max: 1, durationfactor: 1.3, durationbase: 5e4 }, 13112: { type: "building", lifeform: "mecha", metal: 25e4, crystal: 125e3, deut: 125e3, energy: 100, priceFactor: 1.4, energyIncreaseFactor: 1.05, bonus1BaseValue: 1.3, bonus1IncreaseFactor: 1, bonus1Max: .5, durationfactor: 1.4, durationbase: 95e3 }, 13201: { type: "tech 1", lifeform: "mecha", metal: 1e4, crystal: 6e3, deut: 1e3, priceFactor: 1.5, bonus1BaseValue: .08, bonus1IncreaseFactor: 1, durationfactor: 1.3, durationbase: 1e3 }, 13202: { type: "tech 2", lifeform: "mecha", metal: 7500, crystal: 12500, deut: 5e3, priceFactor: 1.3, bonus1BaseValue: .2, bonus1IncreaseFactor: 1, durationfactor: 1.3, durationbase: 2e3 }, 13203: { type: "tech 3", lifeform: "mecha", metal: 15e3, crystal: 1e4, deut: 5e3, priceFactor: 1.5, bonus1BaseValue: .03, bonus1IncreaseFactor: 1, bonus1Max: .3, durationfactor: 1.4, durationbase: 2500 }, 13204: { type: "tech 4", lifeform: "mecha", metal: 2e4, crystal: 15e3, deut: 7500, priceFactor: 1.3, bonus1BaseValue: .1, bonus1IncreaseFactor: 1, bonus1Max: .5, bonus2BaseValue: .2, bonus2IncreaseFactor: 1, bonus2Max: .99, durationfactor: 1.3, durationbase: 3500 }, 13205: { type: "tech 5", lifeform: "mecha", metal: 16e4, crystal: 12e4, deut: 5e4, priceFactor: 1.5, bonus1BaseValue: .3, bonus1IncreaseFactor: 1, durationfactor: 1.4, durationbase: 4500 }, 13206: { type: "tech 6", lifeform: "mecha", metal: 5e4, crystal: 5e4, deut: 2e4, priceFactor: 1.5, bonus1BaseValue: .06, bonus1IncreaseFactor: 1, durationfactor: 1.3, durationbase: 5e3 }, 13207: { type: "tech 7", lifeform: "mecha", metal: 7e4, crystal: 4e4, deut: 2e4, priceFactor: 1.3, bonus1BaseValue: .1, bonus1IncreaseFactor: 1, bonus1Max: .5, bonus2BaseValue: .2, bonus2IncreaseFactor: 1, bonus2Max: .99, durationfactor: 1.3, durationbase: 5500 }, 13208: { type: "tech 8", lifeform: "mecha", metal: 16e4, crystal: 12e4, deut: 5e4, priceFactor: 1.5, bonus1BaseValue: 1, bonus1IncreaseFactor: 1, durationfactor: 1.4, durationbase: 6e3 }, 13209: { type: "tech 9", lifeform: "mecha", metal: 16e4, crystal: 12e4, deut: 5e4, priceFactor: 1.5, bonus1BaseValue: .3, bonus1IncreaseFactor: 1, durationfactor: 1.4, durationbase: 6500 }, 13210: { type: "tech 10", lifeform: "mecha", metal: 85e3, crystal: 4e4, deut: 35e3, priceFactor: 1.2, bonus1BaseValue: .15, bonus1IncreaseFactor: 1, bonus1Max: .9, durationfactor: 1.3, durationbase: 7e3 }, 13211: { type: "tech 11", lifeform: "mecha", metal: 12e4, crystal: 3e4, deut: 25e3, priceFactor: 1.3, bonus1BaseValue: .1, bonus1IncreaseFactor: 1, bonus1Max: .5, bonus2BaseValue: .2, bonus2IncreaseFactor: 1, bonus2Max: .99, durationfactor: 1.3, durationbase: 7500 }, 13212: { type: "tech 12", lifeform: "mecha", metal: 16e4, crystal: 12e4, deut: 5e4, priceFactor: 1.5, bonus1BaseValue: .3, bonus1IncreaseFactor: 1, durationfactor: 1.4, durationbase: 8e3 }, 13213: { type: "tech 13", lifeform: "mecha", metal: 2e5, crystal: 1e5, deut: 1e5, priceFactor: 1.5, bonus1BaseValue: .06, bonus1IncreaseFactor: 1, durationfactor: 1.3, durationbase: 8500 }, 13214: { type: "tech 14", lifeform: "mecha", metal: 16e4, crystal: 12e4, deut: 5e4, priceFactor: 1.5, bonus1BaseValue: .3, bonus1IncreaseFactor: 1, durationfactor: 1.4, durationbase: 9e3 }, 13215: { type: "tech 15", lifeform: "mecha", metal: 32e4, crystal: 24e4, deut: 1e5, priceFactor: 1.5, bonus1BaseValue: .3, bonus1IncreaseFactor: 1, durationfactor: 1.4, durationbase: 9500 }, 13216: { type: "tech 16", lifeform: "mecha", metal: 32e4, crystal: 24e4, deut: 1e5, priceFactor: 1.5, bonus1BaseValue: .3, bonus1IncreaseFactor: 1, durationfactor: 1.4, durationbase: 1e4 }, 13217: { type: "tech 17", lifeform: "mecha", metal: 5e5, crystal: 3e5, deut: 2e5, priceFactor: 1.5, bonus1BaseValue: .2, bonus1IncreaseFactor: 1, bonus1Max: .5, bonus2BaseValue: .2, bonus2IncreaseFactor: 1, bonus2Max: .99, durationfactor: 1.3, durationbase: 13e3 }, 13218: { type: "tech 18", lifeform: "mecha", metal: 3e5, crystal: 18e4, deut: 12e4, priceFactor: 1.7, bonus1BaseValue: .2, bonus1IncreaseFactor: 1, durationfactor: 1.4, durationbase: 11e3 }, 14101: { type: "building", lifeform: "kaelesh", metal: 4, crystal: 3, deut: 0, priceFactor: 1.21, bonus1BaseValue: 250, bonus1IncreaseFactor: 1.21, bonus2BaseValue: 16, bonus2IncreaseFactor: 1.2, bonus3Value: 11, bonus3IncreaseFactor: 1.15, durationfactor: 1.22, durationbase: 40 }, 14102: { type: "building", lifeform: "kaelesh", metal: 6, crystal: 3, deut: 0, energy: 9, priceFactor: 1.2, energyIncreaseFactor: 1.02, bonus1BaseValue: 12, bonus1IncreaseFactor: 1.15, bonus2BaseValue: 12, bonus2IncreaseFactor: 1.14, durationfactor: 1.22, durationbase: 40 }, 14103: { type: "building", lifeform: "kaelesh", metal: 2e4, crystal: 15e3, deut: 15e3, energy: 10, priceFactor: 1.3, energyIncreaseFactor: 1.08, bonus1BaseValue: .25, bonus1IncreaseFactor: 1, bonus1Max: .25, bonus2BaseValue: 2, bonus2IncreaseFactor: 1, bonus2Max: .99, durationfactor: 1.25, durationbase: 16e3 }, 14104: { type: "building", lifeform: "kaelesh", metal: 7500, crystal: 5e3, deut: 800, energy: 15, priceFactor: 1.8, energyIncreaseFactor: 1.3, bonus1BaseValue: 3e7, bonus1IncreaseFactor: 1.1, bonus2BaseValue: 1, bonus2IncreaseFactor: 1, durationfactor: 1.7, durationbase: 16e3 }, 14105: { type: "building", lifeform: "kaelesh", metal: 6e4, crystal: 3e4, deut: 5e4, energy: 30, priceFactor: 1.8, energyIncreaseFactor: 1.3, bonus1BaseValue: 1e8, bonus1IncreaseFactor: 1.1, bonus2BaseValue: 1, bonus2IncreaseFactor: 1, durationfactor: 1.8, durationbase: 64e3 }, 14106: { type: "building", lifeform: "kaelesh", metal: 8500, crystal: 5e3, deut: 3e3, priceFactor: 1.25, bonus1BaseValue: 1, bonus1IncreaseFactor: 1, bonus1Max: .5, durationfactor: 1.35, durationbase: 2e3 }, 14107: { type: "building", lifeform: "kaelesh", metal: 15e3, crystal: 15e3, deut: 5e3, priceFactor: 1.2, bonus1BaseValue: 2, bonus1IncreaseFactor: 1, durationfactor: 1.2, durationbase: 12e3 }, 14108: { type: "building", lifeform: "kaelesh", metal: 75e3, crystal: 25e3, deut: 3e4, energy: 30, priceFactor: 1.05, energyIncreaseFactor: 1.03, bonus1BaseValue: 2, bonus1IncreaseFactor: 1, bonus2BaseValue: 6, bonus2IncreaseFactor: 1, durationfactor: 1.18, durationbase: 16e3 }, 14109: { type: "building", lifeform: "kaelesh", metal: 87500, crystal: 25e3, deut: 3e4, energy: 40, priceFactor: 1.2, energyIncreaseFactor: 1.02, bonus1BaseValue: 200, bonus1IncreaseFactor: 1, durationfactor: 1.2, durationbase: 4e4 }, 14110: { type: "building", lifeform: "kaelesh", metal: 15e4, crystal: 3e4, deut: 3e4, energy: 140, priceFactor: 1.4, energyIncreaseFactor: 1.05, bonus1BaseValue: 2, bonus1IncreaseFactor: 1, bonus1Max: .3, durationfactor: 1.8, durationbase: 52e3 }, 14111: { type: "building", lifeform: "kaelesh", metal: 75e3, crystal: 5e4, deut: 55e3, energy: 90, priceFactor: 1.2, energyIncreaseFactor: 1.04, bonus1BaseValue: 1.5, bonus1IncreaseFactor: 1, bonus1Max: .7, durationfactor: 1.3, durationbase: 9e4 }, 14112: { type: "building", lifeform: "kaelesh", metal: 5e5, crystal: 25e4, deut: 25e4, energy: 100, priceFactor: 1.4, energyIncreaseFactor: 1.05, bonus1BaseValue: .5, bonus1IncreaseFactor: 1, bonus1Max: .3, durationfactor: 1.3, durationbase: 95e3 }, 14201: { type: "tech 1", lifeform: "kaelesh", metal: 1e4, crystal: 6e3, deut: 1e3, priceFactor: 1.5, bonus1BaseValue: .03, bonus1IncreaseFactor: 1, bonus1Max: .3, durationfactor: 1.4, durationbase: 1e3 }, 14202: { type: "tech 2", lifeform: "kaelesh", metal: 7500, crystal: 12500, deut: 5e3, priceFactor: 1.5, bonus1BaseValue: .08, bonus1IncreaseFactor: 1, durationfactor: 1.3, durationbase: 2e3 }, 14203: { type: "tech 3", lifeform: "kaelesh", metal: 15e3, crystal: 1e4, deut: 5e3, priceFactor: 1.5, bonus1BaseValue: .05, bonus1IncreaseFactor: 1, bonus1Max: .5, durationfactor: 1.4, durationbase: 2500 }, 14204: { type: "tech 4", lifeform: "kaelesh", metal: 2e4, crystal: 15e3, deut: 7500, priceFactor: 1.5, bonus1BaseValue: .2, bonus1IncreaseFactor: 1, durationfactor: 1.4, durationbase: 3500 }, 14205: { type: "tech 5", lifeform: "kaelesh", metal: 25e3, crystal: 2e4, deut: 1e4, priceFactor: 1.5, bonus1BaseValue: .2, bonus1IncreaseFactor: 1, durationfactor: 1.4, durationbase: 4500 }, 14206: { type: "tech 6", lifeform: "kaelesh", metal: 5e4, crystal: 5e4, deut: 2e4, priceFactor: 1.3, bonus1BaseValue: .4, bonus1IncreaseFactor: 1, durationfactor: 1.4, durationbase: 5e3 }, 14207: { type: "tech 7", lifeform: "kaelesh", metal: 7e4, crystal: 4e4, deut: 2e4, priceFactor: 1.5, bonus1BaseValue: .1, bonus1IncreaseFactor: 1, bonus1Max: .99, durationfactor: 1.3, durationbase: 5500 }, 14208: { type: "tech 8", lifeform: "kaelesh", metal: 8e4, crystal: 5e4, deut: 2e4, priceFactor: 1.2, bonus1BaseValue: .6, bonus1IncreaseFactor: 1, durationfactor: 1.2, durationbase: 6e3 }, 14209: { type: "tech 9", lifeform: "kaelesh", metal: 32e4, crystal: 24e4, deut: 1e5, priceFactor: 1.5, bonus1BaseValue: .3, bonus1IncreaseFactor: 1, durationfactor: 1.4, durationbase: 6500 }, 14210: { type: "tech 10", lifeform: "kaelesh", metal: 85e3, crystal: 4e4, deut: 35e3, priceFactor: 1.2, bonus1BaseValue: .1, bonus1IncreaseFactor: 1, durationfactor: 1.2, durationbase: 7e3 }, 14211: { type: "tech 11", lifeform: "kaelesh", metal: 12e4, crystal: 3e4, deut: 25e3, priceFactor: 1.5, bonus1BaseValue: .2, bonus1IncreaseFactor: 1, durationfactor: 1.4, durationbase: 7500 }, 14212: { type: "tech 12", lifeform: "kaelesh", metal: 1e5, crystal: 4e4, deut: 3e4, priceFactor: 1.5, bonus1BaseValue: .06, bonus1IncreaseFactor: 1, durationfactor: 1.3, durationbase: 8e3 }, 14213: { type: "tech 13", lifeform: "kaelesh", metal: 2e5, crystal: 1e5, deut: 1e5, priceFactor: 1.5, bonus1BaseValue: .1, bonus1IncreaseFactor: 1, bonus1Max: .99, durationfactor: 1.3, durationbase: 8500 }, 14214: { type: "tech 14", lifeform: "kaelesh", metal: 16e4, crystal: 12e4, deut: 5e4, priceFactor: 1.5, bonus1BaseValue: 1, bonus1IncreaseFactor: 1, durationfactor: 1.4, durationbase: 9e3 }, 14215: { type: "tech 15", lifeform: "kaelesh", metal: 24e4, crystal: 12e4, deut: 12e4, priceFactor: 1.5, bonus1BaseValue: .1, bonus1IncreaseFactor: 1, durationfactor: 1.4, durationbase: 9500 }, 14216: { type: "tech 16", lifeform: "kaelesh", metal: 32e4, crystal: 24e4, deut: 1e5, priceFactor: 1.5, bonus1BaseValue: .3, bonus1IncreaseFactor: 1, durationfactor: 1.4, durationbase: 1e4 }, 14217: { type: "tech 17", lifeform: "kaelesh", metal: 5e5, crystal: 3e5, deut: 2e5, priceFactor: 1.5, bonus1BaseValue: .2, bonus1IncreaseFactor: 1, bonus1Max: .5, bonus2BaseValue: .2, bonus2IncreaseFactor: 1, bonus2Max: .99, durationfactor: 1.3, durationbase: 13e3 }, 14218: { type: "tech 18", lifeform: "kaelesh", metal: 3e5, crystal: 18e4, deut: 12e4, priceFactor: 1.7, bonus1BaseValue: .2, bonus1IncreaseFactor: 1, durationfactor: 1.4, durationbase: 11e3 } }[parseInt(id)]; } } let css = ` :root { --ogl:#FFB800; --primary:linear-gradient(to bottom, #171d23, #101419); --secondary:linear-gradient(192deg, #252e3a, #171c24 70%); --secondaryReversed:linear-gradient(176deg, #252e3a, #171c24 70%); --tertiary:linear-gradient(to bottom, #293746, #212a36 max(5%, 8px), #171c24 max(14%, 20px)); --date:#9c9cd7; --time:#85c1d3; --texthighlight:#6dbbb3; --metal:hsl(229.85deg 48.01% 62.14%); --crystal:hsl(201.27deg 73.83% 75.93%); --deut:hsl(166.15deg 41.73% 62.16%); --metal:hsl(240deg 24% 68%); --crystal:hsl(199deg 72% 74%); --deut:hsl(172deg 45% 46%); --energy:#f5bbb4; --dm:#b58cdb; --food:hsl(316deg 21% 70%); --artefact:#cda126; --population:#ccc; --lifeform:#d569b8; --msu:#c7c7c7; --nothing:#ddd; --resource:#86edfd; --ship:#1dd1a1; --pirate:#ffd60b; --alien:#5ce724; --item:#bf6c4d; --blackhole:#818181; --early:#79a2ff; --late:#df5252; --trader:#ff7d30; --red:#f9392b; --pink:#ff7ba8; --purple:#ba68c8; --indigo:#7e57c2; --blue:#3f51b5; --cyan:#29b6f6; --teal:#06a98b; --green:#4caf50; --lime:#97b327; --yellow:#fbea20; --amber:#ffa000; --orange:#f38b3f; --brown:#5d4037; --grey:#607d8b; --mission1:#ef5f5f; --mission2:#ef5f5f; --mission3:#66cd3d; --mission4:#00c5b2; --mission5:#d97235; --mission6:#e9c74b; --mission7:#5ae8ea; --mission8:#0cc14a; --mission10:#97b0c3; --mission15:#527dcb; --mission18:#7eacb5; --inactive:#b3b3b3; --longInactive:#767676; --banned:#ebb3b3; --vacation:#00ffff; --honorable:#FFFF66; } body[data-colorblind="true"] { --vacation:#8592f5; --honorable:#f9ce27; } .material-icons { direction:ltr; display:inline-block; font-family:'Material Icons' !important; font-weight:normal !important; font-style:normal !important; font-size:inherit !important; image-rendering:pixelated; line-height:inherit !important; letter-spacing:normal; user-select:none; text-transform:none; transform:rotate(0.03deg); white-space:nowrap; word-wrap:normal; -webkit-font-feature-settings:'liga'; font-feature-settings:'liga'; -webkit-font-smoothing:antialiased; } body.ogl_destinationPicker #planetList:before { border:2px solid #fff; bottom:-2px; content:''; left:-2px; pointer-events:none; position:absolute; right:-2px; top:-2px; z-index:2; } line.ogl_line { filter:drop-shadow(0 0 6px #000); marker-end:url(#arrow); marker-start:url(#circle); stroke:#ffffff; stroke-width:2px; } .ui-front:not([aria-describedby="fleetTemplatesEdit"]):not(.errorBox):not(:has(#rocketattack)) { z-index:9999 !important; } .ui-widget-overlay { z-index:9998 !important; } .ogl_unit { white-space:nowrap; } .ogl_suffix { display:inline-block; font-size:smaller; margin-left:2px; } .ogl_text { color:var(--ogl) !important; } .ogl_metal, #resources_metal, .resource.metal, resource-icon.metal .amount { color:var(--metal) !important; } .ogl_crystal, #resources_crystal, .resource.crystal, resource-icon.crystal .amount { color:var(--crystal) !important; } .ogl_deut, #resources_deuterium, .resource.deuterium, resource-icon.deuterium .amount { color:var(--deut) !important; } .ogl_food, #resources_food, .resource.food, resource-icon.food .amount { color:var(--food) !important; } .ogl_dm, #resources_darkmatter, .resource.darkmatter { color:var(--dm) !important; } .ogl_energy, #resources_energy, .resource.energy, resource-icon.energy .amount { color:var(--energy) !important; } .ogl_population, #resources_population, .resource.population, resource-icon.population .amount { color:var(--population) !important; } .ogl_artefact { color:var(--artefact) !important; } [class*="ogl_lifeform"] { color:var(--lifeform) !important; } .ogl_msu { color:var(--msu) !important; } .ogl_mission1, [data-mission-type="1"]:not(.fleetDetails) .detailsFleet { color:var(--mission1) !important; } .ogl_mission2, [data-mission-type="2"]:not(.fleetDetails) .detailsFleet { color:var(--mission2) !important; } .ogl_mission3, [data-mission-type="3"]:not(.fleetDetails) .detailsFleet { color:var(--mission3) !important; } .ogl_mission4, [data-mission-type="4"]:not(.fleetDetails) .detailsFleet { color:var(--mission4) !important; } .ogl_mission5, [data-mission-type="5"]:not(.fleetDetails) .detailsFleet { color:var(--mission5) !important; } .ogl_mission6, [data-mission-type="6"]:not(.fleetDetails) .detailsFleet { color:var(--mission6) !important; } .ogl_mission7, [data-mission-type="7"]:not(.fleetDetails) .detailsFleet { color:var(--mission7) !important; } .ogl_mission8, [data-mission-type="8"]:not(.fleetDetails) .detailsFleet { color:var(--mission8) !important; } .ogl_mission9, [data-mission-type="9"]:not(.fleetDetails) .detailsFleet { color:var(--mission9) !important; } .ogl_mission10, [data-mission-type="10"]:not(.fleetDetails) .detailsFleet { color:var(--mission10) !important; } .ogl_mission11, [data-mission-type="11"]:not(.fleetDetails) .detailsFleet { color:var(--mission11) !important; } .ogl_mission12, [data-mission-type="12"]:not(.fleetDetails) .detailsFleet { color:var(--mission12) !important; } .ogl_mission13, [data-mission-type="13"]:not(.fleetDetails) .detailsFleet { color:var(--mission13) !important; } .ogl_mission14, [data-mission-type="14"]:not(.fleetDetails) .detailsFleet { color:var(--mission14) !important; } .ogl_mission15, [data-mission-type="15"]:not(.fleetDetails) .detailsFleet { color:var(--mission15) !important; } .ogl_mission18, [data-mission-type="18"]:not(.fleetDetails) .detailsFleet { color:var(--mission18) !important; } [data-mission-type] { background: #121b22 !important; } [data-mission-type] .detailsFleet span { filter:brightness(1.5) saturate(.8); } [data-mission-type="1"] { background:linear-gradient(to right, #121b22, #482018, #121b22) !important; } [data-mission-type="2"] { background:linear-gradient(to right, #121b22, #54271f, #121b22) !important; } [data-mission-type="3"] { background:linear-gradient(to right, #121b22, #2c4a14, #121b22) !important; } [data-mission-type="4"] { background:linear-gradient(to right, #121b22, #104841, #121b22) !important; } [data-mission-type="5"] { background:linear-gradient(to right, #121b22, #643d25, #121b22) !important; } [data-mission-type="6"] { background:linear-gradient(to right, #121b22, #4c401f, #121b22) !important; } [data-mission-type="7"] { background:linear-gradient(to right, #121b22, #214350, #121b22) !important; } [data-mission-type="8"] { background:linear-gradient(to right, #121b22, #004011, #121b22) !important; } [data-mission-type="9"] { background:linear-gradient(to right, #121b22, #4a1b14, #121b22) !important; } [data-mission-type="10"] { background:linear-gradient(to right, #121b22, #3f4b54, #121b22) !important; } [data-mission-type="15"] { background:linear-gradient(to right, #121b22, #182542, #121b22) !important; } [data-mission-type="18"] { background:linear-gradient(to right, #121b22, #203642, #121b22) !important; } .ogl_icon, .ogl_metal.ogl_icon, .ogl_crystal.ogl_icon, .ogl_deut.ogl_icon, .ogl_food.ogl_icon, .ogl_dm.ogl_icon, .ogl_energy.ogl_icon, .ogl_artefact.ogl_icon, .ogl_population.ogl_icon, .ogl_icon[class*="ogl_2"], .ogl_icon[class*="ogl_mission"], .ogl_icon[class*="ogl_lifeform"], .ogl_icon.ogl_msu { align-items:center; border-radius:3px; display:flex; padding:3px; white-space:nowrap; } .ogl_metal.ogl_icon:before, .ogl_crystal.ogl_icon:before, .ogl_deut.ogl_icon:before, .ogl_food.ogl_icon:before, .ogl_dm.ogl_icon:before, .ogl_energy.ogl_icon:before, .ogl_artefact.ogl_icon:before, .ogl_icon.ogl_population:before, .ogl_icon.ogl_msu:before { background-image:url(https://gf3.geo.gfsrv.net/cdned/7f14c18b15064d2604c5476f5d10b3.png); background-size:302px; border-radius:3px; content:''; display:inline-block; height:18px; image-rendering:pixelated; margin-right:10px; vertical-align:middle; width:28px; } .ogl_icon.ogl_metal:before { background-position:1% 11%; } .ogl_icon.ogl_crystal:before { background-position:16% 11%; } .ogl_icon.ogl_deut:before { background-position:30% 11%; } .ogl_icon.ogl_dm:before { background-position:57% 11%; } .ogl_icon.ogl_energy:before { background-position:43% 11%; } .ogl_icon.ogl_food:before { background-position:85% 11%; } .ogl_icon.ogl_population:before { background-position:98% 11%; } .ogl_icon.ogl_artefact:before { background-image:url(https://image.board.gameforge.com/uploads/ogame/fr/announcement_ogame_fr_59cb6f773531d4ad73e508c140cd2d3c.png); background-size:28px; } .ogl_miniStats, .ogl_recap, .ogl_stats, .ogl_todoList { .ogl_icon.ogl_metal:before { background-image:url(https://gf2.geo.gfsrv.net/cdn1c/4230ff01e100a38a72dadfa7de0661.png); background-size:28px; image-rendering:auto; } .ogl_icon.ogl_crystal:before { background-image:url(https://gf1.geo.gfsrv.net/cdn65/596ba85baa74145390e04f7428d93e.png); background-size:28px; image-rendering:auto; } .ogl_icon.ogl_deut:before { background-image:url(https://gf1.geo.gfsrv.net/cdnc0/7a7bf2b8edcd74ebafe31dfbae14aa.png); background-size:28px; image-rendering:auto; } .ogl_icon.ogl_dm:before { background-image:url(https://gf2.geo.gfsrv.net/cdna3/4de426cb95e11af9cdabb901dfe802.png); background-size:28px; filter:hue-rotate(40deg) saturate(1); image-rendering:auto; } .ogl_icon.ogl_artefact:before { background-image:url(https://gf1.geo.gfsrv.net/cdn65/596ba85baa74145390e04f7428d93e.png); background-size:28px; filter:hue-rotate(200deg) saturate(4); image-rendering:auto; transform:scaleX(-1); } } .ogl_icon[class*="ogl_2"]:before { background-position:center; border-radius:3px; content:''; display:inline-block; height:18px; image-rendering:pixelated; margin-right:5px; vertical-align:text-bottom; width:28px; } .ogl_icon.ogl_200:before { background:linear-gradient(45deg, #784242, #dd4242); content:'close'; font-family:'Material Icons'; line-height:18px; text-align:center; } .ogl_icon.ogl_202:before { background-image:url(https://gf2.geo.gfsrv.net/cdnd9/60555c3c87b9eb3b5ddf76780b5712.jpg); } .ogl_icon.ogl_203:before { background-image:url(https://gf1.geo.gfsrv.net/cdn34/fdbcc505474e3e108d10a3ed4a19f4.jpg); } .ogl_icon.ogl_204:before { background-image:url(https://gf2.geo.gfsrv.net/cdnd2/9ed5c1b6aea28fa51f84cdb8cb1e7e.jpg); } .ogl_icon.ogl_205:before { background-image:url(https://gf1.geo.gfsrv.net/cdnf1/8266a2cbae5ad630c5fedbdf270f3e.jpg); } .ogl_icon.ogl_206:before { background-image:url(https://gf2.geo.gfsrv.net/cdn45/b7ee4f9d556a0f39dae8d2133e05b7.jpg); } .ogl_icon.ogl_207:before { background-image:url(https://gf1.geo.gfsrv.net/cdn32/3f4a081f4d15662bed33473db53d5b.jpg); } .ogl_icon.ogl_208:before { background-image:url(https://gf1.geo.gfsrv.net/cdn6f/41a21e4253d2231f8937ddef1ba43e.jpg); } .ogl_icon.ogl_209:before { background-image:url(https://gf1.geo.gfsrv.net/cdn07/6246eb3d7fa67414f6b818fa79dd9b.jpg); } .ogl_icon.ogl_210:before { background-image:url(https://gf3.geo.gfsrv.net/cdnb5/347821e80cafc52aec04f27c3a2a4d.jpg); } .ogl_icon.ogl_211:before { background-image:url(https://gf1.geo.gfsrv.net/cdnca/4d55a520aed09d0c43e7b962f33e27.jpg); } .ogl_icon.ogl_213:before { background-image:url(https://gf3.geo.gfsrv.net/cdn2a/c2b9fedc9c93ef22f2739c49fbac52.jpg); } .ogl_icon.ogl_214:before { background-image:url(https://gf3.geo.gfsrv.net/cdn84/155e9e24fc1d34ed4660de8d428f45.jpg); } .ogl_icon.ogl_215:before { background-image:url(https://gf3.geo.gfsrv.net/cdn5a/24f511ec14a71e2d83fd750aa0dee2.jpg); } .ogl_icon.ogl_218:before { background-image:url(https://gf1.geo.gfsrv.net/cdn39/12d016c8bb0d71e053b901560c17cc.jpg); } .ogl_icon.ogl_219:before { background-image:url(https://gf3.geo.gfsrv.net/cdne2/b8d8d18f2baf674acedb7504c7cc83.jpg); } .ogl_icon[class*="ogl_mission"]:before { background-image:url(https://gf2.geo.gfsrv.net/cdn14/f45a18b5e55d2d38e7bdc3151b1fee.jpg); background-position:0 0; background-size:344px !important; border-radius:3px; content:''; display:inline-block; height:18px; margin-right:10px; vertical-align:middle; width:28px; } .ogl_icon.ogl_mission1:before { background-position:80.2% 0 !important; } .ogl_icon.ogl_mission2:before { background-position:99.7% 0 !important; } .ogl_icon.ogl_mission3:before { background-position:50% 0 !important; } .ogl_icon.ogl_mission4:before { background-position:30% 0 !important; } .ogl_icon.ogl_mission5:before { background-position:69.5% 0 !important; } .ogl_icon.ogl_mission6:before { background-position:59.75% 0 !important; } .ogl_icon.ogl_mission7:before { background-position:20.75% 0 !important; } .ogl_icon.ogl_mission8:before { background-position:40.1% 0 !important; } .ogl_icon.ogl_mission9:before { background-position:89% 0 !important; } .ogl_icon.ogl_mission15:before { background-position:0.2% 0 !important; } .ogl_icon.ogl_mission18:before { background:url(https://gf2.geo.gfsrv.net/cdna8/1fc8d15445e97c10c7b6881bccabb2.gif); background-size:18px !important; } .ogl_lifeform0.ogl_icon:before { content:'-'; } .ogl_lifeform1.ogl_icon:before, .ogl_lifeform2.ogl_icon:before, .ogl_lifeform3.ogl_icon:before, .ogl_lifeform4.ogl_icon:before { background-image:url(https://gf2.geo.gfsrv.net/cdna5/5681003b4f1fcb30edc5d0e62382a2.png); background-size:245px; content:''; display:inline-block; height:24px; image-rendering:pixelated; vertical-align:middle; width:24px; } .ogl_icon.ogl_lifeform0:before { background-position:1% 11%; } .ogl_icon.ogl_lifeform1:before { background-position:0% 86%; } .ogl_icon.ogl_lifeform2:before { background-position:11% 86%; } .ogl_icon.ogl_lifeform3:before { background-position:22% 86%; } .ogl_icon.ogl_lifeform4:before { background-position:33% 86%; } .ogl_icon.ogl_msu:before { align-items:center; background:none; color:#fff; content:'MSU'; display:flex; font-size:11px; justify-content:center; } .ogl_gridIcon .ogl_icon { display:grid; grid-gap:7px; justify-content:center; padding-top:6px; text-align:center; } .ogl_gridIcon .ogl_icon:before { margin:auto; } .ogl_header { color:#6F9FC8; font-size:11px; font-weight:700; height:27px; line-height:27px; position:relative; text-align:center; } .ogl_header .material-icons { font-size:17px !important; line-height:28px !important; } .ogl_button, a.ogl_button { background:linear-gradient(to bottom, #405064, #2D3743 2px, #181E25); border:1px solid #17191c; border-radius:3px; color:#b7c1c9 !important; cursor:pointer; display:inline-block; line-height:26px !important; padding:0 4px; text-align:center; text-decoration:none; text-shadow:1px 1px #000; user-select:none; } .ogl_button:hover { color:var(--ogl) !important; } .ogl_invisible { visibility:hidden; } .ogl_hidden { display:none !important; } .ogl_reversed { transform:scaleX(-1); } .ogl_textCenter { justify-content:center; text-align:center; } .ogl_textRight { justify-content:end; text-align:right; } .ogl_disabled { color:rgba(255,255,255,.2); opacity:.5; pointer-events:none; user-select:none; } .ogl_interactive { cursor:pointer; } .ogl_noTouch { pointer-events:none !important; } .ogl_slidingText { display:inline-flex !important; grid-gap:20px; overflow:hidden; position:relative; width:100%; white-space:nowrap; } .ogl_slidingText:before, .ogl_slidingText:after { animation:textSlideLeft 6s infinite linear; content:attr(data-text); } @keyframes textSlideLeft { 0% { transform:translateX(20px); } 100% { transform:translateX(-100%); } } [data-status="pending"] { pointer-events:none; color:orange !important; } [data-status="done"] { color:green !important; } time { color:var(--time); } time span { color:var(--date); } .menubutton.ogl_active .textlabel { color:#75ffcc !important; } #productionboxBottom time { font-size:11px; margin-top:10px; text-align:center; } [data-output-time], [data-output-date] { color:transparent !important; display:inline-grid !important; grid-template-columns:auto 6px auto; overflow:hidden; position:relative; user-select:none; white-space:nowrap; } [data-output-time]:not([data-output-date]) { grid-template-columns:0 auto; } [data-output-time] span, [data-output-date] span { display:none; } [data-output-date]:before { color:var(--date); content:attr(data-output-date); } [data-output-time]:after { color:var(--time); content:attr(data-output-time); } [data-output-time="Invalid Date"] { display:none !important; } .honorRank.rank_0, .honorRank.rank_undefined { display:none; } [data-galaxy] { color:#c3c3c3; cursor:pointer; } [data-galaxy]:hover { color:#fff; text-decoration:underline; } [data-galaxy].ogl_active { color:#c3c3c3; box-shadow:inset 0 0 0 2px rgba(255, 165, 0, .2); } .galaxyCell.cellPlayerName.ogl_active { box-shadow:inset 0 0 0 2px rgba(255, 165, 0, .2); } .ogl_tooltip { border-radius:4px; box-sizing:border-box; font-size:11px; left:0; opacity:0; padding:10px; pointer-events:none; position:absolute; top:0; z-index:1000002; } .ogl_tooltip:not(:has(.ogl_close)) { pointer-events:none !important; } .ogl_tooltip:before { border-radius:inherit; bottom:10px; box-shadow:0 0 15px 5px rgb(0,0,0,.6), 0 0 4px 1px rgba(0,0,0,.7); content:''; left:10px; position:absolute; right:10px; top:10px; } .ogl_tooltip .ogl_tooltipTriangle { background:#171c24; box-shadow:0 0 15px 5px rgb(0,0,0,.6), 0 0 4px 1px rgba(0,0,0,.7); height:15px; pointer-events:none; position:absolute; width:15px; } .ogl_tooltip[data-direction="top"] .ogl_tooltipTriangle { transform:translate(50%, -50%) rotate(45deg); } .ogl_tooltip[data-direction="bottom"] .ogl_tooltipTriangle { background:#293746; transform:translate(50%, 50%) rotate(45deg); } .ogl_tooltip[data-direction="left"] .ogl_tooltipTriangle { transform:translate(-50%, 50%) rotate(45deg); } .ogl_tooltip[data-direction="right"] .ogl_tooltipTriangle { transform:translate(50%, 50%) rotate(45deg); } .ogl_tooltip .ogl_close { align-items:center; background:#7c3434; border-radius:4px; box-shadow:0 0 8px rgb(0,0,0,.6); color:#fff; cursor:pointer; display:flex !important; font-size:16px !important; justify-content:center; height:22px; position:absolute; right:0; top:0; width:22px; z-index:1000004; } .ogl_tooltip .ogl_close:hover { background:#9f3d3d; } .ogl_tooltip.ogl_active { animation-fill-mode:forwards !important; } .ogl_tooltip[data-direction="top"].ogl_active { animation:appearTop .1s; } @keyframes appearTop { from { opacity:0; margin-top:20px; } to { opacity:1; margin-top:0; } 99% { pointer-events:none; } 100% { pointer-events:all; } } .ogl_tooltip[data-direction="bottom"].ogl_active { animation:appearBottom .1s; } @keyframes appearBottom { from { opacity:0; margin-top:-20px; } to { opacity:1; margin-top:0; } 99% { pointer-events:none; } 100% { pointer-events:all; } } .ogl_tooltip[data-direction="left"].ogl_active { animation:appearLeft .1s; } @keyframes appearLeft { from { opacity:0; margin-left:20px; } to { opacity:1; margin-left:0; } 99% { pointer-events:none; } 100% { pointer-events:all; } } .ogl_tooltip[data-direction="right"].ogl_active { animation:appearRight .1s; } @keyframes appearRight { from { opacity:0; margin-left:-20px; } to { opacity:1; margin-left:0; } 99% { pointer-events:none; } 100% { pointer-events:all; } } .ogl_tooltip hr, .ogl_notification hr { background:#1e252e; border:none; grid-column:1 / -1; height:2px; width:100%; } .ogl_tooltip > div:not(.ogl_tooltipTriangle):not(.ogl_close) { background:var(--tertiary); border-radius:inherit; display:block !important; line-height:1.25; max-height:90vh; max-width:400px; overflow-x:hidden; overflow-y:auto; padding:16px 20px; position:relative; z-index:1000003; } .ogl_tooltip .ogl_colorpicker { display:grid !important; grid-auto-flow:column; grid-gap:3px; grid-template-rows:repeat(5, 1fr); } [class*="tooltip"] { user-select:none !important; } [class*="tooltip"] input { box-sizing:border-box; max-width:100%; } .ogl_colorpicker > div { border-radius:50%; box-sizing:border-box; cursor:pointer; height:24px; width:24px; } .ogl_planetIcon, .ogl_moonIcon, .ogl_flagIcon, .ogl_searchIcon, .ogl_pinIcon, .ogl_fleetIcon { display:inline-block !important; font-style:normal !important; text-align:center !important; vertical-align:text-top !important; } .ogl_planetIcon:before, .ogl_moonIcon:before, .ogl_flagIcon:before, .ogl_searchIcon:before, .ogl_pinIcon:before, .ogl_fleetIcon:before { font-family:'Material Icons'; font-size:20px !important; } .ogl_planetIcon:before { content:'language'; } .ogl_moonIcon:before { content:'brightness_2'; } .ogl_flagIcon:before { content:'flag'; } .ogl_pinIcon:before { content:'push_pin'; } .ogl_searchIcon:before { content:'search'; } .ogl_fleetIcon:before { content:'send'; } #bar { line-height:17px !important; grid-gap:20px !important; } #bar li { list-style:none !important; } #fleet1 .content { padding-bottom:30px !important; padding-top:16px !important; } #fleet1 .ogl_shipFlag { background:linear-gradient(180deg, #0d1014 30%, transparent); box-sizing:border-box; display:flex; grid-gap:4px; justify-content:space-evenly; padding:0 10px; position:absolute; right:0; text-align:center; top:0; width:100%; } #fleet1 .ogl_shipFlag > * { color:#b1c2cb; display:block; font-size:14px !important; line-height:16px !important; position:relative; text-shadow:1px 2px #000; top:-4px; width:20px; } #fleet1 .ogl_shipFlag > *:hover { color:#fff; } #fleet1 .ogl_fav:not(.ogl_grayed) { color:var(--yellow); } #fleet1 .ogl_shipLock:not(.ogl_grayed) { color:var(--red); } #fleet1 .ogl_shipLock { font-size:12px !important; } #fleet1 .ogl_reverse { font-size:12px !important; } #fleet1 progress { appearance:none; border:0; bottom:-5px; display:block; height:5px; left:5px; position:absolute; width:655px; z-index:10; } #fleet1 progress, #fleet1 progress::-webkit-progress-bar { background:var(--capacity); } #fleet1 .capacityProgress { position:relative; } #fleet1 .capacityProgress::before { background:#0c1014; border-radius:0 0 5px 5px; content:attr(data-rawCargo); display:inline-block; font-size:11px; left:3px; padding:6px 0; position:absolute; text-align:center; top:5px; width:658px; } #fleet1 .capacityProgress::after { content:attr(data-percentResources)'%'; display:block; font-size:10px; left:var(--currentCapacityPercent); position:absolute; text-shadow:2px 2px 1px #000; top:-14px; transform:translateX(5px); transition:left 0.5s; } #fleet1 progress::-webkit-progress-value { background:rgba(255,255,255,.1); backdrop-filter:brightness(1.8); box-shadow:5px 0 10px #000; transition:width 0.5s; } #fleet1 progress::-moz-progress-bar { background:rgba(255,255,255,.1); backdrop-filter:brightness(1.8); box-shadow:5px 0 10px #000; transition:width 0.5s; } .ogl_requiredShips { align-items:center; display:grid; justify-content:center; user-select:none; width:80px; } #warning .ogl_requiredShips { display:flex; grid-gap:28px; width: 100%; } .ogl_requiredShips .ogl_notEnough { color:var(--red); filter:none; } .ogl_required { background:linear-gradient(145deg, black, transparent); border-radius:3px; font-size:10px; overflow:hidden; padding:0 !important; white-space:nowrap; } .ogl_required:before { vertical-align:middle !important; } .ogl_required:hover { box-shadow:0 0 0 2px var(--ogl); } .ogl_maxShip { background:#3c1a1a; border-radius:0; bottom:19px; box-sizing:border-box; color:var(--red); cursor:pointer; font-size:10px; height:14px; left:2px; line-height:14px; padding:0 5px; position:absolute; right:2px; text-align:right; user-select:none; } .ogl_maxShip:hover { box-shadow:0 0 0 2px var(--ogl); } .resourceIcon .ogl_maxShip { bottom:0; } .ogl_limiterLabel { align-items:center; background:var(--secondary); border-radius:3px; cursor:pointer; display:inline-flex; grid-gap:5px; height:28px; padding:0 9px; user-select:none; } .ogl_limiterGroup { align-items:center; background:var(--secondary); border-radius:3px; display:inline-flex; height:28px; margin-left:auto; padding:0 9px; user-select:none; } .ogl_limiterGroup > i { margin:0 5px; } .ogl_limiterGroup .ogl_icon:first-child { margin-left:5px; } .ogl_limiterGroup .ogl_icon:before { margin-right:0; } .ogl_limiterGroup .ogl_icon:hover { cursor:pointer; } .ogl_limiterGroup .ogl_icon:hover:before { box-shadow:0 0 0 2px var(--ogl); } .ogl_limiterGroup .ogl_icon.ogl_active:before { box-shadow:0 0 0 2px #fff; } .ogl_limiterGroup:has(.ogl_active:not(.ogl_200)) { box-shadow:0 0 0 2px var(--red); } #fleet2 #fleetBriefingPart1 li { margin-bottom:1px !important; } #fleet2[data-selected-mission="4"] .ogl_return { opacity:.6; } #fleet2 #buttonz .header { display:none !important; } #fleet2 #buttonz .footer, #fleet2 .c-left, #fleet2 .c-right { display:none !important; } #fleet2 #buttonz .content { padding:2px 0 !important; margin:0 !important; } #fleet2 #resources.lifeforms-enabled { height:216px !important; } #fleet2 #buttonz div.move-box { top:-1px !important; right:7px !important; } #fleet2 #buttonz ul#missions { height:auto !important; } #fleet2 #buttonz ul li span { height:12px !important; min-width:122px !important; } #fleet2 #mission { margin:auto !important; } #fleet2 div#mission .percentageBarWrapper { margin-top:10px; } #fleet1 .ajax_loading_indicator, #fleet2 .ajax_loading_indicator { transform:scale(.5); } #speedPercentage { float:none !important; margin:auto !important; } .percentageBar .steps .step:not(.selected) { line-height:20px !important; } #speedPercentage .bar { pointer-events:none; } .technology input[type="number"], .technology input[type="text"] { background:#98b2bf !important; border:none !important; border-radius:2px !important; bottom:-20px !important; box-shadow:none !important; height:20px !important; } .ogl_notEnough { filter:sepia(1) hue-rotate(300deg); } .technology.ogl_notEnough { filter:none; } .technology.ogl_notEnough .icon { filter:grayscale(1) brightness(0.5); } .technology.ogl_notEnough input { background:#525556 !important; cursor:not-allowed !important; } .technology input.ogl_flashNotEnough { background:#cf7e7e !important; } .technology:hover { z-index:2; } .technology .icon { border-radius:0 !important; box-shadow:0 0 0 1px #000 !important; position:relative; } .technology[data-status="active"] .icon { box-shadow:0 0 5px 2px var(--ogl); } .technology .icon:hover, .technology.showsDetails .icon { border:2px solid var(--ogl) !important; } .technology .icon .upgrade { border-radius:0 !important; box-shadow:0 0 6px 0px rgba(0,0,0,.8) !important; } .technology .icon .upgrade:after { border-color:transparent transparent currentColor transparent !important; } .technology .icon .level, .technology .icon .amount { background:var(--primary) !important; border-radius:0 !important; } #technologydetails h3, #technologydetails .level, #technologydetails .amount { color:var(--ogl) !important; } #fleetdispatchcomponent #allornone { left:5px !important; padding:0 !important; width:654px !important; } #fleetdispatchcomponent .allornonewrap { align-items:center; background:none !important; border:none !important; box-sizing:border-box; display:flex; padding:24px 9px 15px 9px !important; width:100% !important; } #fleetdispatchcomponent .allornonewrap > div:not(.clearfloat) { margin-right:10px !important; } #fleet1 .allornonewrap .firstcol { display:grid; grid-gap:5px !important; justify-content:space-between !important; width:auto !important; } #fleetdispatchcomponent #continueToFleet2 { margin-left:auto; } #fleetdispatchcomponent #allornone .info { display:none; } #fleetdispatchcomponent #buttonz #battleships { width:408px !important; } #fleetdispatchcomponent #buttonz #civilships { width:254px !important; } #fleetdispatchcomponent #buttonz #battleships ul, #fleetdispatchcomponent #buttonz #civilships ul { padding:0 !important; } #fleetdispatchcomponent #buttonz #battleships ul { margin-left:8px !important; } #fleetdispatchcomponent #buttonz #battleships .header, #fleetdispatchcomponent #buttonz #civilships .header { display:none !important; } #fleetdispatchcomponent #buttonz #battleships .header { border-radius:0 3px 3px 0; border-right:1px solid #000; } #fleetdispatchcomponent #buttonz #civilships .header { border-radius:3px 0 0 3px; border-left:1px solid #000; } #fleetdispatchcomponent .resourceIcon { cursor:default; position:relative; } #fleetdispatchcomponent .ogl_keepRecap { background:#4c1b1b; box-sizing:border-box; bottom:0; color:#f45757; font-size:10px; padding-right:5px; position:absolute; text-align:right; width:100%; } #fleetdispatchcomponent fieldset, #jumpgate fieldset { background:#0c1014; border-radius:3px; box-sizing:border-box; color:#fff; display:flex; grid-gap:10px; margin:10px 5px 5px 5px; padding:12px; width:656px; } #jumpgate fieldset { width:625px; } #fleetdispatchcomponent fieldset legend, #jumpgate fieldset legend { color:#6f9fc8; } #fleetdispatchcomponent .resourceIcon { box-shadow:inset -8px 7px 10px rgba(0,0,0,.5); } #allornone .secondcol { align-items:center; background:none !important; border:none !important; display:inline-flex !important; grid-gap:6px; padding:5px !important; width:auto !important; } #allornone .secondcol .ogl_icon:hover, #allornone .secondcol .material-icons:hover { color:#ccc !important; filter:brightness(1.2); } #allornone .secondcol .clearfloat { display:none !important; } #allornone .secondcol .ogl_icon:not(.ogl_icon .ogl_icon):before { box-shadow:inset 0 0 1px 1px #000; height:31px; width:31px; } #allornone .secondcol .ogl_icon:before { margin:0; } #allornone .secondcol .ogl_icon .ogl_icon:before { border-radius:10px 10px 10px 0; box-shadow:0 0 0 2px #345eb4, 0 0 2px 4px rgba(0,0,0,.7); width:18px; } #allornone .secondcol .ogl_icon { cursor:pointer; padding:0; position:relative; } #allornone .secondcol .ogl_icon .ogl_icon { position:absolute; right:-4px; top:-5px; transform:scale(.8); } #resetall, #sendall { border-radius:3px; overflow:hidden; transform:scale(.97); } #galaxyLoading:after { background:rgba(0,0,0,.7); border-radius:8px; content:attr(data-currentposition); font-size:13px; font-weight:bold; left:50%; padding:5px; position:absolute; top:50%; transform:translate(-50%, -50%); } #headerbarcomponent { width:1045px !important; } #commandercomponent { transform:translateX(55px); } #bar .OGameClock { grid-gap:0 !important; margin:0 !important; padding-right:10px !important; width:auto !important; } #bar #headerBarLinks { gap:18px !important; } #box, #standalonepage #mainContent { width:100% !important; } #top { background-repeat:no-repeat; } #middle { padding-bottom:80px; } #right { float:left !important; position:relative !important; z-index:2 !important; } #right .ogl_ogameDiv, #planetbarcomponent .ogl_ogameDiv { margin-bottom:20px; } #myPlanets .ogl_header .material-icons, #myWorlds .ogl_header .material-icons { color:#fff; cursor:pointer; position:absolute; right:5px; transform-origin:center; top:2px; z-index:1; } #countColonies { display:none; } #bannerSkyscrapercomponent { margin-left:290px !important; } #planetbarcomponent #rechts { margin-bottom:20px !important; margin-left:5px !important; margin-top:-50px !important; width:176px !important; } #rechts .ogl_ogameDiv:first-child { z-index:100001; } #myPlanets { width:auto !important; } #planetList { background:#15191e !important; padding:0 !important; position:relative; transform:translateX(-8px); user-select:none; width:206px; z-index:2; } #planetList.ogl_notReady .smallplanet:after { background:rgba(0,0,0,.5); border-radius:7px; bottom:0px; content:''; left:0px; pointer-events:none; position:absolute; right:0px; top:0px; z-index:100; } #planetList.ogl_notReady .smallplanet { pointer-events:none !important; } #myPlanets { background:none !important; box-shadow:none !important; } .ogl_available { display:grid; font-size:9px; font-weight:bold; line-height:11px; opacity:1; position:absolute; right:3px; text-align:right; top:4px; width:auto; } .smallplanet .planetlink:hover .ogl_available, .smallplanet .moonlink:hover .ogl_available { opacity:1; } .smallplanet { background:linear-gradient(341deg, transparent 29%, #283748); background:#0e1116; border-radius:0 !important; display:grid; font-size:10px; grid-gap:2px; grid-template-columns:139px 64px; height:41px !important; margin:0 !important; padding:1px; position:relative !important; width:100% !important; } .smallplanet:last-child { border-radius:0 0 4px 4px !important; margin-bottom:0 !important; } @property --round { syntax:'<integer>'; inherits:false; initial-value:-50%; } [data-group]:before { --round:-50%; border:2px solid #fff; border-right:none; content:''; height:calc(100% - 1px); position:absolute; top:0; transform:translate(-100%, round(down, -50%, 1px)); transform:translate(-100%, var(--round)); left:0; width:3px; } [data-group="1"]:before { border-color:#3F51B5; } [data-group="2"]:before { border-color:#2196F3; } [data-group="3"]:before { border-color:#009688; } [data-group="4"]:before { border-color:#43A047; } [data-group="5"]:before { border-color:#7CB342; } [data-group="6"]:before { border-color:#FDD835; } [data-group="7"]:before { border-color:#FB8C00; } [data-group="8"]:before { border-color:#E53935; } [data-group="9"]:before { border-color:#EC407A; } [data-group="10"]:before { border-color:#5E35B1; } [data-group="11"]:before { border-color:#795548; } [data-group="12"]:before { border-color:#607D8B; } .smallplanet .planetlink, .smallplanet .moonlink { border-radius:4px !important; background-position:initial !important; height:43px !important; overflow:hidden !important; position:relative !important; padding:0 !important; position:relative !important; top:0 !important; } .smallplanet .planetlink:hover { background:linear-gradient(207deg, #0d1014, #4869c7); } .smallplanet:last-child .planetlink:hover { border-radius:0 0 0 4px !important; } .smallplanet .moonlink:hover { background:linear-gradient(-207deg, #0d1014, #4869c7); } .smallplanet:last-child .moonlink:hover { border-radius:0 0 4px 0 !important; } .ogl_destinationPicker .smallplanet .planetlink.ogl_currentDestination { background:linear-gradient(207deg, #0d1014, #bb8c22) !important; } .ogl_destinationPicker .smallplanet .moonlink.ogl_currentDestination { background:linear-gradient(-207deg, #0d1014, #bb8c22) !important; } .ogl_destinationPicker .smallplanet .ogl_currentDestination .planetPic, .ogl_destinationPicker .smallplanet .ogl_currentDestination .icon-moon, .ogl_destinationPicker .smallplanet .ogl_currentDestination .ogl_refreshTimer { display:none; } .planetBarSpaceObjectContainer { margin:0 !important; left:0 !important; top:0 !important; } .planetBarSpaceObjectHighlightContainer { width:0 !important; height:0 !important; display:none !important; } .ogl_destinationPicker .smallplanet .ogl_currentDestination:after { color:var(--ogl); content:'sports_score'; font-family:'Material Icons'; font-size:20px; left:6px; position:absolute; top:12px; } .ogl_destinationPicker .smallplanet .moonlink.ogl_currentDestination:after { left:2px; } .smallplanet .ogl_disabled { opacity:1; pointer-events:all; } .ogl_destinationPicker .smallplanet .ogl_disabled { opacity:.5; pointer-events:none; } .smallplanet .planetlink { background:linear-gradient(207deg, #0d1014, #212b34); } .smallplanet .moonlink { background:linear-gradient(-207deg, #0d1014, #212b34); } .smallplanet.hightlightPlanet .planetlink { background:linear-gradient(207deg, #0d1014, #4869c7); } .smallplanet.hightlightMoon .moonlink { background:linear-gradient(-207deg, #0d1014, #4869c7); } .ogl_destinationPicker .smallplanet .planetlink.ogl_disabled { background:linear-gradient(207deg, #0d1014, #c74848) !important; } .ogl_destinationPicker .smallplanet .moonlink.ogl_disabled { background:linear-gradient(-207deg, #0d1014, #c74848) !important; } .smallplanet .planetlink.ogl_attacked, .smallplanet .moonlink.ogl_attacked { box-shadow:inset 0 0 0 2px #c93838 !important; } .smallplanet .moonlink { left:auto !important; } .smallplanet .planet-name, .smallplanet .planet-koords { font-weight:normal !important; left:32px !important; position:absolute !important; max-width:67px !important; overflow:hidden !important; text-overflow:ellipsis !important; } .smallplanet .planet-name { color:hsl(208deg 32% 63%) !important; font-size:10px !important; font-weight:bold !important; top:9px !important; } .smallplanet .planet-koords { bottom:10px !important; color:hsl(208deg 3% 57%) !important; letter-spacing:-0.05em; font-size:11px !important; top:auto !important; } .smallplanet .planetPic { background:#1a2534; box-shadow:0 0 8px #000000 !important; height:22px !important; left:-1px !important; margin:0 !important; position:absolute !important; top:23px !important; transform:scale(1.4); width:22px !important; } .smallplanet .icon-moon { background:#1a2534; box-shadow:0 0 8px #000000 !important; height:16px !important; left:0px !important; margin:0 !important; position:absolute !important; top:27px !important; transform: scale(1.5); width:16px !important; } .ogl_refreshTimer { background:rgba(0,0,0,.8); border-radius:14px; bottom:2px; left:3px; padding:1px; position:absolute; text-align:center; transition:opacity .3s; width:15px; } .moonlink .ogl_refreshTimer { left:1px; } .ogl_alt .ogl_refreshTimer { opacity:0; } .smallplanet .constructionIcon { display:none !important; left:3px !important; top:3px !important; } .smallplanet .constructionIcon.moon { left:143px !important; } .smallplanet .alert { display:none; } .smallplanet .ogl_sideIconBottom, .smallplanet .ogl_sideIconTop, .smallplanet .ogl_sideIconInfo { align-items:center; display:flex; grid-gap:5px; position:absolute; right:-5px; text-shadow:0 0 5px #000; top:2px; transform:translateX(100%); } .smallplanet .ogl_sideIconBottom { bottom:11px; top:auto; } .smallplanet .ogl_sideIconInfo { bottom:2px; top:auto; } .smallplanet .ogl_sideIconBottom > *, .smallplanet .ogl_sideIconTop > *, .smallplanet .ogl_sideIconInfo > *, .ogl_fleetIcon:before { align-items:center; cursor:pointer; display:flex !important; font-size:14px !important; } .smallplanet .ogl_sideIconInfo > * { color:var(--yellow); font-size:10px !important; } .smallplanet .ogl_sideIconBottom .ogl_fleetIcon:before { transform:scaleX(-1); } .smallplanet .ogl_todoIcon { color:#cfcfcf; } .smallplanet .ogl_todoIcon:hover, .smallplanet .ogl_fleetIcon:hover { color:var(--ogl) !important; } .smallplanet .ogl_todoIcon:after, .smallplanet .ogl_fleetIcon:after { content:attr(data-list); font-family:Verdana, Arial, SunSans-Regular, sans-serif; font-size:12px; font-weight:bold; } .msg { background:var(--tertiary) !important; outline:1px solid #000; overflow:hidden; position:relative; } .msg[data-msgType] .msg_status:before { background:none !important; } .msg[data-msgType="expe"] .msg_status { background:var(--mission15) !important; } .msg[data-msgType="discovery"] .msg_status { background:var(--lifeform) !important; } .msg_new { background:linear-gradient(to bottom, #2e525e, #223644 6%, #172834 20%) !important; } .msg_title .ogl_mainIcon { color:var(--ogl) !important; } .msg_title .ogl_ptre { color:#ff942c !important; } .ogl_battle { align-items:center; background:rgba(0, 0, 0, .15); border:2px solid #323d4e; box-shadow:0 0 6px -2px #000; color:#48566c !important; display:flex; flex-wrap:wrap; font-weight:bold; grid-gap:6px; justify-content:center; margin:8px auto; padding:3px 6px; position:relative; text-align:center; text-transform:capitalize; width:fit-content; width:-moz-fit-content; } .ogame-tracker-msg .ogl_battle { display:none !important; } .ogl_battleTooltip { font-size:14px !important; } [data-depletion]:after { color:#eb5656; content:'\\e98b'; font-family:'Material Icons'; font-size:16px; font-weight:normal; } [data-depletion="1"]:after { color:#48566c;content:'\\e930'; } [data-depletion="2"]:after { color:#ebb208;content:'\\e98a';transform: scaleX(-1); } [data-depletion="3"]:after { color:#f58725;content:'\\e92d'; } .ogl_battle[data-resultType][data-size="0"] { border-image:linear-gradient(to bottom right, #ede07c, #744407, #ede07c, #744407) 1 !important; } .ogl_battle[data-resultType][data-size="1"] { border-image:linear-gradient(to bottom right, #d7d7d7, #525252, #d7d7d7, #525252) 1 !important; } [data-size-value] { font-weight:bold; } [data-size-depletion] { color:#eb5656 !important; } [data-size-depletion="1"] { color:#48566c !important; } [data-size-depletion="2"] { color:#ebb208 !important; } [data-size-depletion="3"] { color:#f58725 !important; } [data-size-value="0"] { color:#ede07c !important; } [data-size-value="1"] { color:#dddddd !important; } [data-size-value="2"] { color:#d17755 !important; } [data-resultType]:before { content:''; display:block; font-family:'Material Icons'; font-size:18px; font-weight:normal !important; } [data-resultType="raid"]:before, [data-resultType="battle"]:before { content:'\\ea15'; } [data-resultType="resource"]:before, [data-resultType="darkmatter"]:before { content:'\\e972'; } [data-resultType="artefact"]:before { content:'\\ea23'; } [data-resultType="ship"]:before { content:'\\e961'; } [data-resultType="other"]:before { content:'\\e9d0'; } [data-resultType="nothing"]:before { content:'\\e92b'; } [data-resultType*="lifeform"]:before { content:'\\e96e'; } [data-resultType*="item"]:before { content:'\\e996'; } [data-resultType*="debris"]:before { content:'\\e900'; } [data-resultType*="cargo"]:before { content:'\\e950'; } [data-resultType*="early"]:before { content:'\\ea54'; } [data-resultType*="late"]:before, [data-resultType="duration"]:before { content:'\\ea27'; } [data-resultType*="blackhole"]:before { content:'\\e960'; } [data-resultType*="trader"]:before { content:'\\ea03'; } [data-resultType="alien"]:before { content:'\\ea6b'; } [data-resultType="pirate"]:before { content:'\\ea61'; } [data-resultType="alien"] { color:var(--alien) !important; } [data-resultType="pirate"], [data-resultType="battle"] { color:var(--pirate) !important; } [data-resultType="blackhole"] { color:var(--blackhole) !important; } [data-resultType="trader"] { color:var(--trader) !important; } [data-resultType="item"] { color:var(--item) !important; } [data-resultType="early"] { color:var(--early) !important; } [data-resultType="late"], [data-resultType="duration"] { color:var(--late) !important; } [data-resultType="resource"] { color:var(--resource) !important; } [data-resultType="ship"] { color:var(--ship) !important; } [data-resultType="dm"], [data-resultType="darkmatter"] { color:var(--dm) !important; } [data-resultType="lifeform"]:after, .ogl_notification .ogl_icon[class*="lifeform"]:after { align-self:baseline; color:#fff; content:'XP'; display:block; font-size:smaller; margin-left:3px; } .ogl_battle[data-resultType]:before { color:#48566c !important; } .ogl_battle.ogl_clickable:hover { border:2px solid var(--ogl) !important; cursor:pointer; } .ogl_battle .ogl_icon { align-items:center; background:none; display:flex; line-height:16px; padding:0; } .ogl_battle .ogl_icon:not(:last-child) { margin-right:20px; } .ogl_battle[data-resultType="ship"] .ogl_icon, .ogl_battle[data-resultType="global"] .ogl_icon { color:#98b1cb; display:grid; grid-gap:3px; } .ogl_battle[data-resultType="ship"] .ogl_icon:not(:last-child) { margin-right:7px; } .ogl_battle[data-resultType="global"] .ogl_icon:not(:last-child) { margin-right:0; } .ogl_battle .ogl_icon:before { background-size:400px; border-radius:0; display:block; height:20px; image-rendering:auto; margin:0 5px 0 0; vertical-align:bottom; width:32px; } .ogl_battle[data-resultType="raid"] .ogl_icon { display:grid; } .ogl_battle[data-resultType="raid"] .ogl_icon:before { grid-row:1 / 3; } .ogl_battle[data-resultType="raid"] .ogl_icon > span:last-child { grid-column:2; grid-row:2; } .ogl_battle[data-resultType="ship"] .ogl_icon:before, .ogl_battle[data-resultType="global"] .ogl_icon:before { margin:auto; } .ogl_battle .ogl_icon[class*="ogl_2"]:before { background-size:40px; } .ogl_battle .ogl_icon.ogl_artefact:before { background-position:59% 28%; background-size:50px; } .ogl_battle .ogl_icon.ogl_lifeform1:before { background-position:1px 76%; } .ogl_battle .ogl_icon.ogl_lifeform2:before { background-position:11% 76%; } .ogl_battle .ogl_icon.ogl_lifeform3:before { background-position:22% 76%; } .ogl_battle .ogl_icon.ogl_lifeform4:before { background-position:32% 76%; } .ogl_expeRecap { background:#14181f; font-size:11px; grid-gap:8px; padding:10px 0 6px 0; position:relative; width:auto; } .ogl_expeRecap:before { margin-left:0 !important; } .ogl_expeRecap:after { background:var(--blue); border-radius:50px; box-shadow:0 0 6px -2px #000; color:#fff; content:attr(data-count); font-size:10px; padding:4px 5px; position:absolute; right:-3px; text-transform:lowercase; top:-3px; } #messages .tab_favorites, #messages .tab_inner { background:#030406 !important; background-size:410px; } .ogl_deleted { color:var(--red); opacity:.5; } .ogl_spytable { background:#12161a; border-radius:5px; color:#93b3c9; counter-reset:spy; counter-increment:spy; font-size:11px; padding:5px; user-select:none; } .ogl_spytable:after { content:attr(data-total); display:flex; justify-content:end; padding:5px 0; position:relative; } #fleetsTab .ogl_spytable { margin-bottom:-25px; margin-top:55px; } .ogl_spytable a.ogl_important span { color:#fff !important; } .ogl_spytable hr { background:#1e252e; border:none; grid-column:1 / -1; height:2px; width:100%; } .ogl_spytable .ogl_spyIcon { font-size:16px !important; } .ogl_spytable a:not(.ogl_button):not([class*="status_abbr"]), .ogl_spytable [data-galaxy]:not(.ogl_button) { color:inherit !important; } .ogl_spytable a:hover, .ogl_spytable [data-galaxy]:hover { text-decoration:underline !important; } .ogl_spytable .ogl_spyLine > div:not(.ogl_more), .ogl_spyHeader { align-items:center; border-radius:3px; display:grid; grid-gap:3px; grid-template-columns:22px 34px 30px 24px 96px auto 70px 40px 40px 130px; margin-bottom:2px; } .ogl_spytable .ogl_spyLine:not(:first-child) { counter-increment:spy; } .ogl_spytable .ogl_spyLine > div > span, .ogl_spytable .ogl_spyLine > div > a { align-items:center; background:var(--secondary); border-radius:3px; display:flex; height:24px; overflow:hidden; padding:0 4px; position:relative; text-overflow:ellipsis; white-space:nowrap; } .ogl_spytable .ogl_spyLine > div > a { text-decoration:none; } .ogl_spytable .ogl_spyLine > div > span:nth-child(5), .ogl_spytable > div > span:nth-child(6), .ogl_spytable > div > span:nth-child(7) { justify-content:right; } .ogl_spytable .ogl_spyLine > div > span:first-child:before { content:counter(spy); } .ogl_spytable .msg_action_link { overflow:hidden; padding:0 !important; text-overflow:ellipsis; } .ogl_spytable .ogl_fleetIcon { bottom:-2px; left:1px; pointer-events:none; position:absolute; text-shadow:1px 1px 3px #000; } .ogl_spytable .ogl_spyLine > div > span a { text-decoration:none; } .ogl_spytable .ogl_spyLine a:not(.ogl_button):hover, .ogl_spytable .ogl_spyLine [data-galaxy]:hover { color:#fff !important; cursor:pointer !important; text-decoration:underline !important; } .ogl_spytable .ogl_spyHeader b { background:#12161a; border-radius:3px; color:#3c4f5a; font-size:11px !important; line-height:27px !important; padding-left:4px; } .ogl_spytable .ogl_spyHeader b.material-icons { font-size:14px !important; } .ogl_spytable .ogl_spyHeader b:first-child, .ogl_spytable .ogl_spyHeader b:nth-child(3) { padding-left:0; } .ogl_spytable .ogl_spyHeader b:last-child, .ogl_spytable .ogl_spyHeader span:last-child { background:none; padding:0; } .ogl_spytable .ogl_spyHeader [data-filter].ogl_active { color:var(--amber); } .ogl_spytable [data-title]:not(.ogl_spyIcon):not([class*="status_abbr"]) { color:inherit !important; } .ogl_spytable [data-filter]:after { color:#3c4f5a; content:'\\ea28'; font-family:'Material Icons'; font-size:16px; float:right; } .ogl_spytable .ogl_spyHeader [data-filter]:hover { color:#fff; cursor:pointer; } .ogl_spytable .ogl_actions { background:none !important; border-radius:0 !important; font-size:16px; grid-gap:2px; justify-content:space-between; padding:0 !important; } .ogl_spytable .ogl_type > * { color:#b7c1c9; font-size:16px !important; } .ogl_spytable .ogl_type > *:hover { color:#fff; } .ogl_spytable .ogl_actions .ogl_button { border:none; height:24px !important; line-height:24px !important; padding:0; text-decoration:none !important; width:100%; } .ogl_spytable .ogl_actions > *:not(.material-icons) { font-weight:bold; font-size:12px; } .ogl_spytable .ogl_reportTotal, .ogl_spytable .ogl_actions a:hover { text-decoration:none; } .ogl_spyLine .ogl_more { background:var(--primary); border-radius:3px; margin-bottom:3px; padding:7px; } .ogl_spyLine .ogl_more .ogl_icon { align-items:center; display:flex; } .ogl_spyLine .ogl_more > div { align-items:center; display:grid; grid-gap:5px; grid-template-columns:repeat(auto-fit, minmax(0, 1fr)); margin-bottom:5px; } .ogl_spyLine .ogl_more > div > * { background:var(--secondary); border-radius:3px; line-height:20px; padding:2px; text-decoration:none; } .ogl_spyLine .ogl_more a:hover { color:#fff; } .ogl_trashCounterSpy { display:block !important; font-size:16px !important; line-height:26px !important; min-width:0 !important; padding:0 !important; position:absolute; right:104px; top:48px; width:28px; } .galaxyTable { background:#10151a !important; } #galaxycomponent .systembuttons img { pointer-events:none; } #galaxyContent .ctContentRow .galaxyCell { background:var(--secondary) !important; border-radius:2px !important; } #galaxyContent .cellPlanetName, #galaxyContent .cellPlayerName { justify-content:left !important; padding:0 5px; } #galaxyContent .cellPlanetName span { max-width:62px; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; } #galaxyContent .cellPlayerName { flex-basis:106px !important; } #galaxyContent .cellPlayerName .tooltipRel:hover { text-decoration:underline; } #galaxyContent .cellPlayerName [rel] { display:inline-block !important; line-height:28px; max-width:110px; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; } #galaxyContent .cellPlayerName pre { display:none; } .ogl_ranking { text-decoration:none !important; } #galaxyContent .ogl_ranking { color:#7e95a9; cursor:pointer; } #galaxyContent .ogl_ranking:hover { color:#fff; } #galaxyContent .ogl_ranking a { color:inherit; text-decoration:none; } #galaxyHeader .btn_system_action { max-width:100px; overflow:hidden } #galaxyContent .cellPlayerName [class*="status_abbr"] { margin-right:auto; } #galaxyContent .ownPlayerRow { cursor:pointer; } #galaxyContent .ctContentRow .cellDebris a { line-height:30px; text-decoration:none; text-align:center; white-space:nowrap; } #galaxyContent .ctContentRow .cellDebris.ogl_important a { color:#fff !important; } [class*="filtered_filter_"] { opacity:1 !important; } #galaxyContent .ctContentRow[class*="filtered_filter_"] .galaxyCell:not(.ogl_important) { background:#12181e !important; } #galaxyContent .expeditionDebrisSlotBox { background:var(--primary) !important; } #galaxyContent .expeditionDebrisSlotBox .material-icons { color:#48566c; font-size:20px !important; } #galaxyContent .ctContentRow .galaxyCell.cellDebris.ogl_important, #galaxyContent .ogl_expeditionRow.ogl_important, .ogl_spytable .ogl_important { background:linear-gradient(192deg, #a96510, #6c2c0d 70%) !important; } #galaxyContent .ogl_expeditionRow.ogl_important .material-icons { color:#bb6848; } [class*="filtered_filter_"] > .cellPlanet:not(.ogl_important) .microplanet, [class*="filtered_filter_"] > .cellPlanetName:not(.ogl_important) span:not(.icon), [class*="filtered_filter_"] > .cellMoon:not(.ogl_important) .micromoon, [class*="filtered_filter_"] > .cellPlayerName:not(.ogl_important) span, [class*="filtered_filter_"] > .cellPlayerName:not(.ogl_important) .ogl_ranking, [class*="filtered_filter_"] > .cellAlliance:not(.ogl_important) span, [class*="filtered_filter_"] > .cellAction:not(.ogl_important) a:not(.planetDiscover):not(.planetMoveIcons) { opacity:.2 !important; } .ogl_popup { align-items:center; background:rgba(0,0,0,.85); display:flex; flex-direction:column; height:100%; justify-content:center; left:0; opacity:0; pointer-events:none; position:fixed; top:0; width:100%; z-index:1000001; } .ogl_popup.ogl_active { pointer-events:all; opacity:1; } .ogl_popup .ogl_close, .ogl_popup .ogl_share { color:#556672; cursor:pointer; font-size:18px !important; line-height:30px!important; position:absolute; text-align:center; top:2px; right:0; width:30px; } .ogl_popup .ogl_close:hover, .ogl_popup .ogl_share:hover { color:#fff; } .ogl_popup .ogl_share { font-size:16px !important; top:30px; } .ogl_popup > *:not(.ogl_close):not(.ogl_share) { animation:pop .15s; background:var(--primary); background:#0f1218; border-radius:3px; max-height:80%; max-width:980px; overflow-y:auto; overflow-x:hidden; padding:30px; position:relative; } .ogl_popup h2 { border-bottom:2px solid #161b24; color:#9dbddd; font-size:14px; margin-bottom:16px; padding-bottom:7px; text-align:center; } @keyframes pop { from { opacity:0; transform:translateY(-30px) }; to { opacity:1; transform:translateY(0px) }; } .ogl_keeper { max-width:700px !important; } .ogl_keeper .ogl_limiterLabel { float:left; margin-right:20px; width:100px; } .ogl_keeper .ogl_limiterLabel input { margin-left:auto; } .ogl_keeper hr { background:#1e252e; border:none; grid-column:1 / -1; height:2px; width:100%; } .ogl_resourceLimiter, .ogl_shipLimiter, .ogl_jumpgateLimiter { background:#1b202a; border-radius:3px; display:grid; grid-gap:5px 18px; grid-template-columns:repeat(12, 1fr); padding:12px; } .ogl_shipLimiter, .ogl_jumpgateLimiter { grid-template-columns:repeat(20, 1fr); } .ogl_keeper .ogl_icon { grid-column:span 4; padding:0; } .ogl_keeper .ogl_metal, .ogl_keeper .ogl_crystal, .ogl_keeper .ogl_deut, .ogl_keeper .ogl_food { grid-column:span 3; } .ogl_keeper .ogl_icon:before { margin-right:5px !important; vertical-align:text-bottom; } .ogl_keeper input { background:#121518; border:none; border-bottom:1px solid #242a32; border-radius:3px; border-top:1px solid #080b10; box-sizing:border-box; color:inherit; padding:4px 6px; width:calc(100% - 34px); } .ogl_keeper .ogl_button { background:var(--secondary); border-radius:3px; color:#fff; cursor:pointer; line-height:24px !important; } .ogl_keeper .ogl_button.ogl_active { background:var(--highlight); } .ogl_keeper .ogl_button:last-child { grid-column:-2; } .ogl_keeper .ogl_profileTabs { display:grid; grid-gap:0 5px; grid-template-columns:repeat(5, 1fr); grid-column:1 / -1; } .ogl_keeper input.ogl_title { grid-column:1 / -1; padding:8px; text-align:center; width:100%; } .ogl_keeper h2 { grid-column:1 / -1; } .ogl_keeper h2:not(:nth-child(2)) { margin:20px 0 10px 0; } .ogl_keeper .ogl_missionPicker { display:grid; grid-column:1 / -1; grid-gap:4px; grid-template-columns:repeat(11, auto); justify-content:end; margin-top:10px; } .ogl_keeper .ogl_missionPicker [data-mission] { filter:grayscale(1); } .ogl_keeper .ogl_missionPicker [data-mission]:hover { cursor:pointer; filter:grayscale(.5); } .ogl_keeper .ogl_missionPicker .ogl_active { box-shadow:none !important; filter:grayscale(0) !important; } .ogl_empire { color:#6a7d95; display:grid; font-size:11px; font-weight:bold; grid-gap:3px 8px; grid-template-columns:90px 24px 24px 100px 100px 60px 24px 130px 130px 130px; } .ogl_empire .ogl_icon { background:none !important; justify-content:center; padding:0; } .ogl_empire .material-icons { font-size:18px !important; line-height:30px !important; } .ogl_empire img { box-sizing:border-box; height:24px; padding:3px; } .ogl_empire > *:not(.ogl_close):not(.ogl_share):not(a) { background:var(--secondary); border-radius:3px; line-height:24px; position:relative; text-align:center; } .ogl_empire > [class*="ogl_lifeform"]:before { border-radius:3px; image-rendering:pixelated; } .ogl_empire strong { float:left; font-size:14px; padding-left:10px; } .ogl_empire strong span { color:#ff982d !important; font-size:10px; margin-left:2px; } .ogl_empire small { color:#ccc; float:right; font-size:10px; opacity:.6; padding-right:10px; } .ogl_empire .ogl_icon:before { margin:0; } .ogl_empire img:hover { filter:brightness(1.5); } .ogl_side { background:var(--primary); box-shadow:0 0 50px #000; box-sizing:border-box; height:100%; overflow:auto; padding:40px 18px 18px 18px; position:fixed; right:0; top:0; transform:translateX(100%); transition:transform .3s; width:385px; z-index:1000000; } .ogl_side.ogl_active { box-shadow:0 0 50px #000; transform:translateX(0%); } .ogl_side .ogl_close, .ogl_side .ogl_back { color:#556672; cursor:pointer; font-size:28px !important; position:absolute; top:10px; right:20px; } .ogl_side .ogl_close:hover, .ogl_side .ogl_back:hover { color:#fff; } .ogl_side .ogl_back { left:20px; right:auto; } .ogl_side hr { background:#151e28; border:none; grid-column:1 / -1; height:2px; width:100%; } .ogl_side h2 { align-items:center; color:#7e8dab; display:flex; font-size:14px; justify-content:center; margin-bottom:20px; } .ogl_side h2 .ogl_flagPicker { height:17px; margin-left:5px; } .ogl_side h2 i { margin-left:10px; } .ogl_topbar { border-bottom:2px solid #0e1116; color:#546a89; display:grid; font-size:16px; grid-template-columns:repeat(7, 1fr); text-align:center; user-select:none; width:205px; } .ogl_topbar > *:nth-child(1):hover { color:#dbc453 !important; } .ogl_topbar > *:nth-child(2):hover { color:#4bbbd5 !important; } .ogl_topbar > *:nth-child(3):hover { color:#e17171 !important; } .ogl_topbar > *:nth-child(4):hover { color:#76d19a !important; } .ogl_topbar > *:nth-child(5):hover { color:#a1aac9 !important; } .ogl_topbar > *:nth-child(6):hover { color:#fd7db8 !important; } .ogl_topbar > *:nth-child(7):hover { color:#ffffff !important; } .ogl_topbar > *:not(.ogl_button) { cursor:pointer; color:inherit !important; display:block; line-height:30px !important; text-decoration:none; } .ogl_topbar > *:hover { text-shadow:1px 1px 2px #000; } .ogl_topbar .ogl_disabled { color:#898989 !important; opacity:.8 !important; } .ogl_topbar .ogl_active { animation:spinAlt infinite 1s; } @keyframes spin { 0% { transform:rotate(0); } 100% { transform:rotate(-360deg); } } .ogl_topbar button { border:none; grid-column:1 / -1; line-height:26px !important; margin:0; max-height:0; opacity:0; pointer-events:none; transition:max-height .3s cubic-bezier(0, 1, 0, 1); } .ogl_initHarvest .ogl_topbar button { boder:1px solid #17191c; display:block; margin:5px; max-height:30px; opacity:1; pointer-events:all; transition:max-height .1s ease-in-out; } .ogl_config { display:grid; grid-gap:8px; line-height:26px; } .ogl_config label { align-items:center; background:linear-gradient(-207deg, #0d1014, #212b34); border-radius:3px; color:#c7c7c7; display:flex; margin:2px 0px; padding:0; } .ogl_config label:before { content:attr(data-label); display:block; } .ogl_config label.tooltipLeft:before { text-decoration:underline dotted; } .ogl_config label > *:nth-child(1) { margin-left:auto; } .ogl_config label > input[type="text"], .ogl_config label > input[type="password"], .ogl_config label > select { background:#121518; border:none; border-bottom:1px solid #242a32; border-radius:3px; border-top:1px solid #080b10; box-shadow:none; box-sizing:border-box; color:#5d738d; font-size:12px; height:22px; visibility:visible !important; width:105px; } .ogl_config label > input[type="checkbox"], .ogl_todoList input[type="checkbox"], .ogl_limiterLabel input[type="checkbox"] { align-items:center; appearance:none; background:#121518; border:none; border-bottom:1px solid #242a32; border-radius:2px; border-top:1px solid #080b10; color:var(--ogl); cursor:pointer; display:flex; height:16px; justify-content:center; width:16px; } .ogl_config label > input[type="checkbox"]:hover, .ogl_todoList input[type="checkbox"]:hover, .ogl_limiterLabel input[type="checkbox"]:hover { box-shadow:0 0 0 2px var(--ogl); } .ogl_config label > input[type="checkbox"]:checked:before, .ogl_todoList input[type="checkbox"]:checked:before, .ogl_limiterLabel input[type="checkbox"]:checked:before { content:'\\e936'; font-family:'Material Icons'; font-size:18px !important; pointer-events:none; } .ogl_config .ogl_icon[class*="ogl_2"], .ogl_config .ogl_icon[class*="ogl_mission"] { cursor:pointer; padding:0; } .ogl_config .ogl_icon[class*="ogl_2"]:not(:first-child), .ogl_config .ogl_icon[class*="ogl_mission"]:not(:first-child) { margin-left:5px; } .ogl_config .ogl_icon[class*="ogl_2"]:hover:before, .ogl_config .ogl_icon[class*="ogl_mission"]:hover:before { box-shadow:0 0 0 2px var(--ogl); } .ogl_config .ogl_icon[class*="ogl_2"].ogl_active:before, .ogl_config .ogl_icon[class*="ogl_mission"].ogl_active:before { box-shadow:0 0 0 2px #fff; } .ogl_config .ogl_icon[class*="ogl_2"]:before, .ogl_config .ogl_icon[class*="ogl_mission"]:before { margin:0; vertical-align:middle; } .ogl_config .ogl_icon[class*="ogl_mission"]:before { background-size:318px !important; background-position-y:-6px !important; } .ogl_config [data-container] { background:#0e1116; border-radius:3px; max-height:24px; overflow:hidden; padding:5px; transition:max-height .3s cubic-bezier(0, 1, 0, 1); } .ogl_config [data-container].ogl_active { max-height:400px; transition:max-height .3s ease-in-out; } .ogl_config [data-container] > * { padding:0 7px; } .ogl_config h3 { align-items:center; border-radius:3px; color:#90aed5; cursor:pointer; display:flex; font-size:12px; margin-bottom:5px; overflow:hidden; position:relative; text-align:left; text-transform:capitalize; user-select:none; } .ogl_config [data-container] h3:hover { box-shadow:inset 0 0 0 2px var(--ogl); color:var(--ogl); } .ogl_config > div h3:before, .ogl_config svg { color:inherit; fill:currentColor; font-family:'Material Icons'; font-size:16px; height:26px; margin-right:5px; } .ogl_config [data-container="fleet"] h3:before { content:'\\e961'; } .ogl_config [data-container="general"] h3:before { content:'\\e9e8'; } .ogl_config [data-container="interface"] h3:before { content:'\\e95d'; } .ogl_config [data-container="expeditions"] h3:before { content:'\\ea41'; } .ogl_config [data-container="stats"] h3:before { content:'\\ea3e'; } .ogl_config [data-container="messages"] h3:before { content:'\\e9be'; } .ogl_config [data-container="PTRE"] h3:before { content:'\\ea1e'; } .ogl_config [data-container="data"] h3:before { content:'\\ea3f'; } .ogl_config h3:after { content:'\\e9b5'; font-family:'Material Icons'; margin-left:auto; } .ogl_config label button { background:linear-gradient(to bottom, #405064, #2D3743 2px, #181E25); border:1px solid #17191c; border-radius:3px; color:#b7c1c9; cursor:pointer; font-size:16px !important; height:22px !important; line-height:18px !important; position:relative; text-shadow:1px 1px #000; width:30px; } .ogl_config label button:hover { color:var(--ogl); } .ogl_config label .ogl_choice { background:linear-gradient(to bottom, #405064, #2D3743 2px, #181E25); border-bottom:1px solid #17191c; border-top:1px solid #17191c; color:#b7c1c9; cursor:pointer; font-size:11px !important; font-weight:bold; height:20px !important; line-height:20px !important; position:relative; text-align:center; width:30px; } .ogl_config label .ogl_choice:first-child { border-radius:3px 0 0 3px; } .ogl_config label .ogl_choice:last-child { border-radius:0 3px 3px 0; } .ogl_config label .ogl_choice.ogl_active { border-radius:3px; box-shadow:0 0 0 2px #fff; z-index:2; } .ogl_config label .ogl_choice:hover { color:var(--ogl); } .ogl_keyboardActions { display:grid; grid-gap:5px 20px; grid-template-columns:repeat(2, 1fr); } .ogl_keyboardActions h2 { grid-column:1 / -1; } .ogl_keyboardActions label { background:var(--secondary); align-items:center; display:grid; grid-gap:15px; grid-template-columns:auto 100px; padding-left:10px; } .ogl_keyboardActions label:hover { color:var(--amber); cursor:pointer; } .ogl_keyboardActions label hr { appearance:none; border:none; height:1px; margin:0; padding:0; } .ogl_keyboardActions input { background:#fff !important; border:none !important; border-radius:0 !important; box-shadow:none !important; color:#000 !important; font-size:14px !important; font-weight:bold !important; height:21px !important; line-height:21px !important; padding:4px !important; text-align:center !important; text-transform:uppercase !important; } .ogl_keyboardActions input:focus { background:#ffe395 !important; outline:2px solid var(--amber); } .ogl_keyboardActions button { cursor:pointer; grid-column:1 / -1; line-height:30px !important; margin-top:10px; } .ogl_planetList { color:#566c7c; font-size:11px; margin-top:10px; } .ogl_planetList > div { align-items:center; display:grid; grid-gap:3px; grid-template-columns:24px 70px 44px 44px auto; margin-bottom:3px; } .ogl_planetList > div > *:nth-child(2) { text-align:left; text-indent:5px; } .ogl_planetList > div > *:last-child { color:var(--date); font-size:10px; } .ogl_planetList [class*="Icon"] { font-size:10px; } .ogl_planetList [class*="Icon"]:before { font-size:16px; margin-right:5px; vertical-align:bottom; } .ogl_filterColor { display:grid; grid-auto-flow:column; grid-gap:3px; grid-template-rows:repeat(1, 1fr); margin:10px 0; } .ogl_filterColor > * { cursor:pointer; height:18px; border-radius:50%; } .ogl_filterColor > *.ogl_off, label.ogl_off { opacity:.2; } .ogl_filterColor > *:hover, label.ogl_off:hover { opacity:.7; } .ogl_filterStatus { display:grid; grid-auto-flow:column; grid-gap:3px; grid-template-rows:repeat(1, 1fr); justify-content:end; margin:10px 0; } .ogl_filterStatus > * { background:#182b3b; border-radius:4px; cursor:pointer; line-height:24px; text-align:center; width:24px; } .ogl_filterStatus > *.ogl_off { opacity:.2; } .ogl_filterStatus > *:hover { opacity:.7; } .ogl_filterGalaxy, .ogl_filterSystem { color:#a0bacd; display:grid; font-size:11px; grid-gap:3px; grid-template-columns:repeat(10, 1fr); line-height:24px; text-align:center; } .ogl_filterGalaxy > *, .ogl_filterSystem > * { background:#182b3b; border-radius:4px; cursor:pointer; } .ogl_filterGalaxy > *:hover, .ogl_filterSystem > *:hover { color:#fff; text-decoration:underline; } .ogl_filterGalaxy > .ogl_active:not(.ogl_disabled), .ogl_filterSystem > .ogl_active:not(.ogl_disabled) { color:#ccc; filter:brightness(1.4); } .ogl_filterGalaxy { margin-top:30px; } .ogl_filterSystem { margin-top:10px; } .ogl_watchList { display:grid; font-size:11px; grid-gap:3px; padding-top:40px; } .ogl_watchList > div { display:grid; grid-gap:3px; grid-template-columns:24px auto 100px 50px; } .ogl_watchList > div > * { background:#182b3b; border-radius:3px; height:24px; line-height:24px; padding:0 5px; } .ogl_watchList > div > *:nth-child(2):hover { cursor:pointer; text-decoration:underline; } .ogl_targetList { display:grid; font-size:11px; grid-gap:3px; padding-top:30px; } .ogl_targetList .honorRank { margin-right:1px; transform:scale(75%); vertical-align:sub; } .ogl_targetList .ogl_target { color:#566c7c; display:grid; grid-gap:3px; grid-template-columns:76px auto 24px 24px 24px 24px 24px; line-height:24px; position:relative; } .ogl_targetList .ogl_target > * { background:#182b3b; border-radius:3px; height:24px; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; } .ogl_targetList .ogl_target [data-galaxy] { text-indent:17px; } .ogl_targetList .ogl_target [class*="status_abbr_"] { text-indent:3px; } .ogl_targetList .ogl_target > *:first-child { align-self:center; border-radius:50%; display:block; height:7px; left:6px; position:absolute; width:7px; z-index:2; } .ogl_targetList .ogl_target > * { grid-row:1; } .ogl_targetList .ogl_target > [class*="Icon"]:hover { color:#fff; cursor:pointer; } .ogl_ogameDiv { background:linear-gradient(0deg, #0d1014, #1b222a); box-shadow:0 0 20px -5px #000, 0 0 0 1px #17191c; border-radius:0; padding:2px; position:relative; } .ogl_miniStats { border-radius:3px; cursor:pointer; margin-top:10px; width:160px; } .ogl_miniStats:hover:not(:has(.ogl_button:hover)) { box-shadow:0 0 0 2px var(--ogl); } .ogl_miniStats > div { background:var(--secondaryReversed); display:grid; font-size:11px; grid-gap:5px 0; grid-template-columns:repeat(3, 1fr); justify-content:center; padding:3px 2px; } .ogl_miniStats .ogl_header { border-bottom:1px solid #2a3540; height:18px; line-height:18px; padding:5px; user-select:none; } .ogl_miniStats .ogl_header span { display:inline-block; line-height:15px; text-transform:capitalize; } .ogl_miniStats .ogl_header div { color:#fff; cursor:pointer; z-index:1; } .ogl_miniStats .ogl_header div:first-child { left:6px; position:absolute; } .ogl_miniStats .ogl_header div:last-child { right:2px; position:absolute; } .ogl_miniStats .ogl_icon { align-items:center; background:#242c38; display:grid; grid-gap:3px; justify-content:center; margin:0 2px; padding:3px 0; text-align:center; } .ogl_miniStats .ogl_icon > span { } .ogl_miniStats .ogl_icon:before { margin:auto; height:20px; } .ogl_miniStats .ogl_artefact:before { background-size:23px; } .ogl_stats { display:grid; } .ogl_stats h3 { color:#97a7c5; font-size:11px; font-weight:bold; grid-column:1 / -1; margin-top:20px; text-align:center; } .ogl_statsMonth { align-items:center; display:flex; grid-gap:5px; } .ogl_statsMonth > * { padding:0 10px; } .ogl_statsMonth .ogl_button:not(.material-icons) { text-transform:uppercase; } .ogl_dateBar { background:#181d26; border-radius:5px; display:flex; margin:20px 0; padding:4px; user-select:none; } .ogl_dateBar .ogl_item { align-items:end; box-sizing:border-box; cursor:ew-resize; display:grid; grid-template-rows:50px 16px; flex:1; justify-content:center; padding:12px 2px 5px 2px; position:relative; } .ogl_dateBar .ogl_item:after { content:attr(data-day); display:block; opacity:.3; pointer-events:none; text-align:center; } .ogl_dateBar .ogl_item.ogl_active:after { opacity:1; } .ogl_dateBar .ogl_item > div { border-radius:4px; cursor:pointer; font-size:10px; font-weight:bold; height:100%; pointer-events:none; width:20px; } .ogl_dateBar .ogl_selected { background:#524728; border-bottom:2px solid var(--ogl); border-top:2px solid var(--ogl); padding-bottom:3px; padding-top:10px; } .ogl_dateBar .ogl_selected:not(.ogl_selected + .ogl_selected) { border-left:2px solid var(--ogl); border-bottom-left-radius:5px; border-top-left-radius:5px; padding-left:0; } .ogl_dateBar .ogl_selected:has(+ :not(.ogl_selected)), .ogl_dateBar .ogl_item.ogl_selected:last-child { border-right:2px solid var(--ogl); border-bottom-right-radius:5px; border-top-right-radius:5px; padding-right:0; } .ogl_dateBar > .ogl_item:hover { background:#524728; } .ogl_popup.ogl_active .ogl_dateBar .ogl_active { color:#fff !important; pointer-events:all; } .ogl_statsDetails { align-items:end; display:grid; grid-gap:20px; grid-template-columns:430px 430px; } .ogl_statsDetails h3 { color:var(--ogl); } .ogl_pie { align-items:center; background:var(--secondary); border-radius:5px; display:flex; grid-gap:20px; height:182px; justify-content:center; padding:0 20px; position:relative; } .ogl_pie:before { align-items:center; content:attr(data-pie); color:#fff; display:grid; font-size:12px; height:100%; justify-content:center; left:0; line-height:18px; pointer-events:none; position:absolute; text-align:center; text-shadow:1px 1px 5px #000; top:0; width:200px; white-space:pre; z-index:3; } .ogl_noExpe { display:grid; grid-gap:10px; } .ogl_pie span.material-icons { color:#313e4e; font-size:100px !important; margin:auto; } .ogl_pie canvas { height:160px; width:160px; } .ogl_pie .ogl_pieLegendContainer { align-items:center; border-radius:5px; display:grid; min-height:120px; width:210px; } .ogl_pie .ogl_pieLegend { align-items:center; border-radius:3px; cursor:pointer; display:grid; grid-gap:5px; grid-template-columns:18px auto 54px 41px; white-space:nowrap; } .ogl_pie .ogl_pieLegend:hover, .ogl_pie .ogl_pieLegend.ogl_active { box-shadow:0 0 0 2px #fff; } .ogl_pie .ogl_pieLegend > * { color:#fff; overflow:hidden; text-overflow:ellipsis; } .ogl_pie .ogl_pieLegend > span { justify-self:right; } .ogl_pie .ogl_pieLegend i { font-size:smaller; font-weight:normal; opacity:.6; text-align:right; } .ogl_pie .ogl_pieLegend .ogl_suffix { display:inline; } .ogl_shipTable { display:grid; grid-gap:5px; grid-template-columns:repeat(3, 1fr); height:100%; } .ogl_shipTable > .ogl_icon { background:var(--secondary); box-sizing:border-box; padding-right:10px; } .ogl_shipTable > .ogl_icon:before { height:26px; margin-right:auto; width:38px; } .ogl_sumTable { display:grid; grid-column:1 / -1; grid-gap:3px; margin-top:20px; } .ogl_sumTable > * { align-items:center; display:grid; grid-gap:3px; grid-template-columns:repeat(8, 1fr); line-height:26px; text-align:center; } .ogl_sumTable > *:first-child { font-size:20px !important; } .ogl_sumTable > * > *:not(.ogl_icon) { background:var(--secondary); border-radius:3px; } .ogl_sumTable > * > *:not(.ogl_icon):first-child { text-transform:capitalize; } .ogl_sumTable .ogl_icon:before { margin:auto; } .ogl_recap { border-top:2px solid #0e1116; cursor:pointer; padding:10px 6px; position:relative; user-select:none; } .ogl_recap:hover { box-shadow:0 0 0 2px var(--ogl); } .ogl_recap > div { font-size:11px; font-weight:bold; } .ogl_recap .ogl_icon { background:none; display:grid; grid-template-columns:26px auto 70px; text-align:right; } .ogl_recap .ogl_icon > *:last-child { font-size:10px; letter-spacing:-0.03em; opacity:.5; } .ogl_recap .ogl_icon:before { height:14px; vertical-align:bottom; } .ogl_shortCutWrapper { box-sizing:border-box; display:flex; flex-direction:column; justify-content:center; pointer-events:none; position:fixed; text-transform:uppercase; z-index:10; top:0; height:calc(100vh - 25px); left:0; width:100vw; } .ogl_shortCutWrapper > div:nth-child(1) { flex:1; } .ogl_shortcuts { display:flex; grid-gap:7px; flex-wrap:wrap; justify-content:center; } #planetbarcomponent #rechts .ogl_shortcuts { justify-content:left; transform:translateX(-8px); width:206px; } #planetbarcomponent #rechts .ogl_shortcuts .ogl_separator { display:none; } .ogl_shortcuts * { z-index:1; } .ogl_shortcuts [data-key] { align-items:center; box-shadow:0 0 5px rgba(0,0,0,.6); display:inline-flex; font-size:11px; grid-gap:2px; justify-content:space-evenly; line-height:26px; overflow:hidden; pointer-events:all; position:relative; text-transform:uppercase; width:40px; } #planetbarcomponent #rechts .ogl_shortcuts [data-key] { width:36px; } .ogl_shortcuts [data-key-id]:after { font-family:'Material Icons'; font-size:16px !important; order:-1; } .ogl_shortcuts [data-key-id="menu"]:after { content:'\\e91d'; } .ogl_shortcuts [data-key-id="showMenuResources"]:after { content:'\\e95d'; } .ogl_shortcuts [data-key-id="previousPlanet"]:after { content:'\\ea39'; } .ogl_shortcuts [data-key-id="nextPlanet"]:after { content:'\\ea2a'; } .ogl_shortcuts [data-key-id="expeditionSC"]:after { color:var(--mission15);content:'\\ea41'; } .ogl_shortcuts [data-key-id="expeditionLC"]:after { color:var(--mission15);content:'\\ea41'; } .ogl_shortcuts [data-key-id="expeditionPF"]:after { color:var(--mission15);content:'\\ea41'; } .ogl_shortcuts [data-key-id="fleetRepeat"]:after { content:'\\e91a'; } .ogl_shortcuts [data-key-id="fleetSelectAll"]:after { color:#ffab43;content:'\\ea31'; } .ogl_shortcuts [data-key-id="fleetReverseAll"]:after { content:'\\ea0c'; } .ogl_shortcuts [data-key-id="backFirstFleet"]:after { content:'\\e94f'; } .ogl_shortcuts [data-key-id="backLastFleet"]:after { content:'\\e94f'; } .ogl_shortcuts [data-key-id="galaxyUp"]:after { color:#30ba44;content:'\\e946'; } .ogl_shortcuts [data-key-id="galaxyDown"]:after { color:#30ba44;content:'\\e947'; } .ogl_shortcuts [data-key-id="galaxyLeft"]:after { color:#30ba44;content:'\\e942'; } .ogl_shortcuts [data-key-id="galaxyRight"]:after { color:#30ba44;content:'\\e940'; } .ogl_shortcuts [data-key-id="galaxyReload"]:after { content:'\\e919'; } .ogl_shortcuts [data-key-id="discovery"]:after { color:var(--lifeform);content:'\\ea46'; } .ogl_shortcuts [data-key-id="galaxySpySystem"]:after { color:var(--mission6);content:'\\e9ca'; } .ogl_shortcuts [data-key-id="nextPinnedPosition"]:after { content:'\\e9d1'; } .ogl_shortcuts [data-key-id="fleetQuickCollect"]:after { content:'\\e950'; } .ogl_shortcuts .ogl_separator, fieldset .ogl_separator, .ogl_statsMonth .ogl_separator, .ogl_expeRecap .ogl_separator { align-self:center; background:#2e3840; border-radius:50%; height:1px; padding:2px; width:1px; } .ogl_shorcuts .ogl_button { box-shadow:0 1px 3px 0 #000, 0 1px 1px 0 #405064; } #technologydetails .build-it_wrap { transform:scale(.75); transform-origin:bottom right; } #technologydetails .premium_info { font-size:14px; } #technologydetails .information > ul { bottom:8px !important; display:flex !important; flex-flow:row !important; grid-gap:3px !important; left:1px !important; position:absolute !important; top:auto !important; width:auto !important; } #technologydetails .information > ul li { background:var(--secondary); border-radius:3px; margin-bottom:0 !important; padding:5px; } #technologydetails .build_duration, #technologydetails .additional_energy_consumption, #technologydetails .energy_production, #technologydetails .possible_build_start, #technologydetails .required_population, #technologydetails .research_laboratory_levels_sum { align-items:center; display:flex; } #technologydetails .build_duration strong, #technologydetails .additional_energy_consumption strong, #technologydetails .energy_production strong, #technologydetails .possible_build_start strong, #technologydetails .required_population strong, #technologydetails .research_laboratory_levels_sum strong { display:inline-flex; font-size:0; } #technologydetails .build_duration strong:before, #technologydetails .additional_energy_consumption strong:before, #technologydetails .energy_production strong:before, #technologydetails .possible_build_start strong:before, #technologydetails .required_population strong:before, #technologydetails .research_laboratory_levels_sum strong:before { display:block; font-family:'Material Icons'; font-size:16px; margin-right:3px; } #technologydetails .build_duration strong:before { color:var(--time);content:'\\ea27'; } #technologydetails .possible_build_start strong:before { color:#ccc;content:'\\ea03'; } #technologydetails .additional_energy_consumption strong:before, #technologydetails .energy_production strong:before { color:var(--energy);content:'\\ea51'; } #technologydetails .required_population strong:before { color:var(--lifeform);content:'\\ea46'; } #technologydetails .research_laboratory_levels_sum strong:before { color:#21d19f;content:'\\ea17'; } #technologydetails .required_population span { display:inline-flex;font-size:0; } #technologydetails .required_population span:before { content:attr(data-formatted);font-size:11px; } #technologydetails .energy_production .bonus { color:#fff; } #technologydetails .build_amount { top:35px; } #technologydetails .build_amount label { display:none; } #technologydetails .build_amount .maximum { background:none !important; margin:0 0 0 5px !important; min-width:0 !important; padding:0 !important; } #technologydetails .build_amount .maximum:before { display:none !important; } #technologydetails_wrapper.ogl_active { display:block !important; } #technologydetails_wrapper.ogl_active #technologydetails_content { display:block !important; position:initial !important; } #technologydetails_content { background:#0d1014 !important; } #technologydetails > .description { background:var(--primary); } #technologydetails .costs { left:5px !important; top:33px !important; } #technologydetails .costs .ipiHintable { display:none !important; } #technologydetails .costs .ogl_costsWrapper { display:grid; font-weight:bold; grid-gap:3px; } #technologydetails .costs .ogl_costsWrapper div:first-child .material-icons { color:inherit !important; } #technologydetails .costs .ogl_costsWrapper .ogl_icon { align-items:center; display:grid !important; grid-gap:8px; grid-template-columns:28px 70px 70px 70px; padding:0; text-align:center; } #technologydetails .costs .ogl_costsWrapper .ogl_icon:before { margin:0; } #technologydetails .costs .ogl_costsWrapper .ogl_icon > div { background:var(--secondary); border-radius:3px; color:inherit; line-height:18px !important; } #technologydetails .resource.icon { border-radius:5px !important; flex:1 1 0; font-size:12px !important; height:auto !important; padding:2px !important; margin:0 !important; white-space:nowrap !important; width:auto !important; } #technologydetails .resource.icon .ogl_text, #technologydetails .resource.icon .ogl_danger { font-size:10px; } #technologydetails .ogl_actions { display:grid; grid-gap:5px; grid-template-columns:repeat(4, 1fr); line-height:28px; padding:5px; } #technologydetails .ogl_actions .ogl_button { font-size:18px !important; } #technologydetails .ogl_actions .ogl_button.ogl_active { box-shadow:0 0 0 2px var(--amber); color:var(--amber) !important; } #technologydetails .information .material-icons { color:#fff; font-size:16px !important; vertical-align:bottom; } #technologydetails .information .costs > p { display:none; } #technologydetails .information b { font-size:16px; } .tippy-box .ogl_settingsTooltip ul { list-style:square inside; } .tippy-box .ogl_settingsTooltip b { color:var(--ogl); font-weight:bold; } .tippy-box .ogl_fleetDetail, .ogl_ptreContent .ogl_fleetDetail { display:grid !important; font-size:11px; grid-gap:4px 10px; grid-template-columns:repeat(2, 1fr); } .ogl_ptreContent .ogl_fleetDetail { grid-template-columns:repeat(3, 1fr); padding:15px 0; } .ogl_fleetDetail > div { background:var(--secondary); border-radius:3px; line-height:20px; min-width:70px; padding:0px 5px 0px 0px !important; text-align:right; white-space:nowrap; } .ogl_fleetDetail .ogl_metal, .ogl_fleetDetail .ogl_crystal, .ogl_fleetDetail .ogl_deut, .ogl_fleetDetail .ogl_food { grid-column:1 / -1; } .ogl_fleetDetail .ogl_icon { color:#7c95ab; font-weight:bold; } .ogl_fleetDetail .ogl_icon:before { float:left; margin-right:auto; } .ogl_fleetDetail .ogl_button { color:#fff; line-height:22px; text-align:center; user-select:none; } .ogl_fullgrid { grid-column:1 / -1; } .tippy-box .ogl_fleetDetail .ogl_fullgrid { display:grid; grid-gap:7px; grid-template-columns:repeat(2, 1fr); } .tippy-box .ogl_fleetDetail .ogl_button span { pointer-events:none; } .tippy-box .ogl_fleetDetail .ogl_button { border:1px solid #17191c; display:flex; font-size:12px !important; grid-gap:5px; grid-template-columns:16px auto; padding:2px 12px; text-align:left; } .tippy-box .ogl_fleetDetail .ogl_button .material-icons { font-size:16px !important; } #fleetboxmission .content { min-height:0 !important; } #fleet2 #missionNameWrapper, #fleet2 ul#missions span.textlabel { display:none !important; } .ogl_todoList { align-items:center; display:grid; grid-gap:30px; grid-template-columns:auto auto; } .ogl_todoList .ogl_tech { background:#0b0f12; border-bottom:1px solid #1c2630; border-radius:3px; display:grid; margin-bottom:10px; padding:7px; } .ogl_todoList h2 { grid-column:1 / -1; } .ogl_todoList h3 { align-items:center; border-radius:3px; color:#5d6f81; cursor:pointer; display:flex; font-size:12px; line-height:18px; overflow:hidden; position:relative; text-align:left; text-transform:capitalize; } .ogl_todoList h3:after { content:'\\e933'; font-family:'Material Icons'; margin-left:auto; } .ogl_todoList h3:hover { color:#fff; } .ogl_todoList h3:not(:first-child) { margin-top:20px; } .ogl_todoList h3 b { color:var(--ogl); } .ogl_todoList hr { background:#1e252e; border:none; grid-column:1 / -1; height:2px; width:100%; } .ogl_todoList .ogl_line { display:grid; grid-gap:8px; grid-template-columns:70px 114px 114px 114px 50px auto auto; transition:max-height .3s cubic-bezier(0, 1, 0, 1); } .ogl_todoList div > .ogl_line:not(:first-child) { max-height:0; overflow:hidden; } .ogl_todoList .ogl_tech.ogl_active .ogl_line { max-height:28px; transition:max-height .1s ease-in-out; } .ogl_todoList footer { border-top:2px solid #181f24; margin-top:3px; } .ogl_todoList .ogl_line > * { align-items:center; background:var(--secondary); border-radius:3px; color:#849ab9; display:flex; margin-top:3px; padding-right:7px; text-align:right; } .ogl_todoList .ogl_line > *:first-child { justify-content:center; line-height:24px; padding-right:0; } .ogl_todoList .ogl_line .material-icons, .ogl_todoList .ogl_actions .material-icons { font-size:20px !important; } .ogl_todoList .ogl_line .material-icons:hover { color:var(--ogl) !important; } .ogl_todoList .ogl_line label { text-align:left; } .ogl_todoList .ogl_line label:after { content:attr(data-order); } .ogl_todoList .ogl_line .ogl_icon:before { float:left; } .ogl_todoList .ogl_line .ogl_textCenter { padding:0; } .ogl_todoList .ogl_actions { align-self:baseline; display:grid; grid-gap:7px; position:sticky; top:0; } .ogl_todoList .ogl_button { align-items:center; display:flex; grid-gap:5px; padding:0 10px; } .ogl_todoList .ogl_button .material-icons { margin-left:auto; } .ogl_removeTodo, .ogl_blockRecap > *:last-child { color:#ff4f4f !important; } .ogl_todoList .ogl_line button:hover { box-shadow:inset 0 0 0 2px var(--ogl); cursor:pointer; } .originFleet * { color:inherit !important; } .ogl_playerData .ogl_actions { display:flex; grid-gap:2px; margin-bottom:10px; } .ogl_playerData .ogl_actions .ogl_button { border:1px solid #17191c; border-radius:5px; font-size:16px !important; width:100%; } .ogl_playerData .ogl_grid { display:grid; grid-gap:12px; grid-template-columns:repeat(2, 1fr); } .ogl_playerData .ogl_tagSelector { grid-column:1 / -1; } .ogl_playerData .ogl_leftSide { background:#101418; border-radius:5px; font-size:12px; padding:7px; } .ogl_playerData h1 { background:var(--primary); border:2px solid #202834; border-radius:50px; font-size:14px; margin:0 auto 14px auto; padding:3px 12px; text-align:center; width:fit-content; width:-moz-fit-content; } .ogl_playerData h1:before { background:red; content:''; height:2px; } .ogl_playerData h1 a { font-size:12px; text-decoration:none; } .ogl_playerData h1 a:hover { color:var(--ogl); } .ogl_score { display:grid; grid-gap:3px; } .ogl_score .material-icons { font-size:16px !important; line-height:20px !important; } .ogl_score .ogl_line { background:var(--secondary); border-radius:5px; display:grid; grid-gap:3px; grid-template-columns:20px auto; padding:1px 5px; } .ogl_score .ogl_line div { line-height:20px; text-align:right; } .ogl_score .ogl_line:nth-child(1) { color:#f9c846; } .ogl_score .ogl_line:nth-child(2) { color:#6dd0ff; } .ogl_score .ogl_line:nth-child(3) { color:#21d19f; } .ogl_score .ogl_line:nth-child(4) { color:var(--lifeform); } .ogl_score .ogl_line:nth-child(5) { color:#ff4646; } .ogl_score .ogl_line:nth-child(6) { color:#f96e46; } .ogl_score .ogl_line:nth-child(7) { color:#bfbfbf; } .ogl_playerData .ogl_planetStalk { background:#101418; border-radius:5px; display:flex; flex-direction:column; grid-gap:3px; padding:7px; } .ogl_playerData .ogl_planetStalk > div { display:grid; font-size:12px; grid-gap:3px; grid-template-columns:24px auto 22px 22px 22px; position:relative; } .ogl_playerData .ogl_planetStalk > div:last-child { border:none; } .ogl_playerData .ogl_planetStalk > div > * { align-items:center; background:var(--secondary); border-radius:3px; display:flex; justify-content:center; line-height:22px; padding:0 5px; } .ogl_playerData .ogl_tagPicker { background:none !important; pointer-events:none !important; } .ogl_playerData .ogl_tagPicker:before { content:'fiber_manual_record' !important; } .ogl_playerData .ogl_planetStalk [data-galaxy] { justify-content:left; } .ogl_home [data-galaxy]:before { color:#fff; content:'\\e99d'; display:inline-block; font-family:'Material Icons'; margin-right:5px; text-decoration:none; } .ogl_playerData .ogl_planetStalk .ogl_spyIcon { color:#687a89; font-size:15px !important; } .ogl_playerData .ogl_planetStalk .ogl_spyIcon:hover { color:#fff; } #jumpgate .ship_input_row { position:relative; } #jumpgate .ogl_keepRecap { background:#4c1b1b; border-radius:4px; bottom:0; color:#f45757; font-size:10px; padding:2px 4px; position:absolute; right:0px; } #jumpgate .ship_input_row input { text-align:left; } .eventFleet .tooltip { color:inherit; } .galaxyTable .ogl_flagPicker { margin-left:3px; } .ogl_flagPicker, .ogl_flagSelector { cursor:pointer; font-size:19px !important; min-height:19px; } .ogl_flagSelector > * { align-items:center; display:grid; justify-content:center; } .ogl_tooltip .ogl_flagSelector > * { height:100%; min-height:19px; } .ogl_flagPicker:before, .ogl_flagSelector [data-flag="none"]:before { color:#4e5c68; content:'push_pin'; } .ogl_flagPicker[data-flag="friend"]:before, .ogl_flagSelector [data-flag="friend"]:before { color:#ff78cf; content:'handshake'; } .ogl_flagPicker[data-flag="danger"]:before, .ogl_flagSelector [data-flag="danger"]:before { color:#ff4343; content:'alert'; } .ogl_flagPicker[data-flag="skull"]:before, .ogl_flagSelector [data-flag="skull"]:before { color:#e9e9e9; content:'skull'; } .ogl_flagPicker[data-flag="rush"]:before, .ogl_flagSelector [data-flag="rush"]:before { color:#6cddff; content:'electric_bolt'; } .ogl_flagPicker[data-flag="fridge"]:before, .ogl_flagSelector [data-flag="fridge"]:before { color:#667eff; content:'fridge'; } .ogl_flagPicker[data-flag="star"]:before, .ogl_flagSelector [data-flag="star"]:before { color:#ffd745; content:'star'; } .ogl_flagPicker[data-flag="trade"]:before, .ogl_flagSelector [data-flag="trade"]:before { color:#32db9d; content:'local_gas_station'; } .ogl_flagPicker[data-flag="money"]:before, .ogl_flagSelector [data-flag="money"]:before { color:#ab7b65; content:'euro'; } .ogl_flagPicker[data-flag="ptre"]:before, .ogl_flagSelector [data-flag="ptre"]:before { color:#ff942c; content:'ptre'; } .ogl_flagPicker[data-flag="recent"]:before, .ogl_flagSelector [data-flag="recent"]:before { color:#41576c; content:'schedule'; } .ogl_flagPicker:hover, .ogl_flagSelector [data-flag]:hover, .ogl_tagPicker:hover, .ogl_tagSelector [data-tag]:hover { filter:brightness(1.3); } .ogl_flagSelector [data-flag]:hover:after, .ogl_tagSelector [data-tag]:hover:after { border-left:5px solid transparent; border-right:5px solid transparent; border-top:6px solid #fff; top:-8px; content:''; left:50%; position:absolute; transform:translateX(-50%); } .ogl_tooltip > div.ogl_flagSelector:not(.ogl_tooltipTriangle):not(.ogl_close), .ogl_tooltip > div.ogl_tagSelector:not(.ogl_tooltipTriangle):not(.ogl_close), .tippy-content .ogl_flagSelector, .tippy-content .ogl_tagSelector { align-items:center; display:flex !important; grid-auto-flow:column; grid-gap:4px 10px; justify-content:center; } .ogl_tagPicker, .ogl_tagSelector { cursor:pointer; font-size:19px !important; user-select:none; } .ogl_tagPicker:before, .ogl_tagSelector [data-tag]:before { content:'stroke_full'; } .ogl_tagPicker:before, .ogl_tagSelector [data-tag="none"]:before { color:#4e5c68; } .ogl_tagPicker[data-tag="red"]:before, .ogl_tagSelector [data-tag="red"]:before { color:#eb3b5a; } .ogl_tagPicker[data-tag="orange"]:before, .ogl_tagSelector [data-tag="orange"]:before { color:#fa8231; } .ogl_tagPicker[data-tag="yellow"]:before, .ogl_tagSelector [data-tag="yellow"]:before { color:#f7b731; } .ogl_tagPicker[data-tag="lime"]:before, .ogl_tagSelector [data-tag="lime"]:before { color:#7bbf20; } .ogl_tagPicker[data-tag="green"]:before, .ogl_tagSelector [data-tag="green"]:before { color:#20bf6b; } .ogl_tagPicker[data-tag="blue"]:before, .ogl_tagSelector [data-tag="blue"]:before { color:#5bbde3; } .ogl_tagPicker[data-tag="dblue"]:before, .ogl_tagSelector [data-tag="dblue"]:before { color:#3867d6; } .ogl_tagPicker[data-tag="violet"]:before, .ogl_tagSelector [data-tag="violet"]:before { color:#8854d0; } .ogl_tagPicker[data-tag="magenta"]:before, .ogl_tagSelector [data-tag="magenta"]:before { color:#f95692; } .ogl_tagPicker[data-tag="pink"]:before, .ogl_tagSelector [data-tag="pink"]:before { color:#fda7df; } .ogl_tagPicker[data-tag="brown"]:before, .ogl_tagSelector [data-tag="brown"]:before { color:#996c5c; } .ogl_tagPicker[data-tag="gray"]:before, .ogl_tagSelector [data-tag="gray"]:before { color:#75a1b7; } [data-tag].ogl_off { opacity:.2; } #galaxyContent .ctContentRow .galaxyCell:has([data-tag="red"]) { box-shadow:inset 0 0 100px rgba(255, 0, 0, .2); } #galaxyContent .ctContentRow .galaxyCell:has([data-tag="orange"]) { box-shadow:inset 0 0 100px rgba(235, 108, 59, .3); } #galaxyContent .ctContentRow .galaxyCell:has([data-tag="yellow"]) { box-shadow:inset 0 0 100px rgba(235, 181, 59, .3); } #galaxyContent .ctContentRow .galaxyCell:has([data-tag="lime"]) { box-shadow:inset 0 0 100px rgba(167, 235, 59, .2); } #galaxyContent .ctContentRow .galaxyCell:has([data-tag="green"]) { box-shadow:inset 0 0 100px rgba(59, 235, 89, .3); } #galaxyContent .ctContentRow .galaxyCell:has([data-tag="blue"]) { box-shadow:inset 0 0 100px rgba(59, 162, 235, .3); } #galaxyContent .ctContentRow .galaxyCell:has([data-tag="dblue"]) { box-shadow:inset 0 0 100px rgba(59, 81, 235, .3); } #galaxyContent .ctContentRow .galaxyCell:has([data-tag="violet"]) { box-shadow:inset 0 0 100px rgba(110, 59, 235, .3); } #galaxyContent .ctContentRow .galaxyCell:has([data-tag="magenta"]) { box-shadow:inset 0 0 100px rgba(235, 59, 165, .3); } #galaxyContent .ctContentRow .galaxyCell:has([data-tag="pink"]) { box-shadow:inset 0 0 100px rgba(255, 124, 179, .3); } #galaxyContent .ctContentRow .galaxyCell:has([data-tag="brown"]) { box-shadow:inset 0 0 100px rgba(149, 111, 89, .3); } .galaxyRow:has([data-tag="gray"]) { opacity:.2; } .galaxyTable .ogl_tagPicker, .ogl_spytable .ogl_tagPicker { margin-left:auto; } .galaxyTable { .phalanxlink { margin-left:auto !important; } .phalanxlink + .ogl_tagPicker { margin-left:1px; } } .ogl_list { background:#0e1116; display:grid; grid-gap:3px; padding:10px; } .ogl_list .ogl_emptyList { padding:10px; } .ogl_list > div { align-items:center; border-radius:3px; display:grid; grid-gap:4px; position:relative; } .ogl_list > div > *:not(.ogl_button) { align-items:center; background:var(--secondary); border-radius:3px; display:flex; justify-content:center; line-height:24px !important; padding:0 5px; } .ogl_list > div > .ogl_flagPicker { padding:0; } .ogl_pinned .ogl_list > div { grid-template-columns:auto 70px 30px 30px; } .ogl_pinned .ogl_list > div > *:first-child { justify-content:left; } .ogl_pinned .ogl_list .ogl_grid { display:grid; grid-template-columns:repeat(2, 1fr); } .ogl_pinned .ogl_list .material-icons { cursor:pointer; font-size:17px !important; height:24px !important; user-select:none; text-align:right; } .ogl_pinned .ogl_list .material-icons:hover { filter:brightness(1.3); } .ogl_pinned .ogl_list .material-icons:last-child { color:#915454; } .ogl_pinned .ogl_detail { cursor:pointer; } .ogl_pinned .ogl_detail:hover { color:#fff; } .ogl_pinned .ogl_tabs { display:flex; grid-template-columns:repeat(9, 1fr); justify-content:space-between; text-align:center; } .ogl_pinned .ogl_tabs > [data-flag] { align-items:center; display:grid; justify-content:center; padding:5px 7px 7px 7px; } .ogl_pinned .ogl_tabs .ogl_active { background:#0e1116; border-radius:3px 3px 0 0; } .ogl_pinned span:hover { cursor:pointer; text-decoration:underline; } .ogl_expeditionFiller { display:grid; grid-template-columns:repeat(8, 1fr); } .ogl_expeditionFiller h2 { grid-column:1 / -1; } .ogl_expeditionFiller .ogl_icon:before { height:38px; width:38px; } .ogl_expeditionFiller .ogl_icon:hover:before { cursor:pointer; box-shadow:0 0 0 2px var(--ogl); } .ogl_expeditionFiller .ogl_icon.ogl_active:before { box-shadow:0 0 0 2px #fff; } .ogl_wrapperloading { align-items:center; background:rgba(0,0,0, .7); display:flex; height:100%; justify-content:center; width:100%; } .ogl_loading { animation:spinAlt .75s infinite linear; background:conic-gradient(#ffffff00, var(--ogl)); mask:radial-gradient(#0000 40%, #fff 43%, #fff 0); border-radius:50%; height:25px; width:25px; } @keyframes spinAlt { 0% { transform:rotate(0); } 100% { transform:rotate(360deg); } } .ogl_pinDetail h2 { display:flex; grid-gap:5px; } .ogl_pinDetail h2 .ogl_flagPicker { margin:0; } .ogl_pinDetail .ogl_actions { display:flex; grid-gap:3px; margin-bottom:20px; } .ogl_pinDetail .ogl_actions .ogl_button { align-items:center; display:grid; flex:1; font-size:16px !important; justify-content:center; } .ogl_pinDetail .ogl_score { grid-template-columns:repeat(2, 1fr); margin-bottom:20px; } .ogl_pinDetail .ogl_score > div { padding:4px 5px; } .ogl_pinDetail .ogl_list > div { grid-template-columns:20px auto 60px 38px 38px 67px; } .ogl_pinDetail .ogl_list [data-galaxy] { justify-content:left; } .ogl_pinDetail .ogl_list .ogl_spyIcon { color:#687a89; font-size:16px !important; justify-content:space-between; padding:0 3px; } .ogl_pinDetail .ogl_list .ogl_spyIcon:hover { color:#fff; } .ogl_spyIcon { align-items:center; cursor:pointer !important; display:flex; } .ogl_spyIcon span { font-family:Verdana, Arial, SunSans-Regular, sans-serif; font-size:11px; margin-left:3px; } .ogl_spyIcon.ogl_attacked:before { bottom:-6px; content:'send'; color:var(--red); font-size:18px !important; display:block; pointer-events:none; position:absolute; left:-3px; text-shadow:1px 2px 3px #000; } .ogl_pinDetail date { display:grid; font-size:10px; grid-gap:5px; } .ogl_pinDetail date span:nth-child(1) { color:var(--date); } .ogl_pinDetail date span:nth-child(2) { color:var(--time); } .ogl_nextQuickTarget { color:#687a89; font-size:16px !important; } .ogl_nextQuickTarget.ogl_active { color:var(--red); } .ogl_tagged .ogl_grid { align-items:center; display:flex; grid-gap:5px; justify-content:end; } .ogl_tagged .ogl_grid label { align-items:center; display:flex; } .ogl_tagged .ogl_list > div { grid-template-columns:30px auto 30px 30px 30px 30px; } .ogl_tagged .ogl_list > div > div:first-child { text-align:center; } .ogl_tagged .ogl_list .ogl_spyIcon { color:#687a89; font-size:16px !important; } .ogl_tagged .ogl_list .ogl_spyIcon:hover { color:#fff; } .ogl_tagged .ogl_tabs, .ogl_playerData .ogl_tagSelector { display:flex; grid-gap:12px 6px; margin-bottom:8px; text-align:center; } .ogl_tagged .ogl_tabs > *, .ogl_playerData .ogl_tagSelector > * { flex:1; } .ogl_tagged .ogl_actions { align-items:center; display:grid; grid-gap:0 4px; grid-template-columns:repeat(15, 1fr); } .ogl_tagged .ogl_actions input { background:#121518 !important; border:none !important; border-bottom:1px solid #212830 !important; border-radius:3px !important; border-top:1px solid #080b10 !important; box-shadow:none !important; color:#5d738d !important; font-weight:bold !important; } .ogl_tagged .ogl_actions label { align-items:center; background:linear-gradient(to bottom, #405064, #2D3743 2px, #181E25); border-radius:50px; cursor:pointer; display:flex; justify-content:center; } .ogl_tagged .ogl_actions .material-icons { color:#7d8caa; cursor:default; font-size:16px !important; text-align:center; user-select:none; } .ogl_tagged .ogl_actions input, .ogl_tagged .ogl_actions .ogl_button, .ogl_tagged .ogl_actions label { align-self:flex-start; grid-column:span 2; line-height:24px !important; text-align:center; user-select:none; width:auto; } .ogl_tagged .ogl_actions .ogl_button, .ogl_tagged .ogl_list .ogl_button { cursor:pointer; display:inline-block; grid-template-columns:auto; line-height:26px; padding:0 4px; text-align:center; user-select:none; } .ogl_tagged .ogl_actions .ogl_button:hover, .ogl_tagged .ogl_list .ogl_button:hover { color:#fff; } .ogl_planetTooltip { min-width:150px; } .ogl_planetTooltip [class*='ogl_lifeform'] { background:#000; border:2px solid var(--lifeform); border-radius:50%; box-shadow:0 0 5px 2px #000; position:absolute; right:50%; transform:translate(30px, -10px) scale(.75); } .ogl_planetTooltip [class*='ogl_lifeform']:before { border-radius:50%; } .ogl_planetTooltip h3 span { display:inline; } .ogl_planetTooltip img { border:1px solid #000; border-radius:50%; box-shadow:0 0 10px -3px #000; display:block; margin:0 auto 7px auto; } .ogl_planetTooltip a { display:block; } .ogl_planetTooltip a:hover { color:#fff !important; } .ogl_planetTooltip h3 { text-align:center; } .ogl_planetTooltip .ogl_mineRecap { font-size:14px; font-weight:bold; text-align:center; } #empire #siteFooter .content, #siteFooter .content { width:1045px !important; } .ogl_danger { color:#ff665b !important; } .ogl_warning { color:var(--amber) !important; } .ogl_caution { color:var(--yellow) !important; } .ogl_ok { color:#77ddae !important; } .ogl_ping { color:#aaa; font-size:10px; font-weight:bold; position:absolute; right:-14px; top:14px; } .secondcol .material-icons { background:linear-gradient(to bottom, #2d6778 50%, #254650 50%); border-radius:2px !important; color:#fff; cursor:pointer; font-size:20px !important; height:26px !important; line-height:26px !important; text-align:center !important; text-decoration:none !important; text-shadow: 1px 1px #000 !important; transform:scale(1) !important; width:32px !important; } .secondcol .ogl_quickCollectBtn { background:linear-gradient(to bottom, #5e782d 50%, #255026 50%); } .secondcol #resetall.material-icons { background:linear-gradient(to bottom, #812727 50%, #5c1515 50%); } .secondcol #sendall.material-icons { background:linear-gradient(to bottom, #b76908 50%, #9b4a11 50%); } .ogl_tooltip > div.ogl_resourcesPreselection:not(.ogl_tooltipTriangle):not(.ogl_close) { display:grid !important; grid-gap:5px; } .ogl_tooltip > div.ogl_resourcesPreselection .ogl_icon { padding:0; } .ogl_resourcesPreselection { display:grid !important; grid-gap:5px; } .ogl_resourcesPreselection .ogl_icon { padding:0; } .ogl_resourcesPreselection .ogl_icon:before { color:#ffc800; content:'chevron-double-right'; font-family:'Material Icons'; font-size:20px; line-height:18px; text-align:center; text-shadow:1px 1px 2px #000; } .ogl_resourcesPreselection hr { border:none; height:2px; width:100%; } .ogl_resourcesPreselection .ogl_button { line-height:30px; } [data-spy="prepare"] { color:var(--amber) !important; } [data-spy="done"] { color:var(--teal) !important; } [data-spy="fail"] { color:var(--red) !important; } [data-spy="recent"] { color:var(--purple) !important; } [data-spy]:not(.ogl_spyIcon) { box-shadow:0 0 0 2px currentColor !important; border-radius:2px !important; } .expeditionDebrisSlotBox { align-items:center; border:none !important; box-shadow:none !important; box-sizing:border-box !important; display:flex !important; flex-wrap:wrap !important; padding:4px 16px !important; width:642px !important; } .expeditionDebrisSlotBox.ogl_hidden, #expeditionDebrisSlotDebrisContainer { display:none !important; } .expeditionDebrisSlotBox li { list-style:none; } .expeditionDebrisSlotBox > div { display:flex; grid-gap:20px; line-height:1.4; text-align:left; } .expeditionDebrisSlotBox a { color:var(--green1); } .expeditionDebrisSlotBox a:hover { text-decoration:underline; } .ogl_expeditionRow { border-top:2px solid #1a2129; grid-gap:10px !important; margin-top:5px; padding-top:5px; width:100% !important; } .ogl_expeditionRow.ogl_important { border:none; border-radius:5px; padding:0; } .ogl_expeditionRow > div:not(:last-child) { display:flex; } .ogl_expeditionRow * { white-space:nowrap; } .ogl_expeditionText { line-height:24px; } .ogl_expeditionDebris { display:flex; grid-gap:10px; } .ogl_sideFleetTooltip:not(.ogl_tooltipTriangle):not(.ogl_close) { display:grid !important; font-size:11px; grid-gap:2px; max-width:800px !important; } .ogl_sideFleetIcon { align-items:center; display:grid; grid-gap:5px; grid-template-columns:70px 30px 70px 60px 20px 30px 70px 98px 98px 98px; justify-content:center; } .ogl_sideFleetIcon > *:not(img) { background:var(--secondary); border-radius:3px; } .ogl_sideFleetIcon > *:not(img):not(.ogl_icon) { line-height:24px; padding:0 3px; text-align:center; } .ogl_sideFleetIcon .material-icons { color:#fff; font-size:14px !important; line-height:24px !important; } .ogl_sideFleetIcon > span { color:#fff; } [data-return-flight="true"] { filter:brightness(.7); } #movementcomponent .starStreak .route { color:#aaa; text-align:center; } #movementcomponent .starStreak .route b { color:#fff; font-weight:normal; } .msg gradient-button .custom_btn { border:none !important; } gradient-button img { pointer-events:none !important; } .msg:has(.ogl_checked) message-footer-details { margin-right:48px; } .ogl_messageButton { background:linear-gradient(160deg, rgba(54,77,99,1) 0%, rgba(40,57,72,1) 33%, rgba(20,30,38,1) 66%, rgba(18,26,33,1) 100%) !important; box-shadow:0px 2px 3px 1px rgb(0,0,0,.55); border-radius:5px; color:#9ea5af !important; cursor:pointer; float:left; font-size:20px !important; font-weight:bold; height:28px; line-height:28px !important; text-align:center; width:28px; } .ogl_messageButton:hover { background:linear-gradient(160deg, rgba(67, 107, 145, 1) 0%, rgba(52, 76, 97, 1) 33%, rgba(40, 58, 71, 1) 66%, rgba(20, 26, 32, 1) 100%) !important; box-shadow:0px 0px 0px 0px transparent; } message-footer-actions gradient-button[sq30] { height:26px !important; width:26px !important; } .ogl_messageButton.ogl_ignore.ogl_active { color:#c65757 !important; } .ogl_messageButton.ogl_ignore:before { content:'toggle_off'; font-family:'Material Icons'; font-size:18px !important; } .ogl_messageButton.ogl_ignore.ogl_active:before { content:'toggle_on'; } .ogl_messageButton.ogl_ignore:hover:after { display:inline-block; } .ogl_resourcesDetail { display:grid !important; grid-gap:5px; grid-template-columns:repeat(2, 1fr); max-width:800px; } .ogl_resourcesDetail > div:last-child { grid-column:1 / -1; } .ogl_resourcesDetail > div:not(.ogl_close) { background:var(--secondary); padding:10px 15px; position:relative; text-align:center; } .ogl_resourcesDetail h3, .ogl_resourcesDetail h4 { color:#9ea4af; display:block; } .ogl_resourcesDetail h3 { font-size:24px !important; margin-bottom:4px; text-align:center; } .ogl_resourcesDetail h4 { border-bottom:2px solid #353c46; margin-bottom:6px; padding-bottom:6px; } .ogl_resourcesDetail .ogl_todoDays span:not(.ogl_suffix) { color:#fff; } [data-api-code] { cursor:pointer; } .reversal { overflow:unset !important; } .reversal a[data-key-color]:before { color:transparent; content:'\\e98b'; font-family:'Material Icons'; font-size:11px; line-height:12px; pointer-events:none; position:absolute; right:-4px; text-shadow:-1px 1px 2px rgba(0,0,0,.4); top:-3px; } .reversal a:before { right:-6px; top:0; } .ogl_button[data-key-color="orange"]:after { color:#ff7806; } .ogl_button[data-key-color="violet"]:after { color:#fa59fd; } .ogl_button[data-key-color="blue"]:after { color:var(--mission15); } .ogl_button[data-key-color="cyan"]:after { color:#7bffed; } .reversal a[data-key-color="orange"]:before { color:#ff7806; } .reversal a[data-key-color="violet"]:before { color:#fa59fd; } [data-key-color="undefined"]:before { display:none !important; } .resourceIcon .ogl_reverse { color:#b1c2cb; font-size:14px !important; position:absolute; right:5px; text-shadow:1px 2px #000; top:3px; z-index:10; } .resourceIcon .ogl_reverse:hover { opacity:1; } .resourceIcon .ogl_reverse { right:2px; top:1px; } .ogl_notification { background:#191f26; bottom:5px; box-shadow:0 0 20px 10px rgba(0,0,0,.7); font-weight:bold; max-height:500px; min-width:275px; opacity:0; overflow-y:auto; overflow-x:hidden; padding:14px 14px 11px 14px; pointer-events:none; position:fixed; right:5px; transform:scaleX(0); transform-origin:center right; transition:transform .2s; z-index:1000003; } .ogl_notification.ogl_active { opacity:1; pointer-events:all; transform:scaleX(1); } .ogl_notificationLine { border-bottom:1px solid #2b3a42; display:flex; font-size:11px; grid-gap:7px; line-height:15px; padding:8px 0; max-width:380px; } .ogl_notificationLine:last-child { border:none; } .ogl_notification > div > *:last-child > hr:last-child { display:none; } .ogl_notification progress { appearance:none; height:3px; left:0; position:absolute; top:0; width:100%; } .ogl_notification progress::-webkit-progress-value { appearance:none; background:var(--ogl); transition:width .2s linear; } .ogl_notification progress::-moz-progress-bar { appearance:none; background:var(--amber); transition:width .2s linear; } .ogl_notification .ogl_ok, .ogl_notification .ogl_danger { font-size:12px !important; margin-left:4px; vertical-align:middle; } .ogl_notification h2 { font-size:14px; text-align:center; } .ogl_notification .ogl_grid { display:grid; grid-gap:5px; grid-template-columns:repeat(2, 1fr); max-width:275px; } .ogl_notification .ogl_icon { align-items:center; background:#1f2730; border-radius:3px; display:flex; } .ogl_notification .ogl_icon:before { margin-right:auto; } .ogl_notification .ogl_icon[class*="lifeform"]:before { background-position-y:77%; background-size:335px; height:18px; image-rendering:auto; width:28px; } .ogl_notification .ogl_icon .ogl_suffix { text-indent:0; } .ogl_notification .ogl_notificationTimer { color:var(--date); display:inline-block; font-size:11px; margin-right:5px; opacity:.5; } .ogl_empireJumpgate { font-size:20px !important; margin-top:3px; text-align:center; width:100%; } #eventboxContent .eventFleet, #eventboxContent .allianceAttack { align-items:center; display:grid; grid-gap:2px; grid-template-columns:82px 62px 23px 70px 87px auto 19px 87px 70px 20px 21px 20px; white-space:nowrap; } #eventboxContent .eventFleet > td { align-items:center; box-shadow:0 0 0 2px rgba(0,0,0,.25); box-sizing:border-box; border-radius:3px; display:flex; height:calc(100% - 2px); justify-content:left; overflow:hidden; padding:2px 4px; text-align:center; width:100%; } #eventboxContent .eventFleet { td.arrivalTime, td.coordsOrigin, td.destCoords { justify-content:center; }} #eventboxContent .eventFleet > td:not(.icon_movement):not(.icon_movement_reserve) { padding:2px 2px; } #eventboxContent .eventFleet > td:nth-child(3) { background:none !important; } #eventboxContent .eventFleet > td:nth-child(5) { grid-column:4;grid-row:1; } #eventboxContent .eventFleet > td:nth-child(10) span, #eventboxContent .eventFleet > td:nth-child(11) span, #eventboxContent .eventFleet > td:nth-child(12) span { display:flex !important; } #eventboxContent .eventFleet > td a { text-decoration:none !important; } #eventboxContent .eventFleet > td a:hover { color:var(--ogl) !important; } .eventFleet [data-output-time] { justify-self:flex-start; } .icon_movement, .icon_movement_reserve { background-position:center !important; } .originFleet, .destFleet { align-items:center; display:flex; grid-gap:2px; justify-content:center; } .originFleet .tooltip[data-title]:not(figure), .destFleet .tooltip[data-title]:not(figure) { align-items:center; display:inline-flex !important; font-size:0; grid-gap:1px; } .originFleet .tooltip[data-title]:not(figure):after, .destFleet .tooltip[data-title]:not(figure):after { content:attr(data-title); font-size:11px; overflow:hidden; text-overflow:ellipsis; } .originFleet figure, .destFleet figure { flex-shrink:0; } #technologydetails .ogl_queueShip { display:flex; position:absolute; top:52px; } #technologydetails .ogl_queueShip .ogl_button { border-radius:3px 0 0 3px; width:60px; } #technologydetails .ogl_queueShip input { background:#121518; border:none; border-bottom:1px solid #242a32; border-radius:0 3px 3px 0; border-top:1px solid #080b10; box-shadow:none; box-sizing:border-box; color:#5d738d; padding:0 4px; text-align:left; width:45px; } .fleetDetails { background:linear-gradient(to bottom, #1a1d24, #0e1014 26px) !important; border:none !important; border-radius:0 !important; box-shadow:0 0 20px -5px #000, 0 0 0 1px #000 !important; display:inline-block !important; line-height:18px !important; margin:12px 0 0 6px !important; overflow:unset !important; padding:5px !important; position:relative !important; width:96% !important; } .fleetDetails.detailsOpened { height:auto !important; } .fleetDetails .starStreak, .fleetDetails .nextMission, .fleetDetails .mission, .fleetDetails.detailsClosed .ogl_shipsBlock, .fleetDetails.detailsClosed .ogl_resourcesBlock, .fleetDetails.detailsClosed .fedAttack, .fleetDetails.detailsClosed .sendMail, .fleetDetails .fleetDetailButton, .fleetDetails .marker01, .fleetDetails .marker02 { display:none !important; } .fleetDetails hr { background:#1e252e; border:none; height:2px; } .fleetDetails .openDetails { left:auto !important; position:absolute !important; right:0 !important; top:-2px !important; } .fleetDetails.detailsOpened .timer { height:auto !important; } .ogl_resourcesBlock { box-sizing:border-box; display:grid; font-size:11px; grid-gap:5px; grid-template-columns:repeat(8, 1fr); margin-top:5px; text-wrap:nowrap; width:100%; } .ogl_resourcesBlock .ogl_icon { background:#191d26; margin:0; padding:3px; justify-content:end; } .ogl_resourcesBlock .ogl_icon:before { display:block; margin:0 auto 0 0; } .ogl_shipsBlock { box-sizing:border-box; color:#fff; display:grid; grid-template-columns:repeat(3, 1fr); } .ogl_backTimer { align-items:center; box-shadow:0 0 0 1px #000; box-sizing:border-box; font-size:0; grid-column:-3 / -1; grid-row:1; line-height:14px !important; padding:5px 32px 5px 5px; text-align:right; } .ogl_backTimer:before, .ogl_backTimer:after { font-size:11px; } .ogl_backTimer:hover { box-shadow:0 0 0 2px var(--ogl); color:transparent !important; } .fleetDetails .reversal_time { left:auto !important; pointer-events:none !important; position:absolute !important; right:10px !important; top:31px !important; z-index:2 !important; } .fleetDetails.detailsClosed .reversal_time { pointer-events:all !important; right:0 !important; top:14px !important; } .ogl_timeBlock { align-items:center; border-radius:3px; display:grid; grid-gap:78px; grid-template-columns:repeat(2, 1fr); } .ogl_timeBlockLeft, .ogl_timeBlockRight { border-radius:3px; display:grid; grid-template-columns:70px 70px auto; padding:1px; justify-content:start; } .ogl_timeBlockRight { grid-template-columns:auto 70px 70px; justify-content:end; text-align:right; } .ogl_timeBlock > div > * { left:0 !important; line-height:14px !important; margin:0 !important; padding:0 !important; position:relative !important; text-align:inherit !important; top:0 !important; width:auto !important; } .ogl_timeBlock .tooltip { color:inherit !important; } .ogl_timeBlock .originData, .ogl_timeBlock .destinationData { display:flex; grid-gap:5px; justify-content:center; } .ogl_timeBlock .originPlanet, .ogl_timeBlock .destinationPlanet, .ogl_timeBlock .originCoords, .ogl_timeBlock .destinationCoords { left:0 !important; padding:0 !important; position:relative !important; } .detailsOpened .destinationPlanet, .detailsClosed .destinationPlanet, .detailsOpened .originPlanet { width:auto !important; } .ogl_actionsBlock { align-items:center; background:var(--tertiary); border-radius:3px; box-shadow:0 3px 5px -2px #000; display:grid; grid-gap:5px; grid-template-columns:repeat(2, 1fr); justify-content:center; left:50%; padding:2px; position:absolute; top:-5px; transform:translateX(-50%); z-index:2; } .ogl_actionsBlock * { justify-self:center; left:0 !important; margin:0 !important; padding:0 !important; position:relative !important; top:0 !important; width:18px !important; } .ogl_actionsBlock .ogl_icon[class*="ogl_mission"]:not(.ogl_mission18):before { background-size:212px !important; } .ogl_actionsBlock .ogl_icon[class*="ogl_mission"]:before { margin:0; width:18px; } .fleetDetails .allianceName { bottom:auto !important; left:auto !important; right:3px !important; top:-17px !important; } .ogl_phalanxLastUpdate { background:var(--secondary); border-radius:4px; margin-bottom:10px; padding:5px; text-align:center; } .ogl_phalanxLastUpdate b { color:var(--amber); } .ogl_universeName { color:#aeaac1; font-size:12px; font-weight:bold; line-height:12px; pointer-events:none; position:absolute; text-align:right; top:102px; width:138px; } .ogl_universeInfoTooltip { line-height:1.4; } .ogl_universeInfoTooltip div { color:var(--amber); display:inline-block; float:right; font-size:11px; text-indent:10px; } .ogl_popup .ogl_frameSelector { display:grid; grid-gap:5px; grid-template-columns:repeat(6, 1fr); margin-bottom:10px; } .ogl_popup .ogl_frameSelector .ogl_button { min-width:80px; } .ogl_popup .ogl_frameSelector .ogl_button.ogl_active { box-shadow:0 0 0 2px var(--ogl); } .ogl_ptreContent { display:grid; grid-gap:10px; grid-template-columns:auto auto; } .ogl_ptreContent b { align-items:center; border-bottom:1px solid #1b222b; border-top:1px solid #1b222b; color:#ff4646; display:flex; font-size:12px; justify-content:center; margin-bottom:10px; padding:5px 0; } .ogl_ptreContent b .material-icons { font-size:16px !important; margin-right:5px; } .ogl_ptreContent h3 { font-size:18px; grid-column:1 / -1; padding:8px; text-align:center; } .ogl_ptreContent hr { background:#151e28; border:none; grid-column:1 / -1; height:2px; width:100%; } .ogl_ptreActivityBlock, .ogl_ptreBestReport { background:rgba(0,0,0,.2); border-radius:9px; padding:10px; } .ogl_ptreLegend { color:var(--blue); font-size:10px; margin-top:20px; text-align:left; } .ogl_ptreActivities [data-check] { align-self:center; background:currentColor; border:3px solid currentColor; border-radius:50%; height:0; padding:4px; width:0; } .ogl_ptreActivities [data-check].ogl_active { background:none; } .ogl_ptreActivities > span { color:var(--red); } .ogl_ptreActivities > div { display:grid; grid-gap:5px; grid-template-columns:repeat(12, 1fr); } .ogl_ptreActivities > div > * { align-items:center; background:var(--secondary); border-radius:2px; color:#656f78; display:grid; height:45px; padding:3px; } .ogl_ptreActivities > div > * > * { display:inline-block; margin:auto; } .ogl_ptreActivities .ptreDotStats { height:30px; position:relative; width:30px; } .ogl_ptreContent { text-align:center; } .ogl_ptreBestReport > div:first-child { padding:10px; } .ogl_checked { align-items:center; bottom:5px; color:#4d5e78 !important; display:flex; font-size:20px !important; height:28px; justify-content:center; position:absolute; right:5px; width:24px; } .ogl_log > div:not(.ogl_close):not(.ogl_share) { border-bottom:1px solid #20262c; display:grid; grid-template-columns:100px 100px 300px; margin-top:5px; padding-bottom:5px; } .ogl_log h2 { grid-column:1 / -1; } .ogl_ptreActionIcon { align-items:center; display:inline-flex; justify-content:center; } .ogl_ptreActionIcon i { color:inherit; font-size:12px !important; } .ogl_ptreActionIcon i.ogl_active { animation:blink 1.5s linear infinite; } @keyframes blink { 50% { opacity: 0; } } .ogl_leftMenuIcon { background:linear-gradient(to bottom, #1b2024 50%, #000 50%); border-radius:4px; display:block; height:27px; margin-right:11px; user-select:none; text-align:center; width:27px !important; } .ogl_leftMenuIcon a { align-items:center; color:#353a3c !important; display:flex !important; height:100%; justify-content:center; } .ogl_leftMenuIcon a i { font-size:21px !important; line-height:27px !important; } .ogl_leftMenuIcon a:hover { color:#d39343 !important; } .ogl_resourceBoxStorage { display:none; font-size:10px; left:0; pointer-events:none; position:absolute; top:12px; width:100%; } #resources:hover .ogl_resourceBoxStorage { display:block; } #resources:hover .resource_tile .resourceIcon.metal, #resources:hover .resource_tile .resourceIcon.crystal, #resources:hover .resource_tile .resourceIcon.deuterium { box-shadow:inset 0 0 0 20px rgba(0,0,0, .8); } .ogl_manageData .ogl_grid { display:grid; grid-gap:5px; } .ogl_manageData .ogl_button { align-items:center; display:flex; justify-content:center; padding:3px 9px; } .ogl_manageData .ogl_button .material-icons { margin-left:auto; } .ogl_manageData .ogl_button.ogl_danger { background:linear-gradient(to bottom, #7c4848, #5a3535 2px, #3a1818); color:#b7c1c9 !important; } .ogl_manageData .ogl_button.ogl_danger:hover { color:var(--ogl) !important; } .ogl_manageData hr { background:#151e28; border:none; grid-column:1 / -1; height:2px; width:100%; } .chat_msg .msg_date { position:absolute; } .ogl_acsInfo .value span { margin-left:5px; } .ogl_blackHoleButton { font-size:16px !important; position:absolute; right:-3px; top:0; transform:translateX(100%); width:28px; } .ogl_blackhole .ogl_button { float:right; margin-top:10px; width:70px; } .ogl_buildIconList { bottom:0; display:flex; left:30px; pointer-events:none; position:absolute; } .ogl_buildIcon { color:#73fff2; } .ogl_baseShip { color:#ffcb55; } .ogl_buildIcon.ogl_lfBuilding { color:#e598ff; } .ogl_buildList { margin-top:5px; } .ogl_buildList li { align-items:center; display:flex; } .ogl_buildList li span { display:inline-block; max-width:100px; } .ogl_buildList .material-icons { margin:0 7px; } .ogl_buildList .material-icons:first-child { font-size:8px !important; margin:0 4px 0 0; } .ogl_buildList b { color:var(--amber); font-size:12px; font-weight:bold; } [data-debug] { position:relative; } [data-debug]:after { background:rgba(0,0,0,.7); color:yellow !important; content:attr(data-debug); display:block; left:0; opacity:.8; position:absolute; text-shadow:1px 1px #000; top:12px; width:max-content; } .ogl_datePicker { display:grid !important; grid-gap:10px; grid-template-columns:repeat(3, 1fr); user-select:none; } .ogl_datePicker .ogl_dateItem { align-items:center; display:flex; font-size:14px; justify-content:center; } .ogl_datePicker .material-icons { font-size:16px !important; } #jumpgate #selecttarget select { display:block !important; visibility:visible !important; } #jumpgate #selecttarget .dropdown { display:none !important; } #jumpgate select { font-size:12px !important; padding:2px !important; } .ogl_boardMessageTab { padding-top:7px; padding:7px 8px 0 8px; position:relative; } .ogl_boardMessageTab .newMessagesCount { background-color:#242d37; border:1px solid #40c4c1; border-radius:8px; box-shadow:0 2px 4px rgba(0, 0, 0, 0.75); color:#ffffff; line-height:16px; font-size:9px; height:16px; min-width:16px; padding:0 2px; position:absolute; right:-3px; text-align:center; top:-3px; } .ogl_boardMessageTab.marker { background:url('https://gf1.geo.gfsrv.net/cdn69/112960c1ace80c7dcb03ca88d4b6fc.png') no-repeat; } .ogl_boardMessageTab .tabLabel { margin-top:6px; } .ogl_boardMessageTab .material-icons { align-items:center; background:linear-gradient(to bottom, #d7dfe5 50%, #d4d9dd 50%); background-clip:text; color:transparent; display:flex; font-size:36px !important; height:100%; justify-content:center; margin-bottom:4px; width:100%; } .ogl_boardMessageTab .tabImage { background:linear-gradient(135deg, #375063 33.33%, #23394a 33.33%, #23394a 50%, #375063 50%, #375063 83.33%, #23394a 83.33%, #23394a 100%) !important; background-size:3px 3px !important; border-bottom:1px solid #385365 !important; border-left:2px solid #3c596c !important; border-right:2px solid #3c596c !important; border-top:1px solid #385365 !important; border-radius:7px !important; box-shadow:inset 0 0 10px 6px #1c2831 !important; cursor:pointer !important; height:50px !important; margin-top:1px !important; position:relative !important; text-decoration:none !important; width:48px !important; } .ogl_boardMessageTab .tabImage:hover { filter:brightness(1.2); } .ogl_boardMessageTab .tabImage:before { background:#395467; border-radius:6px; content:''; filter:blur(0.5px); height:calc(50% + 2px); left:0; opacity:.6; position:absolute; right:0; top:-2px; } .ogl_boardMessageTab .tabImage:after { background:#395467; border-radius:7px; bottom:2px; content:''; filter:blur(1px); height:4px; left:3px; opacity:.6; position:absolute; right:3px; } .ogl_boardMessageTab.ui-tabs-active .marker { left:-10px !important; top:-9px !important; } #oglBoardTab * { max-width:100%; } #oglBoardTab .msg { padding:10px; } #oglBoardTab .msg_content { margin-top:10px; padding:0; } #oglBoardTab .msg_title { display:inline-block !important } #oglBoardTab .msg_title:hover { color:#fff; cursor:pointer; text-decoration:underline; } #oglBoardTab .msg_title i { color:var(--pink); } #oglBoardTab .spoilerBox { display:none !important; } .ogl_sidenote { color:#aaa; font-style:italic; } .ogl_shipDataInfo .material-icons { color:#7ca8ad; font-size:18px !important; vertical-align:middle; } .ogl_shipDataInfo b { color:var(--ogl); } .ogl_totalRequired { background:var(--primary); border-radius:3px; margin-top:10px; padding:10px; } .ogl_totalRequired h3 { pointer-events:none; text-align:center; } .ogl_totalRequired h3:after { content:none; } .ogl_totalRequired .ogl_200:before { visibility:hidden; } .ogl_totalRequired .ogl_grid { display:flex; } .ogl_totalRequired .ogl_icon { display:grid; grid-gap:8px; text-align:center; } .ogl_totalRequired .ogl_icon:before { margin:auto; } .shipyardSelection { background:var(--primary); padding:10px; width:auto !important; } .ogl_timeBox { display:block; margin-top:5px; } .ogl_lineBreakFlex { flex-basis:100%; height:0; } #messagecontainercomponent .msgHead { padding:5px 5px 0 8px !important; } .msg .content-box { display:none !important; } .msg:has([data-raw-messagetype="25"]) { box-shadow:inset 3px 0 var(--mission1) !important; } .msg:has([data-raw-messagetype="41"]) { box-shadow:inset 3px 0 var(--mission15) !important; } .msg:has([data-raw-messagetype="61"]) { box-shadow:inset 3px 0 var(--lifeform) !important; } .msg:has([data-raw-messagetype="32"]) { box-shadow:inset 3px 0 var(--mission8) !important; } .msg:has([data-raw-messagetype="34"]):has(.ogl_battle) { box-shadow:inset 3px 0 var(--mission3) !important; } .msg:has([data-raw-messagetype="35"]), .msg:has([data-raw-messagetype="54"]) { .content-box { display:block !important; } } .detail_msg .loot-row { background:#1f252e; border-radius:5px; padding:5px; } .ogl_spytable .fleetAction { right:0 !important; margin-left:0 !important; pointer-events:none !important; } #messagecontainercomponent .msg { margin-bottom:3px !important; } .messagesHolder .msgWithFilter .msgFilteredHeaderRow { border-bottom:1px solid #000; box-shadow:none !important; } .tippy-box { box-shadow:0 0 20px -5px #000, 0 0 5px 2px rgba(0,0,0,.5) !important; } .tippy-content { background:var(--tertiary) !important; border:none !important; border-radius:5px !important; font-size:11px !important; padding:20px !important; } .tippy-content hr, .ogl_notification hr { background:#1e252e; border:none; grid-column:1 / -1; height:2px; width:100%; } .tippy-arrow { color:#171c24 !important; } .tippy-box[data-animation='pop'][data-state='hidden'] { opacity:0; } .tippy-box[data-animation='pop'][data-state='hidden'][data-placement^="left"] { transform:translateX(20px); } .tippy-box[data-animation='pop'][data-state='hidden'][data-placement^="right"] { transform:translateX(-20px); } .tippy-box[data-animation='pop'][data-state='hidden'][data-placement^="bottom"] { transform:translateY(-20px); } .tippy-box[data-animation='pop'][data-state='hidden'][data-placement^="top"] { transform:translateY(20px); } * { .status_abbr_inactive { color:var(--inactive) !important; } .status_abbr_longinactive { color:var(--longInactive) !important; } .status_abbr_banned { color:var(--banned) !important; } .status_abbr_vacation { color:var(--vacation) !important; } .status_abbr_honorableTarget { color:var(--honorable) !important; } } [data-status-tag]:not([data-status-tag='false']):before { content:'('attr(data-status-tag)')'; margin-right:2px; opacity:.75; white-space:nowrap; } .ogl_highlight { color:var(--amber); } .ogl_oldScore { font-weight:normal; } .ogl_oldScore em { border-radius:2px; font-style:normal; padding:1px; } #highscoreContent form #content { box-sizing:border-box !important; padding:10px !important; } #highscoreContent div.content table { width:100% !important; } #highscoreContent #ranks tbody tr { background:#151920 !important; border-bottom:3px solid #0d1014 !important; } #highscoreContent #ranks tbody tr.myrank { background:linear-gradient(192deg, #23575c, #1c2a34 70%) !important; } #highscoreContent #ranks tbody tr.allyrank { background:linear-gradient(192deg, #2f366a, #181a2c 70%) !important; } #highscoreContent #ranks td { background:none !important; border:none !important; padding:0 !important; } #highscoreContent #ranks .playername { font-size:11px !important; font-weight:normal !important; } #highscoreContent #ranks .ally-tag { font-size:11px !important; margin-right:4px !important; } #highscoreContent #ranks profile-picture { height:32px !important; width:32px !important; } #highscoreContent #ranks profile-picture * { max-height:100% !important; max-width:100% !important; } #highscoreContent #ranks .highscoreNameFieldWrapper { height:40px !important; } #highscoreContent #ranks .honorScore { display:none !important; } #highscoreContent #ranks tr.expandedRow { height:auto !important; } #highscoreContent #ranks thead .score { font-weight:normal; } #highscoreContent #ranks .score { color:#848484 !important; font-size:11px !important; padding-right:5px !important; } #highscoreContent #ranks .highscorePositionIcon { background-size:75% !important; height:40px !important; } #highscoreContent #ranks .position { text-align:center !important; } #highscoreContent #ranks.allyHighscore tbody .name { display:flex; grid-gap:4px; line-height:34px; padding-left:14px !important; } .ogl_lastGalaxyRefresh { font-size:11px; margin:auto 5px auto auto; } `, oglMaterial = (GM_addStyle(css), ` @font-face { font-family:'Material Icons'; font-style:normal; font-weight:400; src:url('data:font/woff2;base64,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') format('woff2'); } `), miniImage = (GM_addStyle(oglMaterial), ` body[data-minipics="true"] { .maincontent > div header, .maincontent .planet-header { height:34px !important; } .maincontent #overviewcomponent #planet, .maincontent #overviewcomponent #detailWrapper { height:auto !important; min-height:208px !important; position:relative !important; } .maincontent #technologydetails_wrapper:not(.slide-down) { position:relative !important; } .maincontent #detail.detail_screen { height:300px !important; position:relative !important; } } `), altStyle = (GM_addStyle(miniImage), ` body[data-menulayout="1"], body[data-menulayout="2"] { #bannerSkyscrapercomponent { margin-left:260px !important; } #headerbarcomponent { width:1016px !important; } #commandercomponent { transform:translateX(25px); } .ogl_topbar { font-size:16px; width:100%; } #planetbarcomponent #rechts { width:170px !important; } #planetList { transform:translate(0); width:100%; } .smallplanet { background:#0e1116; box-sizing:border-box; height:38px !important; } .smallplanet .planetlink, .smallplanet .moonlink { border-radius:4px !important; height:100% !important; } .smallplanet .planet-name { top:6px !important; } .smallplanet .planet-koords { bottom:7px !important; } .smallplanet .planetPic { box-shadow:0 0 2px #000000 !important; left:8px !important; top:7px !important; transform:scale(1.2); } .smallplanet .icon-moon { box-shadow:0 0 3px #000000 !important; left:11px !important; top:11px !important; transform:scale(1.1); } #planetbarcomponent #rechts .ogl_shortcuts { transform:translateX(0); width:170px; } #planetbarcomponent #rechts .ogl_shortcuts [data-key] { width:42px; } } body[data-menulayout="1"] { .smallplanet { grid-template-columns:127px 38px; } .smallplanet .ogl_available { display:none; } .smallplanet .planet-name, .smallplanet .planet-koords { left:40px !important; } .ogl_refreshTimer { background:none;font-size:11px;left:auto;right:3px; } &.ogl_destinationPicker .smallplanet .planetlink.ogl_currentDestination:after { top:9px !important;left:9px !important; } &.ogl_destinationPicker .smallplanet .moonlink.ogl_currentDestination:after { top:9px !important;left:10px !important; } .ogl_buildIconList { left:4px; } } body[data-menulayout="2"] { .smallplanet { grid-template-columns:101px 64px; } .smallplanet .ogl_available { line-height:10px; } .smallplanet .planet-name, .smallplanet .planet-koords { opacity:0 !important; } .smallplanet .icon-moon { left:4px !important; } &.ogl_destinationPicker .smallplanet .planetlink.ogl_currentDestination:after { top:9px !important;left:9px !important; } &.ogl_destinationPicker .smallplanet .moonlink.ogl_currentDestination:after { top:9px !important;left:4px !important; } } body[data-sidepanel="true"] { .ogl_side { right:auto; transform:translateX(-100%); } .ogl_side.ogl_active { transform:translateX(-0%); } } `); GM_addStyle(altStyle); class CSSManager { static miniMenu(layout) { document.body.setAttribute("data-menulayout", layout), localStorage.setItem("ogl_menulayout", layout); } static miniImage(state) { document.body.setAttribute("data-minipics", state), localStorage.setItem("ogl_minipics", state); } static sidePanelLeft(state) { document.body.setAttribute("data-sidepanel", state), localStorage.setItem("ogl_sidepanel", state); } }