// GridTracker Copyright © 2021 GridTracker.org // All rights reserved. // See LICENSE for more information. var fs = require("fs"); var callRoster = {}; var g_blockedCalls = {}; var g_blockedCQ = {}; var g_blockedDxcc = {}; var g_scriptReport = {}; var g_worked = {}; var g_confirmed = {}; var g_modes = {}; var g_modes_phone = {}; var g_currentUSCallsigns = null; var r_currentUSState = ""; var r_currentDXCCs = -1; var r_callsignManifest = null; var g_rosterSettings = {}; var g_day = 0; var g_menu = null; var g_callMenu = null; var g_ageMenu = null; var g_callingMenu = null; var g_compactMenu = null; var g_targetHash = ""; var g_clearIgnores = null; var g_clearIgnoresCall = null; var g_dxccMenu = null; var g_targetDxcc = -1; var g_clearDxccIgnore = null; var g_clearDxccIgnoreMainMenu = null; var g_CQMenu = null; var g_targetCQ = ""; var g_clearCQIgnore = null; var g_clearCQIgnoreMainMenu = null; var g_timerInterval = null; var g_regFocus = false; var g_awards = {}; var g_awardTypes = {}; var g_awardTracker = {}; var g_callsignDatabaseDXCC = {}; var g_callsignDatabaseUS = {}; var g_callsignDatabaseUSplus = {}; var g_developerMode = process.versions["nw-flavor"] == "sdk"; var g_modeColors = {}; g_modeColors.FT4 = "1111FF"; g_modeColors.FT8 = "11FF11"; g_modeColors.JT4 = "EE1111"; g_modeColors.JT9 = "7CFC00"; g_modeColors.JT65 = "E550E5"; g_modeColors.QRA64 = "FF00FF"; g_modeColors.MSK144 = "4949FF"; var g_defaultSettings = { callsign: "all", hunting: "dxcc", huntNeed: "confirmed", requireGrid: true, wantMaxDT: false, wantMinDB: false, wantMinFreq: false, wantMaxFreq: false, maxDT: 0.5, minDb: -25, minFreq: 0, maxFreq: 3500, noMyDxcc: false, onlyMyDxcc: false, noMsg: false, noMsgValue: "CQ RU", onlyMsg: false, onlyMsgValue: "CQ FD", cqOnly: true, usesLoTW: false, maxLoTW: 27, useseQSL: false, usesOQRS: false, onlySpot: false, allOnlyNew: false, useRegex: false, callsignRegex: "", realtime: false, wanted: { huntCallsign: false, huntGrid: true, huntDXCC: true, huntCQz: false, huntITUz: false, huntState: false, huntCounty: false, huntCont: false, huntPX: false, huntQRZ: true, huntOAMS: false }, columns: { Band: false, Mode: false, Calling: true, Msg: false, DXCC: true, Flag: true, State: true, County: true, Cont: true, dB: true, Freq: false, DT: false, Dist: false, Azim: true, CQz: false, ITUz: false, PX: true, LoTW: false, eQSL: false, OQRS: false, Spot: false, Life: false, OAMS: true, Age: true }, reference: 0, controls: true, controlsExpanded: false, compact: false, settingProfiles: false, lastSortIndex: 6, lastSortReverse: 1 }; document.addEventListener("dragover", function (event) { event.preventDefault(); }); document.addEventListener("drop", function (event) { event.preventDefault(); }); window.addEventListener("message", receiveMessage, false); if (typeof localStorage.blockedCQ == "undefined") { localStorage.blockedCQ = "{}"; } if (typeof localStorage.awardTracker == "undefined") { localStorage.awardTracker = "{}"; g_rosterSettings = {}; writeRosterSettings(); } g_awardTracker = JSON.parse(localStorage.awardTracker); if (typeof localStorage.blockedCalls != "undefined") { g_blockedCalls = JSON.parse(localStorage.blockedCalls); g_blockedCQ = JSON.parse(localStorage.blockedCQ); g_blockedDxcc = JSON.parse(localStorage.blockedDxcc); } function storeBlocks() { localStorage.blockedCalls = JSON.stringify(g_blockedCalls); localStorage.blockedCQ = JSON.stringify(g_blockedCQ); localStorage.blockedDxcc = JSON.stringify(g_blockedDxcc); } function storeAwardTracker() { localStorage.awardTracker = JSON.stringify(g_awardTracker); } function loadSettings() { var readSettings = {}; if (typeof localStorage.rosterSettings != "undefined") { readSettings = JSON.parse(localStorage.rosterSettings); } g_rosterSettings = deepmerge(g_defaultSettings, readSettings); if ("GT" in g_rosterSettings.columns) delete g_rosterSettings.columns.GT; writeRosterSettings(); } function writeRosterSettings() { localStorage.rosterSettings = JSON.stringify(g_rosterSettings); } function isKnownCallsignDXCC(dxcc) { if (dxcc in g_callsignDatabaseDXCC) return true; return false; } function isKnownCallsignUS(dxcc) { if (dxcc in g_callsignDatabaseUS) return true; return false; } function isKnownCallsignUSplus(dxcc) { if (dxcc in g_callsignDatabaseUSplus) return true; return false; } function timeNowSec() { return parseInt(Date.now() / 1000); } function lockNewWindows() { if (typeof nw != "undefined") { var gui = require("nw.gui"); var win = gui.Window.get(); win.on("new-win-policy", function (frame, url, policy) { gui.Shell.openExternal(url); policy.ignore(); }); } } function myCallCompare(a, b) { return a.DEcall.localeCompare(b.DEcall); } function myGridCompare(a, b) { var gridA = a.grid ? a.grid : "0"; var gridB = b.grid ? b.grid : "0"; if (gridA > gridB) return 1; if (gridA < gridB) return -1; return 0; } function myDxccCompare(a, b) { return window.opener.myDxccCompare(a, b); } function myTimeCompare(a, b) { if (a.age > b.age) return 1; if (a.age < b.age) return -1; return 0; } function myLifeCompare(a, b) { if (a.life > b.life) return 1; if (a.life < b.life) return -1; return 0; } function mySpotCompare(a, b) { if (a.spot.when > b.spot.when) return 1; if (a.spot.when < b.spot.when) return -1; return 0; } function myDbCompare(a, b) { if (a.RSTsent > b.RSTsent) return 1; if (a.RSTsent < b.RSTsent) return -1; return 0; } function myFreqCompare(a, b) { if (a.delta > b.delta) return 1; if (a.delta < b.delta) return -1; return 0; } function myDTCompare(a, b) { if (a.dt > b.dt) return 1; if (a.dt < b.dt) return -1; return 0; } function myDistanceCompare(a, b) { if (a.distance > b.distance) return 1; if (a.distance < b.distance) return -1; return 0; } function myHeadingCompare(a, b) { if (a.heading > b.heading) return 1; if (a.heading < b.heading) return -1; return 0; } function myStateCompare(a, b) { if (a.state == null) return 1; if (b.state == null) return -1; if (a.state > b.state) return 1; if (a.state < b.state) return -1; return 0; } function myCQCompare(a, b) { return a.DXcall.localeCompare(b.DXcall); } function myWPXCompare(a, b) { if (a.px == null) return 1; if (b.px == null) return -1; if (a.px > b.px) return 1; if (a.px < b.px) return -1; return 0; } function myCntyCompare(a, b) { if (a.cnty == null) return 1; if (b.cnty == null) return -1; if (a.cnty.substr(3) > b.cnty.substr(3)) return 1; if (a.cnty.substr(3) < b.cnty.substr(3)) return -1; return 0; } function myContCompare(a, b) { if (a.cont == null) return 1; if (b.cont == null) return -1; if (a.cont > b.cont) return 1; if (a.cont < b.cont) return -1; return 0; } function myGTCompare(a, b) { if (a.style.gt != 0 && b.style.gt == 0) return 1; if (a.style.gt == 0 && b.style.gt != 0) return -1; return 0; } var r_sortFunction = [ myCallCompare, myGridCompare, myDbCompare, myDTCompare, myFreqCompare, myDxccCompare, myTimeCompare, myDistanceCompare, myHeadingCompare, myStateCompare, myCQCompare, myWPXCompare, myLifeCompare, mySpotCompare, myGTCompare, myCntyCompare, myContCompare ]; function showRosterBox(sortIndex) { if (g_rosterSettings.lastSortIndex != sortIndex) { g_rosterSettings.lastSortIndex = sortIndex; g_rosterSettings.lastSortReverse = 0; } else { g_rosterSettings.lastSortReverse ^= 1; } writeRosterSettings(); window.opener.goProcessRoster(); } function hashMaker(band, mode) { // "Current Band & Mode" if (g_rosterSettings.reference == 0 || g_rosterSettings.reference == 6) { return band + mode; } // "Current Band, Any Mode" if (g_rosterSettings.reference == 1) return band; // "Current Band, Any Digi Mode" if (g_rosterSettings.reference == 2) return band + "dg"; // "Current Mode, Any Band" if (g_rosterSettings.reference == 3) return mode; // "Any Band, Any Mode" if (g_rosterSettings.reference == 4) return ""; // "Any Band, Any Digi Mode" if (g_rosterSettings.reference == 5) return "dg"; } function processRoster(roster) { callRoster = roster; viewRoster(); } function viewRoster() { var bands = Object(); var modes = Object(); var callMode = g_rosterSettings.callsign; var onlyHits = false; var isAwardTracker = false; if (callMode == "hits") { callMode = "all"; onlyHits = true; } if (referenceNeed.value == 6) { callMode = "all"; onlyHits = false; isAwardTracker = true; g_rosterSettings.huntNeed = "confirmed"; } var canMsg = window.opener.g_mapSettings.offlineMode == false && window.opener.g_appSettings.gtShareEnable == "true" && window.opener.g_appSettings.gtMsgEnable == "true"; if (window.opener.g_callsignLookups.lotwUseEnable == true) { usesLoTWDiv.style.display = ""; if (g_rosterSettings.usesLoTW == true) { maxLoTW.style.display = ""; maxLoTWView.style.display = ""; } else { maxLoTW.style.display = "none"; maxLoTWView.style.display = "none"; } } else { usesLoTWDiv.style.display = "none"; maxLoTW.style.display = "none"; maxLoTWView.style.display = "none"; } if (window.opener.g_callsignLookups.eqslUseEnable == true) { useseQSLDiv.style.display = ""; } else useseQSLDiv.style.display = "none"; if (window.opener.g_callsignLookups.oqrsUseEnable == true) { usesOQRSDiv.style.display = ""; } else usesOQRSDiv.style.display = "none"; if (g_rosterSettings.columns.Spot == true) { onlySpotDiv.style.display = ""; } else onlySpotDiv.style.display = "none"; if (callMode == "all") allOnlyNewDiv.style.display = ""; else allOnlyNewDiv.style.display = "none"; var now = timeNowSec(); for (var callHash in callRoster) { var call = callRoster[callHash].DEcall; callRoster[callHash].tx = true; callRoster[callHash].callObj.shouldAlert = false; callRoster[callHash].callObj.reason = Array(); callRoster[callHash].callObj.awardReason = "Callsign"; if ( now - callRoster[callHash].callObj.age > window.opener.g_mapSettings.rosterTime ) { callRoster[callHash].tx = false; callRoster[callHash].alerted = false; callRoster[callHash].callObj.qrz = false; callRoster[callHash].callObj.reset = true; continue; } if ( window.opener.g_instances[callRoster[callHash].callObj.instance] .crEnable == false ) { callRoster[callHash].tx = false; continue; } if (call in g_blockedCalls) { callRoster[callHash].tx = false; continue; } if ( callRoster[callHash].DXcall + " from All" in g_blockedCQ || callRoster[callHash].DXcall + " from " + window.opener.g_dxccToAltName[callRoster[callHash].callObj.dxcc] in g_blockedCQ ) { callRoster[callHash].tx = false; continue; } if (callRoster[callHash].callObj.dxcc in g_blockedDxcc) { callRoster[callHash].tx = false; continue; } if ( g_rosterSettings.cqOnly == true && callRoster[callHash].callObj.CQ == false ) { callRoster[callHash].tx = false; continue; } if ( g_rosterSettings.useRegex && g_rosterSettings.callsignRegex.length > 0 ) { try { if (!call.match(g_rosterSettings.callsignRegex)) { callRoster[callHash].tx = false; continue; } } catch (e) {} } if ( g_rosterSettings.requireGrid == true && callRoster[callHash].callObj.grid.length != 4 ) { callRoster[callHash].tx = false; continue; } if ( g_rosterSettings.wantMinDB == true && callRoster[callHash].message.SR < g_rosterSettings.minDb ) { callRoster[callHash].tx = false; continue; } if ( g_rosterSettings.wantMaxDT == true && Math.abs(callRoster[callHash].message.DT) > g_rosterSettings.maxDT ) { callRoster[callHash].tx = false; continue; } if ( g_rosterSettings.wantMinFreq == true && callRoster[callHash].message.DF < g_rosterSettings.minFreq ) { callRoster[callHash].tx = false; continue; } if ( g_rosterSettings.wantMaxFreq == true && callRoster[callHash].message.DF > g_rosterSettings.maxFreq ) { callRoster[callHash].tx = false; continue; } if (g_rosterSettings.noMsg == true) { try { if ( callRoster[callHash].callObj.msg.match(g_rosterSettings.noMsgValue) ) { callRoster[callHash].tx = false; continue; } } catch (e) {} } if (g_rosterSettings.onlyMsg == true) { try { if ( !callRoster[callHash].callObj.msg.match(g_rosterSettings.onlyMsgValue) ) { callRoster[callHash].tx = false; continue; } } catch (e) {} } if (callRoster[callHash].callObj.dxcc == window.opener.g_myDXCC) { if (g_rosterSettings.noMyDxcc == true) { callRoster[callHash].tx = false; continue; } } else { if (g_rosterSettings.onlyMyDxcc == true) { callRoster[callHash].tx = false; continue; } } if ( window.opener.g_callsignLookups.lotwUseEnable == true && g_rosterSettings.usesLoTW == true ) { if (!(call in window.opener.g_lotwCallsigns)) { callRoster[callHash].tx = false; continue; } if (g_rosterSettings.maxLoTW < 27) { var months = (g_day - window.opener.g_lotwCallsigns[call]) / 30; if (months > g_rosterSettings.maxLoTW) { callRoster[callHash].tx = false; continue; } } } if ( window.opener.g_callsignLookups.eqslUseEnable == true && g_rosterSettings.useseQSL == true ) { if (!(call in window.opener.g_eqslCallsigns)) { callRoster[callHash].tx = false; continue; } } if ( window.opener.g_callsignLookups.oqrsUseEnable == true && g_rosterSettings.usesOQRS == true ) { if (!(call in window.opener.g_oqrsCallsigns)) { callRoster[callHash].tx = false; continue; } } if (callMode != "all") { if ( callRoster[callHash].DXcall == "CQ DX" && callRoster[callHash].callObj.dxcc == window.opener.g_myDXCC ) { callRoster[callHash].tx = false; continue; } var hash = call + hashMaker( callRoster[callHash].callObj.band, callRoster[callHash].callObj.mode ); if (callMode == "worked" && hash in g_worked.call) { callRoster[callHash].tx = false; continue; } if (callMode == "confirmed" && hash in g_confirmed.call) { callRoster[callHash].tx = false; continue; } if (g_rosterSettings.hunting == "grid") { var hash = callRoster[callHash].callObj.grid.substr(0, 4) + hashMaker( callRoster[callHash].callObj.band, callRoster[callHash].callObj.mode ); if (g_rosterSettings.huntNeed == "worked" && hash in g_worked.grid) { callRoster[callHash].tx = false; continue; } if ( g_rosterSettings.huntNeed == "confirmed" && hash in g_confirmed.grid ) { callRoster[callHash].tx = false; continue; } if (callRoster[callHash].callObj.grid.length == 0) { callRoster[callHash].tx = false; continue; } continue; } if (g_rosterSettings.hunting == "dxcc") { var hash = String(callRoster[callHash].callObj.dxcc) + hashMaker( callRoster[callHash].callObj.band, callRoster[callHash].callObj.mode ); if ((g_rosterSettings.huntNeed == "worked") & (hash in g_worked.dxcc)) { callRoster[callHash].tx = false; continue; } if ( g_rosterSettings.huntNeed == "confirmed" && hash in g_confirmed.dxcc ) { callRoster[callHash].tx = false; continue; } continue; } if (g_rosterSettings.hunting == "dxccs" && r_currentDXCCs != -1) { if (callRoster[callHash].callObj.dxcc != r_currentDXCCs) { callRoster[callHash].tx = false; continue; } } if (g_rosterSettings.hunting == "wpx") { if (String(callRoster[callHash].callObj.px) == null) { callRoster[callHash].tx = false; continue; } var hash = String(callRoster[callHash].callObj.px) + hashMaker( callRoster[callHash].callObj.band, callRoster[callHash].callObj.mode ); if ((g_rosterSettings.huntNeed == "worked") & (hash in g_worked.px)) { callRoster[callHash].tx = false; continue; } if ( g_rosterSettings.huntNeed == "confirmed" && hash in g_confirmed.px ) { callRoster[callHash].tx = false; continue; } continue; } if (g_rosterSettings.hunting == "cq") { var workedTotal = (confirmedTotal = callRoster[callHash].callObj.cqza.length); if (workedTotal == 0) { callRoster[callHash].tx = false; continue; } var workedFound = (confirmedFound = 0); for (index in callRoster[callHash].callObj.cqza) { var hash = callRoster[callHash].callObj.cqza[index] + hashMaker( callRoster[callHash].callObj.band, callRoster[callHash].callObj.mode ); if (hash in g_worked.cqz) workedFound++; if (hash in g_confirmed.cqz) confirmedFound++; } if ( g_rosterSettings.huntNeed == "worked" && workedFound == workedTotal ) { callRoster[callHash].tx = false; continue; } if ( g_rosterSettings.huntNeed == "confirmed" && confirmedFound == confirmedTotal ) { callRoster[callHash].tx = false; continue; } continue; } if (g_rosterSettings.hunting == "itu") { var workedTotal = (confirmedTotal = callRoster[callHash].callObj.ituza.length); if (workedTotal == 0) { callRoster[callHash].tx = false; continue; } var workedFound = (confirmedFound = 0); for (index in callRoster[callHash].callObj.ituza) { var hash = callRoster[callHash].callObj.ituza[index] + hashMaker( callRoster[callHash].callObj.band, callRoster[callHash].callObj.mode ); if (hash in g_worked.ituz) workedFound++; if (hash in g_confirmed.ituz) confirmedFound++; } if ( g_rosterSettings.huntNeed == "worked" && workedFound == workedTotal ) { callRoster[callHash].tx = false; continue; } if ( g_rosterSettings.huntNeed == "confirmed" && confirmedFound == confirmedTotal ) { callRoster[callHash].tx = false; continue; } if (callRoster[callHash].callObj.grid.length == 0) { callRoster[callHash].tx = false; continue; } continue; } if ( g_rosterSettings.hunting == "usstates" && window.opener.g_callsignLookups.ulsUseEnable == true ) { var state = callRoster[callHash].callObj.state; var finalDxcc = callRoster[callHash].callObj.dxcc; if (finalDxcc == 291 || finalDxcc == 110 || finalDxcc == 6) { if (state in window.opener.g_StateData) { var hash = state + hashMaker( callRoster[callHash].callObj.band, callRoster[callHash].callObj.mode ); if ( g_rosterSettings.huntNeed == "worked" && hash in g_worked.state ) { callRoster[callHash].tx = false; continue; } if ( g_rosterSettings.huntNeed == "confirmed" && hash in g_confirmed.state ) { callRoster[callHash].tx = false; continue; } } else callRoster[callHash].tx = false; } else callRoster[callHash].tx = false; continue; } if (g_rosterSettings.hunting == "usstate" && g_currentUSCallsigns) { if (call in g_currentUSCallsigns) { // Do Nothing } else { callRoster[callHash].tx = false; continue; } continue; } } if (isAwardTracker) { var tx = false; var baseHash = hashMaker( callRoster[callHash].callObj.band, callRoster[callHash].callObj.mode ); for (var award in g_awardTracker) { if (g_awardTracker[award].enable) { tx = testAward(award, callRoster[callHash].callObj, baseHash); if (tx) { var x = g_awardTracker[award]; callRoster[callHash].callObj.awardReason = g_awards[x.sponsor].awards[x.name].tooltip + " (" + g_awards[x.sponsor].sponsor + ")"; break; } } } callRoster[callHash].tx = tx; } } var hasGtPin = false; var newCallList = Array(); var inversionAlpha = "DD"; var row = "#000000"; var bold = "#000000;text-shadow: 0px 0px 1px black;"; var unconf = "background-clip:content-box;box-shadow: 0 0 8px 3px inset "; for (var callHash in callRoster) { // Special case check for called station if ( callRoster[callHash].callObj.qrz == true && callRoster[callHash].tx == false ) { // The instance has to be enabled if ( window.opener.g_instances[callRoster[callHash].callObj.instance] .crEnable == true ) { // Calling us, but we wouldn't normally display // If they are not ignored or we're in a QSO with them, var it through if ( (!(callRoster[callHash].DEcall in g_blockedCalls) && !(callRoster[callHash].callObj.dxcc in g_blockedDxcc)) || window.opener.g_instances[callRoster[callHash].callObj.instance] .status.DXcall == callRoster[callHash].DEcall ) { callRoster[callHash].tx = true; } } } if ( callRoster[callHash].callObj.dxcc != -1 && callRoster[callHash].tx == true ) { var workHash = hashMaker( callRoster[callHash].callObj.band, callRoster[callHash].callObj.mode ); var call = callRoster[callHash].DEcall; var testHash = call + workHash; var colorObject = Object(); var callPointer = callRoster[callHash].callObj.CQ == true ? "cursor:pointer" : ""; var didWork = false; var callsign = "#FFFF00"; var grid = "#00FFFF"; var calling = "#90EE90"; var dxcc = "#FFA500"; var state = "#90EE90"; var cnty = "#CCDD00"; var cont = "#00DDDD"; var cqz = "#DDDDDD"; var ituz = "#DDDDDD"; var wpx = "#FFFF00"; hasGtPin = false; var shouldAlert = false; var callsignBg, gridBg, callingBg, dxccBg, stateBg, cntyBg, contBg, cqzBg, ituzBg, wpxBg, gtBg; var callConf, gridConf, callingConf, dxccConf, stateConf, cntyConf, contConf, cqzConf, ituzConf, wpxConf; callsignBg = gridBg = callingBg = dxccBg = stateBg = cntyBg = contBg = cqzBg = ituzBg = wpxBg = gtBg = row; callConf = gridConf = callingConf = dxccConf = stateConf = cntyConf = contConf = cqzConf = ituzConf = wpxConf = ""; if (testHash in g_worked.call) { didWork = true; callConf = unconf + callsign + inversionAlpha + ";"; if (testHash in g_confirmed.call) { callPointer = "text-decoration: line-through; "; callConf = ""; } } if ( call in window.opener.g_gtCallsigns && window.opener.g_gtCallsigns[call] in window.opener.g_gtFlagPins && window.opener.g_gtFlagPins[window.opener.g_gtCallsigns[call]].canmsg == true ) { // grab the CID colorObject.gt = window.opener.g_gtCallsigns[call]; hasGtPin = true; } else colorObject.gt = 0; if (callMode == "all") { if ( allOnlyNew.checked == true && didWork && callRoster[callHash].callObj.qrz == false ) { callRoster[callHash].tx = false; continue; } if (huntCallsign.checked == true) { if (g_rosterSettings.huntNeed == "worked" && didWork) { callRoster[callHash].callObj.reason.push("call"); callConf = unconf + callsign + inversionAlpha + ";"; } if ( didWork && g_rosterSettings.huntNeed == "confirmed" && !(testHash in g_confirmed.call) ) { shouldAlert = true; callRoster[callHash].callObj.reason.push("call"); callConf = unconf + callsign + inversionAlpha + ";"; } else if ( didWork && g_rosterSettings.huntNeed == "confirmed" && testHash in g_confirmed.call ) { callConf = ""; } else if (!didWork) { shouldAlert = true; callConf = ""; callsignBg = callsign + inversionAlpha; callsign = bold; } } if ( huntQRZ.checked == true && callRoster[callHash].callObj.qrz == true ) { shouldAlert = true; callRoster[callHash].callObj.reason.push("qrz"); } if (huntOAMS.checked == true && hasGtPin == true) { shouldAlert = true; callRoster[callHash].callObj.reason.push("oams"); } if ( huntGrid.checked == true && callRoster[callHash].callObj.grid.length > 1 ) { var hash = callRoster[callHash].callObj.grid.substr(0, 4) + workHash; if ( (g_rosterSettings.huntNeed == "worked" && !(hash in g_worked.grid)) || (g_rosterSettings.huntNeed == "confirmed" && !(hash in g_confirmed.grid)) ) { shouldAlert = true; callRoster[callHash].callObj.reason.push("grid"); if ( g_rosterSettings.huntNeed == "confirmed" && hash in g_worked.grid ) { gridConf = unconf + grid + inversionAlpha + ";"; } else { gridBg = grid + inversionAlpha; grid = bold; } } } if (huntDXCC.checked == true) { var hash = String(callRoster[callHash].callObj.dxcc) + workHash; if ( (g_rosterSettings.huntNeed == "worked" && !(hash in g_worked.dxcc)) || (g_rosterSettings.huntNeed == "confirmed" && !(hash in g_confirmed.dxcc)) ) { shouldAlert = true; callRoster[callHash].callObj.reason.push("dxcc"); if ( g_rosterSettings.huntNeed == "confirmed" && hash in g_worked.dxcc ) { dxccConf = unconf + dxcc + inversionAlpha + ";"; } else { dxccBg = dxcc + inversionAlpha; dxcc = bold; } } } if ( huntState.checked == true && window.opener.g_callsignLookups.ulsUseEnable == true ) { var stateSearch = callRoster[callHash].callObj.state; var finalDxcc = callRoster[callHash].callObj.dxcc; if (finalDxcc == 291 || finalDxcc == 110 || finalDxcc == 6) { if (stateSearch in window.opener.g_StateData) { var hash = stateSearch + workHash; if ( (g_rosterSettings.huntNeed == "worked" && !(hash in g_worked.state)) || (g_rosterSettings.huntNeed == "confirmed" && !(hash in g_confirmed.state)) ) { shouldAlert = true; callRoster[callHash].callObj.reason.push("usstates"); if ( g_rosterSettings.huntNeed == "confirmed" && hash in g_worked.state ) { stateConf = unconf + state + inversionAlpha + ";"; } else { stateBg = state + inversionAlpha; state = bold; } } } } } if ( huntCounty.checked == true && window.opener.g_callsignLookups.ulsUseEnable == true ) { var finalDxcc = callRoster[callHash].callObj.dxcc; if ( callRoster[callHash].callObj.cnty && (finalDxcc == 291 || finalDxcc == 110 || finalDxcc == 6 || finalDxcc == 202) && callRoster[callHash].callObj.cnty.length > 0 ) { var hash = callRoster[callHash].callObj.cnty + workHash; if ( (g_rosterSettings.huntNeed == "worked" && !(hash in g_worked.cnty)) || (g_rosterSettings.huntNeed == "confirmed" && !(hash in g_confirmed.cnty)) || callRoster[callHash].callObj.qual == false ) { if (callRoster[callHash].callObj.qual == false) { var counties = window.opener.g_zipToCounty[ callRoster[callHash].callObj.zipcode ]; var foundHit = false; for (var cnt in counties) { var hh = counties[cnt] + workHash; callRoster[callHash].callObj.cnty = counties[cnt]; if ( g_rosterSettings.huntNeed == "worked" && !(hh in g_worked.cnty) ) { foundHit = true; break; } if ( g_rosterSettings.huntNeed == "confirmed" && !(hh in g_confirmed.cnty) ) { foundHit = true; break; } } if (foundHit) shouldAlert = true; } else { shouldAlert = true; } if (shouldAlert) { callRoster[callHash].callObj.reason.push("uscnty"); if ( g_rosterSettings.huntNeed == "confirmed" && hash in g_worked.cnty ) { cntyConf = unconf + cnty + inversionAlpha + ";"; } else { cntyBg = cnty + inversionAlpha; cnty = bold; } } } } } if (huntCQz.checked == true) { var workedTotal = (confirmedTotal = callRoster[callHash].callObj.cqza.length); var workedFound = (confirmedFound = 0); for (index in callRoster[callHash].callObj.cqza) { var hash = callRoster[callHash].callObj.cqza[index] + workHash; if (hash in g_worked.cqz) workedFound++; if (hash in g_confirmed.cqz) confirmedFound++; } if ( (g_rosterSettings.huntNeed == "worked" && workedFound != workedTotal) || (g_rosterSettings.huntNeed == "confirmed" && confirmedFound != confirmedTotal) ) { shouldAlert = true; callRoster[callHash].callObj.reason.push("cq"); if ( g_rosterSettings.huntNeed == "confirmed" && workedFound == workedTotal ) { cqzConf = unconf + cqz + inversionAlpha + ";"; } else { cqzBg = cqz + inversionAlpha; cqz = bold; } } } if (huntITUz.checked == true) { var workedTotal = (confirmedTotal = callRoster[callHash].callObj.ituza.length); var workedFound = (confirmedFound = 0); for (index in callRoster[callHash].callObj.ituza) { var hash = callRoster[callHash].callObj.ituza[index] + workHash; if (hash in g_worked.ituz) workedFound++; if (hash in g_confirmed.ituz) confirmedFound++; } if ( (g_rosterSettings.huntNeed == "worked" && workedFound != workedTotal) || (g_rosterSettings.huntNeed == "confirmed" && confirmedFound != confirmedTotal) ) { shouldAlert = true; callRoster[callHash].callObj.reason.push("itu"); if ( g_rosterSettings.huntNeed == "confirmed" && workedFound == workedTotal ) { ituzConf = unconf + ituz + inversionAlpha + ";"; } else { ituzBg = ituz + inversionAlpha; ituz = bold; } } } if (huntPX.checked == true && callRoster[callHash].callObj.px) { var hash = String(callRoster[callHash].callObj.px) + workHash; if ( (g_rosterSettings.huntNeed == "worked" && !(hash in g_worked.px)) || (g_rosterSettings.huntNeed == "confirmed" && !(hash in g_confirmed.px)) ) { shouldAlert = true; callRoster[callHash].callObj.reason.push("wpx"); if ( g_rosterSettings.huntNeed == "confirmed" && hash in g_worked.px ) { wpxConf = unconf + wpx + inversionAlpha + ";"; } else { wpxBg = wpx + inversionAlpha; wpx = bold; } } } if (huntCont.checked == true && callRoster[callHash].callObj.cont) { var hash = String(callRoster[callHash].callObj.cont) + workHash; if ( (g_rosterSettings.huntNeed == "worked" && !(hash in g_worked.cont)) || (g_rosterSettings.huntNeed == "confirmed" && !(hash in g_confirmed.cont)) ) { shouldAlert = true; callRoster[callHash].callObj.reason.push("cont"); if ( g_rosterSettings.huntNeed == "confirmed" && hash in g_worked.cont ) { contConf = unconf + cont + inversionAlpha + ";"; } else { contBg = cont + inversionAlpha; cont = bold; } } } } if (callRoster[callHash].callObj.DXcall == window.opener.myDEcall) { callingBg = "#0000FF" + inversionAlpha; calling = "#FFFF00;text-shadow: 0px 0px 2px #FFFF00"; } else if ( callRoster[callHash].callObj.CQ == true && g_rosterSettings.cqOnly == false ) { callingBg = calling + inversionAlpha; calling = bold; } colorObject.callsign = "style='" + callConf + "background-color:" + callsignBg + ";color:" + callsign + ";" + callPointer + "'"; colorObject.grid = "style='" + gridConf + "background-color:" + gridBg + ";color:" + grid + ";cursor:pointer'"; colorObject.calling = "style='" + callingConf + "background-color:" + callingBg + ";color:" + calling + "'"; colorObject.dxcc = "style='" + dxccConf + "background-color:" + dxccBg + ";color:" + dxcc + "'"; colorObject.state = "style='" + stateConf + "background-color:" + stateBg + ";color:" + state + "'"; colorObject.cnty = "style='" + cntyConf + "background-color:" + cntyBg + ";color:" + cnty + "'"; colorObject.cont = "style='" + contConf + "background-color:" + contBg + ";color:" + cont + "'"; colorObject.cqz = "style='" + cqzConf + "background-color:" + cqzBg + ";color:" + cqz + "'"; colorObject.ituz = "style='" + ituzConf + "background-color:" + ituzBg + ";color:" + ituz + "'"; colorObject.px = "style='" + wpxConf + "background-color:" + wpxBg + ";color:" + wpx + "'"; if (didWork && shouldAlert) shouldAlert = false; callRoster[callHash].callObj.shouldAlert = shouldAlert; callRoster[callHash].callObj.style = colorObject; if (g_rosterSettings.columns.Spot) { callRoster[callHash].callObj.spot = window.opener.getSpotTime( callRoster[callHash].callObj.DEcall + callRoster[callHash].callObj.mode + callRoster[callHash].callObj.band + callRoster[callHash].callObj.grid ); if (callRoster[callHash].callObj.spot == null) { callRoster[callHash].callObj.spot = { when: 0, snr: 0 }; } } else callRoster[callHash].callObj.spot = { when: 0, snr: 0 }; modes[callRoster[callHash].callObj.mode] = true; bands[callRoster[callHash].callObj.band] = true; newCallList.push(callRoster[callHash].callObj); } } if (g_rosterSettings.compact == false) { newCallList.sort(r_sortFunction[g_rosterSettings.lastSortIndex]); if (g_rosterSettings.lastSortReverse == 1) { newCallList.reverse(); } } else { // Age sort for now... make this happen Tag newCallList.sort(r_sortFunction[6]).reverse(); } var showBands = (Object.keys(bands).length > 1) || g_rosterSettings.columns.Band; var showModes = (Object.keys(modes).length > 1) || g_rosterSettings.columns.Mode; var worker = ""; if (g_rosterSettings.compact == false) { worker = ""; worker += ""; if (showBands) { worker += ""; } if (showModes) { worker += ""; } worker += ""; if (g_rosterSettings.columns.Calling) { worker += ""; } if (g_rosterSettings.columns.Msg) worker += ""; if (g_rosterSettings.columns.DXCC) { worker += ""; } if (g_rosterSettings.columns.Flag) { worker += ""; } if (g_rosterSettings.columns.State) { worker += ""; } if (g_rosterSettings.columns.County) { worker += ""; } if (g_rosterSettings.columns.Cont) { worker += ""; } if (g_rosterSettings.columns.dB) { worker += ""; } if (g_rosterSettings.columns.Freq) { worker += ""; } if (g_rosterSettings.columns.DT) { worker += ""; } if (g_rosterSettings.columns.Dist) { worker += ""; } if (g_rosterSettings.columns.Azim) { worker += ""; } if (g_rosterSettings.columns.CQz) worker += ""; if (g_rosterSettings.columns.ITUz) worker += ""; if (g_rosterSettings.columns.PX) { worker += ""; } if ( window.opener.g_callsignLookups.lotwUseEnable == true && g_rosterSettings.columns.LoTW ) { worker += ""; } if ( window.opener.g_callsignLookups.eqslUseEnable == true && g_rosterSettings.columns.eQSL ) { worker += ""; } if ( window.opener.g_callsignLookups.oqrsUseEnable == true && g_rosterSettings.columns.OQRS ) { worker += ""; } if (g_rosterSettings.columns.Spot) { worker += ""; } if (g_rosterSettings.columns.Life) { worker += ""; } if (g_rosterSettings.columns.OAMS) { worker += ""; } if (g_rosterSettings.columns.Age) { worker += ""; } } else { worker = "
"; } var shouldAlert = 0; for (var x in newCallList) { if ( newCallList[x].shouldAlert == false && onlyHits == true && newCallList[x].qrz == false ) { continue; } var spotString = ""; if (g_rosterSettings.columns.Spot && newCallList[x].qrz == false) { spotString = getSpotString(newCallList[x]); if (g_rosterSettings.onlySpot && spotString == "") continue; } var grid = newCallList[x].grid.length > 1 ? newCallList[x].grid.substr(0, 4) : "-"; var geo = window.opener.g_worldGeoData[ window.opener.g_dxccToGeoData[newCallList[x].dxcc] ]; var cqzone = grid in window.opener.g_gridToCQZone ? window.opener.g_gridToCQZone[grid].join(", ") : "-"; var ituzone = grid in window.opener.g_gridToITUZone ? window.opener.g_gridToITUZone[grid].join(", ") : "-"; var thisCall = newCallList[x].DEcall; if (thisCall.match("^[A-Z][0-9][A-Z](/w+)?$")) { newCallList[x].style.callsign = "class='oneByOne'"; } if ( thisCall == window.opener.g_instances[newCallList[x].instance].status.DXcall ) { if ( window.opener.g_instances[newCallList[x].instance].status.TxEnabled == 1 ) { newCallList[x].style.callsign = "class='dxCalling'"; } else { newCallList[x].style.callsign = "class='dxCaller'"; } } if (g_rosterSettings.compact == false) { var thisHash = thisCall + newCallList[x].band + newCallList[x].mode; worker += "
"; worker += ""; if (showBands) { worker += ""; } if (showModes) { var color = "888888"; if (newCallList[x].mode in g_modeColors) { color = g_modeColors[newCallList[x].mode]; } worker += ""; } worker += ""; if (g_rosterSettings.columns.Calling) { var lookString = newCallList[x].CQ ? "name='CQ'" : "name='Calling'"; worker += ""; } if (g_rosterSettings.columns.Msg) { worker += ""; } if (g_rosterSettings.columns.DXCC) { worker += ""; } if (g_rosterSettings.columns.Flag) { worker += ""; } if (g_rosterSettings.columns.State) { worker += ""; } if (g_rosterSettings.columns.County) { worker += ""; } if (g_rosterSettings.columns.Cont) { worker += ""; } if (g_rosterSettings.columns.dB) { worker += ""; } if (g_rosterSettings.columns.Freq) { worker += ""; } if (g_rosterSettings.columns.DT) { worker += ""; } if (g_rosterSettings.columns.Dist) { worker += ""; } if (g_rosterSettings.columns.Azim) { worker += ""; } if (g_rosterSettings.columns.CQz) { worker += ""; } if (g_rosterSettings.columns.ITUz) { worker += ""; } if (g_rosterSettings.columns.PX) { worker += ""; } if ( window.opener.g_callsignLookups.lotwUseEnable == true && g_rosterSettings.columns.LoTW ) { if (thisCall in window.opener.g_lotwCallsigns) { if (g_rosterSettings.maxLoTW < 27) { var months = (g_day - window.opener.g_lotwCallsigns[thisCall]) / 30; if (months > g_rosterSettings.maxLoTW) { worker += ""; } else { worker += ""; } } else { worker += ""; } } else worker += ""; } if ( window.opener.g_callsignLookups.eqslUseEnable == true && g_rosterSettings.columns.eQSL ) { worker += ""; } if ( window.opener.g_callsignLookups.oqrsUseEnable == true && g_rosterSettings.columns.OQRS ) { worker += ""; } if (g_rosterSettings.columns.Spot) { worker += ""; } if (g_rosterSettings.columns.Life) { worker += ""; } if (g_rosterSettings.columns.OAMS) { if (newCallList[x].style.gt != 0) { if (newCallList[x].reason.includes("oams")) { worker += ""; } else { worker += ""; } } else worker += ""; } if (g_rosterSettings.columns.Age) { worker += ""; } worker += ""; } else { var tt = newCallList[x].RSTsent + "㏈, " + parseInt(newCallList[x].dt * 100) + "ms, " + newCallList[x].delta + "hz" + (newCallList[x].grid.length ? ", " + newCallList[x].grid : "") + ", " + (timeNowSec() - newCallList[x].age).toDHMS(); worker += "
"; worker += "
" + thisCall.formatCallsign() + "
"; worker += "
" + window.opener.g_dxccToAltName[newCallList[x].dxcc] + "
"; worker += "
"; } if (g_rosterSettings.realtime == false) { var call = newCallList[x].DEcall; g_scriptReport[call] = Object.assign({}, newCallList[x]); g_scriptReport[call].dxccName = window.opener.g_dxccToAltName[newCallList[x].dxcc]; g_scriptReport[call].distance = parseInt( newCallList[x].distance * MyCircle.validateRadius(window.opener.distanceUnit.value) ); delete g_scriptReport[call].DEcall; g_scriptReport[call].rect = null; delete g_scriptReport[call].rect; delete g_scriptReport[call].style; delete g_scriptReport[call].wspr; delete g_scriptReport[call].qso; delete g_scriptReport[call].instance; if (callMode != "all") { g_scriptReport[call].shouldAlert = true; g_scriptReport[call].reason.push(g_rosterSettings.hunting); } } if ( newCallList[x].alerted == false && callMode == "all" && newCallList[x].shouldAlert == true ) { newCallList[x].alerted = true; shouldAlert++; } else if (newCallList[x].alerted == false && callMode != "all") { newCallList[x].alerted = true; shouldAlert++; } newCallList[x].shouldAlert = false; } if (g_rosterSettings.compact == false) { worker += "
CallsignBandModeGridCallingMsgDXCCFlagStateCountyContdBFreqDTDist(" + window.opener.distanceUnit.value.toLowerCase() + ")AzimCQzITUzPXLoTWeQSLOQRSSpotLifeOAMAge
" + thisCall.formatCallsign() + "" + newCallList[x].band + "" + newCallList[x].mode + "" + grid + "" + newCallList[x].DXcall.formatCallsign() + "" + newCallList[x].msg + "" + window.opener.g_dxccToAltName[newCallList[x].dxcc] + "" + (newCallList[x].state ? newCallList[x].state.substr(3) : "") + "" + (newCallList[x].cnty ? (newCallList[x].qual ? "" : "~ ") + window.opener.g_cntyToCounty[newCallList[x].cnty] + (newCallList[x].qual ? "" : " ~") : "") + "" + (newCallList[x].cont ? newCallList[x].cont : "") + "" + newCallList[x].RSTsent + "" + newCallList[x].delta + "" + newCallList[x].dt + "" + parseInt( newCallList[x].distance * MyCircle.validateRadius(window.opener.distanceUnit.value) ) + "" + parseInt(newCallList[x].heading) + "" + newCallList[x].cqza.join(",") + "" + newCallList[x].ituza.join(",") + "" + (newCallList[x].px ? newCallList[x].px : "") + "?" + (thisCall in window.opener.g_eqslCallsigns ? "✔" : "") + "" + (thisCall in window.opener.g_oqrsCallsigns ? "✔" : "") + "" + spotString + "" + (timeNowSec() - newCallList[x].life).toDHMS() + "" + (timeNowSec() - newCallList[x].age).toDHMS() + "
"; RosterTable.innerHTML = worker; } else { RosterTable.innerHTML = worker + ""; } var dirPath = window.opener.g_scriptDir; var scriptExists = false; var script = "cr-alert.sh"; try { if (fs.existsSync(dirPath)) { if (window.opener.g_platform == "windows") { script = "cr-alert.bat"; } if ( fs.existsSync(dirPath + script) && g_rosterSettings.realtime == false ) { scriptExists = true; scriptIcon.innerHTML = "
" + (window.opener.g_crScript == 1 ? "Script Enabled" : "Script Disabled") + "
"; scriptIcon.style.display = "block"; } else { scriptIcon.style.display = "none"; } } } catch (e) {} if (shouldAlert > 0) { if (window.opener.g_classicAlerts.huntRoster == true) { var notify = window.opener.huntRosterNotify.value; if (notify == "0") { var media = window.opener.huntRosterNotifyMedia.value; if (media != "none") window.opener.playAlertMediaFile(media); } else if (notify == "1") { window.opener.speakAlertString( window.opener.huntRosterNotifyWord.value ); } } if ( g_rosterSettings.realtime == false && scriptExists && window.opener.g_crScript == 1 ) { try { fs.writeFileSync( dirPath + "cr-alert.json", JSON.stringify(g_scriptReport, null, 2) ); var thisProc = dirPath + script; var cp = require("child_process"); var child = cp.spawn(thisProc, [], { detached: true, cwd: dirPath.slice(0, -1), stdio: ["ignore", "ignore", "ignore"] }); child.unref(); } catch (e) { conosle.log(e); } g_scriptReport = Object(); } else g_scriptReport = Object(); } } function realtimeRoster() { var now = timeNowSec(); g_day = now / 86400; if (g_rosterSettings.realtime == false) return; var timeCols = document.getElementsByClassName("timeCol"); for (var x in timeCols) { if (typeof timeCols[x].id != "undefined") { var when = now - callRoster[timeCols[x].id.substr(2)].callObj.age; timeCols[x].innerHTML = when.toDHMS(); } } var lifeCols = document.getElementsByClassName("lifeCol"); for (var x in lifeCols) { if (typeof lifeCols[x].id != "undefined") { var when = now - callRoster[lifeCols[x].id.substr(2)].callObj.life; lifeCols[x].innerHTML = when.toDHMS(); } } if (g_rosterSettings.columns.Spot) { var spotCols = document.getElementsByClassName("spotCol"); for (var x in spotCols) { if (typeof spotCols[x].id != "undefined") { spotCols[x].innerHTML = getSpotString( callRoster[spotCols[x].id.substr(2)].callObj ); if (g_rosterSettings.onlySpot && spotCols[x].innerHTML == "") { viewRoster(); return; } } } } } function getSpotString(callObj) { var result = ""; if (callObj.spot && callObj.spot.when > 0) { when = timeNowSec() - callObj.spot.when; if (when <= window.opener.g_receptionSettings.viewHistoryTimeSec) { result = parseInt(when).toDHMS(); } } if (result) result += " / " + callObj.spot.snr; return result; } function openChatToCid(cid) { window.opener.showMessaging(true, cid); } function initiateQso(thisHash) { window.opener.initiateQso(thisHash); } function callLookup(thisHash, grid) { window.opener.startLookup( callRoster[thisHash].DEcall, callRoster[thisHash].grid ); } function callingLookup(thisHash, grid) { var thisCall = callRoster[thisHash].DXcall; window.opener.startLookup(thisCall, grid); } function callGenMessage(thisHash, grid) { var thisCall = callRoster[thisHash].DEcall; var instance = callRoster[thisHash].callObj.instance; window.opener.startGenMessages(thisCall, grid, instance); } function callingGenMessage(thisHash, grid) { var thisCall = callRoster[thisHash].DXcall; var instance = callRoster[thisHash].callObj.instance; window.opener.startGenMessages(thisCall, grid, instance); } function centerOn(grid) { window.opener.centerOn(grid); } function instanceChange(what) { window.opener.g_instances[what.id].crEnable = what.checked; window.opener.goProcessRoster(); } function updateInstances() { if (window.opener.g_instancesIndex.length > 1) { var instances = window.opener.g_instances; var worker = ""; var keys = Object.keys(instances).sort(); for (var key in keys) { var inst = keys[key]; var sp = inst.split(" - "); var shortInst = sp[sp.length - 1].substring(0, 18); var color = "blue"; if (instances[inst].open == false) { color = "purple"; } worker += `
` + ` ${shortInst}
` } instancesDiv.innerHTML = worker; instancesWrapper.style.display = ""; } else { instancesDiv.innerHTML = ""; instancesWrapper.style.display = "none"; } } function processStatus(newMessage) { if (newMessage.Transmitting == 0) { // Not Transmitting if (newMessage.Decoding == 1) { // Decoding txrxdec.style.backgroundColor = "Blue"; txrxdec.style.borderColor = "Cyan"; txrxdec.innerHTML = "DECODE"; } else { txrxdec.style.backgroundColor = "Green"; txrxdec.style.borderColor = "GreenYellow"; txrxdec.innerHTML = "RECEIVE"; } } else { txrxdec.style.backgroundColor = "Red"; txrxdec.style.borderColor = "Orange"; txrxdec.innerHTML = "TRANSMIT"; } } function toTitleCase(str) { return str.replace(/\w\S*/g, function (txt) { return txt.charAt(0).toUpperCase() + txt.substr(1).toLowerCase(); }); } function newOption(value, text) { if (typeof text == "undefined") text = value; var option = document.createElement("option"); option.value = value; option.text = text; return option; } function createSelectOptions( selectElementString, selectNameDefault, forObject, altName = null, defaultValue = null, checkSponsor = null ) { var selector = document.getElementById(selectElementString); selector.innerHTML = ""; var option = document.createElement("option"); option.value = defaultValue; option.text = selectNameDefault; option.selected = true; option.disabled = true; option.style.display = "none"; selector.appendChild(option); var obj = null; if (forObject) { obj = Object.keys(forObject).sort(); } for (var k in obj) { var opt = obj[k]; var option = document.createElement("option"); option.value = opt; option.text = altName ? forObject[opt][altName] : opt; if (checkSponsor && opt + "-" + checkSponsor in g_awardTracker) { option.disabled = true; } selector.appendChild(option); } } function awardSponsorChanged() { awardName.style.display = ""; createSelectOptions( "awardName", "Select Award", g_awards[awardSponsor.value].awards, "name", null, awardSponsor.value ); } function awardNameChanged() { var awardToAdd = newAwardTrackerObject( awardSponsor.value, awardName.value, true ); var hash = awardToAdd.name + "-" + awardToAdd.sponsor; if (!(hash in g_awardTracker)) { g_awardTracker[hash] = awardToAdd; storeAwardTracker(); processAward(hash); updateAwardList(hash); window.opener.goProcessRoster(); } createSelectOptions( "awardName", "Select Award", g_awards[awardToAdd.sponsor].awards, "name", null, awardToAdd.sponsor ); } function updateAwardList(target = null) { var worker = ""; worker += ""; worker += ""; worker += ""; worker += ""; worker += ""; worker += ""; worker += "
"; worker += "Name"; worker += ""; worker += "Award"; worker += ""; worker += "Track"; worker += ""; worker += ""; worker += "
"; AwardWantedList.innerHTML = worker; var keys = Object.keys(g_awardTracker).sort(); for (var key in keys) { var award = g_awardTracker[keys[key]]; var rule = g_awards[award.sponsor].awards[award.name].rule; var row = awardTable.insertRow(); row.id = keys[key]; var baseAward = false; var baseCount = 0; var endorseCount = 0; var endorseTotal = 0; var allEndorse = false; var tooltip = g_awards[award.sponsor].awards[award.name].tooltip + " (" + g_awards[award.sponsor].sponsor + ")\n"; tooltip += toTitleCase(award.test.qsl_req) + " QSO\n"; for (var mode in award.comp.counts) { tooltip += mode + "\n"; for (var count in award.comp.counts[mode]) { endorseTotal++; if (award.comp.counts[mode][count].per == 100) { baseAward = true; endorseCount++; } if (award.comp.counts[mode][count].num > baseCount) { baseCount = award.comp.counts[mode][count].num; } tooltip += "\t" + award.comp.counts[mode][count].num + "/" + count + " (" + award.comp.counts[mode][count].per + "%)\n"; var wrk = ""; if (Object.keys(award.comp.endorse).length > 0) { for (var band in award.comp.endorse[mode]) { endorseTotal++; if (award.comp.endorse[mode][band][count] == true) { endorseCount++; wrk += band + " "; } } } if (wrk.length > 0) { tooltip += "\t\t" + wrk + "\n"; } } } if (baseCount > 0 && endorseCount == endorseTotal) allEndorse = true; var cell = createCellHtml( row, "

" + award.name + " - " + award.sponsor ); cell.style.textAlign = "left"; cell.style.color = "lightblue"; createCellHtml( row, "

" + (allEndorse ? "" : baseAward ? "" : baseCount > 0 ? "" : ""), tooltip ); createCell( row, "enable", award.enable, award.enable, "Toggle Tracking", true ); createCellHtml( row, "

" ); } } function deleteAwardTracker(sender) { var id = sender.parentNode.parentNode.id; delete g_awardTracker[id]; storeAwardTracker(); resetAwardAdd(); updateAwardList(); window.opener.goProcessRoster(); } function awardCheckboxChanged(sender) { var awardId = sender.target.parentNode.parentNode.id; g_awardTracker[sender.target.parentNode.parentNode.id][sender.target.name] = sender.target.checked; storeAwardTracker(); window.opener.goProcessRoster(); } function awardValueChanged(sender) { var awardId = sender.target.parentNode.parentNode.id; g_awardTracker[sender.target.parentNode.parentNode.id][sender.target.name] = sender.target.value; storeAwardTracker(); window.opener.goProcessRoster(); } function createCell( row, target, value, data = null, title = null, checkbox = false ) { var cell = row.insertCell(); if (data == null) cell.innerHTML = value; if (title) cell.title = title; if (checkbox) { var x = document.createElement("INPUT"); x.setAttribute("type", "checkbox"); x.checked = value; x.name = target; x.addEventListener("change", awardCheckboxChanged); cell.appendChild(x); } else if (data) { cell.appendChild(createAwardSelector(cell, target, value, data)); } return cell; } function createCellHtml(row, html, title = null) { var cell = row.insertCell(); cell.innerHTML = html; if (title) cell.title = title; return cell; } function createAwardSelector(cell, target, value, forObject) { var selector = document.createElement("select"); selector.name = target; selector.value = value; selector.disabled = forObject.length == 1; selector.style.margin = "0px"; selector.style.padding = "1px"; if (selector.disabled) selector.style.cursor = "auto"; selector.addEventListener("change", awardValueChanged); for (var opt in forObject) { var option = document.createElement("option"); option.value = forObject[opt]; if (option.value == "Phone" || option.value == "CW") option.disabled = true; option.text = forObject[opt]; selector.appendChild(option); } return selector; } function resetAwardAdd() { awardName.style.display = "none"; createSelectOptions("awardName", "Select Award", null); createSelectOptions("awardSponsor", "Select Sponsor", g_awards, "sponsor"); } function openAwardPopup() { awardHunterDiv.style.display = ""; resetAwardAdd(); } function closeAwardPopup() { awardHunterDiv.style.display = "none"; resetAwardAdd(); } function toggleMoreControls() { g_rosterSettings.controlsExtended = !g_rosterSettings.controlsExtended; localStorage.rosterSettings = JSON.stringify(g_rosterSettings); setVisual(); } function setVisual() { huntNeed.style.display = "none"; stateSelect.style.display = "none"; DXCCsSelect.style.display = "none"; if (g_rosterSettings.controls) { if (g_rosterSettings.controlsExtended) { RosterControls.className = "extended"; } else { RosterControls.className = "normal"; } } else { RosterControls.className = "hidden"; } // Award Hunter if (referenceNeed.value == 6) { /* for ( key in g_rosterSettings.wanted ) { document.getElementById(key).checked = true; var t = key.replace("hunt",""); if ( t in g_rosterSettings.columns ) g_rosterSettings.columns[t] = true; } */ HuntModeControls.style.display = "none"; CallsignsControls.style.display = "none"; AwardTrackerControls.style.display = ""; huntingMatrixDiv.style.display = ""; updateAwardList(); } else { for (var key in g_rosterSettings.wanted) { if (document.getElementById(key)) { document.getElementById(key).checked = g_rosterSettings.wanted[key]; } } AwardTrackerControls.style.display = "none"; HuntModeControls.style.display = ""; huntMode.style.display = ""; CallsignsControls.style.display = ""; closeAwardPopup(); if (callsignNeed.value == "all" || callsignNeed.value == "hits") { huntingMatrixDiv.style.display = ""; huntNeed.style.display = ""; huntMode.style.display = "none"; } else { huntingMatrixDiv.style.display = "none"; huntMode.style.display = ""; if ( huntMode.value != "callsign" && huntMode.value != "usstate" && huntMode.value != "dxccs" ) { huntNeed.style.display = ""; } if (huntMode.value == "usstate") { stateSelect.style.display = ""; } if (huntMode.value == "usstates") { huntNeed.style.display = ""; } if (huntMode.value == "dxccs") { DXCCsSelect.style.display = ""; } } } if (wantMaxDT.checked == true) { maxDT.style.display = ""; maxDTView.style.display = ""; } else { maxDT.style.display = "none"; maxDTView.style.display = "none"; } if (wantMinDB.checked == true) { minDb.style.display = ""; minDbView.style.display = ""; } else { minDb.style.display = "none"; minDbView.style.display = "none"; } if (wantMinFreq.checked == true) { minFreq.style.display = ""; minFreqView.style.display = ""; } else { minFreq.style.display = "none"; minFreqView.style.display = "none"; } if (wantMaxFreq.checked == true) { maxFreq.style.display = ""; maxFreqView.style.display = ""; } else { maxFreq.style.display = "none"; maxFreqView.style.display = "none"; } if (useRegex.checked == true) { callsignRegex.style.display = ""; } else { callsignRegex.style.display = "none"; } if (window.opener.g_callsignLookups.lotwUseEnable == true) { usesLoTWDiv.style.display = ""; if (g_rosterSettings.usesLoTW == true) { maxLoTW.style.display = ""; maxLoTWView.style.display = ""; } else { maxLoTW.style.display = "none"; maxLoTWView.style.display = "none"; } } else { usesLoTWDiv.style.display = "none"; maxLoTW.style.display = "none"; maxLoTWView.style.display = "none"; } if (window.opener.g_callsignLookups.eqslUseEnable == true) { useseQSLDiv.style.display = ""; } else useseQSLDiv.style.display = "none"; if (window.opener.g_callsignLookups.oqrsUseEnable == true) { usesOQRSDiv.style.display = ""; } else usesOQRSDiv.style.display = "none"; if (g_rosterSettings.columns.Spot == true) { onlySpotDiv.style.display = ""; } else onlySpotDiv.style.display = "none"; if (g_rosterSettings.callsign == "all" || g_rosterSettings.callsign == "hits") { allOnlyNewDiv.style.display = ""; } else allOnlyNewDiv.style.display = "none"; resize(); } function wantedChanged(element) { g_rosterSettings.wanted[element.id] = element.checked; if (element.checked == true) { var t = element.id.replace("hunt", ""); if (t in g_rosterSettings.columns) { g_rosterSettings.columns[t] = true; for (var i = 0; i < g_menu.items.length; ++i) { if ( typeof g_menu.items[i].checked != "undefined" && g_menu.items[i].label == t ) { g_menu.items[i].checked = true; } } } } writeRosterSettings(); g_scriptReport = Object(); for (var callHash in window.opener.g_callRoster) { window.opener.g_callRoster[callHash].callObj.alerted = false; } window.opener.goProcessRoster(); } function valuesChanged() { setVisual(); g_rosterSettings.callsign = callsignNeed.value; g_rosterSettings.hunting = huntMode.value; g_rosterSettings.huntNeed = huntNeed.value; g_rosterSettings.requireGrid = wantGrid.checked; g_rosterSettings.wantMaxDT = wantMaxDT.checked; g_rosterSettings.wantMinDB = wantMinDB.checked; g_rosterSettings.wantMinFreq = wantMinFreq.checked; g_rosterSettings.wantMaxFreq = wantMaxFreq.checked; maxDTView.innerHTML = g_rosterSettings.maxDT = maxDT.value; minDbView.innerHTML = g_rosterSettings.minDb = minDb.value; minFreqView.innerHTML = g_rosterSettings.minFreq = minFreq.value; maxFreqView.innerHTML = g_rosterSettings.maxFreq = maxFreq.value; g_rosterSettings.maxLoTW = maxLoTW.value; maxLoTWView.innerHTML = g_rosterSettings.maxLoTW < 27 ? Number(g_rosterSettings.maxLoTW).toYM() : ""; g_rosterSettings.maxLoTW = maxLoTW.value; g_rosterSettings.cqOnly = cqOnly.checked; g_rosterSettings.noMyDxcc = noMyDxcc.checked; g_rosterSettings.onlyMyDxcc = onlyMyDxcc.checked; if ( noMsg.checked && onlyMsg.checked && noMsgValue.value == onlyMsgValue.value ) { if (g_rosterSettings.noMsg) noMsg.checked = false; else onlyMsg.checked = false; } g_rosterSettings.noMsg = noMsg.checked; g_rosterSettings.onlyMsg = onlyMsg.checked; g_rosterSettings.noMsgValue = noMsgValue.value; g_rosterSettings.onlyMsgValue = onlyMsgValue.value; g_rosterSettings.usesLoTW = usesLoTW.checked; g_rosterSettings.useseQSL = useseQSL.checked; g_rosterSettings.usesOQRS = usesOQRS.checked; g_rosterSettings.onlySpot = onlySpot.checked; g_rosterSettings.reference = referenceNeed.value; g_rosterSettings.allOnlyNew = allOnlyNew.checked; g_rosterSettings.useRegex = useRegex.checked; g_rosterSettings.callsignRegex = callsignRegex.value; writeRosterSettings(); g_scriptReport = Object(); for (var callHash in window.opener.g_callRoster) { window.opener.g_callRoster[callHash].callObj.alerted = false; } window.opener.goProcessRoster(); } function getBuffer(file_url, callback, flag, mode, port, cookie) { var url = require("url"); var http = require(mode); var fileBuffer = null; var options = null; if (cookie != null) { options = { host: url.parse(file_url).host, // eslint-disable-line node/no-deprecated-api port: port, path: url.parse(file_url).path, // eslint-disable-line node/no-deprecated-api headers: { Cookie: cookie } }; } else { options = { host: url.parse(file_url).host, // eslint-disable-line node/no-deprecated-api port: port, path: url.parse(file_url).path // eslint-disable-line node/no-deprecated-api }; } http.get(options, function (res) { var fsize = res.headers["content-length"]; var cookies = null; if (typeof res.headers["set-cookie"] != "undefined") { cookies = res.headers["set-cookie"]; } res .on("data", function (data) { if (fileBuffer == null) fileBuffer = data; else fileBuffer += data; }) .on("end", function () { if (typeof callback === "function") { // Call it, since we have confirmed it is callable callback(fileBuffer, flag, cookies); } }) .on("error", function () {}); }); } function callsignResult(buffer, flag) { var rawData = JSON.parse(buffer); r_currentUSState = flag; g_currentUSCallsigns = Object(); for (var key in rawData.c) g_currentUSCallsigns[rawData.c[key]] = true; window.opener.goProcessRoster(); } function stateChangedValue(what) { if (r_currentUSState != stateSelect.value && stateSelect.value != "") { r_currentUSState = stateSelect.value; if (window.opener.g_mapSettings.offlineMode == false) { var callState = r_currentUSState.replace("CN-", ""); getBuffer( "http://app.gridtracker.org/callsigns/" + callState + ".callsigns.json", callsignResult, r_currentUSState, "http", 80 ); } else { window.opener.goProcessRoster(); r_currentUSState = ""; g_currentUSCallsigns = null; stateSelect.value = ""; return; } } if (stateSelect.value == "") { r_currentUSState = ""; g_currentUSCallsigns = null; window.opener.goProcessRoster(); } } function DXCCsChangedValue(what) { r_currentDXCCs = DXCCsSelect.value; window.opener.goProcessRoster(); } function initDXCCSelector() { var items = Object.keys(window.opener.g_dxccToAltName).sort(function (a, b) { return window.opener.g_dxccToAltName[a].localeCompare( window.opener.g_dxccToAltName[b] ); }); var newSelect = document.getElementById("DXCCsSelect"); for (var i in items) { var key = items[i]; if ( window.opener.g_worldGeoData[window.opener.g_dxccToGeoData[key]].geo != "deleted" ) { var option = document.createElement("option"); option.value = key; option.text = window.opener.g_dxccToAltName[key] + " (" + window.opener.g_worldGeoData[window.opener.g_dxccToGeoData[key]].pp + ")"; newSelect.appendChild(option); } } newSelect.oninput = DXCCsChangedValue; } function manifestResult(buffer, flag) { r_callsignManifest = JSON.parse(buffer); var newSelect = document.getElementById("stateSelect"); for (var key in r_callsignManifest.cnt) { var option = document.createElement("option"); if (window.opener.g_enums[key]) { option.value = key; option.text = window.opener.g_enums[key]; } else { option.value = "CN-" + key; option.text = window.opener.g_enums["CN-" + key]; } newSelect.appendChild(option); } newSelect.oninput = stateChangedValue; } function receiveMessage(event) {} var g_tracker = {}; function updateWorked() { g_worked = window.opener.g_tracker.worked; g_confirmed = window.opener.g_tracker.confirmed; g_modes = window.opener.g_modes; g_modes_phone = window.opener.g_modes_phone; g_tracker = window.opener.g_tracker; processAllAwardTrackers(); } function deleteCallsignIgnore(key) { delete g_blockedCalls[key]; storeBlocks(); openIgnoreEdit(); window.opener.goProcessRoster(); } function deleteDxccIgnore(key) { delete g_blockedDxcc[key]; storeBlocks(); openIgnoreEdit(); window.opener.goProcessRoster(); } function deleteCQIgnore(key) { delete g_blockedCQ[key]; storeBlocks(); openIgnoreEdit(); window.opener.goProcessRoster(); } function clearAllCallsignIgnores() { g_blockedCalls = Object(); storeBlocks(); openIgnoreEdit(); window.opener.goProcessRoster(); } function clearAllDxccIgnores() { g_blockedDxcc = Object(); storeBlocks(); openIgnoreEdit(); window.opener.goProcessRoster(); } function clearAllCQIgnores() { g_blockedCQ = Object(); storeBlocks(); openIgnoreEdit(); window.opener.goProcessRoster(); } function closeEditIgnores() { MainCallRoster.style.display = "block"; editView.style.display = "none"; } function openIgnoreEdit() { MainCallRoster.style.display = "none"; editView.style.display = "inline-block"; var worker = ""; var clearString = "none"; if (Object.keys(g_blockedCalls).length > 0) { clearString = "Clear All"; } worker += "

" + clearString + ""; Object.keys(g_blockedCalls) .sort() .forEach(function (key, i) { worker += ""; }); worker += "
Callsigns
" + key + "
"; clearString = "none"; if (Object.keys(g_blockedCQ).length > 0) { clearString = "Clear All"; } worker += "
" + clearString + ""; Object.keys(g_blockedCQ) .sort() .forEach(function (key, i) { worker += ""; }); worker += "
CQ
" + key + "
"; clearString = "none"; if (Object.keys(g_blockedDxcc).length > 0) { clearString = "Clear All"; } worker += "
" + clearString + ""; Object.keys(g_blockedDxcc) .sort() .forEach(function (key, i) { worker += ""; }); worker += "
DXCCs
" + window.opener.g_dxccToAltName[key] + " (" + window.opener.g_worldGeoData[window.opener.g_dxccToGeoData[key]].pp + ")
"; editTables.innerHTML = worker; } function onMyKeyDown(event) { if (!g_regFocus) { window.opener.onMyKeyDown(event); } } function checkForEnter(ele) { if (event.key === "Enter") { ele.blur(); } } function resize() { if (editView.style.display == "inline-block") openIgnoreEdit(); window.opener.goProcessRoster(); } function init() { g_callsignDatabaseDXCC = window.opener.g_callsignDatabaseDXCC; g_callsignDatabaseUS = window.opener.g_callsignDatabaseUS; g_callsignDatabaseUSplus = window.opener.g_callsignDatabaseUSplus; loadAwardJson(); updateWorked(); // addAllAwards(); window.addEventListener("message", receiveMessage, false); lockNewWindows(); if (window.opener.g_mapSettings.offlineMode == false) { getBuffer( "http://app.gridtracker.org/callsigns/manifest.json", manifestResult, null, "http", 80 ); } loadSettings(); window.opener.setRosterSpot(g_rosterSettings.columns.Spot); for (var key in g_rosterSettings.wanted) { if (document.getElementById(key)) { document.getElementById(key).checked = g_rosterSettings.wanted[key]; } } g_menu = new nw.Menu(); g_compactMenu = new nw.Menu(); var item = new nw.MenuItem({ type: "normal", label: g_rosterSettings.controls ? "Hide Controls" : "Show Controls", click: function () { if (this.label == "Hide Controls") { this.label = "Show Controls"; g_rosterSettings.controls = false; } else { this.label = "Hide Controls"; g_rosterSettings.controls = true; } g_compactMenu.items[0].label = g_rosterSettings.controls ? "Hide Controls" : "Show Controls"; localStorage.rosterSettings = JSON.stringify(g_rosterSettings); setVisual(); } }); g_menu.append(item); item = new nw.MenuItem({ type: "normal", label: g_rosterSettings.controls ? "Hide Controls" : "Show Controls", click: function () { if (this.label == "Hide Controls") { this.label = "Show Controls"; g_rosterSettings.controls = false; } else { this.label = "Hide Controls"; g_rosterSettings.controls = true; } g_menu.items[0].label = g_rosterSettings.controls ? "Hide Controls" : "Show Controls"; localStorage.rosterSettings = JSON.stringify(g_rosterSettings); setVisual(); } }); g_compactMenu.append(item); item = new nw.MenuItem({ type: "normal", label: "Compact Mode", click: function () { g_rosterSettings.compact = true; localStorage.rosterSettings = JSON.stringify(g_rosterSettings); resize(); } }); g_menu.append(item); item = new nw.MenuItem({ type: "normal", label: "Roster Mode", click: function () { g_rosterSettings.compact = false; localStorage.rosterSettings = JSON.stringify(g_rosterSettings); resize(); } }); g_compactMenu.append(item); g_callMenu = new nw.Menu(); item = new nw.MenuItem({ type: "normal", label: "Lookup", click: function () { callLookup(g_targetHash, ""); } }); g_callMenu.append(item); item = new nw.MenuItem({ type: "normal", label: "Gen Msgs", click: function () { callGenMessage(g_targetHash, ""); } }); g_callMenu.append(item); item = new nw.MenuItem({ type: "separator" }); g_callMenu.append(item); item = new nw.MenuItem({ type: "normal", label: "Ignore Call", click: function () { var thisCall = callRoster[g_targetHash].DEcall; g_blockedCalls[thisCall] = true; storeBlocks(); window.opener.goProcessRoster(); } }); g_callMenu.append(item); g_callingMenu = new nw.Menu(); item = new nw.MenuItem({ type: "normal", label: "Lookup", click: function () { callingLookup(g_targetHash, ""); } }); g_callingMenu.append(item); item = new nw.MenuItem({ type: "normal", label: "Gen Msgs", click: function () { callingGenMessage(g_targetHash, ""); } }); g_callingMenu.append(item); item = new nw.MenuItem({ type: "separator" }); g_menu.append(item); item = new nw.MenuItem({ type: "checkbox", label: "Realtime", checked: g_rosterSettings.realtime, click: function () { g_rosterSettings.realtime = this.checked; writeRosterSettings(); window.opener.goProcessRoster(); } }); g_menu.append(item); item = new nw.MenuItem({ type: "separator" }); g_menu.append(item); for (var key in g_rosterSettings.columns) { var itemx = new nw.MenuItem({ type: "checkbox", label: key, checked: g_rosterSettings.columns[key], click: function () { g_rosterSettings.columns[this.label] = this.checked; if (this.label == "Spot") { window.opener.setRosterSpot(g_rosterSettings.columns.Spot); } writeRosterSettings(); window.opener.goProcessRoster(); resize(); } }); g_menu.append(itemx); } item = new nw.MenuItem({ type: "separator" }); g_menu.append(item); g_clearIgnores = new nw.MenuItem({ type: "normal", label: "Clear Call Ignore", enabled: false, click: function () { g_blockedCalls = Object(); storeBlocks(); window.opener.goProcessRoster(); } }); g_menu.append(g_clearIgnores); g_clearIgnoresCall = new nw.MenuItem({ type: "normal", label: "Clear Ignore", enabled: false, click: function () { g_blockedCalls = Object(); storeBlocks(); window.opener.goProcessRoster(); } }); g_callMenu.append(g_clearIgnoresCall); g_CQMenu = new nw.Menu(); item = new nw.MenuItem({ type: "normal", label: "Ignore CQ from DXCC", click: function () { g_blockedCQ[ callRoster[g_targetCQ].DXcall + " from " + window.opener.g_dxccToAltName[callRoster[g_targetCQ].callObj.dxcc] ] = true; storeBlocks(); window.opener.goProcessRoster(); } }); g_CQMenu.append(item); item = new nw.MenuItem({ type: "normal", label: "Ignore CQ from All", click: function () { g_blockedCQ[callRoster[g_targetCQ].DXcall + " from All"] = true; storeBlocks(); window.opener.goProcessRoster(); } }); g_CQMenu.append(item); g_clearCQIgnoreMainMenu = new nw.MenuItem({ type: "normal", label: "Clear CQ Ignore", enabled: false, click: function () { g_blockedCQ = Object(); storeBlocks(); window.opener.goProcessRoster(); } }); g_menu.append(g_clearCQIgnoreMainMenu); g_clearCQIgnore = new nw.MenuItem({ type: "normal", label: "Clear Ignore", enabled: false, click: function () { g_blockedCQ = Object(); storeBlocks(); window.opener.goProcessRoster(); } }); g_CQMenu.append(g_clearCQIgnore); item = new nw.MenuItem({ type: "normal", label: "Edit Ignores", enabled: true, click: function () { openIgnoreEdit(); } }); g_CQMenu.append(item); g_dxccMenu = new nw.Menu(); item = new nw.MenuItem({ type: "normal", label: "Ignore DXCC", click: function () { g_blockedDxcc[g_targetDxcc] = true; storeBlocks(); window.opener.goProcessRoster(); } }); g_dxccMenu.append(item); g_clearDxccIgnoreMainMenu = new nw.MenuItem({ type: "normal", label: "Clear DXCC Ignore", enabled: false, click: function () { g_blockedDxcc = Object(); storeBlocks(); window.opener.goProcessRoster(); } }); g_menu.append(g_clearDxccIgnoreMainMenu); g_clearDxccIgnore = new nw.MenuItem({ type: "normal", label: "Clear Ignore", enabled: false, click: function () { g_blockedDxcc = Object(); storeBlocks(); window.opener.goProcessRoster(); } }); g_dxccMenu.append(g_clearDxccIgnore); item = new nw.MenuItem({ type: "normal", label: "Edit Ignores", enabled: true, click: function () { openIgnoreEdit(); } }); g_menu.append(item); item = new nw.MenuItem({ type: "normal", label: "Edit Ignores", enabled: true, click: function () { openIgnoreEdit(); } }); g_callMenu.append(item); item = new nw.MenuItem({ type: "normal", label: "Edit Ignores", enabled: true, click: function () { openIgnoreEdit(); } }); g_dxccMenu.append(item); callsignNeed.value = g_rosterSettings.callsign; huntMode.value = g_rosterSettings.hunting; huntNeed.value = g_rosterSettings.huntNeed; wantGrid.checked = g_rosterSettings.requireGrid; wantMaxDT.checked = g_rosterSettings.wantMaxDT; wantMinDB.checked = g_rosterSettings.wantMinDB; wantMinFreq.checked = g_rosterSettings.wantMinFreq; wantMaxFreq.checked = g_rosterSettings.wantMaxFreq; maxDTView.innerHTML = maxDT.value = g_rosterSettings.maxDT; minDbView.innerHTML = minDb.value = g_rosterSettings.minDb; minFreqView.innerHTML = minFreq.value = g_rosterSettings.minFreq; maxFreqView.innerHTML = maxFreq.value = g_rosterSettings.maxFreq; maxLoTW.value = g_rosterSettings.maxLoTW; maxLoTWView.innerHTML = maxLoTW.value < 27 ? Number(maxLoTW.value).toYM() : ""; cqOnly.checked = g_rosterSettings.cqOnly; noMyDxcc.checked = g_rosterSettings.noMyDxcc; onlyMyDxcc.checked = g_rosterSettings.onlyMyDxcc; noMsg.checked = g_rosterSettings.noMsg; onlyMsg.checked = g_rosterSettings.onlyMsg; noMsgValue.value = g_rosterSettings.noMsgValue; onlyMsgValue.value = g_rosterSettings.onlyMsgValue; usesLoTW.checked = g_rosterSettings.usesLoTW; useseQSL.checked = g_rosterSettings.useseQSL; onlySpot.checked = g_rosterSettings.onlySpot; usesOQRS.checked = g_rosterSettings.usesOQRS; referenceNeed.value = g_rosterSettings.reference; allOnlyNew.checked = g_rosterSettings.allOnlyNew; useRegex.checked = g_rosterSettings.useRegex; callsignRegex.value = g_rosterSettings.callsignRegex; setVisual(); document.addEventListener("keydown", onMyKeyDown, false); initDXCCSelector(); g_timerInterval = setInterval(realtimeRoster, 1000); updateInstances(); } function handleContextMenu(ev) { if (editView.style.display == "inline-block") return false; var mouseX = Math.round(ev.x); var mouseY = Math.round(ev.y); var len = Object.keys(g_blockedCalls).length; if (len > 0) { g_clearIgnores.enabled = true; g_clearIgnores.label = "Clear Call Ignore" + (len > 1 ? "s (" + len + ")" : ""); g_clearIgnoresCall.enabled = true; g_clearIgnoresCall.label = "Clear Ignore" + (len > 1 ? "s (" + len + ")" : ""); } else { g_clearIgnores.label = "Clear Call Ignore"; g_clearIgnores.enabled = false; g_clearIgnoresCall.label = "Clear Ignore"; g_clearIgnoresCall.enabled = false; } len = Object.keys(g_blockedDxcc).length; if (len > 0) { g_clearDxccIgnoreMainMenu.enabled = true; g_clearDxccIgnoreMainMenu.label = "Clear DXCC Ignore" + (len > 1 ? "s (" + len + ")" : ""); g_clearDxccIgnore.enabled = true; g_clearDxccIgnore.label = "Clear Ignore" + (len > 1 ? "s (" + len + ")" : ""); } else { g_clearDxccIgnoreMainMenu.label = "Clear DXCC Ignore"; g_clearDxccIgnoreMainMenu.enabled = false; g_clearDxccIgnore.label = "Clear Ignore"; g_clearDxccIgnore.enabled = false; } len = Object.keys(g_blockedCQ).length; if (len > 0) { g_clearCQIgnoreMainMenu.enabled = true; g_clearCQIgnoreMainMenu.label = "Clear CQ Ignore" + (len > 1 ? "s (" + len + ")" : ""); g_clearCQIgnore.enabled = true; g_clearCQIgnore.label = "Clear Ignore" + (len > 1 ? "s (" + len + ")" : ""); } else { g_clearCQIgnoreMainMenu.label = "Clear CQ Ignore"; g_clearCQIgnoreMainMenu.enabled = false; g_clearCQIgnore.label = "Clear Ignore"; g_clearCQIgnore.enabled = false; } if (typeof ev.target != "undefined") { if (g_developerMode) { if ((ev.target.id === "ShowMoreControlsLink") || (ev.target.id === "ShowFewerControlsLink") || (ev.target.id === "txrxdec")) { // Allow event to bubble up so that NWJS will show the developer menu return true; } } var name = ev.target.getAttribute("name"); if (name == "Callsign") { g_targetHash = ev.target.parentNode.id; g_callMenu.popup(mouseX, mouseY); } else if (name == "Calling") { g_targetHash = ev.target.parentNode.id; g_callingMenu.popup(mouseX, mouseY); } else if (name == "CQ") { if (callRoster[ev.target.parentNode.id].DXcall != "CQ") { g_targetCQ = ev.target.parentNode.id; g_CQMenu.popup(mouseX, mouseY); } } else if (name && name.startsWith("DXCC")) { var dxcca = name.split("("); var dxcc = parseInt(dxcca[1]); g_targetDxcc = dxcc; g_dxccMenu.popup(mouseX, mouseY); } else { if (g_rosterSettings.compact == false) { g_menu.popup(mouseX, mouseY); } else { g_compactMenu.popup(mouseX, mouseY); } } } else { if (g_rosterSettings.compact == false) { g_menu.popup(mouseX, mouseY); } else { g_compactMenu.popup(mouseX, mouseY); } } ev.preventDefault(); return false; } function getTypeFromMode(mode) { if (mode in g_modes) { if (g_modes[mode] == true) return "Digital"; else if (g_modes_phone[mode] == true) return "Phone"; } return ""; } function testAward(awardName, obj, baseHash) { if ( g_awardTracker[awardName].test.dxcc && g_awardTracker[awardName].rule.dxcc.indexOf(obj.dxcc) == -1 ) { return false; } if ( g_awardTracker[awardName].test.mode && g_awardTracker[awardName].rule.mode.indexOf(obj.mode) == -1 ) { return false; } if ( g_awardTracker[awardName].test.band && g_awardTracker[awardName].rule.band.indexOf(obj.band) == -1 ) { return false; } if ( g_awardTracker[awardName].test.DEcall && g_awardTracker[awardName].rule.call.indexOf(obj.DEcall) == -1 ) { return false; } if ( g_awardTracker[awardName].test.cont && g_awardTracker[awardName].rule.cont.indexOf(obj.cont) == -1 ) { return false; } if ( g_awardTracker[awardName].test.prop && g_awardTracker[awardName].rule.propMode != obj.propMode ) { return false; } if ( g_awardTracker[awardName].test.sat && g_awardTracker[awardName].rule.satName.indexOf(obj.satName) == -1 ) { return false; } return g_awardTypes[g_awardTracker[awardName].rule.type].test( g_awardTracker[awardName], obj, baseHash ); } function processAward(awardName) { var award = g_awards[g_awardTracker[awardName].sponsor].awards[ g_awardTracker[awardName].name ]; g_awardTracker[awardName].rule = award.rule; var test = (g_awardTracker[awardName].test = {}); var mode = award.rule.mode.slice(); var Index = mode.indexOf("Mixed"); if (Index > -1) mode.splice(Index, 1); Index = mode.indexOf("Digital"); if (Index > -1) mode.splice(Index, 1); Index = mode.indexOf("Phone"); if (Index > -1) mode.splice(Index, 1); test.mode = mode.length > 0; test.confirmed = "qsl_req" in g_awards[g_awardTracker[awardName].sponsor].awards[ g_awardTracker[awardName].name ].rule ? g_awards[g_awardTracker[awardName].sponsor].awards[ g_awardTracker[awardName].name ].rule.qsl_req == "confirmed" : g_awards[g_awardTracker[awardName].sponsor].qsl_req == "confirmed"; test.look = "confirmed"; test.qsl_req = "qsl_req" in g_awards[g_awardTracker[awardName].sponsor].awards[ g_awardTracker[awardName].name ].rule ? g_awards[g_awardTracker[awardName].sponsor].awards[ g_awardTracker[awardName].name ].rule.qsl_req : g_awards[g_awardTracker[awardName].sponsor].qsl_req; test.DEcall = "call" in award.rule; test.band = "band" in award.rule && award.rule.band.indexOf("Mixed") == -1; test.dxcc = "dxcc" in award.rule; test.cont = "cont" in award.rule; test.prop = "propMode" in award.rule; test.sat = "satName" in award.rule; g_awardTracker[awardName].stat = {}; for (var i in window.opener.g_QSOhash) { var obj = window.opener.g_QSOhash[i]; if (test.confirmed && !obj.confirmed) continue; if (obj.dxcc < 1) continue; if (test.dxcc && award.rule.dxcc.indexOf(obj.dxcc) == -1) continue; if (test.mode && award.rule.mode.indexOf(obj.mode) == -1) continue; if (test.band && award.rule.band.indexOf(obj.band) == -1) continue; if (test.DEcall && award.rule.call.indexOf(obj.DEcall) == -1) continue; if (test.cont && award.rule.cont.indexOf(obj.cont) == -1) continue; if (test.prop && award.rule.propMode != obj.propMode) continue; if (test.sat && award.rule.satName.indexOf(obj.satName) == -1) continue; g_awardTypes[award.rule.type].score(g_awardTracker[awardName], obj); } g_awardTracker[awardName].comp = g_awardTypes[award.rule.type].compile( g_awardTracker[awardName], g_awardTracker[awardName].stat ); g_awardTracker[awardName].stat = {}; } function newAwardCountObject() { var statCountObject = {}; statCountObject.bands = {}; statCountObject.bands.Mixed = {}; statCountObject.bands.Digital = {}; statCountObject.bands.Phone = {}; statCountObject.modes = {}; statCountObject.modes.Mixed = {}; statCountObject.modes.Digital = {}; statCountObject.modes.Phone = {}; statCountObject.unique = null; return statCountObject; } function workAwardObject(obj, band, mode, isDigital, isPhone, unique = null) { obj.bands.Mixed[band] = ~~obj.bands.Mixed[band] + 1; if (!(mode in obj.bands)) obj.bands[mode] = {}; obj.bands[mode][band] = ~~obj.bands[mode][band] + 1; obj.modes.Mixed[mode] = ~~obj.modes.Mixed[mode] + 1; if (isDigital) { obj.bands.Digital[band] = ~~obj.bands.Digital[band] + 1; obj.modes.Digital[mode] = ~~obj.modes.Digital[mode] + 1; } if (isPhone) { obj.bands.Phone[band] = ~~obj.bands.Phone[band] + 1; obj.modes.Phone[mode] = ~~obj.modes.Phone[mode] + 1; } if (unique) { if (obj.unique == null) obj.unique = {}; if (!(unique in obj.unique)) obj.unique[unique] = newAwardCountObject(); workAwardObject(obj.unique[unique], band, mode, isDigital, isPhone); } return true; } function buildAwardTypeHandlers() { g_awardTypes = { IOTA: { name: "Islands On The Air" }, call: { name: "Callsign" }, callarea: { name: "Call Area" }, calls2dxcc: { name: "Stations per DXCC" }, cnty: { name: "County" }, cont: { name: "Continents" }, cont5: { name: "5 Continents" }, cont52band: { name: "5 Continents per Band" }, cqz: { name: "CQ Zone" }, dxcc: { name: "DXCC" }, grids: { name: "Grids" }, numsfx: { name: "Call Area + Suffix" }, px: { name: "Prefix" }, pxa: { name: "Prefixes" }, pxplus: { name: "Special Calls" }, sfx: { name: "Suffix" }, states: { name: "States" }, cont2band: { name: "Continents per Band" }, calls2band: { name: "Stations per Band" }, dxcc2band: { name: "DXCC per Band" }, states2band: { name: "States per Band" } }; g_awardTypes.IOTA.score = scoreAIOTA; g_awardTypes.call.score = scoreAcall; g_awardTypes.callarea.score = scoreAcallarea; g_awardTypes.calls2dxcc.score = scoreAcalls2dxcc; g_awardTypes.cnty.score = scoreAcnty; g_awardTypes.cont.score = scoreAcont; g_awardTypes.cont5.score = scoreAcont5; g_awardTypes.cont52band.score = scoreAcont52band; g_awardTypes.cqz.score = scoreAcqz; g_awardTypes.dxcc.score = scoreAdxcc; g_awardTypes.grids.score = scoreAgrids; g_awardTypes.numsfx.score = scoreAnumsfx; g_awardTypes.px.score = scoreApx; g_awardTypes.pxa.score = scoreApxa; g_awardTypes.pxplus.score = scoreApxplus; g_awardTypes.sfx.score = scoreAsfx; g_awardTypes.states.score = scoreAstates; g_awardTypes.cont2band.score = scoreAcont2band; g_awardTypes.calls2band.score = scoreAcalls2band; g_awardTypes.dxcc2band.score = scoreAdxcc2band; g_awardTypes.states2band.score = scoreAstates2band; g_awardTypes.IOTA.test = testAIOTA; g_awardTypes.call.test = testAcall; g_awardTypes.callarea.test = testAcallarea; g_awardTypes.calls2dxcc.test = testAcalls2dxcc; g_awardTypes.cnty.test = testAcnty; g_awardTypes.cont.test = testAcont; g_awardTypes.cont5.test = testAcont5; g_awardTypes.cont52band.test = testAcont52band; g_awardTypes.cqz.test = testAcqz; g_awardTypes.dxcc.test = testAdxcc; g_awardTypes.grids.test = testAgrids; g_awardTypes.numsfx.test = testAnumsfx; g_awardTypes.px.test = testApx; g_awardTypes.pxa.test = testApxa; g_awardTypes.pxplus.test = testApxplus; g_awardTypes.sfx.test = testAsfx; g_awardTypes.states.test = testAstates; g_awardTypes.cont2band.test = testAcont2band; g_awardTypes.calls2band.test = testAcalls2band; g_awardTypes.dxcc2band.test = testAdxcc2band; g_awardTypes.states2band.test = testAstates2band; g_awardTypes.IOTA.compile = singleCompile; g_awardTypes.call.compile = singleCompile; g_awardTypes.callarea.compile = singleCompile; g_awardTypes.calls2dxcc.compile = doubleCompile; g_awardTypes.cnty.compile = singleCompile; g_awardTypes.cont.compile = singleCompile; g_awardTypes.cont5.compile = singleCompile; g_awardTypes.cont52band.compile = doubleCompile; g_awardTypes.cqz.compile = singleCompile; g_awardTypes.dxcc.compile = singleCompile; g_awardTypes.grids.compile = singleCompile; g_awardTypes.numsfx.compile = singleCompile; g_awardTypes.px.compile = singleCompile; g_awardTypes.pxa.compile = singleCompile; g_awardTypes.pxplus.compile = singleCompile; g_awardTypes.sfx.compile = singleCompile; g_awardTypes.states.compile = singleCompile; g_awardTypes.cont2band.compile = doubleCompile; g_awardTypes.calls2band.compile = doubleCompile; g_awardTypes.dxcc2band.compile = doubleCompile; g_awardTypes.states2band.compile = doubleCompile; } function scoreAstates(award, obj) { if (obj.state) { if (!(obj.state in award.stat)) { award.stat[obj.state] = newAwardCountObject(); } return workAwardObject( award.stat[obj.state], obj.band, obj.mode, obj.digital, obj.phone ); } return false; } function testAstates(award, obj, baseHash) { if (obj.state && obj.state + baseHash in g_tracker[award.test.look].state) { return false; } return true; } function scoreAstates2band(award, obj) { if (obj.state) { if (!(obj.band in award.stat)) award.stat[obj.band] = newAwardCountObject(); return workAwardObject( award.stat[obj.band], obj.band, obj.mode, obj.digital, obj.phone, obj.state ); } return false; } function testAstates2band(award, obj, baseHash) { if (obj.state && obj.state + baseHash in g_tracker[award.test.look].state) { return false; } return true; } function scoreAdxcc(award, obj) { if (!(obj.dxcc in award.stat)) award.stat[obj.dxcc] = newAwardCountObject(); return workAwardObject( award.stat[obj.dxcc], obj.band, obj.mode, obj.digital, obj.phone ); } function testAdxcc(award, obj, baseHash) { if (String(obj.dxcc) + baseHash in g_tracker[award.test.look].dxcc) { return false; } return true; } function scoreAcont(award, obj) { if (obj.cont) { var cont = obj.cont; if (cont == "AN") cont = "OC"; if (!(cont in award.stat)) award.stat[cont] = newAwardCountObject(); return workAwardObject( award.stat[cont], obj.band, obj.mode, obj.digital, obj.phone ); } return false; } function testAcont(award, obj, baseHash) { if (obj.cont) { var cont = obj.cont; if (cont == "AN") cont = "OC"; if (cont + baseHash in g_tracker[award.test.look].cont) { return false; } } return true; } function scoreAcont5(award, obj, baseHash) { if (obj.cont) { var cont = obj.cont; if (cont == "NA" || cont == "SA") cont = "AM"; if (cont == "AN") cont = "OC"; if (!(cont in award.stat)) award.stat[cont] = newAwardCountObject(); return workAwardObject( award.stat[cont], obj.band, obj.mode, obj.digital, obj.phone ); } return false; } function testAcont5(award, obj, baseHash) { if (obj.cont) { var cont = obj.cont; if (cont == "NA" || cont == "SA") cont = "AM"; if (cont == "AN") cont = "OC"; if (cont + baseHash in g_tracker[award.test.look].cont) { return false; } } return true; } function scoreAcont2band(award, obj) { if (!(obj.band in award.stat)) award.stat[obj.band] = newAwardCountObject(); return workAwardObject( award.stat[obj.band], obj.band, obj.mode, obj.digital, obj.phone, obj.cont ); } function testAcont2band(award, obj, baseHash) { if (obj.cont) { var cont = obj.cont; if (cont == "AN") cont = "OC"; if (cont + baseHash in g_tracker[award.test.look].cont) { return false; } } return true; } function scoreAcont52band(award, obj) { if (obj.cont) { var cont = obj.cont; if (cont == "NA" || cont == "SA") cont = "AM"; if (cont == "AN") cont = "OC"; if (!(obj.band in award.stat)) award.stat[obj.band] = newAwardCountObject(); return workAwardObject( award.stat[obj.band], obj.band, obj.mode, obj.digital, obj.phone, cont ); } return false; } function testAcont52band(award, obj, baseHash) { if (obj.cont) { var cont = obj.cont; if (cont == "NA" || cont == "SA") cont = "AM"; if (cont == "AN") cont = "OC"; if (cont + baseHash in g_tracker[award.test.look].cont) { return false; } } return true; } function scoreAgrids(award, obj) { if (obj.grid) { var grid = obj.grid.substr(0, 4); if (!(grid in award.stat)) award.stat[grid] = newAwardCountObject(); return workAwardObject( award.stat[grid], obj.band, obj.mode, obj.digital, obj.phone ); } return false; } function testAgrids(award, obj, baseHash) { if (obj.grid && obj.grid + baseHash in g_tracker[award.test.look].grid) { return false; } return true; } function scoreAcnty(award, obj) { if (obj.cnty) { if (!(obj.cnty in award.stat)) award.stat[obj.cnty] = newAwardCountObject(); return workAwardObject( award.stat[obj.cnty], obj.band, obj.mode, obj.digital, obj.phone ); } return false; } function testAcnty(award, obj, baseHash) { if (obj.cnty && obj.cnty + baseHash in g_tracker[award.test.look].cnty) { return false; } return true; } function scoreAcall(award, obj) { var call = obj.DEcall; if (call.indexOf("/") > -1) { if (call.endsWith("/MM")) return false; call = call.replace("/P", "").replace("/R", "").replace("/QRP"); } if (!(call in award.stat)) award.stat[call] = newAwardCountObject(); return workAwardObject( award.stat[call], obj.band, obj.mode, obj.digital, obj.phone ); } function testAcall(award, obj, baseHash) { if (obj.DEcall.indexOf("/") > -1 && obj.DEcall.endsWith("/MM")) return false; if (obj.DEcall + baseHash in g_tracker[award.test.look].call) { return false; } return true; } function scoreAIOTA(award, obj) { if (obj.IOTA) { var test = g_awards[award.sponsor].awards[award.name]; if ("IOTA" in test.rule && test.rule.IOTA.indexOf(obj.IOTA) == -1) { return false; } if (!(obj.IOTA in award.stat)) award.stat[obj.IOTA] = newAwardCountObject(); return workAwardObject( award.stat[obj.IOTA], obj.band, obj.mode, obj.digital, obj.phone ); } return false; } // NO IOTA YET function testAIOTA(award, obj, baseHash) { /* if ( obj.IOTA ) { var test = g_awards[award.sponsor].awards[award.name]; if ( "IOTA" in test.rule && test.rule.IOTA.indexOf(obj.IOTA) == -1 ) return false; } */ return false; } function scoreAcallarea(award, obj) { if (obj.zone != null) { var test = g_awards[award.sponsor].awards[award.name]; if ("zone" in test.rule && test.rule.zone.indexOf(obj.zone) == -1) { return false; } if (!(obj.zone in award.stat)) award.stat[obj.zone] = newAwardCountObject(); return workAwardObject( award.stat[obj.zone], obj.band, obj.mode, obj.digital, obj.phone ); } return false; } function testAcallarea(award, obj, baseHash) { if (obj.zone != null) { var test = g_awards[award.sponsor].awards[award.name]; if ("zone" in test.rule && test.rule.zone.indexOf(obj.zone) == -1) { return false; } } return true; } function scoreApx(award, obj) { if (obj.px) { var test = g_awards[award.sponsor].awards[award.name]; var px = obj.px; if ("px" in test.rule) { px = px.substr(0, test.rule.px[0].length); if (test.rule.px.indexOf(px) == -1) return false; } if (!(px in award.stat)) award.stat[px] = newAwardCountObject(); return workAwardObject( award.stat[px], obj.band, obj.mode, obj.digital, obj.phone ); } return false; } function testApx(award, obj, baseHash) { if (obj.px) { var test = g_awards[award.sponsor].awards[award.name]; var px = obj.px; if ("px" in test.rule) { px = px.substr(0, test.rule.px[0].length); if (test.rule.px.indexOf(px) == -1) return false; } if (String(obj.px) + baseHash in g_tracker[award.test.look].px) { return false; } } return true; } function scoreApxa(award, obj) { if (obj.px) { var test = g_awards[award.sponsor].awards[award.name]; for (var i in test.rule.pxa) { if (test.rule.pxa[i].indexOf(obj.px) > -1) { if (!(i in award.stat)) award.stat[i] = newAwardCountObject(); return workAwardObject( award.stat[i], obj.band, obj.mode, obj.digital, obj.phone ); } } } return false; } function testApxa(award, obj, baseHash) { if (obj.px) { var test = g_awards[award.sponsor].awards[award.name]; for (var i in test.rule.pxa) { if (test.rule.pxa[i].indexOf(obj.px) > -1) { if (String(obj.px) + baseHash in g_tracker[award.test.look].px) { return false; } else { return true; } } } } return false; } function scoreAsfx(award, obj) { var test = g_awards[award.sponsor].awards[award.name]; var suf = obj.DEcall.replace(obj.px, ""); for (var i in test.rule.sfx) { for (var s in test.rule.sfx[i]) { if (suf.indexOf(test.rule.sfx[i][s]) == 0) { if (!(i in award.stat)) award.stat[i] = newAwardCountObject(); return workAwardObject( award.stat[i], obj.band, obj.mode, obj.digital, obj.phone ); } } } return false; } function testAsfx(award, obj, baseHash) { var test = g_awards[award.sponsor].awards[award.name]; var suf = obj.DEcall.replace(obj.px, ""); for (var i in test.rule.sfx) { for (var s in test.rule.sfx[i]) { if (suf.indexOf(test.rule.sfx[i][s]) == 0) { return false; } } } return true; } function scoreAcalls2dxcc(award, obj) { if (!(obj.dxcc in award.stat)) award.stat[obj.dxcc] = newAwardCountObject(); return workAwardObject( award.stat[obj.dxcc], obj.band, obj.mode, obj.digital, obj.phone, obj.DEcall ); } function testAcalls2dxcc(award, obj, baseHash) { if (obj.DEcall + baseHash in g_tracker[award.test.look].call) { return false; } return true; } function scoreAcalls2band(award, obj) { if (!(obj.band in award.stat)) award.stat[obj.band] = newAwardCountObject(); return workAwardObject( award.stat[obj.band], obj.band, obj.mode, obj.digital, obj.phone, obj.DEcall ); } function testAcalls2band(award, obj, baseHash) { if (obj.DEcall + baseHash in g_tracker[award.test.look].call) { return false; } return true; } function scoreAdxcc2band(award, obj) { if (!(obj.band in award.stat)) award.stat[obj.band] = newAwardCountObject(); return workAwardObject( award.stat[obj.band], obj.band, obj.mode, obj.digital, obj.phone, obj.dxcc ); } function testAdxcc2band(award, obj, baseHash) { if (String(obj.dxcc) + baseHash in g_tracker[award.test.look].dxcc) { return false; } return true; } function scoreAcqz(award, obj) { if (obj.cqz) { if (!(obj.cqz in award.stat)) award.stat[obj.cqz] = newAwardCountObject(); return workAwardObject( award.stat[obj.cqz], obj.band, obj.mode, obj.digital, obj.phone ); } return false; } function testAcqz(award, obj, baseHash) { if (obj.cqza) { var x = 0; for (var z in obj.cqza) { if (obj.cqza[z] + baseHash in g_tracker[award.test.look].cqz) x++; } if (obj.cqza.length == x) return false; } return true; } function scoreAnumsfx(award, obj) { var test = g_awards[award.sponsor].awards[award.name]; var px = obj.px.substr(0, obj.px.length - 1); var suf = obj.DEcall.replace(px, ""); suf = suf.substr(0, test.rule.numsfx[0][0].length); for (var i in test.rule.numsfx) { for (var s in test.rule.numsfx[i]) { if (suf.indexOf(test.rule.numsfx[i][s]) == 0) { if (!(i in award.stat)) award.stat[i] = newAwardCountObject(); return workAwardObject( award.stat[i], obj.band, obj.mode, obj.digital, obj.phone ); } } } return false; } function testAnumsfx(award, obj) { var test = g_awards[award.sponsor].awards[award.name]; var px = obj.px.substr(0, obj.px.length - 1); var suf = obj.DEcall.replace(px, ""); suf = suf.substr(0, test.rule.numsfx[0][0].length); for (var i in test.rule.numsfx) { for (var s in test.rule.numsfx[i]) { if (suf.indexOf(test.rule.numsfx[i][s]) == 0) { return false; } } } return true; } function scoreApxplus(award, obj) { var test = g_awards[award.sponsor].awards[award.name]; if (test.rule.pxplus) { for (var i in test.rule.pxplus) { if (obj.DEcall.indexOf(test.rule.pxplus[i]) == 0) { if (!(i in award.stat)) award.stat[i] = newAwardCountObject(); return workAwardObject( award.stat[i], obj.band, obj.mode, obj.digital, obj.phone ); } } } return false; } function testApxplus(award, obj) { var test = g_awards[award.sponsor].awards[award.name]; if (test.rule.pxplus) { for (var i in test.rule.pxplus) { if (obj.DEcall.indexOf(test.rule.pxplus[i]) == 0) { return false; } } } return true; } function loadAwardJson() { g_awards = {}; var fs = require("fs"); if (fs.existsSync("./data/awards.json")) { fileBuf = fs.readFileSync("./data/awards.json"); try { g_awards = JSON.parse(fileBuf); // fs.writeFileSync("./data/awards.json", JSON.stringify(g_awards,null,2)); for (var sp in g_awards) { for (var aw in g_awards[sp].awards) { if (!("unique" in g_awards[sp].awards[aw].rule)) { g_awards[sp].awards[aw].rule.unique = 1; } if (g_awards[sp].awards[aw].rule.band[0] == "Mixed") { g_awards[sp].awards[aw].rule.band.shift(); } if (g_awards[sp].awards[aw].rule.band.length == 0) { g_awards[sp].awards[aw].rule.band = []; for (var key in g_awards[sp].mixed) { g_awards[sp].awards[aw].rule.band.push(g_awards[sp].mixed[key]); } } if ( g_awards[sp].awards[aw].rule.endorse.length == 1 && g_awards[sp].awards[aw].rule.endorse[0] == "Mixed" ) { g_awards[sp].awards[aw].rule.endorse = []; for (var key in g_awards[sp].mixed) { g_awards[sp].awards[aw].rule.endorse.push( g_awards[sp].mixed[key] ); } } } } buildAwardTypeHandlers(); } catch (e) { alert("Core awards.json : " + e); g_awards = {}; } } else alert("Missing core awards.json"); } function processAllAwardTrackers() { for (var tracker in g_awardTracker) { if (!(g_awardTracker[tracker].sponsor in g_awards)) { delete g_awardTracker[tracker]; continue; } if ( !( g_awardTracker[tracker].name in g_awards[g_awardTracker[tracker].sponsor].awards ) ) { delete g_awardTracker[tracker]; continue; } processAward(tracker); } updateAwardList(); } function newAwardTrackerObject(sponsor, award, enable) { var newAward = {}; newAward.sponsor = sponsor; newAward.name = award; newAward.enable = enable; newAward.mode = g_awards[sponsor].awards[award].rule.mode[0]; newAward.band = g_awards[sponsor].awards[award].rule.band[0]; newAward.count = g_awards[sponsor].awards[award].rule.count[0]; newAward.stat = {}; newAward.comp = {}; newAward.test = {}; return newAward; } function addAllAwards() { for (var sponsor in g_awards) { for (var award in g_awards[sponsor].awards) { var awardToAdd = newAwardTrackerObject(sponsor, award, true); var hash = awardToAdd.name + "-" + awardToAdd.sponsor; if (!(hash in g_awardTracker)) { g_awardTracker[hash] = awardToAdd; processAward(hash); storeAwardTracker(); } } } updateAwardList(); window.opener.goProcessRoster(); } function delAllAwards() { g_awardTracker = {}; storeAwardTracker(); updateAwardList(); window.opener.goProcessRoster(); } function newCompileCountObject() { var compileCountObject = {}; compileCountObject.bands = {}; compileCountObject.modes = {}; compileCountObject.endorse = {}; compileCountObject.counts = {}; return compileCountObject; } function singleCompile(award, obj) { var test = g_awards[award.sponsor].awards[award.name]; var rule = test.rule; var comp = newCompileCountObject(); for (var mode in rule.mode) { comp.modes[rule.mode[mode]] = 0; comp.bands[rule.mode[mode]] = {}; for (var band in rule.band) { comp.bands[rule.mode[mode]][rule.band[band]] = 0; } for (var key in obj) { if ( rule.mode[mode] in obj[key].bands && Object.keys(obj[key].bands[rule.mode[mode]]).length ) { comp.modes[rule.mode[mode]] += 1; for (var band in rule.band) { if (rule.band[band] in obj[key].bands[rule.mode[mode]]) { comp.bands[rule.mode[mode]][rule.band[band]] += 1; } } } } } for (var mode in comp.modes) { comp.endorse[mode] = {}; comp.counts[mode] = {}; for (var cnts in rule.count) { comp.counts[mode][rule.count[cnts]] = { num: comp.modes[mode], per: parseInt( Math.min(100, (comp.modes[mode] / rule.count[cnts]) * 100.0) ) }; } for (var endorse in rule.endorse) { comp.endorse[mode][rule.endorse[endorse]] = {}; for (var cnts in rule.count) { comp.endorse[mode][rule.endorse[endorse]][rule.count[cnts]] = comp.bands[mode][rule.endorse[endorse]] >= rule.count[cnts]; } } } return comp; } function doubleCompile(award, firstLevel) { var test = g_awards[award.sponsor].awards[award.name]; var rule = test.rule; for (var k in firstLevel) { firstLevel[k].bands = {}; // firstLevel[k].modes = {}; var obj = singleCompile(award, firstLevel[k].unique); for (var mode in obj.bands) { for (var cnt in test.rule.count) { if (obj.counts[mode][test.rule.count[cnt]].num >= test.rule.unique) { for (var band in obj.bands[mode]) { if (!(mode in firstLevel[k].bands)) firstLevel[k].bands[mode] = {}; if (obj.bands[mode][band] > 0) { firstLevel[k].bands[mode][band] = ~~firstLevel[k].bands[mode][band] + 1; } } } } } /* for ( var mode in obj.modes ) { if ( !(mode in firstLevel[k].modes) ) firstLevel[k].modes[mode] = 0; if ( obj.modes[mode] > 0 ) firstLevel[k].modes[mode] += 1; } */ delete firstLevel[k].unique; firstLevel[k].unique = null; } return singleCompile(award, firstLevel); }