7 Commity a8b185e9c0 ... 6381299dc4

Autor SHA1 Wiadomość Data
  Kirk Trombley 6381299dc4 Teal mask db updates 1 rok temu
  Kirk Trombley 0b1b294eda Teal mask updates 1 rok temu
  Kirk Trombley 6fe2c97364 Updage ignored URLs for animations that were added 1 rok temu
  Kirk Trombley 1e0dff1df5 Update greninja-ash 1 rok temu
  Kirk Trombley 36806ca304 Update reqs 1 rok temu
  Kirk Trombley c93e47bdd2 Handle Ursaluna bloodmoon 1 rok temu
  Kirk Trombley a73c9c12c7 slight template framework cleanup 1 rok temu
5 zmienionych plików z 277 dodań i 53 usunięć
  1. 165 1
      data/pokedex.json
  2. 10 10
      requirements.txt
  3. 45 11
      tools/download.py
  4. 14 1
      web/database.js
  5. 43 30
      web/main.js

+ 165 - 1
data/pokedex.json

@@ -12110,7 +12110,9 @@
       },
       {
         "name": "Greninja-Ash",
-        "traits": [],
+        "traits": [
+          "nostart"
+        ],
         "types": [
           "Water",
           "Dark"
@@ -17567,6 +17569,15 @@
           "Normal"
         ],
         "color": "Brown"
+      },
+      {
+        "name": "Ursaluna-Bloodmoon",
+        "traits": [],
+        "types": [
+          "Ground",
+          "Normal"
+        ],
+        "color": "Brown"
       }
     ]
   },
@@ -19347,5 +19358,158 @@
         "color": "Green"
       }
     ]
+  },
+  "1011": {
+    "num": 1011,
+    "species": "Dipplin",
+    "forms": [
+      {
+        "name": "Dipplin",
+        "traits": [],
+        "types": [
+          "Grass",
+          "Dragon"
+        ],
+        "color": "Green"
+      }
+    ]
+  },
+  "1012": {
+    "num": 1012,
+    "species": "Poltchageist",
+    "forms": [
+      {
+        "name": "Poltchageist",
+        "traits": [
+          "nfe"
+        ],
+        "types": [
+          "Grass",
+          "Ghost"
+        ],
+        "color": "Green"
+      },
+      {
+        "name": "Poltchageist-Artisan",
+        "traits": [
+          "nfe"
+        ],
+        "types": [
+          "Grass",
+          "Ghost"
+        ],
+        "color": "Green"
+      }
+    ]
+  },
+  "1013": {
+    "num": 1013,
+    "species": "Sinistcha",
+    "forms": [
+      {
+        "name": "Sinistcha",
+        "traits": [],
+        "types": [
+          "Grass",
+          "Ghost"
+        ],
+        "color": "Green"
+      },
+      {
+        "name": "Sinistcha-Masterpiece",
+        "traits": [],
+        "types": [
+          "Grass",
+          "Ghost"
+        ],
+        "color": "Green"
+      }
+    ]
+  },
+  "1014": {
+    "num": 1014,
+    "species": "Okidogi",
+    "forms": [
+      {
+        "name": "Okidogi",
+        "traits": [],
+        "types": [
+          "Poison",
+          "Fighting"
+        ],
+        "color": "Black"
+      }
+    ]
+  },
+  "1015": {
+    "num": 1015,
+    "species": "Munkidori",
+    "forms": [
+      {
+        "name": "Munkidori",
+        "traits": [],
+        "types": [
+          "Poison",
+          "Psychic"
+        ],
+        "color": "Black"
+      }
+    ]
+  },
+  "1016": {
+    "num": 1016,
+    "species": "Fezandipiti",
+    "forms": [
+      {
+        "name": "Fezandipiti",
+        "traits": [],
+        "types": [
+          "Poison",
+          "Fairy"
+        ],
+        "color": "Black"
+      }
+    ]
+  },
+  "1017": {
+    "num": 1017,
+    "species": "Ogerpon",
+    "forms": [
+      {
+        "name": "Ogerpon",
+        "traits": [],
+        "types": [
+          "Grass"
+        ],
+        "color": "Green"
+      },
+      {
+        "name": "Ogerpon-Wellspring",
+        "traits": [],
+        "types": [
+          "Grass",
+          "Water"
+        ],
+        "color": "Green"
+      },
+      {
+        "name": "Ogerpon-Hearthflame",
+        "traits": [],
+        "types": [
+          "Grass",
+          "Fire"
+        ],
+        "color": "Red"
+      },
+      {
+        "name": "Ogerpon-Cornerstone",
+        "traits": [],
+        "types": [
+          "Grass",
+          "Rock"
+        ],
+        "color": "Gray"
+      }
+    ]
   }
 }

+ 10 - 10
requirements.txt

@@ -1,11 +1,11 @@
-beautifulsoup4==4.10.0
-certifi==2021.10.8
-charset-normalizer==2.0.12
+beautifulsoup4==4.12.2
+certifi==2023.11.17
+charset-normalizer==3.3.2
 colorspacious==1.1.2
-idna==3.3
-numpy==1.22.2
-Pillow==9.0.0
-requests==2.27.1
-scipy==1.8.0
-soupsieve==2.3.1
-urllib3==1.26.8
+idna==3.5
+numpy==1.26.2
+Pillow==10.1.0
+requests==2.31.0
+scipy==1.11.4
+soupsieve==2.5
+urllib3==2.1.0

+ 45 - 11
tools/download.py

@@ -70,6 +70,7 @@ async def download_pokedex() -> dict:
 START_IN_BASE_FORM = (
   "Castform",    # castform can't start battle in weather forms
   "Cherrim",     # castform can't start battle in sunshine form
+  "Greninja",    # greninja can't start battle in Ash form
   "Aegislash",   # aegislash can't start battle in blade form
   "Wishiwashi",  # wishiwashi can't start battle in schooling form
   "Mimikyu",     # mimikyu can't start battle in busted form
@@ -131,6 +132,10 @@ def clean_dex(raw: dict) -> dict[int, Pokemon]:
       continue  # remove totem pokemon
     if baseSpecies == "Toxtricity" and forme == "Low-Key-Gmax":
       continue  # remove low-key-gmax since it is sort of a duplicate
+    if baseSpecies == "Greninja" and forme == "Bond":
+      continue  # remove bond greninja since it is basically a visual duplicate
+    if baseSpecies == "Ogerpon" and "Tera" in forme:
+      continue  # seems to have no visual change as of 11/25
 
     num = entry["num"]
     # non-cosmetic forms get separate entries automatically
@@ -326,12 +331,16 @@ SEREBII_FORM_FIRST_LETTER = (
   "Zarude-Dada",
   "Calyrex-Ice", "Calyrex-Shadow",
   "Basculegion-F",
+  "Ursaluna-Bloodmoon",
   "Oinkologne-F",
   "Maushold-Four",
   "Palafin-Hero",
   "Tatsugiri-Droopy", "Tatsugiri-Stretchy",
   "Dudunsparce-Three-Segment",
-  "Gimmighoul-Roaming"
+  "Gimmighoul-Roaming",
+  "Ogerpon-Wellspring",
+  "Ogerpon-Hearthflame",
+  "Ogerpon-Cornerstone",
 )
 SEREBII_SPECIAL = {
   "Castform-Rainy": "r",
@@ -407,6 +416,7 @@ SEREBII_SPECIAL = {
 SEREBII_IGNORE_MISSING = (
   "Wobbuffet-F", "Hippopotas-F", "Hippowdon-F", "Floette-Eternal",
   "Squawkabilly-Blue", "Squawkabilly-Yellow", "Squawkabilly-White",
+  "Poltchageist-Artisan", "Sinistcha-Masterpiece",
 )
 
 
@@ -554,6 +564,8 @@ KNOWN_MISSING = [
   "https://play.pokemonshowdown.com/sprites/ani-back/kleavor.gif",
   "https://play.pokemonshowdown.com/sprites/ani/ursaluna.gif",
   "https://play.pokemonshowdown.com/sprites/ani-back/ursaluna.gif",
+  "https://play.pokemonshowdown.com/sprites/ani/ursaluna-bloodmoon.gif",
+  "https://play.pokemonshowdown.com/sprites/ani-back/ursaluna-bloodmoon.gif",
   "https://play.pokemonshowdown.com/sprites/ani/sneasler.gif",
   "https://play.pokemonshowdown.com/sprites/ani-back/sneasler.gif",
   "https://play.pokemonshowdown.com/sprites/ani/overqwil.gif",
@@ -578,12 +590,6 @@ KNOWN_MISSING = [
   "https://play.pokemonshowdown.com/sprites/ani-back/fidough.gif",
   "https://play.pokemonshowdown.com/sprites/ani/dachsbun.gif",
   "https://play.pokemonshowdown.com/sprites/ani-back/dachsbun.gif",
-  "https://play.pokemonshowdown.com/sprites/ani/smoliv.gif",
-  "https://play.pokemonshowdown.com/sprites/ani-back/smoliv.gif",
-  "https://play.pokemonshowdown.com/sprites/ani/dolliv.gif",
-  "https://play.pokemonshowdown.com/sprites/ani-back/dolliv.gif",
-  "https://play.pokemonshowdown.com/sprites/ani/arboliva.gif",
-  "https://play.pokemonshowdown.com/sprites/ani-back/arboliva.gif",
   "https://play.pokemonshowdown.com/sprites/ani/squawkabilly.gif",
   "https://play.pokemonshowdown.com/sprites/ani-back/squawkabilly.gif",
   "https://play.pokemonshowdown.com/sprites/ani/squawkabilly-blue.gif",
@@ -630,10 +636,6 @@ KNOWN_MISSING = [
   "https://play.pokemonshowdown.com/sprites/ani-back/toedscruel.gif",
   "https://play.pokemonshowdown.com/sprites/ani/klawf.gif",
   "https://play.pokemonshowdown.com/sprites/ani-back/klawf.gif",
-  "https://play.pokemonshowdown.com/sprites/ani/capsakid.gif",
-  "https://play.pokemonshowdown.com/sprites/ani-back/capsakid.gif",
-  "https://play.pokemonshowdown.com/sprites/ani/scovillain.gif",
-  "https://play.pokemonshowdown.com/sprites/ani-back/scovillain.gif",
   "https://play.pokemonshowdown.com/sprites/ani/tinkatink.gif",
   "https://play.pokemonshowdown.com/sprites/ani-back/tinkatink.gif",
   "https://play.pokemonshowdown.com/sprites/ani/tinkatuff.gif",
@@ -728,6 +730,38 @@ KNOWN_MISSING = [
   "https://play.pokemonshowdown.com/sprites/ani-back/walkingwake.gif",
   "https://play.pokemonshowdown.com/sprites/ani/ironleaves.gif",
   "https://play.pokemonshowdown.com/sprites/ani-back/ironleaves.gif",
+  "https://play.pokemonshowdown.com/sprites/ani/dipplin.gif",
+  "https://play.pokemonshowdown.com/sprites/ani-back/dipplin.gif",
+  "https://play.pokemonshowdown.com/sprites/ani/poltchageist.gif",
+  "https://play.pokemonshowdown.com/sprites/ani-back/poltchageist.gif",
+  "https://play.pokemonshowdown.com/sprites/ani/poltchageist-artisan.gif",
+  "https://play.pokemonshowdown.com/sprites/ani-back/poltchageist-artisan.gif",
+  "https://play.pokemonshowdown.com/sprites/ani/sinistcha.gif",
+  "https://play.pokemonshowdown.com/sprites/ani-back/sinistcha.gif",
+  "https://play.pokemonshowdown.com/sprites/ani/sinistcha-masterpiece.gif",
+  "https://play.pokemonshowdown.com/sprites/ani-back/sinistcha-masterpiece.gif",
+  "https://play.pokemonshowdown.com/sprites/ani/okidogi.gif",
+  "https://play.pokemonshowdown.com/sprites/ani-back/okidogi.gif",
+  "https://play.pokemonshowdown.com/sprites/ani/munkidori.gif",
+  "https://play.pokemonshowdown.com/sprites/ani-back/munkidori.gif",
+  "https://play.pokemonshowdown.com/sprites/ani/fezandipiti.gif",
+  "https://play.pokemonshowdown.com/sprites/ani-back/fezandipiti.gif",
+  "https://play.pokemonshowdown.com/sprites/ani/ogerpon.gif",
+  "https://play.pokemonshowdown.com/sprites/ani-back/ogerpon.gif",
+  "https://play.pokemonshowdown.com/sprites/ani/ogerpon-wellspring.gif",
+  "https://play.pokemonshowdown.com/sprites/ani-back/ogerpon-wellspring.gif",
+  "https://play.pokemonshowdown.com/sprites/ani/ogerpon-hearthflame.gif",
+  "https://play.pokemonshowdown.com/sprites/ani-back/ogerpon-hearthflame.gif",
+  "https://play.pokemonshowdown.com/sprites/ani/ogerpon-cornerstone.gif",
+  "https://play.pokemonshowdown.com/sprites/ani-back/ogerpon-cornerstone.gif",
+  "https://play.pokemonshowdown.com/sprites/ani/ogerpon-teal-tera.gif",
+  "https://play.pokemonshowdown.com/sprites/ani-back/ogerpon-teal-tera.gif",
+  "https://play.pokemonshowdown.com/sprites/ani/ogerpon-wellspring-tera.gif",
+  "https://play.pokemonshowdown.com/sprites/ani-back/ogerpon-wellspring-tera.gif",
+  "https://play.pokemonshowdown.com/sprites/ani/ogerpon-hearthflame-tera.gif",
+  "https://play.pokemonshowdown.com/sprites/ani-back/ogerpon-hearthflame-tera.gif",
+  "https://play.pokemonshowdown.com/sprites/ani/ogerpon-cornerstone-tera.gif",
+  "https://play.pokemonshowdown.com/sprites/ani-back/ogerpon-cornerstone-tera.gif",
 ]
 KNOWN_MISSING_PNGS = ("vivillon", "furfrou", "alcremie")
 

+ 14 - 1
web/database.js

@@ -837,7 +837,7 @@ const database = [
   {"num": 656, "species": "Froakie", "name": "Froakie", "traits": ["nfe"], "types": ["Water"], "color": "Blue", "total": {"centroid": [0.69756531, -0.0349451, -0.01232766], "median": [0.750359, -0.04704883, -0.02957473], "stddev": [0.22261577, 0.03061751, 0.05183818], "tilt": [0.99467165, -0.04710112, -0.0217909], "chroma": [0.05839213, 0.03985122], "hue": 3.11218217, "size": 205738, "centroidHex": "#83A5A6", "medianHex": "#85B7C2"}, "clusters": [{"centroid": [0.94088108, -0.01671665, 0.0516336], "median": [0.94976569, -0.01158684, 0.03702731], "stddev": [0.03390413, 0.01675299, 0.04951475], "tilt": [0.99677301, -0.01788086, 0.05465152], "chroma": [0.05961856, 0.04608118], "hue": 1.9147469, "size": 45256, "centroidHex": "#EEEEC5", "medianHex": "#F0F0D3"}, {"centroid": [0.15438496, 0.00559624, 0.00334888], "median": [0.15178404, 0.00313991, 0.00257246], "stddev": [0.05994698, 0.00988879, 0.0090338], "tilt": [0.98477059, 0.06623385, 0.03489664], "chroma": [0.01095511, 0.01009535], "hue": 0.59184411, "size": 9563, "centroidHex": "#0E0B0A", "medianHex": "#0D0A0A"}, {"centroid": [0.74462602, -0.05054473, -0.03763129], "median": [0.75767702, -0.06014318, -0.05079711], "stddev": [0.07074098, 0.02960229, 0.03675031], "tilt": [0.99434746, -0.06870428, -0.0513447], "chroma": [0.07107241, 0.03385967], "hue": 3.4878161, "size": 115129, "centroidHex": "#7DB6C6", "medianHex": "#74BCD3"}, {"centroid": [0.38364755, -0.0186465, -0.01599811], "median": [0.40454236, -0.03285861, -0.02256564], "stddev": [0.08369896, 0.01676754, 0.0258639], "tilt": [0.99570289, -0.04483969, -0.03852973], "chroma": [0.02872655, 0.0269909], "hue": 3.7193345, "size": 35790, "centroidHex": "#34464C", "medianHex": "#2E4E56"}]},
   {"num": 657, "species": "Frogadier", "name": "Frogadier", "traits": ["nfe"], "types": ["Water"], "color": "Blue", "total": {"centroid": [0.58617574, -0.02973186, -0.02990511], "median": [0.59480406, -0.04632882, -0.04903743], "stddev": [0.22998455, 0.02859874, 0.03904458], "tilt": [0.99278549, -0.05184343, -0.05781267], "chroma": [0.0502603, 0.03993205], "hue": 3.67140774, "size": 206741, "centroidHex": "#61818F", "medianHex": "#50879D"}, "clusters": [{"centroid": [0.89580995, -0.00354938, 0.01438692], "median": [0.90501275, -0.00335886, 0.01561536], "stddev": [0.06559195, 0.00421085, 0.01688258], "tilt": [0.99968873, -0.00394028, 0.01624334], "chroma": [0.01584119, 0.01647395], "hue": 1.92082792, "size": 43459, "centroidHex": "#DDDDD2", "medianHex": "#E1E0D4"}, {"centroid": [0.34394161, -0.01882869, -0.02482354], "median": [0.3315478, -0.0275534, -0.0304685], "stddev": [0.09260878, 0.01823136, 0.03303277], "tilt": [0.99115755, -0.04616111, -0.06324118], "chroma": [0.03541931, 0.03376012], "hue": 3.97051294, "size": 79515, "centroidHex": "#283B46", "medianHex": "#1D3946"}, {"centroid": [0.58868646, -0.05332187, -0.06260344], "median": [0.61004905, -0.05755948, -0.05909584], "stddev": [0.05051751, 0.0163271, 0.01655575], "tilt": [0.98938919, -0.08898186, -0.10679878], "chroma": [0.08430831, 0.01397098], "hue": 3.99234347, "size": 53110, "centroidHex": "#4286A4", "medianHex": "#468DA8"}, {"centroid": [0.77117459, -0.05426019, -0.04922662], "median": [0.77406491, -0.07170645, -0.06703054], "stddev": [0.03990492, 0.03634152, 0.03870443], "tilt": [0.99310565, -0.0701502, -0.06385043], "chroma": [0.07856086, 0.0448816], "hue": 3.63077295, "size": 30657, "centroidHex": "#7FBFD6", "medianHex": "#68C3E3"}]},
   {"num": 658, "species": "Greninja", "name": "Greninja", "traits": [], "types": ["Water", "Dark"], "color": "Blue", "total": {"centroid": [0.50643346, 0.00168973, -0.04086633], "median": [0.43700634, -0.01910346, -0.07108252], "stddev": [0.20941575, 0.04710813, 0.04977532], "tilt": [0.98695021, -0.00855593, -0.09857963], "chroma": [0.06982812, 0.03864846], "hue": 4.72879257, "size": 271015, "centroidHex": "#5C637C", "medianHex": "#345379"}, "clusters": [{"centroid": [0.39785469, -0.0164676, -0.06046696], "median": [0.41820612, -0.0254743, -0.07675682], "stddev": [0.1074037, 0.0210256, 0.04074205], "tilt": [0.9846082, -0.03735268, -0.13985489], "chroma": [0.06754558, 0.0383017], "hue": 4.51765205, "size": 198911, "centroidHex": "#2F4868", "medianHex": "#284E77"}, {"centroid": [0.80596624, 0.05177979, 0.01320529], "median": [0.79364373, 0.07930986, 0.01256542], "stddev": [0.10378183, 0.06085303, 0.02738025], "tilt": [0.99341103, 0.07088475, 0.01528513], "chroma": [0.07612491, 0.03890105], "hue": 0.53451968, "size": 72104, "centroidHex": "#E0B2B4", "medianHex": "#E9A6B0"}]},
-  {"num": 658, "species": "Greninja", "name": "Greninja-Ash", "traits": [], "types": ["Water", "Dark"], "color": "Blue", "total": {"centroid": [0.49274152, -0.00900578, -0.05297673], "median": [0.45346482, -0.02441134, -0.0743482], "stddev": [0.18713108, 0.05388358, 0.05041615], "tilt": [0.98327795, -0.02939876, -0.1194883], "chroma": [0.08161802, 0.04088232], "hue": 4.44180695, "size": 781404, "centroidHex": "#4F6180", "medianHex": "#335880"}, "clusters": [{"centroid": [0.39041204, -0.02459832, -0.06494591], "median": [0.37880602, -0.03130796, -0.0512762], "stddev": [0.09103264, 0.02268423, 0.04434048], "tilt": [0.98105553, -0.05872432, -0.15465272], "chroma": [0.07493804, 0.04108517], "hue": 4.33423534, "size": 557538, "centroidHex": "#254768", "medianHex": "#1F465E"}, {"centroid": [0.72334952, 0.10516973, 0.0163527], "median": [0.71122783, 0.1087943, 0.00946922], "stddev": [0.08204265, 0.02351589, 0.01791968], "tilt": [0.98715237, 0.14755988, 0.02446688], "chroma": [0.10793116, 0.02351723], "hue": 0.16221592, "size": 116541, "centroidHex": "#DE8897", "medianHex": "#DB8498"}, {"centroid": [0.77391819, -0.0519845, -0.06608127], "median": [0.78740472, -0.06307767, -0.06823358], "stddev": [0.11573401, 0.02449281, 0.04252786], "tilt": [0.99061598, -0.06921077, -0.09313079], "chroma": [0.08774694, 0.04216769], "hue": 3.85105259, "size": 107325, "centroidHex": "#7CBFE1", "medianHex": "#75C5E8"}]},
+  {"num": 658, "species": "Greninja", "name": "Greninja-Ash", "traits": ["nostart"], "types": ["Water", "Dark"], "color": "Blue", "total": {"centroid": [0.49274152, -0.00900578, -0.05297673], "median": [0.45346482, -0.02441134, -0.0743482], "stddev": [0.18713108, 0.05388358, 0.05041615], "tilt": [0.98327795, -0.02939876, -0.1194883], "chroma": [0.08161802, 0.04088232], "hue": 4.44180695, "size": 781404, "centroidHex": "#4F6180", "medianHex": "#335880"}, "clusters": [{"centroid": [0.39041204, -0.02459832, -0.06494591], "median": [0.37880602, -0.03130796, -0.0512762], "stddev": [0.09103264, 0.02268423, 0.04434048], "tilt": [0.98105553, -0.05872432, -0.15465272], "chroma": [0.07493804, 0.04108517], "hue": 4.33423534, "size": 557538, "centroidHex": "#254768", "medianHex": "#1F465E"}, {"centroid": [0.72334952, 0.10516973, 0.0163527], "median": [0.71122783, 0.1087943, 0.00946922], "stddev": [0.08204265, 0.02351589, 0.01791968], "tilt": [0.98715237, 0.14755988, 0.02446688], "chroma": [0.10793116, 0.02351723], "hue": 0.16221592, "size": 116541, "centroidHex": "#DE8897", "medianHex": "#DB8498"}, {"centroid": [0.77391819, -0.0519845, -0.06608127], "median": [0.78740472, -0.06307767, -0.06823358], "stddev": [0.11573401, 0.02449281, 0.04252786], "tilt": [0.99061598, -0.06921077, -0.09313079], "chroma": [0.08774694, 0.04216769], "hue": 3.85105259, "size": 107325, "centroidHex": "#7CBFE1", "medianHex": "#75C5E8"}]},
   {"num": 659, "species": "Bunnelby", "name": "Bunnelby", "traits": ["nfe"], "types": ["Normal"], "color": "Brown", "total": {"centroid": [0.58546881, 0.01392367, 0.01520104], "median": [0.63343275, 0.01165313, 0.01216236], "stddev": [0.18593306, 0.01488201, 0.01671709], "tilt": [0.9981154, 0.02658371, 0.02907818], "chroma": [0.02171677, 0.02131332], "hue": 0.786886, "size": 279100, "centroidHex": "#867871", "medianHex": "#938781"}, "clusters": [{"centroid": [0.37702755, 0.01576492, 0.02019174], "median": [0.38460487, 0.01563256, 0.01929058], "stddev": [0.09571437, 0.01254524, 0.02154459], "tilt": [0.99647049, 0.03792237, 0.04624053], "chroma": [0.02637532, 0.02412746], "hue": 0.75011747, "size": 102548, "centroidHex": "#4C3D35", "medianHex": "#4E4037"}, {"centroid": [0.70653928, 0.0128542, 0.01230226], "median": [0.66456628, 0.01048849, 0.01032043], "stddev": [0.09713886, 0.01598712, 0.01221908], "tilt": [0.99907082, 0.01999779, 0.01910965], "chroma": [0.01901091, 0.01897512], "hue": 0.81361728, "size": 176552, "centroidHex": "#AA9D97", "medianHex": "#9B908C"}]},
   {"num": 660, "species": "Diggersby", "name": "Diggersby", "traits": [], "types": ["Normal", "Ground"], "color": "Brown", "total": {"centroid": [0.58395707, 0.00871001, 0.03339416], "median": [0.58475072, 0.01385422, 0.04075405], "stddev": [0.1851044, 0.0093604, 0.0327118], "tilt": [0.99678522, 0.01772289, 0.05826078], "chroma": [0.03596789, 0.03248114], "hue": 1.16561262, "size": 588260, "centroidHex": "#877864", "medianHex": "#8C775F"}, "clusters": [{"centroid": [0.30494985, 0.00613242, 0.01430144], "median": [0.27236547, 0.00451242, 0.01077926], "stddev": [0.0630576, 0.00514794, 0.00953421], "tilt": [0.99812707, 0.01958545, 0.04384541], "chroma": [0.0159182, 0.01030297], "hue": 1.17413711, "size": 111858, "centroidHex": "#342D26", "medianHex": "#2B2620"}, {"centroid": [0.89736899, -0.00265315, 0.05980721], "median": [0.88612546, -2.573e-05, 0.04366522], "stddev": [0.03880035, 0.00798025, 0.05643036], "tilt": [0.99586938, -0.00276755, 0.06584975], "chroma": [0.06065704, 0.05614922], "hue": 1.44615737, "size": 54644, "centroidHex": "#EADCB0", "medianHex": "#E4D8B9"}, {"centroid": [0.56819211, 0.01427749, 0.03434447], "median": [0.56593929, 0.02023793, 0.05845825], "stddev": [0.07623646, 0.00679274, 0.02364019], "tilt": [0.99640599, 0.02628815, 0.06462926], "chroma": [0.03776977, 0.02370304], "hue": 1.06192976, "size": 316250, "centroidHex": "#86735F", "medianHex": "#8D704D"}, {"centroid": [0.76469009, 0.00063986, 0.03710786], "median": [0.78148778, 0.00258589, 0.01107312], "stddev": [0.04252284, 0.00756113, 0.04220317], "tilt": [0.99697364, 0.00068697, 0.05052441], "chroma": [0.03903647, 0.04113192], "hue": 1.42825163, "size": 105508, "centroidHex": "#BCB198", "medianHex": "#BCB6AF"}]},
   {"num": 661, "species": "Fletchling", "name": "Fletchling", "traits": ["nfe"], "types": ["Normal", "Flying"], "color": "Red", "total": {"centroid": [0.546148, 0.02985414, 0.01859419], "median": [0.57367902, 0.03573634, 0.02293864], "stddev": [0.24455999, 0.04856181, 0.05251441], "tilt": [0.9927483, 0.04491599, 0.02596908], "chroma": [0.05380942, 0.05880113], "hue": 5.51842843, "size": 152034, "centroidHex": "#836963", "medianHex": "#8F6F68"}, "clusters": [{"centroid": [0.68810244, 0.10458994, 0.09480683], "median": [0.71080921, 0.10584083, 0.09741633], "stddev": [0.0610695, 0.01698931, 0.0171726], "tilt": [0.97878588, 0.14985042, 0.13473762], "chroma": [0.14186253, 0.01964549], "hue": 0.73122518, "size": 42755, "centroidHex": "#E2794F", "medianHex": "#EA8054"}, {"centroid": [0.21509553, 8.243e-05, -0.00131303], "median": [0.21711293, -0.00093943, -0.00232929], "stddev": [0.04033391, 0.00312312, 0.00372244], "tilt": [0.99855676, 0.00203495, -0.00689635], "chroma": [0.00338996, 0.00372149], "hue": 4.48811123, "size": 36078, "centroidHex": "#19191A", "medianHex": "#191A1B"}, {"centroid": [0.7964281, -0.00298087, -0.02996998], "median": [0.81133623, -0.00425486, -0.03386609], "stddev": [0.11925384, 0.00598161, 0.02402604], "tilt": [0.99862664, -0.00358275, -0.04079776], "chroma": [0.0333005, 0.02027788], "hue": 4.5567168, "size": 41736, "centroidHex": "#B2BCD0", "medianHex": "#B5C1D8"}, {"centroid": [0.40086779, 0.005992, 0.00227812], "median": [0.36497148, 0.00213234, -0.00180561], "stddev": [0.0771706, 0.01839891, 0.0200343], "tilt": [0.99726339, 0.01582759, 0.00441818], "chroma": [0.01917676, 0.02032828], "hue": 0.17967514, "size": 31465, "centroidHex": "#4B4646", "medianHex": "#3F3D3F"}]},
@@ -1271,6 +1271,7 @@ const database = [
   {"num": 899, "species": "Wyrdeer", "name": "Wyrdeer", "traits": [], "types": ["Normal", "Psychic"], "color": "White", "total": {"centroid": [0.76192155, 0.00450025, 0.0146414], "median": [0.84290592, 0.00177362, 0.00592285], "stddev": [0.24465413, 0.01042541, 0.03374744], "tilt": [0.99859089, 0.00720978, 0.01887802], "chroma": [0.01899401, 0.03348775], "hue": 5.54090646, "size": 59724, "centroidHex": "#B7B0A7", "medianHex": "#CDCAC7"}, "clusters": [{"centroid": [0.38845035, 0.00772929, 0.00456791], "median": [0.40370184, 0.00743482, -0.00030714], "stddev": [0.15801632, 0.01697322, 0.02082475], "tilt": [0.99806791, 0.01610316, 0.01138802], "chroma": [0.01637856, 0.02311084], "hue": 0.65645065, "size": 15201, "centroidHex": "#494241", "medianHex": "#4C4748"}, {"centroid": [0.8554487, 0.01307297, 0.09341801], "median": [0.87080759, 0.01212181, 0.0991673], "stddev": [0.04837961, 0.00833862, 0.01528271], "tilt": [0.99355886, 0.01561016, 0.10935167], "chroma": [0.09451787, 0.01634908], "hue": 1.43585737, "size": 7862, "centroidHex": "#EEC986", "medianHex": "#F4CE86"}, {"centroid": [0.82881315, 0.00223648, 0.00323612], "median": [0.84194908, 0.00031179, 0.00052958], "stddev": [0.05689364, 0.00432916, 0.01212662], "tilt": [0.99981085, 0.0029036, 0.00433541], "chroma": [0.00630983, 0.01189357], "hue": 5.83018632, "size": 21835, "centroidHex": "#C8C6C4", "medianHex": "#CBCACA"}, {"centroid": [0.99672848, -2.249e-05, -7.23e-06], "median": [0.99999765, -2.256e-05, -0.00010023], "stddev": [0.01173999, 0.00056612, 0.0013185], "tilt": [0.99999883, -2.122e-05, -1.69e-06], "chroma": [0.00030711, 0.00140185], "hue": 4.47664188, "size": 14826, "centroidHex": "#FDFDFD", "medianHex": "#FEFEFE"}]},
   {"num": 900, "species": "Kleavor", "name": "Kleavor", "traits": [], "types": ["Bug", "Rock"], "color": "Brown", "total": {"centroid": [0.42340207, 0.01438076, 0.02117539], "median": [0.37423494, 0.0179328, 0.00863547], "stddev": [0.1824355, 0.00639638, 0.0275201], "tilt": [0.99711044, 0.03950488, 0.03890191], "chroma": [0.03013811, 0.02334881], "hue": 0.57272611, "size": 65791, "centroidHex": "#594A40", "medianHex": "#4A3C3B"}, "clusters": [{"centroid": [0.30334485, 0.01467578, 0.00372623], "median": [0.30875441, 0.01612973, 0.00112321], "stddev": [0.08005307, 0.00561032, 0.00790616], "tilt": [0.99803622, 0.04914947, 0.01230083], "chroma": [0.01651167, 0.00711415], "hue": 0.17323495, "size": 39816, "centroidHex": "#352B2C", "medianHex": "#372C2E"}, {"centroid": [0.6074328, 0.01392854, 0.04792248], "median": [0.55326213, 0.01436895, 0.04631269], "stddev": [0.13607188, 0.00741909, 0.02530493], "tilt": [0.99569134, 0.02472107, 0.0796776], "chroma": [0.05102553, 0.02413184], "hue": 1.22732475, "size": 25975, "centroidHex": "#947E61", "medianHex": "#846E52"}]},
   {"num": 901, "species": "Ursaluna", "name": "Ursaluna", "traits": [], "types": ["Ground", "Normal"], "color": "Brown", "total": {"centroid": [0.50461602, 0.01568143, 0.01847726], "median": [0.49538476, 0.01162741, 0.01733925], "stddev": [0.19096979, 0.01314911, 0.01858576], "tilt": [0.99646247, 0.04135706, 0.04121849], "chroma": [0.02587353, 0.02088555], "hue": 0.88733166, "size": 93020, "centroidHex": "#706058", "medianHex": "#6B5F56"}, "clusters": [{"centroid": [0.88529936, 0.00174851, 0.04115577], "median": [0.91000936, -0.00227642, 0.00936624], "stddev": [0.05409508, 0.0081955, 0.05414323], "tilt": [0.99670825, 0.00225525, 0.04855706], "chroma": [0.04354707, 0.05290712], "hue": 2.48317703, "size": 6434, "centroidHex": "#E4D8BA", "medianHex": "#E2E1DA"}, {"centroid": [0.21666772, 0.01233286, 0.00842405], "median": [0.23563423, 0.01198873, 0.00889142], "stddev": [0.08190386, 0.00984008, 0.00542377], "tilt": [0.99080391, 0.07279104, 0.04796239], "chroma": [0.01554619, 0.01037422], "hue": 0.63680246, "size": 14072, "centroidHex": "#201715", "medianHex": "#241B19"}, {"centroid": [0.42156697, 0.02243474, 0.02280709], "median": [0.40315123, 0.03199079, 0.02862605], "stddev": [0.06090711, 0.0144478, 0.00954143], "tilt": [0.99592354, 0.05607709, 0.05518635], "chroma": [0.03284109, 0.01564357], "hue": 0.88596743, "size": 39126, "centroidHex": "#5C483F", "medianHex": "#5C4036"}, {"centroid": [0.64993975, 0.01186375, 0.01327018], "median": [0.63674135, 0.01227846, 0.01240831], "stddev": [0.04234108, 0.00855469, 0.00935933], "tilt": [0.99943157, 0.01839389, 0.02059362], "chroma": [0.01865543, 0.01138424], "hue": 0.86611062, "size": 33388, "centroidHex": "#988C85", "medianHex": "#948882"}]},
+  {"num": 901, "species": "Ursaluna", "name": "Ursaluna-Bloodmoon", "traits": [], "types": ["Ground", "Normal"], "color": "Brown", "total": {"centroid": [0.65955443, 0.02500729, 0.02668218], "median": [0.65989479, 0.02004074, 0.02199141], "stddev": [0.12370045, 0.02772907, 0.02864467], "tilt": [0.99582289, 0.04118349, 0.0446378], "chroma": [0.03800723, 0.03849899], "hue": 0.70820577, "size": 134943, "centroidHex": "#A58B7F", "medianHex": "#A28D82"}, "clusters": [{"centroid": [0.74060622, 0.01146048, 0.00578327], "median": [0.73205832, 0.00508368, 0.00345674], "stddev": [0.04193797, 0.02701576, 0.01177002], "tilt": [0.99914686, 0.01493523, 0.00774137], "chroma": [0.01407897, 0.02889562], "hue": 0.60743767, "size": 48844, "centroidHex": "#B3A8A6", "medianHex": "#ACA6A5"}, {"centroid": [0.6200156, 0.03465235, 0.04066287], "median": [0.61598092, 0.0385213, 0.04724466], "stddev": [0.03585387, 0.02635553, 0.02945405], "tilt": [0.99432494, 0.05562579, 0.06555193], "chroma": [0.05427584, 0.03834765], "hue": 0.78567625, "size": 55642, "centroidHex": "#A17D69", "medianHex": "#A37A63"}, {"centroid": [0.48068929, 0.03932745, 0.04624021], "median": [0.50222528, 0.04450838, 0.05338094], "stddev": [0.08387308, 0.01638361, 0.02001952], "tilt": [0.99078781, 0.07724464, 0.08842665], "chroma": [0.06195547, 0.02270528], "hue": 0.83012667, "size": 22269, "centroidHex": "#79533E", "medianHex": "#84573E"}, {"centroid": [0.93120482, 0.00132807, 0.00315202], "median": [0.94184195, 0.00110329, 0.00132108], "stddev": [0.05661891, 0.00474299, 0.01353058], "tilt": [0.9998677, 0.00154323, 0.00352048], "chroma": [0.0050604, 0.01384428], "hue": 5.72911729, "size": 8188, "centroidHex": "#E9E7E5", "medianHex": "#ECEBEA"}]},
   {"num": 902, "species": "Basculegion", "name": "Basculegion", "traits": [], "types": ["Water", "Ghost"], "color": "Green", "total": {"centroid": [0.55381005, 0.08494162, 0.0226919], "median": [0.55094478, 0.12074523, 0.02496196], "stddev": [0.16972722, 0.12473274, 0.01694458], "tilt": [0.96543156, 0.1446846, 0.04408531], "chroma": [0.12525692, 0.0888036], "hue": 0.8008193, "size": 420726, "centroidHex": "#9F5C61", "medianHex": "#AD4F5E"}, "clusters": [{"centroid": [0.66144081, -0.04425732, 0.02736562], "median": [0.61585346, -0.05655895, 0.03290319], "stddev": [0.17281196, 0.04478419, 0.01986693], "tilt": [0.99156046, -0.08196583, 0.04964422], "chroma": [0.06094871, 0.03732507], "hue": 2.59171763, "size": 146262, "centroidHex": "#7D9B80", "medianHex": "#68906F"}, {"centroid": [0.49645357, 0.15379179, 0.02020128], "median": [0.5437922, 0.2107759, 0.03632091], "stddev": [0.13704436, 0.09562816, 0.01455843], "tilt": [0.95150746, 0.26546672, 0.04112296], "chroma": [0.1595268, 0.0892631], "hue": 0.28182868, "size": 274464, "centroidHex": "#A62F52", "medianHex": "#CC0953"}]},
   {"num": 902, "species": "Basculegion", "name": "Basculegion-F", "traits": [], "types": ["Water", "Ghost"], "color": "Green", "total": {"centroid": [0.69031826, -0.03533329, 0.00983918], "median": [0.75064689, -0.03808161, -0.00245909], "stddev": [0.22030775, 0.0277951, 0.01948271], "tilt": [0.99599616, -0.05760978, 0.02020805], "chroma": [0.04022321, 0.02965616], "hue": 2.99727532, "size": 408069, "centroidHex": "#87A395", "medianHex": "#94B6B0"}, "clusters": [{"centroid": [0.47776847, -0.04301934, 0.02344839], "median": [0.48016762, -0.0494931, 0.02636387], "stddev": [0.10431064, 0.03349291, 0.01868931], "tilt": [0.99248338, -0.08401777, 0.04695983], "chroma": [0.0518402, 0.03441147], "hue": 2.65333463, "size": 186686, "centroidHex": "#48654F", "medianHex": "#45664D"}, {"centroid": [0.86955546, -0.02885186, -0.00163707], "median": [0.86022572, -0.03371505, -0.00155825], "stddev": [0.10032906, 0.01965364, 0.0108272], "tilt": [0.99895839, -0.03534067, -0.00235097], "chroma": [0.03042693, 0.02031762], "hue": 3.30763922, "size": 221383, "centroidHex": "#C0DAD5", "medianHex": "#B9D8D2"}]},
   {"num": 903, "species": "Sneasler", "name": "Sneasler", "traits": [], "types": ["Fighting", "Poison"], "color": "Purple", "total": {"centroid": [0.55127346, 0.01379486, -0.0363721], "median": [0.5695155, 0.00796966, -0.04556344], "stddev": [0.23472654, 0.04276352, 0.02965985], "tilt": [0.98888332, 0.04652644, -0.06251145], "chroma": [0.0529653, 0.03763416], "hue": 4.87133855, "size": 55040, "centroidHex": "#716E87", "medianHex": "#717492"}, "clusters": [{"centroid": [0.43406252, 0.03376972, -0.04787076], "median": [0.42028789, 0.03014175, -0.05152794], "stddev": [0.08600283, 0.04562845, 0.02944625], "tilt": [0.98571307, 0.0751053, -0.10896448], "chroma": [0.07020332, 0.03811213], "hue": 5.17250601, "size": 23215, "centroidHex": "#58486A", "medianHex": "#524568"}, {"centroid": [0.76176591, -0.0036532, -0.03483153], "median": [0.78101621, -0.01257551, -0.04219966], "stddev": [0.09940236, 0.03655894, 0.02512733], "tilt": [0.99673396, -0.00406903, -0.04744447], "chroma": [0.04616895, 0.03260289], "hue": 4.49021085, "size": 25542, "centroidHex": "#A6B1C8", "medianHex": "#A4B9D3"}, {"centroid": [0.1286495, 0.01092077, -0.00014865], "median": [0.12086839, 0.00787737, -0.00073674], "stddev": [0.07525979, 0.01317912, 0.01120415], "tilt": [0.96868221, 0.14661421, 0.04787634], "chroma": [0.01690157, 0.01152581], "hue": 6.05381564, "size": 6283, "centroidHex": "#0A0506", "medianHex": "#070405"}]},
@@ -1392,4 +1393,16 @@ const database = [
   {"num": 1008, "species": "Miraidon", "name": "Miraidon", "traits": [], "types": ["Electric", "Dragon"], "color": "Blue", "total": {"centroid": [0.59484425, 0.00403922, -0.04728324], "median": [0.63007726, 0.00704158, -0.05754753], "stddev": [0.2462834, 0.02678227, 0.07367975], "tilt": [0.98136457, 0.01611309, -0.11560158], "chroma": [0.07911073, 0.04625483], "hue": 4.80436774, "size": 48695, "centroidHex": "#767C9B", "medianHex": "#7F86AC"}, "clusters": [{"centroid": [0.91912284, -0.01700631, 0.0492204], "median": [0.91993957, -0.01928306, 0.06378529], "stddev": [0.04031697, 0.01560575, 0.06701213], "tilt": [0.99566703, -0.01846631, 0.05264906], "chroma": [0.06827757, 0.05276553], "hue": 2.85469416, "size": 11399, "centroidHex": "#E6E7C0", "medianHex": "#E9E8B4"}, {"centroid": [0.69321958, 0.00079609, -0.06422837], "median": [0.70289224, 0.00986347, -0.06848063], "stddev": [0.06825712, 0.03397011, 0.02703769], "tilt": [0.99356447, 0.00301975, -0.09295239], "chroma": [0.07294126, 0.02627728], "hue": 4.81531879, "size": 16194, "centroidHex": "#8D9AC4", "medianHex": "#949BCA"}, {"centroid": [0.34417883, 0.01789655, -0.08640918], "median": [0.36612923, 0.02137687, -0.1153304], "stddev": [0.09193038, 0.01409741, 0.05252228], "tilt": [0.9642762, 0.04484041, -0.22386952], "chroma": [0.08969719, 0.0519478], "hue": 4.90775319, "size": 21102, "centroidHex": "#323165", "medianHex": "#353379"}]},
   {"num": 1009, "species": "Walking Wake", "name": "Walking Wake", "traits": [], "types": ["Water", "Dragon"], "color": "Blue", "total": {"centroid": [0.67444773, 0.00955974, -0.02223284], "median": [0.64589298, 0.01502955, -0.03143846], "stddev": [0.23613172, 0.05515603, 0.02858532], "tilt": [0.99324005, 0.02235603, -0.03765764], "chroma": [0.05136127, 0.042509], "hue": 4.7815044, "size": 82984, "centroidHex": "#9694A4", "medianHex": "#8F8AA1"}, "clusters": [{"centroid": [0.89731335, -0.01888519, -0.00618194], "median": [0.99990034, -3.817e-05, -0.00010556], "stddev": [0.12139468, 0.03587117, 0.02287865], "tilt": [0.99799968, -0.02545024, -0.00836439], "chroma": [0.02693202, 0.03846695], "hue": 4.21315818, "size": 35548, "centroidHex": "#CEE1E1", "medianHex": "#FEFEFE"}, {"centroid": [0.50743477, 0.03087604, -0.0342612], "median": [0.54455156, 0.04689211, -0.0440402], "stddev": [0.14623432, 0.05741928, 0.02644729], "tilt": [0.98967323, 0.05818151, -0.05960967], "chroma": [0.06966828, 0.035636], "hue": 5.39225722, "size": 47436, "centroidHex": "#6E5D78", "medianHex": "#7F6489"}]},
   {"num": 1010, "species": "Iron Leaves", "name": "Iron Leaves", "traits": [], "types": ["Grass", "Psychic"], "color": "Green", "total": {"centroid": [0.63906243, -0.03963569, 0.04135239], "median": [0.6538362, -0.09112204, 0.06942344], "stddev": [0.20837039, 0.08072381, 0.03460596], "tilt": [0.98615251, -0.06607461, 0.06455761], "chroma": [0.08346874, 0.0634656], "hue": 2.55309158, "size": 68563, "centroidHex": "#7D9370", "medianHex": "#64A260"}, "clusters": [{"centroid": [0.65103944, 0.14974059, 0.03736259], "median": [0.66319275, 0.16998775, 0.03610435], "stddev": [0.04788783, 0.05495307, 0.01544854], "tilt": [0.96877182, 0.22486796, 0.05635729], "chroma": [0.15568597, 0.05327834], "hue": 0.31712421, "size": 6569, "centroidHex": "#DC6172", "medianHex": "#E85C76"}, {"centroid": [0.54332349, -0.07627527, 0.05177907], "median": [0.60192991, -0.09497674, 0.06527568], "stddev": [0.15162906, 0.04677129, 0.03349073], "tilt": [0.98453694, -0.12456009, 0.08210433], "chroma": [0.09504477, 0.05267508], "hue": 2.55596413, "size": 47144, "centroidHex": "#4A7D4E", "medianHex": "#4F9254"}, {"centroid": [0.93770481, -0.00708863, 0.01001594], "median": [0.99998001, -2.339e-05, -9.759e-05], "stddev": [0.09005103, 0.02489825, 0.02299343], "tilt": [0.99896991, -0.00910236, 0.01247985], "chroma": [0.01477279, 0.03287785], "hue": 4.39399678, "size": 14850, "centroidHex": "#E8EBE3", "medianHex": "#FEFEFE"}]},
+  {"num": 1011, "species": "Dipplin", "name": "Dipplin", "traits": [], "types": ["Grass", "Dragon"], "color": "Green", "total": {"centroid": [0.58217995, 0.08945938, 0.07465369], "median": [0.57534465, 0.15290242, 0.08919641], "stddev": [0.17623786, 0.08889819, 0.0330015], "tilt": [0.96591887, 0.1583717, 0.12014436], "chroma": [0.13570687, 0.06443435], "hue": 0.87443471, "size": 47604, "centroidHex": "#B46043", "medianHex": "#CC4231"}, "clusters": [{"centroid": [0.51102905, 0.11799423, 0.07220437], "median": [0.55329049, 0.15554151, 0.08707981], "stddev": [0.11916089, 0.07721762, 0.0302695], "tilt": [0.9583228, 0.20662741, 0.12661081], "chroma": [0.14767416, 0.06486335], "hue": 0.68845458, "size": 37123, "centroidHex": "#A64030", "medianHex": "#C5392C"}, {"centroid": [0.83419166, -0.01160917, 0.08332904], "median": [0.87190911, -0.02046294, 0.0990019], "stddev": [0.09663159, 0.04094593, 0.04006038], "tilt": [0.99282365, -0.01254679, 0.09724063], "chroma": [0.09331952, 0.04063706], "hue": 1.65798256, "size": 10481, "centroidHex": "#D6C989", "medianHex": "#E2D787"}]},
+  {"num": 1012, "species": "Poltchageist", "name": "Poltchageist", "traits": ["nfe"], "types": ["Grass", "Ghost"], "color": "Green", "total": {"centroid": [0.62947715, -0.00763526, 0.01937422], "median": [0.69892828, -0.01299316, 0.02696558], "stddev": [0.2616288, 0.02703742, 0.02261379], "tilt": [0.99760755, -0.00718434, 0.02612654], "chroma": [0.02823577, 0.02964463], "hue": 1.26075865, "size": 61605, "centroidHex": "#898A7C", "medianHex": "#9CA08B"}, "clusters": [{"centroid": [0.87931097, -0.00256443, 0.0246199], "median": [0.87545735, 3.252e-05, 0.01853956], "stddev": [0.05890835, 0.00939126, 0.0183308], "tilt": [0.99929463, -0.00282715, 0.02825601], "chroma": [0.02537677, 0.01982296], "hue": 1.5919236, "size": 27189, "centroidHex": "#DBD7C5", "medianHex": "#DAD5C8"}, {"centroid": [0.64262608, -0.04173026, 0.04049707], "median": [0.65075881, -0.05431449, 0.04782484], "stddev": [0.07163577, 0.04125971, 0.02176064], "tilt": [0.99332309, -0.06503203, 0.06224497], "chroma": [0.06341176, 0.03919522], "hue": 2.02002967, "size": 12521, "centroidHex": "#7D9572", "medianHex": "#799A6F"}, {"centroid": [0.3117165, 0.00556558, 0.00078076], "median": [0.31198013, 0.00656495, -0.00211514], "stddev": [0.08228228, 0.01014061, 0.01075918], "tilt": [0.9979627, 0.02048606, 0.00282731], "chroma": [0.01167012, 0.0106764], "hue": 6.12880387, "size": 21895, "centroidHex": "#332F30", "medianHex": "#332F31"}]},
+  {"num": 1012, "species": "Poltchageist", "name": "Poltchageist-Artisan", "traits": ["nfe"], "types": ["Grass", "Ghost"], "color": "Green", "total": {"centroid": [0.60674143, -0.00744373, 0.01671176], "median": [0.59846882, -0.00813076, 0.01778025], "stddev": [0.28406323, 0.02783802, 0.02643357], "tilt": [0.99584745, -0.00440748, 0.0156427], "chroma": [0.02746095, 0.03246964], "hue": 1.27039036, "size": 4294, "centroidHex": "#818377", "medianHex": "#7F8174"}, "clusters": [{"centroid": [0.88040968, -0.01328593, 0.03030067], "median": [0.89582503, -0.00374961, 0.02340951], "stddev": [0.10555225, 0.0323523, 0.02790005], "tilt": [0.9978539, -0.0161538, 0.03527327], "chroma": [0.03698967, 0.03938902], "hue": 1.73103323, "size": 1984, "centroidHex": "#D6DAC1", "medianHex": "#E0DDCB"}, {"centroid": [0.45643517, -0.00639279, 0.00992466], "median": [0.41192614, 0.00032079, 0.00274972], "stddev": [0.09453792, 0.02464082, 0.01904144], "tilt": [0.99796167, -0.01050695, 0.01787187], "chroma": [0.02144224, 0.02548222], "hue": 0.40529177, "size": 1480, "centroidHex": "#555851", "medianHex": "#4B4A49"}, {"centroid": [0.2205914, 0.00464725, -0.00366835], "median": [0.23377443, 0.00385885, -0.00322771], "stddev": [0.08043691, 0.01396043, 0.01299215], "tilt": [0.98728137, 0.03454663, -0.03525638], "chroma": [0.01541603, 0.0126921], "hue": 5.58933019, "size": 830, "centroidHex": "#1C191C", "medianHex": "#1E1D1F"}]},
+  {"num": 1013, "species": "Sinistcha", "name": "Sinistcha", "traits": [], "types": ["Grass", "Ghost"], "color": "Green", "total": {"centroid": [0.64102881, -0.02206077, 0.04336861], "median": [0.69764798, -0.03177954, 0.05328738], "stddev": [0.23528645, 0.04312681, 0.03109474], "tilt": [0.99359089, -0.02494578, 0.06122735], "chroma": [0.05845753, 0.0421549], "hue": 1.65050212, "size": 69093, "centroidHex": "#8A906F", "medianHex": "#97A378"}, "clusters": [{"centroid": [0.86635531, -0.01242276, 0.04716577], "median": [0.85701545, -0.00492321, 0.03573982], "stddev": [0.05735024, 0.02486678, 0.02930182], "tilt": [0.99746087, -0.01428633, 0.05412439], "chroma": [0.05096034, 0.03548143], "hue": 1.70095113, "size": 25797, "centroidHex": "#D7D5B0", "medianHex": "#D6D0B6"}, {"centroid": [0.25246056, 0.00874663, -0.00290812], "median": [0.27307639, 0.00773379, -0.00435558], "stddev": [0.04746231, 0.00685135, 0.01025759], "tilt": [0.99678627, 0.03624687, -0.01792804], "chroma": [0.01187674, 0.00980117], "hue": 5.90483211, "size": 12145, "centroidHex": "#252023", "medianHex": "#292529"}, {"centroid": [0.67018175, -0.06004773, 0.06189217], "median": [0.67320349, -0.06953019, 0.06474996], "stddev": [0.0573001, 0.04498718, 0.01601596], "tilt": [0.98914418, -0.08965238, 0.09163825], "chroma": [0.09178208, 0.03595522], "hue": 2.17743237, "size": 24001, "centroidHex": "#7FA16A", "medianHex": "#7AA469"}, {"centroid": [0.3902196, 0.01835011, 0.04609472], "median": [0.37569983, 0.02403039, 0.05238023], "stddev": [0.05329251, 0.0210839, 0.0188921], "tilt": [0.98912712, 0.04985937, 0.1192253], "chroma": [0.05276609, 0.02187767], "hue": 1.14812682, "size": 7150, "centroidHex": "#564026", "medianHex": "#563A1E"}]},
+  {"num": 1013, "species": "Sinistcha", "name": "Sinistcha-Masterpiece", "traits": [], "types": ["Grass", "Ghost"], "color": "Green", "total": {"centroid": [0.64358132, -0.02225541, 0.04371289], "median": [0.68015823, -0.02977503, 0.05065548], "stddev": [0.19710054, 0.03939742, 0.02867551], "tilt": [0.99454945, -0.02805845, 0.06479873], "chroma": [0.05661873, 0.03968477], "hue": 1.69272668, "size": 4864, "centroidHex": "#8A916F", "medianHex": "#939E75"}, "clusters": [{"centroid": [0.75515713, -0.03426285, 0.05345794], "median": [0.75101274, -0.03130975, 0.0546906], "stddev": [0.10269045, 0.03989307, 0.02429122], "tilt": [0.99399772, -0.0482987, 0.07176827], "chroma": [0.06864074, 0.0387513], "hue": 1.92693476, "size": 3400, "centroidHex": "#A8B689", "medianHex": "#A8B487"}, {"centroid": [0.38445717, 0.00563073, 0.02108095], "median": [0.37492229, 0.00873864, 0.0232925], "stddev": [0.09232012, 0.01866571, 0.02507675], "tilt": [0.9958308, 0.01894758, 0.04861264], "chroma": [0.02869877, 0.02509471], "hue": 0.80707461, "size": 1464, "centroidHex": "#4A4236", "medianHex": "#493E32"}]},
+  {"num": 1014, "species": "Okidogi", "name": "Okidogi", "traits": [], "types": ["Poison", "Fighting"], "color": "Black", "total": {"centroid": [0.47202177, -0.00516554, 0.01615964], "median": [0.36317649, 0.00013017, 0.00444598], "stddev": [0.2326289, 0.05975463, 0.04433459], "tilt": [0.99026029, -0.00543614, 0.02503422], "chroma": [0.04729076, 0.05989635], "hue": 3.67369256, "size": 112924, "centroidHex": "#5C5C51", "medianHex": "#3E3D3B"}, "clusters": [{"centroid": [0.77631456, -0.05015527, 0.05773655], "median": [0.67072123, -0.07403039, 0.08943349], "stddev": [0.18126996, 0.04453439, 0.04993751], "tilt": [0.98717919, -0.07871517, 0.09026867], "chroma": [0.07714037, 0.0661475], "hue": 2.94844137, "size": 31813, "centroidHex": "#A5C08D", "medianHex": "#7EA353"}, {"centroid": [0.49059398, 0.04409639, 0.00021269], "median": [0.47801154, 0.04600278, -0.00345674], "stddev": [0.06697238, 0.09400347, 0.05104564], "tilt": [0.97545467, 0.08112015, 0.00189167], "chroma": [0.10484004, 0.04894296], "hue": 0.50534766, "size": 23747, "centroidHex": "#76565F", "medianHex": "#72525D"}, {"centroid": [0.29557834, -0.00060805, -0.00029657], "median": [0.31233995, -0.00047628, -0.00080895], "stddev": [0.06184546, 0.0110922, 0.00853762], "tilt": [0.9980981, -0.0006287, -0.00156326], "chroma": [0.00691302, 0.01218998], "hue": 4.79770831, "size": 57364, "centroidHex": "#2C2C2C", "medianHex": "#303031"}]},
+  {"num": 1015, "species": "Munkidori", "name": "Munkidori", "traits": [], "types": ["Poison", "Psychic"], "color": "Black", "total": {"centroid": [0.47619298, 0.01458566, -0.01577043], "median": [0.3379905, 0.00305188, -0.00295711], "stddev": [0.25734075, 0.04907454, 0.03112782], "tilt": [0.99299429, 0.03285085, -0.02523536], "chroma": [0.03363336, 0.05203361], "hue": 5.05910792, "size": 73735, "centroidHex": "#605965", "medianHex": "#383638"}, "clusters": [{"centroid": [0.6325892, 0.05294243, -0.05496906], "median": [0.61923976, 0.04030895, -0.05657128], "stddev": [0.10451407, 0.08166541, 0.01914163], "tilt": [0.98206569, 0.09266757, -0.08663456], "chroma": [0.10121174, 0.05115], "hue": 5.14691394, "size": 19640, "centroidHex": "#9A7CAA", "medianHex": "#8F7BA7"}, {"centroid": [0.29434863, 0.00190808, -0.00255692], "median": [0.31750888, 0.00048525, -0.00171461], "stddev": [0.07624461, 0.01100046, 0.0080842], "tilt": [0.99657378, 0.01490622, -0.0041255], "chroma": [0.00727762, 0.01198245], "hue": 5.19499918, "size": 44070, "centroidHex": "#2C2B2D", "medianHex": "#313132"}, {"centroid": [0.96918635, -0.00482843, 0.002937], "median": [0.99999654, -2.279e-05, -0.00010011], "stddev": [0.06169299, 0.01224571, 0.04465238], "tilt": [0.99866905, -0.00545142, 0.00225274], "chroma": [0.01710052, 0.04339705], "hue": 4.47535572, "size": 10025, "centroidHex": "#F2F5F2", "medianHex": "#FEFEFE"}]},
+  {"num": 1016, "species": "Fezandipiti", "name": "Fezandipiti", "traits": [], "types": ["Poison", "Fairy"], "color": "Black", "total": {"centroid": [0.55265902, 0.03809572, 0.00960865], "median": [0.47636041, 0.05282264, 0.02073759], "stddev": [0.28161387, 0.0574278, 0.03970006], "tilt": [0.98826321, 0.07384747, 0.02097451], "chroma": [0.04892065, 0.06343837], "hue": 6.12551193, "size": 90566, "centroidHex": "#87696B", "medianHex": "#794F4E"}, "clusters": [{"centroid": [0.40244148, 0.05146755, 0.0114343], "median": [0.37673516, 0.0290763, 0.01051144], "stddev": [0.14629038, 0.06119201, 0.04367227], "tilt": [0.98425675, 0.10011141, 0.02643738], "chroma": [0.06437078, 0.06548116], "hue": 0.33544531, "size": 66309, "centroidHex": "#613C40", "medianHex": "#503B3A"}, {"centroid": [0.96329408, 0.00154246, 0.00461804], "median": [0.99999709, -2.252e-05, -0.00010012], "stddev": [0.08538876, 0.01588865, 0.02523457], "tilt": [0.9992153, 0.0020523, 0.00604121], "chroma": [0.00668611, 0.02946581], "hue": 4.5695811, "size": 24257, "centroidHex": "#F4F2EF", "medianHex": "#FEFEFE"}]},
+  {"num": 1017, "species": "Ogerpon", "name": "Ogerpon", "traits": [], "types": ["Grass"], "color": "Green", "total": {"centroid": [0.6130798, -0.06271476, 0.04460533], "median": [0.63205058, -0.09561266, 0.06841832], "stddev": [0.22553748, 0.05594638, 0.04921568], "tilt": [0.98498837, -0.09202665, 0.06890389], "chroma": [0.08450029, 0.06583813], "hue": 2.59385544, "size": 100995, "centroidHex": "#679066", "medianHex": "#599C5A"}, "clusters": [{"centroid": [0.74394036, -0.08417639, 0.06129898], "median": [0.69629194, -0.10685445, 0.08144984], "stddev": [0.13544121, 0.05084789, 0.0498137], "tilt": [0.98255491, -0.12273145, 0.0881423], "chroma": [0.11040441, 0.06100005], "hue": 2.69207968, "size": 66430, "centroidHex": "#82BD81", "medianHex": "#68B263"}, {"centroid": [0.18264442, 0.00271707, 0.00438371], "median": [0.18904217, 0.00132472, 0.00342403], "stddev": [0.07656622, 0.01762413, 0.01306943], "tilt": [0.98264818, 0.05016541, 0.03449475], "chroma": [0.01609403, 0.01577979], "hue": 0.9243103, "size": 9000, "centroidHex": "#13110F", "medianHex": "#141311"}, {"centroid": [0.42457409, -0.02998214, 0.01538707], "median": [0.41337008, -0.01307943, 0.00464175], "stddev": [0.07722583, 0.04197487, 0.03022428], "tilt": [0.99213548, -0.06229887, 0.03102688], "chroma": [0.04127107, 0.04591064], "hue": 2.54964831, "size": 25565, "centroidHex": "#405345", "medianHex": "#454D48"}]},
+  {"num": 1017, "species": "Ogerpon", "name": "Ogerpon-Cornerstone", "traits": [], "types": ["Grass", "Rock"], "color": "Gray", "total": {"centroid": [0.48248113, -0.01875395, 0.01737568], "median": [0.44742085, -0.00905661, 0.00354533], "stddev": [0.1831434, 0.04415292, 0.05042297], "tilt": [0.99339271, -0.02944875, 0.02547009], "chroma": [0.03712377, 0.06137921], "hue": 3.81431684, "size": 95118, "centroidHex": "#576153", "medianHex": "#505652"}, "clusters": [{"centroid": [0.49515335, -0.02486799, 0.0149265], "median": [0.48734314, -0.01007803, -0.00024217], "stddev": [0.05786843, 0.04178615, 0.04378232], "tilt": [0.99231169, -0.04622242, 0.02668451], "chroma": [0.03819573, 0.05518403], "hue": 3.57214674, "size": 36097, "centroidHex": "#566658", "medianHex": "#59615F"}, {"centroid": [0.30327286, 0.00048488, -0.00063479], "median": [0.30518936, 8.1e-06, -2.674e-05], "stddev": [0.05942358, 0.00649979, 0.00810621], "tilt": [0.99864082, 0.00294208, -0.00293471], "chroma": [0.0034917, 0.00981856], "hue": 4.54655557, "size": 35842, "centroidHex": "#2E2E2E", "medianHex": "#2F2E2E"}, {"centroid": [0.73985865, -0.03898172, 0.04903967], "median": [0.71775721, -0.02510078, 0.02958223], "stddev": [0.103983, 0.06461964, 0.07637425], "tilt": [0.98696099, -0.05341326, 0.06750159], "chroma": [0.0874601, 0.07927116], "hue": 2.85155095, "size": 23179, "centroidHex": "#9EB288", "medianHex": "#9BA98F"}]},
+  {"num": 1017, "species": "Ogerpon", "name": "Ogerpon-Hearthflame", "traits": [], "types": ["Grass", "Fire"], "color": "Red", "total": {"centroid": [0.53277202, 0.04073506, 0.06764009], "median": [0.49746236, 0.06189065, 0.06357567], "stddev": [0.18272028, 0.09191157, 0.05378094], "tilt": [0.97099875, 0.08721175, 0.11022566], "chroma": [0.11209733, 0.07077317], "hue": 0.91953841, "size": 95296, "centroidHex": "#8E603B", "medianHex": "#8B5135"}, "clusters": [{"centroid": [0.7689246, -0.01826803, 0.10858419], "median": [0.7578997, -0.00157775, 0.12524148], "stddev": [0.09874875, 0.06003072, 0.05940798], "tilt": [0.98302412, -0.02514848, 0.14250476], "chroma": [0.12861483, 0.05211016], "hue": 1.68882441, "size": 26473, "centroidHex": "#C4B55D", "medianHex": "#CEAC47"}, {"centroid": [0.32497838, 0.0323772, 0.01340193], "median": [0.32858094, 0.01397213, 0.0059998], "stddev": [0.06072451, 0.04865965, 0.02481645], "tilt": [0.98007353, 0.09220374, 0.03196416], "chroma": [0.04007904, 0.05104099], "hue": 5.58027013, "size": 24125, "centroidHex": "#442D2B", "medianHex": "#3C3231"}, {"centroid": [0.49573562, -0.05505178, 0.05927524], "median": [0.49802746, -0.0699726, 0.0711321], "stddev": [0.06952038, 0.0565217, 0.04929992], "tilt": [0.9800359, -0.09924311, 0.10695993], "chroma": [0.08530194, 0.06995009], "hue": 2.73984011, "size": 15168, "centroidHex": "#4F6B3A", "medianHex": "#496E31"}, {"centroid": [0.50985032, 0.14965875, 0.07954192], "median": [0.49818356, 0.14806965, 0.08015235], "stddev": [0.08369672, 0.02646659, 0.01829522], "tilt": [0.94816259, 0.27963397, 0.14690255], "chroma": [0.16988962, 0.02995615], "hue": 0.48578418, "size": 29530, "centroidHex": "#B22F27", "medianHex": "#AE2B23"}]},
+  {"num": 1017, "species": "Ogerpon", "name": "Ogerpon-Wellspring", "traits": [], "types": ["Grass", "Water"], "color": "Green", "total": {"centroid": [0.5874154, -0.04499888, -0.02885546], "median": [0.58466049, -0.05289497, -0.04641011], "stddev": [0.19069736, 0.048104, 0.08930405], "tilt": [0.98207325, -0.06916064, -0.04933079], "chroma": [0.09196995, 0.06847096], "hue": 3.98920144, "size": 93093, "centroidHex": "#56858F", "medianHex": "#478599"}, "clusters": [{"centroid": [0.40964876, -0.02060515, -0.04486309], "median": [0.39719771, -0.00951542, -0.02000901], "stddev": [0.09802389, 0.02886311, 0.06786022], "tilt": [0.98340136, -0.03769146, -0.08696731], "chroma": [0.05989543, 0.06548202], "hue": 4.39485708, "size": 39431, "centroidHex": "#334D63", "medianHex": "#3D4852"}, {"centroid": [0.75293416, -0.05823523, -0.07296063], "median": [0.73886731, -0.07960873, -0.07746845], "stddev": [0.11716374, 0.04005962, 0.05692621], "tilt": [0.98586971, -0.0800523, -0.10441492], "chroma": [0.0993621, 0.06072179], "hue": 4.06317232, "size": 37728, "centroidHex": "#6DB9DF", "medianHex": "#4DB9DE"}, {"centroid": [0.63541491, -0.0740241, 0.11518854], "median": [0.61148485, -0.1066703, 0.11379255], "stddev": [0.10395823, 0.07020085, 0.0392049], "tilt": [0.96979751, -0.12124677, 0.17423263], "chroma": [0.15384011, 0.03932392], "hue": 2.1412578, "size": 15934, "centroidHex": "#7B9729", "medianHex": "#5B9623"}]},
 ]

+ 43 - 30
web/main.js

@@ -108,8 +108,8 @@ const pokemonDisplayLookup = Object.fromEntries(
       .replace(/ F$/, " ♀");
     let spriteName = name.toLowerCase();
     if (
-      ["alcremie", "minior", "wobbuffet", "hippopotas", "hippowdon", "unfezant"].find(
-        s => spriteName.includes(s)
+      ["alcremie", "minior", "wobbuffet", "hippopotas", "hippowdon", "unfezant"].find(s =>
+        spriteName.includes(s)
       )
     ) {
       spriteName = species.toLowerCase();
@@ -223,29 +223,41 @@ const makeTemplate = (id, definition = () => ({})) => {
         return [name, element];
       })
     );
-    Object.entries(definition(...args))
-      .map(([name, settings]) => [binds[name], settings])
-      .filter(([bind]) => !!bind)
-      .forEach(([bind, settings]) =>
-        Object.entries(settings).forEach(([setting, value]) => {
-          if (setting.startsWith("@")) {
-            bind.addEventListener(setting.slice(1), value);
-          } else if (setting.startsWith("--")) {
-            bind.style.setProperty(setting, value);
-          } else if (setting === "dataset") {
-            Object.entries(value).forEach(([key, data]) => (bind.dataset[key] = data));
-          } else if (setting === "append") {
-            if (Array.isArray(value)) {
-              bind.append(...value);
+    const children = Array.from(content.children);
+    const update = (...args) => {
+      Object.entries(definition(...args))
+        .map(([name, settings]) => [binds[name], settings])
+        .filter(([bind]) => !!bind)
+        .forEach(([bind, settings]) =>
+          Object.entries(settings).forEach(([setting, value]) => {
+            if (setting.startsWith("@")) {
+              bind.addEventListener(setting.slice(1), value);
+            } else if (setting.startsWith("--")) {
+              bind.style.setProperty(setting, value);
+            } else if (setting === "dataset") {
+              Object.entries(value).forEach(([key, data]) => (bind.dataset[key] = data));
+            } else if (setting === "append") {
+              if (Array.isArray(value)) {
+                bind.append(...value);
+              } else {
+                bind.append(value);
+              }
             } else {
-              bind.append(value);
+              bind[setting] = value;
             }
-          } else {
-            bind[setting] = value;
-          }
-        })
-      );
-    return [fragment, binds];
+          })
+        );
+    };
+    update(...args);
+    return {
+      mount: root =>
+        (typeof root === "string" ? document.querySelector(root) : root).append(fragment),
+      unmount: () => children.forEach(c => c.remove()),
+      update,
+      children,
+      firstElementChild: fragment.firstElementChild,
+      fragment,
+    };
   };
 };
 
@@ -268,14 +280,15 @@ const nameSearchFormElements = document.forms.nameSearchForm.elements;
 // ---- Add Metric Selects ----
 
 const createMetricSelect = makeTemplate("metric-select-template");
-const [{ firstElementChild: sortMetricForm }] = createMetricSelect();
-const [{ firstElementChild: clusterMetricForm }] = createMetricSelect();
-
-document.getElementById("sort-metric-mount").append(sortMetricForm);
+const { firstElementChild: sortMetricForm, mount: mountSortMetricForm } =
+  createMetricSelect();
 sortMetricForm.elements.metricKind.value = "compare";
+mountSortMetricForm("#sort-metric-mount");
 
-document.getElementById("cls-metric-mount").append(clusterMetricForm);
+const { firstElementChild: clusterMetricForm, mount: mountClusterMetricForm } =
+  createMetricSelect();
 clusterMetricForm.elements.metricKind.value = "stat";
+mountClusterMetricForm("#cls-metric-mount");
 
 const updateMetricSelects = form => {
   const kind = form.elements.metricKind.value;
@@ -383,7 +396,7 @@ const createPokemonTile = makeTemplate(
           ...getColorStyles(data.hex),
         },
         [tooltip]: {
-          append: createPokemonTooltip(data)[0],
+          append: createPokemonTooltip(data).fragment,
         },
         [infoHover]: {
           "@mouseenter"({ target }) {
@@ -430,7 +443,7 @@ const renderPokemon = (list, target) => {
 
   target.append(
     ...list.map(
-      pkmn => createPokemonTile(pkmn, !!sortUseWholeImage, enableClusterFlags)[0]
+      pkmn => createPokemonTile(pkmn, !!sortUseWholeImage, enableClusterFlags).fragment
     )
   );
 };