huge election predictor overhaul
This commit is contained in:
parent
cc9fb21fbc
commit
ccc2b6e205
9 changed files with 1424 additions and 425 deletions
630
assets/ElectoralCollege1789.svg
Normal file
630
assets/ElectoralCollege1789.svg
Normal file
|
@ -0,0 +1,630 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<svg
|
||||
width="600"
|
||||
height="500"
|
||||
version="1.1"
|
||||
id="svg2"
|
||||
sodipodi:docname="ElectoralCollege1789.svg"
|
||||
inkscape:version="1.3.2 (091e20e, 2023-11-25, custom)"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/">
|
||||
<sodipodi:namedview
|
||||
id="namedview2"
|
||||
pagecolor="#505050"
|
||||
bordercolor="#ffffff"
|
||||
borderopacity="1"
|
||||
inkscape:showpageshadow="0"
|
||||
inkscape:pageopacity="0"
|
||||
inkscape:pagecheckerboard="1"
|
||||
inkscape:deskcolor="#505050"
|
||||
inkscape:zoom="1.569697"
|
||||
inkscape:cx="304.51737"
|
||||
inkscape:cy="259.92277"
|
||||
inkscape:window-width="1920"
|
||||
inkscape:window-height="1018"
|
||||
inkscape:window-x="-8"
|
||||
inkscape:window-y="-8"
|
||||
inkscape:window-maximized="1"
|
||||
inkscape:current-layer="text"
|
||||
showguides="true"
|
||||
showgrid="false" />
|
||||
<metadata
|
||||
id="metadata1">
|
||||
<rdf:RDF>
|
||||
<cc:Work
|
||||
rdf:about="">
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||
<dc:title>2024 US presidential election results</dc:title>
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<title
|
||||
id="title1">2024 US presidential election results</title>
|
||||
<defs
|
||||
id="defs1">
|
||||
<style
|
||||
type="text/css"
|
||||
id="style1">.state{fill:#C0C0C0;}
|
||||
<!-- #F07763 for Rep; below for Dem -->
|
||||
<!-- #HI, #DC {fill: #698DC5;} -->
|
||||
</style>
|
||||
</defs>
|
||||
<g
|
||||
id="outlines"
|
||||
class="state"
|
||||
transform="translate(-301.83139,-26.775509)">
|
||||
<path
|
||||
id="CT"
|
||||
d="m 626.76329,181.89053 3.6,-3.2 1.9,-2.1 0.8,0.6 2.7,-1.5 5.2,-1.1 7,-3.5 -0.6,-4.2 -0.8,-4.4 -1.6,-6 -4.3,1.1 -21.8,4.7 0.6,3.1 1.5,7.3 v 8.3 l -0.9,2.1 1.7,2.2 z" />
|
||||
<path
|
||||
id="DE"
|
||||
d="m 609.16329,238.19053 -1,0.5 -3.6,-2.4 -1.8,-4.7 -1.9,-3.6 -2.3,-1 -2.1,-3.6 0.5,-2 0.5,-2.3 0.1,-1.1 -0.6,0.1 -1.7,1 -2,1.7 -0.2,0.3 1.4,4.1 2.3,5.6 3.7,16.1 5,-0.3 6,-1.1 z" />
|
||||
<path
|
||||
id="IL"
|
||||
d="m 393.46329,205.29053 -0.8,-2.6 -1.3,-3.7 -1.6,-1.8 -1.5,-2.6 -0.4,-5.5 -15.9,1.8 -17.4,1 h -12.3 l 0.2,2.1 2.2,0.9 1.1,1.4 0.4,1.4 3.9,3.4 0.7,2.4 -0.7,3.3 -1.7,3.7 -0.8,2.7 -2.4,1.9 -1.9,0.6 -5.2,1.3 -1.3,4.1 0.6,1.1 1.9,1.8 -0.2,4.3 -2.1,1.6 -0.5,1.3 v 2.8 l -1.8,0.6 -1.4,1.2 -0.4,1.2 0.4,2 -1.6,1.3 -0.9,2.8 0.3,3.9 2.3,7 7,7.6 5.7,3.7 v 4.4 l 0.7,1.2 6.6,0.6 2.7,1.4 -0.7,3.5 -2.2,6.2 -0.8,3 2,3.7 6.4,5.3 4.8,0.8 2.2,5.1 2,3.4 -0.9,2.8 1.5,3.8 1.7,2.1 1.6,-0.3 1,-2.2 2.4,-1.7 2.8,-1 6.1,2.5 0.5,-0.2 v -1.1 l -1.2,-2.7 0.4,-2.8 2.4,-1.6 3.4,-1.2 -0.5,-1.3 -0.8,-2 1.2,-1.3 1,-2.7 v -4 l 0.4,-4.9 2.5,-3 1.8,-3.8 2.5,-4 -0.5,-5.3 -1.8,-3.2 -0.3,-3.3 0.8,-5.3 -0.7,-7.2 -1.1,-15.8 -1.4,-15.3 -0.9,-11.7 z"
|
||||
style="fill:#666666" />
|
||||
<path
|
||||
id="IN"
|
||||
d="m 397.66329,207.09053 1.5,1 1.1,-0.3 2.1,-1.9 2.5,-1.8 14.3,-1.1 18.4,-1.8 1.6,15.5 4.9,42.6 -0.6,2.9 1.3,1.6 0.2,1.3 -2.3,1.6 -3.6,1.7 -3.2,0.4 -0.5,4.8 -4.7,3.6 -2.9,4 0.2,2.4 -0.5,1.4 h -3.5 l -1.4,-1.7 -5.2,3 0.2,3.1 -0.9,0.2 -0.5,-0.9 -2.4,-1.7 -3.6,1.5 -1.4,2.9 -1.2,-0.6 -1.6,-1.8 -4.4,0.5 -5.7,1 -4.24558,1.3 0.11261,-2.54369 0.56893,-4.53107 1.34275,-4.0825 2.25047,-3.9 2.53107,-3.52429 -0.83785,-5.29321 -0.78644,-3.15631 -0.75047,-3.14369 0.91262,-5.35631 -0.30584,-6.98738 -1.12524,-12.88155 -2.5,-30.1 z"
|
||||
style="fill:#666666"
|
||||
sodipodi:nodetypes="ccccccccccccccccccccccccccccccccccccccccccccccc" />
|
||||
<path
|
||||
id="MA"
|
||||
d="m 666.26326,27.88981 -1.80078,1.800781 -4,2.900391 v 1 l -0.79883,0.798828 -2.70117,-0.59961 -1.29883,-2.298828 V 30.38981 l -1.30078,-0.199219 h -1.29883 l -2.10156,4.199219 -2.89844,8.90039 -1.80078,4.800782 0.19922,4.798828 0.20117,1.5 -0.80078,2.701172 -0.79883,1 v 6 l 1.89844,2.40039 -1.5,4 -2.59961,4.699219 -0.79883,5.5 V 83.2902 l -1.5,-0.40039 -1.30078,0.169922 11.69922,37.431638 0.20117,2.5 4,1.09961 0.5,3.09961 2.19922,0.90039 1.09961,-6.30078 0.20117,-4.40039 1.5,-1.29883 -1,-3.20117 3.09961,-3.59961 1.59961,1.5 1.30078,-0.5 5.29883,-3.09961 0.30078,-2.90039 2.90039,-0.5 1.59961,-2.59961 -0.19922,-1.599608 -0.30078,-3.09961 0.80078,-1.300781 -0.30078,-1.099609 -1.30078,-1.5 2.10156,-1.300782 1.79883,3.201172 1.5,-0.300781 0.30078,1.300781 v 1.59961 l 1.90039,0.199218 0.5,-2.699218 0.5,-0.59961 -1.60156,-1.5 1,-1.5 2.40039,-1.5 1,-1.5 1.80078,-0.201172 c 0,10e-7 0.4,2.09961 1,2.09961 h 1.29883 l 4.80078,-5.5 3.40039,-3.09961 1.90039,-0.599609 2.09961,-4.699219 v -1.90039 l -2.30078,-3.701172 -1.90039,-2.09961 -2.79883,0.5 0.5,1.09961 -0.20117,0.5 h -0.79883 l -2.90039,-2.298828 -0.19922,-4.800782 -0.80078,-1.90039 h -6 l -9.09961,-29.898438 -1.90039,-1 -6,-2.40039 z m 20.90039,61.800781 -2,0.699219 -1.40039,2.201172 1.80078,1.90039 c 0,0 1.29883,0.09883 1.29883,-0.201172 0,-0.299999 0.20117,-1.999999 0.20117,-2 l 0.89844,-0.798828 z m -8.59961,7.300781 -1.5,1.5 1.79883,2.898438 1.70117,-0.89844 -0.60156,-2.400388 z m -22.40039,36.999998 -3.70117,1.79883 -1.79883,2.90039 -18.30078,4.69922 -13.79883,2.5 -0.60156,10.60156 0.70117,4.89844 22,-4.79883 11.19922,-2.80078 2,1.59961 3.40039,4.30078 2.90039,4.69922 2.09961,-0.89844 -0.5,-2.30078 0.80078,-1.5 2.89844,-1.5 0.80078,3.09961 -0.5,1.80078 -2.40039,1.5 v 1 l 1.90039,-1.5 3.90039,-4.5 3.90039,-1.90039 4.19922,-1.5 -0.30078,-2.40039 -1,-2.90039 -1.89844,-2.39844 -1.80078,-0.80078 -2.09961,0.19922 -0.5,0.5 1,1.30078 1.5,-0.80078 2.09961,1.60156 0.80078,2.69922 -1.80078,1.80078 -2.30078,1 -3.59961,-0.5 -3.90039,-6 -2.29883,-2.60156 h -1.80078 l -1.09961,0.80078 -1.90039,-2.59961 0.30078,-1.5 2.40039,-5.20117 z m 21.29883,28.5 -0.5,1.69922 -2.19922,0.69922 -0.5,0.60156 3.90039,-0.10156 1.29883,-0.5 -1,-2.29883 z m -9.79883,0.59961 -2.30078,2.59961 1.09961,0.90039 2.20117,-1 2.40039,-1 -1.80078,-1.5 z" />
|
||||
<path
|
||||
id="MD"
|
||||
d="m 609.56329,255.09053 1.7,-3.8 0.5,-4.8 -6.3,1.1 -5.8,0.3 -3.8,-16.8 -2.3,-5.5 -1.5,-4.6 -22.2,4.3 -37.6,7.6 2,10.4 4.8,-4.9 2.5,-0.7 1.4,-1.5 1.8,-2.7 1.6,0.7 2.6,-0.2 2.6,-2.1 2,-1.5 2.1,-0.6 1.5,1.1 2.7,1.4 1.9,1.8 1.3,1.4 4.8,1.6 -0.6,2.9 5.8,2.1 2.1,-2.6 3.7,2.5 -2.1,3.3 -0.7,3.3 -1.8,2.6 v 2.1 l 0.3,0.8 2,1.3 3.4,1.1 4.3,-0.1 3.1,1 2.1,0.3 1,-2.1 -1.5,-2.1 v -1.8 l -2.4,-2.1 -2.1,-5.5 1.3,-5.3 -0.2,-2.1 -1.3,-1.3 c 0,0 1.5,-1.6 1.5,-2.3 0,-0.6 0.5,-2.1 0.5,-2.1 l 1.9,-1.3 1.9,-1.6 0.5,1 -1.5,1.6 -1.3,3.7 0.3,1.1 1.8,0.3 0.5,5.5 -2.1,1 0.3,3.6 0.5,-0.2 1.1,-1.9 1.6,1.8 -1.6,1.3 -0.3,3.4 2.6,3.4 3.9,0.5 1.6,-0.8 3.2,4.2 1,0.4 z m -14.5,0.2 1.1,2.5 0.2,1.8 1.1,1.9 c 0,0 0.9,-0.9 0.9,-1.2 0,-0.3 -0.7,-3.1 -0.7,-3.1 l -0.7,-2.3 z" />
|
||||
<path
|
||||
id="MI"
|
||||
d="m 419.37591,203.0604 19.60678,-0.66119 -0.4194,0.14274 9.9,-1.55631 12.33786,-1.53107 -0.23786,-2.06404 0.2,-1.5 2.1,-3.7 2,-1.7 -0.2,-5.1 1.6,-1.6 1.1,-0.3 0.2,-3.6 1.5,-3 1.1,0.6 0.2,0.6 0.8,0.2 1.9,-1 -0.4,-9.1 -3.2,-8.2 -2.3,-9.1 -2.4,-3.2 -2.6,-1.8 -1.6,1.1 -3.9,1.8 -1.9,5 -2.7,3.7 -1.1,0.6 -1.5,-0.6 c 0,0 -2.6,-1.5 -2.4,-2.1 0.2,-0.6 0.5,-5 0.5,-5 l 3.4,-1.3 0.8,-3.4 0.6,-2.6 2.4,-1.6 -0.3,-10 -1.6,-2.3 -1.3,-0.8 -0.8,-2.1 0.8,-0.8 1.6,0.3 0.2,-1.6 -2.6,-2.2 -1.3,-2.6 h -2.6 l -4.5,-1.5 -5.5,-3.4 h -2.7 l -0.6,0.6 -1,-0.5 -3.1,-2.3 -2.9,1.8 -2.9,2.3 0.3,3.6 1,0.3 2.1,0.5 0.5,0.8 -2.6,0.8 -2.6,0.3 -1.5,1.8 -0.3,2.1 0.3,1.6 0.3,5.5 -3.6,2.1 -0.6,-0.2 v -4.2 l 1.3,-2.4 0.6,-2.4 -0.8,-0.8 -1.9,0.8 -1,4.2 -2.7,1.1 -1.8,1.9 -0.2,1 0.6,0.8 -0.6,2.6 -2.3,0.5 v 1.1 l 0.8,2.4 -1.1,6.1 -1.6,4 0.6,4.7 0.5,1.1 -0.8,2.4 -0.3,0.8 -0.3,2.7 3.6,6 2.9,6.5 1.5,4.8 -0.8,4.7 -1,6 -2.4,5.2 -0.3,2.7 -3.2,4.16987 z m -34.52748,-72.35501 -1.7778,-1.02036 -1.64074,-9.6833 -3.7,-1.5389 -0.82403,-2.37964 -12.3611,-1.76476 -2.64074,-1.73707 -8.25926,-2.2 -8.59633,-1.4778 -3.34257,-6.0167 1.25743,-1.29633 2.7,-0.8 3.6,-2.299998 v -1 l 0.6,-0.6 6,-1 2.4,-1.9 4.4,-2.1 0.2,-1.3 1.9,-2.9 1.8,-0.8 1.3,-1.8 2.3,-2.3 4.4,-2.4 4.7,-0.5 1.1,1.1 -0.3,1 -3.7,1 -1.5,3.1 -2.3,0.8 -0.5,2.4 -2.4,3.2 -0.3,2.6 0.8,0.5 1,-1.1 3.6,-2.9 1.3,1.3 h 2.3 l 3.2,1 1.5,1.1 1.5,3.1 2.7,2.699998 3.9,-0.2 1.5,-0.999998 1.6,1.299998 1.6,0.5 1.3,-0.8 h 1.1 l 1.6,-0.999998 4,-3.6 3.4,-1.1 6.6,-0.3 4.5,-1.9 2.6,-1.3 1.5,0.2 v 5.7 l 0.5,0.3 2.9,0.8 1.9,-0.5 6.1,-1.6 1.1,-1.1 1.5,0.5 v 6.999998 l 3.2,3.1 1.3,0.6 1.3,1 -1.3,0.3 -0.8,-0.3 -3.7,-0.5 -2.1,0.6 -2.3,-0.2 -3.2,1.5 h -1.8 l -5.8,-1.3 -5.2,0.2 -1.9,2.6 -7,0.6 -2.4,0.8 -1.1,3.1 -1.3,1.1 -0.5,-0.2 -1.5,-1.6 -4.5,2.4 h -0.6 l -1.1,-1.6 -0.8,0.2 -1.9,4.4 -1,4 -3.60824,7.85022 z m -28.48514,-57.614858 1.8,-2.1 2.2,-0.8 5.4,-3.9 2.3,-0.6 0.5,0.5 -5.1,5.1 -3.3,1.9 -2.1,0.9 z m 86.2,32.099998 0.6,2.5 3.2,0.2 1.3,-1.2 c 0,0 -0.1,-1.5 -0.4,-1.6 -0.3,-0.2 -1.6,-1.9 -1.6,-1.9 l -2.2,0.2 -1.6,0.2 -0.3,1.1 z"
|
||||
style="fill:#666666"
|
||||
sodipodi:nodetypes="cccccccccccccccccccccccccccccsccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc" />
|
||||
<path
|
||||
id="NC"
|
||||
d="m 561.46329,348.69053 -12.7,-7.7 -3.1,-0.8 -16.6,2.1 -1.6,-3 -2.8,-2.2 -16.7,0.5 -7.4,0.9 -9.2,4.5 -6.8,2.7 -6.5,1.2 -17.22902,1.96309 1.78927,-4.77571 1.81262,-3.43975 2.36214,1.66499 1.15048,-5.15142 4.01262,-1.59906 c 1.29998,-0.49999 -7.91012,-0.16486 3.67476,-1.95047 l 4.04953,-3.36214 4.51261,-2.63786 0.92524,-3.2 5.22618,-3.8 1.43202,-0.43589 1.79614,0.28449 2.14661,-2.69905 2.9388,-0.4 1.58643,0.18738 1.01168,-3.43691 2.83785,-1.72429 0.27476,-1.57476 -0.0126,-3.72524 6.20189,0.21262 38.5,-5.6 57.5,-12.3 2,4.8 3.6,6.5 2.4,2.4 0.6,2.3 -2.4,0.2 0.8,0.6 -0.3,4.2 -2.6,1.3 -0.6,2.1 -1.3,2.9 -3.7,1.6 -2.4,-0.3 -1.5,-0.2 -1.6,-1.3 0.3,1.3 v 1 h 1.9 l 0.8,1.3 -1.9,6.3 h 4.2 l 0.6,1.6 2.3,-2.3 1.3,-0.5 -1.9,3.6 -3.1,4.8 h -1.30001 l -1.1,-0.5 -2.7,0.6 -5.2,2.4 -6.5,5.3 -3.4,4.7 -1.9,6.5 -0.5,2.4 -4.7,0.5 -5.1,1.5 z m 49.3,-26.2 2.6,-2.5 3.2,-2.6 1.5,-0.6 0.2,-2 -0.6,-6.1 -1.5,-2.3 -0.6,-1.9 0.7,-0.2 2.7,5.5 0.4,4.4 -0.2,3.4 -3.4,1.5 -2.8,2.4 -1.1,1.2 z"
|
||||
style="fill:#c0c0c0;fill-opacity:1"
|
||||
sodipodi:nodetypes="cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc" />
|
||||
<path
|
||||
id="NH"
|
||||
d="m 656.46329,132.29053 1.1,-3.2 -2.7,-1.2 -0.5,-3.1 -4.1,-1.1 -0.3,-3 -11.7,-37.479998 -0.7,0.08 -0.6,1.6 -0.6,-0.5 -1,-1 -1.5,1.9 -0.2,2.29 0.5,8.41 1.9,2.8 v 4.299998 l -3.9,4.8 -2.4,0.9 v 0.7 l 1.1,1.9 v 8.6 l -0.8,9.2 -0.2,4.7 1,1.4 -0.2,4.7 -0.5,1.5 1,1.1 5.1,-1.2 13.8,-3.5 1.7,-2.9 4,-1.9 z" />
|
||||
<path
|
||||
id="NJ"
|
||||
d="m 598.46329,219.29053 0.1,-1.5 2.7,-1.3 1.7,-2.8 1.7,-2.4 3.3,-3.2 v -1.2 l -6.1,-4.1 -1,-2.7 -2.7,-0.3 -0.1,-0.9 -0.7,-2.2 2.2,-1.1 0.2,-2.9 -1.3,-1.3 0.2,-1.2 1.9,-3.1 v -3.1 l 2.5,-3.1 5.6,2.5 6.4,1.9 2.5,1.2 0.1,1.8 -0.5,2.7 0.4,4.5 -2.1,1.9 -1.1,1 0.5,0.5 2.7,-0.3 1.1,-0.8 1.6,3.4 0.2,9.4 0.6,1.1 -1.1,5.5 -3.1,6.5 -2.7,4 -0.8,4.8 -2.1,2.4 h -0.8 l -0.3,-2.7 0.8,-1 -0.2,-1.5 -4,-0.6 -4.8,-2.3 -3.2,-2.9 -1,-2 z" />
|
||||
<path
|
||||
id="NY"
|
||||
d="m 618.16329,190.99053 0.5,-2.7 -0.2,-2.4 -3,-1.5 -6.5,-2 -6,-2.6 -0.6,-0.4 -2.7,-0.3 -2,-1.5 -2.1,-5.9 -3.3,-0.5 -2.4,-2.4 -38.4,8.1 -31.6,6 -0.5,-6.5 1.6,-1.2 1.3,-1.1 1,-1.6 1.8,-1.1 1.9,-1.8 0.5,-1.6 2.1,-2.7 1.1,-1 -0.2,-1 -1.3,-3.1 -1.8,-0.2 -1.9,-6.1 2.9,-1.8 4.4,-1.5 4,-1.3 3.2,-0.5 6.3,-0.2 1.9,1.3 1.6,0.2 2.1,-1.3 2.6,-1.1 5.2,-0.5 2.1,-1.8 1.8,-3.2 1.6,-1.9 h 2.1 l 1.9,-1.1 0.2,-2.3 -1.5,-2.1 -0.3,-1.5 1.1,-2.1 v -1.5 h -1.8 l -1.8,-0.8 -0.8,-1.1 -0.2,-2.6 5.8,-5.5 0.6,-0.8 1.5,-2.9 2.9,-4.5 2.7,-3.7 2.1,-2.4 2.4,-1.8 3.1,-1.2 5.5,-1.3 3.2,0.2 4.5,-1.499998 7.4,-2.2 0.7,4.899998 2.4,6.5 0.8,5 -1,4.2 2.6,4.5 0.8,2 -0.9,3.2 3.7,1.7 2.7,10.2 v 5.8 l -0.6,10.9 0.8,5.4 0.7,3.6 1.5,7.3 v 8.1 l -1.1,2.3 2.1,2.7 0.5,0.9 -1.9,1.8 0.3,1.3 1.3,-0.3 1.5,-1.3 2.3,-2.6 1.1,-0.6 1.6,0.6 2.3,0.2 7.9,-3.9 2.9,-2.7 1.3,-1.5 4.2,1.6 -3.4,3.6 -3.9,2.9 -7.1,5.3 -2.6,1 -5.8,1.9 -4,1.1 -1,-0.4 z"
|
||||
style="fill:#000000" />
|
||||
<path
|
||||
id="OH"
|
||||
d="m 437.3808,202.30315 1.19321,15.5 4.91262,41.38154 5.47666,-0.59416 2.3,-0.8 3.6,1.8 1.7,4.2 5.4,0.1 1.8,2 h 1.7 l 2.4,-1.4 3.1,0.5 1.5,1.3 1.8,-2 2.3,-1.4 2.4,-0.4 0.6,2.7 1.6,1 2.6,2 0.8,0.2 2,-0.1 1.2,-0.6 v -2.1 l 1.7,-1.5 0.1,-4.8 1.1,-4.2 1.9,-1.3 1,0.7 1,1.1 0.7,0.2 0.4,-0.4 -0.9,-2.7 v -2.2 l 1.1,-1.4 2.5,-3.6 1.3,-1.5 2.2,0.5 2.1,-1.5 3,-3.3 2.2,-3.7 0.2,-5.4 0.5,-5 v -4.6 l -1.2,-3.2 1.2,-1.8 1.3,-1.2 -0.6,-2.8 -4.3,-25.6 -6.2,3.7 -3.9,2.3 -3.4,3.7 -4,3.9 -3.2,0.8 -2.9,0.5 -5.5,2.6 -2.1,0.2 -3.4,-3.1 -5.2,0.6 -2.6,-1.5 -2.2,-1.3 z"
|
||||
style="fill:#666666"
|
||||
sodipodi:nodetypes="ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc" />
|
||||
<path
|
||||
id="PA"
|
||||
d="m 511.36329,183.19053 1.3,-0.5 5.7,-5.5 0.7,6.9 33.5,-6.5 36.9,-7.8 2.3,2.3 3.1,0.4 2,5.6 2.4,1.9 2.8,0.4 0.1,0.1 -2.6,3.2 v 3.1 l -1.9,3.1 -0.2,1.9 1.3,1.3 -0.2,1.9 -2.4,1.1 1,3.4 0.2,1.1 2.8,0.3 0.9,2.5 5.9,3.9 v 0.4 l -3.1,3 -1.5,2.2 -1.7,2.8 -2.7,1.2 -1.4,0.3 -2.1,1.3 -1.6,1.4 -22.4,4.3 -38.7,7.8 -11.3,1.4 -3.9,0.7 -5.1,-22.4 -4.3,-25.9 z" />
|
||||
<path
|
||||
id="RI"
|
||||
d="m 648.36329,166.69053 -0.8,-4.4 -1.6,-6 5.7,-1.5 1.5,1.3 3.4,4.3 2.8,4.4 -2.8,1.4 -1.3,-0.2 -1.1,1.8 -2.4,1.9 -2.8,1.1 z" />
|
||||
<path
|
||||
id="SC"
|
||||
d="m 533.76329,404.59053 -2.1,-1 -1.9,-5.6 -2.5,-2.3 -2.5,-0.5 -1.5,-4.6 -3,-6.5 -4.2,-1.8 -1.9,-1.8 -1.2,-2.6 -2.4,-2 -2.3,-1.3 -2.2,-2.9 -3.2,-2.4 -4.4,-1.7 -0.4,-1.4 -2.3,-2.8 -0.5,-1.5 -3.8,-5.4 -3.4,0.1 -3.9,-2.5 -1.2,-1.2 -0.2,-1.4 0.6,-1.6 2.7,-1.3 -0.8,-2 6.4,-2.7 9.2,-4.5 7.1,-0.9 16.4,-0.5 2.3,1.9 1.8,3.5 4.6,-0.8 12.6,-1.5 2.7,0.8 12.5,7.4 10.1,8.3 -5.3,5.4 -2.6,6.1 -0.5,6.3 -1.6,0.8 -1.1,2.7 -2.4,0.6 -2.1,3.6 -2.7,2.7 -2.3,3.4 -1.6,0.8 -3.6,3.4 -2.9,0.2 1,3.2 -5,5.3 -2.3,1.6 z"
|
||||
/>
|
||||
<path
|
||||
id="TN"
|
||||
d="m 445.56329,350.59053 -13.1,1.2 -23.3,2.2 -37.6,2.7 -11.8,0.4 0.9,-0.6 0.9,-4.5 -1.2,-3.6 3.9,-2.3 0.4,-2.5 1.2,-4.3 3,-9.5 0.5,-5.6 0.3,-0.2 12.3,-0.2 13.6,-0.8 0.1,-3.9 3.5,-0.1 30.4,-3.3 54,-5.2 10.3,-1.5 7.6,-0.2 2.4,-1.9 1.3,0.3 -0.1,3.3 -0.4,1.6 -2.4,2.2 -1.6,3.6 -2,-0.4 -2.4,0.9 -2.2,3.3 -1.4,-0.2 -0.8,-1.2 -1.1,0.4 -4.3,4 -0.8,3.1 -4.2,2.2 -4.3,3.6 -3.8,1.5 -4.4,2.8 -0.6,3.6 -2.5,0.5 -2,1.7 -0.2,4.8 z"
|
||||
style="fill:#c0c0c0;fill-opacity:1" />
|
||||
<path
|
||||
id="VT"
|
||||
d="m 607.46329,102.29053 2.4,6.5 0.8,5.3 -1,3.9 2.5,4.4 0.9,2.3 -0.7,2.6 3.3,1.5 2.9,10.8 v 5.3 l 11.5,-2.1 -1,-1.1 0.6,-1.9 0.2,-4.3 -1,-1.4 0.2,-4.7 0.8,-9.3 v -8.5 l -1.1,-1.8 v -1.6 l 2.8,-1.1 3.5,-4.4 v -3.599998 l -1.9,-2.7 -0.3,-5.79 -26.1,6.79 z"
|
||||
style="fill:#000000" />
|
||||
<path
|
||||
id="WI"
|
||||
d="m 316.16329,100.89053 2.9,0.5 2.9,-0.6 7.4,-3.199998 2.9,-1.9 2.1,-0.8 1.9,1.5 -1.1,1.1 -1.9,3.099998 -0.6,1.9 1,0.6 1.8,-1 1.1,-0.2 2.7,0.8 0.6,1.1 1.1,0.2 0.6,-1.1 4,5.3 8.2,1.2 8.2,2.2 2.6,1.1 12.3,2.6 1.6,2.3 3.6,1.2 1.7,10.2 1.6,1.4 1.5,0.9 -1.1,2.3 -1.8,1.6 -2.1,4.7 -1.3,2.4 0.2,1.8 1.5,0.3 1.1,-1.9 1.5,-0.8 0.8,-2.3 1.9,-1.8 2.7,-4 4.2,-6.3 0.8,-0.5 0.3,1 -0.2,2.3 -2.9,6.8 -2.7,5.7 -0.5,3.2 -0.6,2.6 0.8,1.3 -0.2,2.7 -1.9,2.4 -0.5,1.8 0.6,3.6 0.6,3.4 -1.5,2.6 -0.8,2.9 -1,3.1 1.1,2.4 0.6,6.1 1.6,4.5 -0.0874,4.46404 -16.01262,1.68738 -17.5,0.88738 -12.58738,0.0563 -0.8126,-2.7951 -2.9,-0.4 -2.6,-1.3 -2.3,-3.7 -0.3,-3.6 2,-2.9 -0.5,-1.4 -2.1,-2.2 -0.8,-3.3 -0.6,-6.8 -2.1,-2.5 -7,-4.5 -3.8,-5.4 -3.4,-1 -2.2,-2.8 h -3.2 l -2.9,-3.3 -0.5,-6.5 0.1,-3.8 1.5,-3.1 -0.8,-3.2 -2.5,-2.8 1.8,-5.4 5.2,-3.8 1.6,-1.9 -0.2,-8.1 0.2,-2.8 2.4,-2.8 z"
|
||||
style="fill:#666666"
|
||||
sodipodi:nodetypes="ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc" />
|
||||
<path
|
||||
id="VA"
|
||||
d="m 512.08093,215.61215 -1.2832,1.29297 -0.96875,1.45507 1.13085,3.07227 v 4.6875 l -0.48437,5.01172 -0.32422,5.65625 -2.26367,3.88086 -3.07031,3.39453 -2.26367,1.61719 -2.10157,-0.48438 -1.29297,1.45508 -2.26562,3.39453 -0.96875,1.29297 v 2.42578 l 1.13086,1.77734 -0.48438,1.61719 -1.77734,0.96875 -0.48438,-1.77734 -1.29492,-1.13086 -1.29297,0.64453 -0.96875,3.88086 -0.16211,5.01172 -1.61718,1.45508 -0.16211,2.74804 -1.9375,0.8086 -2.1836,0.0801 -1.05078,0.10157 -0.006,-0.22461 -2.42187,-2.21485 -1.77735,-0.96875 -0.64648,-2.75 h -1.61719 l -1.77734,1.29297 -2.74805,2.58594 -1.29297,-1.45508 -3.07031,-0.48437 -2.42578,1.45507 -2.10156,-0.1621 -1.7793,-1.7793 -5.81836,-0.32227 -1.61719,-4.36523 -2.91015,-1.61719 -2.42383,0.80859 -4.12305,0.24219 -0.5664,2.1836 1.45507,1.45507 0.32422,1.93946 -2.74804,1.93945 -3.88086,1.77734 -2.74805,0.32422 -0.48438,4.52539 -4.6875,3.88086 -2.91015,3.55664 0.32226,2.26368 -0.80859,2.10156 h -4.6875 l -1.13281,-1.61719 -1.13086,0.80859 -2.91016,1.61719 0.16211,3.39453 -2.10351,0.48438 -0.8086,-1.13086 -1.93945,-1.61719 -2.91016,1.45508 -1.77734,3.23242 -1.77735,-0.80859 -1.45507,-1.93946 -3.55664,0.48633 -5.82032,0.96875 -2.99023,1.69727 -1.05078,3.3125 -1.13281,0.81055 0.64648,1.9375 0.80859,1.77929 -1.61523,0.64649 -2.58789,0.64648 -1.93945,1.45508 -0.32227,2.26172 1.29297,2.42578 -0.16211,2.26367 -1.13086,0.32422 -3.55664,-1.29492 -2.74805,-1.29297 -2.10156,0.64648 -2.26367,1.7793 -0.80274,1.9043 1.60547,2.53906 -0.91406,1.82812 -0.22852,3.20118 -2.05859,1.14453 -2.17969,1.76172 -1.91211,0.22265 10.42969,-0.20508 6.95117,-0.64648 8.17969,-0.14453 0.22852,-4.2207 3.86718,0.0273 4.6211,-0.51367 15.75976,-1.77735 51.86914,-4.89843 3.51953,-0.38477 0.29297,-0.17578 1.74024,-0.0586 8.92578,-0.95118 8.38281,-0.97851 7.33789,-0.22071 2.58594,-1.92773 6.67969,0.375 37.42578,-5.27734 58.17578,-12.57617 -3.61328,-6.00977 -5.80078,1.68555 -1.57227,-1.49414 2.55274,-1.38086 -0.49024,-2.52344 -1.77344,-1.78516 v -0.002 l -0.12109,-1.41016 -2.28125,-1.54492 -0.0879,-1.61523 2.69336,0.0957 0.22266,-1.38477 -1.23047,-0.79101 0.48047,-1.92969 v -0.002 l -1.375,-1.10156 0.43945,-4.68946 v -0.002 l -0.86914,-1.19922 -3.18945,-0.40234 -2.15235,-2.08789 -4.85547,-0.94141 -2.94922,-0.96875 -4.625,-1.0918 -1.60546,-1.63086 -0.14063,-2.40429 0.50586,-1.7461 1.26367,-1.32617 0.86914,-3.68164 -1.29297,-1.79297 -1.88867,-0.67578 -0.21094,-0.30859 -2.15429,-0.53711 -1.43555,-0.51367 -2.47656,-0.60157 -0.0274,-0.0137 -0.006,-2.97851 -3.54687,-1.31641 c 0,0 -0.50769,-0.31367 -0.72266,-0.44727 l 0.006,-0.16992 -1.375,-1.29297 -1.9375,-1.77734 h -0.002 l -2.22852,-1.11524 -1.30273,-1.01757 -1.84766,0.48633 -2.00586,1.45312 -2.58593,2.10156 -2.91016,0.32227 -1.17969,-0.64453 -1.77929,2.58593 -1.45508,1.45508 -2.53711,0.61524 -2.26367,3.07031 -3.56055,2.75 -1.08203,-6.90625 -1.11328,-4.94531 -11.30078,1.55078 -4.63086,0.75195 z m 98.07812,40.30664 -6.45312,2.55078 0.14453,1.94726 -0.76758,3.09766 -1.58789,4.18359 -0.44531,5.44922 1.4707,4.64063 2.16406,-1.91602 1.82813,-4.97851 -0.46289,-3.39063 0.41797,-4.58594 2.91992,-3.77929 0.77148,-3.2168 z"
|
||||
/>
|
||||
<path
|
||||
id="GA"
|
||||
d="m 484.35742,346.5561 -5.82031,0.9707 -6.95117,0.8086 -6.79102,0.48437 -4.84961,0.8086 -8.40624,1.13281 -8.56836,0.88867 -1.11329,0.43359 0.0137,-0.21093 -8.92188,0.66211 -27.80469,2.58593 -7.75781,0.3711 v 0.0293 l -1.08008,0.0156 -4.58007,0.22852 -24.0879,1.93945 -8.67578,0.0781 -0.10547,3.41211 -2.74414,1.14258 -2.74414,5.25977 0.6875,1.37109 v 2.51562 l -2.74414,0.91407 -3.6582,5.25781 0.6875,2.05859 -2.97266,2.74219 -0.91406,6.17383 -0.45703,1.82812 1.37109,2.0586 -1.37109,1.37305 1.37109,2.9707 0.40039,4.34375 -1.37304,2.6582 0.28711,5.34375 2.05664,4.57227 -0.22852,1.83007 2.28516,1.82813 -0.68555,3.20117 h -1.14453 l 0.91406,2.0586 -5.25781,9.14453 -3.42969,6.17383 -0.68555,8.00195 0.45704,1.59961 24.23437,-0.68555 10.30859,-0.66406 26.16407,-2.64063 13.27539,-1.07812 10.41211,-1.40625 25.54297,-2.91016 6.78906,-0.64648 h 6.30469 l -0.006,-0.0137 0.86523,0.64843 2.58594,3.88086 1.45508,1.45508 7.92187,0.16016 10.81836,-0.64649 21.51367,-1.29297 5.44336,-0.67382 4.57813,0.0273 0.16211,2.9082 2.58593,0.81055 0.32422,-4.36524 -1.61718,-4.52734 1.13085,-1.61523 5.82032,0.80859 4.97851,0.31641 -0.77539,-6.29883 2.26367,-10.02149 1.45508,-4.20312 -0.48437,-2.58594 3.33398,-6.24414 -0.51172,-1.35156 -1.91211,0.70312 -2.58789,-1.29297 -0.64453,-2.10156 -1.29297,-3.55664 -2.26562,-2.10351 -2.58594,-0.64453 -1.61523,-4.85157 -2.92579,-6.33398 -4.20312,-1.93945 -2.10156,-1.94141 -1.29492,-2.58594 -2.10157,-1.93945 -2.26367,-1.29297 -2.26367,-2.9082 -3.07031,-2.26563 -4.52539,-1.77734 -0.48633,-1.45508 -2.42383,-2.91016 -0.48633,-1.45312 -3.39453,-4.9082 -3.39453,0.16015 -4.13086,-3.04297 -1.29297,-1.29297 -0.32422,-1.77929 0.81055,-1.93946 2.35156,-1.23437 -1.13281,-1.22656 z"
|
||||
/>
|
||||
</g>
|
||||
<text
|
||||
id="PAn-6"
|
||||
x="286.39993"
|
||||
y="116.41373"
|
||||
style="font-size:13.3333px"><tspan
|
||||
sodipodi:role="line"
|
||||
id="tspan87-6"
|
||||
x="286.39993"
|
||||
y="116.41373"
|
||||
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:13.3333px;font-family:'Helvetica Neue';-inkscape-font-specification:'Helvetica Neue Bold';text-align:center;text-anchor:middle;fill:#ffffff">NY</tspan><tspan
|
||||
sodipodi:role="line"
|
||||
id="tspan88-3"
|
||||
x="286.39993"
|
||||
y="133.1395"
|
||||
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:13.3333px;font-family:'Helvetica Neue';-inkscape-font-specification:'Helvetica Neue Bold';text-align:center;text-anchor:middle;fill:#ffffff">0</tspan></text>
|
||||
<g
|
||||
id="text"
|
||||
font-family="'Helvetica Neue'"
|
||||
font-weight="bold"
|
||||
transform="translate(-527.0681,-35.784978)">
|
||||
<g
|
||||
font-size="28px"
|
||||
id="g1">
|
||||
<text
|
||||
id="AKn"
|
||||
x="121.59544"
|
||||
y="493.18863"
|
||||
style="font-size:13.3333px"><tspan
|
||||
sodipodi:role="line"
|
||||
id="tspan41"
|
||||
x="121.59544"
|
||||
y="493.18863"
|
||||
style="font-size:13.3333px;text-align:center;text-anchor:middle;fill:#ffffff" /></text>
|
||||
<text
|
||||
id="HIn"
|
||||
x="281.26047"
|
||||
y="554.18866"
|
||||
style="font-size:13.3333px"><tspan
|
||||
sodipodi:role="line"
|
||||
id="tspan20"
|
||||
x="281.26047"
|
||||
y="554.18866"
|
||||
style="font-size:13.3333px;text-align:center;text-anchor:middle;fill:#ffffff;fill-opacity:1" /></text>
|
||||
<text
|
||||
id="WAn"
|
||||
x="117.53755"
|
||||
y="49.386745"
|
||||
style="font-size:13.3333px"><tspan
|
||||
sodipodi:role="line"
|
||||
id="tspan39"
|
||||
x="117.53755"
|
||||
y="49.386745"
|
||||
style="font-size:13.3333px;text-align:center;text-anchor:middle;fill:#ffffff" /></text>
|
||||
<text
|
||||
id="AZn"
|
||||
x="188.30663"
|
||||
y="358.99054"
|
||||
style="font-size:13.3333px"><tspan
|
||||
sodipodi:role="line"
|
||||
id="tspan28"
|
||||
x="188.30663"
|
||||
y="358.99054"
|
||||
style="font-size:13.3333px;fill:#ffffff" /></text>
|
||||
<text
|
||||
id="UTn"
|
||||
x="219.70537"
|
||||
y="251.48579"
|
||||
style="font-size:13.3333px"><tspan
|
||||
sodipodi:role="line"
|
||||
id="tspan26"
|
||||
x="219.70537"
|
||||
y="251.48579"
|
||||
style="font-size:13.3333px;text-align:center;text-anchor:middle;fill:#ffffff" /></text>
|
||||
<text
|
||||
id="IDn"
|
||||
x="194.15645"
|
||||
y="151.80695"
|
||||
style="font-size:13.3333px"><tspan
|
||||
sodipodi:role="line"
|
||||
x="194.15645"
|
||||
y="151.80695"
|
||||
id="tspan22"
|
||||
style="font-size:13.3333px;text-align:center;text-anchor:middle;fill:#ffffff;fill-opacity:1" /></text>
|
||||
<text
|
||||
id="MTn"
|
||||
x="279.21573"
|
||||
y="85.347488"
|
||||
style="font-size:13.3333px"><tspan
|
||||
sodipodi:role="line"
|
||||
id="tspan16"
|
||||
x="279.21573"
|
||||
y="85.347488"
|
||||
style="font-size:13.3333px;text-align:center;text-anchor:middle;fill:#ffffff" /></text>
|
||||
<text
|
||||
id="WYn"
|
||||
x="298.39981"
|
||||
y="182.08109"
|
||||
style="font-size:13.3333px"><tspan
|
||||
sodipodi:role="line"
|
||||
x="298.39981"
|
||||
y="182.08109"
|
||||
id="tspan19"
|
||||
style="font-size:13.3333px;text-align:center;text-anchor:middle;fill:#ffffff" /></text>
|
||||
<text
|
||||
id="COn"
|
||||
x="319.78827"
|
||||
y="270.08292"
|
||||
style="font-size:13.3333px"><tspan
|
||||
sodipodi:role="line"
|
||||
id="tspan24"
|
||||
x="319.78827"
|
||||
y="270.08292"
|
||||
style="font-size:13.3333px;text-align:center;text-anchor:middle;fill:#ffffff;fill-opacity:1" /></text>
|
||||
<text
|
||||
id="NMn"
|
||||
x="302.97266"
|
||||
y="369.28769"
|
||||
style="font-size:16px"><tspan
|
||||
sodipodi:role="line"
|
||||
x="302.97266"
|
||||
y="369.28769"
|
||||
id="tspan31"
|
||||
style="font-size:16px;text-align:center;text-anchor:middle;fill:#ffffff" /></text>
|
||||
<text
|
||||
id="TXn"
|
||||
x="415.85614"
|
||||
y="451.69336"
|
||||
style="font-size:13.3333px"><tspan
|
||||
sodipodi:role="line"
|
||||
id="tspan2"
|
||||
x="415.85614"
|
||||
y="451.69336"
|
||||
style="font-size:13.3333px;fill:#ffffff;fill-opacity:1" /></text>
|
||||
<text
|
||||
id="OKn"
|
||||
x="461.73621"
|
||||
y="358.28769"
|
||||
style="font-size:13.3333px;text-align:center;text-anchor:middle;fill:#ffffff;fill-opacity:1"><tspan
|
||||
sodipodi:role="line"
|
||||
id="tspan6"
|
||||
x="461.73621"
|
||||
y="358.28769" /></text>
|
||||
<text
|
||||
id="NEn"
|
||||
x="414.12476"
|
||||
y="221.48842"
|
||||
style="font-size:13.3333px"><tspan
|
||||
sodipodi:role="line"
|
||||
id="tspan10"
|
||||
x="414.12476"
|
||||
y="221.48842"
|
||||
style="font-size:13.3333px;text-align:center;text-anchor:middle;fill:#ffffff;fill-opacity:1" /></text>
|
||||
<text
|
||||
id="SDn"
|
||||
x="415.85419"
|
||||
y="157.25868"
|
||||
style="font-size:13.3333px"><tspan
|
||||
sodipodi:role="line"
|
||||
id="tspan12"
|
||||
x="415.85419"
|
||||
y="157.25868"
|
||||
style="font-size:13.3333px;text-align:center;text-anchor:middle;fill:#ffffff;fill-opacity:1" /></text>
|
||||
<text
|
||||
id="NDn"
|
||||
x="417.25748"
|
||||
y="91.851349"
|
||||
style="font-size:13.3333px"><tspan
|
||||
sodipodi:role="line"
|
||||
id="tspan14"
|
||||
x="417.25748"
|
||||
y="91.851349"
|
||||
style="font-size:13.3333px;text-align:center;text-anchor:middle;fill:#ffffff;fill-opacity:1" /></text>
|
||||
<text
|
||||
id="ARn"
|
||||
x="547.24762"
|
||||
y="374.0896"
|
||||
style="font-size:13.3333px"><tspan
|
||||
sodipodi:role="line"
|
||||
id="tspan52"
|
||||
x="547.24762"
|
||||
y="374.0896"
|
||||
style="font-size:13.3333px;text-align:center;text-anchor:middle;fill:#ffffff;fill-opacity:1" /></text>
|
||||
<text
|
||||
id="MSn"
|
||||
x="597.98846"
|
||||
y="417.18863"
|
||||
style="font-size:13.3333px"><tspan
|
||||
sodipodi:role="line"
|
||||
id="tspan48"
|
||||
x="597.98846"
|
||||
y="417.18863"
|
||||
style="font-size:13.3333px;text-align:center;text-anchor:middle;fill:#ffffff;fill-opacity:1" /></text>
|
||||
<text
|
||||
id="ALn"
|
||||
x="650.66272"
|
||||
y="409.38675"
|
||||
style="font-size:13.3333px"><tspan
|
||||
sodipodi:role="line"
|
||||
id="tspan58"
|
||||
x="650.66272"
|
||||
y="409.38675"
|
||||
style="font-size:13.3333px;text-align:center;text-anchor:middle;fill:#ffffff;fill-opacity:1" /></text>
|
||||
<text
|
||||
id="GAn"
|
||||
x="714.30121"
|
||||
y="407.73816"
|
||||
style="font-size:13.3333px"><tspan
|
||||
sodipodi:role="line"
|
||||
id="tspan50"
|
||||
x="714.30121"
|
||||
y="407.73816"
|
||||
style="font-size:13.3333px;text-align:center;text-anchor:middle;fill:#ffffff;fill-opacity:1" /></text>
|
||||
<text
|
||||
id="FLn"
|
||||
x="763.43597"
|
||||
y="504.54953"
|
||||
style="font-size:13.3333px"><tspan
|
||||
sodipodi:role="line"
|
||||
id="tspan56"
|
||||
x="763.43597"
|
||||
y="504.54953"
|
||||
style="font-size:13.3333px;text-align:center;text-anchor:middle;fill:#f8f8f8;fill-opacity:1" /></text>
|
||||
<text
|
||||
id="SCn"
|
||||
x="759.23254"
|
||||
y="347.11545"><tspan
|
||||
sodipodi:role="line"
|
||||
x="759.23254"
|
||||
y="347.11545"
|
||||
id="tspan61"
|
||||
style="font-size:13.3333px;text-align:center;text-anchor:middle;fill:#ffffff;fill-opacity:1" /></text>
|
||||
<text
|
||||
id="NCn"
|
||||
x="781.7052"
|
||||
y="328.48581"
|
||||
style="font-size:13.3333px"><tspan
|
||||
sodipodi:role="line"
|
||||
id="tspan68"
|
||||
x="781.7052"
|
||||
y="328.48581"
|
||||
style="font-size:13.3333px;text-align:center;text-anchor:middle;fill:#ffffff;fill-opacity:1" /></text>
|
||||
<text
|
||||
id="TNn"
|
||||
x="659.12402"
|
||||
y="401.87637"
|
||||
style="font-size:13.3333px"><tspan
|
||||
sodipodi:role="line"
|
||||
id="tspan65"
|
||||
x="659.12402"
|
||||
y="401.87637"
|
||||
style="font-size:13.3333px;text-align:center;text-anchor:middle;fill:#ffffff;fill-opacity:1">GA</tspan><tspan
|
||||
sodipodi:role="line"
|
||||
id="tspan66"
|
||||
x="659.12402"
|
||||
y="418.543"
|
||||
style="font-size:13.3333px;text-align:center;text-anchor:middle;fill:#ffffff;fill-opacity:1">5</tspan></text>
|
||||
<text
|
||||
id="TNn-3"
|
||||
x="754.21326"
|
||||
y="368.78839"
|
||||
style="font-size:13.3333px"><tspan
|
||||
sodipodi:role="line"
|
||||
id="tspan65-5"
|
||||
x="754.21326"
|
||||
y="368.78839"
|
||||
style="font-size:13.3333px;text-align:center;text-anchor:middle;fill:#ffffff;fill-opacity:1">SC</tspan><tspan
|
||||
sodipodi:role="line"
|
||||
id="tspan66-5"
|
||||
x="754.21326"
|
||||
y="385.45502"
|
||||
style="font-size:13.3333px;text-align:center;text-anchor:middle;fill:#ffffff;fill-opacity:1">7</tspan></text>
|
||||
<text
|
||||
id="KYn"
|
||||
x="756.65363"
|
||||
y="277.30893"
|
||||
style="font-size:13.3333px"><tspan
|
||||
sodipodi:role="line"
|
||||
id="tspan69"
|
||||
x="756.65363"
|
||||
y="277.30893"
|
||||
style="font-size:13.3333px;text-align:center;text-anchor:middle;fill:#ffffff">VA</tspan><tspan
|
||||
sodipodi:role="line"
|
||||
id="tspan70"
|
||||
x="756.65363"
|
||||
y="293.97556"
|
||||
style="font-size:13.3333px;text-align:center;text-anchor:middle;fill:#ffffff">10</tspan></text>
|
||||
<text
|
||||
id="VAn"
|
||||
x="771.05426"
|
||||
y="282.73816"
|
||||
style="font-size:13.3333px"><tspan
|
||||
sodipodi:role="line"
|
||||
id="tspan86"
|
||||
x="771.05426"
|
||||
y="282.73816"
|
||||
style="font-size:13.3333px;fill:#ffffff" /></text>
|
||||
<text
|
||||
id="PAn"
|
||||
x="779.22137"
|
||||
y="210.08958"
|
||||
style="font-size:13.3333px"><tspan
|
||||
sodipodi:role="line"
|
||||
id="tspan87"
|
||||
x="779.22137"
|
||||
y="210.08958"
|
||||
style="font-size:13.3333px;text-align:center;text-anchor:middle;fill:#ffffff">PA</tspan><tspan
|
||||
sodipodi:role="line"
|
||||
id="tspan88"
|
||||
x="779.22137"
|
||||
y="226.75621"
|
||||
style="font-size:13.3333px;text-align:center;text-anchor:middle;fill:#ffffff">10</tspan></text>
|
||||
<text
|
||||
id="MEn"
|
||||
x="891.53564"
|
||||
y="78.833321"
|
||||
style="font-size:13.3333px"><tspan
|
||||
sodipodi:role="line"
|
||||
id="tspan62"
|
||||
x="891.53564"
|
||||
y="78.833321"
|
||||
style="font-size:13.3333px;text-align:center;text-anchor:middle;fill:#ffffff" /></text>
|
||||
<text
|
||||
id="MEn-9"
|
||||
x="885.10718"
|
||||
y="80.869125"
|
||||
style="font-size:14.7521px;stroke-width:0.52686"><tspan
|
||||
sodipodi:role="line"
|
||||
id="tspan4"
|
||||
x="885.10718"
|
||||
y="80.869125"
|
||||
style="fill:#ffffff;stroke-width:0.52686" /><tspan
|
||||
sodipodi:role="line"
|
||||
id="tspan5"
|
||||
x="885.10718"
|
||||
y="99.30925"
|
||||
style="fill:#ffffff;stroke-width:0.52686" /></text>
|
||||
<text
|
||||
id="MEn-9-7"
|
||||
x="877.93567"
|
||||
y="111.5111"
|
||||
style="font-size:14.7521px;stroke-width:0.52686"><tspan
|
||||
sodipodi:role="line"
|
||||
id="tspan4-0"
|
||||
x="877.93567"
|
||||
y="111.5111"
|
||||
style="fill:#ffffff;stroke-width:0.52686" /><tspan
|
||||
sodipodi:role="line"
|
||||
id="tspan5-9"
|
||||
x="877.93567"
|
||||
y="129.95123"
|
||||
style="fill:#ffffff;stroke-width:0.52686" /></text>
|
||||
<text
|
||||
id="MEn-9-0"
|
||||
x="463.3028"
|
||||
y="239.15771"
|
||||
style="font-size:14.7521px;stroke-width:0.52686"><tspan
|
||||
sodipodi:role="line"
|
||||
id="tspan4-6"
|
||||
x="463.3028"
|
||||
y="239.15771"
|
||||
style="fill:#ffffff;fill-opacity:1;stroke-width:0.52686" /><tspan
|
||||
sodipodi:role="line"
|
||||
id="tspan5-2"
|
||||
x="463.3028"
|
||||
y="257.59784"
|
||||
style="fill:#ffffff;fill-opacity:1;stroke-width:0.52686" /></text>
|
||||
<text
|
||||
id="DemL"
|
||||
x="855"
|
||||
y="425" />
|
||||
<text
|
||||
id="RepL"
|
||||
x="855"
|
||||
y="458" />
|
||||
</g>
|
||||
<g
|
||||
font-size="22px"
|
||||
id="g2">
|
||||
<text
|
||||
id="NHn"
|
||||
x="817.56848"
|
||||
y="56.648579"
|
||||
style="font-size:16px"><tspan
|
||||
style="font-size:16px;fill:#ffffff"
|
||||
id="tspan92">NH 5</tspan></text>
|
||||
<text
|
||||
id="MAn"
|
||||
x="905.17847"
|
||||
y="169.01566"
|
||||
style="font-size:13.3333px"><tspan
|
||||
style="font-size:13.3333px;fill:#ffffff"
|
||||
id="tspan94">MA 10</tspan></text>
|
||||
<text
|
||||
id="RIn"
|
||||
x="925"
|
||||
y="199"
|
||||
style="font-size:16px"><tspan
|
||||
style="font-size:16px;fill:#ffffff"
|
||||
id="tspan95" /></text>
|
||||
<text
|
||||
id="CTn"
|
||||
x="918"
|
||||
y="228"
|
||||
style="font-size:16px"><tspan
|
||||
style="fill:#ffffff"
|
||||
id="tspan96">CT 7</tspan></text>
|
||||
<text
|
||||
id="NJn"
|
||||
x="898"
|
||||
y="260"
|
||||
style="font-size:16px"><tspan
|
||||
style="fill:#ffffff"
|
||||
id="tspan97">NJ 6</tspan></text>
|
||||
<text
|
||||
id="DEn"
|
||||
x="891"
|
||||
y="284"
|
||||
style="font-size:16px"><tspan
|
||||
style="font-size:16px;fill:#ffffff"
|
||||
id="tspan98">DE 3</tspan></text>
|
||||
<text
|
||||
id="MDn"
|
||||
x="883"
|
||||
y="305"
|
||||
style="font-size:16px"><tspan
|
||||
style="font-size:16px;fill:#ffffff"
|
||||
id="tspan99">MD 6</tspan></text>
|
||||
<text
|
||||
id="DCn"
|
||||
x="864"
|
||||
y="327"
|
||||
style="font-size:16px"><tspan
|
||||
style="font-size:16px;fill:#ffffff"
|
||||
id="tspan100" /></text>
|
||||
</g>
|
||||
</g>
|
||||
<path
|
||||
d="m 304.45211,224.13438 c 36.981,39.184 39.104,40.251 39.104,40.251"
|
||||
stroke-width="1.5242"
|
||||
stroke="#000000"
|
||||
fill="none"
|
||||
id="path5643"
|
||||
style="fill:#ffffff;stroke-linecap:round" />
|
||||
<path
|
||||
d="m 309.80711,214.28538 c 51,26 51,26 51,26"
|
||||
stroke-width="1.5"
|
||||
stroke="#000000"
|
||||
fill="none"
|
||||
id="path8572"
|
||||
style="fill:#ffffff;stroke-linecap:round" />
|
||||
<path
|
||||
d="m 317.80711,194.28538 c 50,22 50,22 50,22"
|
||||
stroke-width="1.5"
|
||||
stroke="#000000"
|
||||
fill="none"
|
||||
id="path9543"
|
||||
style="fill:#ffffff;stroke-linecap:round" />
|
||||
<path
|
||||
d="m 361.80711,117.28538 c 34,3 34,3 34,3"
|
||||
stroke-width="1.5"
|
||||
stroke="#000000"
|
||||
fill="none"
|
||||
id="path11485"
|
||||
style="fill:#ffffff;stroke-linecap:round" />
|
||||
<path
|
||||
d="m 338.80711,148.28538 c 50,33 51,33 51,33"
|
||||
stroke-width="1.5"
|
||||
stroke="#000000"
|
||||
fill="none"
|
||||
id="path13435"
|
||||
style="fill:#ffffff;stroke-linecap:round" />
|
||||
<path
|
||||
d="m 330.04111,55.519381 c -13.469,-29.469 -13.469,-29.469 -13.469,-29.469"
|
||||
stroke-width="1.5"
|
||||
stroke="#000000"
|
||||
fill="none"
|
||||
id="path14422"
|
||||
style="fill:#ffffff;stroke-linecap:round" />
|
||||
<path
|
||||
d="m 395.64811,120.12638 c -22.682,-40.682003 -22.682,-40.682003 -22.682,-40.682003"
|
||||
stroke-width="2.2871"
|
||||
stroke="#000000"
|
||||
fill="none"
|
||||
id="path9642"
|
||||
style="fill:#ffffff;stroke-width:1.5;stroke-linecap:round;stroke-miterlimit:4;stroke-dasharray:none" />
|
||||
<!--
|
||||
<rect id="Dem" x="828" y="406" height="19" width="19" fill="#698DC5" stroke="#000000" stroke-width="0.8"/>
|
||||
<rect id="Rep" x="828" y="439" height="19" width="19" fill="#F07763" stroke="#000000" stroke-width="0.8"/>
|
||||
-->
|
||||
</svg>
|
After Width: | Height: | Size: 36 KiB |
|
@ -1,4 +1,5 @@
|
|||
import {ApplicationCommandOptionType} from "discord.js";
|
||||
import Elections from "./elections/elections.js";
|
||||
const commands = [
|
||||
{
|
||||
name: 'poll',
|
||||
|
@ -6,33 +7,54 @@ const commands = [
|
|||
},
|
||||
{
|
||||
name: 'simulate',
|
||||
description: "Simulate the 2024 United States Presidential Election",
|
||||
description: "Simulate an election",
|
||||
options: [
|
||||
{
|
||||
name: 'bias',
|
||||
description: 'Adds a bias to a certain candidate. Use a positive number for Biden bias, negative for Trump bias',
|
||||
type: ApplicationCommandOptionType.Number,
|
||||
name: 'election',
|
||||
description: 'The election to simulate',
|
||||
type: ApplicationCommandOptionType.SubcommandGroup,
|
||||
options: Object.keys(Elections).map(e => {
|
||||
return {
|
||||
name: e,
|
||||
description: Elections[e].title,
|
||||
type: ApplicationCommandOptionType.Subcommand,
|
||||
options: [
|
||||
{
|
||||
name: 'add_candidate',
|
||||
description: 'Add a candidate to the election',
|
||||
type: ApplicationCommandOptionType.String,
|
||||
},
|
||||
{
|
||||
name: 'with_party',
|
||||
description: 'The party of the candidate to add',
|
||||
type: ApplicationCommandOptionType.String,
|
||||
},
|
||||
{
|
||||
name: 'with_color',
|
||||
description: 'Hex color of the candidate to add',
|
||||
type: ApplicationCommandOptionType.String
|
||||
},
|
||||
{
|
||||
name: 'with_odds',
|
||||
description: 'The odds of the candidate to win in any state',
|
||||
type: ApplicationCommandOptionType.Number
|
||||
},
|
||||
...Elections[e].candidates.flatMap(c => [
|
||||
{
|
||||
name: c.party.toLowerCase().replace(/ /g, "_") + "_candidate",
|
||||
description: `The candidate to simulate for the ${c.party} party (Default: ${c.name})`,
|
||||
type: ApplicationCommandOptionType.String
|
||||
},
|
||||
{
|
||||
name: c.party.toLowerCase().replace(/ /g, "_") + "_bias",
|
||||
description: `The bias toward the ${c.party} party (Default: 0)`,
|
||||
type: ApplicationCommandOptionType.Number
|
||||
}
|
||||
])
|
||||
],
|
||||
};
|
||||
})
|
||||
},
|
||||
{
|
||||
name: 'type',
|
||||
description: 'The type of election to simulate. Valid options are senate and presidential (default: presidential)',
|
||||
type: ApplicationCommandOptionType.String,
|
||||
},
|
||||
{
|
||||
name: 'year',
|
||||
description: 'The year to set the simulation to (default: 2024)',
|
||||
type: ApplicationCommandOptionType.Number,
|
||||
},
|
||||
{
|
||||
name: 'gopcandidate',
|
||||
description: 'The GOP candidate to simulate (default: Donald Trump)',
|
||||
type: ApplicationCommandOptionType.String,
|
||||
},
|
||||
{
|
||||
name: 'demcandidate',
|
||||
description: 'The Democratic candidate to simulate (default: Joe Biden)',
|
||||
type: ApplicationCommandOptionType.String,
|
||||
}
|
||||
],
|
||||
}
|
||||
];
|
||||
|
|
19
src/election.ts
Normal file
19
src/election.ts
Normal file
|
@ -0,0 +1,19 @@
|
|||
export default interface Election {
|
||||
title : string,
|
||||
shortname : string,
|
||||
description : string,
|
||||
svg: string,
|
||||
candidates : {
|
||||
name : string,
|
||||
party : string,
|
||||
color : string
|
||||
}[],
|
||||
states : {
|
||||
[key : string] : {
|
||||
electoralVotes : number,
|
||||
odds : {
|
||||
[key : string] : number
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
214
src/elections/1864.ts
Normal file
214
src/elections/1864.ts
Normal file
|
@ -0,0 +1,214 @@
|
|||
import { readFile } from "node:fs/promises";
|
||||
import Election from "../election.js";
|
||||
|
||||
const Presidential_1864 = {
|
||||
title: "1864 United States Presidential Election Simulator",
|
||||
shortname: "1864",
|
||||
description: "The CalubViem Press has rewritten history and called the 1864 United States Presidential Election for $WINNER!",
|
||||
svg: await readFile("assets/ElectoralCollege1864.svg", "utf-8"),
|
||||
candidates: [
|
||||
{
|
||||
name: "Abraham Lincoln",
|
||||
party: "National Union",
|
||||
color: "#BF1D29",
|
||||
},
|
||||
{
|
||||
name: "George B. McClellan",
|
||||
party: "Democratic",
|
||||
color: "#1C408C",
|
||||
},
|
||||
],
|
||||
states: {
|
||||
"CA": {
|
||||
electoralVotes: 5,
|
||||
odds: {
|
||||
"National Union": 0.7,
|
||||
"Democratic": 0.3,
|
||||
}
|
||||
},
|
||||
"CT": {
|
||||
electoralVotes: 6,
|
||||
odds: {
|
||||
"National Union": 0.6,
|
||||
"Democratic": 0.4,
|
||||
}
|
||||
},
|
||||
"DE": {
|
||||
electoralVotes: 3,
|
||||
odds: {
|
||||
"National Union": 0.5,
|
||||
"Democratic": 0.5,
|
||||
}
|
||||
},
|
||||
"IA": {
|
||||
electoralVotes: 8,
|
||||
odds: {
|
||||
"National Union": 0.95,
|
||||
"Democratic": 0.05,
|
||||
}
|
||||
},
|
||||
"IL": {
|
||||
electoralVotes: 16,
|
||||
odds: {
|
||||
"National Union": 0.8,
|
||||
"Democratic": 0.2,
|
||||
}
|
||||
},
|
||||
"IN": {
|
||||
electoralVotes: 13,
|
||||
odds: {
|
||||
"National Union": 0.6,
|
||||
"Democratic": 0.4,
|
||||
}
|
||||
},
|
||||
"KS": {
|
||||
electoralVotes: 3,
|
||||
odds: {
|
||||
"National Union": 1,
|
||||
"Democratic": 0,
|
||||
}
|
||||
},
|
||||
"KY": {
|
||||
electoralVotes: 11,
|
||||
odds: {
|
||||
"National Union": 0.2,
|
||||
"Democratic": 0.8,
|
||||
}
|
||||
},
|
||||
"LA": {
|
||||
electoralVotes: 7,
|
||||
odds: {
|
||||
"National Union": 0.2,
|
||||
"Democratic": 0.8,
|
||||
}
|
||||
},
|
||||
"MA": {
|
||||
electoralVotes: 12,
|
||||
odds: {
|
||||
"National Union": 1,
|
||||
"Democratic": 0,
|
||||
}
|
||||
},
|
||||
"MD": {
|
||||
electoralVotes: 7,
|
||||
odds: {
|
||||
"National Union": 0.7,
|
||||
"Democratic": 0.3,
|
||||
}
|
||||
},
|
||||
"ME": {
|
||||
electoralVotes: 7,
|
||||
odds: {
|
||||
"National Union": 0.9,
|
||||
"Democratic": 0.1,
|
||||
}
|
||||
},
|
||||
"MI": {
|
||||
electoralVotes: 8,
|
||||
odds: {
|
||||
"National Union": 0.7,
|
||||
"Democratic": 0.3,
|
||||
}
|
||||
},
|
||||
"MN": {
|
||||
electoralVotes: 4,
|
||||
odds: {
|
||||
"National Union": 0.8,
|
||||
"Democratic": 0.2,
|
||||
}
|
||||
},
|
||||
"MO": {
|
||||
electoralVotes: 11,
|
||||
odds: {
|
||||
"National Union": 0.99,
|
||||
"Democratic": 0.01,
|
||||
}
|
||||
},
|
||||
"NH": {
|
||||
electoralVotes: 5,
|
||||
odds: {
|
||||
"National Union": 0.6,
|
||||
"Democratic": 0.4,
|
||||
}
|
||||
},
|
||||
"NV": {
|
||||
electoralVotes: 2,
|
||||
odds: {
|
||||
"National Union": 0.9,
|
||||
"Democratic": 0.1,
|
||||
}
|
||||
},
|
||||
"NJ": {
|
||||
electoralVotes: 7,
|
||||
odds: {
|
||||
"National Union": 0.4,
|
||||
"Democratic": 0.6,
|
||||
}
|
||||
},
|
||||
"NY": {
|
||||
electoralVotes: 33,
|
||||
odds: {
|
||||
"National Union": 0.55,
|
||||
"Democratic": 0.45,
|
||||
}
|
||||
},
|
||||
"OH": {
|
||||
electoralVotes: 21,
|
||||
odds: {
|
||||
"National Union": 0.7,
|
||||
"Democratic": 0.3,
|
||||
}
|
||||
},
|
||||
"OR": {
|
||||
electoralVotes: 3,
|
||||
odds: {
|
||||
"National Union": 0.7,
|
||||
"Democratic": 0.3,
|
||||
}
|
||||
},
|
||||
"PA": {
|
||||
electoralVotes: 26,
|
||||
odds: {
|
||||
"National Union": 0.6,
|
||||
"Democratic": 0.4,
|
||||
}
|
||||
},
|
||||
"RI": {
|
||||
electoralVotes: 4,
|
||||
odds: {
|
||||
"National Union": 0.95,
|
||||
"Democratic": 0.05,
|
||||
}
|
||||
},
|
||||
"TN": {
|
||||
electoralVotes: 10,
|
||||
odds: {
|
||||
"National Union": 1,
|
||||
"Democratic": 0,
|
||||
}
|
||||
},
|
||||
"VT": {
|
||||
electoralVotes: 5,
|
||||
odds: {
|
||||
"National Union": 1,
|
||||
"Democratic": 0,
|
||||
}
|
||||
},
|
||||
"WI": {
|
||||
electoralVotes: 8,
|
||||
odds: {
|
||||
"National Union": 0.7,
|
||||
"Democratic": 0.3,
|
||||
}
|
||||
},
|
||||
"WV": {
|
||||
electoralVotes: 5,
|
||||
odds: {
|
||||
"National Union": 0.99,
|
||||
"Democratic": 0.01,
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
export default Presidential_1864 as Election;
|
403
src/elections/2024.ts
Normal file
403
src/elections/2024.ts
Normal file
|
@ -0,0 +1,403 @@
|
|||
import { readFile } from "node:fs/promises";
|
||||
import Election from "../election.js";
|
||||
|
||||
const Presidential_2024 = {
|
||||
title: "2024 United States Presidential Election Simulator",
|
||||
shortname: "2024",
|
||||
description: "The CalubViem Press has called the 2024 United States Presidential Election for $WINNER!",
|
||||
svg: await readFile("assets/ElectoralCollege2024.svg", "utf-8"),
|
||||
candidates: [
|
||||
{
|
||||
name: "Joseph R. Biden Jr.",
|
||||
party: "Democratic",
|
||||
color: "#1C408C",
|
||||
},
|
||||
{
|
||||
name: "Donald J. Trump",
|
||||
party: "Republican",
|
||||
color: "#BF1D29",
|
||||
}
|
||||
],
|
||||
states: {
|
||||
"AL": {
|
||||
electoralVotes: 9,
|
||||
odds: {
|
||||
"Republican": 1,
|
||||
"Democratic": 0,
|
||||
}
|
||||
},
|
||||
"AK": {
|
||||
electoralVotes: 3,
|
||||
odds: {
|
||||
"Republican": 1,
|
||||
"Democratic": 0,
|
||||
}
|
||||
},
|
||||
"AZ": {
|
||||
electoralVotes: 11,
|
||||
odds: {
|
||||
"Republican": 0.5,
|
||||
"Democratic": 0.5,
|
||||
}
|
||||
},
|
||||
"AR": {
|
||||
electoralVotes: 6,
|
||||
odds: {
|
||||
"Republican": 1,
|
||||
"Democratic": 0,
|
||||
}
|
||||
},
|
||||
"CA": {
|
||||
electoralVotes: 54,
|
||||
odds: {
|
||||
"Republican": 0,
|
||||
"Democratic": 1,
|
||||
}
|
||||
},
|
||||
"CO": {
|
||||
electoralVotes: 10,
|
||||
odds: {
|
||||
"Republican": 0,
|
||||
"Democratic": 1,
|
||||
}
|
||||
},
|
||||
"CT": {
|
||||
electoralVotes: 7,
|
||||
odds: {
|
||||
"Republican": 0,
|
||||
"Democratic": 1,
|
||||
}
|
||||
},
|
||||
"DE": {
|
||||
electoralVotes: 3,
|
||||
odds: {
|
||||
"Republican": 0,
|
||||
"Democratic": 1,
|
||||
}
|
||||
},
|
||||
"DC": {
|
||||
electoralVotes: 3,
|
||||
odds: {
|
||||
"Republican": 0,
|
||||
"Democratic": 1,
|
||||
}
|
||||
},
|
||||
"FL": {
|
||||
electoralVotes: 30,
|
||||
odds: {
|
||||
"Republican": 0.6,
|
||||
"Democratic": 0.4,
|
||||
}
|
||||
},
|
||||
"GA": {
|
||||
electoralVotes: 16,
|
||||
odds: {
|
||||
"Republican": 0.5,
|
||||
"Democratic": 0.5,
|
||||
}
|
||||
},
|
||||
"HI": {
|
||||
electoralVotes: 4,
|
||||
odds: {
|
||||
"Republican": 0,
|
||||
"Democratic": 1,
|
||||
}
|
||||
},
|
||||
"ID": {
|
||||
electoralVotes: 4,
|
||||
odds: {
|
||||
"Republican": 1,
|
||||
"Democratic": 0,
|
||||
}
|
||||
},
|
||||
"IL": {
|
||||
electoralVotes: 19,
|
||||
odds: {
|
||||
"Republican": 0,
|
||||
"Democratic": 1,
|
||||
}
|
||||
},
|
||||
"IN": {
|
||||
electoralVotes: 11,
|
||||
odds: {
|
||||
"Republican": 1,
|
||||
"Democratic": 0,
|
||||
}
|
||||
},
|
||||
"IA": {
|
||||
electoralVotes: 6,
|
||||
odds: {
|
||||
"Republican": 0.8,
|
||||
"Democratic": 0.2,
|
||||
}
|
||||
},
|
||||
"KS": {
|
||||
electoralVotes: 6,
|
||||
odds: {
|
||||
"Republican": 1,
|
||||
"Democratic": 0,
|
||||
}
|
||||
},
|
||||
"KY": {
|
||||
electoralVotes: 8,
|
||||
odds: {
|
||||
"Republican": 1,
|
||||
"Democratic": 0,
|
||||
}
|
||||
},
|
||||
"LA": {
|
||||
electoralVotes: 8,
|
||||
odds: {
|
||||
"Republican": 1,
|
||||
"Democratic": 0,
|
||||
}
|
||||
},
|
||||
"ME": {
|
||||
electoralVotes: 2,
|
||||
odds: {
|
||||
"Republican": 0.2,
|
||||
"Democratic": 0.8,
|
||||
}
|
||||
},
|
||||
"ME-01": {
|
||||
electoralVotes: 1,
|
||||
odds: {
|
||||
"Republican": 0,
|
||||
"Democratic": 1,
|
||||
}
|
||||
},
|
||||
"ME-02": {
|
||||
electoralVotes: 1,
|
||||
odds: {
|
||||
"Republican": 0.8,
|
||||
"Democratic": 0.2,
|
||||
}
|
||||
},
|
||||
"MD": {
|
||||
electoralVotes: 10,
|
||||
odds: {
|
||||
"Republican": 0,
|
||||
"Democratic": 1,
|
||||
}
|
||||
},
|
||||
"MA": {
|
||||
electoralVotes: 11,
|
||||
odds: {
|
||||
"Republican": 0,
|
||||
"Democratic": 1,
|
||||
}
|
||||
},
|
||||
"MI": {
|
||||
electoralVotes: 15,
|
||||
odds: {
|
||||
"Republican": 0.5,
|
||||
"Democratic": 0.5,
|
||||
}
|
||||
},
|
||||
"MN": {
|
||||
electoralVotes: 10,
|
||||
odds: {
|
||||
"Republican": 0.4,
|
||||
"Democratic": 0.6,
|
||||
}
|
||||
},
|
||||
"MS": {
|
||||
electoralVotes: 6,
|
||||
odds: {
|
||||
"Republican": 1,
|
||||
"Democratic": 0,
|
||||
}
|
||||
},
|
||||
"MO": {
|
||||
electoralVotes: 10,
|
||||
odds: {
|
||||
"Republican": 1,
|
||||
"Democratic": 0,
|
||||
}
|
||||
},
|
||||
"MT": {
|
||||
electoralVotes: 4,
|
||||
odds: {
|
||||
"Republican": 1,
|
||||
"Democratic": 0,
|
||||
}
|
||||
},
|
||||
"NE": {
|
||||
electoralVotes: 4,
|
||||
odds: {
|
||||
"Republican": 1,
|
||||
"Democratic": 0,
|
||||
}
|
||||
},
|
||||
"NE-02": {
|
||||
electoralVotes: 1,
|
||||
odds: {
|
||||
"Republican": 0.55,
|
||||
"Democratic": 0.45,
|
||||
}
|
||||
},
|
||||
"NV": {
|
||||
electoralVotes: 6,
|
||||
odds: {
|
||||
"Republican": 0.5,
|
||||
"Democratic": 0.5,
|
||||
}
|
||||
},
|
||||
"NH": {
|
||||
electoralVotes: 4,
|
||||
odds: {
|
||||
"Republican": 0.4,
|
||||
"Democratic": 0.6,
|
||||
}
|
||||
},
|
||||
"NJ": {
|
||||
electoralVotes: 14,
|
||||
odds: {
|
||||
"Republican": 0,
|
||||
"Democratic": 1,
|
||||
}
|
||||
},
|
||||
"NM": {
|
||||
electoralVotes: 5,
|
||||
odds: {
|
||||
"Republican": 0,
|
||||
"Democratic": 1,
|
||||
}
|
||||
},
|
||||
"NY": {
|
||||
electoralVotes: 28,
|
||||
odds: {
|
||||
"Republican": 0,
|
||||
"Democratic": 1,
|
||||
}
|
||||
},
|
||||
"NC": {
|
||||
electoralVotes: 16,
|
||||
odds: {
|
||||
"Republican": 0.55,
|
||||
"Democratic": 0.45,
|
||||
}
|
||||
},
|
||||
"ND": {
|
||||
electoralVotes: 3,
|
||||
odds: {
|
||||
"Republican": 1,
|
||||
"Democratic": 0,
|
||||
}
|
||||
},
|
||||
"OH": {
|
||||
electoralVotes: 17,
|
||||
odds: {
|
||||
"Republican": 0.8,
|
||||
"Democratic": 0.2,
|
||||
}
|
||||
},
|
||||
"OK": {
|
||||
electoralVotes: 7,
|
||||
odds: {
|
||||
"Republican": 1,
|
||||
"Democratic": 0,
|
||||
}
|
||||
},
|
||||
"OR": {
|
||||
electoralVotes: 8,
|
||||
odds: {
|
||||
"Republican": 0,
|
||||
"Democratic": 1,
|
||||
}
|
||||
},
|
||||
"PA": {
|
||||
electoralVotes: 19,
|
||||
odds: {
|
||||
"Republican": 0.5,
|
||||
"Democratic": 0.5,
|
||||
}
|
||||
},
|
||||
"RI": {
|
||||
electoralVotes: 4,
|
||||
odds: {
|
||||
"Republican": 0,
|
||||
"Democratic": 1,
|
||||
}
|
||||
},
|
||||
"SC": {
|
||||
electoralVotes: 9,
|
||||
odds: {
|
||||
"Republican": 1,
|
||||
"Democratic": 0,
|
||||
}
|
||||
},
|
||||
"SD": {
|
||||
electoralVotes: 3,
|
||||
odds: {
|
||||
"Republican": 1,
|
||||
"Democratic": 0,
|
||||
}
|
||||
},
|
||||
"TN": {
|
||||
electoralVotes: 11,
|
||||
odds: {
|
||||
"Republican": 1,
|
||||
"Democratic": 0,
|
||||
}
|
||||
},
|
||||
"TX": {
|
||||
electoralVotes: 40,
|
||||
odds: {
|
||||
"Republican": 0.8,
|
||||
"Democratic": 0.2,
|
||||
}
|
||||
},
|
||||
"UT": {
|
||||
electoralVotes: 6,
|
||||
odds: {
|
||||
"Republican": 1,
|
||||
"Democratic": 0,
|
||||
}
|
||||
},
|
||||
"VT": {
|
||||
electoralVotes: 3,
|
||||
odds: {
|
||||
"Republican": 0,
|
||||
"Democratic": 1,
|
||||
}
|
||||
},
|
||||
"VA": {
|
||||
electoralVotes: 13,
|
||||
odds: {
|
||||
"Republican": 0.2,
|
||||
"Democratic": 0.8,
|
||||
}
|
||||
},
|
||||
"WA": {
|
||||
electoralVotes: 12,
|
||||
odds: {
|
||||
"Republican": 0,
|
||||
"Democratic": 1,
|
||||
}
|
||||
},
|
||||
"WV": {
|
||||
electoralVotes: 4,
|
||||
odds: {
|
||||
"Republican": 1,
|
||||
"Democratic": 0,
|
||||
}
|
||||
},
|
||||
"WI": {
|
||||
electoralVotes: 10,
|
||||
odds: {
|
||||
"Republican": 0.5,
|
||||
"Democratic": 0.5,
|
||||
}
|
||||
},
|
||||
"WY": {
|
||||
electoralVotes: 3,
|
||||
odds: {
|
||||
"Republican": 1,
|
||||
"Democratic": 0,
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export default Presidential_2024 as Election;
|
10
src/elections/elections.ts
Normal file
10
src/elections/elections.ts
Normal file
|
@ -0,0 +1,10 @@
|
|||
import Election from "../election.js";
|
||||
import Presidential_1864 from "./1864.js";
|
||||
import Presidential_2024 from "./2024.js";
|
||||
|
||||
const Elections = {
|
||||
"1864": Presidential_1864,
|
||||
"2024": Presidential_2024
|
||||
}
|
||||
|
||||
export default (Elections as {[key : string] : Election})
|
103
src/index.ts
103
src/index.ts
|
@ -1,7 +1,10 @@
|
|||
import {REST, Routes, Client, GatewayIntentBits, CommandInteraction, EmbedBuilder } from "discord.js";
|
||||
import {REST, Routes, Client, GatewayIntentBits, CommandInteraction, EmbedBuilder, CommandInteractionOption, CommandInteractionOptionResolver } from "discord.js";
|
||||
import * as fs from "node:fs";
|
||||
import commands from "./commands.js";
|
||||
import {MakePrediction} from "./predictor.js";
|
||||
import Election from "./election.js";
|
||||
import Presidential_2024 from "./elections/2024.js";
|
||||
import Elections from "./elections/elections.js";
|
||||
|
||||
const configraw = fs.readFileSync("config.json", "utf-8");
|
||||
const config = JSON.parse(configraw);
|
||||
|
@ -31,59 +34,57 @@ if (!config.token) {
|
|||
await i.reply(`Biden Approval Rating\n\n${polls}`);
|
||||
break;
|
||||
case "simulate":
|
||||
var simulationtype = i.options.get('type')?.value as string || "presidential";
|
||||
var year = Number(i.options.get('year')?.value);
|
||||
var electionname = (i.options as CommandInteractionOptionResolver).getSubcommand();
|
||||
|
||||
switch(simulationtype) {
|
||||
case "presidential":
|
||||
if (year == 1864) {
|
||||
var gopcandidate = i.options.get('gopcandidate')?.value as string || "Abraham Lincoln";
|
||||
var demcandidate = i.options.get('demcandidate')?.value as string || "George B. McClellan";
|
||||
var result = await MakePrediction(Number(i.options.get('bias')?.value), gopcandidate, demcandidate, simulationtype, Number(i.options.get('year')?.value));
|
||||
var embed = new EmbedBuilder()
|
||||
.setTitle("1864 United States Presidential Election Simulator")
|
||||
.setDescription(`The CalubViem Press has rewritten history, and has called the 1864 United States Presidential Election for ${result.winner}!`)
|
||||
.addFields(
|
||||
{name: `${result.winner === gopcandidate ? ":white_check_mark:" : ""} ${gopcandidate}`, value: `${result.gopVotes} Electoral Votes`, inline: true},
|
||||
{name: `${result.winner === demcandidate ? ":white_check_mark:" : ""} ${demcandidate}`, value: `${result.demVotes} Electoral Votes`, inline: true},
|
||||
)
|
||||
.setImage("attachment://election.png")
|
||||
.setTimestamp();
|
||||
await i.reply({embeds: [embed], files: [{attachment: result.png, name: "election.png"}]});
|
||||
break;
|
||||
} else {
|
||||
var gopcandidate = i.options.get('gopcandidate')?.value as string || "Donald J. Trump";
|
||||
var demcandidate = i.options.get('demcandidate')?.value as string || "Joseph R. Biden Jr.";
|
||||
var result = await MakePrediction(Number(i.options.get('bias')?.value), gopcandidate, demcandidate, simulationtype, Number(i.options.get('year')?.value));
|
||||
var embed = new EmbedBuilder()
|
||||
.setTitle("2024 United States Presidential Election Simulator")
|
||||
.setDescription(`The CalubViem Press has called the 2024 United States Presidential Election for ${result.winner}!`)
|
||||
.addFields(
|
||||
{name: `${result.winner === gopcandidate ? ":white_check_mark:" : ""} ${gopcandidate}`, value: `${result.gopVotes} Electoral Votes`, inline: true},
|
||||
{name: `${result.winner === demcandidate ? ":white_check_mark:" : ""} ${demcandidate}`, value: `${result.demVotes} Electoral Votes`, inline: true},
|
||||
)
|
||||
.setImage("attachment://election.png")
|
||||
.setTimestamp();
|
||||
await i.reply({embeds: [embed], files: [{attachment: result.png, name: "election.png"}]});
|
||||
break;
|
||||
var election = structuredClone(Elections[electionname]);
|
||||
for (const candidate of election.candidates) {
|
||||
var option = (i.options as CommandInteractionOptionResolver).getString(candidate.party.toLowerCase().replace(/ /g, "_") + "_candidate");
|
||||
if (option) {
|
||||
candidate.name = option;
|
||||
}
|
||||
var bias = (i.options as CommandInteractionOptionResolver).getNumber(candidate.party.toLowerCase().replace(/ /g, "_") + "_bias");
|
||||
if (bias) {
|
||||
for (const state of Object.keys(election.states)) {
|
||||
election.states[state].odds[candidate.party] += bias;
|
||||
}
|
||||
case "senate":
|
||||
var gopcandidate = i.options.get('gopcandidate')?.value as string || "Republicans";
|
||||
var demcandidate = i.options.get('demcandidate')?.value as string || "Democrats";
|
||||
var result = await MakePrediction(Number(i.options.get('bias')?.value), gopcandidate, demcandidate, simulationtype, 0);
|
||||
var embed = new EmbedBuilder()
|
||||
.setTitle("2024 United States Senate Simulator")
|
||||
.setDescription(`The CalubViem Press has called the 2024 United States Senate for ${result.winner}!`)
|
||||
.addFields(
|
||||
{name: `${result.winner === gopcandidate ? ":white_check_mark:" : ""} ${gopcandidate}`, value: `${result.gopVotes} seats`, inline: true},
|
||||
{name: `${result.winner === demcandidate ? ":white_check_mark:" : ""} ${demcandidate}`, value: `${result.demVotes} seats`, inline: true},
|
||||
)
|
||||
.setImage("attachment://election.png")
|
||||
.setTimestamp();
|
||||
await i.reply({embeds: [embed], files: [{attachment: result.png, name: "election.png"}]});
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
var newcandidate = (i.options as CommandInteractionOptionResolver).getString("add_candidate");
|
||||
if (newcandidate) {
|
||||
var party = (i.options as CommandInteractionOptionResolver).getString("with_party") || "Independent";
|
||||
var color = (i.options as CommandInteractionOptionResolver).getString("with_color") || "#bfab22";
|
||||
var odds = (i.options as CommandInteractionOptionResolver).getNumber("with_odds") || 0.33;
|
||||
if (!/^#[0-9A-Fa-f]{3,6}$/.test(color)) {
|
||||
await i.reply("Please provide a valid hex color code");
|
||||
return;
|
||||
}
|
||||
if (election.candidates.some(c => c.party === party || c.name === newcandidate)) {
|
||||
await i.reply("A candidate with that name or party already exists");
|
||||
return
|
||||
}
|
||||
election.candidates.push({
|
||||
name: newcandidate,
|
||||
party: party,
|
||||
color: color
|
||||
});
|
||||
for (const state of Object.keys(election.states))
|
||||
election.states[state].odds[party] = odds;
|
||||
}
|
||||
var result = await MakePrediction(election);
|
||||
var embed = new EmbedBuilder()
|
||||
.setTitle(election.title)
|
||||
.setDescription(election.description.replace("$WINNER", result.winner))
|
||||
.addFields(result.candidates.map(c => {
|
||||
return {
|
||||
name: `${(result.winner === c.name ? ":white_check_mark:" : "")} ${c.name} (${c.party})`,
|
||||
value: `${c.votes} Electoral Votes`,
|
||||
inline: true
|
||||
}
|
||||
}))
|
||||
.setImage("attachment://election.png")
|
||||
.setTimestamp();
|
||||
await i.reply({embeds: [embed], files: [{attachment: result.png, name: "election.png"}]});
|
||||
}
|
||||
}
|
||||
});
|
||||
|
|
236
src/numbers.ts
236
src/numbers.ts
|
@ -1,236 +0,0 @@
|
|||
const GOP_WIN_ODDS = {
|
||||
// Data from https://www.insideelections.com/ratings/president
|
||||
// Toss-up
|
||||
"AZ": 0.5,
|
||||
"GA": 0.5,
|
||||
"MI": 0.5,
|
||||
"NV": 0.5,
|
||||
"PA": 0.5,
|
||||
"WI": 0.5,
|
||||
// Lean D
|
||||
"MN": 0.4,
|
||||
"NH": 0.4,
|
||||
// Likely D
|
||||
"ME": 0.2,
|
||||
"VA": 0.2,
|
||||
// Solid D
|
||||
"CA": 0,
|
||||
"CO": 0,
|
||||
"CT": 0,
|
||||
"DC": 0,
|
||||
"DE": 0,
|
||||
"HI": 0,
|
||||
"IL": 0,
|
||||
"MA": 0,
|
||||
"MD": 0,
|
||||
"NJ": 0,
|
||||
"NM": 0,
|
||||
"NY": 0,
|
||||
"OR": 0,
|
||||
"RI": 0,
|
||||
"VT": 0,
|
||||
"WA": 0,
|
||||
"ME-01": 0,
|
||||
// Tilt R
|
||||
"NC": 0.55,
|
||||
"NE-02": 0.55,
|
||||
// Lean R
|
||||
"FL": 0.6,
|
||||
// Likely R
|
||||
"IA": 0.8,
|
||||
"OH": 0.8,
|
||||
"TX": 0.8,
|
||||
"ME-02": 0.8,
|
||||
// Solid R
|
||||
"AK": 1,
|
||||
"AL": 1,
|
||||
"AR": 1,
|
||||
"ID": 1,
|
||||
"IN": 1,
|
||||
"KS": 1,
|
||||
"KY": 1,
|
||||
"LA": 1,
|
||||
"MO": 1,
|
||||
"MS": 1,
|
||||
"MT": 1,
|
||||
"NE": 1,
|
||||
"ND": 1,
|
||||
"OK": 1,
|
||||
"SC": 1,
|
||||
"SD": 1,
|
||||
"TN": 1,
|
||||
"UT": 1,
|
||||
"WV": 1,
|
||||
"WY": 1
|
||||
};
|
||||
|
||||
const GOP_WIN_ODDS_1864 = {
|
||||
// Solid R
|
||||
"TN": 1,
|
||||
"KS": 1,
|
||||
"VT": 1,
|
||||
"MA": 1,
|
||||
// Likely R
|
||||
"MO": 0.99,
|
||||
"WV": 0.99,
|
||||
"IA": 0.95,
|
||||
"RI": 0.95,
|
||||
"NV": 0.9,
|
||||
"ME": 0.9,
|
||||
"IL": 0.8,
|
||||
"MN": 0.8,
|
||||
"CA": 0.7,
|
||||
"OH": 0.7,
|
||||
"WI": 0.7,
|
||||
"MD": 0.7,
|
||||
"OR": 0.7,
|
||||
"MI": 0.7,
|
||||
"IN": 0.6,
|
||||
"NH": 0.6,
|
||||
"PA": 0.6,
|
||||
"CT": 0.6,
|
||||
"NY": 0.55,
|
||||
"DE": 0.5,
|
||||
// Likely D
|
||||
"NJ": 0.4,
|
||||
"KY": 0.2,
|
||||
"LA": 0.2
|
||||
};
|
||||
|
||||
const GOP_WIN_ODDS_SENATE = {
|
||||
// Data from https://www.insideelections.com/ratings/senate
|
||||
// Toss-up
|
||||
"MT": 0.5,
|
||||
"OH": 0.5,
|
||||
// Tilt D
|
||||
"AZ": 0.4,
|
||||
"MI": 0.4,
|
||||
"NV": 0.4,
|
||||
"PA": 0.4,
|
||||
// Lean D
|
||||
"WI": 0.3,
|
||||
// Likely D
|
||||
"MD": 0.2,
|
||||
// Solid D
|
||||
"CA": 0,
|
||||
"CT": 0,
|
||||
"DE": 0,
|
||||
"HI": 0,
|
||||
"MA": 0,
|
||||
"ME": 0,
|
||||
"MN": 0,
|
||||
"NJ": 0,
|
||||
"NM": 0,
|
||||
"NY": 0,
|
||||
"RI": 0,
|
||||
"VA": 0,
|
||||
"VT": 0,
|
||||
"WA": 0,
|
||||
// Likely R
|
||||
"TX": 0.8,
|
||||
// Solid R
|
||||
"FL": 1,
|
||||
"IN": 1,
|
||||
"MO": 1,
|
||||
"MS": 1,
|
||||
"ND": 1,
|
||||
"NE": 1,
|
||||
"NE-02": 1,
|
||||
"TN": 1,
|
||||
"UT": 1,
|
||||
"WV": 1,
|
||||
"WY": 1
|
||||
}
|
||||
|
||||
const ELECTORAL_COLLEGE = {
|
||||
"AL": 9,
|
||||
"AK": 3,
|
||||
"AZ": 11,
|
||||
"AR": 6,
|
||||
"CA": 54,
|
||||
"CO": 10,
|
||||
"CT": 7,
|
||||
"DE": 3,
|
||||
"DC": 3,
|
||||
"FL": 30,
|
||||
"GA": 16,
|
||||
"HI": 4,
|
||||
"ID": 4,
|
||||
"IL": 19,
|
||||
"IN": 11,
|
||||
"IA": 6,
|
||||
"KS": 6,
|
||||
"KY": 8,
|
||||
"LA": 8,
|
||||
"ME": 2,
|
||||
"ME-01": 1,
|
||||
"ME-02": 1,
|
||||
"MD": 10,
|
||||
"MA": 11,
|
||||
"MI": 15,
|
||||
"MN": 10,
|
||||
"MS": 6,
|
||||
"MO": 10,
|
||||
"MT": 4,
|
||||
"NE": 4,
|
||||
"NE-02": 1,
|
||||
"NV": 6,
|
||||
"NH": 4,
|
||||
"NJ": 14,
|
||||
"NM": 5,
|
||||
"NY": 28,
|
||||
"NC": 16,
|
||||
"ND": 3,
|
||||
"OH": 17,
|
||||
"OK": 7,
|
||||
"OR": 8,
|
||||
"PA": 19,
|
||||
"RI": 4,
|
||||
"SC": 9,
|
||||
"SD": 3,
|
||||
"TN": 11,
|
||||
"TX": 40,
|
||||
"UT": 6,
|
||||
"VT": 3,
|
||||
"VA": 13,
|
||||
"WA": 12,
|
||||
"WV": 4,
|
||||
"WI": 10,
|
||||
"WY": 3
|
||||
};
|
||||
|
||||
const ELECTORAL_COLLEGE_1864 = {
|
||||
"CA": 5,
|
||||
"CT": 6,
|
||||
"DE": 3,
|
||||
"IA": 8,
|
||||
"IL": 16,
|
||||
"IN": 13,
|
||||
"KS": 3,
|
||||
"KY": 11,
|
||||
"LA": 7,
|
||||
"MA": 12,
|
||||
"MD": 7,
|
||||
"ME": 7,
|
||||
"MI": 8,
|
||||
"MN": 4,
|
||||
"MO": 11,
|
||||
"NH": 5,
|
||||
"NV": 2,
|
||||
"NJ": 7,
|
||||
"NY": 33,
|
||||
"OH": 21,
|
||||
"OR": 3,
|
||||
"PA": 26,
|
||||
"RI": 4,
|
||||
"TN": 10,
|
||||
"VT": 5,
|
||||
"WI": 8,
|
||||
"WV": 5
|
||||
};
|
||||
|
||||
export const ElectoralCollege = ELECTORAL_COLLEGE;
|
||||
export const ElectoralCollege1864 = ELECTORAL_COLLEGE_1864;
|
||||
export const GOPWinOddsSenate = GOP_WIN_ODDS_SENATE;
|
||||
export const GOPWinOdds1864 = GOP_WIN_ODDS_1864;
|
||||
export const GOPWinOdds = GOP_WIN_ODDS;
|
164
src/predictor.ts
164
src/predictor.ts
|
@ -1,134 +1,70 @@
|
|||
import { ElectoralCollege, ElectoralCollege1864, GOPWinOdds, GOPWinOdds1864, GOPWinOddsSenate } from "./numbers.js";
|
||||
import { createSVGWindow } from 'svgdom'
|
||||
import { SVG, registerWindow } from '@svgdotjs/svg.js'
|
||||
import * as fs from "node:fs/promises";
|
||||
import sharp from "sharp";
|
||||
import crypto from "crypto";
|
||||
import Election from "./election.js";
|
||||
|
||||
const BASE_SVG = await fs.readFile("assets/ElectoralCollege2024.svg", "utf-8");
|
||||
const BASE_SVG_1864 = await fs.readFile("assets/ElectoralCollege1864.svg", "utf-8");
|
||||
const BASE_SVG_SENATE = await fs.readFile("assets/SenateMap2024.svg", "utf-8");
|
||||
export function MakePrediction(election : Election) : Promise<Prediction> {
|
||||
return new Promise(async res => {
|
||||
const window = createSVGWindow();
|
||||
registerWindow(window, window.document);
|
||||
var draw = SVG(window.document.documentElement);
|
||||
draw.svg(election.svg);
|
||||
var pred = {} as any;
|
||||
pred.candidates = [];
|
||||
for (var candidate of election.candidates) {
|
||||
pred.candidates.push({
|
||||
name: candidate.name,
|
||||
party: candidate.party,
|
||||
votes: 0,
|
||||
});
|
||||
}
|
||||
|
||||
export function MakePrediction(bias : number, gopcandidate : string, demcandidate : string, simulationtype : string, year : number) : Promise<Prediction> {
|
||||
return new Promise(async res => {
|
||||
if (Number.isNaN(bias)) bias = 0;
|
||||
const window = createSVGWindow();
|
||||
registerWindow(window, window.document);
|
||||
var election = {} as any;
|
||||
var gopVotes = 0;
|
||||
var demVotes = 0;
|
||||
for (const state of Object.keys(election.states)) {
|
||||
var winner = await weightedRand(election.states[state].odds);
|
||||
pred.candidates.find((c : any) => c.party === winner).votes += election.states[state].electoralVotes;
|
||||
// @ts-ignore
|
||||
draw.find(`#${state}`).fill(election.candidates.find((c : any) => c.party === winner).color);
|
||||
}
|
||||
|
||||
var s = sharp(Buffer.from(draw.svg()));
|
||||
var png = await s.png().toBuffer();
|
||||
pred.winner = pred.candidates.sort((a : any, b : any) => b.votes - a.votes)[0].name;
|
||||
pred.svg = draw.svg();
|
||||
pred.png = png;
|
||||
res(pred);
|
||||
|
||||
switch (simulationtype) {
|
||||
case "presidential":
|
||||
if(year == 1864) {
|
||||
var draw = SVG(window.document.documentElement);
|
||||
draw.svg(BASE_SVG_1864);
|
||||
for (const state of Object.keys(ElectoralCollege1864)) {
|
||||
if ((GOPWinOdds1864 as any)[state] >= bias + await betterRandom()) {
|
||||
election[state] = "R";
|
||||
gopVotes += (ElectoralCollege1864 as any)[state];
|
||||
// @ts-ignore
|
||||
draw.find(`#${state}`).fill("#BF1D29");
|
||||
}
|
||||
else {
|
||||
election[state] = "D";
|
||||
demVotes += (ElectoralCollege1864 as any)[state];
|
||||
// @ts-ignore
|
||||
draw.find(`#${state}`).fill("#1C408C");
|
||||
}
|
||||
};
|
||||
var s = sharp(Buffer.from(draw.svg()));
|
||||
var png = await s.png().toBuffer();
|
||||
res({
|
||||
gopVotes,
|
||||
demVotes,
|
||||
gopCandidate: gopcandidate,
|
||||
demCandidate: demcandidate,
|
||||
winner: gopVotes > demVotes ? gopcandidate : demcandidate,
|
||||
svg: draw.svg(),
|
||||
png,
|
||||
});
|
||||
break;
|
||||
} else {
|
||||
var draw = SVG(window.document.documentElement);
|
||||
draw.svg(BASE_SVG);
|
||||
for (const state of Object.keys(ElectoralCollege)) {
|
||||
if ((GOPWinOdds as any)[state] >= bias + await betterRandom()) {
|
||||
election[state] = "R";
|
||||
gopVotes += (ElectoralCollege as any)[state];
|
||||
// @ts-ignore
|
||||
draw.find(`#${state}`).fill("#BF1D29");
|
||||
}
|
||||
else {
|
||||
election[state] = "D";
|
||||
demVotes += (ElectoralCollege as any)[state];
|
||||
// @ts-ignore
|
||||
draw.find(`#${state}`).fill("#1C408C");
|
||||
}
|
||||
};
|
||||
var s = sharp(Buffer.from(draw.svg()));
|
||||
var png = await s.png().toBuffer();
|
||||
res({
|
||||
gopVotes,
|
||||
demVotes,
|
||||
gopCandidate: gopcandidate,
|
||||
demCandidate: demcandidate,
|
||||
winner: gopVotes > demVotes ? gopcandidate : demcandidate,
|
||||
svg: draw.svg(),
|
||||
png,
|
||||
});
|
||||
break;
|
||||
}
|
||||
case "senate":
|
||||
var draw = SVG(window.document.documentElement);
|
||||
draw.svg(BASE_SVG_SENATE);
|
||||
let senatestates = ["AZ", "CA", "CT", "DE", "FL", "HI", "IN", "MA", "MD", "ME", "MI", "MN",
|
||||
"MO", "MS", "MT", "ND", "NE", "NE-02", "NJ", "NM", "NV", "NY", "OH", "PA", "RI", "TN", "TX",
|
||||
"UT", "VA", "VT", "WA", "WI", "WV", "WY"];
|
||||
|
||||
for await (const state of senatestates) {
|
||||
if ((GOPWinOddsSenate as any)[state] >= bias + await betterRandom()) {
|
||||
election[state] = "R";
|
||||
gopVotes += 1;
|
||||
// @ts-ignore
|
||||
draw.find(`#${state}`).fill("#BF1D29");
|
||||
} else {
|
||||
election[state] = "D";
|
||||
demVotes += 1;
|
||||
// @ts-ignore
|
||||
draw.find(`#${state}`).fill("#1C408C");
|
||||
}
|
||||
}
|
||||
var s = sharp(Buffer.from(draw.svg()));
|
||||
var png = await s.png().toBuffer();
|
||||
res({
|
||||
gopVotes,
|
||||
demVotes,
|
||||
gopCandidate: gopcandidate,
|
||||
demCandidate: demcandidate,
|
||||
winner: gopVotes > demVotes ? gopcandidate : demcandidate,
|
||||
svg: draw.svg(),
|
||||
png,
|
||||
});
|
||||
break;
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
export interface Prediction {
|
||||
gopVotes: number,
|
||||
demVotes: number,
|
||||
gopCandidate: string,
|
||||
demCandidate: string,
|
||||
candidates : {
|
||||
name : string,
|
||||
party : string,
|
||||
votes : string,
|
||||
}[],
|
||||
winner: string,
|
||||
svg: string,
|
||||
png: Buffer,
|
||||
}
|
||||
|
||||
export function betterRandom() : Promise<number> {
|
||||
export function betterRandom(min : number, max : number) : Promise<number> {
|
||||
return new Promise(res => {
|
||||
crypto.randomBytes(4, (err, buf) => {
|
||||
res(buf.readUInt32BE(0) / 0x100000000);
|
||||
if (err) throw err;
|
||||
const random = buf.readUInt32LE(0) / 0x100000000;
|
||||
res(Math.floor(min + random * (max - min)));
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
// https://stackoverflow.com/a/8435261
|
||||
export async function weightedRand(spec : { [key : string] : number }) : Promise<string> {
|
||||
var i, j, table = [];
|
||||
for (i in spec) {
|
||||
for (j = 0; j < spec[i] * 10; j++) {
|
||||
table.push(i);
|
||||
}
|
||||
}
|
||||
return table[await betterRandom(0, table.length)];
|
||||
}
|
Loading…
Reference in a new issue