Initial commit

This commit is contained in:
John Drake 2025-11-09 16:14:45 -05:00
parent 5cc80aa8a6
commit 827d70088c
122 changed files with 1975 additions and 0 deletions

2
.gitignore vendored Normal file
View file

@ -0,0 +1,2 @@
*.pyc

163
glicko2.py Normal file
View file

@ -0,0 +1,163 @@
"""
Copyright (c) 2009 Ryan Kirkman
Permission is hereby granted, free of charge, to any person
obtaining a copy of this software and associated documentation
files (the "Software"), to deal in the Software without
restriction, including without limitation the rights to use,
copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following
conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
OTHER DEALINGS IN THE SOFTWARE.
"""
import math
class Player:
# Class attribute
# The system constant, which constrains
# the change in volatility over time.
_tau = 0.5
def getRating(self):
return (self.__rating * 173.7178) + 1500
def setRating(self, rating):
self.__rating = (rating - 1500) / 173.7178
rating = property(getRating, setRating)
def getRd(self):
return self.__rd * 173.7178
def setRd(self, rd):
self.__rd = rd / 173.7178
rd = property(getRd, setRd)
def __init__(self, rating = 1500, rd = 350, vol = 0.06):
# For testing purposes, preload the values
# assigned to an unrated player.
self.setRating(rating)
self.setRd(rd)
self.vol = vol
def _preRatingRD(self):
""" Calculates and updates the player's rating deviation for the
beginning of a rating period.
preRatingRD() -> None
"""
self.__rd = math.sqrt(math.pow(self.__rd, 2) + math.pow(self.vol, 2))
def update_player(self, rating_list, RD_list, outcome_list):
""" Calculates the new rating and rating deviation of the player.
update_player(list[int], list[int], list[bool]) -> None
"""
# Convert the rating and rating deviation values for internal use.
rating_list = [(x - 1500) / 173.7178 for x in rating_list]
RD_list = [x / 173.7178 for x in RD_list]
v = self._v(rating_list, RD_list)
self.vol = self._newVol(rating_list, RD_list, outcome_list, v)
self._preRatingRD()
self.__rd = 1 / math.sqrt((1 / math.pow(self.__rd, 2)) + (1 / v))
tempSum = 0
for i in range(len(rating_list)):
tempSum += self._g(RD_list[i]) * \
(outcome_list[i] - self._E(rating_list[i], RD_list[i]))
self.__rating += math.pow(self.__rd, 2) * tempSum
def _newVol(self, rating_list, RD_list, outcome_list, v):
""" Calculating the new volatility as per the Glicko2 system.
_newVol(list, list, list) -> float
"""
i = 0
delta = self._delta(rating_list, RD_list, outcome_list, v)
a = math.log(math.pow(self.vol, 2))
tau = self._tau
x0 = a
x1 = 0
while x0 != x1:
# New iteration, so x(i) becomes x(i-1)
x0 = x1
d = math.pow(self.__rating, 2) + v + math.exp(x0)
h1 = -(x0 - a) / math.pow(tau, 2) - 0.5 * math.exp(x0) \
/ d + 0.5 * math.exp(x0) * math.pow(delta / d, 2)
h2 = -1 / math.pow(tau, 2) - 0.5 * math.exp(x0) * \
(math.pow(self.__rating, 2) + v) \
/ math.pow(d, 2) + 0.5 * math.pow(delta, 2) * math.exp(x0) \
* (math.pow(self.__rating, 2) + v - math.exp(x0)) / math.pow(d, 3)
x1 = x0 - (h1 / h2)
return math.exp(x1 / 2)
def _delta(self, rating_list, RD_list, outcome_list, v):
""" The delta function of the Glicko2 system.
_delta(list, list, list) -> float
"""
tempSum = 0
for i in range(len(rating_list)):
tempSum += self._g(RD_list[i]) * (outcome_list[i] - self._E(rating_list[i], RD_list[i]))
return v * tempSum
def _v(self, rating_list, RD_list):
""" The v function of the Glicko2 system.
_v(list[int], list[int]) -> float
"""
tempSum = 0
for i in range(len(rating_list)):
tempE = self._E(rating_list[i], RD_list[i])
tempSum += math.pow(self._g(RD_list[i]), 2) * tempE * (1 - tempE)
return 1 / tempSum
def _E(self, p2rating, p2RD):
""" The Glicko E function.
_E(int) -> float
"""
return 1 / (1 + math.exp(-1 * self._g(p2RD) * \
(self.__rating - p2rating)))
def _g(self, RD):
""" The Glicko2 g(RD) function.
_g() -> float
"""
return 1 / math.sqrt(1 + 3 * math.pow(RD, 2) / math.pow(math.pi, 2))
def did_not_compete(self):
""" Applies Step 6 of the algorithm. Use this for
players who did not compete in the rating period.
did_not_compete() -> None
"""
self._preRatingRD()

1526
pubresults.yaml Normal file

File diff suppressed because it is too large Load diff

284
pubstatcruncher.py Normal file
View file

@ -0,0 +1,284 @@
# from yaml import safe_load, dump
import yaml
from operator import itemgetter
import glicko2
# from itertools import pairwise
from more_itertools import pairwise
# load file
with open('pubresults.yaml', 'r') as file:
file_contents = yaml.full_load(file)
# print(yaml.dump(file_contents))
# print(len([key for key in file_contents]))
# print(len(file_contents))
# print(file_contents[0]['mission']) # zero'th match, missionname
# print(file_contents[0]['date'])
# print(file_contents[0]['results'])
# create player dictionary
# playerdata = dict()
# Point Whore Glickos
pwglickos = dict()
# Single Team Whore Glickos
stpwglickos = dict()
# Team Player Glickos
tpglickos = dict()
players_to_roles = {
'stormcrow':['ld','lof'],
'jacob':['ld','lo','cap'],
'bizzy':['ld','lo'],
'slush':['cap'],
'astralis':['cap','flex'],
'domestic':['ld','chase'],
'danno':['ho','ho'],
'hybrid':['lof','ho'],
'vaxity':['ho','shrike'],
'mistcane':['ld','cap'],
'nevares':['cap'],
'haggis':['ho'],
'devil':['cap','ho'],
'efx':['ld','lof'],
'hexy':['ld','shrike'],
'halo2':['ho'],
'blake':['lof'],
'future':['flex'],
'thaen':['offense'],
'strazz':['hof'],
'history':['cap','shrike','ho'],
'sliderzero':['shrike','flex'],
'jerry':['ld'],
'wingedwarrior':['ld','snipe'],
'sylock':['ho'],
'darrell':['ld'],
'pedro':['ld'],
'coorslightman':['ld'],
'hautsoss':['flex'],
'sajent':['ld','ho'],
'turtle':['ld'],
'irvin':['cap'],
'redeye':['lo','ho','flex'],
'mlgru':['shrike','ho','cap'],
'actionswanson':['flex'],
'bendover':['ho'],
'warchilde':['ho'],
'johnwayne':['flex'],
'lsecannon':['farm'],
'hp':['ld','lof'],
'sake':['ld'],
'anthem':['ho'],
'taco':['ho'],
'exogen':['cap'],
'mp40':['hd'],
'gunther':['ho'],
'ipkiss':['snipe'],
'alterego':['hd'],
'homer':['ho'],
'spartanonyx':['ld'],
'bish':['ho'],
'flyersfan':['ld'],
'geekofwires':['ho'],
'aromatomato':['ho'],
'heat':['ho','hd','farm'],
'daddyroids':['ld'],
'pupecki':['ld'],
'yuanz':['farm','hd','ho'],
'm80':['lof'],
'andycap':['hof'],
'tetchy':['cap','shrike'],
'systeme':['hd','farm','ho'],
'friendo':['hof','farm','ld','ho'],
'coastal':['shrike','ld'],
'caution':['ho','cap'],
'jx':['ld'],
'nightwear':['flex'],
'piata':['ho'],
'foxox':['snipe','farm'],
'elliebackwards':['ld'],
'nutty':['ld'],
'sweetcheeks':['farm'],
'carpenter':['hd','ld'],
'eeor':['ld'],
'cooter':['cap'],
'flakpyro':['flex','d'],
'doug':['ld','ho','snipe'],
'raynian':['ho','mo'],
'legelos':['ld'],
'7thbishop':['cap','hd'],
'dirkdiggler':['ho'],
'lazer':['ld'],
'iroc':['ld'],
'ember':['ld'],
'2short':['hd','ho','cap'],
'earth':['tank','hd','hof'],
'lolcaps':['cap'],
'aftermath':['ld'],
'fnatic':['ld'],
}
first_roles_to_players = dict()
any_roles_to_players = dict()
for player,roles in players_to_roles.items():
if roles[0] is None:
# print('')
continue
# first_role_players = first_roles_to_players[roles[0]]
if not roles[0] in first_roles_to_players:
first_roles_to_players[roles[0]] = list()
# print('adding', player,'to role',roles[0])
first_roles_to_players[roles[0]].append(player)
for role in roles:
if not role in any_roles_to_players:
any_roles_to_players[role] = list()
any_roles_to_players[role].append(player)
print(first_roles_to_players)
print(any_roles_to_players)
# quit()
# loop over all matches
for match in file_contents:
print()
print(match['date'], match['mission'])
winning_team_score = 0
winning_team_name = None
results = match['results']
# match
merged_match_player_results = list()
for team in results:
print('team:', team)
# if results[team]['score'] > winning_team_score:
# winning_team_score = results[team]['score']
# winning_team_name = team
# print('input unsorted')
# for player in results[team]['players']:
# print('player:', player)
# results[team]['players'].sort(key=itemgetter(2), reverse=True)
# print('input sorted')
# print('appending to list this thing',results[team]['players'],type(results[team]['players']), type(results[team]['players'][0]))
team_player_results = list()
# parse the string as a tuple
for player in results[team]['players']:
player_split = player.split(", ")
# print('player_split:',player_split)
player_tuple = (player_split[0], int(player_split[1]))
# print('xx:"',player,'"')
# print('xx:',player_tuple)
# todo consider removing the bottom 20% or something, to filter out people who had connection problems
merged_match_player_results.append(player_tuple)
team_player_results.append(player_tuple)
# initialize glicko objects for each player, if not already initialized
if player_tuple[0] not in pwglickos:
pwglickos[player_tuple[0]] = glicko2.Player()
if player_tuple[0] not in stpwglickos:
stpwglickos[player_tuple[0]] = glicko2.Player()
if player_tuple[0] not in tpglickos:
tpglickos[player_tuple[0]] = glicko2.Player()
# per team point whore glicko updates
team_player_results.sort(key=itemgetter(1), reverse=True)
for better_player, worse_player in pairwise(team_player_results):
# score ties
lose = 0
win = 1
if better_player[1] == worse_player[1]:
lose = 0.5
win = 0.5
# print('bp:', better_player)
# print('wp:', worse_player)
worse_player_glicko = stpwglickos[worse_player[0]]
stpwglickos[better_player[0]].update_player([worse_player_glicko.rating], [worse_player_glicko.rd], [win])
better_player_glicko = stpwglickos[better_player[0]]
stpwglickos[worse_player[0]].update_player([better_player_glicko.rating], [better_player_glicko.rd], [lose])
# for player in merged_match_player_results:
# print('inplayer:', player)
# Sort all of the players in the match by their scores
merged_match_player_results.sort(key=itemgetter(1), reverse=True)
for better_player, worse_player in pairwise(merged_match_player_results):
# score ties
lose = 0
win = 1
if better_player[1] == worse_player[1]:
lose = 0.5
win = 0.5
# print('bp:', better_player)
# print('wp:', worse_player)
worse_player_glicko = pwglickos[worse_player[0]]
pwglickos[better_player[0]].update_player([worse_player_glicko.rating], [worse_player_glicko.rd], [win])
better_player_glicko = pwglickos[better_player[0]]
pwglickos[worse_player[0]].update_player([better_player_glicko.rating], [better_player_glicko.rd], [lose])
# for player in merged_match_player_results:
# print(player[0], pwglickos[player[0]].rating, pwglickos[player[0]].rd)
# Count a team win as an individual win for each winning team player against all losing team players (and vice versa for losses)
# todo: maybe it should only count as a personal win if your personal score is higher than the other team's player
assert(len(results) == 2)
winning_team_name = 0
losing_team_name = 0
lose = 0
win = 1
team_names = list(results.keys())
if results[team_names[0]]['score'] > results[team_names[1]]['score']:
winning_team_name = team_names[0]
losing_team_name = team_names[1]
elif results[team_names[0]]['score'] < results[team_names[1]]['score']:
winning_team_name = team_names[1]
losing_team_name = team_names[0]
else:
lose = 0.5
win = 0.5
for losing_team_player in results[losing_team_name]['players']:
losing_player_split = losing_team_player.split(", ")
losing_player_tuple = (losing_player_split[0], int(losing_player_split[1]))
# print('losing_team_player:',losing_player_tuple[0])
for winning_team_player in results[winning_team_name]['players']:
winning_player_split = winning_team_player.split(", ")
winning_player_tuple = (winning_player_split[0], int(winning_player_split[1]))
# print('winning_team_player:',winning_player_tuple[0])
# if winning_player_split[1] > losing_player_split[1]:
tpglickos[losing_player_tuple[0]].update_player([tpglickos[winning_player_tuple[0]].rating],[tpglickos[winning_player_tuple[0]].rd],[lose])
tpglickos[winning_player_tuple[0]].update_player([tpglickos[losing_player_tuple[0]].rating],[tpglickos[losing_player_tuple[0]].rd],[win])
# Sort by glicko ratings and print them out
pwglickolist = list(pwglickos.items())
pwglickolist.sort(key=lambda rating: rating[1].rating, reverse=True)
print('Point Whore Ratings, sorted:\n', [(x[0], str(round(x[1].rating))) for x in pwglickolist])
# Sort by glicko ratings and print them out
stpwglickolist = list(stpwglickos.items())
stpwglickolist.sort(key=lambda rating: rating[1].rating, reverse=True)
# print('Single Team Point Whore Ratings, sorted:\n', [(x[0], str(round(x[1].rating))) for x in stpwglickolist])
print('\nSingle Team Point Whore Ratings',"\n".join([ str((x[0], str(round(x[1].rating)), str(round(x[1].rd)))) for x in stpwglickolist]))
# Sort by glicko ratings and print them out
tpglickolist = list(tpglickos.items())
tpglickolist.sort(key=lambda rating: rating[1].rating, reverse=True)
print('\nTeam Player Ratings, sorted:')
print("\n".join([ str((x[0], str(round(x[1].rating)), str(round(x[1].rd)))) for x in tpglickolist]))
print('\nPer role single team point whore ratings:\n')
for role, players in first_roles_to_players.items():
# print('unsorted:',role,players)
players.sort(key=lambda p: stpwglickos[p].rating if p in stpwglickos else 1400, reverse=True)
print('sorted:',role,players)

Binary file not shown.

After

Width:  |  Height:  |  Size: 217 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 204 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 210 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 208 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 204 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 314 KiB

BIN
pugstatspics/3280.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 MiB

BIN
pugstatspics/3283.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 980 KiB

BIN
pugstatspics/3284.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 984 KiB

BIN
pugstatspics/328aa.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1 MiB

BIN
pugstatspics/4110.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2 MiB

BIN
pugstatspics/4111.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 MiB

BIN
pugstatspics/4113.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 MiB

BIN
pugstatspics/4114.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 MiB

BIN
pugstatspics/4115.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 MiB

BIN
pugstatspics/4180.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 MiB

BIN
pugstatspics/4181.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 MiB

BIN
pugstatspics/4182.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 MiB

BIN
pugstatspics/4183.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 MiB

BIN
pugstatspics/4184.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1 MiB

BIN
pugstatspics/4240.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 313 KiB

BIN
pugstatspics/4241.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 178 KiB

BIN
pugstatspics/4242.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 176 KiB

BIN
pugstatspics/4243.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 184 KiB

BIN
pugstatspics/4244.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 222 KiB

BIN
pugstatspics/4245.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 216 KiB

BIN
pugstatspics/4246.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 318 KiB

BIN
pugstatspics/4247.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 204 KiB

BIN
pugstatspics/4250.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 966 KiB

BIN
pugstatspics/4251.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 532 KiB

BIN
pugstatspics/4252.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 519 KiB

BIN
pugstatspics/4253.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 521 KiB

BIN
pugstatspics/4254.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 522 KiB

BIN
pugstatspics/4255.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 488 KiB

BIN
pugstatspics/441.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 MiB

BIN
pugstatspics/442.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 MiB

BIN
pugstatspics/443.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1 MiB

BIN
pugstatspics/445.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.6 MiB

BIN
pugstatspics/615a.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 346 KiB

BIN
pugstatspics/615b.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 213 KiB

BIN
pugstatspics/615c.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 225 KiB

BIN
pugstatspics/615d.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 231 KiB

BIN
pugstatspics/615e.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 235 KiB

BIN
pugstatspics/615f.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 228 KiB

BIN
pugstatspics/72025/0.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 MiB

BIN
pugstatspics/72025/1.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 579 KiB

BIN
pugstatspics/72025/2.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 594 KiB

BIN
pugstatspics/72025/3.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 607 KiB

BIN
pugstatspics/72025/4.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 601 KiB

BIN
pugstatspics/7625/0.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 892 KiB

BIN
pugstatspics/7625/1.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 592 KiB

BIN
pugstatspics/7625/2.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 602 KiB

BIN
pugstatspics/7625/3.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 579 KiB

BIN
pugstatspics/7625/4.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 598 KiB

BIN
pugstatspics/81725/0.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 MiB

BIN
pugstatspics/81725/1.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 508 KiB

BIN
pugstatspics/81725/2.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 570 KiB

BIN
pugstatspics/81725/3.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 594 KiB

BIN
pugstatspics/81725/4.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 598 KiB

BIN
pugstatspics/81725/5.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 606 KiB

BIN
pugstatspics/81725/6.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 603 KiB

BIN
pugstatspics/824a.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 341 KiB

BIN
pugstatspics/824b.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 217 KiB

BIN
pugstatspics/824c.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 219 KiB

BIN
pugstatspics/824d.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 233 KiB

BIN
pugstatspics/824e.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 234 KiB

BIN
pugstatspics/824f.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 227 KiB

BIN
pugstatspics/83125.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 898 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 558 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 592 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 612 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 578 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 568 KiB

BIN
pugstatspics/8325/0.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 905 KiB

BIN
pugstatspics/8325/1.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 567 KiB

BIN
pugstatspics/8325/2.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 585 KiB

BIN
pugstatspics/8325/3.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 583 KiB

BIN
pugstatspics/8325/4.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 600 KiB

BIN
pugstatspics/8325/5.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 578 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 199 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 208 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 315 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 222 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 211 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 218 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 210 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 213 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 198 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 201 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 200 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 209 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 214 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 209 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 211 KiB

Some files were not shown because too many files have changed in this diff Show more