NOTICE: By continued use of this site you understand and agree to the binding Terms of Service and Privacy Policy.
// ==UserScript== // @name 270tools // @namespace https://github.com/eduardog3000 // @version 0.3 // @description Tool for 270 to Win Presidential Map. Can remove states, grant statehood to territories, and change the number of senators and house reps (and therefore total electoral votes). // @author eduardog3000 // @license 0BSD // @match https://www.270towin.com/ // @grant GM_getResourceText // @require https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js // @require https://cdnjs.cloudflare.com/ajax/libs/floatthead/2.1.2/jquery.floatThead.js // @require https://cdn.datatables.net/1.10.19/js/jquery.dataTables.min.js // @resource dataTableCSS https://cdn.datatables.net/1.10.18/css/jquery.dataTables.min.css // ==/UserScript== (function() { 'use strict'; function addGlobalStyle(css) { var head, style; head = document.getElementsByTagName('head')[0]; if (!head) { return; } style = document.createElement('style'); style.type = 'text/css'; style.innerHTML = css.replace(/;/g, ' !important;'); head.appendChild(style); } addGlobalStyle(GM_getResourceText('dataTableCSS')); addGlobalStyle(` #territories { width: 50% !important; } thead { background: white; } .cell-center { text-align: center; } .pop { text-align: right; } #DC-name { display: none; font-family: inherit; font-size: inherit; padding: none; width: 95%; } /* #a23-extra { display: none; } */ #custom-abbr { width: 25px; } #custom-census, #custom-est { width: 75px; appearance: textfield; -moz-appearance: textfield; -webkit-appearance: textfield; } .settings-modal-hidden { display: none; } .settings-modal-shown { display: block; } #settings-modal { position: fixed; z-index: 1001; left: 0; top: 0; width: 100%; /* Full width */ height: 100%; /* Full height */ overflow: auto; /* Enable scroll if needed */ background-color: rgb(0,0,0); /* Fallback color */ background-color: rgba(0,0,0,0.4); /* Black w/ opacity */ } #settings { background-color: #fefefe; margin: 15% auto; /* 15% from the top and centered */ padding: 20px; border: 1px solid #888; width: 80%; /* Could be more or less, depending on screen size */ } /* The Close Button */ .close { color: #aaa; float: right; font-size: 28px; font-weight: bold; } .close:hover, .close:focus { color: black; text-decoration: none; cursor: pointer; } `); String.prototype.formatUnicorn = function() { //"use strict"; var str = this.toString(); if(arguments.length) { var t = typeof arguments[0]; var key; var args = ("string" === t || "number" === t) ? Array.prototype.slice.call(arguments) : arguments[0]; for(key in args) { str = str.replace(new RegExp("\\{" + key + "\\}", "gi"), args[key]); } } return str; }; var territories = [ {abbr: 'AL', name: 'Alabama', fips: '01', pro: 4918973, est: 4874747, census: 4780127, is_state: true, current_ev: 9}, {abbr: 'AK', name: 'Alaska', fips: '02', pro: 753900, est: 739795, census: 710249, is_state: true, current_ev: 3}, {abbr: 'AS', name: 'American Samoa', fips: '03', pro: 55519, est: 55519, census: 55519, is_state: false, current_ev: 0}, {abbr: 'AZ', name: 'Arizona', fips: '04', pro: 7330167, est: 7016270, census: 6392307, is_state: true, current_ev: 11}, {abbr: 'AR', name: 'Arkansas', fips: '05', pro: 3045986, est: 3004279, census: 2915958, is_state: true, current_ev: 6}, {abbr: 'CA', name: 'California', fips: '06', pro: 40646714, est: 39536653, census: 37252895, is_state: true, current_ev: 55}, {abbr: 'CO', name: 'Colorado', fips: '08', pro: 5902421, est: 5607154, census: 5029324, is_state: true, current_ev: 9}, {abbr: 'CT', name: 'Connecticut', fips: '09', pro: 3594666, est: 3588184, census: 3574118, is_state: true, current_ev: 7}, {abbr: 'DE', name: 'Delaware', fips: '10', pro: 993365, est: 961939, census: 897936, is_state: true, current_ev: 3}, {abbr: 'DC', name: 'District of Columbia', fips: '11', pro: 742708, est: 693972, census: 601767, is_state: false, current_ev: 3}, {abbr: 'FL', name: 'Florida', fips: '12', pro: 22099273, est: 20984400, census: 18804623, is_state: true, current_ev: 29}, {abbr: 'GA', name: 'Georgia', fips: '13', pro: 10794819, est: 10429379, census: 9688681, is_state: true, current_ev: 16}, {abbr: 'GU', name: 'Guam', fips: '14', pro: 159358, est: 159358, census: 159358, is_state: false, current_ev: 0}, {abbr: 'HI', name: 'Hawaii', fips: '15', pro: 1459878, est: 1427538, census: 1360301, is_state: true, current_ev: 4}, {abbr: 'ID', name: 'Idaho', fips: '16', pro: 1791884, est: 1716943, census: 1567652, is_state: true, current_ev: 4}, {abbr: 'IL', name: 'Illinois', fips: '17', pro: 12788504, est: 12802023, census: 12831549, is_state: true, current_ev: 20}, {abbr: 'IN', name: 'Indiana', fips: '18', pro: 6752879, est: 6666818, census: 6484229, is_state: true, current_ev: 11}, {abbr: 'IA', name: 'Iowa', fips: '19', pro: 3192483, est: 3145711, census: 3046869, is_state: true, current_ev: 6}, {abbr: 'KS', name: 'Kansas', fips: '20', pro: 2941197, est: 2913123, census: 2853132, is_state: true, current_ev: 6}, {abbr: 'KY', name: 'Kentucky', fips: '21', pro: 4508217, est: 4454189, census: 4339349, is_state: true, current_ev: 8}, {abbr: 'LA', name: 'Louisiana', fips: '22', pro: 4755775, est: 4684333, census: 4533479, is_state: true, current_ev: 8}, {abbr: 'ME', name: 'Maine', fips: '23', pro: 1339385, est: 1335907, census: 1328361, is_state: true, current_ev: 4}, {abbr: 'MD', name: 'Maryland', fips: '24', pro: 6185926, est: 6052177, census: 5773785, is_state: true, current_ev: 10}, {abbr: 'MA', name: 'Massachusetts', fips: '25', pro: 7009634, est: 6859819, census: 6547817, is_state: true, current_ev: 11}, {abbr: 'MI', name: 'Michigan', fips: '26', pro: 9998426, est: 9962311, census: 9884129, is_state: true, current_ev: 16}, {abbr: 'MN', name: 'Minnesota', fips: '27', pro: 5708010, est: 5576606, census: 5303925, is_state: true, current_ev: 10}, {abbr: 'MS', name: 'Mississippi', fips: '28', pro: 2991471, est: 2984100, census: 2968103, is_state: true, current_ev: 6}, {abbr: 'MO', name: 'Missouri', fips: '29', pro: 6171833, est: 6113532, census: 5988927, is_state: true, current_ev: 10}, {abbr: 'MT', name: 'Montana', fips: '30', pro: 1080214, est: 1050493, census: 989417, is_state: true, current_ev: 3}, {abbr: 'NE', name: 'Nebraska', fips: '31', pro: 1965243, est: 1920076, census: 1826341, is_state: true, current_ev: 5}, {abbr: 'NV', name: 'Nevada', fips: '32', pro: 3149328, est: 2998039, census: 2700691, is_state: true, current_ev: 6}, {abbr: 'NH', name: 'New Hampshire', fips: '33', pro: 1355104, est: 1342795, census: 1316466, is_state: true, current_ev: 4}, {abbr: 'NJ', name: 'New Jersey', fips: '34', pro: 9105974, est: 9005644, census: 8791936, is_state: true, current_ev: 14}, {abbr: 'NM', name: 'New Mexico', fips: '35', pro: 2101491, est: 2088070, census: 2059192, is_state: true, current_ev: 5}, {abbr: 'NY', name: 'New York', fips: '36', pro: 20070659, est: 19849399, census: 19378087, is_state: true, current_ev: 29}, {abbr: 'NC', name: 'North Carolina', fips: '37', pro: 10637703, est: 10273419, census: 9535692, is_state: true, current_ev: 15}, {abbr: 'ND', name: 'North Dakota', fips: '38', pro: 798016, est: 755393, census: 672591, is_state: true, current_ev: 3}, {abbr: 'MP', name: 'Northern Mariana Islands', fips: '69', pro: 53883, est: 53883, census: 53883, is_state: false, current_ev: 0}, {abbr: 'OH', name: 'Ohio', fips: '39', pro: 11715063, est: 11658609, census: 11536725, is_state: true, current_ev: 18}, {abbr: 'OK', name: 'Oklahoma', fips: '40', pro: 4016945, est: 3930864, census: 3751616, is_state: true, current_ev: 7}, {abbr: 'OR', name: 'Oregon', fips: '41', pro: 4297264, est: 4142776, census: 3831073, is_state: true, current_ev: 7}, {abbr: 'PA', name: 'Pennsylvania', fips: '42', pro: 12852967, est: 12805537, census: 12702887, is_state: true, current_ev: 20}, {abbr: 'PR', name: 'Puerto Rico', fips: '72', pro: 3337177, est: 3337177, census: 3726157, is_state: false, current_ev: 0}, {abbr: 'RI', name: 'Rhode Island', fips: '44', pro: 1062733, est: 1059639, census: 1052931, is_state: true, current_ev: 4}, {abbr: 'SC', name: 'South Carolina', fips: '45', pro: 5223002, est: 5024369, census: 4625401, is_state: true, current_ev: 9}, {abbr: 'SD', name: 'South Dakota', fips: '46', pro: 896824, est: 869666, census: 814191, is_state: true, current_ev: 3}, {abbr: 'TN', name: 'Tennessee', fips: '47', pro: 6895305, est: 6715984, census: 6346275, is_state: true, current_ev: 11}, {abbr: 'TX', name: 'Texas', fips: '48', pro: 29934070, est: 28304596, census: 25146105, is_state: true, current_ev: 38}, {abbr: 'VI', name: 'U.S. Virgin Islands', fips: '52', pro: 106405, est: 106405, census: 106405, is_state: false, current_ev: 0}, {abbr: 'UT', name: 'Utah', fips: '49', pro: 3275665, est: 3101833, census: 2763888, is_state: true, current_ev: 6}, {abbr: 'VT', name: 'Vermont', fips: '50', pro: 622703, est: 623657, census: 625745, is_state: true, current_ev: 3}, {abbr: 'VA', name: 'Virginia', fips: '51', pro: 8697577, est: 8470020, census: 8001045, is_state: true, current_ev: 13}, {abbr: 'WA', name: 'Washington', fips: '53', pro: 7749587, est: 7405743, census: 6724543, is_state: true, current_ev: 12}, {abbr: 'WV', name: 'West Virginia', fips: '54', pro: 1799160, est: 1815857, census: 1853011, is_state: true, current_ev: 5}, {abbr: 'WI', name: 'Wisconsin', fips: '55', pro: 5846015, est: 5795483, census: 5687289, is_state: true, current_ev: 10}, {abbr: 'WY', name: 'Wyoming', fips: '56', pro: 586638, est: 579315, census: 563767, is_state: true, current_ev: 3}, {abbr: 'EX', name: 'Extra', fips: '99', pro: 0, est: 0, census: 0, is_state: false, current_ev: 0} ]; $('#view_container').css('left', '1000px'); $('#map').append(` <div style="position:absolute;top:430px;left:370px;width:200px"> <table class="unbootstrap" style="float:left" cellspacing="5"> <tbody> <tr> <td id="sp_03" class="map_text sp_state" style="width: 13px; height: 20px; background-color: rgb(187, 170, 144); display: none;">0</td> <td id="sp_14" class="map_text sp_state" style="width: 13px; height: 20px; background-color: rgb(187, 170, 144); display: none;">0</td> <td id="sp_69" class="map_text sp_state" style="width: 13px; height: 20px; background-color: rgb(187, 170, 144); display: none;">0</td> </tr> <tr> <td id="abbr_03" class="map_text" style="text-align:center; display: none;">AS</td> <td id="abbr_14" class="map_text" style="text-align:center; display: none;">GU</td> <td id="abbr_69" class="map_text" style="text-align:center; display: none;">MP</td> </tr> </tbody> </table> <table class="unbootstrap" style="float:right" cellspacing="5"> <tbody> <tr> <td id="sp_72" class="map_text sp_state" style="width: 13px; height: 20px; background-color: rgb(187, 170, 144); display: none;">0</td> <td id="sp_52" class="map_text sp_state" style="width: 13px; height: 20px; background-color: rgb(187, 170, 144); display: none;">0</td> <td id="sp_99" class="map_text sp_state" style="width: 13px; height: 20px; background-color: rgb(187, 170, 144); display: none;">0</td> </tr> <tr> <td id="abbr_72" class="map_text" style="text-align:center; display: none;">PR</td> <td id="abbr_52" class="map_text" style="text-align:center; display: none;">VI</td> <td id="abbr_99" class="map_text" style="text-align:center; display: none;">23<sup>rd</sup></td> </tr> </tbody> </table> </div> `); $("g.states").append(` <path class="state" id="03" fill="#BBAA90"></path> <path class="state" id="14" fill="#BBAA90"></path> <path class="state" id="69" fill="#BBAA90"></path> <path class="state" id="52" fill="#BBAA90"></path> <path class="state" id="99" fill="#BBAA90"></path> `); $("#72").attr("fill", "#BBAA90") m.states['03'] = {"state_abbr":"AS","e_votes":"0","outcome":0,"state_name":"American Samoa"} m.states['14'] = {"state_abbr":"GU","e_votes":"0","outcome":0,"state_name":"Guam"} m.states['69'] = {"state_abbr":"MP","e_votes":"0","outcome":0,"state_name":"Northen Mariana Islands"} m.states['72'] = {"state_abbr":"PR","e_votes":"0","outcome":0,"state_name":"Puerto Rico"} m.states['52'] = {"state_abbr":"VI","e_votes":"0","outcome":0,"state_name":"U.S. Virgin Islands"} m.states['99'] = {"state_abbr":"EX","e_votes":"0","outcome":0,"state_name":"23rd Amendment"} m.specialStates = ["23", "25", "44", "09", "34", "10", "24", "11", "31", "03", "14", "69", "72", "52", "99"]; var ontclick = function() { var state_id = $(this).attr("id").split("_"); m.state_click( state_id[1], state_id[2] ); }; $("#sp_03").click(ontclick); $("#sp_14").click(ontclick); $("#sp_69").click(ontclick); $("#sp_72").click(ontclick); $("#sp_52").click(ontclick); $("#sp_99").click(ontclick); m.update_electoral_votes = function() { if (this.debug == 1) console.log('m.update_electoral_votes()'); var t_total = 0; var i_total = 0; var r_total = 0; var r1_total = 0; var r2_total = 0; var r4_total = 0; var d_total = 0; var d1_total = 0; var d2_total = 0; var d4_total = 0; var t_states = 0; // Number of states undecided var n_states = 0; // Number of states not polled - polling-maps only var n_total = 0; var states = this.states; for (key in states) { if (key != "23" && key != "31") { if (states[key].outcome==0 ) { t_total += parseInt(states[key].e_votes); t_states++; } else if(states[key].outcome==1 ) { d4_total += parseInt(states[key].e_votes); } else if(states[key].outcome==2 ) { r4_total += parseInt(states[key].e_votes); } else if(states[key].outcome==3 ) { d2_total += parseInt(states[key].e_votes); } else if(states[key].outcome==4 ) { r2_total += parseInt(states[key].e_votes); } else if(states[key].outcome==5 ) { d1_total += parseInt(states[key].e_votes); } else if(states[key].outcome==6 ) { r1_total += parseInt(states[key].e_votes); } else if(states[key].outcome==7 ) { i_total += parseInt(states[key].e_votes); } else if(states[key].outcome==9 ) { n_total += parseInt(states[key].e_votes); } } else { for (spec_state in states[key]) { //TODO not sure how to hande this with regard to R270 if (spec_state == "MX" || spec_state == "M3" || spec_state == "M4" || spec_state == "NX" || spec_state == "N3" || spec_state == "N4" || spec_state == "N5") { if (this.debug == 1) console.log(key+"="+spec_state+"="+states[key][spec_state]["outcome"]+"="+states[key][spec_state]["e_votes"]); if (states[key][spec_state]["outcome"] == 0 ) { t_total += parseInt(states[key][spec_state]["e_votes"]); } else if(states[key][spec_state]["outcome"] == 1 ) { d4_total += parseInt(states[key][spec_state]["e_votes"]); } else if(states[key][spec_state]["outcome"] == 2 ) { r4_total += parseInt(states[key][spec_state]["e_votes"]); } else if(states[key][spec_state]["outcome"] == 3 ) { d2_total += parseInt(states[key][spec_state]["e_votes"]); } else if(states[key][spec_state]["outcome"] == 4 ) { r2_total += parseInt(states[key][spec_state]["e_votes"]); } else if(states[key][spec_state]["outcome"] == 5 ) { d1_total += parseInt(states[key][spec_state]["e_votes"]); } else if(states[key][spec_state]["outcome"] == 6 ) { r1_total += parseInt(states[key][spec_state]["e_votes"]); } else if(states[key][spec_state]["outcome"] == 7 ) { i_total += parseInt(states[key][spec_state]["e_votes"]); } else if(states[key][spec_state]["outcome"] == 9 ) { n_total += parseInt(states[key][spec_state]["e_votes"]); } } } } } if (this.colorMode > 1 || d2_total || d1_total || r2_total || r1_total) { $(".hide3").show(); } else { $(".hide3").hide(); } if (d4_total > 9 ) { $("#d4_ev").html(d4_total); $("#d4_color").show(); } else { if (d4_total == 0) { $("#d4_color").hide(); } else { $("#d4_color").show(); $("#d4_ev").html(""); } } if (d2_total > 9 ) { $("#d2_ev").html(d2_total); $("#d2_color").show(); } else { if (d2_total == 0) { $("#d2_color").hide(); } else { $("#d2_color").show(); $("#d2_ev").html(""); } } if (d1_total > 9 ) { $("#d1_ev").html(d1_total); $("#d1_color").show(); } else { if (d1_total == 0) { $("#d1_color").hide(); } else { $("#d1_color").show(); $("#d1_ev").html(""); } } if (t_total > 9 ) { $("#t_color").html(t_total); $("#t_color").show(); } else { if (t_total == 0) { $("#t_color").hide(); } else { $("#t_color").show(); $("#t_color").html(""); } } if (r4_total > 9 ) { $("#r4_ev").html(r4_total); $("#r4_color").show(); } else { if (r4_total == 0) { $("#r4_color").hide(); } else { $("#r4_color").show(); $("#r4_ev").html(""); } } if (r2_total > 9 ) { $("#r2_ev").html(r2_total); $("#r2_color").show(); } else { if (r2_total == 0) { $("#r2_color").hide(); } else { $("#r2_color").show(); $("#r2_ev").html(""); } } if (r1_total > 9 ) { $("#r1_ev").html(r1_total); $("#r1_color").show(); } else { if (r1_total == 0) { $("#r1_color").hide(); } else { $("#r1_color").show(); $("#r1_ev").html(""); } } if (n_total > 9 ) { $("#n_color").html(n_total); $("#n_color").show(); } else { if (n_total == 0) { $("#n_color").hide(); } else { $("#n_color").show(); $("#n_color").html(""); } } if (i_total > 9 ) { $("#i_color").html(i_total); $("#i_color").show(); } else { if (i_total == 0) { $("#i_color").hide(); } else { $("#i_color").show(); $("#i_color").html(""); } } var total_e_votes = 0; for(var i in this.states) { total_e_votes += Number(this.states[i].e_votes); } var to_win = Math.floor((total_e_votes / 2) + 1); //Update Slider d_total = d1_total + d2_total + d4_total; r_total = r1_total + r2_total + r4_total; var d4_width = (d4_total/total_e_votes)*650; var d2_width = (d2_total/total_e_votes)*650; var d1_width = (d1_total/total_e_votes)*650; var r4_width = (r4_total/total_e_votes)*650; var r2_width = (r2_total/total_e_votes)*650; var r1_width = (r1_total/total_e_votes)*650; var t_width = (t_total/total_e_votes)*650; var n_width = (n_total/total_e_votes)*650; var i_width = (i_total/total_e_votes)*650; $("#dem_ev").html(d_total); $("#rep_ev").html(r_total); $("#d4_color").css("width",Math.round(d4_width)+"px"); $("#d2_color").css("width",Math.round(d2_width)+"px"); $("#d1_color").css("width",Math.round(d1_width)+"px"); $("#t_color" ).css("width",Math.round(t_width)+"px"); $("#n_color" ).css("width",Math.round(n_width)+"px"); $("#i_color" ).css("width",Math.round(i_width)+"px"); $("#r1_color").css("width",Math.round(r1_width)+"px"); $("#r2_color").css("width",Math.round(r2_width)+"px"); $("#r4_color").css("width",Math.round(r4_width)+"px"); if (d_total >= to_win) { $("#count_tri_down").attr("src", "/images/blue_triangle.png"); $("#count_tri_up").attr("src", "/images/blue_triangle_up.png"); $('#arrow-top').attr("fill", "#244999"); $('#arrow-bottom').attr("fill", "#244999"); $('#line-270').attr("fill", "#244999"); } else if (r_total >= to_win) { $("#count_tri_down").attr("src","/images/red_triangle.png"); $("#count_tri_up").attr("src", "/images/red_triangle_up.png"); $('#arrow-top').attr("fill", "#D22532"); $('#arrow-bottom').attr("fill", "#D22532"); $('#line-270').attr("fill", "#D22532"); } else if (i_total >= to_win) { $('#arrow-top').attr("fill", "#CCAD29"); $('#arrow-bottom').attr("fill", "#CCAD29"); $('#line-270').attr("fill", "#CCAD29"); } else { $("#count_tri_down").attr("src", "/images/black_triangle.png"); $("#count_tri_up").attr("src", "/images/black_triangle_up.png"); $('#arrow-top').attr("fill", "black"); $('#arrow-bottom').attr("fill", "black"); $('#line-270').attr("fill", "black"); } // D3 slider stuff $("#R_bar").css("width", r_total*1.02+'px'); $("#D_bar").css("width", d_total*1.02+'px'); $("#I_bar").css("width", i_total*1.02+'px'); $("#U_bar").css("width", t_total*1.02+'px'); $("#R_remain").css("width", 548.76 - r_total * 1.02 + 'px'); //275.4 $("#D_remain").css("width", 548.76 - d_total * 1.02 + 'px'); //275.4 $("#I_remain").css("width", 548.76 - i_total * 1.02 + 'px'); //275.4 $("#R_remain").attr("x", r_total * 1.02 + 95); $("#D_remain").attr("x", d_total * 1.02 + 95); $("#I_remain").attr("x", i_total * 1.02 + 95); if (r_total > 19) { $("#R_ev").attr("x", "100px").attr("fill", "white"); } else { $("#R_ev").attr("x", 100 + parseInt(r_total) + "px").attr("fill", "black"); } if (d_total > 19) { $("#D_ev").attr("x", "100px").attr("fill", "white"); } else { $("#D_ev").attr("x", 100 + parseInt(d_total) + "px").attr("fill", "black"); } if (i_total > 19) { $("#I_ev").attr("x", "100px").attr("fill", "white"); } else { $("#I_ev").attr("x", 100 + parseInt(i_total) + "px").attr("fill", "black"); } /* if (t_total > 19) { $("#U_ev").attr("x", "100px").attr("fill", "white"); } else { $("#U_ev").attr("x", 100 + parseInt(t_total) + "px").attr("fill", "black"); }*/ $("#U_ev").attr("x", 100 + "px").attr("fill", "#bbaa90"); if (r_total == 0) $("#R_bar").css('width', '2px'); if (d_total == 0) $("#D_bar").css('width', '2px'); if (i_total == 0) $("#I_bar").css('width', '2px'); if (t_total == 0) $("#U_bar").css('width', '2px'); $("#R_ev").html(r_total); $("#D_ev").html(d_total); $("#I_ev").html(i_total); $("#U_ev").html(t_total); // Road to 270 Stuff if (r_total < 270 && d_total < 270 && t_states <= 12) { if (this.debug == 1) console.log("ROAD TO 270!!!"); } } var settings = $('<div id="settings-modal" class="settings-modal-hidden">').html(` <div id="settings"> <span class="close">Changes apply on close ×</span> <div>Population Data:<label> <input id="census" type="radio" name="pop" value="census" checked />2010 Census</label> <label><input id="est" type="radio" name="pop" value="est" />2017 Estimate</label> <label><input id="pro" type="radio" name="pop" value="pro" /><abbr title="2020 Projection from Election Data Services, based on population changes from 2010 to 2017.">2020 Projection</abbr></label></div> <div><label># of Senators per State: <input id="senators" type="number" value="2" /></label></div> <div><label>Total # of House Reps: <input id="reps" type="number" value="435" /></label></div> <div><label><abbr title="If DC is not a state, this will give DC 3 electoral votes. If DC is a state, but the 23rd Amendment is not repealed, then the state will get its electors, and the 23rd Amendment electors will be allocated in some other way.">23<sup>rd</sup> Amendment</abbr>: <input id="a23" type="checkbox" checked /></label></div> <div><label>Total # of Electors: <input id="ev-total" type="number" value="538" disabled/></label></div> <div><label>Needed to Win: <input id="ev-needed" type="number" value="270" disabled/></label></div> <br /> <table id="territories" class="display cell-border compact"> <thead> <tr> <th>Name</th> <th>Abbr</th> <th class="cell-center">Is State?</th> <th>Census Pop</th> <th>2017 Est. Pop</th> <th>2020 Proj. Pop</th> <th>Electors</th> <th>Current Electors</th> <th>Change</th> </tr> </thead> <tbody> </tbody> <tfoot> <tr id="a23-extra" class="settings-modal-hidden"> <td><abbr title="Since DC is a state, but the 23rd Amendment hasn't been repealed, there are 3 extra Electors to allocate in some other way. One possibility is giving them to the nationwide popular vote winner.">Extra</abbr></td> <td>23<sup>rd</sup></td> <td class="cell-center">N/A</td> <td class="pop">N/A</td> <td class="pop">N/A</td> <td class="pop">N/A</td> <td id="EX-evs" class="cell-center">3</td> <td id="EX-evs-current" class="cell-center">0</td> <td id="EX-evs-change" class="cell-center" style="color: green;">+3</td> </tr> <tr style="display: none;"> <td><input id="custom-name" /></td> <td><input id="custom-abbr" maxlength="2" /></td> <td></td> <td><input id="custom-census" class="pop" type="number" min="1" /></td> <td><input id="custom-est" class="pop" type="number" min="1" /></td> <td><input id="custom-pro" class="pop" type="number" min="1" /></td> <td colspan="3" class="cell-center"><button id="custom-submit">Add</button></td> </tr> <tr> <td>United States of America</td> <td>USA</td> <td class="cell-center">N/A</td> <td class="pop">312,913,872</td> <td class="pop">329,431,520</td> <td class="pop">337,866,086</td> <td id="USA-evs" class="cell-center">538</td> <td id="USA-evs-current" class="cell-center">538</td> <td id="USA-evs-change" class="cell-center">0</td> </tr> </tfoot> </table> </div> `); $('body').append(settings); $('#button_container > div:nth-child(2)').prepend($('<button id="settings_button" class="nice_button">').text('Settings')); var settingsShown = false; function toggleSettings() { if(settingsShown) { $('#settings-modal').addClass('settings-modal-hidden'); $('#settings-modal').removeClass('settings-modal-shown'); } else { $('#settings-modal').addClass('settings-modal-shown'); $('#settings-modal').removeClass('settings-modal-hidden'); } settingsShown = !settingsShown; } $('#settings_button').click(toggleSettings); $('.close').click(function() { toggleSettings(); for(var tt in territories) { var t = territories[tt]; console.log(t.fips); console.log(t.ev); m.states[t.fips].e_votes = t.ev.toString() | 0; if(t.fips == "23") { var atlarge = t.ev >= 4 ? t.ev - 2 : (t.ev == 3 ? 2 : t.ev); m.states[t.fips].MX.e_votes = atlarge; $('#sp_23_1').text('ME ' + atlarge); if(t.ev >= 4) { $('#sp_23_4').text('1'); m.states[t.fips].M4.e_votes = 1; } else { $('#sp_23_4').text('0'); m.states[t.fips].M4.e_votes = 0; } if(t.ev >= 3) { $('#sp_23_3').text('1'); m.states[t.fips].M3.e_votes = 1; } else { $('#sp_23_3').text('0'); m.states[t.fips].M3.e_votes = 0; } $(`.state_info:contains(${t.abbr})`).html(`${t.abbr}<br />${t.ev}`); if(t.ev == 0) { $('#sp_23_1').parent().hide(); $('#23').hide(); } else { $('#sp_23_1').parent().show(); $('#23').show(); } } else if(t.fips == "31") { var atlarge = t.ev >= 5 ? t.ev - 3 : (t.ev >=4 ? t.ev - 2 : (t.ev == 3 ? 2 : t.ev)); m.states[t.fips].NX.e_votes = atlarge; $('#sp_31_1').text('NE ' + atlarge); if(t.ev >= 5) { $('#sp_31_5').text('1'); m.states[t.fips].N5.e_votes = 1; } else { $('#sp_31_5').text('0'); m.states[t.fips].N5.e_votes = 0; } if(t.ev >= 4) { $('#sp_31_4').text('1'); m.states[t.fips].N4.e_votes = 1; } else { $('#sp_31_4').text('0'); m.states[t.fips].N4.e_votes = 0; } if(t.ev >= 3) { $('#sp_31_3').text('1'); m.states[t.fips].N3.e_votes = 1; } else { $('#sp_31_3').text('0'); m.states[t.fips].N3.e_votes = 0; } $(`.state_info:contains(${t.abbr})`).html(`${t.abbr}<br />${t.ev}`); if(t.ev == 0) { $('#sp_31_1').parent().hide(); $('#31').hide(); } else { $('#sp_31_1').parent().show(); $('#31').show(); } } else if(['03', '14', '69', '72', '52', '99'].includes(t.fips)) { $('#sp_' + t.fips).text(t.ev); if(t.ev == 0) { $('#sp_' + t.fips).hide(); $('#abbr_' + t.fips).hide(); } else { $('#sp_' + t.fips).show(); $('#abbr_' + t.fips).show(); } } else if(m.specialStates.includes(t.fips)) { $('#sp_' + t.fips).text(t.ev); if(t.ev == 0) { $('#sp_' + t.fips).parent().hide(); $('#' + t.fips).hide(); } else { $('#sp_' + t.fips).parent().show(); $('#' + t.fips).show(); } } else if(t.fips == '15') { $(`.state_info:contains(HI)`).next().html(t.ev); if(t.ev == 0) { $('#' + t.fips).hide(); $(`.state_info:contains(HI)`).hide(); } else { $('#' + t.fips).show(); $(`.state_info:contains(HI)`).show(); } } else { $(`.state_info:contains(${t.abbr})`).html(`${t.abbr}<br />${t.ev}`); if(t.ev == 0) $('#' + t.fips).hide(); else $('#' + t.fips).show(); } } m.update_electoral_votes(); }); var temp = ` <tr> <td>{0}</td> <td>{1}</td> <td class="cell-center"><input data-state="{1}" type="checkbox" {2}/></td> <td class="pop">{3}</td> <td class="pop">{4}</td> <td class="pop">{5}</td> <td id="{1}-evs" class="cell-center">{6}</td> <td id="{1}-evs-current" class="cell-center">{6}</td> <td id="{1}-evs-change" class="cell-center">0</td> </tr> `; for(var territory in territories) { if(territory == 56) continue; var t = territories[territory]; t.ev = t.current_ev; var name = t.name; if(t.abbr === 'DC') { name = '<input id="DC-name" value="District of Columbia" disabled /><span id="DC-name-span">District of Columbia</span>'; } var est = t.est.toLocaleString() if(['GU', 'VI', 'AS', 'MP'].includes(t.abbr)) { est = '<abbr title="No 2017 estimate, so 2010 census is used.">' + est + '</abbr>' } var pro = t.pro.toLocaleString() if(['GU', 'VI', 'AS', 'MP'].includes(t.abbr)) { pro = '<abbr title="No 2020 projection, so 2010 census is used.">' + pro + '</abbr>' } else if(t.abbr == 'PR') { pro = '<abbr title="No 2020 projection, so 2017 estimate is used.">' + pro + '</abbr>' } $('#territories > tbody').append(temp.formatUnicorn( name, t.abbr, t.is_state ? 'checked' : '', t.census.toLocaleString(), est, pro, t.current_ev )); } var table = $('#territories').DataTable({paging: false}); //$('#territories').floatThead(); var params = new URLSearchParams(window.location.search); var get_pop = ['1', null].includes(params.get('pop')); $('#census').prop('checked', get_pop); $('#est').prop('checked', !get_pop); var get_sen = Number(params.get('sen') || '2'); $('#senators').val(get_sen); var get_rep = Number(params.get('rep') || '435'); $('#reps').val(get_rep); var get_a23 = ['1', null].includes(params.get('a23')); $('#a23').prop('checked', get_a23); var get_states = params.get('states'); if(/^[0-1]{56}$/.test(get_states)) { var get_states_split = get_states.split(''); for(x in get_states_split) { var get_abbr = $('input[data-state=' + territories[x].abbr + ']'); get_abbr.prop('checked', get_states_split[x] === '1'); get_abbr.change(); } } else { params.set('states', '11011111101101111111111111111111111110111101111101111111'); } function change_electors() { console.log(`?${params}`) //top.history.replaceState({}, '', `${window.location.pathname}?${params}`); var senators = territories.filter(a => a.is_state).length * $('#senators').val(); var reps = Number($('#reps').val()) var ev = senators + reps + ($('#a23').prop('checked') ? 3 : 0); var needed = Math.floor((ev / 2) + 1); $('#USA-evs').text(ev); var change = ev - 538; $('#USA-evs-change').html('<span style="color: ' + (change>0?'green':(change<0?'red':'black')) + ';">' + (change>0?'+':'') + change + '</span>') $('#ev-total').val(ev); $('#ev-needed').val(needed); var states = []; for(var territory in territories) { if(territory == 56) continue; var t = territories[territory]; if(t.is_state) { t.senators = Number($('#senators').val()); t.reps = 1; t.ev = t.senators + 1; t.pop = $('#census').prop('checked') ? t.census : ($('#est').prop('checked') ? t.est : t.pro); states.push(t); if(t.abbr === 'DC') { if($('#a23').prop('checked')) { //$('#a23-extra').show(); $('#a23-extra').removeClass('settings-modal-hidden'); territories[56].ev = 3; } else { //$('#a23-extra').hide(); $('#a23-extra').addClass('settings-modal-hidden'); territories[56].ev = 0; } } } else { t.senators = 0; t.reps = 0; if(t.abbr === 'DC') { territories[56].ev = 0; if($('#a23').prop('checked')) { t.ev = 3; //$('#a23-extra').hide(); $('#a23-extra').addClass('settings-modal-hidden'); } else { t.ev = 0 } } else { t.ev = 0; } } } for(var i = states.length + 1; i < reps + 1; i++) { var highest = {priority: -1}; for(n in states) { var state = states[n]; state.priority = state.pop / Math.sqrt(state.reps * (state.reps + 1)); if(state.priority > highest.priority) { highest = state; } } highest.reps++; highest.ev++; } for(var n in territories) { var t = territories[n]; $('#' + t.abbr + '-evs').text(t.ev); change = t.ev - t.current_ev $('#' + t.abbr + '-evs-change').html('<span style="color: ' + (change>0?'green':(change<0?'red':'black')) + ';">' + (change>0?'+':'') + change + '</span>'); } table.cells().invalidate(); table.cells().draw(); } change_electors(); $('#senators').change(function() { params.set('sen', $(this).val()); change_electors(); }); $('#reps').change(function() { params.set('rep', $(this).val()); change_electors(); }); $('#a23').change(function() { params.set('a23', $(this).prop('checked') ? '1' : '0'); change_electors(); }); $('#census').change(function() { params.set('pop', '1'); change_electors(); }); $('#est').change(function() { params.set('pop', '0'); change_electors(); }); $('#pro').change(function() { params.set('pop', '0'); change_electors(); }); $('input[data-state]').change(function() { if($(this).data('state') === 'DC') { var dc_statehood = $(this).prop('checked'); $('#DC-name').prop('disabled', !dc_statehood); territories[9].is_state = dc_statehood; if(!dc_statehood) { $('#DC-name').val('District of Columbia'); $('#DC-name').change(); } var state_param = params.get('states'); state_param = state_param.split(''); state_param[9] = dc_statehood ? '1' : '0'; params.set('states', state_param.join('')); //$('#DC-name').toggle(); //$('#DC-name-span').toggle(); change_electors(); return; } for(var territory in territories) { if(territory == 56) continue; var t = territories[territory]; if(t.abbr === $(this).data('state')) { t.is_state = $(this).prop('checked'); var state_param = params.get('states'); state_param = state_param.split(''); state_param[territory] = $(this).prop('checked') ? '1' : '0'; params.set('states', state_param.join('')); break; } } change_electors(); }); $('#DC-name').change(function() { name = $(this).val(); territories[9].name = name; $(this).next().text(name); table.cells().invalidate(); table.cells().draw(); }); })();