added a bunch of stuff idk bro

This commit is contained in:
st committed 2026-06-28 13:53:12 -05:00
1 parent adf3cd2014
commit 072de326e4
129 files changed
+505 -18513

No files matched your search

Binary file not shown.
BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 203 KiB

-1
View File
@@ -1 +0,0 @@
.env
-27
View File
@@ -1,27 +0,0 @@
![test](https://cdn.discordapp.com/attachments/1285541629016670300/1320374781333340211/logo.png?ex=67695e57&is=67680cd7&hm=e5962535a2d6b7864a4a81e87fe51422356ecc85fecbb96ab88b7250e390245c&)
Provably-Safe Telegram Fortnite Skin Checker Bot
- single handedly developed by @xhexago on telegram and discord
Setup Guide(Windows):
- install Python 3.11.4 from https://www.python.org/ftp/python/3.11.4/python-3.11.4-amd64.exe
- make sure python is installed with the option "Add to "PATh";
- python -m pip install --upgrade pip
- pip install Pillow==11.0.0
- pip install telebot
- pip install asyncio
- pip install aiohttp
Setup Guide(Linux):
- sudo apt update
- sudo apt upgrade
- sudo apt install -y python3
- sudo apt install -y python3-pip
- pip install Pillow==11.0.0
- pip install telebot
- pip install asyncio
- pip install aiohttp
- Make .env file with variables for:
- TELEGRAM_API_TOKEN
View File
Whitespace-only changes.
Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 29 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.9 KiB

-2002
View File
File diff suppressed because it is too large. Load diff
-24
View File
@@ -1,24 +0,0 @@
class FortniteCosmetic:
def __init__(self):
self.cosmetic_id = ""
self.name = ""
self.backend_value = "AthenaCharacter"
self.rarity_value = "common"
self.small_icon = ""
self.is_banner = False
self.unlocked_styles = {}
self.is_exclusive = False
self.is_popular = False
def to_dict(self):
return {
"cosmetic_id": self.cosmetic_id,
"name": self.name,
"backend_value": self.backend_value,
"rarity_value": self.rarity_value,
"small_icon": self.small_icon,
"is_banner": self.is_banner,
"unlocked_styles": self.unlocked_styles,
"is_exclusive": self.is_exclusive,
"is_popular": self.is_popular,
}
Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 14 KiB

-690
View File
@@ -1,690 +0,0 @@
import aiohttp
import requests
import asyncio
import os
import platform
import json
import math
from typing import Optional
from datetime import datetime, timezone
from cosmetic import FortniteCosmetic
from utils import bool_to_emoji
# these tokens are used to authorize in epic games's API and let us do the skincheck without getting errors
EPIC_API_SWITCH_TOKEN = "OThmN2U0MmMyZTNhNGY4NmE3NGViNDNmYmI0MWVkMzk6MGEyNDQ5YTItMDAxYS00NTFlLWFmZWMtM2U4MTI5MDFjNGQ3"
# keep in mind, sometimes epic games block the client ids, so then you have to generate new ios token for it to start working again
EPIC_API_IOS_CLIENT_TOKEN = "M2Y2OWU1NmM3NjQ5NDkyYzhjYzI5ZjFhZjA4YThhMTI6YjUxZWU5Y2IxMjIzNGY1MGE2OWVmYTY3ZWY1MzgxMmU="
class EpicEndpoints:
endpoint_oauth_token = "https://account-public-service-prod.ol.epicgames.com/account/api/oauth/token"
endpoint_prod03_oauth_token = "https://account-public-service-prod03.ol.epicgames.com/account/api/oauth/token"
endpoint_redirect_url = "https://www.epicgames.com/id/login?redirectUrl=https%3A//www.epicgames.com/id/login%3FredirectUrl%3Dhttps%253A%252F%252Fwww.epicgames.com%252Fid%252Fapi%252Fredirect%253FclientId%253Dec684b8c687f479fadea3cb2ad83f5c6%2526responseType%253Dcode"
endpoint_oauth_exchange = "https://account-public-service-prod03.ol.epicgames.com/account/api/oauth/exchange"
endpoint_device_auth = "https://account-public-service-prod03.ol.epicgames.com/account/api/oauth/deviceAuthorization"
# locker categories we render
locker_categories = ['AthenaCharacter', 'AthenaBackpack', 'AthenaPickaxe', 'AthenaDance', 'AthenaGlider', 'AthenaPopular', 'AthenaExclusive']
class EpicUser:
def __init__(self, data: dict = {}):
self.raw = data
# api response for login link generation
self.access_token = data.get("access_token", "")
self.expires_in = data.get("expires_in", 0)
self.expires_at = data.get("expires_at", "")
self.token_type = data.get("token_type", "")
self.client_id = data.get("client_id", "")
self.internal_client = data.get("internal_client", False)
self.client_service = data.get("client_service", "")
self.product_id = data.get("product_id", "")
self.application_id = data.get("application_id", "")
# api response for account metadata
self.refresh_token = data.get("refresh_token", "")
self.refresh_expires = data.get("refresh_expires", "")
self.refresh_expires_at = data.get("refresh_expires_at", "")
self.account_id = data.get("account_id", "")
self.display_name = data.get("displayName", "")
self.app = data.get("app", "")
self.in_app_id = data.get("in_app_id", "")
self.acr = data.get("acr", "")
self.auth_time = data.get("auth_time", "")
class LockerData:
def __init__(self):
self.cosmetic_categories = {}
self.cosmetic_array = {}
self.unlocked_styles = {}
self.homebase_banners = {}
self.last_match = ''
def to_dict(self):
return {
"cosmetic_categories": self.cosmetic_categories,
"cosmetic_array": self.cosmetic_array,
"unlocked_styles": self.unlocked_styles,
"homebase_banners": self.homebase_banners,
}
def add_missing_array2(arr, arr2, category, idclean):
# i hate hardcoding stuff, so ill make helper funcs instead
if category not in arr:
arr[category] = []
arr2[category] = []
arr[category].append(idclean)
def add_missing_array(arr, arr2, category):
# i hate hardcoding stuff, so ill make helper funcs instead
if category not in arr:
arr[category] = []
arr2[category] = []
async def get_cosmetic_data(cosmetic_lowercase_id):
try:
response = requests.get(
f'https://fortnite-api.com/v2/cosmetics/br/search/ids?language=en{cosmetic_lowercase_id}'
)
response.raise_for_status()
return response.json().get('data', [])
except Exception as e:
print(f"Error getting cosmetic info for cosmetic with ID: {cosmetic_lowercase_id}\n> Exception: {e}")
return []
class EpicGenerator:
def __init__(self) -> None:
# init the generator
self.http: aiohttp.ClientSession
self.user_agent = f"DeviceAuthGenerator/{platform.system()}/{platform.version()}"
self.access_token = ""
async def start(self) -> None:
self.http = aiohttp.ClientSession(headers={"User-Agent": self.user_agent})
self.access_token = await self.get_access_token()
async def kill(self) -> None:
await self.http.close()
async def get_access_token(self) -> str:
# getting the access token from epic's api(REQUIRES usage of EPIC_API_SWITCH_TOKEN as Authorization in headers for it to work)
# if it's not getting any data, it means the EPIC_API_SWITCH_TOKEN is expired, you must find new one :D
async with self.http.request(
method="POST",
url=EpicEndpoints.endpoint_oauth_token,
headers={
"Content-Type": "application/x-www-form-urlencoded",
"Authorization": f"basic {EPIC_API_SWITCH_TOKEN}"
},
data={ "grant_type": "client_credentials" },
) as response:
data = await response.json()
return data["access_token"]
async def create_device_code(self) -> tuple:
# devide code is used on the link the checker bot sends u "active?userCode=SOMETHING" something like this
# REQUIRES usage of self.access_token, which we got from get_access_token function, as Authorization in headers
# returns the device code, used in the link we generate for the user to login
async with self.http.request(
method="POST",
url=EpicEndpoints.endpoint_device_auth,
headers={
"Authorization": f"bearer {self.access_token}",
"Content-Type": "application/x-www-form-urlencoded"
}
) as response:
data = await response.json()
return data
async def create_exchange_code(self, user: EpicUser) -> str:
# creates exchange code for the api requests & returns it
# REQUIRES usage of user.access_token, which we got from get_access_token function, as Authorization in headers
async with self.http.request(
method="GET",
url=EpicEndpoints.endpoint_oauth_exchange,
headers={"Authorization": f"bearer {user.access_token}"},
) as response:
data = await response.json()
return data["code"]
async def wait_for_device_code_completion(self, bot, message, code: str) -> Optional[EpicUser]:
while True:
try:
async with self.http.request(
method="POST",
url=EpicEndpoints.endpoint_prod03_oauth_token,
headers={
"Authorization": f"basic {EPIC_API_SWITCH_TOKEN}",
"Content-Type": "application/x-www-form-urlencoded",
},
data={"grant_type": "device_code", "device_code": code},
timeout=10
) as request:
token_data = await request.json()
if request.status == 200 and "access_token" in token_data:
break
# Handle specific API errors
error_code = token_data.get("errorCode")
if error_code == "errors.com.epicgames.account.oauth.authorization_pending":
pass
elif error_code == "g":
pass
elif error_code == "errors.com.epicgames.not_found":
bot.send_message(message.chat.id, f'❌ Login link expired, please use /login again.')
return None
else:
bot.send_message(message.chat.id, f'❌ Error occurred: {token_data.get("errorMessage", "Unknown error")}')
return None
await asyncio.sleep(10)
except ValueError as ve:
print(f"Error with waiting for device code: {ve}")
bot.send_message(message.chat.id, f'❌ An unexpected error occurred, please try again later.')
return None
except Exception as e:
print(f"Unhandled exception: {e}")
bot.send_message(message.chat.id, f'❌ An error occurred, please contact support.')
return None
try:
async with self.http.request(
method="GET",
url=EpicEndpoints.endpoint_oauth_exchange,
headers={"Authorization": f"bearer {token_data['access_token']}"},
) as request:
if request.status != 200:
bot.send_message(message.chat.id, f'❌ Failed to retrieve exchange code. Please try again.')
return None
exchange_data = await request.json()
async with self.http.request(
method="POST",
url=EpicEndpoints.endpoint_prod03_oauth_token,
headers={
"Authorization": f"basic {EPIC_API_IOS_CLIENT_TOKEN}",
"Content-Type": "application/x-www-form-urlencoded"
},
data={
"grant_type": "exchange_code",
"exchange_code": exchange_data["code"]
},
) as request:
if request.status != 200:
bot.send_message(message.chat.id, f'❌ Failed to authenticate using exchange code. Please try again.')
return None
auth_data = await request.json()
return EpicUser(data=auth_data)
except KeyError as ke:
bot.send_message(message.chat.id, f'❌ Unexpected response format from server.')
return None
except Exception as e:
print(f"Unhandled exception during token exchange: {e}")
bot.send_message(message.chat.id, f'❌ An error occurred while completing authentication.')
return None
async def create_device_auths(self, user: EpicUser) -> dict:
# creates device auth
# REQUIRES usage of user.access_token as Authorization in headers
async with self.http.request(
method="POST",
url=f"https://account-public-service-prod.ol.epicgames.com/account/api/public/account/{user.account_id}/deviceAuth",
headers={
"Authorization": f"bearer {user.access_token}",
"Content-Type": "application/json",
},
) as request:
data = await request.json()
return {
"device_id": data["deviceId"],
"account_id": data["accountId"],
"secret": data["secret"],
"user_agent": data["userAgent"],
"created": {
"location": data["created"]["location"],
"ip_address": data["created"]["ipAddress"],
"datetime": data["created"]["dateTime"],
},
}
async def get_account_metadata(self, user: EpicUser) -> json:
# grabs account's metadata(basic information) from the api
# REQUIRES usage of user.access_token as Authorization in headers
url = f'https://account-public-service-prod03.ol.epicgames.com/account/api/public/account/displayName/{user.display_name}'
headers = {
"Authorization": f"bearer {user.access_token}",
"Content-Type": "application/json",
}
async with self.http.get(url, headers=headers) as response:
metadata = await response.json()
return metadata
async def get_external_connections(self, user: EpicUser) -> dict:
# returns external connected accounts info
# REQUIRES usage of user.access_token as Authorization in headers
async with self.http.request(
method="GET",
url=f"https://account-public-service-prod03.ol.epicgames.com/account/api/public/account/{user.account_id}/externalAuths",
headers={"Authorization": f"bearer {user.access_token}"}
) as resp:
if resp.status != 200:
return []
external_auths = await resp.json()
return external_auths
async def get_public_account_info(self, user: EpicUser) -> dict:
# returns basic public info about the account
# REQUIRES usage of user.access_token as Authorization in headers
url = f'https://account-public-service-prod03.ol.epicgames.com/account/api/public/account/{user.account_id}'
headers = {
"Authorization": f"bearer {user.access_token}"
}
async with self.http.get(url, headers=headers) as response:
account_data = await response.json()
account_info = {} # creating json for only stuff we are interested into
creation_date = account_data.get("created", "?")
if creation_date != "?":
creation_date = datetime.strptime(creation_date, "%Y-%m-%dT%H:%M:%S.%fZ").strftime("%d/%m/%Y")
account_info['creation_date'] = creation_date
account_info['externalAuths'] = await self.get_external_connections(user)
return account_info
async def get_common_profile(self, user: EpicUser) -> json:
# gets the common profile, containing vbucks, receipts amount, vbucks purchases history, banners list
# REQUIRES usage of user.access_token as Authorization in headers
url = f'https://fortnite-public-service-prod11.ol.epicgames.com/fortnite/api/game/v2/profile/{user.account_id}/client/QueryProfile?profileId=common_core&rvn=-1'
headers = {
"Authorization": f"bearer {user.access_token}",
"Content-Type": "application/json"
}
profile_data = requests.post(url, headers=headers, json={}).json()
return profile_data
async def get_friend_codes(self, user: EpicUser, platform: str) -> json:
# https://fngw-mcp-gc-livefn.ol.epicgames.com/fortnite/api/v2/game/friendcodes/<accountID>/<platform>
# gets the save the world redeem codes based on the platform you've entered
# REQUIRES usage of user.access_token as Authorization in headers
# this always returns an error saying page isn't found, im not sure why.
url = f'https://fngw-mcp-gc-livefn.ol.epicgames.com/fortnite/api/v2/game/friendcodes/{user.account_id}/{platform}'
headers = {
"Authorization": f"bearer {user.access_token}"
}
async with self.http.get(url, headers=headers) as response:
codes_data = await response.json()
return codes_data
async def get_homebase_profile(self, user: EpicUser) -> json:
# gets the save the world profile data
# REQUIRES usage of user.access_token as Authorization in headers
url = f'https://fngw-mcp-gc-livefn.ol.epicgames.com/fortnite/api/game/v2/profile/{user.account_id}/client/QueryPublicProfile'
querystring = { "profileId":"campaign", "rvn":"-1" }
payload = {}
headers = {
"Content-Type": "application/json",
"Authorization": f"bearer {user.access_token}"
}
profile_data = requests.request("POST", url, json=payload, headers=headers, params=querystring).json()
return profile_data
async def set_affiliate(self, user: EpicUser, affiliate_name: str):
url = f'https://fortnite-public-service-prod11.ol.epicgames.com/fortnite/api/game/v2/profile/{user.account_id}/client/SetAffiliateName?profileId=common_core'
payload = { "affiliateName": affiliate_name }
headers = {
"Content-Type": "application/json",
"Authorization": f"bearer {user.access_token}"
}
affiliate_response = requests.request("POST", url, json=payload, headers=headers)
if affiliate_response.status != 200:
print(f"Error setting affiliate name ({affiliate_response.status})")
async def get_locker_data(self, user: EpicUser) -> LockerData:
# gets locker arrays
# locker_categories - the locker categories we render
url = f'https://fortnite-public-service-prod11.ol.epicgames.com/fortnite/api/game/v2/profile/{user.account_id}/client/QueryProfile?profileId=athena'
headers = {
"Authorization": f"bearer {user.access_token}",
"Content-Type": "application/json"
}
athena_data = requests.post(url, headers=headers, json={}).json()
locker_data = LockerData()
exclusive_cosmetics = []
popular_cosmetics = []
if "profileChanges" not in athena_data:
return LockerData()
# activity
account_level = athena_data.get("profileChanges", [{}])[0].get("profile", {}).get("stats", {}).get("attributes", {}).get("accountLevel", 1)
last_match_end = athena_data.get("profileChanges", [{}])[0].get("profile", {}).get("stats", {}).get("attributes", {}).get("last_match_end_datetime", "")
if last_match_end:
last_match_end_date = datetime.fromisoformat(last_match_end.replace("Z", "+00:00"))
days_since_last_match = (datetime.now(timezone.utc) - last_match_end_date).days
last_match_date_str = last_match_end_date.strftime("%d.%m.%y")
locker_data.last_match = f"{last_match_date_str} ({days_since_last_match} days ago)"
else:
locker_data.last_match = "800+ days ago"
# getting extra cosmetics
try:
with open('exclusive.txt', 'r', encoding='utf-8') as f:
exclusive_cosmetics = [i.strip() for i in f.readlines()]
with open('most_wanted.txt', 'r', encoding='utf-8') as f:
popular_cosmetics = [i.strip() for i in f.readlines()]
except FileNotFoundError:
print("Warning: exclusive.txt or most_wanted.txt not found.")
# getting owned items list
for i in athena_data['profileChanges'][0]['profile']['items']:
template_id = athena_data['profileChanges'][0]['profile']['items'][i]['templateId']
if template_id.startswith('Athena'):
cosmetic_category = template_id.split(':')[0]
cosmetic_id = template_id.split(':')[1]
locker_data.unlocked_styles[cosmetic_id] = []
# adding missing categories to the arrays
if 'AthenaExclusive' not in locker_data.cosmetic_categories:
locker_data.cosmetic_categories['AthenaExclusive'] = []
locker_data.cosmetic_array['AthenaExclusive'] = []
locker_data.cosmetic_categories['AthenaExclusive'].append(cosmetic_id)
if 'AthenaPopular' not in locker_data.cosmetic_categories:
locker_data.cosmetic_categories['AthenaPopular'] = []
locker_data.cosmetic_array['AthenaPopular'] = []
locker_data.cosmetic_categories['AthenaPopular'].append(cosmetic_id)
if 'HomebaseBannerIcons' not in locker_data.cosmetic_categories:
locker_data.cosmetic_categories['HomebaseBannerIcons'] = []
locker_data.cosmetic_array['HomebaseBannerIcons'] = []
locker_data.cosmetic_categories['HomebaseBannerIcons'].append(cosmetic_id)
if cosmetic_category not in locker_data.cosmetic_categories:
locker_data.cosmetic_categories[cosmetic_category] = []
locker_data.cosmetic_array[cosmetic_category] = []
locker_data.cosmetic_categories[cosmetic_category].append(cosmetic_id)
# listing the owned unlocked styles for each cosmetic
for item_id, item_data in athena_data['profileChanges'][0]['profile']['items'].items():
template_id = item_data.get('templateId', '')
if template_id.startswith('Athena'):
lowercase_cosmetic_id = template_id.split(':')[1]
# adding the cosmetic to the "unlocked styles"
if lowercase_cosmetic_id not in locker_data.unlocked_styles:
locker_data.unlocked_styles[lowercase_cosmetic_id] = []
attributes = item_data.get('attributes', {})
variants = attributes.get('variants', [])
for variant in variants:
# adding the cosmetic's owned styles
locker_data.unlocked_styles[lowercase_cosmetic_id].extend(variant.get('owned', []))
# getting banners
common_profile_data = await self.get_common_profile(user)
if common_profile_data:
# common profile found
for profileChange in common_profile_data["profileChanges"]:
profile_items = profileChange["profile"]["items"]
# checking every item
for item_key, item_value in profile_items.items():
cosmetic_template_id = item_value.get("templateId", "")
if cosmetic_template_id:
# the banner is found, so we adding it
lowercase_banner_id = cosmetic_template_id.split(':')[1]
if lowercase_banner_id not in locker_data.homebase_banners:
locker_data.homebase_banners[lowercase_banner_id] = []
for category in locker_categories:
if category == "AthenaPopular" or category == 'AthenaExclusive':
continue
try:
list_of_cosmetic_ids = []
# splitting the category's cosmetic ids to sublists
for i in range(0, len(locker_data.cosmetic_categories[category]), 50):
sublist = locker_data.cosmetic_categories[category][i:i+50]
list_of_cosmetic_ids.append(sublist)
for cosmetic_id in list_of_cosmetic_ids:
cosmetics_data = requests.get('https://fortnite-api.com/v2/cosmetics/br/search/ids?language=en&id={}'.format('&id='.join(cosmetic_id)))
c_data = cosmetics_data.json().get("data", [])
if not c_data:
# cosmetics data not found
continue
for cosmetic in c_data:
if cosmetic['id'] == "CID_DefaultOutfit":
# skipping default skin
continue
if category == 'AthenaDance' and cosmetic['type']['value'] != 'emote' and cosmetic['id'] not in exclusive_cosmetics:
# emote category, but isnt exclusive and isnt emote
continue
make_mythic = False
if cosmetic['id'] in exclusive_cosmetics:
make_mythic = True
# Pink Ghoul Trooper
if cosmetic['id'].lower() == 'cid_029_athena_commando_f_halloween':
make_mythic = False
if 'Mat3' in locker_data.unlocked_styles.get('cid_029_athena_commando_f_halloween', []):
make_mythic = True
# Purple Skull Trooper
if cosmetic['id'].lower() == 'cid_030_athena_commando_m_halloween':
make_mythic = False
if 'Mat1' in locker_data.unlocked_styles.get('cid_030_athena_commando_m_halloween', []):
make_mythic = True
# Aerial Assault Trooper
if cosmetic['id'].lower() == 'cid_017_athena_commando_m':
make_mythic = False
if 'Stage2' in locker_data.unlocked_styles.get('cid_017_athena_commando_m', []):
make_mythic = True
# Renegade Raider
if cosmetic['id'].lower() == 'cid_028_athena_commando_f':
make_mythic = False
if 'Mat3' in locker_data.unlocked_styles.get('cid_028_athena_commando_f', []):
make_mythic = True
# Raider's Revenge
if cosmetic['id'].lower() == 'pickaxe_lockjaw':
make_mythic = False
if 'Stage2' in locker_data.unlocked_styles.get('pickaxe_lockjaw', []):
make_mythic = True
# Aerial Assault One
if cosmetic['id'].lower() == 'glider_id_001':
make_mythic = False
if 'Stage2' in locker_data.unlocked_styles.get('glider_id_001', []):
make_mythic = True
# Stage 5 Omega Lights
if cosmetic['id'].lower() == 'cid_116_athena_commando_m_carbideblack':
make_mythic = False
if 'Stage5' in locker_data.unlocked_styles.get('cid_116_athena_commando_m_carbideblack', []):
make_mythic = True
# Gold Midas
if cosmetic['id'].lower() == 'cid_694_athena_commando_m_catburglar':
make_mythic = False
if 'Stage4' in locker_data.unlocked_styles.get('cid_694_athena_commando_m_catburglar', []):
make_mythic = True
# Gold Meowscles
if cosmetic['id'].lower() == 'cid_693_athena_commando_m_buffcat':
make_mythic = False
if 'Stage4' in locker_data.unlocked_styles.get('cid_693_athena_commando_m_buffcat', []):
make_mythic = True
# Gold TNtina
if cosmetic['id'].lower() == 'cid_691_athena_commando_f_tntina':
make_mythic = False
if 'Stage7' in locker_data.unlocked_styles.get('cid_691_athena_commando_f_tntina', []):
make_mythic = True
# Gold Skye
if cosmetic['id'].lower() == 'cid_690_athena_commando_f_photographer':
make_mythic = False
if 'Stage4' in locker_data.unlocked_styles.get('cid_690_athena_commando_f_photographer', []):
make_mythic = True
# Gold Agent Peely
if cosmetic['id'].lower() == 'cid_701_athena_commando_m_bananaagent':
make_mythic = False
if 'Stage4' in locker_data.unlocked_styles.get('cid_701_athena_commando_m_bananaagent', []):
make_mythic = True
# World Cup Fishtick
if cosmetic['id'].lower() == 'cid_315_athena_commando_m_teriyakifish':
make_mythic = False
if 'Stage3' in locker_data.unlocked_styles.get('cid_315_athena_commando_m_teriyakifish', []):
make_mythic = True
# Mate Black Masterchief
if cosmetic['id'].lower() == 'cid_971_athena_commando_m_jupiter_s0z6m':
make_mythic = False
if 'Mat2' in locker_data.unlocked_styles.get('cid_971_athena_commando_m_jupiter_s0z6m', []):
make_mythic = True
if make_mythic == True:
cosmetic['rarity']['value'] = 'mythic'
cosmetic_info = FortniteCosmetic()
cosmetic_info.cosmetic_id = cosmetic['id']
cosmetic_info.name = cosmetic['name']
cosmetic_info.small_icon = cosmetic['images']['smallIcon']
cosmetic_info.backend_value = category
cosmetic_info.rarity_value = cosmetic['rarity']['value']
cosmetic_info.is_banner = False
cosmetic_info.is_exclusive = make_mythic
cosmetic_info.is_popular = cosmetic['id'] in popular_cosmetics
cosmetic_info.unlocked_styles = locker_data.unlocked_styles[cosmetic['id'].lower()]
locker_data.cosmetic_array[category].append(cosmetic_info)
# now special ones
if cosmetic_info.is_popular:
locker_data.cosmetic_array['AthenaPopular'].append(cosmetic_info)
if make_mythic:
locker_data.cosmetic_array['AthenaExclusive'].append(cosmetic_info)
except Exception as e:
print(f'exception: {e}')
continue
# handle banners
banners_data = requests.get('https://fortnite-api.com/v1/banners')
for fn_banner in banners_data.json()['data']:
banner_lower_id = fn_banner['id'].lower()
if banner_lower_id not in locker_data.homebase_banners:
# banner isn't owned
continue
make_mythic = False
icon = fn_banner['images']['icon']
rarity = 'uncommon'
if fn_banner['id'] in exclusive_cosmetics:
make_mythic = True
rarity = 'mythic'
# for future
cosmetic_info = FortniteCosmetic()
cosmetic_info.cosmetic_id = fn_banner['id']
cosmetic_info.name = fn_banner['devName']
cosmetic_info.small_icon = fn_banner['images']['smallIcon']
cosmetic_info.rarity_value = rarity
cosmetic_info.backend_value = 'HomebaseBannerIcons'
cosmetic_info.is_banner = True
cosmetic_info.is_exclusive = make_mythic
cosmetic_info.is_popular = fn_banner['id'] in popular_cosmetics
locker_data.cosmetic_array['HomebaseBannerIcons'].append(cosmetic_info)
# now exclusive ones
if make_mythic:
locker_data.cosmetic_array['AthenaExclusive'].append(cosmetic_info)
# sorting exclusives category
locker_data.cosmetic_array['AthenaExclusive'].sort(
key=lambda cosmetic: exclusive_cosmetics.index(cosmetic.cosmetic_id)
if cosmetic.cosmetic_id in exclusive_cosmetics
else float('inf')
)
# returning back the locker data
return locker_data
async def get_seasons_message(self, user: EpicUser) -> str:
url = f'https://fortnite-public-service-prod11.ol.epicgames.com/fortnite/api/game/v2/profile/{user.account_id}/client/QueryProfile?profileId=athena'
headers = {
"Authorization": f"bearer {user.access_token}",
"Content-Type": "application/json"
}
athena_data = requests.post(url, headers=headers, json={}).json()
past_seasons = {}
seasons_info = []
# seasons infos
past_seasons = athena_data.get("profileChanges", [{}])[0].get("profile", {}).get("stats", {}).get("attributes", {}).get("past_seasons", [])
total_wins = sum(season.get("numWins", 0) for season in past_seasons)
total_matches = sum(
season.get("numHighBracket", 0) + season.get("numLowBracket", 0) +
season.get("numHighBracket_LTM", 0) + season.get("numLowBracket_LTM", 0) +
season.get("numHighBracket_Ar", 0) + season.get("numLowBracket_Ar", 0)
for season in past_seasons
)
curses = athena_data.get("profileChanges", [{}])[0].get("profile", {}).get("stats", {}).get("attributes", {})
cursesinfo = {
'level': curses.get('level', 1),
'book_level': curses.get('book_level', 1)
}
for season in past_seasons:
seasons_info.append(f"""
#️⃣Season {season.get('seasonNumber', 1)}
› Level: {season.get('seasonLevel', '1')}
› Battle Pass: {bool_to_emoji(season.get('purchasedVIP', False))}
› Wins: {season.get('numWins', 0)}
""")
seasons_info_embeds = seasons_info
seasons_info_message = "Previous Seasons History:\n" + "\n".join(seasons_info_embeds)
seasons_info_message += f"\nCurrent Season:\n› Level: {cursesinfo['level']}\n› Battle Pass Level: {cursesinfo['book_level']}"
return seasons_info_message
-415
View File
@@ -1,415 +0,0 @@
Pickaxe_Lockjaw
CID_028_Athena_Commando_F
CID_029_Athena_Commando_F_Halloween
CID_017_Athena_Commando_M
CID_030_Athena_Commando_M_Halloween
Glider_ID_001
Pickaxe_ID_376_FNCS
Pickaxe_FNCS_S32
CID_035_Athena_Commando_M_Medieval
CID_039_Athena_Commando_F_Disco
CID_660_Athena_Commando_F_BandageNinjaBlue
CID_619_Athena_Commando_F_TechLlama
CID_434_Athena_Commando_F_StealthHonor
CID_757_Athena_Commando_F_WildCat
CID_175_Athena_Commando_M_Celestial
CID_342_Athena_Commando_M_StreetRacerMetallic
CID_313_Athena_Commando_M_KpopFashion
CID_386_Athena_Commando_M_StreetOpsStealth
CID_259_Athena_Commando_M_StreetOps
CID_174_Athena_Commando_F_CarbideWhite
Character_MasterKeyOrder
CID_371_Athena_Commando_M_SpeedyMidnight
CID_753_Athena_Commando_F_Hostile
CID_183_Athena_Commando_M_ModernMilitaryRed
CID_479_Athena_Commando_F_Davinci
CID_516_Athena_Commando_M_BlackWidowRogue
CID_441_Athena_Commando_F_CyberScavengerBlue
CID_783_Athena_Commando_M_AquaJacket
CID_850_Athena_Commando_F_SkullBriteCube
CID_113_Athena_Commando_M_BlueAce
CID_515_Athena_Commando_M_BarbequeLarry
CID_971_Athena_Commando_M_Jupiter_S0Z6M
CID_033_Athena_Commando_F_Medieval
CID_032_Athena_Commando_M_Medieval
CID_084_Athena_Commando_M_Assassin
CID_083_Athena_Commando_F_Tactical
CID_090_Athena_Commando_M_Tactical
CID_116_Athena_Commando_M_CarbideBlack
CID_703_Athena_Commando_M_Cyclone
CID_761_Athena_Commando_M_CycloneSpace
CID_478_Athena_Commando_F_WorldCup
CID_964_Athena_Commando_M_Historian_869BC
CID_315_Athena_Commando_M_TeriyakiFish
CID_085_Athena_Commando_M_Twitch
CID_089_Athena_Commando_M_RetroGrey
CID_114_Athena_Commando_F_TacticalWoodland
CID_096_Athena_Commando_F_Founder
CID_095_Athena_Commando_M_Founder
Character_SnowNinjaDark
CID_052_Athena_Commando_F_PSBlue
CID_138_Athena_Commando_M_PSBurnout
CID_296_Athena_Commando_M_Math
CID_360_Athena_Commando_M_TechOpsBlue
CID_A_101_Athena_Commando_M_TacticalWoodlandBlue
CID_A_421_Athena_Commando_F_BlizzardBomber
CID_657_Athena_Commando_F_TechOpsBlue
CID_711_Athena_Commando_M_LongShorts
Character_BlueJet
CID_926_Athena_Commando_F_StreetFashionDiamond
Character_RetroWheels
CID_701_Athena_Commando_M_BananaAgent
CID_690_Athena_Commando_F_Photographer
CID_691_Athena_Commando_F_TNTina
CID_693_Athena_Commando_M_BuffCat
CID_694_Athena_Commando_M_CatBurglar
Character_TubaGummi
BID_004_BlackKnight
BID_415_TechLlama
BID_138_Celestial
BID_521_WildCat
BID_249_StreetOpsStealth
BID_234_SpeedyMidnight
BID_604_SkullBritecube
BID_114_ModernMilitaryRed
BID_346_BlackWidowRogue
PetCarrier_013_BbqLarry
BID_002_RoyaleKnight
BID_001_BlueSquire
Backpack_SnowNinjaDark
BID_A_019_BlizzardBomberFemale
BID_169_MathMale
BID_224_TechOpsBlue
Backpack_BlueJet
Backpack_SnowSoldierFashion
BID_027_Scavenger
BID_468_Cyclone
BID_520_CycloneUniverse
Backpack_FNCSShield_S32
Pickaxe_ID_116_Celestial
Pickaxe_ID_398_WildCatFemale
Pickaxe_ID_077_CarbideWhite
Pickaxe_ID_099_ModernMilitaryRed
Pickaxe_ID_461_SkullBriteCube
Pickaxe_ID_189_StreetOpsStealth
Pickaxe_ID_178_SpeedyMidnight
Pickaxe_ID_294_CandyCane
Pickaxe_ID_508_HistorianMale_6BQSW
Pickaxe_ID_013_Teslacoil
Pickaxe_ID_011_Medieval
Pickaxe_ID_028_Space
Pickaxe_ID_092_Bling
Pickaxe_ID_039_TacticalBlack
Pickaxe_ID_044_TacticalUrbanHammer
Pickaxe_ID_265_BarbequeLarry1H
Pickaxe_ID_STW006_Tier_7
Pickaxe_ID_153_RoseLeader
Pickaxe_SnowNinjaDark
BID_055_PSBurnout
Pickaxe_ID_088_PSBurnout
Pickaxe_ID_256_TechOpsBlue
Pickaxe_ID_464_LongShortsMale
Pickaxe_ID_717_NetworkFemale
Pickaxe_SnowSoldierFashion
Pickaxe_RetroWheels
Pickaxe_ID_STW005_Tier_6
Pickaxe_ID_STW004_Tier_5
Pickaxe_ID_STW003_Tier_4
Pickaxe_ID_STW002_Tier_3
Pickaxe_ID_STW007_Basic
Pickaxe_ID_STW001_Tier_1
Pickaxe_SpookyNeonRed
Pickaxe_SpookyNeonBlue
Pickaxe_ID_359_CycloneMale
EID_KPopDance03
EID_Davinci
EID_Fresh
EID_Floss
EID_Worm
EID_RideThePonyTwo
EID_TakeTheL
EID_HipHop01
EID_GoodVibes
EID_IceKing
EID_RichFam
EID_PlayerEleven
EID_RigorMortis
EID_Gleam
EID_Downward_8GZUA
EID_CycloneHeadBang
EID_SandwichBop
EID_JulyBooks
EID_Laugh
EID_Textile_3O8QG
EID_Uproar_496SC
EID_Tidy
EID_Zippy
EID_Avian
Emoji_S22_Showdown_Mae
Emoji_S22_Showdown_Zet
Spray_Showdown_Mae
Spray_Showdown_Zet
Spray_Showdown_Pi
SPID_066_Llamalaxy
SPID_065_DiscoBaller
SPID_043_Flairspray
SPID_274_Alt_3
SPID_022_SoloShowdown
Glider_Warthog
Glider_ID_003_District
Glider_ID_211_WildCatBlue
Glider_ID_090_Celestial
Glider_ID_056_CarbideWhite
Glider_ID_075_ModernMilitaryRed
Glider_ID_137_StreetOpsStealth
Glider_ID_131_SpeedyMidnight
Glider_ID_002_Medieval
Glider_ID_015_Brite
Glider_ID_161_RoseLeader
FounderGlider
Glider_Military
Glider_ID_013_PSBlue
Glider_ID_067_PSBurnout
Glider_ID_150_TechOpsBlue
Glider_ID_309_TacticalWoodlandBlue
Glider_ID_389_BlizzardBomberFemale
Glider_SnowSoldierFashion
Glider_ID_196_CycloneMale
Glider_ID_347_PeachMale
FounderUmbrella
Umbrella_Snowflake
Umbrella_PaperParasol
Umbrella_AssassinSuit
Umbrella_Lettuce
Umbrella_Vendetta
Wrap_SnowNinjaDark
Wrap_333_StealthWoodland
Wrap_UnknownNetwork
Wrap_DyedBurst
Wrap_210_Thermal
Wrap_303_GasCloud
Trails_ID_059_Sony2
Trails_ID_123_TacticalWoodlandBlue
Trails_ID_150_Avalanche
OT11Banner
OT10Banner
OT9Banner
OT8Banner
OT7Banner
OT6Banner
OT5Banner
OT4Banner
OT3Banner
OT2Banner
OT1Banner
OtherBanner51
BRSeason01
NewsletterBanner
Winter2018Krampus
Winter2018BearTrapFoot
Winter2018Cooker
Winter2018SnowmanBuried
Winter2018CrownFlame
Winter2018IcicleCluster
Winter2018Tower
Winter2018Wave30Complete
Winter2018GingerbreadMan
StarlightBanner6
StarlightBanner5
StarlightBanner4
StarlightBanner3
StarlightBanner2
StarlightBanner1
EnduranceWave30Theater04
EnduranceWave30Theater03
EnduranceWave30Theater02
EnduranceWave30Theater01
WargamesTprifts
WargamesTiki
WargamesPods
SurvivalBannerStorm2018Med
HordeBanner2018TwinePeaks
SurvivalBannerStorm2018Stonewood
WargamesAnomaly
WargamesMeteor
WargamesTornado
AchievementUnspeakableHorrors
AchievementWorldExplorer
AchievementGuardianAngel
AchievementPlaysWellWithOthers
AchievementTalentedBuilder
AchievementGoGnome
AchievementLootLegend
SurvivalBannerPlankertonComplete
SurvivalBannerCannyValleyComplete
SurvivalBannerStonewoodComplete
InfluencerBanner1
InfluencerBanner2
InfluencerBanner3
InfluencerBanner4
InfluencerBanner5
InfluencerBanner6
InfluencerBanner7
InfluencerBanner8
InfluencerBanner9
InfluencerBanner10
InfluencerBanner11
InfluencerBanner12
InfluencerBanner13
InfluencerBanner14
InfluencerBanner15
InfluencerBanner16
InfluencerBanner17
InfluencerBanner18
InfluencerBanner19
InfluencerBanner20
InfluencerBanner21
InfluencerBanner22
InfluencerBanner23
InfluencerBanner24
InfluencerBanner25
InfluencerBanner26
InfluencerBanner27
InfluencerBanner28
InfluencerBanner29
InfluencerBanner30
InfluencerBanner31
InfluencerBanner32
InfluencerBanner33
InfluencerBanner34
InfluencerBanner35
InfluencerBanner36
InfluencerBanner37
InfluencerBanner38
InfluencerBanner39
InfluencerBanner40
InfluencerBanner41
InfluencerBanner42
InfluencerBanner43
InfluencerBanner44
InfluencerBanner45
InfluencerBanner46
InfluencerBanner47
InfluencerBanner48
InfluencerBanner49
InfluencerBanner50
InfluencerBanner51
InfluencerBanner52
InfluencerBanner53
InfluencerBanner54
InfluencerBanner55
InfluencerBanner56
InfluencerBanner57
InfluencerBanner58
BRS22_Showdown_Mae
FounderTier5Banner1
FounderTier5Banner2
FounderTier5Banner3
FounderTier5Banner4
FounderTier5Banner5
FounderTier4Banner1
FounderTier4Banner2
FounderTier4Banner3
FounderTier4Banner4
FounderTier4Banner5
FounderTier3Banner1
FounderTier3Banner2
FounderTier3Banner3
FounderTier3Banner4
FounderTier3Banner5
FounderTier2Banner1
FounderTier2Banner2
FounderTier2Banner3
FounderTier2Banner4
FounderTier2Banner5
FounderTier1Banner1
FounderTier1Banner2
FounderTier1Banner3
FounderTier1Banner4
FounderTier1Banner5
SurvivalBannerHolidayHard
SurvivalBannerHolidayMed
SurvivalBannerHolidayEasy
SurvivalBannerStorm2018Hard
SurvivalBannerStorm2018Med
SurvivalBannerStorm2018Easy
BRS10Level100
BRS9Lvl100
BRS8Level100
NewsletterBanne
BRWorldCup2019
BRS23_FNCS_Drops
BRS9Doggus
BRS9Cattus
File diff suppressed because it is too large. Load diff
Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.0 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.9 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.2 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.8 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.2 MiB

-148
View File
@@ -1,148 +0,0 @@
Pickaxe_ID_376_FNCS
Pickaxe_FNCS_S32
CID_017_Athena_Commando_M
CID_028_Athena_Commando_F
Pickaxe_Lockjaw
Glider_ID_001
CID_619_Athena_Commando_F_TechLlama
CID_035_Athena_Commando_M_Medieval
CID_039_Athena_Commando_F_Disco
CID_434_Athena_Commando_F_StealthHonor
CID_757_Athena_Commando_F_WildCat
CID_175_Athena_Commando_M_Celestial
CID_703_Athena_Commando_M_Cyclone
CID_761_Athena_Commando_M_CycloneSpace
CID_515_Athena_Commando_M_BarbequeLarry
CID_259_Athena_Commando_M_StreetOps
CID_A_215_Athena_Commando_F_SunriseCastle_48TIZ
CID_A_381_Athena_Commando_F_CactusRocker_3HTBV
Character_TigerRootFame
Character_Hitman_Dark
Character_VoltaicHuntress
Character_FallValleyBlink
Character_FallValleyCharge
Character_UpbeatIguana_D
Character_UpbeatIguana
CID_993_Athena_Commando_M_TyphoonRobot_2YRGV
Character_StallionAviator
CID_530_Athena_Commando_F_BlackMonday_1BV6J
CID_A_138_Athena_Commando_F_Foray_YQPB0
CID_A_205_Athena_Commando_F_TextileRam_GMRJ0
CID_A_206_Athena_Commando_F_TextileSparkle_V8YSA
CID_A_207_Athena_Commando_M_TextileKnight_9TE8L
CID_A_208_Athena_Commando_M_TextilePup_C85OD
CID_424_Athena_Commando_M_Vigilante
CID_423_Athena_Commando_F_Painter
CID_A_266_Athena_Commando_F_Grandeur_9CO1M
CID_A_265_Athena_Commando_M_Grandeur_TBC0O
Character_Hitman_Dark
Character_BlueMystery_Dark
Character_PinkTrooperDark
Character_DarkVogue
CID_A_256_Athena_Commando_F_UproarBraids_8IOZW
CID_A_329_Athena_Commando_F_Uproar_I5N5Z
CID_A_385_Athena_Commando_F_Rumble
CID_A_162_Athena_Commando_F_Quarrel_E5D63
CID_A_161_Athena_Commando_M_Quarrel_SLXQG
CID_A_384_Athena_Commando_M_Rumble
CID_A_024_Athena_Commando_F_Skirmish_QW2BQ
CID_A_023_Athena_Commando_M_Skirmish_W1N7H
CID_478_Athena_Commando_F_WorldCup
Character_SpeedDialBattle
CID_704_Athena_Commando_F_LollipopTrickster
CID_715_Athena_Commando_F_TwinDark
CID_A_047_Athena_Commando_F_Windwalker
CID_805_Athena_Commando_F_PunkDevilSummer
CID_801_Athena_Commando_F_GolfSummer
CID_650_Athena_Commando_F_HolidayPJ_B
Character_FauxVenom
CID_365_Athena_Commando_M_LuckyRider
CID_512_Athena_Commando_F_CubePaintRedKnight
CID_653_Athena_Commando_F_UglySweaterFrozen
Character_BrightIon
CID_216_Athena_Commando_F_Medic
CID_A_338_Athena_Commando_F_Galactic_HN9D
Character_RedOasisPomegranate
Character_RedOasisApricot
CID_819_Athena_Commando_F_NeonTightSuit_B
Character_SuperNovaTaro
CID_A_096_Athena_Commando_F_TaxiUpgradedMulticolor
CID_A_388_Athena_Commando_F_Lyrical
CID_A_387_Athena_Commando_M_Lyrical
CID_861_Athena_Commando_F_Elastic_B
CID_A_250_Athena_Commando_F_ZombieElastic_B
CID_A_443_Athena_Commando_F_PennantSeasOne_C
CID_A_444_Athena_Commando_F_PennantSeasOne_D
CID_A_441_Athena_Commando_F_PennantSeasOne
CID_065_Athena_Commando_F_SkiGirl_FRA
CID_062_Athena_Commando_F_SkiGirl_USA
CID_066_Athena_Commando_F_SkiGirl_GER
CID_064_Athena_Commando_F_SkiGirl_GBR
CID_063_Athena_Commando_F_SkiGirl_CAN
CID_068_Athena_Commando_F_SkiGirl_KOR
Character_ReconExpert_FNCS
Character_GarbageFNCS
Character_TreasureHunterFashionsFNCS
Character_LeatherKey
CID_888_Athena_Commando_F_ChOneBanshee
CID_889_Athena_Commando_F_ChOneWildcat
CID_884_Athena_Commando_F_ChOneRamirez
CID_885_Athena_Commando_M_ChOneHawk
BID_138_Celestial
BID_004_BlackKnight
BID_229_LuckyRiderMale
BID_468_Cyclone
BID_273_AssassinSuitCoin
Pickaxe_ID_294_CandyCane
Pickaxe_ID_508_HistorianMale_6BQSW
Pickaxe_ID_363_LollipopTricksterFemale
HalloweenScythe
Pickaxe_ID_015_HolidayCandyCane
Pickaxe_ID_599_CavernFemale
Pickaxe_ID_804_FNCSS20Male
Pickaxe_ID_138_Gnome
Pickaxe_SlowBurn
Pickaxe_IronBlaze
Pickaxe_ID_074_SharpDresser
Pickaxe_ID_014_WinterCamo
Pickaxe_ID_359_CycloneMale
Pickaxe_ID_475_ChOnePickaxe
EID_Fresh
EID_Floss
EID_TakeTheL
EID_CycloneHeadBang
EID_SpeedDial
EID_JanuaryBop
EID_Devotion
EID_Laugh
EID_Griddles
EID_Coping
EID_Cyclone
EID_JanuaryBop
EID_Punctual
EID_Breakdance2
EID_Jaywalking
EID_PlayerEleven
EID_HipHop01
EID_GoodVibes
EID_SandwichBop
EID_LetsPlay
Glider_ID_314_SpaceChimpMale
Glider_Warthog
Glider_ID_244_ChOneGlider
-1
View File
@@ -1 +0,0 @@
import os
Binary file not shown.
Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 32 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 24 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 34 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 31 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.
Binary file not shown.

Before

Width:  |  Height:  |  Size: 35 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 31 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 36 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 30 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 38 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 40 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 42 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 32 KiB

Binary file not shown.
Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 31 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 30 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.5 KiB

Binary file not shown.
Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 31 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 30 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 15 KiB

Loaded 100 of 129 files, more files were not shown because too many files have changed in this diff. Show more