Compare commits
60 Commits
eb329adb68
...
v2.65.2.23
| Author | SHA1 | Date | |
|---|---|---|---|
| c64991fb59 | |||
| ce5dca9818 | |||
| 38376046d0 | |||
| 38356acd37 | |||
| 64a11aaa6f | |||
| 1063a1ab49 | |||
| 959467028c | |||
| 9b4c523aa6 | |||
| 411ef933d1 | |||
| 0a1c177442 | |||
| a03c2e4091 | |||
| 564a68e5cb | |||
| aec20c1f5a | |||
| 8800533c8a | |||
| 1db6b3372c | |||
| 169b041677 | |||
| 3a5a9c6e09 | |||
| eadf18ec00 | |||
| b70833ea3e | |||
| f12a0fe237 | |||
| de7f6a0523 | |||
| fa6dc76d10 | |||
| f03ffa85d8 | |||
| 8d6ae56f33 | |||
| 64e339fb46 | |||
| 29ee808337 | |||
| 72d65e6118 | |||
| 135fdd8812 | |||
| 6bb0938be0 | |||
| 8a37ee810a | |||
| 4d1320161a | |||
| b5d6211ae0 | |||
| fa05cd625f | |||
| d18ebb6dc0 | |||
| f3a89157ca | |||
| 766d45dd17 | |||
| 457bbc0dc3 | |||
| 4ddf1733e4 | |||
| ca2a80cc85 | |||
|
|
c7074f499f | ||
|
|
f6f3a69be4 | ||
|
|
23e09729f7 | ||
|
|
0aca05704f | ||
|
|
b08894e984 | ||
|
|
a1bc8742c9 | ||
|
|
6472cabc05 | ||
|
|
56bb8217d3 | ||
|
|
17f9071317 | ||
|
|
50eda1f4db | ||
|
|
84fbc0a46c | ||
|
|
9551195078 | ||
|
|
f01949d892 | ||
|
|
26b4c05b6f | ||
|
|
6ecab03fd8 | ||
|
|
edc0418d9a | ||
|
|
1d413595b9 | ||
|
|
ce5a593f7b | ||
|
|
faea6a97f0 | ||
|
|
b92913cbf9 | ||
|
|
edec81f4b8 |
@@ -32,7 +32,7 @@ for:
|
||||
- sh: export PYFA_VERSION="$(python3 -B scripts/dump_version.py)"
|
||||
- sh: mkdir build
|
||||
# Download packaging tool
|
||||
- sh: curl -o $APPIMAGE_TOOL -L https://github.com/AppImageCrafters/appimage-builder/releases/download/v1.1.0/appimage-builder-1.1.0-x86_64.AppImage
|
||||
- sh: curl --fail-with-body -o $APPIMAGE_TOOL -L https://github.com/AppImageCrafters/appimage-builder/releases/download/v1.1.0/appimage-builder-1.1.0-x86_64.AppImage
|
||||
- sh: chmod +x $APPIMAGE_TOOL
|
||||
build_script:
|
||||
- sh: mkdir -p AppDir/opt/pyfa
|
||||
|
||||
2
.gitattributes
vendored
@@ -33,4 +33,4 @@ pyfa.py text eol=lf
|
||||
*.jpg binary
|
||||
*.icns binary
|
||||
*.ico binary
|
||||
|
||||
*.dll filter=lfs diff=lfs merge=lfs -text
|
||||
|
||||
3
.gitignore
vendored
@@ -126,4 +126,5 @@ gitversion
|
||||
/locale/progress.json
|
||||
|
||||
# vscode settings
|
||||
.vscode
|
||||
.vscode
|
||||
eve.db
|
||||
|
||||
3
.gitmodules
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
[submodule "Pyfa-Mod"]
|
||||
path = Pyfa-Mod
|
||||
url = https://github.com/Eivonz/Pyfa-Mod
|
||||
30
build.sh
Normal file
@@ -0,0 +1,30 @@
|
||||
#!/bin/bash
|
||||
|
||||
set -e
|
||||
|
||||
echo "Building pyfa binary..."
|
||||
|
||||
# Ensure we're using the local venv
|
||||
if [ ! -d ".venv" ]; then
|
||||
echo "Creating virtual environment..."
|
||||
uv venv
|
||||
fi
|
||||
|
||||
# Install dependencies
|
||||
echo "Installing dependencies..."
|
||||
uv pip install -r requirements.txt
|
||||
uv pip install pyinstaller
|
||||
|
||||
# Clean previous builds
|
||||
echo "Cleaning previous builds..."
|
||||
rm -rf build dist
|
||||
|
||||
# Build the binary
|
||||
echo "Building binary with PyInstaller..."
|
||||
uv run pyinstaller pyfa.spec
|
||||
|
||||
# cp oleacc* dist/pyfa/
|
||||
|
||||
echo ""
|
||||
echo "Build complete! Binary is located at: dist/pyfa/pyfa.exe"
|
||||
echo "You can run it with: dist/pyfa/pyfa.exe"
|
||||
387
eos/effects.py
@@ -1333,10 +1333,10 @@ class Effect446(BaseEffect):
|
||||
Implants named like: Capsuleer Defense Augmentation Chip (3 of 3)
|
||||
Implants named like: Festival only 'Rock' SH Dose (4 of 4)
|
||||
Implants named like: Halcyon G Booster (5 of 5)
|
||||
Implants named like: Nirvana Booster (5 of 5)
|
||||
Implants named like: Serenity Limited 'Hardshell' Dose (3 of 3)
|
||||
Implants named like: Zainou 'Gnome' Shield Management SM (6 of 6)
|
||||
Modules named like: Core Defense Field Extender (8 of 8)
|
||||
Implant: AIR Nirvana Booster II
|
||||
Implant: Genolution Core Augmentation CA-3
|
||||
Implant: Sansha Modified 'Gnome' Implant
|
||||
Skill: Shield Management
|
||||
@@ -1358,6 +1358,7 @@ class Effect485(BaseEffect):
|
||||
Implants named like: Halcyon G Booster (5 of 5)
|
||||
Implants named like: Halcyon R Booster (5 of 5)
|
||||
Implants named like: Inherent Implants 'Squire' Capacitor Systems Operation EO (6 of 6)
|
||||
Implants named like: Wightstorm Rapture Booster (4 of 4)
|
||||
Implants named like: grade Rapture (15 of 18)
|
||||
Modules named like: Capacitor Control Circuit (8 of 8)
|
||||
Implant: AIR Overclocker Booster III
|
||||
@@ -2603,15 +2604,22 @@ class Effect891(BaseEffect):
|
||||
|
||||
Used by:
|
||||
Variations of ship: Raven (3 of 4)
|
||||
Module: Anhinga Tertiary Mode
|
||||
"""
|
||||
|
||||
type = 'passive'
|
||||
|
||||
@staticmethod
|
||||
def handler(fit, ship, context, projectionRange, **kwargs):
|
||||
fit.modules.filteredChargeBoost(lambda mod: mod.charge.requiresSkill('Cruise Missiles'),
|
||||
'maxVelocity', ship.getModifiedItemAttr('shipBonusCB3'),
|
||||
skill='Caldari Battleship', **kwargs)
|
||||
if 'ship' in context:
|
||||
skill = 'Caldari Battleship'
|
||||
penalties = False
|
||||
else:
|
||||
skill = None
|
||||
penalties = True
|
||||
fit.modules.filteredChargeBoost(
|
||||
lambda mod: mod.charge.requiresSkill('Cruise Missiles'), 'maxVelocity',
|
||||
ship.getModifiedItemAttr('shipBonusCB3'), skill=skill, stackingPenalties=penalties, **kwargs)
|
||||
|
||||
|
||||
class Effect892(BaseEffect):
|
||||
@@ -2620,15 +2628,22 @@ class Effect892(BaseEffect):
|
||||
|
||||
Used by:
|
||||
Variations of ship: Raven (3 of 4)
|
||||
Module: Anhinga Tertiary Mode
|
||||
"""
|
||||
|
||||
type = 'passive'
|
||||
|
||||
@staticmethod
|
||||
def handler(fit, ship, context, projectionRange, **kwargs):
|
||||
fit.modules.filteredChargeBoost(lambda mod: mod.charge.requiresSkill('Torpedoes'),
|
||||
'maxVelocity', ship.getModifiedItemAttr('shipBonusCB3'),
|
||||
skill='Caldari Battleship', **kwargs)
|
||||
if 'ship' in context:
|
||||
skill = 'Caldari Battleship'
|
||||
penalties = False
|
||||
else:
|
||||
skill = None
|
||||
penalties = True
|
||||
fit.modules.filteredChargeBoost(
|
||||
lambda mod: mod.charge.requiresSkill('Torpedoes'), 'maxVelocity',
|
||||
ship.getModifiedItemAttr('shipBonusCB3'), skill=skill, stackingPenalties=penalties, **kwargs)
|
||||
|
||||
|
||||
class Effect896(BaseEffect):
|
||||
@@ -3285,6 +3300,7 @@ class Effect1024(BaseEffect):
|
||||
shipMissileHeavyVelocityBonusCC2
|
||||
|
||||
Used by:
|
||||
Module: Anhinga Tertiary Mode
|
||||
Ship: Caracal
|
||||
Ship: Osprey Navy Issue
|
||||
"""
|
||||
@@ -3293,9 +3309,15 @@ class Effect1024(BaseEffect):
|
||||
|
||||
@staticmethod
|
||||
def handler(fit, ship, context, projectionRange, **kwargs):
|
||||
fit.modules.filteredChargeBoost(lambda mod: mod.charge.requiresSkill('Heavy Missiles'),
|
||||
'maxVelocity', ship.getModifiedItemAttr('shipBonusCC2'),
|
||||
skill='Caldari Cruiser', **kwargs)
|
||||
if 'ship' in context:
|
||||
skill = 'Caldari Cruiser'
|
||||
penalties = False
|
||||
else:
|
||||
skill = None
|
||||
penalties = True
|
||||
fit.modules.filteredChargeBoost(
|
||||
lambda mod: mod.charge.requiresSkill('Heavy Missiles'), 'maxVelocity',
|
||||
ship.getModifiedItemAttr('shipBonusCC2'), skill=skill, stackingPenalties=penalties, **kwargs)
|
||||
|
||||
|
||||
class Effect1030(BaseEffect):
|
||||
@@ -3905,6 +3927,7 @@ class Effect1230(BaseEffect):
|
||||
shipMissileVelocityPirateFactionFrigate
|
||||
|
||||
Used by:
|
||||
Module: Anhinga Primary Mode
|
||||
Ship: Barghest
|
||||
Ship: Garmur
|
||||
Ship: Laelaps
|
||||
@@ -3916,8 +3939,10 @@ class Effect1230(BaseEffect):
|
||||
|
||||
@staticmethod
|
||||
def handler(fit, ship, context, projectionRange, **kwargs):
|
||||
fit.modules.filteredChargeBoost(lambda mod: mod.charge.requiresSkill('Missile Launcher Operation'),
|
||||
'maxVelocity', ship.getModifiedItemAttr('shipBonusRole7'), **kwargs)
|
||||
penalties = 'ship' not in context
|
||||
fit.modules.filteredChargeBoost(
|
||||
lambda mod: mod.charge.requiresSkill('Missile Launcher Operation'), 'maxVelocity',
|
||||
ship.getModifiedItemAttr('shipBonusRole7'), stackingPenalties=penalties, **kwargs)
|
||||
|
||||
|
||||
class Effect1232(BaseEffect):
|
||||
@@ -5654,6 +5679,7 @@ class Effect1885(BaseEffect):
|
||||
shipCruiseLauncherROFBonus2CB
|
||||
|
||||
Used by:
|
||||
Modules named like: Anhinga Mode (3 of 3)
|
||||
Ship: Raven
|
||||
Ship: Raven State Issue
|
||||
"""
|
||||
@@ -5662,9 +5688,18 @@ class Effect1885(BaseEffect):
|
||||
|
||||
@staticmethod
|
||||
def handler(fit, ship, context, projectionRange, **kwargs):
|
||||
fit.modules.filteredItemBoost(lambda mod: mod.item.group.name == 'Missile Launcher Cruise',
|
||||
'speed', ship.getModifiedItemAttr('shipBonus2CB'),
|
||||
skill='Caldari Battleship', **kwargs)
|
||||
if 'ship' in context:
|
||||
skill = 'Caldari Battleship'
|
||||
penalties = False
|
||||
penaltyGroup = None
|
||||
else:
|
||||
skill = None
|
||||
penalties = True
|
||||
penaltyGroup = 'postPerc'
|
||||
fit.modules.filteredItemBoost(
|
||||
lambda mod: mod.item.group.name == 'Missile Launcher Cruise', 'speed',
|
||||
ship.getModifiedItemAttr('shipBonus2CB'), skill=skill,
|
||||
stackingPenalties=penalties, penaltyGroup=penaltyGroup, **kwargs)
|
||||
|
||||
|
||||
class Effect1886(BaseEffect):
|
||||
@@ -5672,6 +5707,7 @@ class Effect1886(BaseEffect):
|
||||
shipSiegeLauncherROFBonus2CB
|
||||
|
||||
Used by:
|
||||
Modules named like: Anhinga Mode (3 of 3)
|
||||
Ship: Raven
|
||||
Ship: Raven State Issue
|
||||
"""
|
||||
@@ -5680,9 +5716,18 @@ class Effect1886(BaseEffect):
|
||||
|
||||
@staticmethod
|
||||
def handler(fit, ship, context, projectionRange, **kwargs):
|
||||
fit.modules.filteredItemBoost(lambda mod: mod.item.group.name == 'Missile Launcher Torpedo',
|
||||
'speed', ship.getModifiedItemAttr('shipBonus2CB'),
|
||||
skill='Caldari Battleship', **kwargs)
|
||||
if 'ship' in context:
|
||||
skill = 'Caldari Battleship'
|
||||
penalties = False
|
||||
penaltyGroup = None
|
||||
else:
|
||||
skill = None
|
||||
penalties = True
|
||||
penaltyGroup = 'postPerc'
|
||||
fit.modules.filteredItemBoost(
|
||||
lambda mod: mod.item.group.name == 'Missile Launcher Torpedo', 'speed',
|
||||
ship.getModifiedItemAttr('shipBonus2CB'), skill=skill,
|
||||
stackingPenalties=penalties, penaltyGroup=penaltyGroup, **kwargs)
|
||||
|
||||
|
||||
class Effect1910(BaseEffect):
|
||||
@@ -8398,6 +8443,7 @@ class Effect2803(BaseEffect):
|
||||
|
||||
Used by:
|
||||
Implants named like: Harvest Damage Booster (4 of 4)
|
||||
Implants named like: Wightstorm Vitarka Booster (4 of 4)
|
||||
Modules named like: Energy Collision Accelerator (8 of 8)
|
||||
Implant: Wisdom of Gheinok
|
||||
"""
|
||||
@@ -9674,6 +9720,7 @@ class Effect3196(BaseEffect):
|
||||
thermodynamicsSkillDamageBonus
|
||||
|
||||
Used by:
|
||||
Implants named like: Wightstorm Sunyata Booster (4 of 4)
|
||||
Skill: Thermodynamics
|
||||
"""
|
||||
|
||||
@@ -18029,6 +18076,7 @@ class Effect5189(BaseEffect):
|
||||
|
||||
Used by:
|
||||
Implants named like: Tetrimon Precision Booster (4 of 4)
|
||||
Implants named like: Wightstorm Manasikara Booster (4 of 4)
|
||||
Modules named like: Energy Metastasis Adjuster (8 of 8)
|
||||
"""
|
||||
|
||||
@@ -18179,6 +18227,7 @@ class Effect5213(BaseEffect):
|
||||
shipRocketMaxVelocityBonusRookie
|
||||
|
||||
Used by:
|
||||
Module: Skua Sharpshooter Mode
|
||||
Ship: Taipan
|
||||
"""
|
||||
|
||||
@@ -18186,8 +18235,10 @@ class Effect5213(BaseEffect):
|
||||
|
||||
@staticmethod
|
||||
def handler(fit, ship, context, projectionRange, **kwargs):
|
||||
fit.modules.filteredChargeBoost(lambda mod: mod.charge.requiresSkill('Rockets'),
|
||||
'maxVelocity', ship.getModifiedItemAttr('rookieRocketVelocity'), **kwargs)
|
||||
penalties = 'ship' not in context
|
||||
fit.modules.filteredChargeBoost(
|
||||
lambda mod: mod.charge.requiresSkill('Rockets'), 'maxVelocity',
|
||||
ship.getModifiedItemAttr('rookieRocketVelocity'), stackingPenalties=penalties, **kwargs)
|
||||
|
||||
|
||||
class Effect5214(BaseEffect):
|
||||
@@ -18195,6 +18246,7 @@ class Effect5214(BaseEffect):
|
||||
shipLightMissileMaxVelocityBonusRookie
|
||||
|
||||
Used by:
|
||||
Module: Skua Sharpshooter Mode
|
||||
Ship: Taipan
|
||||
"""
|
||||
|
||||
@@ -18202,8 +18254,10 @@ class Effect5214(BaseEffect):
|
||||
|
||||
@staticmethod
|
||||
def handler(fit, ship, context, projectionRange, **kwargs):
|
||||
fit.modules.filteredChargeBoost(lambda mod: mod.charge.requiresSkill('Light Missiles'),
|
||||
'maxVelocity', ship.getModifiedItemAttr('rookieLightMissileVelocity'), **kwargs)
|
||||
penalties = 'ship' not in context
|
||||
fit.modules.filteredChargeBoost(
|
||||
lambda mod: mod.charge.requiresSkill('Light Missiles'), 'maxVelocity',
|
||||
ship.getModifiedItemAttr('rookieLightMissileVelocity'), stackingPenalties=penalties, **kwargs)
|
||||
|
||||
|
||||
class Effect5215(BaseEffect):
|
||||
@@ -20345,6 +20399,7 @@ class Effect5468(BaseEffect):
|
||||
shipBonusAgilityCI2
|
||||
|
||||
Used by:
|
||||
Module: Anhinga Tertiary Mode
|
||||
Ship: Badger
|
||||
"""
|
||||
|
||||
@@ -20352,7 +20407,14 @@ class Effect5468(BaseEffect):
|
||||
|
||||
@staticmethod
|
||||
def handler(fit, ship, context, projectionRange, **kwargs):
|
||||
fit.ship.boostItemAttr('agility', ship.getModifiedItemAttr('shipBonusCI2'), skill='Caldari Hauler', **kwargs)
|
||||
if 'ship' in context:
|
||||
skill = 'Caldari Hauler'
|
||||
penalties = False
|
||||
else:
|
||||
skill = None
|
||||
penalties = True
|
||||
fit.ship.boostItemAttr('agility', ship.getModifiedItemAttr('shipBonusCI2'),
|
||||
skill=skill, stackingPenalties=penalties, **kwargs)
|
||||
|
||||
|
||||
class Effect5469(BaseEffect):
|
||||
@@ -20885,6 +20947,24 @@ class Effect5559(BaseEffect):
|
||||
'shieldBonus', ship.getModifiedItemAttr('shipBonusMC2'), skill='Minmatar Cruiser', **kwargs)
|
||||
|
||||
|
||||
class Effect5560(BaseEffect):
|
||||
"""
|
||||
roleBonusMarauderMJDRReactivationDelayBonus
|
||||
|
||||
Used by:
|
||||
Module: Anhinga Tertiary Mode
|
||||
"""
|
||||
|
||||
type = 'passive'
|
||||
|
||||
@staticmethod
|
||||
def handler(fit, ship, context, projectionRange, **kwargs):
|
||||
penalties = 'ship' not in context
|
||||
fit.modules.filteredItemBoost(
|
||||
lambda mod: mod.item.group.name == 'Micro Jump Drive', 'moduleReactivationDelay',
|
||||
ship.getModifiedItemAttr('roleBonusMarauder'), stackingPenalties=penalties, **kwargs)
|
||||
|
||||
|
||||
class Effect5564(BaseEffect):
|
||||
"""
|
||||
subSystemBonusCaldariOffensiveCommandBursts
|
||||
@@ -21075,6 +21155,7 @@ class Effect5618(BaseEffect):
|
||||
shipBonusRHMLROF2CB
|
||||
|
||||
Used by:
|
||||
Modules named like: Anhinga Mode (3 of 3)
|
||||
Ship: Raven
|
||||
Ship: Widow
|
||||
"""
|
||||
@@ -21083,8 +21164,18 @@ class Effect5618(BaseEffect):
|
||||
|
||||
@staticmethod
|
||||
def handler(fit, ship, context, projectionRange, **kwargs):
|
||||
fit.modules.filteredItemBoost(lambda mod: mod.item.group.name == 'Missile Launcher Rapid Heavy',
|
||||
'speed', ship.getModifiedItemAttr('shipBonus2CB'), skill='Caldari Battleship', **kwargs)
|
||||
if 'ship' in context:
|
||||
skill = 'Caldari Battleship'
|
||||
penalties = False
|
||||
penaltyGroup = None
|
||||
else:
|
||||
skill = None
|
||||
penalties = True
|
||||
penaltyGroup = 'postPerc'
|
||||
fit.modules.filteredItemBoost(
|
||||
lambda mod: mod.item.group.name == 'Missile Launcher Rapid Heavy', 'speed',
|
||||
ship.getModifiedItemAttr('shipBonus2CB'), skill=skill,
|
||||
stackingPenalties=penalties, penaltyGroup=penaltyGroup, **kwargs)
|
||||
|
||||
|
||||
class Effect5619(BaseEffect):
|
||||
@@ -22373,6 +22464,8 @@ class Effect5867(BaseEffect):
|
||||
shipBonusMissileExplosionDelayPirateFaction2
|
||||
|
||||
Used by:
|
||||
Module: Anhinga Primary Mode
|
||||
Module: Anhinga Secondary Mode
|
||||
Ship: Barghest
|
||||
Ship: Garmur
|
||||
Ship: Laelaps
|
||||
@@ -22384,8 +22477,10 @@ class Effect5867(BaseEffect):
|
||||
|
||||
@staticmethod
|
||||
def handler(fit, ship, context, projectionRange, **kwargs):
|
||||
fit.modules.filteredChargeBoost(lambda mod: mod.charge.requiresSkill('Missile Launcher Operation'),
|
||||
'explosionDelay', ship.getModifiedItemAttr('shipBonusRole8'), **kwargs)
|
||||
penalties = 'ship' not in context
|
||||
fit.modules.filteredChargeBoost(
|
||||
lambda mod: mod.charge.requiresSkill('Missile Launcher Operation'), 'explosionDelay',
|
||||
ship.getModifiedItemAttr('shipBonusRole8'), stackingPenalties=penalties, **kwargs)
|
||||
|
||||
|
||||
class Effect5868(BaseEffect):
|
||||
@@ -23307,7 +23402,7 @@ class Effect6009(BaseEffect):
|
||||
|
||||
Used by:
|
||||
Ships from group: Strategic Cruiser (4 of 4)
|
||||
Ships from group: Tactical Destroyer (4 of 4)
|
||||
Ships from group: Tactical Destroyer (5 of 5)
|
||||
"""
|
||||
|
||||
type = 'passive'
|
||||
@@ -23324,7 +23419,8 @@ class Effect6010(BaseEffect):
|
||||
shipModeMaxTargetRangePostDiv
|
||||
|
||||
Used by:
|
||||
Modules named like: Sharpshooter Mode (4 of 4)
|
||||
Modules named like: Sharpshooter Mode (5 of 5)
|
||||
Module: Anhinga Primary Mode
|
||||
"""
|
||||
|
||||
type = 'passive'
|
||||
@@ -23365,7 +23461,7 @@ class Effect6012(BaseEffect):
|
||||
shipModeScanStrengthPostDiv
|
||||
|
||||
Used by:
|
||||
Modules named like: Sharpshooter Mode (4 of 4)
|
||||
Modules named like: Sharpshooter Mode (5 of 5)
|
||||
"""
|
||||
|
||||
type = 'passive'
|
||||
@@ -23386,8 +23482,7 @@ class Effect6014(BaseEffect):
|
||||
modeSigRadiusPostDiv
|
||||
|
||||
Used by:
|
||||
Module: Confessor Defense Mode
|
||||
Module: Jackdaw Defense Mode
|
||||
Modules named like: Defense Mode (3 of 5)
|
||||
"""
|
||||
|
||||
type = 'passive'
|
||||
@@ -23403,7 +23498,7 @@ class Effect6015(BaseEffect):
|
||||
modeArmorResonancePostDiv
|
||||
|
||||
Used by:
|
||||
Modules named like: Defense Mode (3 of 4)
|
||||
Modules named like: Defense Mode (3 of 5)
|
||||
"""
|
||||
|
||||
type = 'passive'
|
||||
@@ -23429,7 +23524,7 @@ class Effect6016(BaseEffect):
|
||||
modeAgilityPostDiv
|
||||
|
||||
Used by:
|
||||
Modules named like: Propulsion Mode (4 of 4)
|
||||
Modules named like: Propulsion Mode (5 of 5)
|
||||
"""
|
||||
|
||||
type = 'passive'
|
||||
@@ -23643,8 +23738,7 @@ class Effect6041(BaseEffect):
|
||||
modeShieldResonancePostDiv
|
||||
|
||||
Used by:
|
||||
Module: Jackdaw Defense Mode
|
||||
Module: Svipul Defense Mode
|
||||
Modules named like: Defense Mode (3 of 5)
|
||||
"""
|
||||
|
||||
type = 'passive'
|
||||
@@ -23968,6 +24062,7 @@ class Effect6077(BaseEffect):
|
||||
|
||||
Used by:
|
||||
Ship: Jackdaw
|
||||
Ship: Skua
|
||||
"""
|
||||
|
||||
type = 'passive'
|
||||
@@ -23986,6 +24081,7 @@ class Effect6083(BaseEffect):
|
||||
Used by:
|
||||
Ship: Jackdaw
|
||||
Ship: Metamorphosis
|
||||
Ship: Skua
|
||||
Ship: Sunesis
|
||||
"""
|
||||
|
||||
@@ -24005,6 +24101,7 @@ class Effect6085(BaseEffect):
|
||||
|
||||
Used by:
|
||||
Ship: Jackdaw
|
||||
Ship: Skua
|
||||
"""
|
||||
|
||||
type = 'passive'
|
||||
@@ -24079,6 +24176,7 @@ class Effect6098(BaseEffect):
|
||||
|
||||
Used by:
|
||||
Ship: Jackdaw
|
||||
Ship: Skua
|
||||
"""
|
||||
|
||||
type = 'passive'
|
||||
@@ -25472,6 +25570,7 @@ class Effect6316(BaseEffect):
|
||||
|
||||
Used by:
|
||||
Ships from group: Command Destroyer (3 of 6)
|
||||
Ship: Skua
|
||||
"""
|
||||
|
||||
type = 'passive'
|
||||
@@ -25490,6 +25589,7 @@ class Effect6317(BaseEffect):
|
||||
|
||||
Used by:
|
||||
Ships from group: Command Destroyer (6 of 6)
|
||||
Ship: Skua
|
||||
"""
|
||||
|
||||
type = 'passive'
|
||||
@@ -25763,6 +25863,7 @@ class Effect6334(BaseEffect):
|
||||
|
||||
Used by:
|
||||
Ships from group: Command Destroyer (3 of 6)
|
||||
Ship: Skua
|
||||
"""
|
||||
|
||||
type = 'passive'
|
||||
@@ -31727,6 +31828,7 @@ class Effect6799(BaseEffect):
|
||||
|
||||
Used by:
|
||||
Module: Jackdaw Sharpshooter Mode
|
||||
Module: Skua Sharpshooter Mode
|
||||
"""
|
||||
|
||||
type = 'passive'
|
||||
@@ -31747,7 +31849,7 @@ class Effect6800(BaseEffect):
|
||||
modeDampTDResistsPostDiv
|
||||
|
||||
Used by:
|
||||
Modules named like: Sharpshooter Mode (4 of 4)
|
||||
Modules named like: Sharpshooter Mode (5 of 5)
|
||||
"""
|
||||
|
||||
type = 'passive'
|
||||
@@ -31763,8 +31865,7 @@ class Effect6801(BaseEffect):
|
||||
modeMWDandABBoostPostDiv
|
||||
|
||||
Used by:
|
||||
Module: Confessor Propulsion Mode
|
||||
Module: Svipul Propulsion Mode
|
||||
Modules named like: Propulsion Mode (3 of 5)
|
||||
"""
|
||||
|
||||
type = 'passive'
|
||||
@@ -34760,11 +34861,20 @@ class Effect7117(BaseEffect):
|
||||
roleBonusWarpSpeed
|
||||
|
||||
Used by:
|
||||
Items from category: Ship (42 of 409)
|
||||
Ships from group: Blockade Runner (5 of 5)
|
||||
Ships from group: Covert Ops (9 of 9)
|
||||
Ships from group: Hauler (5 of 18)
|
||||
Ships from group: Interceptor (10 of 10)
|
||||
Ships from group: Interdictor (4 of 4)
|
||||
Ship: Azariel
|
||||
Ship: Cynabal
|
||||
Ship: Dramiel
|
||||
Ship: Khizriel
|
||||
Ship: Leopard
|
||||
Ship: Machariel
|
||||
Ship: Mekubal
|
||||
Ship: Sarathiel
|
||||
Ship: Victorieux Luxury Yacht
|
||||
"""
|
||||
|
||||
type = 'passive'
|
||||
@@ -37751,6 +37861,23 @@ class Effect8279(BaseEffect):
|
||||
skill='Industrial Command Ships', **kwargs)
|
||||
|
||||
|
||||
class Effect8291(BaseEffect):
|
||||
"""
|
||||
afterburnerSpeedBoostBonusPassive
|
||||
|
||||
Used by:
|
||||
Implants named like: Wightstorm Cetana Booster (4 of 4)
|
||||
"""
|
||||
|
||||
type = 'passive'
|
||||
|
||||
@staticmethod
|
||||
def handler(fit, booster, context, projectionRange, **kwargs):
|
||||
fit.modules.filteredItemBoost(
|
||||
lambda mod: mod.item.requiresSkill('Afterburner'), 'speedFactor',
|
||||
booster.getModifiedItemAttr('speedFBonus'), **kwargs)
|
||||
|
||||
|
||||
class Effect8294(BaseEffect):
|
||||
"""
|
||||
industrialCommandBonusDroneOreMiningYield
|
||||
@@ -41626,7 +41753,7 @@ class Effect12329(BaseEffect):
|
||||
shipMiningYieldBonusOreDestroyer1
|
||||
|
||||
Used by:
|
||||
Variations of ship: Pioneer (3 of 3)
|
||||
Variations of ship: Pioneer (3 of 4)
|
||||
"""
|
||||
|
||||
type = 'passive'
|
||||
@@ -42378,6 +42505,26 @@ class Effect12757(BaseEffect):
|
||||
'miningCritBonusYield', src.getModifiedItemAttr('miningCritBonusYieldBonus') * src.level, **kwargs)
|
||||
|
||||
|
||||
class Effect12758(BaseEffect):
|
||||
"""
|
||||
shipRoleBonusAnhingaLargeMissilePowerFittingBonus
|
||||
|
||||
Used by:
|
||||
Ship: Anhinga
|
||||
"""
|
||||
|
||||
type = 'passive'
|
||||
|
||||
@staticmethod
|
||||
def handler(fit, ship, context, projectionRange, **kwargs):
|
||||
fit.modules.filteredItemMultiply(
|
||||
lambda mod: mod.item.group.name in (
|
||||
'Missile Launcher Rapid Heavy',
|
||||
'Missile Launcher Cruise',
|
||||
'Missile Launcher Torpedo'),
|
||||
'power', ship.getModifiedItemAttr('AnhingaLargeMissilePowerFittingBonus'), **kwargs)
|
||||
|
||||
|
||||
class Effect12759(BaseEffect):
|
||||
"""
|
||||
miningCritChanceBonusOreIceOnline
|
||||
@@ -42428,4 +42575,160 @@ class Effect12761(BaseEffect):
|
||||
lambda mod: (mod.item.requiresSkill('Mining')
|
||||
or mod.item.requiresSkill('Ice Harvesting')
|
||||
or mod.item.requiresSkill('Gas Cloud Harvesting')),
|
||||
'miningWasteProbability', src.getModifiedItemAttr('miningWasteProbabilityBonus'), **kwargs)
|
||||
'miningWasteProbability', src.getModifiedItemAttr('miningWasteProbabilityBonus'),
|
||||
stackingPenalties=True, **kwargs)
|
||||
|
||||
|
||||
class Effect12764(BaseEffect):
|
||||
"""
|
||||
shipRoleBonusAnhingaLargeMissileCpuFittingBonus
|
||||
|
||||
Used by:
|
||||
Ship: Anhinga
|
||||
"""
|
||||
|
||||
type = 'passive'
|
||||
|
||||
@staticmethod
|
||||
def handler(fit, ship, context, projectionRange, **kwargs):
|
||||
fit.modules.filteredItemMultiply(
|
||||
lambda mod: mod.item.group.name in (
|
||||
'Missile Launcher Rapid Heavy',
|
||||
'Missile Launcher Cruise',
|
||||
'Missile Launcher Torpedo'),
|
||||
'cpu', ship.getModifiedItemAttr('AnhingaLargeMissileCpuFittingBonus'), **kwargs)
|
||||
|
||||
|
||||
class Effect12766(BaseEffect):
|
||||
"""
|
||||
shipBonusTorpedoAndCruiseMissileExplosionRadiusCBC1
|
||||
|
||||
Used by:
|
||||
Ship: Anhinga
|
||||
"""
|
||||
|
||||
type = 'passive'
|
||||
|
||||
@staticmethod
|
||||
def handler(fit, ship, context, projectionRange, **kwargs):
|
||||
fit.modules.filteredChargeBoost(
|
||||
lambda mod: mod.charge.requiresSkill('Torpedoes') or mod.charge.requiresSkill('Cruise Missiles'),
|
||||
'aoeCloudSize', ship.getModifiedItemAttr('shipBonusCBC1'), skill='Caldari Battlecruiser', **kwargs)
|
||||
|
||||
|
||||
class Effect12767(BaseEffect):
|
||||
"""
|
||||
tacticalBonusSkuaDefensiveShieldRechargeRate
|
||||
|
||||
Used by:
|
||||
Module: Skua Defense Mode
|
||||
"""
|
||||
|
||||
type = 'passive'
|
||||
|
||||
@staticmethod
|
||||
def handler(fit, module, context, projectionRange, **kwargs):
|
||||
fit.ship.multiplyItemAttr('shieldRechargeRate', 1 / module.getModifiedItemAttr('modeShieldRechargePostDiv'), **kwargs)
|
||||
|
||||
|
||||
class Effect12771(BaseEffect):
|
||||
"""
|
||||
shipRoleBonusPerseveranceIceMiningCriticalHitChanceBonus
|
||||
|
||||
Used by:
|
||||
Ship: Perseverance
|
||||
"""
|
||||
|
||||
type = 'passive'
|
||||
|
||||
@staticmethod
|
||||
def handler(fit, ship, context, projectionRange, **kwargs):
|
||||
fit.modules.filteredItemBoost(
|
||||
lambda mod: mod.item.requiresSkill('Ice Harvesting'), 'miningCritChance',
|
||||
ship.getModifiedItemAttr('shipRoleBonusPerseveranceIceMiningCriticalHitChance'), **kwargs)
|
||||
|
||||
|
||||
class Effect12772(BaseEffect):
|
||||
"""
|
||||
shipIceMiningCriticalHitChanceBonusOreDestroyer1
|
||||
|
||||
Used by:
|
||||
Ship: Perseverance
|
||||
"""
|
||||
|
||||
type = 'passive'
|
||||
|
||||
@staticmethod
|
||||
def handler(fit, ship, context, projectionRange, **kwargs):
|
||||
fit.modules.filteredItemBoost(
|
||||
lambda mod: mod.item.requiresSkill('Ice Harvesting'), 'miningCritChance',
|
||||
ship.getModifiedItemAttr('shipBonusOreDestroyer1'), skill='Mining Destroyer', **kwargs)
|
||||
|
||||
|
||||
class Effect12773(BaseEffect):
|
||||
"""
|
||||
shipIceMiningCriticalHitYieldBonusOreDestroyer2
|
||||
|
||||
Used by:
|
||||
Ship: Perseverance
|
||||
"""
|
||||
|
||||
type = 'passive'
|
||||
|
||||
@staticmethod
|
||||
def handler(fit, ship, context, projectionRange, **kwargs):
|
||||
fit.modules.filteredItemBoost(
|
||||
lambda mod: mod.item.requiresSkill('Ice Harvesting'), 'miningCritBonusYield',
|
||||
ship.getModifiedItemAttr('shipBonusOreDestroyer2'), skill='Mining Destroyer', **kwargs)
|
||||
|
||||
|
||||
class Effect12774(BaseEffect):
|
||||
"""
|
||||
shipIceMiningRangeBonusOreDestroyer3
|
||||
|
||||
Used by:
|
||||
Ship: Perseverance
|
||||
"""
|
||||
|
||||
type = 'passive'
|
||||
|
||||
@staticmethod
|
||||
def handler(fit, ship, context, projectionRange, **kwargs):
|
||||
fit.modules.filteredItemBoost(
|
||||
lambda mod: mod.item.requiresSkill('Ice Harvesting'), 'maxRange',
|
||||
ship.getModifiedItemAttr('shipBonusOreDestroyer3'), skill='Mining Destroyer', **kwargs)
|
||||
|
||||
|
||||
class Effect12777(BaseEffect):
|
||||
"""
|
||||
roleBonusCDLinksPGCPUReductionSkua
|
||||
|
||||
Used by:
|
||||
Ship: Skua
|
||||
"""
|
||||
|
||||
type = 'passive'
|
||||
|
||||
@staticmethod
|
||||
def handler(fit, src, context, projectionRange, **kwargs):
|
||||
fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill('Leadership'), 'cpu',
|
||||
src.getModifiedItemAttr('roleBonusCD'), **kwargs)
|
||||
fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill('Leadership'), 'power',
|
||||
src.getModifiedItemAttr('roleBonusCD'), **kwargs)
|
||||
|
||||
|
||||
class Effect12790(BaseEffect):
|
||||
"""
|
||||
shipBonusTorpedoAndCruiseMissileExplosionVelocityCBC2
|
||||
|
||||
Used by:
|
||||
Ship: Anhinga
|
||||
"""
|
||||
|
||||
type = 'passive'
|
||||
|
||||
@staticmethod
|
||||
def handler(fit, ship, context, projectionRange, **kwargs):
|
||||
fit.modules.filteredChargeBoost(
|
||||
lambda mod: mod.charge.requiresSkill('Torpedoes') or mod.charge.requiresSkill('Cruise Missiles'),
|
||||
'aoeVelocity', ship.getModifiedItemAttr('shipBonusCBC2'), skill='Caldari Battlecruiser', **kwargs)
|
||||
|
||||
@@ -951,7 +951,7 @@ class Fit:
|
||||
mod.item.requiresSkill("Mining")
|
||||
or mod.item.requiresSkill("Ice Harvesting")
|
||||
or mod.item.requiresSkill("Gas Cloud Harvesting")),
|
||||
"miningWasteProbability", value)
|
||||
"miningWasteProbability", value, stackingPenalties=True)
|
||||
|
||||
del self.commandBonuses[warfareBuffID]
|
||||
|
||||
|
||||
@@ -126,7 +126,7 @@ class Ship(ItemAttrShortcut, HandledItem):
|
||||
valid Item objects, not the Mode objects. Returns None if not a
|
||||
t3 dessy
|
||||
"""
|
||||
if self.item.group.name != "Tactical Destroyer":
|
||||
if self.item.group.name != "Tactical Destroyer" and self.item.name != "Anhinga":
|
||||
return None
|
||||
|
||||
items = []
|
||||
|
||||
@@ -332,3 +332,78 @@ class Distance2TpStrGetter(SmoothPointGetter):
|
||||
strMult = calculateMultiplier(strMults)
|
||||
strength = (strMult - 1) * 100
|
||||
return strength
|
||||
|
||||
|
||||
class Distance2JamChanceGetter(SmoothPointGetter):
|
||||
|
||||
_baseResolution = 50
|
||||
_extraDepth = 2
|
||||
|
||||
ECM_ATTRS_GENERAL = ('scanGravimetricStrengthBonus', 'scanLadarStrengthBonus', 'scanMagnetometricStrengthBonus', 'scanRadarStrengthBonus')
|
||||
ECM_ATTRS_FIGHTERS = ('fighterAbilityECMStrengthGravimetric', 'fighterAbilityECMStrengthLadar', 'fighterAbilityECMStrengthMagnetometric', 'fighterAbilityECMStrengthRadar')
|
||||
SCAN_TYPES = ('Gravimetric', 'Ladar', 'Magnetometric', 'Radar')
|
||||
|
||||
def _getCommonData(self, miscParams, src, tgt):
|
||||
ecms = []
|
||||
for mod in src.item.activeModulesIter():
|
||||
for effectName in ('remoteECMFalloff', 'structureModuleEffectECM'):
|
||||
if effectName in mod.item.effects:
|
||||
ecms.append((
|
||||
tuple(mod.getModifiedItemAttr(a) or 0 for a in self.ECM_ATTRS_GENERAL),
|
||||
mod.maxRange or 0, mod.falloff or 0, True, False))
|
||||
if 'doomsdayAOEECM' in mod.item.effects:
|
||||
ecms.append((
|
||||
tuple(mod.getModifiedItemAttr(a) or 0 for a in self.ECM_ATTRS_GENERAL),
|
||||
max(0, (mod.maxRange or 0) + mod.getModifiedItemAttr('doomsdayAOERange')),
|
||||
mod.falloff or 0, False, False))
|
||||
for drone in src.item.activeDronesIter():
|
||||
if 'entityECMFalloff' in drone.item.effects:
|
||||
ecms.extend(drone.amountActive * ((
|
||||
tuple(drone.getModifiedItemAttr(a) or 0 for a in self.ECM_ATTRS_GENERAL),
|
||||
math.inf, 0, True, True),))
|
||||
for fighter, ability in src.item.activeFighterAbilityIter():
|
||||
if ability.effect.name == 'fighterAbilityECM':
|
||||
ecms.append((
|
||||
tuple(fighter.getModifiedItemAttr(a) or 0 for a in self.ECM_ATTRS_FIGHTERS),
|
||||
math.inf, 0, True, False))
|
||||
# Determine target's strongest sensor type if target is available
|
||||
targetScanTypeIndex = None
|
||||
if tgt is not None:
|
||||
maxStr = -1
|
||||
for i, scanType in enumerate(self.SCAN_TYPES):
|
||||
currStr = tgt.item.ship.getModifiedItemAttr('scan%sStrength' % scanType) or 0
|
||||
if currStr > maxStr:
|
||||
maxStr = currStr
|
||||
targetScanTypeIndex = i
|
||||
return {'ecms': ecms, 'targetScanTypeIndex': targetScanTypeIndex}
|
||||
|
||||
def _calculatePoint(self, x, miscParams, src, tgt, commonData):
|
||||
distance = x
|
||||
inLockRange = checkLockRange(src=src, distance=distance)
|
||||
inDroneRange = checkDroneControlRange(src=src, distance=distance)
|
||||
jamStrengths = []
|
||||
targetScanTypeIndex = commonData['targetScanTypeIndex']
|
||||
for strengths, optimal, falloff, needsLock, needsDcr in commonData['ecms']:
|
||||
if (needsLock and not inLockRange) or (needsDcr and not inDroneRange):
|
||||
continue
|
||||
rangeFactor = calculateRangeFactor(srcOptimalRange=optimal, srcFalloffRange=falloff, distance=distance)
|
||||
# Use the strength matching the target's sensor type
|
||||
if targetScanTypeIndex is not None and targetScanTypeIndex < len(strengths):
|
||||
strength = strengths[targetScanTypeIndex]
|
||||
effectiveStrength = strength * rangeFactor
|
||||
if effectiveStrength > 0:
|
||||
jamStrengths.append(effectiveStrength)
|
||||
if not jamStrengths:
|
||||
return 0
|
||||
# Get sensor strength from target
|
||||
if tgt is None:
|
||||
return 0
|
||||
sensorStrength = max([tgt.item.ship.getModifiedItemAttr('scan%sStrength' % scanType)
|
||||
for scanType in self.SCAN_TYPES]) or 0
|
||||
if sensorStrength <= 0:
|
||||
return 100 # If target has no sensor strength, 100% jam chance
|
||||
# Calculate jam chance: 1 - (1 - (ecmStrength / sensorStrength)) ^ numJammers
|
||||
retainLockChance = 1
|
||||
for jamStrength in jamStrengths:
|
||||
retainLockChance *= 1 - min(1, jamStrength / sensorStrength)
|
||||
return (1 - retainLockChance) * 100
|
||||
|
||||
@@ -21,8 +21,8 @@
|
||||
import wx
|
||||
|
||||
from graphs.data.base import FitGraph, Input, XDef, YDef
|
||||
from .getter import (Distance2DampStrLockRangeGetter, Distance2EcmStrMaxGetter, Distance2GdStrRangeGetter, Distance2NeutingStrGetter, Distance2TdStrOptimalGetter,
|
||||
Distance2TpStrGetter, Distance2WebbingStrGetter)
|
||||
from .getter import (Distance2DampStrLockRangeGetter, Distance2EcmStrMaxGetter, Distance2GdStrRangeGetter, Distance2JamChanceGetter, Distance2NeutingStrGetter,
|
||||
Distance2TdStrOptimalGetter, Distance2TpStrGetter, Distance2WebbingStrGetter)
|
||||
|
||||
_t = wx.GetTranslation
|
||||
|
||||
@@ -31,11 +31,13 @@ class FitEwarStatsGraph(FitGraph):
|
||||
# UI stuff
|
||||
internalName = 'ewarStatsGraph'
|
||||
name = _t('Electronic Warfare Stats')
|
||||
hasTargets = True
|
||||
xDefs = [XDef(handle='distance', unit='km', label=_t('Distance'), mainInput=('distance', 'km'))]
|
||||
yDefs = [
|
||||
YDef(handle='neutStr', unit=None, label=_t('Cap neutralized per second'), selectorLabel=_t('Neuts: cap per second')),
|
||||
YDef(handle='webStr', unit='%', label=_t('Speed reduction'), selectorLabel=_t('Webs: speed reduction')),
|
||||
YDef(handle='ecmStrMax', unit=None, label=_t('Combined ECM strength'), selectorLabel=_t('ECM: combined strength')),
|
||||
YDef(handle='jamChance', unit='%', label=_t('Jam chance'), selectorLabel=_t('ECM: jam chance')),
|
||||
YDef(handle='dampStrLockRange', unit='%', label=_t('Lock range reduction'), selectorLabel=_t('Damps: lock range reduction')),
|
||||
YDef(handle='tdStrOptimal', unit='%', label=_t('Turret optimal range reduction'), selectorLabel=_t('TDs: turret optimal range reduction')),
|
||||
YDef(handle='gdStrRange', unit='%', label=_t('Missile flight range reduction'), selectorLabel=_t('GDs: missile flight range reduction')),
|
||||
@@ -53,6 +55,7 @@ class FitEwarStatsGraph(FitGraph):
|
||||
('distance', 'neutStr'): Distance2NeutingStrGetter,
|
||||
('distance', 'webStr'): Distance2WebbingStrGetter,
|
||||
('distance', 'ecmStrMax'): Distance2EcmStrMaxGetter,
|
||||
('distance', 'jamChance'): Distance2JamChanceGetter,
|
||||
('distance', 'dampStrLockRange'): Distance2DampStrLockRangeGetter,
|
||||
('distance', 'tdStrOptimal'): Distance2TdStrOptimalGetter,
|
||||
('distance', 'gdStrRange'): Distance2GdStrRangeGetter,
|
||||
|
||||
@@ -18,6 +18,7 @@ from gui.builtinContextMenus import resistMode
|
||||
from gui.builtinContextMenus.targetProfile import editor
|
||||
# Item info
|
||||
from gui.builtinContextMenus import itemStats
|
||||
from gui.builtinContextMenus import fitDiff
|
||||
from gui.builtinContextMenus import itemMarketJump
|
||||
from gui.builtinContextMenus import fitSystemSecurity # Not really an item info but want to keep it here
|
||||
from gui.builtinContextMenus import fitPilotSecurity # Not really an item info but want to keep it here
|
||||
|
||||
@@ -47,6 +47,8 @@ class AddCurrentlyOpenFit(ContextMenuUnconditional):
|
||||
if isinstance(page, BlankPage):
|
||||
continue
|
||||
fit = sFit.getFit(page.activeFitID, basic=True)
|
||||
if fit is None:
|
||||
continue
|
||||
id = ContextMenuUnconditional.nextID()
|
||||
mitem = wx.MenuItem(rootMenu, id, "{}: {}".format(fit.ship.item.name, fit.name))
|
||||
bindmenu.Bind(wx.EVT_MENU, self.handleSelection, mitem)
|
||||
|
||||
48
gui/builtinContextMenus/fitDiff.py
Normal file
@@ -0,0 +1,48 @@
|
||||
# =============================================================================
|
||||
# Copyright (C) 2025
|
||||
#
|
||||
# This file is part of pyfa.
|
||||
#
|
||||
# pyfa is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# pyfa is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with pyfa. If not, see <http://www.gnu.org/licenses/>.
|
||||
# =============================================================================
|
||||
|
||||
|
||||
# noinspection PyPackageRequirements
|
||||
import wx
|
||||
|
||||
import gui.mainFrame
|
||||
from gui.contextMenu import ContextMenuSingle
|
||||
|
||||
_t = wx.GetTranslation
|
||||
|
||||
|
||||
class FitDiff(ContextMenuSingle):
|
||||
def __init__(self):
|
||||
self.mainFrame = gui.mainFrame.MainFrame.getInstance()
|
||||
|
||||
def display(self, callingWindow, srcContext, mainItem):
|
||||
# Only show for fittingShip context (right-click on ship)
|
||||
return srcContext == "fittingShip"
|
||||
|
||||
def getText(self, callingWindow, itmContext, mainItem):
|
||||
return _t("Fit Diff...")
|
||||
|
||||
def activate(self, callingWindow, fullContext, mainItem, i):
|
||||
fitID = self.mainFrame.getActiveFit()
|
||||
if fitID is not None:
|
||||
from gui.fitDiffFrame import FitDiffFrame
|
||||
FitDiffFrame(self.mainFrame, fitID)
|
||||
|
||||
|
||||
FitDiff.register()
|
||||
@@ -17,7 +17,10 @@ class ChangeShipTacticalMode(ContextMenuUnconditional):
|
||||
self.modeMap = {
|
||||
'Defense': _t('Defense'),
|
||||
'Propulsion': _t('Propulsion'),
|
||||
'Sharpshooter': _t('Sharpshooter')
|
||||
'Sharpshooter': _t('Sharpshooter'),
|
||||
'Primary': _t('Primary'),
|
||||
'Secondary': _t('Secondary'),
|
||||
'Tertiary': _t('Tertiary'),
|
||||
}
|
||||
|
||||
def display(self, callingWindow, srcContext):
|
||||
|
||||
@@ -79,7 +79,7 @@ class ChangeAffectingSkills(ContextMenuSingle):
|
||||
label = _t("Level %s") % i
|
||||
|
||||
id = ContextMenuSingle.nextID()
|
||||
self.skillIds[id] = (skill, i)
|
||||
self.skillIds[id] = (skill, i, False) # False = not "up" for individual skills
|
||||
menuItem = wx.MenuItem(rootMenu, id, label, kind=wx.ITEM_RADIO)
|
||||
rootMenu.Bind(wx.EVT_MENU, self.handleSkillChange, menuItem)
|
||||
return menuItem
|
||||
@@ -89,6 +89,40 @@ class ChangeAffectingSkills(ContextMenuSingle):
|
||||
self.skillIds = {}
|
||||
sub = wx.Menu()
|
||||
|
||||
# When rootMenu is None (direct menu access), use sub for binding on Windows
|
||||
bindMenu = rootMenu if (rootMenu is not None and msw) else (sub if msw else None)
|
||||
|
||||
# Add "All" entry
|
||||
allItem = wx.MenuItem(sub, ContextMenuSingle.nextID(), _t("All"))
|
||||
grandSubAll = wx.Menu()
|
||||
allItem.SetSubMenu(grandSubAll)
|
||||
|
||||
# For "All", only show levels 1-5 (not "Not Learned")
|
||||
for i in range(1, 6):
|
||||
id = ContextMenuSingle.nextID()
|
||||
self.skillIds[id] = (None, i, False) # None indicates "All" was selected, False = not "up"
|
||||
label = _t("Level %s") % i
|
||||
menuItem = wx.MenuItem(bindMenu if bindMenu else grandSubAll, id, label, kind=wx.ITEM_RADIO)
|
||||
grandSubAll.Bind(wx.EVT_MENU, self.handleSkillChange, menuItem)
|
||||
grandSubAll.Append(menuItem)
|
||||
|
||||
# Add separator
|
||||
grandSubAll.AppendSeparator()
|
||||
|
||||
# Add "Up Level 1..5" entries
|
||||
for i in range(1, 6):
|
||||
id = ContextMenuSingle.nextID()
|
||||
self.skillIds[id] = (None, i, True) # None indicates "All" was selected, True = "up" only
|
||||
label = _t("Up Level %s") % i
|
||||
menuItem = wx.MenuItem(bindMenu if bindMenu else grandSubAll, id, label, kind=wx.ITEM_RADIO)
|
||||
grandSubAll.Bind(wx.EVT_MENU, self.handleSkillChange, menuItem)
|
||||
grandSubAll.Append(menuItem)
|
||||
|
||||
sub.Append(allItem)
|
||||
|
||||
# Add separator
|
||||
sub.AppendSeparator()
|
||||
|
||||
for skill in self.skills:
|
||||
skillItem = wx.MenuItem(sub, ContextMenuSingle.nextID(), skill.item.name)
|
||||
grandSub = wx.Menu()
|
||||
@@ -99,7 +133,7 @@ class ChangeAffectingSkills(ContextMenuSingle):
|
||||
skillItem.SetBitmap(bitmap)
|
||||
|
||||
for i in range(-1, 6):
|
||||
levelItem = self.addSkill(rootMenu if msw else grandSub, skill, i)
|
||||
levelItem = self.addSkill(bindMenu if bindMenu else grandSub, skill, i)
|
||||
grandSub.Append(levelItem)
|
||||
if (not skill.learned and i == -1) or (skill.learned and skill.level == i):
|
||||
levelItem.Check(True)
|
||||
@@ -108,9 +142,24 @@ class ChangeAffectingSkills(ContextMenuSingle):
|
||||
return sub
|
||||
|
||||
def handleSkillChange(self, event):
|
||||
skill, level = self.skillIds[event.Id]
|
||||
skill, level, up = self.skillIds[event.Id]
|
||||
|
||||
if skill is None: # "All" was selected
|
||||
for s in self.skills:
|
||||
if up:
|
||||
# Only increase skill if it's below the target level
|
||||
if not s.learned or s.level < level:
|
||||
self.sChar.changeLevel(self.charID, s.item.ID, level)
|
||||
else:
|
||||
self.sChar.changeLevel(self.charID, s.item.ID, level)
|
||||
else:
|
||||
if up:
|
||||
# Only increase skill if it's below the target level
|
||||
if not skill.learned or skill.level < level:
|
||||
self.sChar.changeLevel(self.charID, skill.item.ID, level)
|
||||
else:
|
||||
self.sChar.changeLevel(self.charID, skill.item.ID, level)
|
||||
|
||||
self.sChar.changeLevel(self.charID, skill.item.ID, level)
|
||||
fitID = self.mainFrame.getActiveFit()
|
||||
self.sFit.changeChar(fitID, self.charID)
|
||||
|
||||
|
||||
@@ -9,6 +9,46 @@ from gui.utils.numberFormatter import formatAmount
|
||||
|
||||
_t = wx.GetTranslation
|
||||
|
||||
# Mapping of repair/transfer amount attributes to their duration attribute and display name
|
||||
PER_SECOND_ATTRIBUTES = {
|
||||
"armorDamageAmount": {
|
||||
"durationAttr": "duration",
|
||||
"displayName": "Armor Hitpoints Repaired per second",
|
||||
"unit": "HP/s"
|
||||
},
|
||||
"shieldBonus": {
|
||||
"durationAttr": "duration",
|
||||
"displayName": "Shield Hitpoints Repaired per second",
|
||||
"unit": "HP/s"
|
||||
},
|
||||
"powerTransferAmount": {
|
||||
"durationAttr": "duration",
|
||||
"displayName": "Capacitor Transferred per second",
|
||||
"unit": "GJ/s"
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
class PerSecondAttributeInfo:
|
||||
"""Helper class to store info about computed per-second attributes"""
|
||||
def __init__(self, displayName, unit):
|
||||
self.displayName = displayName
|
||||
self.unit = PerSecondUnit(unit)
|
||||
|
||||
|
||||
class PerSecondUnit:
|
||||
"""Helper class to mimic the Unit class for per-second attributes"""
|
||||
def __init__(self, displayName):
|
||||
self.displayName = displayName
|
||||
self.name = ""
|
||||
|
||||
|
||||
class PerSecondAttributeValue:
|
||||
"""Helper class to store computed per-second attribute values"""
|
||||
def __init__(self, value):
|
||||
self.value = value
|
||||
self.info = None # Will be set when adding to attrs
|
||||
|
||||
|
||||
def defaultSort(item):
|
||||
return (item.metaLevel or 0, item.name)
|
||||
@@ -36,6 +76,7 @@ class ItemCompare(wx.Panel):
|
||||
self.item = item
|
||||
self.items = sorted(items, key=defaultSort)
|
||||
self.attrs = {}
|
||||
self.computedAttrs = {} # Store computed per-second attributes
|
||||
self.HighlightOn = wx.Colour(255, 255, 0, wx.ALPHA_OPAQUE)
|
||||
self.highlightedNames = []
|
||||
|
||||
@@ -45,23 +86,66 @@ class ItemCompare(wx.Panel):
|
||||
if item.attributes[attr].info.displayName:
|
||||
self.attrs[attr] = item.attributes[attr].info
|
||||
|
||||
# Compute per-second attributes for items that have both the amount and duration
|
||||
for perSecondKey, config in PER_SECOND_ATTRIBUTES.items():
|
||||
amountAttr = perSecondKey
|
||||
durationAttr = config["durationAttr"]
|
||||
perSecondAttrName = f"{perSecondKey}_per_second"
|
||||
|
||||
# Check if any item has both attributes
|
||||
hasPerSecondAttr = False
|
||||
for item in self.items:
|
||||
if amountAttr in item.attributes and durationAttr in item.attributes:
|
||||
hasPerSecondAttr = True
|
||||
break
|
||||
|
||||
if hasPerSecondAttr:
|
||||
# Add the per-second attribute info to attrs
|
||||
perSecondInfo = PerSecondAttributeInfo(config["displayName"], config["unit"])
|
||||
self.attrs[perSecondAttrName] = perSecondInfo
|
||||
self.computedAttrs[perSecondAttrName] = {
|
||||
"amountAttr": amountAttr,
|
||||
"durationAttr": durationAttr
|
||||
}
|
||||
|
||||
# Process attributes for items and find ones that differ
|
||||
for attr in list(self.attrs.keys()):
|
||||
value = None
|
||||
|
||||
for item in self.items:
|
||||
# we can automatically break here if this item doesn't have the attribute,
|
||||
# as that means at least one item did
|
||||
if attr not in item.attributes:
|
||||
break
|
||||
# Check if this is a computed attribute
|
||||
if attr in self.computedAttrs:
|
||||
computed = self.computedAttrs[attr]
|
||||
amountAttr = computed["amountAttr"]
|
||||
durationAttr = computed["durationAttr"]
|
||||
|
||||
# this is the first attribute for the item set, set the initial value
|
||||
if value is None:
|
||||
value = item.attributes[attr].value
|
||||
continue
|
||||
# Item needs both attributes to compute per-second value
|
||||
if amountAttr not in item.attributes or durationAttr not in item.attributes:
|
||||
break
|
||||
|
||||
if attr not in item.attributes or item.attributes[attr].value != value:
|
||||
break
|
||||
# Calculate per-second value
|
||||
amountValue = item.attributes[amountAttr].value
|
||||
durationValue = item.attributes[durationAttr].value
|
||||
# Duration is in milliseconds, convert to seconds
|
||||
perSecondValue = amountValue / (durationValue / 1000.0) if durationValue > 0 else 0
|
||||
|
||||
if value is None:
|
||||
value = perSecondValue
|
||||
continue
|
||||
|
||||
if perSecondValue != value:
|
||||
break
|
||||
else:
|
||||
# Regular attribute handling
|
||||
if attr not in item.attributes:
|
||||
break
|
||||
|
||||
if value is None:
|
||||
value = item.attributes[attr].value
|
||||
continue
|
||||
|
||||
if item.attributes[attr].value != value:
|
||||
break
|
||||
else:
|
||||
# attribute values were all the same, delete
|
||||
del self.attrs[attr]
|
||||
@@ -148,7 +232,14 @@ class ItemCompare(wx.Panel):
|
||||
# Remember to reduce by 1, because the attrs array
|
||||
# starts at 0 while the list has the item name as column 0.
|
||||
attr = str(list(self.attrs.keys())[sort - 1])
|
||||
func = lambda _val: _val.attributes[attr].value if attr in _val.attributes else 0.0
|
||||
# Handle computed attributes for sorting
|
||||
if attr in self.computedAttrs:
|
||||
computed = self.computedAttrs[attr]
|
||||
amountAttr = computed["amountAttr"]
|
||||
durationAttr = computed["durationAttr"]
|
||||
func = lambda _val: (_val.attributes[amountAttr].value / (_val.attributes[durationAttr].value / 1000.0)) if (amountAttr in _val.attributes and durationAttr in _val.attributes and _val.attributes[durationAttr].value > 0) else 0.0
|
||||
else:
|
||||
func = lambda _val: _val.attributes[attr].value if attr in _val.attributes else 0.0
|
||||
# Clicked on a column that's not part of our array (price most likely)
|
||||
except IndexError:
|
||||
# Price
|
||||
@@ -177,7 +268,28 @@ class ItemCompare(wx.Panel):
|
||||
for item in self.items:
|
||||
i = self.paramList.InsertItem(self.paramList.GetItemCount(), item.name)
|
||||
for x, attr in enumerate(self.attrs.keys()):
|
||||
if attr in item.attributes:
|
||||
# Handle computed attributes
|
||||
if attr in self.computedAttrs:
|
||||
computed = self.computedAttrs[attr]
|
||||
amountAttr = computed["amountAttr"]
|
||||
durationAttr = computed["durationAttr"]
|
||||
|
||||
# Item needs both attributes to display per-second value
|
||||
if amountAttr in item.attributes and durationAttr in item.attributes:
|
||||
amountValue = item.attributes[amountAttr].value
|
||||
durationValue = item.attributes[durationAttr].value
|
||||
# Duration is in milliseconds, convert to seconds
|
||||
perSecondValue = amountValue / (durationValue / 1000.0) if durationValue > 0 else 0
|
||||
|
||||
info = self.attrs[attr]
|
||||
if self.toggleView == 1:
|
||||
valueUnit = formatAmount(perSecondValue, 3, 0, 0) + " " + info.unit.displayName
|
||||
else:
|
||||
valueUnit = str(perSecondValue)
|
||||
|
||||
self.paramList.SetItem(i, x + 1, valueUnit)
|
||||
# else: leave cell empty
|
||||
elif attr in item.attributes:
|
||||
info = self.attrs[attr]
|
||||
value = item.attributes[attr].value
|
||||
if self.toggleView != 1:
|
||||
|
||||
220
gui/builtinItemStatsViews/itemSkills.py
Normal file
@@ -0,0 +1,220 @@
|
||||
# noinspection PyPackageRequirements
|
||||
import wx
|
||||
import itertools
|
||||
|
||||
import gui.mainFrame
|
||||
from eos.saveddata.character import Skill
|
||||
from eos.saveddata.fighter import Fighter as es_Fighter
|
||||
from eos.saveddata.module import Module as es_Module
|
||||
from eos.saveddata.ship import Ship
|
||||
from gui.utils.clipboard import toClipboard
|
||||
from gui.utils.numberFormatter import formatAmount
|
||||
from service.fit import Fit
|
||||
|
||||
_t = wx.GetTranslation
|
||||
|
||||
|
||||
class ItemSkills(wx.Panel):
|
||||
def __init__(self, parent, stuff, item):
|
||||
wx.Panel.__init__(self, parent)
|
||||
self.stuff = stuff
|
||||
self.item = item
|
||||
|
||||
mainSizer = wx.BoxSizer(wx.HORIZONTAL)
|
||||
|
||||
leftPanel = wx.Panel(self)
|
||||
leftSizer = wx.BoxSizer(wx.VERTICAL)
|
||||
leftPanel.SetSizer(leftSizer)
|
||||
|
||||
header = wx.StaticText(leftPanel, wx.ID_ANY, _t("Components"))
|
||||
font = header.GetFont()
|
||||
font.SetWeight(wx.FONTWEIGHT_BOLD)
|
||||
header.SetFont(font)
|
||||
leftSizer.Add(header, 0, wx.ALL, 5)
|
||||
|
||||
self.checkboxes = {}
|
||||
components = [
|
||||
("Ship", "ship"),
|
||||
("Modules", "modules"),
|
||||
("Drones", "drones"),
|
||||
("Fighters", "fighters"),
|
||||
("Cargo", "cargo"),
|
||||
("Implants", "appliedImplants"),
|
||||
("Boosters", "boosters"),
|
||||
("Necessary", "necessary"),
|
||||
]
|
||||
|
||||
for label, key in components:
|
||||
cb = wx.CheckBox(leftPanel, wx.ID_ANY, label)
|
||||
cb.SetValue(True)
|
||||
cb.Bind(wx.EVT_CHECKBOX, self.onCheckboxChange)
|
||||
self.checkboxes[key] = cb
|
||||
leftSizer.Add(cb, 0, wx.ALL, 2)
|
||||
|
||||
leftSizer.AddStretchSpacer()
|
||||
|
||||
mainSizer.Add(leftPanel, 0, wx.EXPAND | wx.ALL, 5)
|
||||
|
||||
rightPanel = wx.Panel(self)
|
||||
rightSizer = wx.BoxSizer(wx.VERTICAL)
|
||||
rightPanel.SetSizer(rightSizer)
|
||||
|
||||
headerRight = wx.StaticText(rightPanel, wx.ID_ANY, _t("Skills"))
|
||||
fontRight = headerRight.GetFont()
|
||||
fontRight.SetWeight(wx.FONTWEIGHT_BOLD)
|
||||
headerRight.SetFont(fontRight)
|
||||
rightSizer.Add(headerRight, 0, wx.ALL, 5)
|
||||
|
||||
self.skillsText = wx.TextCtrl(rightPanel, wx.ID_ANY, "", style=wx.TE_MULTILINE | wx.TE_READONLY | wx.TE_DONTWRAP)
|
||||
font = wx.Font(9, wx.FONTFAMILY_TELETYPE, wx.FONTSTYLE_NORMAL, wx.FONTWEIGHT_NORMAL)
|
||||
self.skillsText.SetFont(font)
|
||||
rightSizer.Add(self.skillsText, 1, wx.EXPAND | wx.ALL, 5)
|
||||
|
||||
mainSizer.Add(rightPanel, 1, wx.EXPAND | wx.ALL, 5)
|
||||
|
||||
self.SetSizer(mainSizer)
|
||||
|
||||
self.nbContainer = parent if isinstance(parent, wx.Notebook) else None
|
||||
if self.nbContainer:
|
||||
self.nbContainer.Bind(wx.EVT_NOTEBOOK_PAGE_CHANGED, self.onTabChanged)
|
||||
|
||||
self.updateSkills()
|
||||
|
||||
def onCheckboxChange(self, event):
|
||||
self.updateSkills()
|
||||
self._copyToClipboard()
|
||||
|
||||
def updateSkills(self):
|
||||
fitID = gui.mainFrame.MainFrame.getInstance().getActiveFit()
|
||||
if fitID is None:
|
||||
self.skillsText.SetValue("")
|
||||
self._updateCheckboxStates(None)
|
||||
return
|
||||
|
||||
sFit = Fit.getInstance()
|
||||
fit = sFit.getFit(fitID)
|
||||
if fit is None:
|
||||
self.skillsText.SetValue("")
|
||||
self._updateCheckboxStates(None)
|
||||
return
|
||||
|
||||
if not fit.calculated:
|
||||
fit.calculate()
|
||||
|
||||
self._updateCheckboxStates(fit)
|
||||
|
||||
char = fit.character
|
||||
skillsMap = {}
|
||||
|
||||
items = []
|
||||
if self.checkboxes["ship"].GetValue():
|
||||
items.append(fit.ship)
|
||||
if self.checkboxes["modules"].GetValue():
|
||||
items.extend(fit.modules)
|
||||
if self.checkboxes["drones"].GetValue():
|
||||
items.extend(fit.drones)
|
||||
if self.checkboxes["fighters"].GetValue():
|
||||
items.extend(fit.fighters)
|
||||
if self.checkboxes["cargo"].GetValue():
|
||||
items.extend(fit.cargo)
|
||||
if self.checkboxes["appliedImplants"].GetValue():
|
||||
items.extend(fit.appliedImplants)
|
||||
if self.checkboxes["boosters"].GetValue():
|
||||
items.extend(fit.boosters)
|
||||
|
||||
for thing in items:
|
||||
self._collectAffectingSkills(thing, char, skillsMap)
|
||||
|
||||
if self.checkboxes["necessary"].GetValue():
|
||||
self._collectRequiredSkills(items, char, skillsMap)
|
||||
|
||||
skillsList = ""
|
||||
for skillName in sorted(skillsMap):
|
||||
charLevel = skillsMap[skillName]
|
||||
for level in range(1, charLevel + 1):
|
||||
skillsList += "%s %d\n" % (skillName, level)
|
||||
|
||||
self.skillsText.SetValue(skillsList)
|
||||
self._copyToClipboard()
|
||||
|
||||
def _copyToClipboard(self):
|
||||
skillsText = self.skillsText.GetValue()
|
||||
if skillsText:
|
||||
toClipboard(skillsText)
|
||||
|
||||
def onTabChanged(self, event):
|
||||
if self.nbContainer:
|
||||
pageIndex = self.nbContainer.FindPage(self)
|
||||
if pageIndex != -1 and event.GetSelection() == pageIndex:
|
||||
self.updateSkills()
|
||||
event.Skip()
|
||||
|
||||
def _updateCheckboxStates(self, fit):
|
||||
if fit is None:
|
||||
for cb in self.checkboxes.values():
|
||||
cb.Enable(False)
|
||||
return
|
||||
|
||||
self.checkboxes["ship"].Enable(True)
|
||||
self.checkboxes["modules"].Enable(len(fit.modules) > 0)
|
||||
self.checkboxes["drones"].Enable(len(fit.drones) > 0)
|
||||
self.checkboxes["fighters"].Enable(len(fit.fighters) > 0)
|
||||
self.checkboxes["cargo"].Enable(len(fit.cargo) > 0)
|
||||
self.checkboxes["appliedImplants"].Enable(len(fit.appliedImplants) > 0)
|
||||
self.checkboxes["boosters"].Enable(len(fit.boosters) > 0)
|
||||
self.checkboxes["necessary"].Enable(True)
|
||||
|
||||
def _collectAffectingSkills(self, thing, char, skillsMap):
|
||||
for attr in ("item", "charge"):
|
||||
if attr == "charge" and isinstance(thing, es_Fighter):
|
||||
continue
|
||||
subThing = getattr(thing, attr, None)
|
||||
if subThing is None:
|
||||
continue
|
||||
if isinstance(thing, es_Fighter) and attr == "charge":
|
||||
continue
|
||||
|
||||
if attr == "charge":
|
||||
cont = getattr(thing, "chargeModifiedAttributes", None)
|
||||
else:
|
||||
cont = getattr(thing, "itemModifiedAttributes", None)
|
||||
|
||||
if cont is not None:
|
||||
for attrName in cont.iterAfflictions():
|
||||
for fit, afflictors in cont.getAfflictions(attrName).items():
|
||||
for afflictor, operator, stackingGroup, preResAmount, postResAmount, used in afflictors:
|
||||
if isinstance(afflictor, Skill) and afflictor.character == char:
|
||||
skillName = afflictor.item.name
|
||||
if skillName not in skillsMap:
|
||||
skillsMap[skillName] = afflictor.level
|
||||
elif skillsMap[skillName] < afflictor.level:
|
||||
skillsMap[skillName] = afflictor.level
|
||||
|
||||
def _collectRequiredSkills(self, items, char, skillsMap):
|
||||
"""Collect required skills from items (necessary to use them)"""
|
||||
for thing in items:
|
||||
for attr in ("item", "charge"):
|
||||
if attr == "charge" and isinstance(thing, es_Fighter):
|
||||
continue
|
||||
subThing = getattr(thing, attr, None)
|
||||
if subThing is None:
|
||||
continue
|
||||
if isinstance(thing, es_Fighter) and attr == "charge":
|
||||
continue
|
||||
|
||||
if hasattr(subThing, "requiredSkills"):
|
||||
for reqSkill, level in subThing.requiredSkills.items():
|
||||
skillName = reqSkill.name
|
||||
charSkill = char.getSkill(reqSkill) if char else None
|
||||
charLevel = charSkill.level if charSkill else 0
|
||||
|
||||
if charLevel > 0:
|
||||
if skillName not in skillsMap:
|
||||
skillsMap[skillName] = charLevel
|
||||
elif skillsMap[skillName] < charLevel:
|
||||
skillsMap[skillName] = charLevel
|
||||
else:
|
||||
if skillName not in skillsMap:
|
||||
skillsMap[skillName] = level
|
||||
elif skillsMap[skillName] < level:
|
||||
skillsMap[skillName] = level
|
||||
@@ -5,6 +5,7 @@ import gui.builtinMarketBrowser.pfSearchBox as SBox
|
||||
import gui.globalEvents as GE
|
||||
from config import slotColourMap, slotColourMapDark
|
||||
from eos.saveddata.module import Module
|
||||
from eos.const import FittingSlot
|
||||
from gui.builtinMarketBrowser.events import ItemSelected, RECENTLY_USED_MODULES, CHARGES_FOR_FIT
|
||||
from gui.contextMenu import ContextMenu
|
||||
from gui.display import Display
|
||||
@@ -22,6 +23,7 @@ class ItemView(Display):
|
||||
|
||||
DEFAULT_COLS = ["Base Icon",
|
||||
"Base Name",
|
||||
"Price",
|
||||
"attr:power,,,True",
|
||||
"attr:cpu,,,True"]
|
||||
|
||||
@@ -153,19 +155,22 @@ class ItemView(Display):
|
||||
# skip the event so the other handlers also get called
|
||||
event.Skip()
|
||||
|
||||
if self.marketBrowser.mode != 'charges':
|
||||
return
|
||||
|
||||
activeFitID = self.mainFrame.getActiveFit()
|
||||
# if it was not the active fitting that was changed, do not do anything
|
||||
if activeFitID is not None and activeFitID not in event.fitIDs:
|
||||
return
|
||||
|
||||
items = self.getChargesForActiveFit()
|
||||
# Handle charges mode
|
||||
if self.marketBrowser.mode == 'charges':
|
||||
items = self.getChargesForActiveFit()
|
||||
# update the UI
|
||||
self.updateItemStore(items)
|
||||
self.filterItemStore()
|
||||
return
|
||||
|
||||
# update the UI
|
||||
self.updateItemStore(items)
|
||||
self.filterItemStore()
|
||||
# If "Fits" filter is active, re-filter the current view
|
||||
if self.marketBrowser.getFitsFilter():
|
||||
self.filterItemStore()
|
||||
|
||||
def updateItemStore(self, items):
|
||||
self.unfilteredStore = items
|
||||
@@ -197,13 +202,115 @@ class ItemView(Display):
|
||||
if btn.userSelected:
|
||||
selectedMetas.update(sMkt.META_MAP[btn.metaName])
|
||||
filteredItems = sMkt.filterItemsByMeta(self.unfilteredStore, selectedMetas)
|
||||
|
||||
# Apply slot/fits filters - works IDENTICALLY to meta buttons (filters CURRENT VIEW only)
|
||||
activeSlotFilters = []
|
||||
fitsFilterActive = False
|
||||
for btn in self.marketBrowser.slotButtons:
|
||||
if btn.userSelected and btn.IsEnabled():
|
||||
if btn.filterType == "fits":
|
||||
fitsFilterActive = True
|
||||
elif btn.filterType == "slot":
|
||||
activeSlotFilters.append(btn.slotType)
|
||||
|
||||
# Apply fits filter
|
||||
if fitsFilterActive:
|
||||
filteredItems = self._filterByFits(filteredItems)
|
||||
|
||||
# Apply slot filters
|
||||
if activeSlotFilters:
|
||||
filteredItems = [item for item in filteredItems if Module.calculateSlot(item) in activeSlotFilters]
|
||||
|
||||
return filteredItems
|
||||
|
||||
def _filterByFits(self, items):
|
||||
"""Filter items by remaining CPU/PG - filters CURRENT VIEW only"""
|
||||
fitId = self.mainFrame.getActiveFit()
|
||||
if fitId is None:
|
||||
return []
|
||||
|
||||
fit = self.sFit.getFit(fitId)
|
||||
|
||||
# Get remaining CPU and power grid
|
||||
cpuOutput = fit.ship.getModifiedItemAttr("cpuOutput")
|
||||
powerOutput = fit.ship.getModifiedItemAttr("powerOutput")
|
||||
cpuUsed = fit.cpuUsed
|
||||
pgUsed = fit.pgUsed
|
||||
cpuRemaining = cpuOutput - cpuUsed
|
||||
pgRemaining = powerOutput - pgUsed
|
||||
|
||||
# Get remaining calibration (for rigs)
|
||||
calibrationCapacity = fit.ship.getModifiedItemAttr("upgradeCapacity")
|
||||
calibrationUsed = fit.calibrationUsed
|
||||
calibrationRemaining = None
|
||||
if calibrationCapacity is not None and calibrationCapacity > 0:
|
||||
calibrationRemaining = calibrationCapacity - calibrationUsed
|
||||
|
||||
fittingItems = []
|
||||
for item in items:
|
||||
# Check if item is a module (has a slot)
|
||||
slot = Module.calculateSlot(item)
|
||||
if slot is None:
|
||||
continue
|
||||
|
||||
# Rigs don't use CPU/power, they use calibration - check rig size and calibration
|
||||
if slot == FittingSlot.RIG:
|
||||
# Check if item can fit on the ship
|
||||
if not fit.canFit(item):
|
||||
continue
|
||||
# Check rig size compatibility with ship
|
||||
shipRigSize = fit.ship.getModifiedItemAttr("rigSize")
|
||||
itemRigSize = item.attributes.get("rigSize")
|
||||
if shipRigSize is not None and itemRigSize is not None:
|
||||
if shipRigSize != itemRigSize.value:
|
||||
continue
|
||||
# Check calibration requirement
|
||||
if calibrationRemaining is not None and calibrationRemaining > 0:
|
||||
itemCalibration = item.attributes.get("upgradeCost")
|
||||
if itemCalibration is not None:
|
||||
itemCalibrationValue = itemCalibration.value
|
||||
if itemCalibrationValue > calibrationRemaining:
|
||||
continue
|
||||
fittingItems.append(item)
|
||||
continue
|
||||
|
||||
# For non-rigs, check CPU and power requirements
|
||||
itemCpu = item.attributes.get("cpu")
|
||||
itemPower = item.attributes.get("power")
|
||||
|
||||
# Skip items without CPU or power (not modules)
|
||||
if itemCpu is None and itemPower is None:
|
||||
continue
|
||||
|
||||
# Check CPU requirement
|
||||
if itemCpu is not None:
|
||||
itemCpuValue = itemCpu.value
|
||||
if itemCpuValue > cpuRemaining:
|
||||
continue
|
||||
|
||||
# Check power requirement
|
||||
if itemPower is not None:
|
||||
itemPowerValue = itemPower.value
|
||||
if itemPowerValue > pgRemaining:
|
||||
continue
|
||||
|
||||
# Check if item can fit on the ship (most expensive check, do last)
|
||||
if not fit.canFit(item):
|
||||
continue
|
||||
|
||||
fittingItems.append(item)
|
||||
|
||||
return fittingItems
|
||||
|
||||
def setToggles(self):
|
||||
metaIDs = set()
|
||||
slotIDs = set()
|
||||
sMkt = self.sMkt
|
||||
for item in self.unfilteredStore:
|
||||
metaIDs.add(sMkt.getMetaGroupIdByItem(item))
|
||||
slot = Module.calculateSlot(item)
|
||||
if slot is not None:
|
||||
slotIDs.add(slot)
|
||||
|
||||
for btn in self.marketBrowser.metaButtons:
|
||||
btn.reset()
|
||||
@@ -212,6 +319,23 @@ class ItemView(Display):
|
||||
btn.setMetaAvailable(True)
|
||||
else:
|
||||
btn.setMetaAvailable(False)
|
||||
|
||||
# Set toggles for slot/fits buttons
|
||||
for btn in self.marketBrowser.slotButtons:
|
||||
btn.reset()
|
||||
if btn.filterType == "fits":
|
||||
# Fits button is available if there's an active fit
|
||||
fitId = self.mainFrame.getActiveFit()
|
||||
isAvailable = fitId is not None
|
||||
btn.setMetaAvailable(isAvailable)
|
||||
if not isAvailable:
|
||||
btn.setUserSelection(False)
|
||||
elif btn.filterType == "slot":
|
||||
# Slot button is available if items with that slot exist in current view
|
||||
isAvailable = btn.slotType in slotIDs
|
||||
btn.setMetaAvailable(isAvailable)
|
||||
if not isAvailable:
|
||||
btn.setUserSelection(False)
|
||||
|
||||
def scheduleSearch(self, event=None):
|
||||
self.searchTimer.Stop() # Cancel any pending timers
|
||||
|
||||
@@ -130,6 +130,7 @@ class TargetingMiscViewMinimal(StatsView):
|
||||
("specialPlanetaryCommoditiesHoldCapacity", _t("Planetary goods hold")),
|
||||
("specialQuafeHoldCapacity", _t("Quafe hold")),
|
||||
("specialMobileDepotHoldCapacity", _t("Mobile depot hold")),
|
||||
("specialExpeditionHoldCapacity", _t("Expedition hold")),
|
||||
))
|
||||
|
||||
cargoValues = {
|
||||
@@ -154,6 +155,7 @@ class TargetingMiscViewMinimal(StatsView):
|
||||
"specialPlanetaryCommoditiesHoldCapacity": lambda: fit.ship.getModifiedItemAttr("specialPlanetaryCommoditiesHoldCapacity"),
|
||||
"specialQuafeHoldCapacity": lambda: fit.ship.getModifiedItemAttr("specialQuafeHoldCapacity"),
|
||||
"specialMobileDepotHoldCapacity": lambda: fit.ship.getModifiedItemAttr("specialMobileDepotHoldCapacity"),
|
||||
"specialExpeditionHoldCapacity": lambda: fit.ship.getModifiedItemAttr("specialExpeditionHoldCapacity"),
|
||||
}
|
||||
|
||||
stats = (("labelTargets", {"main": lambda: fit.maxTargets}, 3, 0, 0, ""),
|
||||
|
||||
@@ -20,6 +20,7 @@
|
||||
# noinspection PyPackageRequirements
|
||||
import wx
|
||||
|
||||
from eos.gamedata import Item
|
||||
from eos.saveddata.cargo import Cargo
|
||||
from eos.saveddata.drone import Drone
|
||||
from eos.saveddata.fighter import Fighter
|
||||
@@ -53,7 +54,14 @@ class Price(ViewColumn):
|
||||
self.imageId = fittingView.imageList.GetImageIndex("totalPrice_small", "gui")
|
||||
|
||||
def getText(self, stuff):
|
||||
if stuff.item is None or stuff.item.group.name == "Ship Modifiers":
|
||||
if isinstance(stuff, Item):
|
||||
item = stuff
|
||||
else:
|
||||
if not hasattr(stuff, "item") or stuff.item is None:
|
||||
return ""
|
||||
item = stuff.item
|
||||
|
||||
if item.group.name == "Ship Modifiers":
|
||||
return ""
|
||||
|
||||
if hasattr(stuff, "isEmpty"):
|
||||
@@ -63,7 +71,7 @@ class Price(ViewColumn):
|
||||
if isinstance(stuff, Module) and stuff.isMutated:
|
||||
return ""
|
||||
|
||||
priceObj = stuff.item.price
|
||||
priceObj = item.price
|
||||
|
||||
if not priceObj.isValid():
|
||||
return False
|
||||
@@ -79,7 +87,11 @@ class Price(ViewColumn):
|
||||
|
||||
display.SetItem(colItem)
|
||||
|
||||
sPrice.getPrices([mod.item], callback, waitforthread=True)
|
||||
if isinstance(mod, Item):
|
||||
item = mod
|
||||
else:
|
||||
item = mod.item
|
||||
sPrice.getPrices([item], callback, waitforthread=True)
|
||||
|
||||
def getImageId(self, mod):
|
||||
return -1
|
||||
|
||||
@@ -668,6 +668,21 @@ class FittingView(d.Display):
|
||||
contexts.append(fullContext)
|
||||
contexts.append(("fittingShip", _t("Ship") if not fit.isStructure else _t("Citadel")))
|
||||
|
||||
# Check if shift is held for direct skills menu access
|
||||
if wx.GetKeyState(wx.WXK_SHIFT):
|
||||
from gui.builtinContextMenus.skillAffectors import ChangeAffectingSkills
|
||||
for fullContext in contexts:
|
||||
srcContext = fullContext[0]
|
||||
itemContext = fullContext[1] if len(fullContext) > 1 else None
|
||||
skillsMenu = ChangeAffectingSkills()
|
||||
if skillsMenu.display(self, srcContext, mainMod):
|
||||
# On Windows, menu items need to be bound to the menu shown with PopupMenu
|
||||
# We pass None as rootMenu so items are bound to their parent submenus
|
||||
sub = skillsMenu.getSubMenu(self, srcContext, mainMod, None, 0, None)
|
||||
if sub:
|
||||
self.PopupMenu(sub)
|
||||
return
|
||||
|
||||
menu = ContextMenu.getMenu(self, mainMod, selection, *contexts)
|
||||
self.PopupMenu(menu)
|
||||
|
||||
|
||||
@@ -29,7 +29,7 @@ import config
|
||||
import gui.globalEvents as GE
|
||||
import gui.mainFrame
|
||||
from gui.bitmap_loader import BitmapLoader
|
||||
from gui.utils.clipboard import toClipboard
|
||||
from gui.utils.clipboard import toClipboard, fromClipboard
|
||||
from service.character import Character
|
||||
from service.fit import Fit
|
||||
|
||||
@@ -49,6 +49,10 @@ class CharacterSelection(wx.Panel):
|
||||
|
||||
# cache current selection to fall back in case we choose to open char editor
|
||||
self.charCache = None
|
||||
|
||||
# history for Shift-Tab navigation
|
||||
self.charHistory = []
|
||||
self._updatingFromHistory = False
|
||||
|
||||
self.charChoice = wx.Choice(self)
|
||||
mainSizer.Add(self.charChoice, 1, wx.ALIGN_CENTER_VERTICAL | wx.RIGHT | wx.LEFT, 3)
|
||||
@@ -92,7 +96,7 @@ class CharacterSelection(wx.Panel):
|
||||
sFit = Fit.getInstance()
|
||||
fit = sFit.getFit(self.mainFrame.getActiveFit())
|
||||
|
||||
if not fit or not self.needsSkills:
|
||||
if not fit:
|
||||
return
|
||||
|
||||
pos = wx.GetMousePosition()
|
||||
@@ -100,14 +104,23 @@ class CharacterSelection(wx.Panel):
|
||||
|
||||
menu = wx.Menu()
|
||||
|
||||
grantItem = menu.Append(wx.ID_ANY, _t("Grant Missing Skills"))
|
||||
self.Bind(wx.EVT_MENU, self.grantMissingSkills, grantItem)
|
||||
if self.needsSkills:
|
||||
grantItem = menu.Append(wx.ID_ANY, _t("Grant Missing Skills"))
|
||||
self.Bind(wx.EVT_MENU, self.grantMissingSkills, grantItem)
|
||||
|
||||
exportItem = menu.Append(wx.ID_ANY, _t("Copy Missing Skills"))
|
||||
self.Bind(wx.EVT_MENU, self.exportSkills, exportItem)
|
||||
exportItem = menu.Append(wx.ID_ANY, _t("Copy Missing Skills"))
|
||||
self.Bind(wx.EVT_MENU, self.exportSkills, exportItem)
|
||||
|
||||
exportItem = menu.Append(wx.ID_ANY, _t("Copy Missing Skills (EVEMon)"))
|
||||
self.Bind(wx.EVT_MENU, self.exportSkillsEveMon, exportItem)
|
||||
exportItem = menu.Append(wx.ID_ANY, _t("Copy Missing Skills (condensed)"))
|
||||
self.Bind(wx.EVT_MENU, self.exportSkillsCondensed, exportItem)
|
||||
|
||||
exportItem = menu.Append(wx.ID_ANY, _t("Copy Missing Skills (EVEMon)"))
|
||||
self.Bind(wx.EVT_MENU, self.exportSkillsEveMon, exportItem)
|
||||
|
||||
menu.AppendSeparator()
|
||||
|
||||
importItem = menu.Append(wx.ID_ANY, _t("Import Skills from Clipboard"))
|
||||
self.Bind(wx.EVT_MENU, self.importSkillsFromClipboard, importItem)
|
||||
|
||||
self.PopupMenu(menu, pos)
|
||||
|
||||
@@ -186,6 +199,13 @@ class CharacterSelection(wx.Panel):
|
||||
sFit = Fit.getInstance()
|
||||
sFit.changeChar(fitID, charID)
|
||||
self.charCache = self.charChoice.GetCurrentSelection()
|
||||
|
||||
if not self._updatingFromHistory and charID is not None:
|
||||
currentChar = self.getActiveCharacter()
|
||||
if currentChar is not None:
|
||||
if not self.charHistory or self.charHistory[-1] != currentChar:
|
||||
self.charHistory.append(currentChar)
|
||||
|
||||
wx.PostEvent(self.mainFrame, GE.FitChanged(fitIDs=(fitID,)))
|
||||
|
||||
def toggleRefreshButton(self):
|
||||
@@ -207,6 +227,29 @@ class CharacterSelection(wx.Panel):
|
||||
return True
|
||||
|
||||
return False
|
||||
|
||||
def selectPreviousChar(self):
|
||||
currentChar = self.getActiveCharacter()
|
||||
if currentChar is None:
|
||||
return
|
||||
|
||||
if not self.charHistory:
|
||||
return
|
||||
|
||||
if self.charHistory and self.charHistory[-1] == currentChar:
|
||||
self.charHistory.pop()
|
||||
|
||||
if not self.charHistory:
|
||||
return
|
||||
|
||||
prevChar = self.charHistory.pop()
|
||||
if currentChar != prevChar:
|
||||
self.charHistory.append(currentChar)
|
||||
|
||||
self._updatingFromHistory = True
|
||||
if self.selectChar(prevChar):
|
||||
self.charChanged(None)
|
||||
self._updatingFromHistory = False
|
||||
|
||||
def fitChanged(self, event):
|
||||
"""
|
||||
@@ -219,7 +262,7 @@ class CharacterSelection(wx.Panel):
|
||||
self.charChoice.Enable(activeFitID is not None)
|
||||
choice = self.charChoice
|
||||
sFit = Fit.getInstance()
|
||||
currCharID = choice.GetClientData(choice.GetCurrentSelection())
|
||||
currCharID = choice.GetClientData(choice.GetCurrentSelection()) if choice.GetCurrentSelection() != -1 else None
|
||||
fit = sFit.getFit(activeFitID)
|
||||
newCharID = fit.character.ID if fit is not None else None
|
||||
|
||||
@@ -253,6 +296,9 @@ class CharacterSelection(wx.Panel):
|
||||
self.selectChar(sChar.all5ID())
|
||||
|
||||
elif currCharID != newCharID:
|
||||
if currCharID is not None and not self._updatingFromHistory:
|
||||
if not self.charHistory or self.charHistory[-1] != currCharID:
|
||||
self.charHistory.append(currCharID)
|
||||
self.selectChar(newCharID)
|
||||
if not fit.calculated:
|
||||
self.charChanged(None)
|
||||
@@ -268,6 +314,15 @@ class CharacterSelection(wx.Panel):
|
||||
|
||||
toClipboard(list)
|
||||
|
||||
def exportSkillsCondensed(self, evt):
|
||||
skillsMap = self._buildSkillsTooltipSuperCondensed(self.reqs, skillsMap={})
|
||||
|
||||
list = ""
|
||||
for key in sorted(skillsMap):
|
||||
list += "%s %d\n" % (key, skillsMap[key][0])
|
||||
|
||||
toClipboard(list)
|
||||
|
||||
def exportSkillsEveMon(self, evt):
|
||||
skillsMap = self._buildSkillsTooltipCondensed(self.reqs, skillsMap={})
|
||||
|
||||
@@ -277,6 +332,83 @@ class CharacterSelection(wx.Panel):
|
||||
|
||||
toClipboard(list)
|
||||
|
||||
def importSkillsFromClipboard(self, evt):
|
||||
charID = self.getActiveCharacter()
|
||||
if charID is None:
|
||||
return
|
||||
|
||||
sChar = Character.getInstance()
|
||||
char = sChar.getCharacter(charID)
|
||||
|
||||
text = fromClipboard()
|
||||
if not text:
|
||||
with wx.MessageDialog(self, _t("Clipboard is empty"), _t("Error"), wx.OK | wx.ICON_ERROR) as dlg:
|
||||
dlg.ShowModal()
|
||||
return
|
||||
|
||||
try:
|
||||
lines = text.strip().splitlines()
|
||||
imported = 0
|
||||
errors = []
|
||||
|
||||
for line in lines:
|
||||
line = line.strip()
|
||||
if not line:
|
||||
continue
|
||||
|
||||
try:
|
||||
parts = line.rsplit(None, 1)
|
||||
if len(parts) != 2:
|
||||
errors.append(_t("Invalid format: {}").format(line))
|
||||
continue
|
||||
|
||||
skillName = parts[0]
|
||||
levelStr = parts[1]
|
||||
|
||||
try:
|
||||
level = int(levelStr)
|
||||
except ValueError:
|
||||
try:
|
||||
level = roman.fromRoman(levelStr.upper())
|
||||
except (roman.InvalidRomanNumeralError, ValueError):
|
||||
errors.append(_t("Invalid level format: {}").format(line))
|
||||
continue
|
||||
|
||||
if level < 0 or level > 5:
|
||||
errors.append(_t("Level must be between 0 and 5: {}").format(line))
|
||||
continue
|
||||
|
||||
skill = char.getSkill(skillName)
|
||||
sChar.changeLevel(charID, skill.item.ID, level)
|
||||
imported += 1
|
||||
|
||||
except KeyError as e:
|
||||
errors.append(_t("Skill not found: {}").format(skillName))
|
||||
pyfalog.error("Skill not found: '{}'", skillName)
|
||||
except Exception as e:
|
||||
errors.append(_t("Error processing line '{}': {}").format(line, str(e)))
|
||||
pyfalog.error("Error importing skill from line '{}': {}", line, e)
|
||||
|
||||
if imported > 0:
|
||||
self.refreshCharacterList()
|
||||
wx.PostEvent(self.mainFrame, GE.CharListUpdated())
|
||||
fitID = self.mainFrame.getActiveFit()
|
||||
if fitID is not None:
|
||||
wx.PostEvent(self.mainFrame, GE.FitChanged(fitIDs=(fitID,)))
|
||||
|
||||
if errors:
|
||||
errorMsg = _t("Imported {} skill(s). Errors:\n{}").format(imported, "\n".join(errors))
|
||||
with wx.MessageDialog(self, errorMsg, _t("Import Skills"), wx.OK | wx.ICON_WARNING) as dlg:
|
||||
dlg.ShowModal()
|
||||
elif imported > 0:
|
||||
with wx.MessageDialog(self, _t("Successfully imported {} skill(s)").format(imported), _t("Import Skills"), wx.OK) as dlg:
|
||||
dlg.ShowModal()
|
||||
|
||||
except Exception as e:
|
||||
pyfalog.error("Error importing skills from clipboard: {}", e)
|
||||
with wx.MessageDialog(self, _t("Error importing skills. Please check the log file."), _t("Error"), wx.OK | wx.ICON_ERROR) as dlg:
|
||||
dlg.ShowModal()
|
||||
|
||||
def _buildSkillsTooltip(self, reqs, currItem="", tabulationLevel=0):
|
||||
tip = ""
|
||||
sCharacter = Character.getInstance()
|
||||
|
||||
326
gui/fitDiffFrame.py
Normal file
@@ -0,0 +1,326 @@
|
||||
# =============================================================================
|
||||
# Copyright (C) 2025
|
||||
#
|
||||
# This file is part of pyfa.
|
||||
#
|
||||
# pyfa is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# pyfa is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with pyfa. If not, see <http://www.gnu.org/licenses/>.
|
||||
# =============================================================================
|
||||
|
||||
|
||||
# noinspection PyPackageRequirements
|
||||
import wx
|
||||
from collections import Counter
|
||||
|
||||
from eos.const import FittingSlot
|
||||
from service.fit import Fit as svcFit
|
||||
from service.port.eft import exportEft, importEft, _importPrepare
|
||||
from service.const import PortEftOptions
|
||||
|
||||
_t = wx.GetTranslation
|
||||
|
||||
|
||||
class FitDiffFrame(wx.Frame):
|
||||
"""A frame to display differences between two fits."""
|
||||
|
||||
def __init__(self, parent, fitID):
|
||||
super().__init__(
|
||||
parent,
|
||||
title=_t("Fit Diff"),
|
||||
style=wx.DEFAULT_FRAME_STYLE | wx.RESIZE_BORDER,
|
||||
size=(1000, 600)
|
||||
)
|
||||
self.parent = parent
|
||||
self.fitID = fitID
|
||||
self.sFit = svcFit.getInstance()
|
||||
|
||||
# EFT export options (same as CTRL-C)
|
||||
self.eftOptions = {
|
||||
PortEftOptions.LOADED_CHARGES: True,
|
||||
PortEftOptions.MUTATIONS: True,
|
||||
PortEftOptions.IMPLANTS: True,
|
||||
PortEftOptions.BOOSTERS: True,
|
||||
PortEftOptions.CARGO: True,
|
||||
}
|
||||
|
||||
self.initUI()
|
||||
self.Centre()
|
||||
self.Show()
|
||||
|
||||
def initUI(self):
|
||||
panel = wx.Panel(self)
|
||||
mainSizer = wx.BoxSizer(wx.VERTICAL)
|
||||
|
||||
# Instructions and flip button at the top
|
||||
topSizer = wx.BoxSizer(wx.HORIZONTAL)
|
||||
instructions = wx.StaticText(
|
||||
panel,
|
||||
label=_t("Paste fits in EFT format to compare")
|
||||
)
|
||||
topSizer.Add(instructions, 1, wx.ALL | wx.EXPAND, 5)
|
||||
|
||||
flipButton = wx.Button(panel, label=_t("Flip"))
|
||||
flipButton.Bind(wx.EVT_BUTTON, self.onFlip)
|
||||
topSizer.Add(flipButton, 0, wx.ALL | wx.ALIGN_CENTER_VERTICAL, 5)
|
||||
|
||||
mainSizer.Add(topSizer, 0, wx.EXPAND)
|
||||
|
||||
# Three panes: Fit 1 | Diff | Fit 2
|
||||
panesSizer = wx.BoxSizer(wx.HORIZONTAL)
|
||||
|
||||
# Pane 1: Fit 1 (editable)
|
||||
fit1Box = wx.StaticBox(panel, label=_t("Fit 1"))
|
||||
fit1Sizer = wx.StaticBoxSizer(fit1Box, wx.VERTICAL)
|
||||
self.fit1Text = wx.TextCtrl(
|
||||
panel,
|
||||
style=wx.TE_MULTILINE | wx.TE_DONTWRAP
|
||||
)
|
||||
fit1Sizer.Add(self.fit1Text, 1, wx.EXPAND)
|
||||
panesSizer.Add(fit1Sizer, 1, wx.ALL | wx.EXPAND, 5)
|
||||
|
||||
# Bind text changed event to update diff
|
||||
self.fit1Text.Bind(wx.EVT_TEXT, self.onFitChanged)
|
||||
|
||||
# Pane 2: Diff (simple text format)
|
||||
diffBox = wx.StaticBox(panel, label=_t("Differences"))
|
||||
diffSizer = wx.StaticBoxSizer(diffBox, wx.VERTICAL)
|
||||
self.diffText = wx.TextCtrl(
|
||||
panel,
|
||||
style=wx.TE_MULTILINE | wx.TE_READONLY | wx.TE_DONTWRAP
|
||||
)
|
||||
diffSizer.Add(self.diffText, 1, wx.EXPAND)
|
||||
panesSizer.Add(diffSizer, 1, wx.ALL | wx.EXPAND, 5)
|
||||
|
||||
# Pane 3: Fit 2 (user input)
|
||||
fit2Box = wx.StaticBox(panel, label=_t("Fit 2"))
|
||||
fit2Sizer = wx.StaticBoxSizer(fit2Box, wx.VERTICAL)
|
||||
self.fit2Text = wx.TextCtrl(
|
||||
panel,
|
||||
style=wx.TE_MULTILINE | wx.TE_DONTWRAP
|
||||
)
|
||||
fit2Sizer.Add(self.fit2Text, 1, wx.EXPAND)
|
||||
|
||||
# Bind text changed event to update diff
|
||||
self.fit2Text.Bind(wx.EVT_TEXT, self.onFitChanged)
|
||||
|
||||
panesSizer.Add(fit2Sizer, 1, wx.ALL | wx.EXPAND, 5)
|
||||
|
||||
mainSizer.Add(panesSizer, 1, wx.EXPAND | wx.ALL, 5)
|
||||
|
||||
panel.SetSizer(mainSizer)
|
||||
|
||||
# Load current fit into pane 1
|
||||
self.loadFit1()
|
||||
|
||||
def loadFit1(self):
|
||||
"""Load the current fit into pane 1 as EFT format."""
|
||||
fit = self.sFit.getFit(self.fitID)
|
||||
if fit:
|
||||
eftText = exportEft(fit, self.eftOptions, callback=None)
|
||||
self.fit1Text.SetValue(eftText)
|
||||
|
||||
def onFitChanged(self, event):
|
||||
"""Handle text change in either fit pane - update diff."""
|
||||
self.updateDiff()
|
||||
event.Skip()
|
||||
|
||||
def onFlip(self, event):
|
||||
"""Swap Fit 1 and Fit 2."""
|
||||
fit1Value = self.fit1Text.GetValue()
|
||||
fit2Value = self.fit2Text.GetValue()
|
||||
self.fit1Text.SetValue(fit2Value)
|
||||
self.fit2Text.SetValue(fit1Value)
|
||||
self.updateDiff()
|
||||
event.Skip()
|
||||
|
||||
def updateDiff(self):
|
||||
"""Calculate and display the differences between the two fits."""
|
||||
self.diffText.Clear()
|
||||
|
||||
fit1Text = self.fit1Text.GetValue().strip()
|
||||
fit2Text = self.fit2Text.GetValue().strip()
|
||||
|
||||
if not fit1Text or not fit2Text:
|
||||
return
|
||||
|
||||
# Parse both fits
|
||||
fit1 = self.parsePastedFit(fit1Text)
|
||||
fit2 = self.parsePastedFit(fit2Text)
|
||||
|
||||
if fit1 is None:
|
||||
self.diffText.SetValue(_t("Error: Fit 1 has invalid EFT format"))
|
||||
return
|
||||
if fit2 is None:
|
||||
self.diffText.SetValue(_t("Error: Fit 2 has invalid EFT format"))
|
||||
return
|
||||
|
||||
# Calculate differences and format as simple text list
|
||||
diffLines = self.calculateDiff(fit1, fit2)
|
||||
self.diffText.SetValue('\n'.join(diffLines))
|
||||
|
||||
def parsePastedFit(self, text):
|
||||
"""Parse pasted EFT text into a fit object."""
|
||||
try:
|
||||
lines = _importPrepare(text.splitlines())
|
||||
if not lines:
|
||||
return None
|
||||
return importEft(lines)
|
||||
except Exception:
|
||||
return None
|
||||
|
||||
def calculateDiff(self, fit1, fit2):
|
||||
"""Calculate items needed to transform fit1 into fit2.
|
||||
|
||||
Returns a list of strings in the format: "<item> <quantity>"
|
||||
Only shows items that need to be added (no negative values).
|
||||
"""
|
||||
diffLines = []
|
||||
|
||||
# Get module counts by type for each fit (grouped by slot type)
|
||||
fit1_modules = self.getModuleCounts(fit1)
|
||||
fit2_modules = self.getModuleCounts(fit2)
|
||||
|
||||
# Slot order
|
||||
slotOrder = [
|
||||
FittingSlot.HIGH,
|
||||
FittingSlot.MED,
|
||||
FittingSlot.LOW,
|
||||
FittingSlot.RIG,
|
||||
FittingSlot.SUBSYSTEM,
|
||||
FittingSlot.SERVICE,
|
||||
]
|
||||
|
||||
# Diff modules by slot - only show items needed to add
|
||||
for slot in slotOrder:
|
||||
fit1_slot_modules = fit1_modules.get(slot, Counter())
|
||||
fit2_slot_modules = fit2_modules.get(slot, Counter())
|
||||
|
||||
all_module_types = set(fit1_slot_modules.keys()) | set(fit2_slot_modules.keys())
|
||||
slot_diff_lines = []
|
||||
for module_type in sorted(all_module_types):
|
||||
count1 = fit1_slot_modules.get(module_type, 0)
|
||||
count2 = fit2_slot_modules.get(module_type, 0)
|
||||
if count2 > count1:
|
||||
slot_diff_lines.append(f"{module_type} x{count2 - count1}")
|
||||
|
||||
if slot_diff_lines:
|
||||
if diffLines:
|
||||
diffLines.append("")
|
||||
diffLines.extend(slot_diff_lines)
|
||||
|
||||
# Get drone counts
|
||||
fit1_drones = self.getDroneCounts(fit1)
|
||||
fit2_drones = self.getDroneCounts(fit2)
|
||||
|
||||
all_drone_types = set(fit1_drones.keys()) | set(fit2_drones.keys())
|
||||
for drone_type in sorted(all_drone_types):
|
||||
count1 = fit1_drones.get(drone_type, 0)
|
||||
count2 = fit2_drones.get(drone_type, 0)
|
||||
if count2 > count1:
|
||||
diffLines.append(f"{drone_type} x{count2 - count1}")
|
||||
|
||||
# Get fighter counts
|
||||
fit1_fighters = self.getFighterCounts(fit1)
|
||||
fit2_fighters = self.getFighterCounts(fit2)
|
||||
|
||||
all_fighter_types = set(fit1_fighters.keys()) | set(fit2_fighters.keys())
|
||||
for fighter_type in sorted(all_fighter_types):
|
||||
count1 = fit1_fighters.get(fighter_type, 0)
|
||||
count2 = fit2_fighters.get(fighter_type, 0)
|
||||
if count2 > count1:
|
||||
diffLines.append(f"{fighter_type} x{count2 - count1}")
|
||||
|
||||
# Get cargo counts
|
||||
fit1_cargo = self.getCargoCounts(fit1)
|
||||
fit2_cargo = self.getCargoCounts(fit2)
|
||||
|
||||
all_cargo_types = set(fit1_cargo.keys()) | set(fit2_cargo.keys())
|
||||
for cargo_type in sorted(all_cargo_types):
|
||||
count1 = fit1_cargo.get(cargo_type, 0)
|
||||
count2 = fit2_cargo.get(cargo_type, 0)
|
||||
if count2 > count1:
|
||||
diffLines.append(f"{cargo_type} x{count2 - count1}")
|
||||
|
||||
# Get implants
|
||||
fit1_implants = self.getImplantNames(fit1)
|
||||
fit2_implants = self.getImplantNames(fit2)
|
||||
|
||||
for implant in sorted(fit2_implants - fit1_implants):
|
||||
diffLines.append(f"{implant} x1")
|
||||
|
||||
# Get boosters
|
||||
fit1_boosters = self.getBoosterNames(fit1)
|
||||
fit2_boosters = self.getBoosterNames(fit2)
|
||||
|
||||
for booster in sorted(fit2_boosters - fit1_boosters):
|
||||
diffLines.append(f"{booster} x1")
|
||||
|
||||
return diffLines
|
||||
|
||||
def getModuleCounts(self, fit):
|
||||
"""Get a counter of module types for a fit, grouped by slot type.
|
||||
|
||||
Returns a dict mapping FittingSlot -> Counter of module names.
|
||||
Position doesn't matter, just counts by module name.
|
||||
"""
|
||||
counts_by_slot = {}
|
||||
for module in fit.modules:
|
||||
if module.isEmpty:
|
||||
continue
|
||||
slot = module.slot
|
||||
if slot not in counts_by_slot:
|
||||
counts_by_slot[slot] = Counter()
|
||||
# Use item type name for comparison
|
||||
name = module.item.typeName if module.item else ""
|
||||
counts_by_slot[slot][name] += 1
|
||||
return counts_by_slot
|
||||
|
||||
def getDroneCounts(self, fit):
|
||||
"""Get a counter of drone types for a fit."""
|
||||
counts = Counter()
|
||||
for drone in fit.drones:
|
||||
if drone.item:
|
||||
counts[drone.item.typeName] += drone.amount
|
||||
return counts
|
||||
|
||||
def getFighterCounts(self, fit):
|
||||
"""Get a counter of fighter types for a fit."""
|
||||
counts = Counter()
|
||||
for fighter in fit.fighters:
|
||||
if fighter.item:
|
||||
counts[fighter.item.typeName] += fighter.amount
|
||||
return counts
|
||||
|
||||
def getCargoCounts(self, fit):
|
||||
"""Get a counter of cargo items for a fit."""
|
||||
counts = Counter()
|
||||
for cargo in fit.cargo:
|
||||
if cargo.item:
|
||||
counts[cargo.item.typeName] += cargo.amount
|
||||
return counts
|
||||
|
||||
def getImplantNames(self, fit):
|
||||
"""Get a set of implant names for a fit."""
|
||||
names = set()
|
||||
for implant in fit.implants:
|
||||
if implant.item:
|
||||
names.add(implant.item.typeName)
|
||||
return names
|
||||
|
||||
def getBoosterNames(self, fit):
|
||||
"""Get a set of booster names for a fit."""
|
||||
names = set()
|
||||
for booster in fit.boosters:
|
||||
if booster.item:
|
||||
names.add(booster.item.typeName)
|
||||
return names
|
||||
@@ -24,6 +24,7 @@ import config
|
||||
import gui.mainFrame
|
||||
from eos.saveddata.drone import Drone
|
||||
from eos.saveddata.module import Module
|
||||
from eos.saveddata.ship import Ship
|
||||
from gui.auxWindow import AuxiliaryFrame
|
||||
from gui.bitmap_loader import BitmapLoader
|
||||
from gui.builtinItemStatsViews.itemAffectedBy import ItemAffectedBy
|
||||
@@ -35,6 +36,7 @@ from gui.builtinItemStatsViews.itemEffects import ItemEffects
|
||||
from gui.builtinItemStatsViews.itemMutator import ItemMutatorPanel
|
||||
from gui.builtinItemStatsViews.itemProperties import ItemProperties
|
||||
from gui.builtinItemStatsViews.itemRequirements import ItemRequirements
|
||||
from gui.builtinItemStatsViews.itemSkills import ItemSkills
|
||||
from gui.builtinItemStatsViews.itemTraits import ItemTraits
|
||||
from service.market import Market
|
||||
|
||||
@@ -156,6 +158,8 @@ class ItemStatsContainer(wx.Panel):
|
||||
def __init__(self, parent, stuff, item, context=None):
|
||||
wx.Panel.__init__(self, parent)
|
||||
sMkt = Market.getInstance()
|
||||
self.stuff = stuff
|
||||
self.context = context
|
||||
|
||||
mainSizer = wx.BoxSizer(wx.VERTICAL)
|
||||
|
||||
@@ -196,6 +200,10 @@ class ItemStatsContainer(wx.Panel):
|
||||
self.affectedby = ItemAffectedBy(self.nbContainer, stuff, item)
|
||||
self.nbContainer.AddPage(self.affectedby, _t("Affected by"))
|
||||
|
||||
if stuff is not None and isinstance(stuff, Ship):
|
||||
self.skills = ItemSkills(self.nbContainer, stuff, item)
|
||||
self.nbContainer.AddPage(self.skills, _t("Skills"))
|
||||
|
||||
if config.debug:
|
||||
self.properties = ItemProperties(self.nbContainer, stuff, item, context)
|
||||
self.nbContainer.AddPage(self.properties, _t("Properties"))
|
||||
|
||||
112
gui/mainFrame.py
@@ -18,6 +18,7 @@
|
||||
# =============================================================================
|
||||
|
||||
import datetime
|
||||
import itertools
|
||||
import os.path
|
||||
import threading
|
||||
import time
|
||||
@@ -60,8 +61,12 @@ from gui.shipBrowser import ShipBrowser
|
||||
from gui.statsPane import StatsPane
|
||||
from gui.targetProfileEditor import TargetProfileEditor
|
||||
from gui.updateDialog import UpdateDialog
|
||||
from gui.utils.clipboard import fromClipboard
|
||||
from gui.utils.clipboard import fromClipboard, toClipboard
|
||||
from gui.utils.progressHelper import ProgressHelper
|
||||
from eos.const import FittingSlot as es_Slot
|
||||
from eos.saveddata.character import Skill
|
||||
from eos.saveddata.fighter import Fighter as es_Fighter
|
||||
from eos.saveddata.module import Module as es_Module
|
||||
from service.character import Character
|
||||
from service.esi import Esi
|
||||
from service.fit import Fit
|
||||
@@ -522,6 +527,8 @@ class MainFrame(wx.Frame):
|
||||
self.Bind(wx.EVT_MENU, self.backupToXml, id=menuBar.backupFitsId)
|
||||
# Export skills needed
|
||||
self.Bind(wx.EVT_MENU, self.exportSkillsNeeded, id=menuBar.exportSkillsNeededId)
|
||||
# Copy skills needed
|
||||
self.Bind(wx.EVT_MENU, self.copySkillsNeeded, id=menuBar.copySkillsNeededId)
|
||||
# Import character
|
||||
self.Bind(wx.EVT_MENU, self.importCharacter, id=menuBar.importCharacterId)
|
||||
# Export HTML
|
||||
@@ -558,7 +565,8 @@ class MainFrame(wx.Frame):
|
||||
self.Bind(wx.EVT_MENU, self.toggleOverrides, id=menuBar.toggleOverridesId)
|
||||
|
||||
# Clipboard exports
|
||||
self.Bind(wx.EVT_MENU, self.exportToClipboard, id=wx.ID_COPY)
|
||||
self.Bind(wx.EVT_MENU, self.exportToClipboardDirectEft, id=menuBar.copyDirectEftId)
|
||||
self.Bind(wx.EVT_MENU, self.exportToClipboard, id=menuBar.copyWithDialogId)
|
||||
|
||||
# Fitting Restrictions
|
||||
self.Bind(wx.EVT_MENU, self.toggleIgnoreRestriction, id=menuBar.toggleIgnoreRestrictionID)
|
||||
@@ -571,6 +579,7 @@ class MainFrame(wx.Frame):
|
||||
toggleShipMarketId = wx.NewId()
|
||||
ctabnext = wx.NewId()
|
||||
ctabprev = wx.NewId()
|
||||
charPrevId = wx.NewId()
|
||||
|
||||
# Close Page
|
||||
self.Bind(wx.EVT_MENU, self.CloseCurrentPage, id=self.closePageId)
|
||||
@@ -580,6 +589,7 @@ class MainFrame(wx.Frame):
|
||||
self.Bind(wx.EVT_MENU, self.toggleShipMarket, id=toggleShipMarketId)
|
||||
self.Bind(wx.EVT_MENU, self.CTabNext, id=ctabnext)
|
||||
self.Bind(wx.EVT_MENU, self.CTabPrev, id=ctabprev)
|
||||
self.Bind(wx.EVT_MENU, self.selectPreviousCharacter, id=charPrevId)
|
||||
|
||||
actb = [(wx.ACCEL_CTRL, ord('T'), self.addPageId),
|
||||
(wx.ACCEL_CMD, ord('T'), self.addPageId),
|
||||
@@ -613,7 +623,19 @@ class MainFrame(wx.Frame):
|
||||
(wx.ACCEL_CMD, wx.WXK_PAGEDOWN, ctabnext),
|
||||
(wx.ACCEL_CMD, wx.WXK_PAGEUP, ctabprev),
|
||||
|
||||
(wx.ACCEL_CMD | wx.ACCEL_SHIFT, ord("Z"), wx.ID_REDO)
|
||||
(wx.ACCEL_CMD | wx.ACCEL_SHIFT, ord("Z"), wx.ID_REDO),
|
||||
|
||||
# Ctrl+Shift+C for copy with dialog (must come before Ctrl+C)
|
||||
# Note: use lowercase 'c' because SHIFT is already in flags
|
||||
(wx.ACCEL_CTRL | wx.ACCEL_SHIFT, ord('c'), menuBar.copyWithDialogId),
|
||||
(wx.ACCEL_CMD | wx.ACCEL_SHIFT, ord('c'), menuBar.copyWithDialogId),
|
||||
|
||||
# Ctrl+C for direct EFT copy
|
||||
(wx.ACCEL_CTRL, ord('c'), menuBar.copyDirectEftId),
|
||||
(wx.ACCEL_CMD, ord('c'), menuBar.copyDirectEftId),
|
||||
|
||||
# Shift+Tab for previous character
|
||||
(wx.ACCEL_SHIFT, wx.WXK_TAB, charPrevId)
|
||||
]
|
||||
|
||||
# Ctrl/Cmd+# for addition pane selection
|
||||
@@ -739,6 +761,9 @@ class MainFrame(wx.Frame):
|
||||
|
||||
def CTabPrev(self, event):
|
||||
self.fitMultiSwitch.PrevPage()
|
||||
|
||||
def selectPreviousCharacter(self, event):
|
||||
self.charSelection.selectPreviousChar()
|
||||
|
||||
def HAddPage(self, event):
|
||||
self.fitMultiSwitch.AddPage()
|
||||
@@ -798,6 +823,32 @@ class MainFrame(wx.Frame):
|
||||
else:
|
||||
self._openAfterImport(importData)
|
||||
|
||||
def exportToClipboardDirectEft(self, event):
|
||||
""" Copy fit to clipboard in EFT format without showing dialog """
|
||||
from eos.db import getFit
|
||||
from service.const import PortEftOptions
|
||||
from service.settings import SettingsProvider
|
||||
|
||||
fit = getFit(self.getActiveFit())
|
||||
if fit is None:
|
||||
return
|
||||
|
||||
# Get the default EFT export options from settings
|
||||
defaultOptions = {
|
||||
PortEftOptions.LOADED_CHARGES: True,
|
||||
PortEftOptions.MUTATIONS: True,
|
||||
PortEftOptions.IMPLANTS: True,
|
||||
PortEftOptions.BOOSTERS: True,
|
||||
PortEftOptions.CARGO: True,
|
||||
}
|
||||
settings = SettingsProvider.getInstance().getSettings("pyfaExport", {"format": CopySelectDialog.copyFormatEft, "options": {CopySelectDialog.copyFormatEft: defaultOptions}})
|
||||
options = settings["options"].get(CopySelectDialog.copyFormatEft, defaultOptions)
|
||||
|
||||
def copyToClipboard(text):
|
||||
toClipboard(text)
|
||||
|
||||
Port.exportEft(fit, options, callback=copyToClipboard)
|
||||
|
||||
def exportToClipboard(self, event):
|
||||
with CopySelectDialog(self) as dlg:
|
||||
dlg.ShowModal()
|
||||
@@ -832,6 +883,61 @@ class MainFrame(wx.Frame):
|
||||
self.waitDialog = wx.BusyInfo(_t("Exporting skills needed..."), parent=self)
|
||||
sCharacter.backupSkills(filePath, saveFmt, self.getActiveFit(), self.closeWaitDialog)
|
||||
|
||||
def copySkillsNeeded(self, event):
|
||||
""" Copies skills used by the fit that the character has to clipboard """
|
||||
activeFitID = self.getActiveFit()
|
||||
if activeFitID is None:
|
||||
return
|
||||
|
||||
sFit = Fit.getInstance()
|
||||
fit = sFit.getFit(activeFitID)
|
||||
if fit is None:
|
||||
return
|
||||
|
||||
if not fit.calculated:
|
||||
fit.calculate()
|
||||
|
||||
char = fit.character
|
||||
skillsMap = {}
|
||||
# for thing in itertools.chain(fit.modules, fit.drones, fit.fighters, [fit.ship], fit.appliedImplants, fit.boosters, fit.cargo):
|
||||
for thing in itertools.chain(fit.modules, fit.drones, fit.fighters, fit.appliedImplants, fit.boosters, fit.cargo):
|
||||
self._collectAffectingSkills(thing, char, skillsMap)
|
||||
|
||||
skillsList = ""
|
||||
for skillName in sorted(skillsMap):
|
||||
charLevel = skillsMap[skillName]
|
||||
for level in range(1, charLevel + 1):
|
||||
skillsList += "%s %d\n" % (skillName, level)
|
||||
|
||||
toClipboard(skillsList)
|
||||
|
||||
def _collectAffectingSkills(self, thing, char, skillsMap):
|
||||
""" Collect skills that affect items in the fit that the character has """
|
||||
for attr in ("item", "charge"):
|
||||
if attr == "charge" and isinstance(thing, es_Fighter):
|
||||
continue
|
||||
subThing = getattr(thing, attr, None)
|
||||
if subThing is None:
|
||||
continue
|
||||
if isinstance(thing, es_Fighter) and attr == "charge":
|
||||
continue
|
||||
|
||||
if attr == "charge":
|
||||
cont = getattr(thing, "chargeModifiedAttributes", None)
|
||||
else:
|
||||
cont = getattr(thing, "itemModifiedAttributes", None)
|
||||
|
||||
if cont is not None:
|
||||
for attrName in cont.iterAfflictions():
|
||||
for fit, afflictors in cont.getAfflictions(attrName).items():
|
||||
for afflictor, operator, stackingGroup, preResAmount, postResAmount, used in afflictors:
|
||||
if isinstance(afflictor, Skill) and afflictor.character == char:
|
||||
skillName = afflictor.item.name
|
||||
if skillName not in skillsMap:
|
||||
skillsMap[skillName] = afflictor.level
|
||||
elif skillsMap[skillName] < afflictor.level:
|
||||
skillsMap[skillName] = afflictor.level
|
||||
|
||||
def fileImportDialog(self, event):
|
||||
"""Handles importing single/multiple EVE XML / EFT cfg fit files"""
|
||||
with wx.FileDialog(
|
||||
|
||||
@@ -42,6 +42,7 @@ class MainMenuBar(wx.MenuBar):
|
||||
self.graphFrameId = wx.NewId()
|
||||
self.backupFitsId = wx.NewId()
|
||||
self.exportSkillsNeededId = wx.NewId()
|
||||
self.copySkillsNeededId = wx.NewId()
|
||||
self.importCharacterId = wx.NewId()
|
||||
self.exportHtmlId = wx.NewId()
|
||||
self.wikiId = wx.NewId()
|
||||
@@ -57,6 +58,8 @@ class MainMenuBar(wx.MenuBar):
|
||||
self.toggleIgnoreRestrictionID = wx.NewId()
|
||||
self.devToolsId = wx.NewId()
|
||||
self.optimizeFitPrice = wx.NewId()
|
||||
self.copyWithDialogId = wx.NewId()
|
||||
self.copyDirectEftId = wx.NewId()
|
||||
|
||||
self.mainFrame = mainFrame
|
||||
wx.MenuBar.__init__(self)
|
||||
@@ -84,7 +87,8 @@ class MainMenuBar(wx.MenuBar):
|
||||
fitMenu.Append(wx.ID_REDO, _t("&Redo") + "\tCTRL+Y", _t("Redo the most recent undone action"))
|
||||
|
||||
fitMenu.AppendSeparator()
|
||||
fitMenu.Append(wx.ID_COPY, _t("&To Clipboard") + "\tCTRL+C", _t("Export a fit to the clipboard"))
|
||||
fitMenu.Append(self.copyDirectEftId, _t("&To Clipboard (EFT)") + "\tCTRL+C", _t("Export a fit to the clipboard in EFT format"))
|
||||
fitMenu.Append(self.copyWithDialogId, _t("&To Clipboard (Select Format)") + "\tCTRL+SHIFT+C", _t("Export a fit to the clipboard with format selection"))
|
||||
fitMenu.Append(wx.ID_PASTE, _t("&From Clipboard") + "\tCTRL+V", _t("Import a fit from the clipboard"))
|
||||
|
||||
fitMenu.AppendSeparator()
|
||||
@@ -117,6 +121,7 @@ class MainMenuBar(wx.MenuBar):
|
||||
characterMenu.AppendSeparator()
|
||||
characterMenu.Append(self.importCharacterId, _t("&Import Character File"), _t("Import characters into pyfa from file"))
|
||||
characterMenu.Append(self.exportSkillsNeededId, _t("&Export Skills Needed"), _t("Export skills needed for this fitting"))
|
||||
characterMenu.Append(self.copySkillsNeededId, _t("&Copy Skills Needed"), _t("Copy skills needed for this fitting to clipboard"))
|
||||
|
||||
characterMenu.AppendSeparator()
|
||||
characterMenu.Append(self.ssoLoginId, _t("&Manage ESI Characters"))
|
||||
@@ -176,8 +181,10 @@ class MainMenuBar(wx.MenuBar):
|
||||
return
|
||||
enable = activeFitID is not None
|
||||
self.Enable(wx.ID_SAVEAS, enable)
|
||||
self.Enable(wx.ID_COPY, enable)
|
||||
self.Enable(self.copyDirectEftId, enable)
|
||||
self.Enable(self.copyWithDialogId, enable)
|
||||
self.Enable(self.exportSkillsNeededId, enable)
|
||||
self.Enable(self.copySkillsNeededId, enable)
|
||||
|
||||
self.refreshUndo()
|
||||
|
||||
|
||||
@@ -54,6 +54,7 @@ class MarketBrowser(wx.Panel):
|
||||
self.settings = MarketPriceSettings.getInstance()
|
||||
self.__mode = 'normal'
|
||||
self.__normalBtnMap = {}
|
||||
self.__normalSlotBtnMap = {}
|
||||
self.marketView = MarketTree(self.splitter, self)
|
||||
self.itemView = ItemView(self.splitter, self)
|
||||
|
||||
@@ -64,22 +65,61 @@ class MarketBrowser(wx.Panel):
|
||||
# Same fix as for search box on macs,
|
||||
# need some pixels of extra space or everything clips and is ugly
|
||||
p = wx.Panel(self)
|
||||
box = wx.BoxSizer(wx.HORIZONTAL)
|
||||
p.SetSizer(box)
|
||||
vbox_panel = wx.BoxSizer(wx.VERTICAL)
|
||||
p.SetSizer(vbox_panel)
|
||||
vbox.Add(p, 0, wx.EXPAND)
|
||||
|
||||
# First row: meta buttons
|
||||
metaBox = wx.BoxSizer(wx.HORIZONTAL)
|
||||
vbox_panel.Add(metaBox, 0, wx.EXPAND)
|
||||
self.metaButtons = []
|
||||
btn = None
|
||||
for name in list(self.sMkt.META_MAP.keys()):
|
||||
btn = MetaButton(p, wx.ID_ANY, name.capitalize(), style=wx.BU_EXACTFIT)
|
||||
setattr(self, name, btn)
|
||||
box.Add(btn, 1, wx.ALIGN_CENTER)
|
||||
metaBox.Add(btn, 1, wx.ALIGN_CENTER)
|
||||
btn.Bind(wx.EVT_TOGGLEBUTTON, self.toggleMetaButton)
|
||||
btn.metaName = name
|
||||
self.metaButtons.append(btn)
|
||||
|
||||
# Second row: slot/fits filter buttons (BELOW meta buttons)
|
||||
slotBox = wx.BoxSizer(wx.HORIZONTAL)
|
||||
vbox_panel.Add(slotBox, 0, wx.EXPAND)
|
||||
self.slotButtons = []
|
||||
from eos.const import FittingSlot
|
||||
|
||||
# Fits button
|
||||
fitsBtn = MetaButton(p, wx.ID_ANY, "Fits", style=wx.BU_EXACTFIT)
|
||||
setattr(self, "fits", fitsBtn)
|
||||
slotBox.Add(fitsBtn, 1, wx.ALIGN_CENTER)
|
||||
fitsBtn.Bind(wx.EVT_TOGGLEBUTTON, self.toggleSlotButton)
|
||||
fitsBtn.filterType = "fits"
|
||||
# Fits button starts deselected (checkbox, off by default)
|
||||
fitsBtn.setUserSelection(False)
|
||||
self.slotButtons.append(fitsBtn)
|
||||
|
||||
# High, Med, Low, Rig buttons
|
||||
slotMap = {
|
||||
FittingSlot.HIGH: "High",
|
||||
FittingSlot.MED: "Med",
|
||||
FittingSlot.LOW: "Low",
|
||||
FittingSlot.RIG: "Rig"
|
||||
}
|
||||
for slot, label in slotMap.items():
|
||||
slotBtn = MetaButton(p, wx.ID_ANY, label, style=wx.BU_EXACTFIT)
|
||||
setattr(self, "slot_%s" % label.lower(), slotBtn)
|
||||
slotBox.Add(slotBtn, 1, wx.ALIGN_CENTER)
|
||||
slotBtn.Bind(wx.EVT_TOGGLEBUTTON, self.toggleSlotButton)
|
||||
slotBtn.filterType = "slot"
|
||||
slotBtn.slotType = slot
|
||||
# Slot buttons start deselected (unlike meta buttons which start selected)
|
||||
slotBtn.setUserSelection(False)
|
||||
self.slotButtons.append(slotBtn)
|
||||
|
||||
# Make itemview to set toggles according to list contents
|
||||
self.itemView.setToggles()
|
||||
|
||||
p.SetMinSize((wx.SIZE_AUTO_WIDTH, btn.GetSize()[1] + 5))
|
||||
p.SetMinSize((wx.SIZE_AUTO_WIDTH, btn.GetSize()[1] * 2 + 10))
|
||||
|
||||
def toggleMetaButton(self, event):
|
||||
"""Process clicks on toggle buttons"""
|
||||
@@ -100,6 +140,21 @@ class MarketBrowser(wx.Panel):
|
||||
|
||||
self.itemView.filterItemStore()
|
||||
|
||||
def toggleSlotButton(self, event):
|
||||
"""Process clicks on slot/fits filter buttons"""
|
||||
clickedBtn = event.EventObject
|
||||
|
||||
# All buttons (Fits, High, Med, Low, Rig) work as checkboxes (independent toggles)
|
||||
clickedBtn.setUserSelection(clickedBtn.GetValue())
|
||||
self.itemView.filterItemStore()
|
||||
|
||||
def getFitsFilter(self):
|
||||
"""Check if Fits button is active"""
|
||||
for btn in self.slotButtons:
|
||||
if btn.filterType == "fits" and btn.userSelected:
|
||||
return True
|
||||
return False
|
||||
|
||||
def jump(self, item):
|
||||
self.mode = 'normal'
|
||||
self.marketView.jump(item)
|
||||
@@ -141,6 +196,9 @@ class MarketBrowser(wx.Panel):
|
||||
self.__normalBtnMap.clear()
|
||||
for btn in self.metaButtons:
|
||||
self.__normalBtnMap[btn] = btn.userSelected
|
||||
self.__normalSlotBtnMap.clear()
|
||||
for btn in self.slotButtons:
|
||||
self.__normalSlotBtnMap[btn] = btn.userSelected
|
||||
if newMode == 'search':
|
||||
self.marketView.UnselectAll()
|
||||
setting = self.settings.get('marketMGSearchMode')
|
||||
@@ -149,12 +207,16 @@ class MarketBrowser(wx.Panel):
|
||||
if newMode in ('search', 'recent', 'charges'):
|
||||
for btn in self.metaButtons:
|
||||
btn.setUserSelection(True)
|
||||
# Clear slot button selections when searching (search can return any item type)
|
||||
for btn in self.slotButtons:
|
||||
btn.setUserSelection(False)
|
||||
if newMode == 'normal':
|
||||
for btn, state in self.__normalBtnMap.items():
|
||||
btn.setUserSelection(state)
|
||||
for btn, state in self.__normalSlotBtnMap.items():
|
||||
btn.setUserSelection(state)
|
||||
# We turn on all meta buttons permanently
|
||||
if setting == 2:
|
||||
for btn in self.metaButtons:
|
||||
btn.setUserSelection(True)
|
||||
self.__mode = newMode
|
||||
|
||||
|
||||
@@ -1,22 +1,68 @@
|
||||
# noinspection PyPackageRequirements
|
||||
import wx
|
||||
from logbook import Logger
|
||||
|
||||
logger = Logger(__name__)
|
||||
|
||||
|
||||
def toClipboard(text):
|
||||
clip = wx.TheClipboard
|
||||
clip.Open()
|
||||
data = wx.TextDataObject(text)
|
||||
clip.SetData(data)
|
||||
clip.Close()
|
||||
"""
|
||||
Copy text to clipboard. Explicitly uses CLIPBOARD selection, not PRIMARY.
|
||||
|
||||
On X11 systems, wxPython can confuse between PRIMARY and CLIPBOARD selections,
|
||||
causing "already open" errors. This function ensures we always use CLIPBOARD.
|
||||
|
||||
See: https://discuss.wxpython.org/t/wx-theclipboard-pasting-different-content-on-every-second-paste/35361
|
||||
"""
|
||||
clipboard = wx.TheClipboard
|
||||
try:
|
||||
# Explicitly use CLIPBOARD selection, not PRIMARY selection
|
||||
# This prevents X11 confusion between the two clipboard types
|
||||
clipboard.UsePrimarySelection(False)
|
||||
|
||||
if clipboard.Open():
|
||||
try:
|
||||
data = wx.TextDataObject(text)
|
||||
clipboard.SetData(data)
|
||||
return True
|
||||
finally:
|
||||
clipboard.Close()
|
||||
else:
|
||||
logger.debug("Failed to open clipboard for writing")
|
||||
return False
|
||||
except Exception as e:
|
||||
logger.warning("Error writing to clipboard: {}", e)
|
||||
return False
|
||||
|
||||
|
||||
def fromClipboard():
|
||||
clip = wx.TheClipboard
|
||||
clip.Open()
|
||||
data = wx.TextDataObject("")
|
||||
if clip.GetData(data):
|
||||
clip.Close()
|
||||
return data.GetText()
|
||||
else:
|
||||
clip.Close()
|
||||
"""
|
||||
Read text from clipboard. Explicitly uses CLIPBOARD selection, not PRIMARY.
|
||||
|
||||
On X11 systems, wxPython can confuse between PRIMARY and CLIPBOARD selections,
|
||||
causing "already open" errors. This function ensures we always use CLIPBOARD.
|
||||
|
||||
See: https://discuss.wxpython.org/t/wx-theclipboard-pasting-different-content-on-every-second-paste/35361
|
||||
"""
|
||||
clipboard = wx.TheClipboard
|
||||
try:
|
||||
# Explicitly use CLIPBOARD selection, not PRIMARY selection
|
||||
# This prevents X11 confusion between the two clipboard types
|
||||
clipboard.UsePrimarySelection(False)
|
||||
|
||||
if clipboard.Open():
|
||||
try:
|
||||
data = wx.TextDataObject()
|
||||
if clipboard.GetData(data):
|
||||
return data.GetText()
|
||||
else:
|
||||
logger.debug("Clipboard open but no CLIPBOARD data available")
|
||||
return None
|
||||
finally:
|
||||
clipboard.Close()
|
||||
else:
|
||||
logger.debug("Failed to open clipboard for reading")
|
||||
return None
|
||||
except Exception as e:
|
||||
logger.warning("Error reading from clipboard: {}", e)
|
||||
return None
|
||||
|
||||
BIN
imgs/icons/10850@1x.png
Normal file
|
After Width: | Height: | Size: 582 B |
BIN
imgs/icons/10850@2x.png
Normal file
|
After Width: | Height: | Size: 1.6 KiB |
BIN
imgs/icons/24566@1x.png
Normal file
|
After Width: | Height: | Size: 812 B |
BIN
imgs/icons/24566@2x.png
Normal file
|
After Width: | Height: | Size: 2.4 KiB |
BIN
imgs/renders/29066@1x.png
Normal file
|
After Width: | Height: | Size: 2.3 KiB |
BIN
imgs/renders/29066@2x.png
Normal file
|
After Width: | Height: | Size: 7.3 KiB |
BIN
imgs/renders/29067@1x.png
Normal file
|
After Width: | Height: | Size: 2.3 KiB |
BIN
imgs/renders/29067@2x.png
Normal file
|
After Width: | Height: | Size: 7.9 KiB |
BIN
imgs/renders/29105@1x.png
Normal file
|
After Width: | Height: | Size: 2.2 KiB |
BIN
imgs/renders/29105@2x.png
Normal file
|
After Width: | Height: | Size: 7.5 KiB |
@@ -77,6 +77,14 @@ msgstr ""
|
||||
msgid "&Export Skills Needed"
|
||||
msgstr ""
|
||||
|
||||
#: gui/mainMenuBar.py:120
|
||||
msgid "&Copy Skills Needed"
|
||||
msgstr ""
|
||||
|
||||
#: gui/mainMenuBar.py:120
|
||||
msgid "Copy skills needed for this fitting to clipboard"
|
||||
msgstr ""
|
||||
|
||||
#: gui/mainMenuBar.py:66 gui/propertyEditor.py:42
|
||||
msgid "&File"
|
||||
msgstr ""
|
||||
|
||||
BIN
oleacc.dll
LFS
Normal file
28
oleacc.ini
Normal file
@@ -0,0 +1,28 @@
|
||||
;
|
||||
; Pyfa mod Darkmode settings
|
||||
;
|
||||
; ActiveThemePalette [OPTIONAL, Boolean, Default=1]
|
||||
; Indicate which of the available color themes to use. (ex. "ActiveThemePalette = 3" to use the LicoriceBlue color theme)
|
||||
; Available color themes: 1 = BlackBeauty, 2 = Licorice, 3 = LicoriceBlue, 4 = BlackBeauty
|
||||
;
|
||||
; OverrideThemePalette [OPTIONAL, Comma separated string]
|
||||
; Specify a string of (5) comma separated RGB hex colors to use as theme palette, ordered from darkest to lightest.
|
||||
; Valid RGB hex format prefix are #, 0x or nothing.
|
||||
; (ex. OverrideThemePalette = #521ecc, #e68ca1, #1a2070, #a85294, #aaccb5)
|
||||
;
|
||||
; EnableCustomControls[OPTIONAL, Boolean, Default = true]
|
||||
; Indicates if the standard windows controls will be colored by the active theme palette.
|
||||
;
|
||||
; UseExperimentalDarkmode [OPTIONAL, Boolean, Default = true]
|
||||
; Implementation of some undocumented windows api call, to force certain apps into a darkmode state.
|
||||
;
|
||||
; EnableLogging [OPTIONAL, Boolean, Default = false]
|
||||
; Write log output to a .log file.
|
||||
;
|
||||
|
||||
[settings]
|
||||
ActiveThemePalette = 1
|
||||
OverrideThemePalette = #521ecc, #EE3460, #1a2070, #a85294, #aaccb5
|
||||
EnableCustomControls = true
|
||||
UseExperimentalDarkmode = true
|
||||
EnableLogging = false
|
||||
11
pyfa.py
@@ -150,6 +150,17 @@ if __name__ == "__main__":
|
||||
mf = MainFrame(options.title)
|
||||
ErrorHandler.SetParent(mf)
|
||||
|
||||
# Start ESI token validation, this helps avoid token expiry
|
||||
try:
|
||||
from service.esi import Esi
|
||||
esi = Esi.getInstance()
|
||||
esi.startTokenValidation()
|
||||
pyfalog.info("ESI token validation started")
|
||||
except (KeyboardInterrupt, SystemExit):
|
||||
raise
|
||||
except Exception as e:
|
||||
pyfalog.warning(f"failed to start ESI token validation thread:\n{e}")
|
||||
|
||||
if options.profile_path:
|
||||
profile_path = os.path.join(options.profile_path, 'pyfa-{}.profile'.format(datetime.datetime.now().strftime('%Y%m%d_%H%M%S')))
|
||||
pyfalog.debug("Starting pyfa with a profiler, saving to {}".format(profile_path))
|
||||
|
||||
24
pyproject.toml
Normal file
@@ -0,0 +1,24 @@
|
||||
[project]
|
||||
name = "pyfa"
|
||||
version = "0.1.0"
|
||||
description = "Add your description here"
|
||||
readme = "README.md"
|
||||
requires-python = ">=3.12"
|
||||
dependencies = [
|
||||
"beautifulsoup4==4.12.2",
|
||||
"cryptography==42.0.4",
|
||||
"logbook==1.7.0.post0",
|
||||
"markdown2==2.4.11",
|
||||
"matplotlib==3.8.2",
|
||||
"numpy==1.26.2",
|
||||
"packaging==23.2",
|
||||
"python-dateutil==2.8.2",
|
||||
"python-jose==3.3.0",
|
||||
"pyyaml==6.0.1",
|
||||
"requests==2.31.0",
|
||||
"requests-cache==1.1.1",
|
||||
"roman==4.1",
|
||||
"ruff>=0.14.8",
|
||||
"sqlalchemy==1.4.50",
|
||||
"wxpython==4.2.1",
|
||||
]
|
||||
60
release.sh
Normal file
@@ -0,0 +1,60 @@
|
||||
#!/bin/bash
|
||||
|
||||
set -e
|
||||
|
||||
echo "Figuring out the tag..."
|
||||
TAG=$(git describe --tags --exact-match 2>/dev/null || echo "")
|
||||
if [ -z "$TAG" ]; then
|
||||
# Get the latest tag
|
||||
LATEST_TAG=$(git describe --tags $(git rev-list --tags --max-count=1) 2>/dev/null || echo "v0.0.0")
|
||||
# Remove 'v' prefix if present
|
||||
LATEST_TAG=${LATEST_TAG#v}
|
||||
# Increment the patch version
|
||||
IFS='.' read -r -a VERSION_PARTS <<< "$LATEST_TAG"
|
||||
VERSION_PARTS[2]=$((VERSION_PARTS[2]+1))
|
||||
TAG="v${VERSION_PARTS[0]}.${VERSION_PARTS[1]}.${VERSION_PARTS[2]}"
|
||||
# Create a new tag
|
||||
git tag $TAG
|
||||
git push origin $TAG
|
||||
fi
|
||||
echo "Tag: $TAG"
|
||||
|
||||
echo "Building the binary..."
|
||||
./build.sh
|
||||
|
||||
echo "Creating release zip..."
|
||||
ZIP="pyfa-${TAG}-win.zip"
|
||||
7z a "${ZIP}" dist/pyfa/*
|
||||
|
||||
echo "Creating a release..."
|
||||
TOKEN="$GITEA_API_KEY"
|
||||
GITEA="https://git.site.quack-lab.dev"
|
||||
REPO="dave/pyfa"
|
||||
|
||||
# Create a release
|
||||
RELEASE_RESPONSE=$(curl -s -X POST \
|
||||
-H "Authorization: token $TOKEN" \
|
||||
-H "Accept: application/json" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{
|
||||
"tag_name": "'"$TAG"'",
|
||||
"name": "'"$TAG"'",
|
||||
"draft": false,
|
||||
"prerelease": false
|
||||
}' \
|
||||
$GITEA/api/v1/repos/$REPO/releases)
|
||||
|
||||
# Extract the release ID
|
||||
echo $RELEASE_RESPONSE
|
||||
RELEASE_ID=$(echo $RELEASE_RESPONSE | awk -F'"id":' '{print $2+0; exit}')
|
||||
echo "Release ID: $RELEASE_ID"
|
||||
|
||||
echo "Uploading the zip..."
|
||||
curl -X POST \
|
||||
-H "Authorization: token $TOKEN" \
|
||||
-F "attachment=@${ZIP}" \
|
||||
"$GITEA/api/v1/repos/$REPO/releases/${RELEASE_ID}/assets?name=${ZIP}"
|
||||
|
||||
rm "${ZIP}"
|
||||
|
||||
echo "Release complete! ${ZIP} uploaded to ${TAG}"
|
||||
@@ -41,11 +41,15 @@ def main(old, new, groups=True, effects=True, attributes=True, renames=True):
|
||||
new_cursor = new_db.cursor()
|
||||
|
||||
# Force some of the items to make them published
|
||||
FORCEPUB_TYPES = ("Ibis", "Impairor", "Velator", "Reaper",
|
||||
"Amarr Tactical Destroyer Propulsion Mode",
|
||||
"Amarr Tactical Destroyer Sharpshooter Mode",
|
||||
"Amarr Tactical Destroyer Defense Mode")
|
||||
OVERRIDES_TYPEPUB = 'UPDATE invtypes SET published = 1 WHERE typeName = ?'
|
||||
FORCEPUB_TYPES = (
|
||||
"% Propulsion Mode",
|
||||
"% Sharpshooter Mode",
|
||||
"% Defense Mode",
|
||||
"% Primary Mode",
|
||||
"% Secondary Mode",
|
||||
"% Tertiary Mode",
|
||||
)
|
||||
OVERRIDES_TYPEPUB = 'UPDATE invtypes SET published = 1 WHERE typeName like ?'
|
||||
for typename in FORCEPUB_TYPES:
|
||||
old_cursor.execute(OVERRIDES_TYPEPUB, (typename,))
|
||||
new_cursor.execute(OVERRIDES_TYPEPUB, (typename,))
|
||||
|
||||
@@ -25,6 +25,44 @@ pyfalog = Logger(__name__)
|
||||
_t = wx.GetTranslation
|
||||
|
||||
|
||||
class EsiTokenValidationThread(threading.Thread):
|
||||
def __init__(self, callback=None):
|
||||
threading.Thread.__init__(self)
|
||||
self.name = "EsiTokenValidation"
|
||||
self.callback = callback
|
||||
self.running = True
|
||||
|
||||
def run(self):
|
||||
with config.logging_setup.threadbound():
|
||||
try:
|
||||
esi = Esi.getInstance()
|
||||
chars = esi.getSsoCharacters()
|
||||
|
||||
for char in chars:
|
||||
if not self.running:
|
||||
return
|
||||
|
||||
if char.is_token_expired():
|
||||
pyfalog.info(f"Token expired for {char.characterName}, attempting refresh")
|
||||
try:
|
||||
esi.refresh(char)
|
||||
eos.db.save(char)
|
||||
pyfalog.info(f"Successfully refreshed token for {char.characterName}")
|
||||
except Exception as e:
|
||||
pyfalog.error(f"Failed to refresh token for {char.characterName}: {e}")
|
||||
else:
|
||||
pyfalog.debug(f"Token valid for {char.characterName}")
|
||||
|
||||
except Exception as e:
|
||||
pyfalog.error(f"Error validating ESI tokens: {e}")
|
||||
finally:
|
||||
if self.callback:
|
||||
wx.CallAfter(self.callback)
|
||||
|
||||
def stop(self):
|
||||
self.running = False
|
||||
|
||||
|
||||
class Esi(EsiAccess):
|
||||
_instance = None
|
||||
|
||||
@@ -194,3 +232,9 @@ class Esi(EsiAccess):
|
||||
pyfalog.debug("Handling SSO login with: {0}", message)
|
||||
|
||||
self.handleLogin(message['code'])
|
||||
|
||||
def startTokenValidation(self):
|
||||
pyfalog.debug("Starting ESI token validation thread")
|
||||
tokenValidationThread = EsiTokenValidationThread()
|
||||
tokenValidationThread.daemon = True
|
||||
tokenValidationThread.start()
|
||||
|
||||
@@ -327,6 +327,8 @@ class Market:
|
||||
"Sidewinder" : self.les_grp, # AT20 prize
|
||||
"Cobra" : self.les_grp, # AT20 prize
|
||||
"Python" : self.les_grp, # AT20 prize
|
||||
"Skua" : self.les_grp, # AT21 prize
|
||||
"Anhinga" : self.les_grp, # AT21 prize
|
||||
}
|
||||
|
||||
self.ITEMS_FORCEGROUP_R = self.__makeRevDict(self.ITEMS_FORCEGROUP)
|
||||
|
||||
@@ -49167,5 +49167,51 @@
|
||||
"published": 1,
|
||||
"stackable": 1,
|
||||
"unitID": 105
|
||||
},
|
||||
"6054": {
|
||||
"attributeID": 6054,
|
||||
"categoryID": 37,
|
||||
"dataType": 5,
|
||||
"defaultValue": 0.0,
|
||||
"displayWhenZero": 0,
|
||||
"highIsGood": 1,
|
||||
"name": "AnhingaLargeMissilePowerFittingBonus",
|
||||
"published": 0,
|
||||
"stackable": 1
|
||||
},
|
||||
"6055": {
|
||||
"attributeID": 6055,
|
||||
"categoryID": 37,
|
||||
"dataType": 5,
|
||||
"defaultValue": 0.0,
|
||||
"displayWhenZero": 0,
|
||||
"highIsGood": 1,
|
||||
"name": "AnhingaLargeMissileCpuFittingBonus",
|
||||
"published": 0,
|
||||
"stackable": 1
|
||||
},
|
||||
"6057": {
|
||||
"attributeID": 6057,
|
||||
"categoryID": 2,
|
||||
"dataType": 5,
|
||||
"defaultValue": 1.0,
|
||||
"description": "",
|
||||
"displayWhenZero": 0,
|
||||
"highIsGood": 0,
|
||||
"name": "modeShieldRechargePostDiv",
|
||||
"published": 0,
|
||||
"stackable": 1
|
||||
},
|
||||
"6062": {
|
||||
"attributeID": 6062,
|
||||
"categoryID": 51,
|
||||
"dataType": 5,
|
||||
"defaultValue": 0.0,
|
||||
"description": "Role Bonus for Perseverance Ice Mining Critical Hit Role bonus",
|
||||
"displayWhenZero": 0,
|
||||
"highIsGood": 1,
|
||||
"name": "shipRoleBonusPerseveranceIceMiningCriticalHitChance",
|
||||
"published": 0,
|
||||
"stackable": 1
|
||||
}
|
||||
}
|
||||
@@ -58317,6 +58317,7 @@
|
||||
],
|
||||
"propulsionChance": 0,
|
||||
"published": 0,
|
||||
"rangeAttributeID": 54,
|
||||
"rangeChance": 0
|
||||
},
|
||||
"6216": {
|
||||
@@ -99669,6 +99670,56 @@
|
||||
"published": 0,
|
||||
"rangeChance": 0
|
||||
},
|
||||
"12758": {
|
||||
"description_de": "Automatically generated effect",
|
||||
"description_en-us": "Automatically generated effect",
|
||||
"description_es": "Automatically generated effect",
|
||||
"description_fr": "Automatically generated effect",
|
||||
"description_it": "Automatically generated effect",
|
||||
"description_ja": "Automatically generated effect",
|
||||
"description_ko": "Automatically generated effect",
|
||||
"description_ru": "Automatically generated effect",
|
||||
"description_zh": "Automatically generated effect",
|
||||
"descriptionID": 1022818,
|
||||
"disallowAutoRepeat": 0,
|
||||
"effectCategory": 0,
|
||||
"effectID": 12758,
|
||||
"effectName": "shipRoleBonusAnhingaLargeMissilePowerFittingBonus",
|
||||
"electronicChance": 0,
|
||||
"isAssistance": 0,
|
||||
"isOffensive": 0,
|
||||
"isWarpSafe": 0,
|
||||
"modifierInfo": [
|
||||
{
|
||||
"domain": "shipID",
|
||||
"func": "LocationGroupModifier",
|
||||
"groupID": 1245,
|
||||
"modifiedAttributeID": 30,
|
||||
"modifyingAttributeID": 6054,
|
||||
"operation": 0
|
||||
},
|
||||
{
|
||||
"domain": "shipID",
|
||||
"func": "LocationGroupModifier",
|
||||
"groupID": 506,
|
||||
"modifiedAttributeID": 30,
|
||||
"modifyingAttributeID": 6054,
|
||||
"operation": 0
|
||||
},
|
||||
{
|
||||
"domain": "shipID",
|
||||
"func": "LocationGroupModifier",
|
||||
"groupID": 508,
|
||||
"modifiedAttributeID": 30,
|
||||
"modifyingAttributeID": 6054,
|
||||
"operation": 0
|
||||
}
|
||||
],
|
||||
"propulsionChance": 0,
|
||||
"published": 0,
|
||||
"rangeAttributeID": 54,
|
||||
"rangeChance": 0
|
||||
},
|
||||
"12759": {
|
||||
"disallowAutoRepeat": 0,
|
||||
"effectCategory": 4,
|
||||
@@ -99769,5 +99820,285 @@
|
||||
"propulsionChance": 0,
|
||||
"published": 0,
|
||||
"rangeChance": 0
|
||||
},
|
||||
"12764": {
|
||||
"disallowAutoRepeat": 0,
|
||||
"effectCategory": 0,
|
||||
"effectID": 12764,
|
||||
"effectName": "shipRoleBonusAnhingaLargeMissileCpuFittingBonus",
|
||||
"electronicChance": 0,
|
||||
"isAssistance": 0,
|
||||
"isOffensive": 0,
|
||||
"isWarpSafe": 0,
|
||||
"modifierInfo": [
|
||||
{
|
||||
"domain": "shipID",
|
||||
"func": "LocationGroupModifier",
|
||||
"groupID": 1245,
|
||||
"modifiedAttributeID": 50,
|
||||
"modifyingAttributeID": 6055,
|
||||
"operation": 0
|
||||
},
|
||||
{
|
||||
"domain": "shipID",
|
||||
"func": "LocationGroupModifier",
|
||||
"groupID": 506,
|
||||
"modifiedAttributeID": 50,
|
||||
"modifyingAttributeID": 6055,
|
||||
"operation": 0
|
||||
},
|
||||
{
|
||||
"domain": "shipID",
|
||||
"func": "LocationGroupModifier",
|
||||
"groupID": 508,
|
||||
"modifiedAttributeID": 50,
|
||||
"modifyingAttributeID": 6055,
|
||||
"operation": 0
|
||||
}
|
||||
],
|
||||
"propulsionChance": 0,
|
||||
"published": 0,
|
||||
"rangeAttributeID": 54,
|
||||
"rangeChance": 0
|
||||
},
|
||||
"12765": {
|
||||
"disallowAutoRepeat": 0,
|
||||
"effectCategory": 0,
|
||||
"effectID": 12765,
|
||||
"effectName": "shipBonusTorpedoAndCruiseMissileExplosionVelocityMB",
|
||||
"electronicChance": 0,
|
||||
"isAssistance": 0,
|
||||
"isOffensive": 0,
|
||||
"isWarpSafe": 0,
|
||||
"modifierInfo": [
|
||||
{
|
||||
"domain": "charID",
|
||||
"func": "OwnerRequiredSkillModifier",
|
||||
"modifiedAttributeID": 653,
|
||||
"modifyingAttributeID": 490,
|
||||
"operation": 6,
|
||||
"skillTypeID": 3325
|
||||
},
|
||||
{
|
||||
"domain": "charID",
|
||||
"func": "OwnerRequiredSkillModifier",
|
||||
"modifiedAttributeID": 653,
|
||||
"modifyingAttributeID": 490,
|
||||
"operation": 6,
|
||||
"skillTypeID": 3326
|
||||
}
|
||||
],
|
||||
"propulsionChance": 0,
|
||||
"published": 0,
|
||||
"rangeChance": 0
|
||||
},
|
||||
"12766": {
|
||||
"disallowAutoRepeat": 0,
|
||||
"effectCategory": 0,
|
||||
"effectID": 12766,
|
||||
"effectName": "shipBonusTorpedoAndCruiseMissileExplosionRadiusCBC1",
|
||||
"electronicChance": 0,
|
||||
"isAssistance": 0,
|
||||
"isOffensive": 0,
|
||||
"isWarpSafe": 0,
|
||||
"modifierInfo": [
|
||||
{
|
||||
"domain": "charID",
|
||||
"func": "OwnerRequiredSkillModifier",
|
||||
"modifiedAttributeID": 654,
|
||||
"modifyingAttributeID": 743,
|
||||
"operation": 6,
|
||||
"skillTypeID": 3326
|
||||
},
|
||||
{
|
||||
"domain": "charID",
|
||||
"func": "OwnerRequiredSkillModifier",
|
||||
"modifiedAttributeID": 654,
|
||||
"modifyingAttributeID": 743,
|
||||
"operation": 6,
|
||||
"skillTypeID": 3325
|
||||
}
|
||||
],
|
||||
"propulsionChance": 0,
|
||||
"published": 0,
|
||||
"rangeChance": 0
|
||||
},
|
||||
"12767": {
|
||||
"disallowAutoRepeat": 0,
|
||||
"effectCategory": 0,
|
||||
"effectID": 12767,
|
||||
"effectName": "tacticalBonusSkuaDefensiveShieldRechargeRate",
|
||||
"electronicChance": 0,
|
||||
"guid": "",
|
||||
"isAssistance": 0,
|
||||
"isOffensive": 0,
|
||||
"isWarpSafe": 0,
|
||||
"modifierInfo": [
|
||||
{
|
||||
"domain": "shipID",
|
||||
"func": "ItemModifier",
|
||||
"modifiedAttributeID": 479,
|
||||
"modifyingAttributeID": 6057,
|
||||
"operation": 5
|
||||
}
|
||||
],
|
||||
"propulsionChance": 0,
|
||||
"published": 0,
|
||||
"rangeChance": 0
|
||||
},
|
||||
"12771": {
|
||||
"disallowAutoRepeat": 0,
|
||||
"effectCategory": 0,
|
||||
"effectID": 12771,
|
||||
"effectName": "shipRoleBonusPerseveranceIceMiningCriticalHitChanceBonus",
|
||||
"electronicChance": 0,
|
||||
"isAssistance": 0,
|
||||
"isOffensive": 0,
|
||||
"isWarpSafe": 0,
|
||||
"modifierInfo": [
|
||||
{
|
||||
"domain": "shipID",
|
||||
"func": "LocationRequiredSkillModifier",
|
||||
"modifiedAttributeID": 5967,
|
||||
"modifyingAttributeID": 6062,
|
||||
"operation": 6,
|
||||
"skillTypeID": 16281
|
||||
}
|
||||
],
|
||||
"propulsionChance": 0,
|
||||
"published": 0,
|
||||
"rangeChance": 0
|
||||
},
|
||||
"12772": {
|
||||
"disallowAutoRepeat": 0,
|
||||
"effectCategory": 0,
|
||||
"effectID": 12772,
|
||||
"effectName": "shipIceMiningCriticalHitChanceBonusOreDestroyer1",
|
||||
"electronicChance": 0,
|
||||
"isAssistance": 0,
|
||||
"isOffensive": 0,
|
||||
"isWarpSafe": 0,
|
||||
"modifierInfo": [
|
||||
{
|
||||
"domain": "shipID",
|
||||
"func": "LocationRequiredSkillModifier",
|
||||
"modifiedAttributeID": 5967,
|
||||
"modifyingAttributeID": 5820,
|
||||
"operation": 6,
|
||||
"skillTypeID": 16281
|
||||
}
|
||||
],
|
||||
"propulsionChance": 0,
|
||||
"published": 0,
|
||||
"rangeChance": 0
|
||||
},
|
||||
"12773": {
|
||||
"disallowAutoRepeat": 0,
|
||||
"effectCategory": 0,
|
||||
"effectID": 12773,
|
||||
"effectName": "shipIceMiningCriticalHitYieldBonusOreDestroyer2",
|
||||
"electronicChance": 0,
|
||||
"isAssistance": 0,
|
||||
"isOffensive": 0,
|
||||
"isWarpSafe": 0,
|
||||
"modifierInfo": [
|
||||
{
|
||||
"domain": "shipID",
|
||||
"func": "LocationRequiredSkillModifier",
|
||||
"modifiedAttributeID": 5969,
|
||||
"modifyingAttributeID": 5821,
|
||||
"operation": 6,
|
||||
"skillTypeID": 16281
|
||||
}
|
||||
],
|
||||
"propulsionChance": 0,
|
||||
"published": 0,
|
||||
"rangeChance": 0
|
||||
},
|
||||
"12774": {
|
||||
"disallowAutoRepeat": 0,
|
||||
"effectCategory": 0,
|
||||
"effectID": 12774,
|
||||
"effectName": "shipIceMiningRangeBonusOreDestroyer3",
|
||||
"electronicChance": 0,
|
||||
"isAssistance": 0,
|
||||
"isOffensive": 0,
|
||||
"isWarpSafe": 0,
|
||||
"modifierInfo": [
|
||||
{
|
||||
"domain": "shipID",
|
||||
"func": "LocationRequiredSkillModifier",
|
||||
"modifiedAttributeID": 54,
|
||||
"modifyingAttributeID": 5822,
|
||||
"operation": 6,
|
||||
"skillTypeID": 16281
|
||||
}
|
||||
],
|
||||
"propulsionChance": 0,
|
||||
"published": 0,
|
||||
"rangeChance": 0
|
||||
},
|
||||
"12777": {
|
||||
"disallowAutoRepeat": 0,
|
||||
"effectCategory": 0,
|
||||
"effectID": 12777,
|
||||
"effectName": "roleBonusCDLinksPGCPUReductionSkua",
|
||||
"electronicChance": 0,
|
||||
"isAssistance": 0,
|
||||
"isOffensive": 0,
|
||||
"isWarpSafe": 0,
|
||||
"modifierInfo": [
|
||||
{
|
||||
"domain": "shipID",
|
||||
"func": "LocationRequiredSkillModifier",
|
||||
"modifiedAttributeID": 30,
|
||||
"modifyingAttributeID": 2064,
|
||||
"operation": 6,
|
||||
"skillTypeID": 3348
|
||||
},
|
||||
{
|
||||
"domain": "shipID",
|
||||
"func": "LocationRequiredSkillModifier",
|
||||
"modifiedAttributeID": 50,
|
||||
"modifyingAttributeID": 2064,
|
||||
"operation": 6,
|
||||
"skillTypeID": 3348
|
||||
}
|
||||
],
|
||||
"propulsionChance": 0,
|
||||
"published": 0,
|
||||
"rangeChance": 0
|
||||
},
|
||||
"12790": {
|
||||
"disallowAutoRepeat": 0,
|
||||
"effectCategory": 0,
|
||||
"effectID": 12790,
|
||||
"effectName": "shipBonusTorpedoAndCruiseMissileExplosionVelocityCBC2",
|
||||
"electronicChance": 0,
|
||||
"isAssistance": 0,
|
||||
"isOffensive": 0,
|
||||
"isWarpSafe": 0,
|
||||
"modifierInfo": [
|
||||
{
|
||||
"domain": "charID",
|
||||
"func": "OwnerRequiredSkillModifier",
|
||||
"modifiedAttributeID": 653,
|
||||
"modifyingAttributeID": 745,
|
||||
"operation": 6,
|
||||
"skillTypeID": 3325
|
||||
},
|
||||
{
|
||||
"domain": "charID",
|
||||
"func": "OwnerRequiredSkillModifier",
|
||||
"modifiedAttributeID": 653,
|
||||
"modifyingAttributeID": 745,
|
||||
"operation": 6,
|
||||
"skillTypeID": 3326
|
||||
}
|
||||
],
|
||||
"propulsionChance": 0,
|
||||
"published": 0,
|
||||
"rangeAttributeID": 54,
|
||||
"rangeChance": 0
|
||||
}
|
||||
}
|
||||
@@ -29731,7 +29731,7 @@
|
||||
"groupName_ja": "突入ポッドランチャー",
|
||||
"groupName_ko": "침투 포드 런처",
|
||||
"groupName_ru": "Пусковая установка внедряющихся капсул",
|
||||
"groupName_zh": "分裂者级逃生舱发射器",
|
||||
"groupName_zh": "突破者级逃生舱发射器",
|
||||
"groupNameID": 726805,
|
||||
"published": 1,
|
||||
"useBasePrice": 0
|
||||
@@ -29750,7 +29750,7 @@
|
||||
"groupName_ja": "突入ポッド「SCARAB」",
|
||||
"groupName_ko": "스캐럽 침투 포드",
|
||||
"groupName_ru": "Внедряющиеся капсулы «Скарабей»",
|
||||
"groupName_zh": "圣甲虫分裂者级逃生舱",
|
||||
"groupName_zh": "圣甲虫突破者级逃生舱",
|
||||
"groupNameID": 726814,
|
||||
"published": 1,
|
||||
"useBasePrice": 0
|
||||
@@ -30182,14 +30182,14 @@
|
||||
"categoryID": 2,
|
||||
"fittableNonSingleton": 0,
|
||||
"groupID": 4918,
|
||||
"groupName_de": "Phasenasteroiden",
|
||||
"groupName_en-us": "Phased Asteroids",
|
||||
"groupName_es": "Asteroides fásicos",
|
||||
"groupName_fr": "Astéroïdes phasiques",
|
||||
"groupName_it": "Phased Asteroids",
|
||||
"groupName_de": "Phasenasteroid",
|
||||
"groupName_en-us": "Phased Asteroid",
|
||||
"groupName_es": "Asteroide fásico",
|
||||
"groupName_fr": "Astéroïde phasique",
|
||||
"groupName_it": "Phased Asteroid",
|
||||
"groupName_ja": "位相偏移アステロイド",
|
||||
"groupName_ko": "위상 소행성",
|
||||
"groupName_ru": "Фазовые астероиды",
|
||||
"groupName_ru": "Фазовый астероид",
|
||||
"groupName_zh": "相位小行星",
|
||||
"groupNameID": 1019374,
|
||||
"published": 0,
|
||||
@@ -30366,6 +30366,63 @@
|
||||
"published": 0,
|
||||
"useBasePrice": 0
|
||||
},
|
||||
"4949": {
|
||||
"anchorable": 0,
|
||||
"anchored": 0,
|
||||
"categoryID": 11,
|
||||
"fittableNonSingleton": 0,
|
||||
"groupID": 4949,
|
||||
"groupName_de": "Interbus-Yoiul-LADs",
|
||||
"groupName_en-us": "InterBus Yoiul LADs",
|
||||
"groupName_es": "MAL de Yoiul de InterBus",
|
||||
"groupName_fr": "LUTINs de Yoiul d'InterBus",
|
||||
"groupName_it": "InterBus Yoiul LADs",
|
||||
"groupName_ja": "インターバス・ヨイウルLAD",
|
||||
"groupName_ko": "인터버스 요이얼 LAD",
|
||||
"groupName_ru": "Йольские ГАДы консорциума «ИнтерБас»",
|
||||
"groupName_zh": "星际捷运尤尔节自动化物流配送舰",
|
||||
"groupNameID": 1025585,
|
||||
"published": 0,
|
||||
"useBasePrice": 0
|
||||
},
|
||||
"4972": {
|
||||
"anchorable": 0,
|
||||
"anchored": 0,
|
||||
"categoryID": 17,
|
||||
"fittableNonSingleton": 0,
|
||||
"groupID": 4972,
|
||||
"groupName_de": "Verity-Kryo-Technologie",
|
||||
"groupName_en-us": "Verity Cryo Tech",
|
||||
"groupName_es": "Tecnología criogénica de Verity",
|
||||
"groupName_fr": "Cryotechnologie de Verity",
|
||||
"groupName_it": "Verity Cryo Tech",
|
||||
"groupName_ja": "ヴェリティ・クライオテック",
|
||||
"groupName_ko": "베리티 크라이오 장비",
|
||||
"groupName_ru": "Криотехнология «Подлинных улучшений»",
|
||||
"groupName_zh": "维里蒂低温技术",
|
||||
"groupNameID": 1028940,
|
||||
"published": 1,
|
||||
"useBasePrice": 1
|
||||
},
|
||||
"4975": {
|
||||
"anchorable": 0,
|
||||
"anchored": 0,
|
||||
"categoryID": 11,
|
||||
"fittableNonSingleton": 0,
|
||||
"groupID": 4975,
|
||||
"groupName_de": "Irregular Capital Industrial Ship",
|
||||
"groupName_en-us": "Irregular Capital Industrial Ship",
|
||||
"groupName_es": "Irregular Capital Industrial Ship",
|
||||
"groupName_fr": "Irregular Capital Industrial Ship",
|
||||
"groupName_it": "Irregular Capital Industrial Ship",
|
||||
"groupName_ja": "Irregular Capital Industrial Ship",
|
||||
"groupName_ko": "Irregular Capital Industrial Ship",
|
||||
"groupName_ru": "Irregular Capital Industrial Ship",
|
||||
"groupName_zh": "Irregular Capital Industrial Ship",
|
||||
"groupNameID": 1030693,
|
||||
"published": 0,
|
||||
"useBasePrice": 0
|
||||
},
|
||||
"350858": {
|
||||
"anchorable": 0,
|
||||
"anchored": 0,
|
||||
|
||||
@@ -14686,5 +14686,131 @@
|
||||
},
|
||||
"27266": {
|
||||
"iconFile": "res:/UI/Texture/Icons/Modules/fleetBoost_MiningCrit.png"
|
||||
},
|
||||
"27267": {
|
||||
"iconFile": "res:/UI/Texture/classes/Cosmetics/Ship/patterns/cosm_racial_ama_05_128.png"
|
||||
},
|
||||
"27268": {
|
||||
"iconFile": "res:/UI/Texture/classes/Cosmetics/Ship/patterns/cosm_racial_ama_05_128.png"
|
||||
},
|
||||
"27269": {
|
||||
"iconFile": "res:/UI/Texture/classes/Cosmetics/Ship/patterns/cosm_racial_ama_05_128.png"
|
||||
},
|
||||
"27270": {
|
||||
"iconFile": "res:/UI/Texture/classes/Cosmetics/Ship/patterns/cosm_ornament_01_128.png"
|
||||
},
|
||||
"27271": {
|
||||
"iconFile": "res:/UI/Texture/classes/Cosmetics/Ship/patterns/cosm_ornament_01_128.png"
|
||||
},
|
||||
"27272": {
|
||||
"iconFile": "res:/UI/Texture/classes/Cosmetics/Ship/patterns/cosm_art_deco_01_2K_128.png"
|
||||
},
|
||||
"27273": {
|
||||
"iconFile": "res:/UI/Texture/classes/Cosmetics/Ship/patterns/cosm_winter_10_128.png"
|
||||
},
|
||||
"27274": {
|
||||
"iconFile": "res:/UI/Texture/classes/Cosmetics/Ship/patterns/cosm_winter_10_128.png"
|
||||
},
|
||||
"27275": {
|
||||
"iconFile": "res:/UI/Texture/classes/Cosmetics/Ship/patterns/cosm_winter_08_128.png"
|
||||
},
|
||||
"27276": {
|
||||
"iconFile": "res:/UI/Texture/classes/Cosmetics/Ship/patterns/cosm_winter_08_128.png"
|
||||
},
|
||||
"27277": {
|
||||
"iconFile": "res:/UI/Texture/classes/Cosmetics/Ship/patterns/cosm_winter_05_128.png"
|
||||
},
|
||||
"27278": {
|
||||
"iconFile": "res:/UI/Texture/classes/Cosmetics/Ship/patterns/cosm_winter_05_128.png"
|
||||
},
|
||||
"27279": {
|
||||
"iconFile": "res:/UI/Texture/classes/Cosmetics/Ship/patterns/cosm_winter_16_128.png"
|
||||
},
|
||||
"27280": {
|
||||
"iconFile": "res:/UI/Texture/classes/Cosmetics/Ship/patterns/cosm_winter_16_128.png"
|
||||
},
|
||||
"27281": {
|
||||
"iconFile": "res:/UI/Texture/classes/Cosmetics/Ship/patterns/cosm_winter_12_128.png"
|
||||
},
|
||||
"27282": {
|
||||
"iconFile": "res:/UI/Texture/classes/Cosmetics/Ship/patterns/cosm_winter_12_128.png"
|
||||
},
|
||||
"27283": {
|
||||
"iconFile": "res:/UI/Texture/classes/Cosmetics/Ship/patterns/cosm_winter_07_128.png"
|
||||
},
|
||||
"27284": {
|
||||
"iconFile": "res:/UI/Texture/classes/Cosmetics/Ship/patterns/cosm_winter_07_128.png"
|
||||
},
|
||||
"27285": {
|
||||
"iconFile": "res:/UI/Texture/classes/Cosmetics/Ship/patterns/cosm_winter_11_128.png"
|
||||
},
|
||||
"27286": {
|
||||
"iconFile": "res:/UI/Texture/classes/Cosmetics/Ship/patterns/cosm_winter_11_128.png"
|
||||
},
|
||||
"27287": {
|
||||
"iconFile": "res:/UI/Texture/classes/Cosmetics/Ship/patterns/cosm_organic_10_128.png"
|
||||
},
|
||||
"27288": {
|
||||
"iconFile": "res:/UI/Texture/classes/Cosmetics/Ship/patterns/cosm_winter_09_128.png"
|
||||
},
|
||||
"27289": {
|
||||
"iconFile": "res:/UI/Texture/classes/Cosmetics/Ship/patterns/cosm_winter_06_128.png"
|
||||
},
|
||||
"27290": {
|
||||
"iconFile": "res:/UI/Texture/classes/Cosmetics/Ship/patterns/cosm_winter_14_128.png"
|
||||
},
|
||||
"27291": {
|
||||
"iconFile": "res:/UI/Texture/classes/Cosmetics/Ship/patterns/cosm_winter_14_128.png"
|
||||
},
|
||||
"27292": {
|
||||
"iconFile": "res:/UI/Texture/classes/Cosmetics/Ship/materials/cosm_turquoise_gloss_000_060_100_cs180.png"
|
||||
},
|
||||
"27293": {
|
||||
"iconFile": "res:/UI/Texture/classes/Cosmetics/Ship/materials/cosm_malachite_highgloss_000_100_010_cs180.png"
|
||||
},
|
||||
"27294": {
|
||||
"iconFile": "res:/UI/Texture/classes/Cosmetics/Ship/materials/cosm_orange_matt_000_100_010_cs180.png"
|
||||
},
|
||||
"27295": {
|
||||
"iconFile": "res:/UI/Texture/classes/Cosmetics/Ship/materials/cosm_emerald_brushed_000_060_100.png"
|
||||
},
|
||||
"27296": {
|
||||
"iconFile": "res:/UI/Texture/classes/Cosmetics/Ship/materials/cosm_emerald_brushed_000_060_100.png"
|
||||
},
|
||||
"27297": {
|
||||
"iconFile": "res:/UI/Texture/classes/Cosmetics/Ship/materials/cosm_royal_polished_000_080_100.png"
|
||||
},
|
||||
"27298": {
|
||||
"iconFile": "res:/UI/Texture/classes/Cosmetics/Ship/materials/cosm_royal_polished_000_080_100.png"
|
||||
},
|
||||
"27299": {
|
||||
"iconFile": "res:/UI/Texture/classes/Cosmetics/Ship/materials/cosm_emerald_polished_000_100_010.png"
|
||||
},
|
||||
"27300": {
|
||||
"iconFile": "res:/UI/Texture/classes/Cosmetics/Ship/materials/cosm_emerald_polished_000_100_010.png"
|
||||
},
|
||||
"27301": {
|
||||
"iconFile": "res:/UI/Texture/classes/Cosmetics/Ship/materials/cosm_azure_gloss_000_030_100.png"
|
||||
},
|
||||
"27302": {
|
||||
"iconFile": "res:/UI/Texture/classes/Cosmetics/Ship/materials/cosm_azure_gloss_000_030_100.png"
|
||||
},
|
||||
"27303": {
|
||||
"iconFile": "res:/UI/Texture/classes/Cosmetics/Ship/materials/cosm_azure_highgloss_000_100_001.png"
|
||||
},
|
||||
"27304": {
|
||||
"iconFile": "res:/UI/Texture/classes/Cosmetics/Ship/materials/cosm_azure_highgloss_000_100_001.png"
|
||||
},
|
||||
"27305": {
|
||||
"iconFile": "res:/UI/Texture/classes/Cosmetics/Ship/materials/cosm_rosered_satin_000_100_050.png"
|
||||
},
|
||||
"27306": {
|
||||
"iconFile": "res:/UI/Texture/classes/Cosmetics/Ship/materials/cosm_rosered_satin_000_100_050.png"
|
||||
},
|
||||
"27307": {
|
||||
"iconFile": "res:/UI/Texture/classes/Cosmetics/Ship/materials/cosm_royal_metallic_000_100_100.png"
|
||||
},
|
||||
"27309": {
|
||||
"iconFile": "res:/UI/Texture/classes/Cosmetics/Ship/materials/cosm_brass_metallic_013_051_089.png"
|
||||
}
|
||||
}
|
||||
@@ -45856,7 +45856,7 @@
|
||||
"name_ja": "突入ポッド",
|
||||
"name_ko": "침투 포드",
|
||||
"name_ru": "Внедряющиеся капсулы",
|
||||
"name_zh": "分裂者级逃生舱",
|
||||
"name_zh": "突破者级逃生舱",
|
||||
"nameID": 871476,
|
||||
"parentGroupID": 11
|
||||
},
|
||||
@@ -45881,7 +45881,7 @@
|
||||
"name_ja": "突入ポッドランチャー",
|
||||
"name_ko": "침투 포드 런처",
|
||||
"name_ru": "Пусковая установка внедряющихся капсул",
|
||||
"name_zh": "分裂者级逃生舱发射器",
|
||||
"name_zh": "突破者级逃生舱发射器",
|
||||
"nameID": 871478,
|
||||
"parentGroupID": 10
|
||||
},
|
||||
|
||||
@@ -11511,7 +11511,7 @@
|
||||
"17940": {
|
||||
"3380": 5,
|
||||
"3410": 3,
|
||||
"89241": 3
|
||||
"32918": 3
|
||||
},
|
||||
"17975": {
|
||||
"16281": 1
|
||||
@@ -30076,6 +30076,12 @@
|
||||
"3436": 1,
|
||||
"9955": 5
|
||||
},
|
||||
"89807": {
|
||||
"33096": 1
|
||||
},
|
||||
"89808": {
|
||||
"35680": 1
|
||||
},
|
||||
"90037": {
|
||||
"11584": 3
|
||||
},
|
||||
@@ -30249,8 +30255,86 @@
|
||||
"43703": 1,
|
||||
"60515": 1
|
||||
},
|
||||
"90665": {
|
||||
"3386": 1
|
||||
"90669": {
|
||||
"3405": 1
|
||||
},
|
||||
"90670": {
|
||||
"3405": 1
|
||||
},
|
||||
"90671": {
|
||||
"3405": 1
|
||||
},
|
||||
"90672": {
|
||||
"3405": 1
|
||||
},
|
||||
"90673": {
|
||||
"3405": 1
|
||||
},
|
||||
"90674": {
|
||||
"3405": 1
|
||||
},
|
||||
"90675": {
|
||||
"3405": 1
|
||||
},
|
||||
"90676": {
|
||||
"3405": 1
|
||||
},
|
||||
"90677": {
|
||||
"3405": 1
|
||||
},
|
||||
"90678": {
|
||||
"3405": 1
|
||||
},
|
||||
"90679": {
|
||||
"3405": 1
|
||||
},
|
||||
"90680": {
|
||||
"3405": 1
|
||||
},
|
||||
"90682": {
|
||||
"3405": 1
|
||||
},
|
||||
"90683": {
|
||||
"3405": 1
|
||||
},
|
||||
"90684": {
|
||||
"3405": 1
|
||||
},
|
||||
"90685": {
|
||||
"3405": 1
|
||||
},
|
||||
"90686": {
|
||||
"3405": 1
|
||||
},
|
||||
"90687": {
|
||||
"3405": 1
|
||||
},
|
||||
"90688": {
|
||||
"3405": 1
|
||||
},
|
||||
"90689": {
|
||||
"3405": 1
|
||||
},
|
||||
"90690": {
|
||||
"3405": 1
|
||||
},
|
||||
"90691": {
|
||||
"3405": 1
|
||||
},
|
||||
"90692": {
|
||||
"3405": 1
|
||||
},
|
||||
"90693": {
|
||||
"3405": 1
|
||||
},
|
||||
"90694": {
|
||||
"3402": 1
|
||||
},
|
||||
"90695": {
|
||||
"3402": 1
|
||||
},
|
||||
"90696": {
|
||||
"3402": 1
|
||||
},
|
||||
"90727": {
|
||||
"3386": 3
|
||||
@@ -30263,5 +30347,18 @@
|
||||
"90733": {
|
||||
"3348": 1,
|
||||
"22536": 1
|
||||
},
|
||||
"91044": {
|
||||
"21718": 1
|
||||
},
|
||||
"91045": {
|
||||
"21718": 1
|
||||
},
|
||||
"91046": {
|
||||
"21718": 1
|
||||
},
|
||||
"91174": {
|
||||
"16281": 1,
|
||||
"89241": 2
|
||||
}
|
||||
}
|
||||
@@ -827996,7 +827996,7 @@
|
||||
},
|
||||
{
|
||||
"attributeID": 184,
|
||||
"value": 89241.0
|
||||
"value": 32918.0
|
||||
},
|
||||
{
|
||||
"attributeID": 275,
|
||||
|
||||
@@ -878783,6 +878783,10 @@
|
||||
"attributeID": 1298,
|
||||
"value": 1283.0
|
||||
},
|
||||
{
|
||||
"attributeID": 1302,
|
||||
"value": 91174.0
|
||||
},
|
||||
{
|
||||
"attributeID": 1768,
|
||||
"value": 11346.0
|
||||
@@ -878873,6 +878877,10 @@
|
||||
"attributeID": 1298,
|
||||
"value": 1283.0
|
||||
},
|
||||
{
|
||||
"attributeID": 1302,
|
||||
"value": 91174.0
|
||||
},
|
||||
{
|
||||
"attributeID": 1768,
|
||||
"value": 11346.0
|
||||
@@ -878963,6 +878971,10 @@
|
||||
"attributeID": 1298,
|
||||
"value": 1283.0
|
||||
},
|
||||
{
|
||||
"attributeID": 1302,
|
||||
"value": 91174.0
|
||||
},
|
||||
{
|
||||
"attributeID": 1692,
|
||||
"value": 4.0
|
||||
@@ -886541,6 +886553,10 @@
|
||||
"attributeID": 1299,
|
||||
"value": 1534.0
|
||||
},
|
||||
{
|
||||
"attributeID": 1303,
|
||||
"value": 89808.0
|
||||
},
|
||||
{
|
||||
"attributeID": 1544,
|
||||
"value": 1.0
|
||||
@@ -958018,6 +958034,10 @@
|
||||
"attributeID": 1301,
|
||||
"value": 540.0
|
||||
},
|
||||
{
|
||||
"attributeID": 1302,
|
||||
"value": 89808.0
|
||||
},
|
||||
{
|
||||
"attributeID": 1795,
|
||||
"value": 60000.0
|
||||
@@ -958188,6 +958208,10 @@
|
||||
"attributeID": 1301,
|
||||
"value": 540.0
|
||||
},
|
||||
{
|
||||
"attributeID": 1302,
|
||||
"value": 89808.0
|
||||
},
|
||||
{
|
||||
"attributeID": 1795,
|
||||
"value": 60000.0
|
||||
@@ -958528,6 +958552,10 @@
|
||||
"attributeID": 1301,
|
||||
"value": 540.0
|
||||
},
|
||||
{
|
||||
"attributeID": 1302,
|
||||
"value": 89808.0
|
||||
},
|
||||
{
|
||||
"attributeID": 1795,
|
||||
"value": 60000.0
|
||||
@@ -958698,6 +958726,10 @@
|
||||
"attributeID": 1301,
|
||||
"value": 540.0
|
||||
},
|
||||
{
|
||||
"attributeID": 1302,
|
||||
"value": 89808.0
|
||||
},
|
||||
{
|
||||
"attributeID": 1795,
|
||||
"value": 60000.0
|
||||
@@ -970503,6 +970535,10 @@
|
||||
"attributeID": 1301,
|
||||
"value": 540.0
|
||||
},
|
||||
{
|
||||
"attributeID": 1302,
|
||||
"value": 89808.0
|
||||
},
|
||||
{
|
||||
"attributeID": 1795,
|
||||
"value": 60000.0
|
||||
@@ -970685,6 +970721,10 @@
|
||||
"attributeID": 1301,
|
||||
"value": 540.0
|
||||
},
|
||||
{
|
||||
"attributeID": 1302,
|
||||
"value": 89808.0
|
||||
},
|
||||
{
|
||||
"attributeID": 1795,
|
||||
"value": 60000.0
|
||||
@@ -970867,6 +970907,10 @@
|
||||
"attributeID": 1301,
|
||||
"value": 540.0
|
||||
},
|
||||
{
|
||||
"attributeID": 1303,
|
||||
"value": 89808.0
|
||||
},
|
||||
{
|
||||
"attributeID": 1795,
|
||||
"value": 60000.0
|
||||
@@ -971049,6 +971093,10 @@
|
||||
"attributeID": 1301,
|
||||
"value": 540.0
|
||||
},
|
||||
{
|
||||
"attributeID": 1302,
|
||||
"value": 89808.0
|
||||
},
|
||||
{
|
||||
"attributeID": 1795,
|
||||
"value": 60000.0
|
||||
|
||||
@@ -168393,7 +168393,7 @@
|
||||
"wreckTypeID": 41699
|
||||
},
|
||||
"42125": {
|
||||
"basePrice": 119829000000.0,
|
||||
"basePrice": 20000000000.0,
|
||||
"capacity": 1750.0,
|
||||
"certificateTemplate": 86,
|
||||
"description_de": "<i>\"Die Föderation glaubt immer noch, sie könne mit der Zukunft der Menschen ihre Spiele treiben. So, wie sie auch mit dem Lebenswerk meines Vaters gespielt hat.\n\n\n\nIch werde ihnen zeigen, wie man dieses Spiel richtig spielt. Sie haben einen Mann zerstört, der die Wissenschaft und Anwendung von Neuralboostern revolutioniert hätte.\n\n\n\nIch werde sie zerstören, indem ich ihnen zeige, wie mächtig diese Wissenschaft sein kann. Es wird keinen Frieden, kein Erbarmen geben. Ich schwöre Rache, im Namen und in Erinnerung Igil Sarpatis.\"</i>\n\n\n\n- V. Salvador Sarpati, im Interview mit Alton Haveri von Scope",
|
||||
@@ -168442,7 +168442,7 @@
|
||||
"wreckTypeID": 72817
|
||||
},
|
||||
"42126": {
|
||||
"basePrice": 672620000000.0,
|
||||
"basePrice": 60000000000.0,
|
||||
"capacity": 18000.0,
|
||||
"certificateTemplate": 244,
|
||||
"description_de": "<i>\"Die Kaperung der Molyneux hat mir gezeigt, dass Kapselpiloten herausragende Dinge leisten können, wenn sie Blut gerochen haben. Eine Zeit lang war ich mir nicht sicher, ob wir entkommen würden.\n\n\n\nNicht wegen der Regierungspolizei. Nein, die waren der reinste Witz. Aber die Kapselpiloten hätten mich fast erwischt. Das Witzige an der Sache ist, dass sie einander fast so erbittert bekämpft haben, wie sie versuchten mich zu fassen.\n\n\n\nEinige haben wir sogar geholfen. Wissen Sie, der Pfad der Zerstörung, den wir hinterlassen haben, ging fast ausschließlich auf sie zurück. Ich denke, es wäre sicher amüsant, ihnen ein paar mehr Spielzeuge zu geben, Sie nicht?\"</i>\n\n\n\n- V. Salvador Sarpati, im Interview mit Alton Haveri von Scope",
|
||||
@@ -171548,7 +171548,7 @@
|
||||
"volume": 1.0
|
||||
},
|
||||
"42241": {
|
||||
"basePrice": 253642000000.0,
|
||||
"basePrice": 60000000000.0,
|
||||
"capacity": 12400.0,
|
||||
"certificateTemplate": 249,
|
||||
"description_de": "<i>\"Molok, vom falschen Glauben als 'Der Täuscher' verhöhnt, war wahrhaftiger als jeder der sogenannten 'Echten Amarr', die den korrupten Thronbeschmutzern Gefolgschaft leisteten, es sich je erhoffen konnte. Er war es, der die wahre Natur des Universums begriffen hatte. Es gibt nur eine Wahrheit: Macht ist alles; die nackte, gnadenlose Kraft in der Hand jener, die den Willen haben, nach ihr zu greifen. Wir trinken das Blut der Mächtigen und der Reinen, denn um zu überleben und fortzuschreiten, müssen wir uns an ihrer Energie laben und sie unser eigen machen. Das ist die Lektion von Molok. Sein Scheitern ist nicht von Belang, seine Erkenntnis der großen Wahrheit ist alles, was zählt.\"</i>\n\n\n\n- Omir Sarikusa, Meditationen des Blutroten Kelchs",
|
||||
@@ -178117,6 +178117,7 @@
|
||||
"descriptionID": 522185,
|
||||
"groupID": 1770,
|
||||
"iconID": 21687,
|
||||
"isDynamicType": 0,
|
||||
"marketGroupID": 1633,
|
||||
"mass": 0.0,
|
||||
"metaGroupID": 1,
|
||||
@@ -178153,6 +178154,7 @@
|
||||
"descriptionID": 522191,
|
||||
"groupID": 1770,
|
||||
"iconID": 21691,
|
||||
"isDynamicType": 0,
|
||||
"marketGroupID": 1633,
|
||||
"mass": 0.0,
|
||||
"metaGroupID": 1,
|
||||
@@ -178225,6 +178227,7 @@
|
||||
"descriptionID": 522212,
|
||||
"groupID": 1770,
|
||||
"iconID": 21700,
|
||||
"isDynamicType": 0,
|
||||
"marketGroupID": 1633,
|
||||
"mass": 0.0,
|
||||
"metaGroupID": 1,
|
||||
@@ -178261,6 +178264,7 @@
|
||||
"descriptionID": 522216,
|
||||
"groupID": 1770,
|
||||
"iconID": 21704,
|
||||
"isDynamicType": 0,
|
||||
"marketGroupID": 1633,
|
||||
"mass": 0.0,
|
||||
"metaGroupID": 1,
|
||||
@@ -199677,6 +199681,7 @@
|
||||
"descriptionID": 522187,
|
||||
"groupID": 1770,
|
||||
"iconID": 21687,
|
||||
"isDynamicType": 0,
|
||||
"marketGroupID": 1633,
|
||||
"mass": 0.0,
|
||||
"metaGroupID": 2,
|
||||
@@ -199714,6 +199719,7 @@
|
||||
"descriptionID": 522194,
|
||||
"groupID": 1770,
|
||||
"iconID": 21691,
|
||||
"isDynamicType": 0,
|
||||
"marketGroupID": 1633,
|
||||
"mass": 0.0,
|
||||
"metaGroupID": 2,
|
||||
@@ -199751,6 +199757,7 @@
|
||||
"descriptionID": 522214,
|
||||
"groupID": 1770,
|
||||
"iconID": 21700,
|
||||
"isDynamicType": 0,
|
||||
"marketGroupID": 1633,
|
||||
"mass": 0.0,
|
||||
"metaGroupID": 2,
|
||||
@@ -199788,6 +199795,7 @@
|
||||
"descriptionID": 522226,
|
||||
"groupID": 1770,
|
||||
"iconID": 21704,
|
||||
"isDynamicType": 0,
|
||||
"marketGroupID": 1633,
|
||||
"mass": 0.0,
|
||||
"metaGroupID": 2,
|
||||
@@ -238958,7 +238966,7 @@
|
||||
"volume": 0.01
|
||||
},
|
||||
"45649": {
|
||||
"basePrice": 254538000000.0,
|
||||
"basePrice": 60000000000.0,
|
||||
"capacity": 13750.0,
|
||||
"certificateTemplate": 247,
|
||||
"description_de": "„Wir sind also die Neunte Megacorporation. Wir sind es schon lange Zeit und wir sind ein wichtiger Teil der ganzen Masche. Der Staat der Caldari wurde damals schal und unflexibel, mit all diesem „Heiian“-Bockmist. Glaubt irgendwer, dass sich die Großen Acht auch nur einen Fedofurz darum scheren? Das ist Holoreel-Mindflood. Nur für die Trottel. Die Proleten, die nur Ausreden suchen, den Großen Mega-Daddys nicht im Wege zu stehen. Und die Kapselpiloten, die „Ehre sei dem Staat“ kleffen. Sie sind die allerschlimmsten. All diese Macht und sie verbeugen sich vor Mami Staat und Daddy Mega. Das macht mich krank.\n\n\n\n„Was? Achso, die Neunte Mega. Was ich meine? Also, die Großen Acht, ja? Sie teilen den Staat unter sich auf. Sie stecken die Köpfe zusammen, bestimmen wer was kriegt, und geben dem Ganzen einen netten Anstrich mit ein bisschen Wettbewerb hier und ein wenig Krieg da. Das ist alles nur Theater. Sie sind vertikal integrierte Megacorporations, die komplette Sektoren der Wirtschaft beherrschen, weil sie sich alle an denselben Plan halten. Wir aber sind der Anti-Plan. Wir sind die neunte Mega, weil sich schließlich ja auch jemand um die Kriminalität kümmern muss, oder? Das sind wir: die Megacorporation des Verbrechens!“ \n\n\n\n– Korako „The Rabbit“ Kosakami, Interview mit Ret Gloriaxx von der Sendung „Scopes Galaktische Stunde“",
|
||||
|
||||
@@ -697,6 +697,10 @@
|
||||
{
|
||||
"level": 3,
|
||||
"typeID": 90727
|
||||
},
|
||||
{
|
||||
"level": 2,
|
||||
"typeID": 91017
|
||||
}
|
||||
]
|
||||
},
|
||||
@@ -1398,6 +1402,10 @@
|
||||
{
|
||||
"level": 3,
|
||||
"typeID": 90727
|
||||
},
|
||||
{
|
||||
"level": 2,
|
||||
"typeID": 91017
|
||||
}
|
||||
]
|
||||
},
|
||||
@@ -2099,6 +2107,10 @@
|
||||
{
|
||||
"level": 3,
|
||||
"typeID": 90727
|
||||
},
|
||||
{
|
||||
"level": 2,
|
||||
"typeID": 91017
|
||||
}
|
||||
]
|
||||
},
|
||||
@@ -2800,6 +2812,10 @@
|
||||
{
|
||||
"level": 3,
|
||||
"typeID": 90727
|
||||
},
|
||||
{
|
||||
"level": 2,
|
||||
"typeID": 91017
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
@@ -70,7 +70,7 @@
|
||||
"displayNameID": 517442,
|
||||
"itemModifiers": [
|
||||
{
|
||||
"dogmaAttributeID": 37
|
||||
"dogmaAttributeID": 3171
|
||||
}
|
||||
],
|
||||
"locationGroupModifiers": [],
|
||||
@@ -5261,5 +5261,135 @@
|
||||
],
|
||||
"operationName": "PostPercent",
|
||||
"showOutputValueInUI": "ShowNormal"
|
||||
},
|
||||
"2518": {
|
||||
"aggregateMode": "Minimum",
|
||||
"developerDescription": "Sisters of EVE Metaliminal Storm Bonus 5 - Winter Nexus Storm",
|
||||
"displayName_de": "Thermalresistenz-Bonus (unbeständiger Eissturm)",
|
||||
"displayName_en-us": "Thermal Resistance Bonus (Volatile Ice Storm)",
|
||||
"displayName_es": "Bonificación de resistencia térmica (tormenta de hielo volátil)",
|
||||
"displayName_fr": "Bonus de résistance thermique (tempête de glace volatile)",
|
||||
"displayName_it": "Thermal Resistance Bonus (Volatile Ice Storm)",
|
||||
"displayName_ja": "サーマルレジスタンスボーナス(揮発性アイスストーム)",
|
||||
"displayName_ko": "열 저항력 보너스(불안정한 얼음 폭풍)",
|
||||
"displayName_ru": "Бонус к сопротивляемости термальному урону (нестабильная ледяная буря)",
|
||||
"displayName_zh": "热能抗性加成(不稳定冰风暴)",
|
||||
"displayNameID": 1030721,
|
||||
"itemModifiers": [
|
||||
{
|
||||
"dogmaAttributeID": 110
|
||||
},
|
||||
{
|
||||
"dogmaAttributeID": 270
|
||||
},
|
||||
{
|
||||
"dogmaAttributeID": 274
|
||||
}
|
||||
],
|
||||
"locationGroupModifiers": [],
|
||||
"locationModifiers": [],
|
||||
"locationRequiredSkillModifiers": [],
|
||||
"operationName": "PostPercent",
|
||||
"showOutputValueInUI": "ShowInverted"
|
||||
},
|
||||
"2519": {
|
||||
"aggregateMode": "Maximum",
|
||||
"developerDescription": "Sisters of EVE Landmark Bonus 21",
|
||||
"itemModifiers": [],
|
||||
"locationGroupModifiers": [],
|
||||
"locationModifiers": [],
|
||||
"locationRequiredSkillModifiers": [],
|
||||
"operationName": "PreAssignment",
|
||||
"showOutputValueInUI": "ShowNormal"
|
||||
},
|
||||
"2520": {
|
||||
"aggregateMode": "Maximum",
|
||||
"developerDescription": "Sisters of EVE Landmark Bonus 22",
|
||||
"itemModifiers": [],
|
||||
"locationGroupModifiers": [],
|
||||
"locationModifiers": [],
|
||||
"locationRequiredSkillModifiers": [],
|
||||
"operationName": "PreAssignment",
|
||||
"showOutputValueInUI": "ShowNormal"
|
||||
},
|
||||
"2521": {
|
||||
"aggregateMode": "Maximum",
|
||||
"developerDescription": "Sisters of EVE Landmark Bonus 23",
|
||||
"itemModifiers": [],
|
||||
"locationGroupModifiers": [],
|
||||
"locationModifiers": [],
|
||||
"locationRequiredSkillModifiers": [],
|
||||
"operationName": "PreAssignment",
|
||||
"showOutputValueInUI": "ShowNormal"
|
||||
},
|
||||
"2522": {
|
||||
"aggregateMode": "Maximum",
|
||||
"developerDescription": "Sisters of EVE Landmark Bonus 24",
|
||||
"itemModifiers": [],
|
||||
"locationGroupModifiers": [],
|
||||
"locationModifiers": [],
|
||||
"locationRequiredSkillModifiers": [],
|
||||
"operationName": "PreAssignment",
|
||||
"showOutputValueInUI": "ShowNormal"
|
||||
},
|
||||
"2523": {
|
||||
"aggregateMode": "Maximum",
|
||||
"developerDescription": "Sisters of EVE Landmark Bonus 25",
|
||||
"itemModifiers": [],
|
||||
"locationGroupModifiers": [],
|
||||
"locationModifiers": [],
|
||||
"locationRequiredSkillModifiers": [],
|
||||
"operationName": "PreAssignment",
|
||||
"showOutputValueInUI": "ShowNormal"
|
||||
},
|
||||
"2524": {
|
||||
"aggregateMode": "Maximum",
|
||||
"developerDescription": "Sisters of EVE Landmark Bonus 27",
|
||||
"itemModifiers": [],
|
||||
"locationGroupModifiers": [],
|
||||
"locationModifiers": [],
|
||||
"locationRequiredSkillModifiers": [],
|
||||
"operationName": "PreAssignment",
|
||||
"showOutputValueInUI": "ShowNormal"
|
||||
},
|
||||
"2525": {
|
||||
"aggregateMode": "Maximum",
|
||||
"developerDescription": "Sisters of EVE Landmark Bonus 28",
|
||||
"itemModifiers": [],
|
||||
"locationGroupModifiers": [],
|
||||
"locationModifiers": [],
|
||||
"locationRequiredSkillModifiers": [],
|
||||
"operationName": "PreAssignment",
|
||||
"showOutputValueInUI": "ShowNormal"
|
||||
},
|
||||
"2526": {
|
||||
"aggregateMode": "Maximum",
|
||||
"developerDescription": "Sisters of EVE Landmark Bonus 26",
|
||||
"itemModifiers": [],
|
||||
"locationGroupModifiers": [],
|
||||
"locationModifiers": [],
|
||||
"locationRequiredSkillModifiers": [],
|
||||
"operationName": "PreAssignment",
|
||||
"showOutputValueInUI": "ShowNormal"
|
||||
},
|
||||
"2527": {
|
||||
"aggregateMode": "Maximum",
|
||||
"developerDescription": "Sisters of EVE Landmark Bonus 29",
|
||||
"itemModifiers": [],
|
||||
"locationGroupModifiers": [],
|
||||
"locationModifiers": [],
|
||||
"locationRequiredSkillModifiers": [],
|
||||
"operationName": "PreAssignment",
|
||||
"showOutputValueInUI": "ShowNormal"
|
||||
},
|
||||
"2528": {
|
||||
"aggregateMode": "Maximum",
|
||||
"developerDescription": "Sisters of EVE Landmark Bonus 30",
|
||||
"itemModifiers": [],
|
||||
"locationGroupModifiers": [],
|
||||
"locationModifiers": [],
|
||||
"locationRequiredSkillModifiers": [],
|
||||
"operationName": "PreAssignment",
|
||||
"showOutputValueInUI": "ShowNormal"
|
||||
}
|
||||
}
|
||||
@@ -1,10 +1,10 @@
|
||||
[
|
||||
{
|
||||
"field_name": "client_build",
|
||||
"field_value": 3103065
|
||||
"field_value": 3137986
|
||||
},
|
||||
{
|
||||
"field_name": "dump_time",
|
||||
"field_value": 1763465723
|
||||
"field_value": 1765458681
|
||||
}
|
||||
]
|
||||
863
uv.lock
generated
Normal file
@@ -0,0 +1,863 @@
|
||||
version = 1
|
||||
revision = 3
|
||||
requires-python = ">=3.12"
|
||||
|
||||
[[package]]
|
||||
name = "attrs"
|
||||
version = "25.4.0"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/6b/5c/685e6633917e101e5dcb62b9dd76946cbb57c26e133bae9e0cd36033c0a9/attrs-25.4.0.tar.gz", hash = "sha256:16d5969b87f0859ef33a48b35d55ac1be6e42ae49d5e853b597db70c35c57e11", size = 934251, upload-time = "2025-10-06T13:54:44.725Z" }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/3a/2a/7cc015f5b9f5db42b7d48157e23356022889fc354a2813c15934b7cb5c0e/attrs-25.4.0-py3-none-any.whl", hash = "sha256:adcf7e2a1fb3b36ac48d97835bb6d8ade15b8dcce26aba8bf1d14847b57a3373", size = 67615, upload-time = "2025-10-06T13:54:43.17Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "beautifulsoup4"
|
||||
version = "4.12.2"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
dependencies = [
|
||||
{ name = "soupsieve" },
|
||||
]
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/af/0b/44c39cf3b18a9280950ad63a579ce395dda4c32193ee9da7ff0aed547094/beautifulsoup4-4.12.2.tar.gz", hash = "sha256:492bbc69dca35d12daac71c4db1bfff0c876c00ef4a2ffacce226d4638eb72da", size = 505113, upload-time = "2023-04-07T15:02:49.038Z" }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/57/f4/a69c20ee4f660081a7dedb1ac57f29be9378e04edfcb90c526b923d4bebc/beautifulsoup4-4.12.2-py3-none-any.whl", hash = "sha256:bd2520ca0d9d7d12694a53d44ac482d181b4ec1888909b035a3dbf40d0f57d4a", size = 142979, upload-time = "2023-04-07T15:02:50.77Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cattrs"
|
||||
version = "25.3.0"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
dependencies = [
|
||||
{ name = "attrs" },
|
||||
{ name = "typing-extensions" },
|
||||
]
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/6e/00/2432bb2d445b39b5407f0a90e01b9a271475eea7caf913d7a86bcb956385/cattrs-25.3.0.tar.gz", hash = "sha256:1ac88d9e5eda10436c4517e390a4142d88638fe682c436c93db7ce4a277b884a", size = 509321, upload-time = "2025-10-07T12:26:08.737Z" }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/d8/2b/a40e1488fdfa02d3f9a653a61a5935ea08b3c2225ee818db6a76c7ba9695/cattrs-25.3.0-py3-none-any.whl", hash = "sha256:9896e84e0a5bf723bc7b4b68f4481785367ce07a8a02e7e9ee6eb2819bc306ff", size = 70738, upload-time = "2025-10-07T12:26:06.603Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "certifi"
|
||||
version = "2025.11.12"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/a2/8c/58f469717fa48465e4a50c014a0400602d3c437d7c0c468e17ada824da3a/certifi-2025.11.12.tar.gz", hash = "sha256:d8ab5478f2ecd78af242878415affce761ca6bc54a22a27e026d7c25357c3316", size = 160538, upload-time = "2025-11-12T02:54:51.517Z" }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/70/7d/9bc192684cea499815ff478dfcdc13835ddf401365057044fb721ec6bddb/certifi-2025.11.12-py3-none-any.whl", hash = "sha256:97de8790030bbd5c2d96b7ec782fc2f7820ef8dba6db909ccf95449f2d062d4b", size = 159438, upload-time = "2025-11-12T02:54:49.735Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cffi"
|
||||
version = "2.0.0"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
dependencies = [
|
||||
{ name = "pycparser", marker = "implementation_name != 'PyPy'" },
|
||||
]
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/eb/56/b1ba7935a17738ae8453301356628e8147c79dbb825bcbc73dc7401f9846/cffi-2.0.0.tar.gz", hash = "sha256:44d1b5909021139fe36001ae048dbdde8214afa20200eda0f64c068cac5d5529", size = 523588, upload-time = "2025-09-08T23:24:04.541Z" }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/ea/47/4f61023ea636104d4f16ab488e268b93008c3d0bb76893b1b31db1f96802/cffi-2.0.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:6d02d6655b0e54f54c4ef0b94eb6be0607b70853c45ce98bd278dc7de718be5d", size = 185271, upload-time = "2025-09-08T23:22:44.795Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/df/a2/781b623f57358e360d62cdd7a8c681f074a71d445418a776eef0aadb4ab4/cffi-2.0.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:8eca2a813c1cb7ad4fb74d368c2ffbbb4789d377ee5bb8df98373c2cc0dee76c", size = 181048, upload-time = "2025-09-08T23:22:45.938Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/ff/df/a4f0fbd47331ceeba3d37c2e51e9dfc9722498becbeec2bd8bc856c9538a/cffi-2.0.0-cp312-cp312-manylinux1_i686.manylinux2014_i686.manylinux_2_17_i686.manylinux_2_5_i686.whl", hash = "sha256:21d1152871b019407d8ac3985f6775c079416c282e431a4da6afe7aefd2bccbe", size = 212529, upload-time = "2025-09-08T23:22:47.349Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/d5/72/12b5f8d3865bf0f87cf1404d8c374e7487dcf097a1c91c436e72e6badd83/cffi-2.0.0-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:b21e08af67b8a103c71a250401c78d5e0893beff75e28c53c98f4de42f774062", size = 220097, upload-time = "2025-09-08T23:22:48.677Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/c2/95/7a135d52a50dfa7c882ab0ac17e8dc11cec9d55d2c18dda414c051c5e69e/cffi-2.0.0-cp312-cp312-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:1e3a615586f05fc4065a8b22b8152f0c1b00cdbc60596d187c2a74f9e3036e4e", size = 207983, upload-time = "2025-09-08T23:22:50.06Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/3a/c8/15cb9ada8895957ea171c62dc78ff3e99159ee7adb13c0123c001a2546c1/cffi-2.0.0-cp312-cp312-manylinux2014_s390x.manylinux_2_17_s390x.whl", hash = "sha256:81afed14892743bbe14dacb9e36d9e0e504cd204e0b165062c488942b9718037", size = 206519, upload-time = "2025-09-08T23:22:51.364Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/78/2d/7fa73dfa841b5ac06c7b8855cfc18622132e365f5b81d02230333ff26e9e/cffi-2.0.0-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:3e17ed538242334bf70832644a32a7aae3d83b57567f9fd60a26257e992b79ba", size = 219572, upload-time = "2025-09-08T23:22:52.902Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/07/e0/267e57e387b4ca276b90f0434ff88b2c2241ad72b16d31836adddfd6031b/cffi-2.0.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:3925dd22fa2b7699ed2617149842d2e6adde22b262fcbfada50e3d195e4b3a94", size = 222963, upload-time = "2025-09-08T23:22:54.518Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/b6/75/1f2747525e06f53efbd878f4d03bac5b859cbc11c633d0fb81432d98a795/cffi-2.0.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:2c8f814d84194c9ea681642fd164267891702542f028a15fc97d4674b6206187", size = 221361, upload-time = "2025-09-08T23:22:55.867Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/7b/2b/2b6435f76bfeb6bbf055596976da087377ede68df465419d192acf00c437/cffi-2.0.0-cp312-cp312-win32.whl", hash = "sha256:da902562c3e9c550df360bfa53c035b2f241fed6d9aef119048073680ace4a18", size = 172932, upload-time = "2025-09-08T23:22:57.188Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/f8/ed/13bd4418627013bec4ed6e54283b1959cf6db888048c7cf4b4c3b5b36002/cffi-2.0.0-cp312-cp312-win_amd64.whl", hash = "sha256:da68248800ad6320861f129cd9c1bf96ca849a2771a59e0344e88681905916f5", size = 183557, upload-time = "2025-09-08T23:22:58.351Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/95/31/9f7f93ad2f8eff1dbc1c3656d7ca5bfd8fb52c9d786b4dcf19b2d02217fa/cffi-2.0.0-cp312-cp312-win_arm64.whl", hash = "sha256:4671d9dd5ec934cb9a73e7ee9676f9362aba54f7f34910956b84d727b0d73fb6", size = 177762, upload-time = "2025-09-08T23:22:59.668Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/4b/8d/a0a47a0c9e413a658623d014e91e74a50cdd2c423f7ccfd44086ef767f90/cffi-2.0.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:00bdf7acc5f795150faa6957054fbbca2439db2f775ce831222b66f192f03beb", size = 185230, upload-time = "2025-09-08T23:23:00.879Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/4a/d2/a6c0296814556c68ee32009d9c2ad4f85f2707cdecfd7727951ec228005d/cffi-2.0.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:45d5e886156860dc35862657e1494b9bae8dfa63bf56796f2fb56e1679fc0bca", size = 181043, upload-time = "2025-09-08T23:23:02.231Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/b0/1e/d22cc63332bd59b06481ceaac49d6c507598642e2230f201649058a7e704/cffi-2.0.0-cp313-cp313-manylinux1_i686.manylinux2014_i686.manylinux_2_17_i686.manylinux_2_5_i686.whl", hash = "sha256:07b271772c100085dd28b74fa0cd81c8fb1a3ba18b21e03d7c27f3436a10606b", size = 212446, upload-time = "2025-09-08T23:23:03.472Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/a9/f5/a2c23eb03b61a0b8747f211eb716446c826ad66818ddc7810cc2cc19b3f2/cffi-2.0.0-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:d48a880098c96020b02d5a1f7d9251308510ce8858940e6fa99ece33f610838b", size = 220101, upload-time = "2025-09-08T23:23:04.792Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/f2/7f/e6647792fc5850d634695bc0e6ab4111ae88e89981d35ac269956605feba/cffi-2.0.0-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:f93fd8e5c8c0a4aa1f424d6173f14a892044054871c771f8566e4008eaa359d2", size = 207948, upload-time = "2025-09-08T23:23:06.127Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/cb/1e/a5a1bd6f1fb30f22573f76533de12a00bf274abcdc55c8edab639078abb6/cffi-2.0.0-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.whl", hash = "sha256:dd4f05f54a52fb558f1ba9f528228066954fee3ebe629fc1660d874d040ae5a3", size = 206422, upload-time = "2025-09-08T23:23:07.753Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/98/df/0a1755e750013a2081e863e7cd37e0cdd02664372c754e5560099eb7aa44/cffi-2.0.0-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:c8d3b5532fc71b7a77c09192b4a5a200ea992702734a2e9279a37f2478236f26", size = 219499, upload-time = "2025-09-08T23:23:09.648Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/50/e1/a969e687fcf9ea58e6e2a928ad5e2dd88cc12f6f0ab477e9971f2309b57c/cffi-2.0.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:d9b29c1f0ae438d5ee9acb31cadee00a58c46cc9c0b2f9038c6b0b3470877a8c", size = 222928, upload-time = "2025-09-08T23:23:10.928Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/36/54/0362578dd2c9e557a28ac77698ed67323ed5b9775ca9d3fe73fe191bb5d8/cffi-2.0.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:6d50360be4546678fc1b79ffe7a66265e28667840010348dd69a314145807a1b", size = 221302, upload-time = "2025-09-08T23:23:12.42Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/eb/6d/bf9bda840d5f1dfdbf0feca87fbdb64a918a69bca42cfa0ba7b137c48cb8/cffi-2.0.0-cp313-cp313-win32.whl", hash = "sha256:74a03b9698e198d47562765773b4a8309919089150a0bb17d829ad7b44b60d27", size = 172909, upload-time = "2025-09-08T23:23:14.32Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/37/18/6519e1ee6f5a1e579e04b9ddb6f1676c17368a7aba48299c3759bbc3c8b3/cffi-2.0.0-cp313-cp313-win_amd64.whl", hash = "sha256:19f705ada2530c1167abacb171925dd886168931e0a7b78f5bffcae5c6b5be75", size = 183402, upload-time = "2025-09-08T23:23:15.535Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/cb/0e/02ceeec9a7d6ee63bb596121c2c8e9b3a9e150936f4fbef6ca1943e6137c/cffi-2.0.0-cp313-cp313-win_arm64.whl", hash = "sha256:256f80b80ca3853f90c21b23ee78cd008713787b1b1e93eae9f3d6a7134abd91", size = 177780, upload-time = "2025-09-08T23:23:16.761Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/92/c4/3ce07396253a83250ee98564f8d7e9789fab8e58858f35d07a9a2c78de9f/cffi-2.0.0-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:fc33c5141b55ed366cfaad382df24fe7dcbc686de5be719b207bb248e3053dc5", size = 185320, upload-time = "2025-09-08T23:23:18.087Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/59/dd/27e9fa567a23931c838c6b02d0764611c62290062a6d4e8ff7863daf9730/cffi-2.0.0-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:c654de545946e0db659b3400168c9ad31b5d29593291482c43e3564effbcee13", size = 181487, upload-time = "2025-09-08T23:23:19.622Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/d6/43/0e822876f87ea8a4ef95442c3d766a06a51fc5298823f884ef87aaad168c/cffi-2.0.0-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:24b6f81f1983e6df8db3adc38562c83f7d4a0c36162885ec7f7b77c7dcbec97b", size = 220049, upload-time = "2025-09-08T23:23:20.853Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/b4/89/76799151d9c2d2d1ead63c2429da9ea9d7aac304603de0c6e8764e6e8e70/cffi-2.0.0-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:12873ca6cb9b0f0d3a0da705d6086fe911591737a59f28b7936bdfed27c0d47c", size = 207793, upload-time = "2025-09-08T23:23:22.08Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/bb/dd/3465b14bb9e24ee24cb88c9e3730f6de63111fffe513492bf8c808a3547e/cffi-2.0.0-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.whl", hash = "sha256:d9b97165e8aed9272a6bb17c01e3cc5871a594a446ebedc996e2397a1c1ea8ef", size = 206300, upload-time = "2025-09-08T23:23:23.314Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/47/d9/d83e293854571c877a92da46fdec39158f8d7e68da75bf73581225d28e90/cffi-2.0.0-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:afb8db5439b81cf9c9d0c80404b60c3cc9c3add93e114dcae767f1477cb53775", size = 219244, upload-time = "2025-09-08T23:23:24.541Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/2b/0f/1f177e3683aead2bb00f7679a16451d302c436b5cbf2505f0ea8146ef59e/cffi-2.0.0-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:737fe7d37e1a1bffe70bd5754ea763a62a066dc5913ca57e957824b72a85e205", size = 222828, upload-time = "2025-09-08T23:23:26.143Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/c6/0f/cafacebd4b040e3119dcb32fed8bdef8dfe94da653155f9d0b9dc660166e/cffi-2.0.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:38100abb9d1b1435bc4cc340bb4489635dc2f0da7456590877030c9b3d40b0c1", size = 220926, upload-time = "2025-09-08T23:23:27.873Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/3e/aa/df335faa45b395396fcbc03de2dfcab242cd61a9900e914fe682a59170b1/cffi-2.0.0-cp314-cp314-win32.whl", hash = "sha256:087067fa8953339c723661eda6b54bc98c5625757ea62e95eb4898ad5e776e9f", size = 175328, upload-time = "2025-09-08T23:23:44.61Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/bb/92/882c2d30831744296ce713f0feb4c1cd30f346ef747b530b5318715cc367/cffi-2.0.0-cp314-cp314-win_amd64.whl", hash = "sha256:203a48d1fb583fc7d78a4c6655692963b860a417c0528492a6bc21f1aaefab25", size = 185650, upload-time = "2025-09-08T23:23:45.848Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/9f/2c/98ece204b9d35a7366b5b2c6539c350313ca13932143e79dc133ba757104/cffi-2.0.0-cp314-cp314-win_arm64.whl", hash = "sha256:dbd5c7a25a7cb98f5ca55d258b103a2054f859a46ae11aaf23134f9cc0d356ad", size = 180687, upload-time = "2025-09-08T23:23:47.105Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/3e/61/c768e4d548bfa607abcda77423448df8c471f25dbe64fb2ef6d555eae006/cffi-2.0.0-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:9a67fc9e8eb39039280526379fb3a70023d77caec1852002b4da7e8b270c4dd9", size = 188773, upload-time = "2025-09-08T23:23:29.347Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/2c/ea/5f76bce7cf6fcd0ab1a1058b5af899bfbef198bea4d5686da88471ea0336/cffi-2.0.0-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:7a66c7204d8869299919db4d5069a82f1561581af12b11b3c9f48c584eb8743d", size = 185013, upload-time = "2025-09-08T23:23:30.63Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/be/b4/c56878d0d1755cf9caa54ba71e5d049479c52f9e4afc230f06822162ab2f/cffi-2.0.0-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:7cc09976e8b56f8cebd752f7113ad07752461f48a58cbba644139015ac24954c", size = 221593, upload-time = "2025-09-08T23:23:31.91Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/e0/0d/eb704606dfe8033e7128df5e90fee946bbcb64a04fcdaa97321309004000/cffi-2.0.0-cp314-cp314t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:92b68146a71df78564e4ef48af17551a5ddd142e5190cdf2c5624d0c3ff5b2e8", size = 209354, upload-time = "2025-09-08T23:23:33.214Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/d8/19/3c435d727b368ca475fb8742ab97c9cb13a0de600ce86f62eab7fa3eea60/cffi-2.0.0-cp314-cp314t-manylinux2014_s390x.manylinux_2_17_s390x.whl", hash = "sha256:b1e74d11748e7e98e2f426ab176d4ed720a64412b6a15054378afdb71e0f37dc", size = 208480, upload-time = "2025-09-08T23:23:34.495Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/d0/44/681604464ed9541673e486521497406fadcc15b5217c3e326b061696899a/cffi-2.0.0-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:28a3a209b96630bca57cce802da70c266eb08c6e97e5afd61a75611ee6c64592", size = 221584, upload-time = "2025-09-08T23:23:36.096Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/25/8e/342a504ff018a2825d395d44d63a767dd8ebc927ebda557fecdaca3ac33a/cffi-2.0.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:7553fb2090d71822f02c629afe6042c299edf91ba1bf94951165613553984512", size = 224443, upload-time = "2025-09-08T23:23:37.328Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/e1/5e/b666bacbbc60fbf415ba9988324a132c9a7a0448a9a8f125074671c0f2c3/cffi-2.0.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:6c6c373cfc5c83a975506110d17457138c8c63016b563cc9ed6e056a82f13ce4", size = 223437, upload-time = "2025-09-08T23:23:38.945Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/a0/1d/ec1a60bd1a10daa292d3cd6bb0b359a81607154fb8165f3ec95fe003b85c/cffi-2.0.0-cp314-cp314t-win32.whl", hash = "sha256:1fc9ea04857caf665289b7a75923f2c6ed559b8298a1b8c49e59f7dd95c8481e", size = 180487, upload-time = "2025-09-08T23:23:40.423Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/bf/41/4c1168c74fac325c0c8156f04b6749c8b6a8f405bbf91413ba088359f60d/cffi-2.0.0-cp314-cp314t-win_amd64.whl", hash = "sha256:d68b6cef7827e8641e8ef16f4494edda8b36104d79773a334beaa1e3521430f6", size = 191726, upload-time = "2025-09-08T23:23:41.742Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/ae/3a/dbeec9d1ee0844c679f6bb5d6ad4e9f198b1224f4e7a32825f47f6192b0c/cffi-2.0.0-cp314-cp314t-win_arm64.whl", hash = "sha256:0a1527a803f0a659de1af2e1fd700213caba79377e27e4693648c2923da066f9", size = 184195, upload-time = "2025-09-08T23:23:43.004Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "charset-normalizer"
|
||||
version = "3.4.4"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/13/69/33ddede1939fdd074bce5434295f38fae7136463422fe4fd3e0e89b98062/charset_normalizer-3.4.4.tar.gz", hash = "sha256:94537985111c35f28720e43603b8e7b43a6ecfb2ce1d3058bbe955b73404e21a", size = 129418, upload-time = "2025-10-14T04:42:32.879Z" }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/f3/85/1637cd4af66fa687396e757dec650f28025f2a2f5a5531a3208dc0ec43f2/charset_normalizer-3.4.4-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:0a98e6759f854bd25a58a73fa88833fba3b7c491169f86ce1180c948ab3fd394", size = 208425, upload-time = "2025-10-14T04:40:53.353Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/9d/6a/04130023fef2a0d9c62d0bae2649b69f7b7d8d24ea5536feef50551029df/charset_normalizer-3.4.4-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:b5b290ccc2a263e8d185130284f8501e3e36c5e02750fc6b6bdeb2e9e96f1e25", size = 148162, upload-time = "2025-10-14T04:40:54.558Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/78/29/62328d79aa60da22c9e0b9a66539feae06ca0f5a4171ac4f7dc285b83688/charset_normalizer-3.4.4-cp312-cp312-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:74bb723680f9f7a6234dcf67aea57e708ec1fbdf5699fb91dfd6f511b0a320ef", size = 144558, upload-time = "2025-10-14T04:40:55.677Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/86/bb/b32194a4bf15b88403537c2e120b817c61cd4ecffa9b6876e941c3ee38fe/charset_normalizer-3.4.4-cp312-cp312-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:f1e34719c6ed0b92f418c7c780480b26b5d9c50349e9a9af7d76bf757530350d", size = 161497, upload-time = "2025-10-14T04:40:57.217Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/19/89/a54c82b253d5b9b111dc74aca196ba5ccfcca8242d0fb64146d4d3183ff1/charset_normalizer-3.4.4-cp312-cp312-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:2437418e20515acec67d86e12bf70056a33abdacb5cb1655042f6538d6b085a8", size = 159240, upload-time = "2025-10-14T04:40:58.358Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/c0/10/d20b513afe03acc89ec33948320a5544d31f21b05368436d580dec4e234d/charset_normalizer-3.4.4-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:11d694519d7f29d6cd09f6ac70028dba10f92f6cdd059096db198c283794ac86", size = 153471, upload-time = "2025-10-14T04:40:59.468Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/61/fa/fbf177b55bdd727010f9c0a3c49eefa1d10f960e5f09d1d887bf93c2e698/charset_normalizer-3.4.4-cp312-cp312-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:ac1c4a689edcc530fc9d9aa11f5774b9e2f33f9a0c6a57864e90908f5208d30a", size = 150864, upload-time = "2025-10-14T04:41:00.623Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/05/12/9fbc6a4d39c0198adeebbde20b619790e9236557ca59fc40e0e3cebe6f40/charset_normalizer-3.4.4-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:21d142cc6c0ec30d2efee5068ca36c128a30b0f2c53c1c07bd78cb6bc1d3be5f", size = 150647, upload-time = "2025-10-14T04:41:01.754Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/ad/1f/6a9a593d52e3e8c5d2b167daf8c6b968808efb57ef4c210acb907c365bc4/charset_normalizer-3.4.4-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:5dbe56a36425d26d6cfb40ce79c314a2e4dd6211d51d6d2191c00bed34f354cc", size = 145110, upload-time = "2025-10-14T04:41:03.231Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/30/42/9a52c609e72471b0fc54386dc63c3781a387bb4fe61c20231a4ebcd58bdd/charset_normalizer-3.4.4-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:5bfbb1b9acf3334612667b61bd3002196fe2a1eb4dd74d247e0f2a4d50ec9bbf", size = 162839, upload-time = "2025-10-14T04:41:04.715Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/c4/5b/c0682bbf9f11597073052628ddd38344a3d673fda35a36773f7d19344b23/charset_normalizer-3.4.4-cp312-cp312-musllinux_1_2_riscv64.whl", hash = "sha256:d055ec1e26e441f6187acf818b73564e6e6282709e9bcb5b63f5b23068356a15", size = 150667, upload-time = "2025-10-14T04:41:05.827Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/e4/24/a41afeab6f990cf2daf6cb8c67419b63b48cf518e4f56022230840c9bfb2/charset_normalizer-3.4.4-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:af2d8c67d8e573d6de5bc30cdb27e9b95e49115cd9baad5ddbd1a6207aaa82a9", size = 160535, upload-time = "2025-10-14T04:41:06.938Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/2a/e5/6a4ce77ed243c4a50a1fecca6aaaab419628c818a49434be428fe24c9957/charset_normalizer-3.4.4-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:780236ac706e66881f3b7f2f32dfe90507a09e67d1d454c762cf642e6e1586e0", size = 154816, upload-time = "2025-10-14T04:41:08.101Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/a8/ef/89297262b8092b312d29cdb2517cb1237e51db8ecef2e9af5edbe7b683b1/charset_normalizer-3.4.4-cp312-cp312-win32.whl", hash = "sha256:5833d2c39d8896e4e19b689ffc198f08ea58116bee26dea51e362ecc7cd3ed26", size = 99694, upload-time = "2025-10-14T04:41:09.23Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/3d/2d/1e5ed9dd3b3803994c155cd9aacb60c82c331bad84daf75bcb9c91b3295e/charset_normalizer-3.4.4-cp312-cp312-win_amd64.whl", hash = "sha256:a79cfe37875f822425b89a82333404539ae63dbdddf97f84dcbc3d339aae9525", size = 107131, upload-time = "2025-10-14T04:41:10.467Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/d0/d9/0ed4c7098a861482a7b6a95603edce4c0d9db2311af23da1fb2b75ec26fc/charset_normalizer-3.4.4-cp312-cp312-win_arm64.whl", hash = "sha256:376bec83a63b8021bb5c8ea75e21c4ccb86e7e45ca4eb81146091b56599b80c3", size = 100390, upload-time = "2025-10-14T04:41:11.915Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/97/45/4b3a1239bbacd321068ea6e7ac28875b03ab8bc0aa0966452db17cd36714/charset_normalizer-3.4.4-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:e1f185f86a6f3403aa2420e815904c67b2f9ebc443f045edd0de921108345794", size = 208091, upload-time = "2025-10-14T04:41:13.346Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/7d/62/73a6d7450829655a35bb88a88fca7d736f9882a27eacdca2c6d505b57e2e/charset_normalizer-3.4.4-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:6b39f987ae8ccdf0d2642338faf2abb1862340facc796048b604ef14919e55ed", size = 147936, upload-time = "2025-10-14T04:41:14.461Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/89/c5/adb8c8b3d6625bef6d88b251bbb0d95f8205831b987631ab0c8bb5d937c2/charset_normalizer-3.4.4-cp313-cp313-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:3162d5d8ce1bb98dd51af660f2121c55d0fa541b46dff7bb9b9f86ea1d87de72", size = 144180, upload-time = "2025-10-14T04:41:15.588Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/91/ed/9706e4070682d1cc219050b6048bfd293ccf67b3d4f5a4f39207453d4b99/charset_normalizer-3.4.4-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:81d5eb2a312700f4ecaa977a8235b634ce853200e828fbadf3a9c50bab278328", size = 161346, upload-time = "2025-10-14T04:41:16.738Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/d5/0d/031f0d95e4972901a2f6f09ef055751805ff541511dc1252ba3ca1f80cf5/charset_normalizer-3.4.4-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:5bd2293095d766545ec1a8f612559f6b40abc0eb18bb2f5d1171872d34036ede", size = 158874, upload-time = "2025-10-14T04:41:17.923Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/f5/83/6ab5883f57c9c801ce5e5677242328aa45592be8a00644310a008d04f922/charset_normalizer-3.4.4-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:a8a8b89589086a25749f471e6a900d3f662d1d3b6e2e59dcecf787b1cc3a1894", size = 153076, upload-time = "2025-10-14T04:41:19.106Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/75/1e/5ff781ddf5260e387d6419959ee89ef13878229732732ee73cdae01800f2/charset_normalizer-3.4.4-cp313-cp313-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:bc7637e2f80d8530ee4a78e878bce464f70087ce73cf7c1caf142416923b98f1", size = 150601, upload-time = "2025-10-14T04:41:20.245Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/d7/57/71be810965493d3510a6ca79b90c19e48696fb1ff964da319334b12677f0/charset_normalizer-3.4.4-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:f8bf04158c6b607d747e93949aa60618b61312fe647a6369f88ce2ff16043490", size = 150376, upload-time = "2025-10-14T04:41:21.398Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/e5/d5/c3d057a78c181d007014feb7e9f2e65905a6c4ef182c0ddf0de2924edd65/charset_normalizer-3.4.4-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:554af85e960429cf30784dd47447d5125aaa3b99a6f0683589dbd27e2f45da44", size = 144825, upload-time = "2025-10-14T04:41:22.583Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/e6/8c/d0406294828d4976f275ffbe66f00266c4b3136b7506941d87c00cab5272/charset_normalizer-3.4.4-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:74018750915ee7ad843a774364e13a3db91682f26142baddf775342c3f5b1133", size = 162583, upload-time = "2025-10-14T04:41:23.754Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/d7/24/e2aa1f18c8f15c4c0e932d9287b8609dd30ad56dbe41d926bd846e22fb8d/charset_normalizer-3.4.4-cp313-cp313-musllinux_1_2_riscv64.whl", hash = "sha256:c0463276121fdee9c49b98908b3a89c39be45d86d1dbaa22957e38f6321d4ce3", size = 150366, upload-time = "2025-10-14T04:41:25.27Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/e4/5b/1e6160c7739aad1e2df054300cc618b06bf784a7a164b0f238360721ab86/charset_normalizer-3.4.4-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:362d61fd13843997c1c446760ef36f240cf81d3ebf74ac62652aebaf7838561e", size = 160300, upload-time = "2025-10-14T04:41:26.725Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/7a/10/f882167cd207fbdd743e55534d5d9620e095089d176d55cb22d5322f2afd/charset_normalizer-3.4.4-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:9a26f18905b8dd5d685d6d07b0cdf98a79f3c7a918906af7cc143ea2e164c8bc", size = 154465, upload-time = "2025-10-14T04:41:28.322Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/89/66/c7a9e1b7429be72123441bfdbaf2bc13faab3f90b933f664db506dea5915/charset_normalizer-3.4.4-cp313-cp313-win32.whl", hash = "sha256:9b35f4c90079ff2e2edc5b26c0c77925e5d2d255c42c74fdb70fb49b172726ac", size = 99404, upload-time = "2025-10-14T04:41:29.95Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/c4/26/b9924fa27db384bdcd97ab83b4f0a8058d96ad9626ead570674d5e737d90/charset_normalizer-3.4.4-cp313-cp313-win_amd64.whl", hash = "sha256:b435cba5f4f750aa6c0a0d92c541fb79f69a387c91e61f1795227e4ed9cece14", size = 107092, upload-time = "2025-10-14T04:41:31.188Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/af/8f/3ed4bfa0c0c72a7ca17f0380cd9e4dd842b09f664e780c13cff1dcf2ef1b/charset_normalizer-3.4.4-cp313-cp313-win_arm64.whl", hash = "sha256:542d2cee80be6f80247095cc36c418f7bddd14f4a6de45af91dfad36d817bba2", size = 100408, upload-time = "2025-10-14T04:41:32.624Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/2a/35/7051599bd493e62411d6ede36fd5af83a38f37c4767b92884df7301db25d/charset_normalizer-3.4.4-cp314-cp314-macosx_10_13_universal2.whl", hash = "sha256:da3326d9e65ef63a817ecbcc0df6e94463713b754fe293eaa03da99befb9a5bd", size = 207746, upload-time = "2025-10-14T04:41:33.773Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/10/9a/97c8d48ef10d6cd4fcead2415523221624bf58bcf68a802721a6bc807c8f/charset_normalizer-3.4.4-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:8af65f14dc14a79b924524b1e7fffe304517b2bff5a58bf64f30b98bbc5079eb", size = 147889, upload-time = "2025-10-14T04:41:34.897Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/10/bf/979224a919a1b606c82bd2c5fa49b5c6d5727aa47b4312bb27b1734f53cd/charset_normalizer-3.4.4-cp314-cp314-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:74664978bb272435107de04e36db5a9735e78232b85b77d45cfb38f758efd33e", size = 143641, upload-time = "2025-10-14T04:41:36.116Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/ba/33/0ad65587441fc730dc7bd90e9716b30b4702dc7b617e6ba4997dc8651495/charset_normalizer-3.4.4-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:752944c7ffbfdd10c074dc58ec2d5a8a4cd9493b314d367c14d24c17684ddd14", size = 160779, upload-time = "2025-10-14T04:41:37.229Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/67/ed/331d6b249259ee71ddea93f6f2f0a56cfebd46938bde6fcc6f7b9a3d0e09/charset_normalizer-3.4.4-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:d1f13550535ad8cff21b8d757a3257963e951d96e20ec82ab44bc64aeb62a191", size = 159035, upload-time = "2025-10-14T04:41:38.368Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/67/ff/f6b948ca32e4f2a4576aa129d8bed61f2e0543bf9f5f2b7fc3758ed005c9/charset_normalizer-3.4.4-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:ecaae4149d99b1c9e7b88bb03e3221956f68fd6d50be2ef061b2381b61d20838", size = 152542, upload-time = "2025-10-14T04:41:39.862Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/16/85/276033dcbcc369eb176594de22728541a925b2632f9716428c851b149e83/charset_normalizer-3.4.4-cp314-cp314-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:cb6254dc36b47a990e59e1068afacdcd02958bdcce30bb50cc1700a8b9d624a6", size = 149524, upload-time = "2025-10-14T04:41:41.319Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/9e/f2/6a2a1f722b6aba37050e626530a46a68f74e63683947a8acff92569f979a/charset_normalizer-3.4.4-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:c8ae8a0f02f57a6e61203a31428fa1d677cbe50c93622b4149d5c0f319c1d19e", size = 150395, upload-time = "2025-10-14T04:41:42.539Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/60/bb/2186cb2f2bbaea6338cad15ce23a67f9b0672929744381e28b0592676824/charset_normalizer-3.4.4-cp314-cp314-musllinux_1_2_armv7l.whl", hash = "sha256:47cc91b2f4dd2833fddaedd2893006b0106129d4b94fdb6af1f4ce5a9965577c", size = 143680, upload-time = "2025-10-14T04:41:43.661Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/7d/a5/bf6f13b772fbb2a90360eb620d52ed8f796f3c5caee8398c3b2eb7b1c60d/charset_normalizer-3.4.4-cp314-cp314-musllinux_1_2_ppc64le.whl", hash = "sha256:82004af6c302b5d3ab2cfc4cc5f29db16123b1a8417f2e25f9066f91d4411090", size = 162045, upload-time = "2025-10-14T04:41:44.821Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/df/c5/d1be898bf0dc3ef9030c3825e5d3b83f2c528d207d246cbabe245966808d/charset_normalizer-3.4.4-cp314-cp314-musllinux_1_2_riscv64.whl", hash = "sha256:2b7d8f6c26245217bd2ad053761201e9f9680f8ce52f0fcd8d0755aeae5b2152", size = 149687, upload-time = "2025-10-14T04:41:46.442Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/a5/42/90c1f7b9341eef50c8a1cb3f098ac43b0508413f33affd762855f67a410e/charset_normalizer-3.4.4-cp314-cp314-musllinux_1_2_s390x.whl", hash = "sha256:799a7a5e4fb2d5898c60b640fd4981d6a25f1c11790935a44ce38c54e985f828", size = 160014, upload-time = "2025-10-14T04:41:47.631Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/76/be/4d3ee471e8145d12795ab655ece37baed0929462a86e72372fd25859047c/charset_normalizer-3.4.4-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:99ae2cffebb06e6c22bdc25801d7b30f503cc87dbd283479e7b606f70aff57ec", size = 154044, upload-time = "2025-10-14T04:41:48.81Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/b0/6f/8f7af07237c34a1defe7defc565a9bc1807762f672c0fde711a4b22bf9c0/charset_normalizer-3.4.4-cp314-cp314-win32.whl", hash = "sha256:f9d332f8c2a2fcbffe1378594431458ddbef721c1769d78e2cbc06280d8155f9", size = 99940, upload-time = "2025-10-14T04:41:49.946Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/4b/51/8ade005e5ca5b0d80fb4aff72a3775b325bdc3d27408c8113811a7cbe640/charset_normalizer-3.4.4-cp314-cp314-win_amd64.whl", hash = "sha256:8a6562c3700cce886c5be75ade4a5db4214fda19fede41d9792d100288d8f94c", size = 107104, upload-time = "2025-10-14T04:41:51.051Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/da/5f/6b8f83a55bb8278772c5ae54a577f3099025f9ade59d0136ac24a0df4bde/charset_normalizer-3.4.4-cp314-cp314-win_arm64.whl", hash = "sha256:de00632ca48df9daf77a2c65a484531649261ec9f25489917f09e455cb09ddb2", size = 100743, upload-time = "2025-10-14T04:41:52.122Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/0a/4c/925909008ed5a988ccbb72dcc897407e5d6d3bd72410d69e051fc0c14647/charset_normalizer-3.4.4-py3-none-any.whl", hash = "sha256:7a32c560861a02ff789ad905a2fe94e3f840803362c84fecf1851cb4cf3dc37f", size = 53402, upload-time = "2025-10-14T04:42:31.76Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "contourpy"
|
||||
version = "1.3.3"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
dependencies = [
|
||||
{ name = "numpy" },
|
||||
]
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/58/01/1253e6698a07380cd31a736d248a3f2a50a7c88779a1813da27503cadc2a/contourpy-1.3.3.tar.gz", hash = "sha256:083e12155b210502d0bca491432bb04d56dc3432f95a979b429f2848c3dbe880", size = 13466174, upload-time = "2025-07-26T12:03:12.549Z" }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/be/45/adfee365d9ea3d853550b2e735f9d66366701c65db7855cd07621732ccfc/contourpy-1.3.3-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:b08a32ea2f8e42cf1d4be3169a98dd4be32bafe4f22b6c4cb4ba810fa9e5d2cb", size = 293419, upload-time = "2025-07-26T12:01:21.16Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/53/3e/405b59cfa13021a56bba395a6b3aca8cec012b45bf177b0eaf7a202cde2c/contourpy-1.3.3-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:556dba8fb6f5d8742f2923fe9457dbdd51e1049c4a43fd3986a0b14a1d815fc6", size = 273979, upload-time = "2025-07-26T12:01:22.448Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/d4/1c/a12359b9b2ca3a845e8f7f9ac08bdf776114eb931392fcad91743e2ea17b/contourpy-1.3.3-cp312-cp312-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:92d9abc807cf7d0e047b95ca5d957cf4792fcd04e920ca70d48add15c1a90ea7", size = 332653, upload-time = "2025-07-26T12:01:24.155Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/63/12/897aeebfb475b7748ea67b61e045accdfcf0d971f8a588b67108ed7f5512/contourpy-1.3.3-cp312-cp312-manylinux_2_26_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:b2e8faa0ed68cb29af51edd8e24798bb661eac3bd9f65420c1887b6ca89987c8", size = 379536, upload-time = "2025-07-26T12:01:25.91Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/43/8a/a8c584b82deb248930ce069e71576fc09bd7174bbd35183b7943fb1064fd/contourpy-1.3.3-cp312-cp312-manylinux_2_26_s390x.manylinux_2_28_s390x.whl", hash = "sha256:626d60935cf668e70a5ce6ff184fd713e9683fb458898e4249b63be9e28286ea", size = 384397, upload-time = "2025-07-26T12:01:27.152Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/cc/8f/ec6289987824b29529d0dfda0d74a07cec60e54b9c92f3c9da4c0ac732de/contourpy-1.3.3-cp312-cp312-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:4d00e655fcef08aba35ec9610536bfe90267d7ab5ba944f7032549c55a146da1", size = 362601, upload-time = "2025-07-26T12:01:28.808Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/05/0a/a3fe3be3ee2dceb3e615ebb4df97ae6f3828aa915d3e10549ce016302bd1/contourpy-1.3.3-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:451e71b5a7d597379ef572de31eeb909a87246974d960049a9848c3bc6c41bf7", size = 1331288, upload-time = "2025-07-26T12:01:31.198Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/33/1d/acad9bd4e97f13f3e2b18a3977fe1b4a37ecf3d38d815333980c6c72e963/contourpy-1.3.3-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:459c1f020cd59fcfe6650180678a9993932d80d44ccde1fa1868977438f0b411", size = 1403386, upload-time = "2025-07-26T12:01:33.947Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/cf/8f/5847f44a7fddf859704217a99a23a4f6417b10e5ab1256a179264561540e/contourpy-1.3.3-cp312-cp312-win32.whl", hash = "sha256:023b44101dfe49d7d53932be418477dba359649246075c996866106da069af69", size = 185018, upload-time = "2025-07-26T12:01:35.64Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/19/e8/6026ed58a64563186a9ee3f29f41261fd1828f527dd93d33b60feca63352/contourpy-1.3.3-cp312-cp312-win_amd64.whl", hash = "sha256:8153b8bfc11e1e4d75bcb0bff1db232f9e10b274e0929de9d608027e0d34ff8b", size = 226567, upload-time = "2025-07-26T12:01:36.804Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/d1/e2/f05240d2c39a1ed228d8328a78b6f44cd695f7ef47beb3e684cf93604f86/contourpy-1.3.3-cp312-cp312-win_arm64.whl", hash = "sha256:07ce5ed73ecdc4a03ffe3e1b3e3c1166db35ae7584be76f65dbbe28a7791b0cc", size = 193655, upload-time = "2025-07-26T12:01:37.999Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/68/35/0167aad910bbdb9599272bd96d01a9ec6852f36b9455cf2ca67bd4cc2d23/contourpy-1.3.3-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:177fb367556747a686509d6fef71d221a4b198a3905fe824430e5ea0fda54eb5", size = 293257, upload-time = "2025-07-26T12:01:39.367Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/96/e4/7adcd9c8362745b2210728f209bfbcf7d91ba868a2c5f40d8b58f54c509b/contourpy-1.3.3-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:d002b6f00d73d69333dac9d0b8d5e84d9724ff9ef044fd63c5986e62b7c9e1b1", size = 274034, upload-time = "2025-07-26T12:01:40.645Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/73/23/90e31ceeed1de63058a02cb04b12f2de4b40e3bef5e082a7c18d9c8ae281/contourpy-1.3.3-cp313-cp313-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:348ac1f5d4f1d66d3322420f01d42e43122f43616e0f194fc1c9f5d830c5b286", size = 334672, upload-time = "2025-07-26T12:01:41.942Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/ed/93/b43d8acbe67392e659e1d984700e79eb67e2acb2bd7f62012b583a7f1b55/contourpy-1.3.3-cp313-cp313-manylinux_2_26_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:655456777ff65c2c548b7c454af9c6f33f16c8884f11083244b5819cc214f1b5", size = 381234, upload-time = "2025-07-26T12:01:43.499Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/46/3b/bec82a3ea06f66711520f75a40c8fc0b113b2a75edb36aa633eb11c4f50f/contourpy-1.3.3-cp313-cp313-manylinux_2_26_s390x.manylinux_2_28_s390x.whl", hash = "sha256:644a6853d15b2512d67881586bd03f462c7ab755db95f16f14d7e238f2852c67", size = 385169, upload-time = "2025-07-26T12:01:45.219Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/4b/32/e0f13a1c5b0f8572d0ec6ae2f6c677b7991fafd95da523159c19eff0696a/contourpy-1.3.3-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:4debd64f124ca62069f313a9cb86656ff087786016d76927ae2cf37846b006c9", size = 362859, upload-time = "2025-07-26T12:01:46.519Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/33/71/e2a7945b7de4e58af42d708a219f3b2f4cff7386e6b6ab0a0fa0033c49a9/contourpy-1.3.3-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:a15459b0f4615b00bbd1e91f1b9e19b7e63aea7483d03d804186f278c0af2659", size = 1332062, upload-time = "2025-07-26T12:01:48.964Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/12/fc/4e87ac754220ccc0e807284f88e943d6d43b43843614f0a8afa469801db0/contourpy-1.3.3-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:ca0fdcd73925568ca027e0b17ab07aad764be4706d0a925b89227e447d9737b7", size = 1403932, upload-time = "2025-07-26T12:01:51.979Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/a6/2e/adc197a37443f934594112222ac1aa7dc9a98faf9c3842884df9a9d8751d/contourpy-1.3.3-cp313-cp313-win32.whl", hash = "sha256:b20c7c9a3bf701366556e1b1984ed2d0cedf999903c51311417cf5f591d8c78d", size = 185024, upload-time = "2025-07-26T12:01:53.245Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/18/0b/0098c214843213759692cc638fce7de5c289200a830e5035d1791d7a2338/contourpy-1.3.3-cp313-cp313-win_amd64.whl", hash = "sha256:1cadd8b8969f060ba45ed7c1b714fe69185812ab43bd6b86a9123fe8f99c3263", size = 226578, upload-time = "2025-07-26T12:01:54.422Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/8a/9a/2f6024a0c5995243cd63afdeb3651c984f0d2bc727fd98066d40e141ad73/contourpy-1.3.3-cp313-cp313-win_arm64.whl", hash = "sha256:fd914713266421b7536de2bfa8181aa8c699432b6763a0ea64195ebe28bff6a9", size = 193524, upload-time = "2025-07-26T12:01:55.73Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/c0/b3/f8a1a86bd3298513f500e5b1f5fd92b69896449f6cab6a146a5d52715479/contourpy-1.3.3-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:88df9880d507169449d434c293467418b9f6cbe82edd19284aa0409e7fdb933d", size = 306730, upload-time = "2025-07-26T12:01:57.051Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/3f/11/4780db94ae62fc0c2053909b65dc3246bd7cecfc4f8a20d957ad43aa4ad8/contourpy-1.3.3-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:d06bb1f751ba5d417047db62bca3c8fde202b8c11fb50742ab3ab962c81e8216", size = 287897, upload-time = "2025-07-26T12:01:58.663Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/ae/15/e59f5f3ffdd6f3d4daa3e47114c53daabcb18574a26c21f03dc9e4e42ff0/contourpy-1.3.3-cp313-cp313t-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:e4e6b05a45525357e382909a4c1600444e2a45b4795163d3b22669285591c1ae", size = 326751, upload-time = "2025-07-26T12:02:00.343Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/0f/81/03b45cfad088e4770b1dcf72ea78d3802d04200009fb364d18a493857210/contourpy-1.3.3-cp313-cp313t-manylinux_2_26_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:ab3074b48c4e2cf1a960e6bbeb7f04566bf36b1861d5c9d4d8ac04b82e38ba20", size = 375486, upload-time = "2025-07-26T12:02:02.128Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/0c/ba/49923366492ffbdd4486e970d421b289a670ae8cf539c1ea9a09822b371a/contourpy-1.3.3-cp313-cp313t-manylinux_2_26_s390x.manylinux_2_28_s390x.whl", hash = "sha256:6c3d53c796f8647d6deb1abe867daeb66dcc8a97e8455efa729516b997b8ed99", size = 388106, upload-time = "2025-07-26T12:02:03.615Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/9f/52/5b00ea89525f8f143651f9f03a0df371d3cbd2fccd21ca9b768c7a6500c2/contourpy-1.3.3-cp313-cp313t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:50ed930df7289ff2a8d7afeb9603f8289e5704755c7e5c3bbd929c90c817164b", size = 352548, upload-time = "2025-07-26T12:02:05.165Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/32/1d/a209ec1a3a3452d490f6b14dd92e72280c99ae3d1e73da74f8277d4ee08f/contourpy-1.3.3-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:4feffb6537d64b84877da813a5c30f1422ea5739566abf0bd18065ac040e120a", size = 1322297, upload-time = "2025-07-26T12:02:07.379Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/bc/9e/46f0e8ebdd884ca0e8877e46a3f4e633f6c9c8c4f3f6e72be3fe075994aa/contourpy-1.3.3-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:2b7e9480ffe2b0cd2e787e4df64270e3a0440d9db8dc823312e2c940c167df7e", size = 1391023, upload-time = "2025-07-26T12:02:10.171Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/b9/70/f308384a3ae9cd2209e0849f33c913f658d3326900d0ff5d378d6a1422d2/contourpy-1.3.3-cp313-cp313t-win32.whl", hash = "sha256:283edd842a01e3dcd435b1c5116798d661378d83d36d337b8dde1d16a5fc9ba3", size = 196157, upload-time = "2025-07-26T12:02:11.488Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/b2/dd/880f890a6663b84d9e34a6f88cded89d78f0091e0045a284427cb6b18521/contourpy-1.3.3-cp313-cp313t-win_amd64.whl", hash = "sha256:87acf5963fc2b34825e5b6b048f40e3635dd547f590b04d2ab317c2619ef7ae8", size = 240570, upload-time = "2025-07-26T12:02:12.754Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/80/99/2adc7d8ffead633234817ef8e9a87115c8a11927a94478f6bb3d3f4d4f7d/contourpy-1.3.3-cp313-cp313t-win_arm64.whl", hash = "sha256:3c30273eb2a55024ff31ba7d052dde990d7d8e5450f4bbb6e913558b3d6c2301", size = 199713, upload-time = "2025-07-26T12:02:14.4Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/72/8b/4546f3ab60f78c514ffb7d01a0bd743f90de36f0019d1be84d0a708a580a/contourpy-1.3.3-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:fde6c716d51c04b1c25d0b90364d0be954624a0ee9d60e23e850e8d48353d07a", size = 292189, upload-time = "2025-07-26T12:02:16.095Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/fd/e1/3542a9cb596cadd76fcef413f19c79216e002623158befe6daa03dbfa88c/contourpy-1.3.3-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:cbedb772ed74ff5be440fa8eee9bd49f64f6e3fc09436d9c7d8f1c287b121d77", size = 273251, upload-time = "2025-07-26T12:02:17.524Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/b1/71/f93e1e9471d189f79d0ce2497007731c1e6bf9ef6d1d61b911430c3db4e5/contourpy-1.3.3-cp314-cp314-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:22e9b1bd7a9b1d652cd77388465dc358dafcd2e217d35552424aa4f996f524f5", size = 335810, upload-time = "2025-07-26T12:02:18.9Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/91/f9/e35f4c1c93f9275d4e38681a80506b5510e9327350c51f8d4a5a724d178c/contourpy-1.3.3-cp314-cp314-manylinux_2_26_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:a22738912262aa3e254e4f3cb079a95a67132fc5a063890e224393596902f5a4", size = 382871, upload-time = "2025-07-26T12:02:20.418Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/b5/71/47b512f936f66a0a900d81c396a7e60d73419868fba959c61efed7a8ab46/contourpy-1.3.3-cp314-cp314-manylinux_2_26_s390x.manylinux_2_28_s390x.whl", hash = "sha256:afe5a512f31ee6bd7d0dda52ec9864c984ca3d66664444f2d72e0dc4eb832e36", size = 386264, upload-time = "2025-07-26T12:02:21.916Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/04/5f/9ff93450ba96b09c7c2b3f81c94de31c89f92292f1380261bd7195bea4ea/contourpy-1.3.3-cp314-cp314-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:f64836de09927cba6f79dcd00fdd7d5329f3fccc633468507079c829ca4db4e3", size = 363819, upload-time = "2025-07-26T12:02:23.759Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/3e/a6/0b185d4cc480ee494945cde102cb0149ae830b5fa17bf855b95f2e70ad13/contourpy-1.3.3-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:1fd43c3be4c8e5fd6e4f2baeae35ae18176cf2e5cced681cca908addf1cdd53b", size = 1333650, upload-time = "2025-07-26T12:02:26.181Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/43/d7/afdc95580ca56f30fbcd3060250f66cedbde69b4547028863abd8aa3b47e/contourpy-1.3.3-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:6afc576f7b33cf00996e5c1102dc2a8f7cc89e39c0b55df93a0b78c1bd992b36", size = 1404833, upload-time = "2025-07-26T12:02:28.782Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/e2/e2/366af18a6d386f41132a48f033cbd2102e9b0cf6345d35ff0826cd984566/contourpy-1.3.3-cp314-cp314-win32.whl", hash = "sha256:66c8a43a4f7b8df8b71ee1840e4211a3c8d93b214b213f590e18a1beca458f7d", size = 189692, upload-time = "2025-07-26T12:02:30.128Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/7d/c2/57f54b03d0f22d4044b8afb9ca0e184f8b1afd57b4f735c2fa70883dc601/contourpy-1.3.3-cp314-cp314-win_amd64.whl", hash = "sha256:cf9022ef053f2694e31d630feaacb21ea24224be1c3ad0520b13d844274614fd", size = 232424, upload-time = "2025-07-26T12:02:31.395Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/18/79/a9416650df9b525737ab521aa181ccc42d56016d2123ddcb7b58e926a42c/contourpy-1.3.3-cp314-cp314-win_arm64.whl", hash = "sha256:95b181891b4c71de4bb404c6621e7e2390745f887f2a026b2d99e92c17892339", size = 198300, upload-time = "2025-07-26T12:02:32.956Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/1f/42/38c159a7d0f2b7b9c04c64ab317042bb6952b713ba875c1681529a2932fe/contourpy-1.3.3-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:33c82d0138c0a062380332c861387650c82e4cf1747aaa6938b9b6516762e772", size = 306769, upload-time = "2025-07-26T12:02:34.2Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/c3/6c/26a8205f24bca10974e77460de68d3d7c63e282e23782f1239f226fcae6f/contourpy-1.3.3-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:ea37e7b45949df430fe649e5de8351c423430046a2af20b1c1961cae3afcda77", size = 287892, upload-time = "2025-07-26T12:02:35.807Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/66/06/8a475c8ab718ebfd7925661747dbb3c3ee9c82ac834ccb3570be49d129f4/contourpy-1.3.3-cp314-cp314t-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:d304906ecc71672e9c89e87c4675dc5c2645e1f4269a5063b99b0bb29f232d13", size = 326748, upload-time = "2025-07-26T12:02:37.193Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/b4/a3/c5ca9f010a44c223f098fccd8b158bb1cb287378a31ac141f04730dc49be/contourpy-1.3.3-cp314-cp314t-manylinux_2_26_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:ca658cd1a680a5c9ea96dc61cdbae1e85c8f25849843aa799dfd3cb370ad4fbe", size = 375554, upload-time = "2025-07-26T12:02:38.894Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/80/5b/68bd33ae63fac658a4145088c1e894405e07584a316738710b636c6d0333/contourpy-1.3.3-cp314-cp314t-manylinux_2_26_s390x.manylinux_2_28_s390x.whl", hash = "sha256:ab2fd90904c503739a75b7c8c5c01160130ba67944a7b77bbf36ef8054576e7f", size = 388118, upload-time = "2025-07-26T12:02:40.642Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/40/52/4c285a6435940ae25d7410a6c36bda5145839bc3f0beb20c707cda18b9d2/contourpy-1.3.3-cp314-cp314t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:b7301b89040075c30e5768810bc96a8e8d78085b47d8be6e4c3f5a0b4ed478a0", size = 352555, upload-time = "2025-07-26T12:02:42.25Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/24/ee/3e81e1dd174f5c7fefe50e85d0892de05ca4e26ef1c9a59c2a57e43b865a/contourpy-1.3.3-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:2a2a8b627d5cc6b7c41a4beff6c5ad5eb848c88255fda4a8745f7e901b32d8e4", size = 1322295, upload-time = "2025-07-26T12:02:44.668Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/3c/b2/6d913d4d04e14379de429057cd169e5e00f6c2af3bb13e1710bcbdb5da12/contourpy-1.3.3-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:fd6ec6be509c787f1caf6b247f0b1ca598bef13f4ddeaa126b7658215529ba0f", size = 1391027, upload-time = "2025-07-26T12:02:47.09Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/93/8a/68a4ec5c55a2971213d29a9374913f7e9f18581945a7a31d1a39b5d2dfe5/contourpy-1.3.3-cp314-cp314t-win32.whl", hash = "sha256:e74a9a0f5e3fff48fb5a7f2fd2b9b70a3fe014a67522f79b7cca4c0c7e43c9ae", size = 202428, upload-time = "2025-07-26T12:02:48.691Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/fa/96/fd9f641ffedc4fa3ace923af73b9d07e869496c9cc7a459103e6e978992f/contourpy-1.3.3-cp314-cp314t-win_amd64.whl", hash = "sha256:13b68d6a62db8eafaebb8039218921399baf6e47bf85006fd8529f2a08ef33fc", size = 250331, upload-time = "2025-07-26T12:02:50.137Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/ae/8c/469afb6465b853afff216f9528ffda78a915ff880ed58813ba4faf4ba0b6/contourpy-1.3.3-cp314-cp314t-win_arm64.whl", hash = "sha256:b7448cb5a725bb1e35ce88771b86fba35ef418952474492cf7c764059933ff8b", size = 203831, upload-time = "2025-07-26T12:02:51.449Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cryptography"
|
||||
version = "42.0.4"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
dependencies = [
|
||||
{ name = "cffi", marker = "platform_python_implementation != 'PyPy'" },
|
||||
]
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/81/d8/214d25515bf6034dce99aba22eeb47443b14c82160114e3d3f33067c6d3b/cryptography-42.0.4.tar.gz", hash = "sha256:831a4b37accef30cccd34fcb916a5d7b5be3cbbe27268a02832c3e450aea39cb", size = 670311, upload-time = "2024-02-21T03:07:29.752Z" }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/08/87/58a38f8f4d0fe388aaceec8d4b91644cc1edfe4fd3b9ccf5dad414f60738/cryptography-42.0.4-cp37-abi3-macosx_10_12_universal2.whl", hash = "sha256:ffc73996c4fca3d2b6c1c8c12bfd3ad00def8621da24f547626bf06441400449", size = 5874004, upload-time = "2024-02-21T03:06:15.711Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/ec/3a/2138a6246804d5d0b588031ad9795c7672317591a9ec2c5962cb65a912c3/cryptography-42.0.4-cp37-abi3-macosx_10_12_x86_64.whl", hash = "sha256:db4b65b02f59035037fde0998974d84244a64c3265bdef32a827ab9b63d61b18", size = 3098630, upload-time = "2024-02-21T03:07:08.813Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/84/3d/f4e69dd3773826c12a7eeb7e7550616c0932e7c4cc3c677023964f137b46/cryptography-42.0.4-cp37-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dad9c385ba8ee025bb0d856714f71d7840020fe176ae0229de618f14dae7a6e2", size = 4371589, upload-time = "2024-02-21T03:06:56.874Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/2f/d1/6ca412147384b0b02cb343a3e8b7d3fde7ac6833c29fee9ca91f59ab5fdf/cryptography-42.0.4-cp37-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:69b22ab6506a3fe483d67d1ed878e1602bdd5912a134e6202c1ec672233241c1", size = 4561822, upload-time = "2024-02-21T03:06:41.423Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/ba/c8/df35ce0519febdf46ebfab1a6ef1278c95a45b060a613fac57de64aa727e/cryptography-42.0.4-cp37-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:e09469a2cec88fb7b078e16d4adec594414397e8879a4341c6ace96013463d5b", size = 4355915, upload-time = "2024-02-21T03:06:34.924Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/35/ed/e8ad5637b8ac1fd1b48fadb11dcf3649083af5c4298dfdc81d0382de9191/cryptography-42.0.4-cp37-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:3e970a2119507d0b104f0a8e281521ad28fc26f2820687b3436b8c9a5fcf20d1", size = 4573394, upload-time = "2024-02-21T03:07:06.381Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/27/98/c4a7fd53fd27619d5baa6102af7833543a8428479b81959942aeb98b278e/cryptography-42.0.4-cp37-abi3-musllinux_1_1_aarch64.whl", hash = "sha256:e53dc41cda40b248ebc40b83b31516487f7db95ab8ceac1f042626bc43a2f992", size = 4471747, upload-time = "2024-02-21T03:06:18.099Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/4a/dc/9beb49116370d8086a10d1dd0b5cbe7816efeebdfda414f3fd09a95b8525/cryptography-42.0.4-cp37-abi3-musllinux_1_1_x86_64.whl", hash = "sha256:c3a5cbc620e1e17009f30dd34cb0d85c987afd21c41a74352d1719be33380885", size = 4646204, upload-time = "2024-02-21T03:06:50.63Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/c0/a8/200e5afdb96ac3ebd4025dcc18cc43e73b1e4f6d839b7f2c9f1eb1a6a6c6/cryptography-42.0.4-cp37-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:6bfadd884e7280df24d26f2186e4e07556a05d37393b0f220a840b083dc6a824", size = 4444931, upload-time = "2024-02-21T03:07:13.485Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/9d/74/3bbe47d186ed91e3fa7ffb4426f39cb63d299842a9c600f4834530599bd4/cryptography-42.0.4-cp37-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:01911714117642a3f1792c7f376db572aadadbafcd8d75bb527166009c9f1d1b", size = 4645892, upload-time = "2024-02-21T03:06:37.021Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/3b/32/6d4907f82d2870959ad3dfc21f0a20b6501c143034d249df852281ae3543/cryptography-42.0.4-cp37-abi3-win32.whl", hash = "sha256:fb0cef872d8193e487fc6bdb08559c3aa41b659a7d9be48b2e10747f47863925", size = 2430337, upload-time = "2024-02-21T03:06:43.879Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/d3/70/08b9cc6690e252541286fcfda770023a27aa0e1a1f8a1df52ee052c0494b/cryptography-42.0.4-cp37-abi3-win_amd64.whl", hash = "sha256:c1f25b252d2c87088abc8bbc4f1ecbf7c919e05508a7e8628e6875c40bc70923", size = 2885772, upload-time = "2024-02-21T03:07:19.763Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/ba/71/b9ed937252fad47d8d24746b876ca6f2dc31bd495e78f5b77a5082d73ae2/cryptography-42.0.4-cp39-abi3-macosx_10_12_universal2.whl", hash = "sha256:15a1fb843c48b4a604663fa30af60818cd28f895572386e5f9b8a665874c26e7", size = 5873636, upload-time = "2024-02-21T03:06:55.038Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/44/61/644e21048102cd72a13325fd6443db741746fbf0157e7c5d5c7628afc336/cryptography-42.0.4-cp39-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a1327f280c824ff7885bdeef8578f74690e9079267c1c8bd7dc5cc5aa065ae52", size = 4372889, upload-time = "2024-02-21T03:06:25.409Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/32/c2/4ff3cf950504aa6ccd3db3712f515151536eea0cf6125442015b0532a46d/cryptography-42.0.4-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6ffb03d419edcab93b4b19c22ee80c007fb2d708429cecebf1dd3258956a563a", size = 4561544, upload-time = "2024-02-21T03:06:20.715Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/4c/e1/18056b2c0e4ba031ea6b9d660bc2bdf491f7ef64ab7ef1a803a03a8b8d26/cryptography-42.0.4-cp39-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:1df6fcbf60560d2113b5ed90f072dc0b108d64750d4cbd46a21ec882c7aefce9", size = 4357160, upload-time = "2024-02-21T03:07:22.468Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/7e/45/81f378eb85aab14b229c1032ba3694eff85a3d75b35092c3e71abd2d34f6/cryptography-42.0.4-cp39-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:44a64043f743485925d3bcac548d05df0f9bb445c5fcca6681889c7c3ab12764", size = 4573002, upload-time = "2024-02-21T03:07:04.598Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/ea/a1/04733ecbe1e77a228c738f4ab321ca050e45284997f3e3a1539461cd4bca/cryptography-42.0.4-cp39-abi3-musllinux_1_1_aarch64.whl", hash = "sha256:3c6048f217533d89f2f8f4f0fe3044bf0b2090453b7b73d0b77db47b80af8dff", size = 4471962, upload-time = "2024-02-21T03:06:12.027Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/41/5d/33f17e40dbb7441ad51e8a6920e726f68443cdbfb388cb8eff53e4b6ffd4/cryptography-42.0.4-cp39-abi3-musllinux_1_1_x86_64.whl", hash = "sha256:6d0fbe73728c44ca3a241eff9aefe6496ab2656d6e7a4ea2459865f2e8613257", size = 4646395, upload-time = "2024-02-21T03:06:23.044Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/da/56/1b2c8aa8e62bfb568022b68d77ebd2bd9afddea37898350fbfe008dcefa7/cryptography-42.0.4-cp39-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:887623fe0d70f48ab3f5e4dbf234986b1329a64c066d719432d0698522749929", size = 4445612, upload-time = "2024-02-21T03:06:58.673Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/a2/8e/dac70232d4231c53448e29aa4b768cf82d891fcfd6e0caa7ace242da8c9b/cryptography-42.0.4-cp39-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:ce8613beaffc7c14f091497346ef117c1798c202b01153a8cc7b8e2ebaaf41c0", size = 4646026, upload-time = "2024-02-21T03:06:33.094Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/a7/d7/8b9d29cf3745b928a71b1f6c3c54366272d8d67181d1f056309992d19640/cryptography-42.0.4-cp39-abi3-win32.whl", hash = "sha256:810bcf151caefc03e51a3d61e53335cd5c7316c0a105cc695f0959f2c638b129", size = 2430620, upload-time = "2024-02-21T03:07:17.818Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/af/df/c220c1be23d1f0ee55f4d1589203936cfa221f95ac5d1b1b342109c1143e/cryptography-42.0.4-cp39-abi3-win_amd64.whl", hash = "sha256:a0298bdc6e98ca21382afe914c642620370ce0470a01e1bef6dd9b5354c36854", size = 2887348, upload-time = "2024-02-21T03:06:27.929Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cycler"
|
||||
version = "0.12.1"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/a9/95/a3dbbb5028f35eafb79008e7522a75244477d2838f38cbb722248dabc2a8/cycler-0.12.1.tar.gz", hash = "sha256:88bb128f02ba341da8ef447245a9e138fae777f6a23943da4540077d3601eb1c", size = 7615, upload-time = "2023-10-07T05:32:18.335Z" }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/e7/05/c19819d5e3d95294a6f5947fb9b9629efb316b96de511b418c53d245aae6/cycler-0.12.1-py3-none-any.whl", hash = "sha256:85cef7cff222d8644161529808465972e51340599459b8ac3ccbac5a854e0d30", size = 8321, upload-time = "2023-10-07T05:32:16.783Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ecdsa"
|
||||
version = "0.19.1"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
dependencies = [
|
||||
{ name = "six" },
|
||||
]
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/c0/1f/924e3caae75f471eae4b26bd13b698f6af2c44279f67af317439c2f4c46a/ecdsa-0.19.1.tar.gz", hash = "sha256:478cba7b62555866fcb3bb3fe985e06decbdb68ef55713c4e5ab98c57d508e61", size = 201793, upload-time = "2025-03-13T11:52:43.25Z" }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/cb/a3/460c57f094a4a165c84a1341c373b0a4f5ec6ac244b998d5021aade89b77/ecdsa-0.19.1-py2.py3-none-any.whl", hash = "sha256:30638e27cf77b7e15c4c4cc1973720149e1033827cfd00661ca5c8cc0cdb24c3", size = 150607, upload-time = "2025-03-13T11:52:41.757Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "fonttools"
|
||||
version = "4.61.1"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/ec/ca/cf17b88a8df95691275a3d77dc0a5ad9907f328ae53acbe6795da1b2f5ed/fonttools-4.61.1.tar.gz", hash = "sha256:6675329885c44657f826ef01d9e4fb33b9158e9d93c537d84ad8399539bc6f69", size = 3565756, upload-time = "2025-12-12T17:31:24.246Z" }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/6f/16/7decaa24a1bd3a70c607b2e29f0adc6159f36a7e40eaba59846414765fd4/fonttools-4.61.1-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:f3cb4a569029b9f291f88aafc927dd53683757e640081ca8c412781ea144565e", size = 2851593, upload-time = "2025-12-12T17:30:04.225Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/94/98/3c4cb97c64713a8cf499b3245c3bf9a2b8fd16a3e375feff2aed78f96259/fonttools-4.61.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:41a7170d042e8c0024703ed13b71893519a1a6d6e18e933e3ec7507a2c26a4b2", size = 2400231, upload-time = "2025-12-12T17:30:06.47Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/b7/37/82dbef0f6342eb01f54bca073ac1498433d6ce71e50c3c3282b655733b31/fonttools-4.61.1-cp312-cp312-manylinux1_x86_64.manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:10d88e55330e092940584774ee5e8a6971b01fc2f4d3466a1d6c158230880796", size = 4954103, upload-time = "2025-12-12T17:30:08.432Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/6c/44/f3aeac0fa98e7ad527f479e161aca6c3a1e47bb6996b053d45226fe37bf2/fonttools-4.61.1-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:15acc09befd16a0fb8a8f62bc147e1a82817542d72184acca9ce6e0aeda9fa6d", size = 5004295, upload-time = "2025-12-12T17:30:10.56Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/14/e8/7424ced75473983b964d09f6747fa09f054a6d656f60e9ac9324cf40c743/fonttools-4.61.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:e6bcdf33aec38d16508ce61fd81838f24c83c90a1d1b8c68982857038673d6b8", size = 4944109, upload-time = "2025-12-12T17:30:12.874Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/c8/8b/6391b257fa3d0b553d73e778f953a2f0154292a7a7a085e2374b111e5410/fonttools-4.61.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:5fade934607a523614726119164ff621e8c30e8fa1ffffbbd358662056ba69f0", size = 5093598, upload-time = "2025-12-12T17:30:15.79Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/d9/71/fd2ea96cdc512d92da5678a1c98c267ddd4d8c5130b76d0f7a80f9a9fde8/fonttools-4.61.1-cp312-cp312-win32.whl", hash = "sha256:75da8f28eff26defba42c52986de97b22106cb8f26515b7c22443ebc9c2d3261", size = 2269060, upload-time = "2025-12-12T17:30:18.058Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/80/3b/a3e81b71aed5a688e89dfe0e2694b26b78c7d7f39a5ffd8a7d75f54a12a8/fonttools-4.61.1-cp312-cp312-win_amd64.whl", hash = "sha256:497c31ce314219888c0e2fce5ad9178ca83fe5230b01a5006726cdf3ac9f24d9", size = 2319078, upload-time = "2025-12-12T17:30:22.862Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/4b/cf/00ba28b0990982530addb8dc3e9e6f2fa9cb5c20df2abdda7baa755e8fe1/fonttools-4.61.1-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:8c56c488ab471628ff3bfa80964372fc13504ece601e0d97a78ee74126b2045c", size = 2846454, upload-time = "2025-12-12T17:30:24.938Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/5a/ca/468c9a8446a2103ae645d14fee3f610567b7042aba85031c1c65e3ef7471/fonttools-4.61.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:dc492779501fa723b04d0ab1f5be046797fee17d27700476edc7ee9ae535a61e", size = 2398191, upload-time = "2025-12-12T17:30:27.343Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/a3/4b/d67eedaed19def5967fade3297fed8161b25ba94699efc124b14fb68cdbc/fonttools-4.61.1-cp313-cp313-manylinux1_x86_64.manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:64102ca87e84261419c3747a0d20f396eb024bdbeb04c2bfb37e2891f5fadcb5", size = 4928410, upload-time = "2025-12-12T17:30:29.771Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/b0/8d/6fb3494dfe61a46258cd93d979cf4725ded4eb46c2a4ca35e4490d84daea/fonttools-4.61.1-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:4c1b526c8d3f615a7b1867f38a9410849c8f4aef078535742198e942fba0e9bd", size = 4984460, upload-time = "2025-12-12T17:30:32.073Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/f7/f1/a47f1d30b3dc00d75e7af762652d4cbc3dff5c2697a0dbd5203c81afd9c3/fonttools-4.61.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:41ed4b5ec103bd306bb68f81dc166e77409e5209443e5773cb4ed837bcc9b0d3", size = 4925800, upload-time = "2025-12-12T17:30:34.339Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/a7/01/e6ae64a0981076e8a66906fab01539799546181e32a37a0257b77e4aa88b/fonttools-4.61.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:b501c862d4901792adaec7c25b1ecc749e2662543f68bb194c42ba18d6eec98d", size = 5067859, upload-time = "2025-12-12T17:30:36.593Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/73/aa/28e40b8d6809a9b5075350a86779163f074d2b617c15d22343fce81918db/fonttools-4.61.1-cp313-cp313-win32.whl", hash = "sha256:4d7092bb38c53bbc78e9255a59158b150bcdc115a1e3b3ce0b5f267dc35dd63c", size = 2267821, upload-time = "2025-12-12T17:30:38.478Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/1a/59/453c06d1d83dc0951b69ef692d6b9f1846680342927df54e9a1ca91c6f90/fonttools-4.61.1-cp313-cp313-win_amd64.whl", hash = "sha256:21e7c8d76f62ab13c9472ccf74515ca5b9a761d1bde3265152a6dc58700d895b", size = 2318169, upload-time = "2025-12-12T17:30:40.951Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/32/8f/4e7bf82c0cbb738d3c2206c920ca34ca74ef9dabde779030145d28665104/fonttools-4.61.1-cp314-cp314-macosx_10_15_universal2.whl", hash = "sha256:fff4f534200a04b4a36e7ae3cb74493afe807b517a09e99cb4faa89a34ed6ecd", size = 2846094, upload-time = "2025-12-12T17:30:43.511Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/71/09/d44e45d0a4f3a651f23a1e9d42de43bc643cce2971b19e784cc67d823676/fonttools-4.61.1-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:d9203500f7c63545b4ce3799319fe4d9feb1a1b89b28d3cb5abd11b9dd64147e", size = 2396589, upload-time = "2025-12-12T17:30:45.681Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/89/18/58c64cafcf8eb677a99ef593121f719e6dcbdb7d1c594ae5a10d4997ca8a/fonttools-4.61.1-cp314-cp314-manylinux1_x86_64.manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:fa646ecec9528bef693415c79a86e733c70a4965dd938e9a226b0fc64c9d2e6c", size = 4877892, upload-time = "2025-12-12T17:30:47.709Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/8a/ec/9e6b38c7ba1e09eb51db849d5450f4c05b7e78481f662c3b79dbde6f3d04/fonttools-4.61.1-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:11f35ad7805edba3aac1a3710d104592df59f4b957e30108ae0ba6c10b11dd75", size = 4972884, upload-time = "2025-12-12T17:30:49.656Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/5e/87/b5339da8e0256734ba0dbbf5b6cdebb1dd79b01dc8c270989b7bcd465541/fonttools-4.61.1-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:b931ae8f62db78861b0ff1ac017851764602288575d65b8e8ff1963fed419063", size = 4924405, upload-time = "2025-12-12T17:30:51.735Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/0b/47/e3409f1e1e69c073a3a6fd8cb886eb18c0bae0ee13db2c8d5e7f8495e8b7/fonttools-4.61.1-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:b148b56f5de675ee16d45e769e69f87623a4944f7443850bf9a9376e628a89d2", size = 5035553, upload-time = "2025-12-12T17:30:54.823Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/bf/b6/1f6600161b1073a984294c6c031e1a56ebf95b6164249eecf30012bb2e38/fonttools-4.61.1-cp314-cp314-win32.whl", hash = "sha256:9b666a475a65f4e839d3d10473fad6d47e0a9db14a2f4a224029c5bfde58ad2c", size = 2271915, upload-time = "2025-12-12T17:30:57.913Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/52/7b/91e7b01e37cc8eb0e1f770d08305b3655e4f002fc160fb82b3390eabacf5/fonttools-4.61.1-cp314-cp314-win_amd64.whl", hash = "sha256:4f5686e1fe5fce75d82d93c47a438a25bf0d1319d2843a926f741140b2b16e0c", size = 2323487, upload-time = "2025-12-12T17:30:59.804Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/39/5c/908ad78e46c61c3e3ed70c3b58ff82ab48437faf84ec84f109592cabbd9f/fonttools-4.61.1-cp314-cp314t-macosx_10_15_universal2.whl", hash = "sha256:e76ce097e3c57c4bcb67c5aa24a0ecdbd9f74ea9219997a707a4061fbe2707aa", size = 2929571, upload-time = "2025-12-12T17:31:02.574Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/bd/41/975804132c6dea64cdbfbaa59f3518a21c137a10cccf962805b301ac6ab2/fonttools-4.61.1-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:9cfef3ab326780c04d6646f68d4b4742aae222e8b8ea1d627c74e38afcbc9d91", size = 2435317, upload-time = "2025-12-12T17:31:04.974Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/b0/5a/aef2a0a8daf1ebaae4cfd83f84186d4a72ee08fd6a8451289fcd03ffa8a4/fonttools-4.61.1-cp314-cp314t-manylinux1_x86_64.manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:a75c301f96db737e1c5ed5fd7d77d9c34466de16095a266509e13da09751bd19", size = 4882124, upload-time = "2025-12-12T17:31:07.456Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/80/33/d6db3485b645b81cea538c9d1c9219d5805f0877fda18777add4671c5240/fonttools-4.61.1-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:91669ccac46bbc1d09e9273546181919064e8df73488ea087dcac3e2968df9ba", size = 5100391, upload-time = "2025-12-12T17:31:09.732Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/6c/d6/675ba631454043c75fcf76f0ca5463eac8eb0666ea1d7badae5fea001155/fonttools-4.61.1-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:c33ab3ca9d3ccd581d58e989d67554e42d8d4ded94ab3ade3508455fe70e65f7", size = 4978800, upload-time = "2025-12-12T17:31:11.681Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/7f/33/d3ec753d547a8d2bdaedd390d4a814e8d5b45a093d558f025c6b990b554c/fonttools-4.61.1-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:664c5a68ec406f6b1547946683008576ef8b38275608e1cee6c061828171c118", size = 5006426, upload-time = "2025-12-12T17:31:13.764Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/b4/40/cc11f378b561a67bea850ab50063366a0d1dd3f6d0a30ce0f874b0ad5664/fonttools-4.61.1-cp314-cp314t-win32.whl", hash = "sha256:aed04cabe26f30c1647ef0e8fbb207516fd40fe9472e9439695f5c6998e60ac5", size = 2335377, upload-time = "2025-12-12T17:31:16.49Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/e4/ff/c9a2b66b39f8628531ea58b320d66d951267c98c6a38684daa8f50fb02f8/fonttools-4.61.1-cp314-cp314t-win_amd64.whl", hash = "sha256:2180f14c141d2f0f3da43f3a81bc8aa4684860f6b0e6f9e165a4831f24e6a23b", size = 2400613, upload-time = "2025-12-12T17:31:18.769Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/c7/4e/ce75a57ff3aebf6fc1f4e9d508b8e5810618a33d900ad6c19eb30b290b97/fonttools-4.61.1-py3-none-any.whl", hash = "sha256:17d2bf5d541add43822bcf0c43d7d847b160c9bb01d15d5007d84e2217aaa371", size = 1148996, upload-time = "2025-12-12T17:31:21.03Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "greenlet"
|
||||
version = "3.3.0"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/c7/e5/40dbda2736893e3e53d25838e0f19a2b417dfc122b9989c91918db30b5d3/greenlet-3.3.0.tar.gz", hash = "sha256:a82bb225a4e9e4d653dd2fb7b8b2d36e4fb25bc0165422a11e48b88e9e6f78fb", size = 190651, upload-time = "2025-12-04T14:49:44.05Z" }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/f8/0a/a3871375c7b9727edaeeea994bfff7c63ff7804c9829c19309ba2e058807/greenlet-3.3.0-cp312-cp312-macosx_11_0_universal2.whl", hash = "sha256:b01548f6e0b9e9784a2c99c5651e5dc89ffcbe870bc5fb2e5ef864e9cc6b5dcb", size = 276379, upload-time = "2025-12-04T14:23:30.498Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/43/ab/7ebfe34dce8b87be0d11dae91acbf76f7b8246bf9d6b319c741f99fa59c6/greenlet-3.3.0-cp312-cp312-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:349345b770dc88f81506c6861d22a6ccd422207829d2c854ae2af8025af303e3", size = 597294, upload-time = "2025-12-04T14:50:06.847Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/a4/39/f1c8da50024feecd0793dbd5e08f526809b8ab5609224a2da40aad3a7641/greenlet-3.3.0-cp312-cp312-manylinux_2_24_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:e8e18ed6995e9e2c0b4ed264d2cf89260ab3ac7e13555b8032b25a74c6d18655", size = 607742, upload-time = "2025-12-04T14:57:42.349Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/77/cb/43692bcd5f7a0da6ec0ec6d58ee7cddb606d055ce94a62ac9b1aa481e969/greenlet-3.3.0-cp312-cp312-manylinux_2_24_s390x.manylinux_2_28_s390x.whl", hash = "sha256:c024b1e5696626890038e34f76140ed1daf858e37496d33f2af57f06189e70d7", size = 622297, upload-time = "2025-12-04T15:07:13.552Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/75/b0/6bde0b1011a60782108c01de5913c588cf51a839174538d266de15e4bf4d/greenlet-3.3.0-cp312-cp312-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:047ab3df20ede6a57c35c14bf5200fcf04039d50f908270d3f9a7a82064f543b", size = 609885, upload-time = "2025-12-04T14:26:02.368Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/49/0e/49b46ac39f931f59f987b7cd9f34bfec8ef81d2a1e6e00682f55be5de9f4/greenlet-3.3.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:2d9ad37fc657b1102ec880e637cccf20191581f75c64087a549e66c57e1ceb53", size = 1567424, upload-time = "2025-12-04T15:04:23.757Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/05/f5/49a9ac2dff7f10091935def9165c90236d8f175afb27cbed38fb1d61ab6b/greenlet-3.3.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:83cd0e36932e0e7f36a64b732a6f60c2fc2df28c351bae79fbaf4f8092fe7614", size = 1636017, upload-time = "2025-12-04T14:27:29.688Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/6c/79/3912a94cf27ec503e51ba493692d6db1e3cd8ac7ac52b0b47c8e33d7f4f9/greenlet-3.3.0-cp312-cp312-win_amd64.whl", hash = "sha256:a7a34b13d43a6b78abf828a6d0e87d3385680eaf830cd60d20d52f249faabf39", size = 301964, upload-time = "2025-12-04T14:36:58.316Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/02/2f/28592176381b9ab2cafa12829ba7b472d177f3acc35d8fbcf3673d966fff/greenlet-3.3.0-cp313-cp313-macosx_11_0_universal2.whl", hash = "sha256:a1e41a81c7e2825822f4e068c48cb2196002362619e2d70b148f20a831c00739", size = 275140, upload-time = "2025-12-04T14:23:01.282Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/2c/80/fbe937bf81e9fca98c981fe499e59a3f45df2a04da0baa5c2be0dca0d329/greenlet-3.3.0-cp313-cp313-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:9f515a47d02da4d30caaa85b69474cec77b7929b2e936ff7fb853d42f4bf8808", size = 599219, upload-time = "2025-12-04T14:50:08.309Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/c2/ff/7c985128f0514271b8268476af89aee6866df5eec04ac17dcfbc676213df/greenlet-3.3.0-cp313-cp313-manylinux_2_24_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:7d2d9fd66bfadf230b385fdc90426fcd6eb64db54b40c495b72ac0feb5766c54", size = 610211, upload-time = "2025-12-04T14:57:43.968Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/79/07/c47a82d881319ec18a4510bb30463ed6891f2ad2c1901ed5ec23d3de351f/greenlet-3.3.0-cp313-cp313-manylinux_2_24_s390x.manylinux_2_28_s390x.whl", hash = "sha256:30a6e28487a790417d036088b3bcb3f3ac7d8babaa7d0139edbaddebf3af9492", size = 624311, upload-time = "2025-12-04T15:07:14.697Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/fd/8e/424b8c6e78bd9837d14ff7df01a9829fc883ba2ab4ea787d4f848435f23f/greenlet-3.3.0-cp313-cp313-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:087ea5e004437321508a8d6f20efc4cfec5e3c30118e1417ea96ed1d93950527", size = 612833, upload-time = "2025-12-04T14:26:03.669Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/b5/ba/56699ff9b7c76ca12f1cdc27a886d0f81f2189c3455ff9f65246780f713d/greenlet-3.3.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:ab97cf74045343f6c60a39913fa59710e4bd26a536ce7ab2397adf8b27e67c39", size = 1567256, upload-time = "2025-12-04T15:04:25.276Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/1e/37/f31136132967982d698c71a281a8901daf1a8fbab935dce7c0cf15f942cc/greenlet-3.3.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:5375d2e23184629112ca1ea89a53389dddbffcf417dad40125713d88eb5f96e8", size = 1636483, upload-time = "2025-12-04T14:27:30.804Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/7e/71/ba21c3fb8c5dce83b8c01f458a42e99ffdb1963aeec08fff5a18588d8fd7/greenlet-3.3.0-cp313-cp313-win_amd64.whl", hash = "sha256:9ee1942ea19550094033c35d25d20726e4f1c40d59545815e1128ac58d416d38", size = 301833, upload-time = "2025-12-04T14:32:23.929Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/d7/7c/f0a6d0ede2c7bf092d00bc83ad5bafb7e6ec9b4aab2fbdfa6f134dc73327/greenlet-3.3.0-cp314-cp314-macosx_11_0_universal2.whl", hash = "sha256:60c2ef0f578afb3c8d92ea07ad327f9a062547137afe91f38408f08aacab667f", size = 275671, upload-time = "2025-12-04T14:23:05.267Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/44/06/dac639ae1a50f5969d82d2e3dd9767d30d6dbdbab0e1a54010c8fe90263c/greenlet-3.3.0-cp314-cp314-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:0a5d554d0712ba1de0a6c94c640f7aeba3f85b3a6e1f2899c11c2c0428da9365", size = 646360, upload-time = "2025-12-04T14:50:10.026Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/e0/94/0fb76fe6c5369fba9bf98529ada6f4c3a1adf19e406a47332245ef0eb357/greenlet-3.3.0-cp314-cp314-manylinux_2_24_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:3a898b1e9c5f7307ebbde4102908e6cbfcb9ea16284a3abe15cab996bee8b9b3", size = 658160, upload-time = "2025-12-04T14:57:45.41Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/93/79/d2c70cae6e823fac36c3bbc9077962105052b7ef81db2f01ec3b9bf17e2b/greenlet-3.3.0-cp314-cp314-manylinux_2_24_s390x.manylinux_2_28_s390x.whl", hash = "sha256:dcd2bdbd444ff340e8d6bdf54d2f206ccddbb3ccfdcd3c25bf4afaa7b8f0cf45", size = 671388, upload-time = "2025-12-04T15:07:15.789Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/b8/14/bab308fc2c1b5228c3224ec2bf928ce2e4d21d8046c161e44a2012b5203e/greenlet-3.3.0-cp314-cp314-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:5773edda4dc00e173820722711d043799d3adb4f01731f40619e07ea2750b955", size = 660166, upload-time = "2025-12-04T14:26:05.099Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/4b/d2/91465d39164eaa0085177f61983d80ffe746c5a1860f009811d498e7259c/greenlet-3.3.0-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:ac0549373982b36d5fd5d30beb8a7a33ee541ff98d2b502714a09f1169f31b55", size = 1615193, upload-time = "2025-12-04T15:04:27.041Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/42/1b/83d110a37044b92423084d52d5d5a3b3a73cafb51b547e6d7366ff62eff1/greenlet-3.3.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:d198d2d977460358c3b3a4dc844f875d1adb33817f0613f663a656f463764ccc", size = 1683653, upload-time = "2025-12-04T14:27:32.366Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/7c/9a/9030e6f9aa8fd7808e9c31ba4c38f87c4f8ec324ee67431d181fe396d705/greenlet-3.3.0-cp314-cp314-win_amd64.whl", hash = "sha256:73f51dd0e0bdb596fb0417e475fa3c5e32d4c83638296e560086b8d7da7c4170", size = 305387, upload-time = "2025-12-04T14:26:51.063Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/a0/66/bd6317bc5932accf351fc19f177ffba53712a202f9df10587da8df257c7e/greenlet-3.3.0-cp314-cp314t-macosx_11_0_universal2.whl", hash = "sha256:d6ed6f85fae6cdfdb9ce04c9bf7a08d666cfcfb914e7d006f44f840b46741931", size = 282638, upload-time = "2025-12-04T14:25:20.941Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/30/cf/cc81cb030b40e738d6e69502ccbd0dd1bced0588e958f9e757945de24404/greenlet-3.3.0-cp314-cp314t-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:d9125050fcf24554e69c4cacb086b87b3b55dc395a8b3ebe6487b045b2614388", size = 651145, upload-time = "2025-12-04T14:50:11.039Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/9c/ea/1020037b5ecfe95ca7df8d8549959baceb8186031da83d5ecceff8b08cd2/greenlet-3.3.0-cp314-cp314t-manylinux_2_24_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:87e63ccfa13c0a0f6234ed0add552af24cc67dd886731f2261e46e241608bee3", size = 654236, upload-time = "2025-12-04T14:57:47.007Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/69/cc/1e4bae2e45ca2fa55299f4e85854606a78ecc37fead20d69322f96000504/greenlet-3.3.0-cp314-cp314t-manylinux_2_24_s390x.manylinux_2_28_s390x.whl", hash = "sha256:2662433acbca297c9153a4023fe2161c8dcfdcc91f10433171cf7e7d94ba2221", size = 662506, upload-time = "2025-12-04T15:07:16.906Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/57/b9/f8025d71a6085c441a7eaff0fd928bbb275a6633773667023d19179fe815/greenlet-3.3.0-cp314-cp314t-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:3c6e9b9c1527a78520357de498b0e709fb9e2f49c3a513afd5a249007261911b", size = 653783, upload-time = "2025-12-04T14:26:06.225Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/f6/c7/876a8c7a7485d5d6b5c6821201d542ef28be645aa024cfe1145b35c120c1/greenlet-3.3.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:286d093f95ec98fdd92fcb955003b8a3d054b4e2cab3e2707a5039e7b50520fd", size = 1614857, upload-time = "2025-12-04T15:04:28.484Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/4f/dc/041be1dff9f23dac5f48a43323cd0789cb798342011c19a248d9c9335536/greenlet-3.3.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:6c10513330af5b8ae16f023e8ddbfb486ab355d04467c4679c5cfe4659975dd9", size = 1676034, upload-time = "2025-12-04T14:27:33.531Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "idna"
|
||||
version = "3.11"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/6f/6d/0703ccc57f3a7233505399edb88de3cbd678da106337b9fcde432b65ed60/idna-3.11.tar.gz", hash = "sha256:795dafcc9c04ed0c1fb032c2aa73654d8e8c5023a7df64a53f39190ada629902", size = 194582, upload-time = "2025-10-12T14:55:20.501Z" }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/0e/61/66938bbb5fc52dbdf84594873d5b51fb1f7c7794e9c0f5bd885f30bc507b/idna-3.11-py3-none-any.whl", hash = "sha256:771a87f49d9defaf64091e6e6fe9c18d4833f140bd19464795bc32d966ca37ea", size = 71008, upload-time = "2025-10-12T14:55:18.883Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "kiwisolver"
|
||||
version = "1.4.9"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/5c/3c/85844f1b0feb11ee581ac23fe5fce65cd049a200c1446708cc1b7f922875/kiwisolver-1.4.9.tar.gz", hash = "sha256:c3b22c26c6fd6811b0ae8363b95ca8ce4ea3c202d3d0975b2914310ceb1bcc4d", size = 97564, upload-time = "2025-08-10T21:27:49.279Z" }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/86/c9/13573a747838aeb1c76e3267620daa054f4152444d1f3d1a2324b78255b5/kiwisolver-1.4.9-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:ac5a486ac389dddcc5bef4f365b6ae3ffff2c433324fb38dd35e3fab7c957999", size = 123686, upload-time = "2025-08-10T21:26:10.034Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/51/ea/2ecf727927f103ffd1739271ca19c424d0e65ea473fbaeea1c014aea93f6/kiwisolver-1.4.9-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:f2ba92255faa7309d06fe44c3a4a97efe1c8d640c2a79a5ef728b685762a6fd2", size = 66460, upload-time = "2025-08-10T21:26:11.083Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/5b/5a/51f5464373ce2aeb5194508298a508b6f21d3867f499556263c64c621914/kiwisolver-1.4.9-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:4a2899935e724dd1074cb568ce7ac0dce28b2cd6ab539c8e001a8578eb106d14", size = 64952, upload-time = "2025-08-10T21:26:12.058Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/70/90/6d240beb0f24b74371762873e9b7f499f1e02166a2d9c5801f4dbf8fa12e/kiwisolver-1.4.9-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:f6008a4919fdbc0b0097089f67a1eb55d950ed7e90ce2cc3e640abadd2757a04", size = 1474756, upload-time = "2025-08-10T21:26:13.096Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/12/42/f36816eaf465220f683fb711efdd1bbf7a7005a2473d0e4ed421389bd26c/kiwisolver-1.4.9-cp312-cp312-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:67bb8b474b4181770f926f7b7d2f8c0248cbcb78b660fdd41a47054b28d2a752", size = 1276404, upload-time = "2025-08-10T21:26:14.457Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/2e/64/bc2de94800adc830c476dce44e9b40fd0809cddeef1fde9fcf0f73da301f/kiwisolver-1.4.9-cp312-cp312-manylinux_2_24_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:2327a4a30d3ee07d2fbe2e7933e8a37c591663b96ce42a00bc67461a87d7df77", size = 1294410, upload-time = "2025-08-10T21:26:15.73Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/5f/42/2dc82330a70aa8e55b6d395b11018045e58d0bb00834502bf11509f79091/kiwisolver-1.4.9-cp312-cp312-manylinux_2_24_s390x.manylinux_2_28_s390x.whl", hash = "sha256:7a08b491ec91b1d5053ac177afe5290adacf1f0f6307d771ccac5de30592d198", size = 1343631, upload-time = "2025-08-10T21:26:17.045Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/22/fd/f4c67a6ed1aab149ec5a8a401c323cee7a1cbe364381bb6c9c0d564e0e20/kiwisolver-1.4.9-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:d8fc5c867c22b828001b6a38d2eaeb88160bf5783c6cb4a5e440efc981ce286d", size = 2224963, upload-time = "2025-08-10T21:26:18.737Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/45/aa/76720bd4cb3713314677d9ec94dcc21ced3f1baf4830adde5bb9b2430a5f/kiwisolver-1.4.9-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:3b3115b2581ea35bb6d1f24a4c90af37e5d9b49dcff267eeed14c3893c5b86ab", size = 2321295, upload-time = "2025-08-10T21:26:20.11Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/80/19/d3ec0d9ab711242f56ae0dc2fc5d70e298bb4a1f9dfab44c027668c673a1/kiwisolver-1.4.9-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:858e4c22fb075920b96a291928cb7dea5644e94c0ee4fcd5af7e865655e4ccf2", size = 2487987, upload-time = "2025-08-10T21:26:21.49Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/39/e9/61e4813b2c97e86b6fdbd4dd824bf72d28bcd8d4849b8084a357bc0dd64d/kiwisolver-1.4.9-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:ed0fecd28cc62c54b262e3736f8bb2512d8dcfdc2bcf08be5f47f96bf405b145", size = 2291817, upload-time = "2025-08-10T21:26:22.812Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/a0/41/85d82b0291db7504da3c2defe35c9a8a5c9803a730f297bd823d11d5fb77/kiwisolver-1.4.9-cp312-cp312-win_amd64.whl", hash = "sha256:f68208a520c3d86ea51acf688a3e3002615a7f0238002cccc17affecc86a8a54", size = 73895, upload-time = "2025-08-10T21:26:24.37Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/e2/92/5f3068cf15ee5cb624a0c7596e67e2a0bb2adee33f71c379054a491d07da/kiwisolver-1.4.9-cp312-cp312-win_arm64.whl", hash = "sha256:2c1a4f57df73965f3f14df20b80ee29e6a7930a57d2d9e8491a25f676e197c60", size = 64992, upload-time = "2025-08-10T21:26:25.732Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/31/c1/c2686cda909742ab66c7388e9a1a8521a59eb89f8bcfbee28fc980d07e24/kiwisolver-1.4.9-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:a5d0432ccf1c7ab14f9949eec60c5d1f924f17c037e9f8b33352fa05799359b8", size = 123681, upload-time = "2025-08-10T21:26:26.725Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/ca/f0/f44f50c9f5b1a1860261092e3bc91ecdc9acda848a8b8c6abfda4a24dd5c/kiwisolver-1.4.9-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:efb3a45b35622bb6c16dbfab491a8f5a391fe0e9d45ef32f4df85658232ca0e2", size = 66464, upload-time = "2025-08-10T21:26:27.733Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/2d/7a/9d90a151f558e29c3936b8a47ac770235f436f2120aca41a6d5f3d62ae8d/kiwisolver-1.4.9-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:1a12cf6398e8a0a001a059747a1cbf24705e18fe413bc22de7b3d15c67cffe3f", size = 64961, upload-time = "2025-08-10T21:26:28.729Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/e9/e9/f218a2cb3a9ffbe324ca29a9e399fa2d2866d7f348ec3a88df87fc248fc5/kiwisolver-1.4.9-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:b67e6efbf68e077dd71d1a6b37e43e1a99d0bff1a3d51867d45ee8908b931098", size = 1474607, upload-time = "2025-08-10T21:26:29.798Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/d9/28/aac26d4c882f14de59041636292bc838db8961373825df23b8eeb807e198/kiwisolver-1.4.9-cp313-cp313-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:5656aa670507437af0207645273ccdfee4f14bacd7f7c67a4306d0dcaeaf6eed", size = 1276546, upload-time = "2025-08-10T21:26:31.401Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/8b/ad/8bfc1c93d4cc565e5069162f610ba2f48ff39b7de4b5b8d93f69f30c4bed/kiwisolver-1.4.9-cp313-cp313-manylinux_2_24_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:bfc08add558155345129c7803b3671cf195e6a56e7a12f3dde7c57d9b417f525", size = 1294482, upload-time = "2025-08-10T21:26:32.721Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/da/f1/6aca55ff798901d8ce403206d00e033191f63d82dd708a186e0ed2067e9c/kiwisolver-1.4.9-cp313-cp313-manylinux_2_24_s390x.manylinux_2_28_s390x.whl", hash = "sha256:40092754720b174e6ccf9e845d0d8c7d8e12c3d71e7fc35f55f3813e96376f78", size = 1343720, upload-time = "2025-08-10T21:26:34.032Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/d1/91/eed031876c595c81d90d0f6fc681ece250e14bf6998c3d7c419466b523b7/kiwisolver-1.4.9-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:497d05f29a1300d14e02e6441cf0f5ee81c1ff5a304b0d9fb77423974684e08b", size = 2224907, upload-time = "2025-08-10T21:26:35.824Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/e9/ec/4d1925f2e49617b9cca9c34bfa11adefad49d00db038e692a559454dfb2e/kiwisolver-1.4.9-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:bdd1a81a1860476eb41ac4bc1e07b3f07259e6d55bbf739b79c8aaedcf512799", size = 2321334, upload-time = "2025-08-10T21:26:37.534Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/43/cb/450cd4499356f68802750c6ddc18647b8ea01ffa28f50d20598e0befe6e9/kiwisolver-1.4.9-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:e6b93f13371d341afee3be9f7c5964e3fe61d5fa30f6a30eb49856935dfe4fc3", size = 2488313, upload-time = "2025-08-10T21:26:39.191Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/71/67/fc76242bd99f885651128a5d4fa6083e5524694b7c88b489b1b55fdc491d/kiwisolver-1.4.9-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:d75aa530ccfaa593da12834b86a0724f58bff12706659baa9227c2ccaa06264c", size = 2291970, upload-time = "2025-08-10T21:26:40.828Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/75/bd/f1a5d894000941739f2ae1b65a32892349423ad49c2e6d0771d0bad3fae4/kiwisolver-1.4.9-cp313-cp313-win_amd64.whl", hash = "sha256:dd0a578400839256df88c16abddf9ba14813ec5f21362e1fe65022e00c883d4d", size = 73894, upload-time = "2025-08-10T21:26:42.33Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/95/38/dce480814d25b99a391abbddadc78f7c117c6da34be68ca8b02d5848b424/kiwisolver-1.4.9-cp313-cp313-win_arm64.whl", hash = "sha256:d4188e73af84ca82468f09cadc5ac4db578109e52acb4518d8154698d3a87ca2", size = 64995, upload-time = "2025-08-10T21:26:43.889Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/e2/37/7d218ce5d92dadc5ebdd9070d903e0c7cf7edfe03f179433ac4d13ce659c/kiwisolver-1.4.9-cp313-cp313t-macosx_10_13_universal2.whl", hash = "sha256:5a0f2724dfd4e3b3ac5a82436a8e6fd16baa7d507117e4279b660fe8ca38a3a1", size = 126510, upload-time = "2025-08-10T21:26:44.915Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/23/b0/e85a2b48233daef4b648fb657ebbb6f8367696a2d9548a00b4ee0eb67803/kiwisolver-1.4.9-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:1b11d6a633e4ed84fc0ddafd4ebfd8ea49b3f25082c04ad12b8315c11d504dc1", size = 67903, upload-time = "2025-08-10T21:26:45.934Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/44/98/f2425bc0113ad7de24da6bb4dae1343476e95e1d738be7c04d31a5d037fd/kiwisolver-1.4.9-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:61874cdb0a36016354853593cffc38e56fc9ca5aa97d2c05d3dcf6922cd55a11", size = 66402, upload-time = "2025-08-10T21:26:47.101Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/98/d8/594657886df9f34c4177cc353cc28ca7e6e5eb562d37ccc233bff43bbe2a/kiwisolver-1.4.9-cp313-cp313t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:60c439763a969a6af93b4881db0eed8fadf93ee98e18cbc35bc8da868d0c4f0c", size = 1582135, upload-time = "2025-08-10T21:26:48.665Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/5c/c6/38a115b7170f8b306fc929e166340c24958347308ea3012c2b44e7e295db/kiwisolver-1.4.9-cp313-cp313t-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:92a2f997387a1b79a75e7803aa7ded2cfbe2823852ccf1ba3bcf613b62ae3197", size = 1389409, upload-time = "2025-08-10T21:26:50.335Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/bf/3b/e04883dace81f24a568bcee6eb3001da4ba05114afa622ec9b6fafdc1f5e/kiwisolver-1.4.9-cp313-cp313t-manylinux_2_24_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:a31d512c812daea6d8b3be3b2bfcbeb091dbb09177706569bcfc6240dcf8b41c", size = 1401763, upload-time = "2025-08-10T21:26:51.867Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/9f/80/20ace48e33408947af49d7d15c341eaee69e4e0304aab4b7660e234d6288/kiwisolver-1.4.9-cp313-cp313t-manylinux_2_24_s390x.manylinux_2_28_s390x.whl", hash = "sha256:52a15b0f35dad39862d376df10c5230155243a2c1a436e39eb55623ccbd68185", size = 1453643, upload-time = "2025-08-10T21:26:53.592Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/64/31/6ce4380a4cd1f515bdda976a1e90e547ccd47b67a1546d63884463c92ca9/kiwisolver-1.4.9-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:a30fd6fdef1430fd9e1ba7b3398b5ee4e2887783917a687d86ba69985fb08748", size = 2330818, upload-time = "2025-08-10T21:26:55.051Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/fa/e9/3f3fcba3bcc7432c795b82646306e822f3fd74df0ee81f0fa067a1f95668/kiwisolver-1.4.9-cp313-cp313t-musllinux_1_2_ppc64le.whl", hash = "sha256:cc9617b46837c6468197b5945e196ee9ca43057bb7d9d1ae688101e4e1dddf64", size = 2419963, upload-time = "2025-08-10T21:26:56.421Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/99/43/7320c50e4133575c66e9f7dadead35ab22d7c012a3b09bb35647792b2a6d/kiwisolver-1.4.9-cp313-cp313t-musllinux_1_2_s390x.whl", hash = "sha256:0ab74e19f6a2b027ea4f845a78827969af45ce790e6cb3e1ebab71bdf9f215ff", size = 2594639, upload-time = "2025-08-10T21:26:57.882Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/65/d6/17ae4a270d4a987ef8a385b906d2bdfc9fce502d6dc0d3aea865b47f548c/kiwisolver-1.4.9-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:dba5ee5d3981160c28d5490f0d1b7ed730c22470ff7f6cc26cfcfaacb9896a07", size = 2391741, upload-time = "2025-08-10T21:26:59.237Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/2a/8f/8f6f491d595a9e5912971f3f863d81baddccc8a4d0c3749d6a0dd9ffc9df/kiwisolver-1.4.9-cp313-cp313t-win_arm64.whl", hash = "sha256:0749fd8f4218ad2e851e11cc4dc05c7cbc0cbc4267bdfdb31782e65aace4ee9c", size = 68646, upload-time = "2025-08-10T21:27:00.52Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/6b/32/6cc0fbc9c54d06c2969faa9c1d29f5751a2e51809dd55c69055e62d9b426/kiwisolver-1.4.9-cp314-cp314-macosx_10_13_universal2.whl", hash = "sha256:9928fe1eb816d11ae170885a74d074f57af3a0d65777ca47e9aeb854a1fba386", size = 123806, upload-time = "2025-08-10T21:27:01.537Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/b2/dd/2bfb1d4a4823d92e8cbb420fe024b8d2167f72079b3bb941207c42570bdf/kiwisolver-1.4.9-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:d0005b053977e7b43388ddec89fa567f43d4f6d5c2c0affe57de5ebf290dc552", size = 66605, upload-time = "2025-08-10T21:27:03.335Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/f7/69/00aafdb4e4509c2ca6064646cba9cd4b37933898f426756adb2cb92ebbed/kiwisolver-1.4.9-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:2635d352d67458b66fd0667c14cb1d4145e9560d503219034a18a87e971ce4f3", size = 64925, upload-time = "2025-08-10T21:27:04.339Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/43/dc/51acc6791aa14e5cb6d8a2e28cefb0dc2886d8862795449d021334c0df20/kiwisolver-1.4.9-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:767c23ad1c58c9e827b649a9ab7809fd5fd9db266a9cf02b0e926ddc2c680d58", size = 1472414, upload-time = "2025-08-10T21:27:05.437Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/3d/bb/93fa64a81db304ac8a246f834d5094fae4b13baf53c839d6bb6e81177129/kiwisolver-1.4.9-cp314-cp314-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:72d0eb9fba308b8311685c2268cf7d0a0639a6cd027d8128659f72bdd8a024b4", size = 1281272, upload-time = "2025-08-10T21:27:07.063Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/70/e6/6df102916960fb8d05069d4bd92d6d9a8202d5a3e2444494e7cd50f65b7a/kiwisolver-1.4.9-cp314-cp314-manylinux_2_24_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:f68e4f3eeca8fb22cc3d731f9715a13b652795ef657a13df1ad0c7dc0e9731df", size = 1298578, upload-time = "2025-08-10T21:27:08.452Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/7c/47/e142aaa612f5343736b087864dbaebc53ea8831453fb47e7521fa8658f30/kiwisolver-1.4.9-cp314-cp314-manylinux_2_24_s390x.manylinux_2_28_s390x.whl", hash = "sha256:d84cd4061ae292d8ac367b2c3fa3aad11cb8625a95d135fe93f286f914f3f5a6", size = 1345607, upload-time = "2025-08-10T21:27:10.125Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/54/89/d641a746194a0f4d1a3670fb900d0dbaa786fb98341056814bc3f058fa52/kiwisolver-1.4.9-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:a60ea74330b91bd22a29638940d115df9dc00af5035a9a2a6ad9399ffb4ceca5", size = 2230150, upload-time = "2025-08-10T21:27:11.484Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/aa/6b/5ee1207198febdf16ac11f78c5ae40861b809cbe0e6d2a8d5b0b3044b199/kiwisolver-1.4.9-cp314-cp314-musllinux_1_2_ppc64le.whl", hash = "sha256:ce6a3a4e106cf35c2d9c4fa17c05ce0b180db622736845d4315519397a77beaf", size = 2325979, upload-time = "2025-08-10T21:27:12.917Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/fc/ff/b269eefd90f4ae14dcc74973d5a0f6d28d3b9bb1afd8c0340513afe6b39a/kiwisolver-1.4.9-cp314-cp314-musllinux_1_2_s390x.whl", hash = "sha256:77937e5e2a38a7b48eef0585114fe7930346993a88060d0bf886086d2aa49ef5", size = 2491456, upload-time = "2025-08-10T21:27:14.353Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/fc/d4/10303190bd4d30de547534601e259a4fbf014eed94aae3e5521129215086/kiwisolver-1.4.9-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:24c175051354f4a28c5d6a31c93906dc653e2bf234e8a4bbfb964892078898ce", size = 2294621, upload-time = "2025-08-10T21:27:15.808Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/28/e0/a9a90416fce5c0be25742729c2ea52105d62eda6c4be4d803c2a7be1fa50/kiwisolver-1.4.9-cp314-cp314-win_amd64.whl", hash = "sha256:0763515d4df10edf6d06a3c19734e2566368980d21ebec439f33f9eb936c07b7", size = 75417, upload-time = "2025-08-10T21:27:17.436Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/1f/10/6949958215b7a9a264299a7db195564e87900f709db9245e4ebdd3c70779/kiwisolver-1.4.9-cp314-cp314-win_arm64.whl", hash = "sha256:0e4e2bf29574a6a7b7f6cb5fa69293b9f96c928949ac4a53ba3f525dffb87f9c", size = 66582, upload-time = "2025-08-10T21:27:18.436Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/ec/79/60e53067903d3bc5469b369fe0dfc6b3482e2133e85dae9daa9527535991/kiwisolver-1.4.9-cp314-cp314t-macosx_10_13_universal2.whl", hash = "sha256:d976bbb382b202f71c67f77b0ac11244021cfa3f7dfd9e562eefcea2df711548", size = 126514, upload-time = "2025-08-10T21:27:19.465Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/25/d1/4843d3e8d46b072c12a38c97c57fab4608d36e13fe47d47ee96b4d61ba6f/kiwisolver-1.4.9-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:2489e4e5d7ef9a1c300a5e0196e43d9c739f066ef23270607d45aba368b91f2d", size = 67905, upload-time = "2025-08-10T21:27:20.51Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/8c/ae/29ffcbd239aea8b93108de1278271ae764dfc0d803a5693914975f200596/kiwisolver-1.4.9-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:e2ea9f7ab7fbf18fffb1b5434ce7c69a07582f7acc7717720f1d69f3e806f90c", size = 66399, upload-time = "2025-08-10T21:27:21.496Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/a1/ae/d7ba902aa604152c2ceba5d352d7b62106bedbccc8e95c3934d94472bfa3/kiwisolver-1.4.9-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:b34e51affded8faee0dfdb705416153819d8ea9250bbbf7ea1b249bdeb5f1122", size = 1582197, upload-time = "2025-08-10T21:27:22.604Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/f2/41/27c70d427eddb8bc7e4f16420a20fefc6f480312122a59a959fdfe0445ad/kiwisolver-1.4.9-cp314-cp314t-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:d8aacd3d4b33b772542b2e01beb50187536967b514b00003bdda7589722d2a64", size = 1390125, upload-time = "2025-08-10T21:27:24.036Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/41/42/b3799a12bafc76d962ad69083f8b43b12bf4fe78b097b12e105d75c9b8f1/kiwisolver-1.4.9-cp314-cp314t-manylinux_2_24_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:7cf974dd4e35fa315563ac99d6287a1024e4dc2077b8a7d7cd3d2fb65d283134", size = 1402612, upload-time = "2025-08-10T21:27:25.773Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/d2/b5/a210ea073ea1cfaca1bb5c55a62307d8252f531beb364e18aa1e0888b5a0/kiwisolver-1.4.9-cp314-cp314t-manylinux_2_24_s390x.manylinux_2_28_s390x.whl", hash = "sha256:85bd218b5ecfbee8c8a82e121802dcb519a86044c9c3b2e4aef02fa05c6da370", size = 1453990, upload-time = "2025-08-10T21:27:27.089Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/5f/ce/a829eb8c033e977d7ea03ed32fb3c1781b4fa0433fbadfff29e39c676f32/kiwisolver-1.4.9-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:0856e241c2d3df4efef7c04a1e46b1936b6120c9bcf36dd216e3acd84bc4fb21", size = 2331601, upload-time = "2025-08-10T21:27:29.343Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/e0/4b/b5e97eb142eb9cd0072dacfcdcd31b1c66dc7352b0f7c7255d339c0edf00/kiwisolver-1.4.9-cp314-cp314t-musllinux_1_2_ppc64le.whl", hash = "sha256:9af39d6551f97d31a4deebeac6f45b156f9755ddc59c07b402c148f5dbb6482a", size = 2422041, upload-time = "2025-08-10T21:27:30.754Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/40/be/8eb4cd53e1b85ba4edc3a9321666f12b83113a178845593307a3e7891f44/kiwisolver-1.4.9-cp314-cp314t-musllinux_1_2_s390x.whl", hash = "sha256:bb4ae2b57fc1d8cbd1cf7b1d9913803681ffa903e7488012be5b76dedf49297f", size = 2594897, upload-time = "2025-08-10T21:27:32.803Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/99/dd/841e9a66c4715477ea0abc78da039832fbb09dac5c35c58dc4c41a407b8a/kiwisolver-1.4.9-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:aedff62918805fb62d43a4aa2ecd4482c380dc76cd31bd7c8878588a61bd0369", size = 2391835, upload-time = "2025-08-10T21:27:34.23Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/0c/28/4b2e5c47a0da96896fdfdb006340ade064afa1e63675d01ea5ac222b6d52/kiwisolver-1.4.9-cp314-cp314t-win_amd64.whl", hash = "sha256:1fa333e8b2ce4d9660f2cda9c0e1b6bafcfb2457a9d259faa82289e73ec24891", size = 79988, upload-time = "2025-08-10T21:27:35.587Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/80/be/3578e8afd18c88cdf9cb4cffde75a96d2be38c5a903f1ed0ceec061bd09e/kiwisolver-1.4.9-cp314-cp314t-win_arm64.whl", hash = "sha256:4a48a2ce79d65d363597ef7b567ce3d14d68783d2b2263d98db3d9477805ba32", size = 70260, upload-time = "2025-08-10T21:27:36.606Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "logbook"
|
||||
version = "1.7.0.post0"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/cc/98/c1d93c1d7593f58515333a6217aa4ae647d9ee9c1aa2dfdf77b28b7bb7c7/Logbook-1.7.0.post0.tar.gz", hash = "sha256:a5e8016701ca3beea6a390b0ba1541037f663543ca508ccd36cfdc841639cdd7", size = 367964, upload-time = "2023-11-10T23:33:29.292Z" }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/c7/d0/0d9e4f08333189547ffa85257c3053a07a4c1a431dcbfbe9a49eaedc33dc/Logbook-1.7.0.post0-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:b1e0b8c3d25a7cf539340c299a8a1fd37d19809a158c8849f6e73a6304f583c7", size = 201359, upload-time = "2023-11-10T23:32:57.454Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/62/f3/8c2146de5f2179cb7d8727b8e150def2db3dfa74e0a6341a3921557aff28/Logbook-1.7.0.post0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:3f2928505d528fb2efa5c4c7e63bd0a3d5ded4d96db8e056ab61a69313739072", size = 134941, upload-time = "2023-11-10T23:32:58.901Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/64/70/26a766173b212b003149b5899cd6616f415a82f11b86a5c5628494cd44cf/Logbook-1.7.0.post0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:5f891dc3f60a18f85d09698d1ea429b2effb06bfd42a1835493efde5eb6ea08b", size = 130611, upload-time = "2023-11-10T23:33:00.794Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/07/d1/0be80be60881e2b5d8747a64558a858c759443ad2d2b7e036272e87cb9f4/Logbook-1.7.0.post0-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c7d7a39dbfa9c2793569691c719c6f0269a21b01583f33dfcc6052b3312fc5f2", size = 518536, upload-time = "2023-11-10T23:33:02.461Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/38/fa/4c717b80b59496010c9fc5d6a372df0215d0c480548baae1c36f443075db/Logbook-1.7.0.post0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:40a8e1b4fc0d2fdf8e662fabd8a933ba1ce91a355c755ab7a1d13469ec0e590e", size = 527547, upload-time = "2023-11-10T23:33:04.341Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/e4/a9/78983454f4b638e9875b783bebce92a634829f3ea50743f9275e4db2a8d3/Logbook-1.7.0.post0-cp312-cp312-win32.whl", hash = "sha256:faf156af8a8954a227f141ffedf7ac1d9ba573b0066f19033ab2240329f94793", size = 115785, upload-time = "2023-11-10T23:33:05.875Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/99/34/3bc539cdeffc55e4be527c205b11f7f1f43b665fed8175558dff8c8afa7d/Logbook-1.7.0.post0-cp312-cp312-win_amd64.whl", hash = "sha256:6316fa5eb09b375980a9ee3fd8c72cf9020b532d4c73fd7cbfd7a1a74694739e", size = 122823, upload-time = "2023-11-10T23:33:07.313Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "markdown2"
|
||||
version = "2.4.11"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/a7/b7/0ba8568968673ba5bcd221525ec364820b46dea9da441146d72cae4df18a/markdown2-2.4.11.tar.gz", hash = "sha256:c04841d0f9df37457396b9d73c54846ddb097a73e7eb7c81d1589e0bba566cda", size = 128610, upload-time = "2023-12-03T18:52:01.29Z" }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/c9/38/183d3c253b9dc884c9d698dd5d68f258d0f853726260362f0fa49400279d/markdown2-2.4.11-py2.py3-none-any.whl", hash = "sha256:2fff5d8e9283218797c5db0e9caad14c4307839919297c5be6ae507d4eeaddbc", size = 41072, upload-time = "2023-12-03T18:51:59.111Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "matplotlib"
|
||||
version = "3.8.2"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
dependencies = [
|
||||
{ name = "contourpy" },
|
||||
{ name = "cycler" },
|
||||
{ name = "fonttools" },
|
||||
{ name = "kiwisolver" },
|
||||
{ name = "numpy" },
|
||||
{ name = "packaging" },
|
||||
{ name = "pillow" },
|
||||
{ name = "pyparsing" },
|
||||
{ name = "python-dateutil" },
|
||||
]
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/fb/ab/38a0e94cb01dacb50f06957c2bed1c83b8f9dac6618988a37b2487862944/matplotlib-3.8.2.tar.gz", hash = "sha256:01a978b871b881ee76017152f1f1a0cbf6bd5f7b8ff8c96df0df1bd57d8755a1", size = 35866957, upload-time = "2023-11-17T21:16:40.15Z" }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/e4/1b/864d28d5a72d586ac137f4ca54d5afc8b869720e30d508dbd9adcce4d231/matplotlib-3.8.2-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:4c318c1e95e2f5926fba326f68177dee364aa791d6df022ceb91b8221bd0a627", size = 7590988, upload-time = "2023-11-17T21:19:01.119Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/9a/b0/dd2b60f2dd90fbc21d1d3129c36a453c322d7995d5e3589f5b3c59ee528d/matplotlib-3.8.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:091275d18d942cf1ee9609c830a1bc36610607d8223b1b981c37d5c9fc3e46a4", size = 7483594, upload-time = "2023-11-17T21:19:09.865Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/33/da/9942533ad9f96753bde0e5a5d48eacd6c21de8ea1ad16570e31bda8a017f/matplotlib-3.8.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1b0f3b8ea0e99e233a4bcc44590f01604840d833c280ebb8fe5554fd3e6cfe8d", size = 11380843, upload-time = "2023-11-17T21:19:20.46Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/fc/52/bfd36eb4745a3b21b3946c2c3a15679b620e14574fe2b98e9451b65ef578/matplotlib-3.8.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d7b1704a530395aaf73912be741c04d181f82ca78084fbd80bc737be04848331", size = 11604608, upload-time = "2023-11-17T21:19:31.363Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/6d/8c/0cdfbf604d4ea3dfa77435176c51e233cc408ad8f3efbf8d2c9f57cbdafb/matplotlib-3.8.2-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:533b0e3b0c6768eef8cbe4b583731ce25a91ab54a22f830db2b031e83cca9213", size = 9545252, upload-time = "2023-11-17T21:19:42.271Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/2e/51/c77a14869b7eb9d6fb440e811b754fc3950d6868c38ace57d0632b674415/matplotlib-3.8.2-cp312-cp312-win_amd64.whl", hash = "sha256:0f4fc5d72b75e2c18e55eb32292659cf731d9d5b312a6eb036506304f4675630", size = 7645067, upload-time = "2023-11-17T21:19:50.091Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "numpy"
|
||||
version = "1.26.2"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/dd/2b/205ddff2314d4eea852e31d53b8e55eb3f32b292efc3dd86bd827ab9019d/numpy-1.26.2.tar.gz", hash = "sha256:f65738447676ab5777f11e6bbbdb8ce11b785e105f690bc45966574816b6d3ea", size = 15664248, upload-time = "2023-11-12T23:17:31.386Z" }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/b1/97/6694e0855b11be0fd8598d484c09edd876ec738a8741025dee072f026c33/numpy-1.26.2-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:a4cd6ed4a339c21f1d1b0fdf13426cb3b284555c27ac2f156dfdaaa7e16bfab0", size = 20323012, upload-time = "2023-11-12T23:02:57.091Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/2a/17/1fdc154e75d24d8c20c42b71bae1b5cf752453f0fc3a2504bbb810293dd1/numpy-1.26.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:5d5244aabd6ed7f312268b9247be47343a654ebea52a60f002dc70c769048e75", size = 13675818, upload-time = "2023-11-12T23:03:32.823Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/a1/42/a2819c5b77fe6506662ffc13b767e0c216c02f75ae840219013ab822a473/numpy-1.26.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6a3cdb4d9c70e6b8c0814239ead47da00934666f668426fc6e94cce869e13fd7", size = 13917117, upload-time = "2023-11-12T23:03:59.013Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/04/89/3b831e2b50c9364069609d1335f46c488a149d5f2be14a08741c92a60009/numpy-1.26.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:aa317b2325f7aa0a9471663e6093c210cb2ae9c0ad824732b307d2c51983d5b6", size = 17938212, upload-time = "2023-11-12T23:04:32.896Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/02/51/f078f1e7f658022150e7c8d5f99d505b40812840349d54667f98bb915b26/numpy-1.26.2-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:174a8880739c16c925799c018f3f55b8130c1f7c8e75ab0a6fa9d41cab092fd6", size = 13564269, upload-time = "2023-11-12T23:05:31.101Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/8c/9f/2f5c6b5f63cf006e6190bf750ade791d1fee353bab654bbde2f83a3ab92e/numpy-1.26.2-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:f79b231bf5c16b1f39c7f4875e1ded36abee1591e98742b05d8a0fb55d8a3eec", size = 17774512, upload-time = "2023-11-12T23:06:03.941Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/51/7d/6181c8778cdb15ba0a4959bb72dcc1854c89ca4824481f224c6faf7024e1/numpy-1.26.2-cp312-cp312-win32.whl", hash = "sha256:4a06263321dfd3598cacb252f51e521a8cb4b6df471bb12a7ee5cbab20ea9167", size = 19962368, upload-time = "2023-11-12T23:06:51.561Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/28/75/3b679b41713bb60e2e8f6e2f87be72c971c9e718b1c17b8f8749240ddca8/numpy-1.26.2-cp312-cp312-win_amd64.whl", hash = "sha256:b04f5dc6b3efdaab541f7857351aac359e6ae3c126e2edb376929bd3b7f92d7e", size = 15504951, upload-time = "2023-11-12T23:07:33.828Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "packaging"
|
||||
version = "23.2"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/fb/2b/9b9c33ffed44ee921d0967086d653047286054117d584f1b1a7c22ceaf7b/packaging-23.2.tar.gz", hash = "sha256:048fb0e9405036518eaaf48a55953c750c11e1a1b68e0dd1a9d62ed0c092cfc5", size = 146714, upload-time = "2023-10-01T13:50:05.279Z" }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/ec/1a/610693ac4ee14fcdf2d9bf3c493370e4f2ef7ae2e19217d7a237ff42367d/packaging-23.2-py3-none-any.whl", hash = "sha256:8c491190033a9af7e1d931d0b5dacc2ef47509b34dd0de67ed209b5203fc88c7", size = 53011, upload-time = "2023-10-01T13:50:03.745Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pillow"
|
||||
version = "12.0.0"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/5a/b0/cace85a1b0c9775a9f8f5d5423c8261c858760e2466c79b2dd184638b056/pillow-12.0.0.tar.gz", hash = "sha256:87d4f8125c9988bfbed67af47dd7a953e2fc7b0cc1e7800ec6d2080d490bb353", size = 47008828, upload-time = "2025-10-15T18:24:14.008Z" }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/2c/90/4fcce2c22caf044e660a198d740e7fbc14395619e3cb1abad12192c0826c/pillow-12.0.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:53561a4ddc36facb432fae7a9d8afbfaf94795414f5cdc5fc52f28c1dca90371", size = 5249377, upload-time = "2025-10-15T18:22:05.993Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/fd/e0/ed960067543d080691d47d6938ebccbf3976a931c9567ab2fbfab983a5dd/pillow-12.0.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:71db6b4c1653045dacc1585c1b0d184004f0d7e694c7b34ac165ca70c0838082", size = 4650343, upload-time = "2025-10-15T18:22:07.718Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/e7/a1/f81fdeddcb99c044bf7d6faa47e12850f13cee0849537a7d27eeab5534d4/pillow-12.0.0-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:2fa5f0b6716fc88f11380b88b31fe591a06c6315e955c096c35715788b339e3f", size = 6232981, upload-time = "2025-10-15T18:22:09.287Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/88/e1/9098d3ce341a8750b55b0e00c03f1630d6178f38ac191c81c97a3b047b44/pillow-12.0.0-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:82240051c6ca513c616f7f9da06e871f61bfd7805f566275841af15015b8f98d", size = 8041399, upload-time = "2025-10-15T18:22:10.872Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/a7/62/a22e8d3b602ae8cc01446d0c57a54e982737f44b6f2e1e019a925143771d/pillow-12.0.0-cp312-cp312-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:55f818bd74fe2f11d4d7cbc65880a843c4075e0ac7226bc1a23261dbea531953", size = 6347740, upload-time = "2025-10-15T18:22:12.769Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/4f/87/424511bdcd02c8d7acf9f65caa09f291a519b16bd83c3fb3374b3d4ae951/pillow-12.0.0-cp312-cp312-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:b87843e225e74576437fd5b6a4c2205d422754f84a06942cfaf1dc32243e45a8", size = 7040201, upload-time = "2025-10-15T18:22:14.813Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/dc/4d/435c8ac688c54d11755aedfdd9f29c9eeddf68d150fe42d1d3dbd2365149/pillow-12.0.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:c607c90ba67533e1b2355b821fef6764d1dd2cbe26b8c1005ae84f7aea25ff79", size = 6462334, upload-time = "2025-10-15T18:22:16.375Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/2b/f2/ad34167a8059a59b8ad10bc5c72d4d9b35acc6b7c0877af8ac885b5f2044/pillow-12.0.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:21f241bdd5080a15bc86d3466a9f6074a9c2c2b314100dd896ac81ee6db2f1ba", size = 7134162, upload-time = "2025-10-15T18:22:17.996Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/0c/b1/a7391df6adacf0a5c2cf6ac1cf1fcc1369e7d439d28f637a847f8803beb3/pillow-12.0.0-cp312-cp312-win32.whl", hash = "sha256:dd333073e0cacdc3089525c7df7d39b211bcdf31fc2824e49d01c6b6187b07d0", size = 6298769, upload-time = "2025-10-15T18:22:19.923Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/a2/0b/d87733741526541c909bbf159e338dcace4f982daac6e5a8d6be225ca32d/pillow-12.0.0-cp312-cp312-win_amd64.whl", hash = "sha256:9fe611163f6303d1619bbcb653540a4d60f9e55e622d60a3108be0d5b441017a", size = 7001107, upload-time = "2025-10-15T18:22:21.644Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/bc/96/aaa61ce33cc98421fb6088af2a03be4157b1e7e0e87087c888e2370a7f45/pillow-12.0.0-cp312-cp312-win_arm64.whl", hash = "sha256:7dfb439562f234f7d57b1ac6bc8fe7f838a4bd49c79230e0f6a1da93e82f1fad", size = 2436012, upload-time = "2025-10-15T18:22:23.621Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/62/f2/de993bb2d21b33a98d031ecf6a978e4b61da207bef02f7b43093774c480d/pillow-12.0.0-cp313-cp313-ios_13_0_arm64_iphoneos.whl", hash = "sha256:0869154a2d0546545cde61d1789a6524319fc1897d9ee31218eae7a60ccc5643", size = 4045493, upload-time = "2025-10-15T18:22:25.758Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/0e/b6/bc8d0c4c9f6f111a783d045310945deb769b806d7574764234ffd50bc5ea/pillow-12.0.0-cp313-cp313-ios_13_0_arm64_iphonesimulator.whl", hash = "sha256:a7921c5a6d31b3d756ec980f2f47c0cfdbce0fc48c22a39347a895f41f4a6ea4", size = 4120461, upload-time = "2025-10-15T18:22:27.286Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/5d/57/d60d343709366a353dc56adb4ee1e7d8a2cc34e3fbc22905f4167cfec119/pillow-12.0.0-cp313-cp313-ios_13_0_x86_64_iphonesimulator.whl", hash = "sha256:1ee80a59f6ce048ae13cda1abf7fbd2a34ab9ee7d401c46be3ca685d1999a399", size = 3576912, upload-time = "2025-10-15T18:22:28.751Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/a4/a4/a0a31467e3f83b94d37568294b01d22b43ae3c5d85f2811769b9c66389dd/pillow-12.0.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:c50f36a62a22d350c96e49ad02d0da41dbd17ddc2e29750dbdba4323f85eb4a5", size = 5249132, upload-time = "2025-10-15T18:22:30.641Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/83/06/48eab21dd561de2914242711434c0c0eb992ed08ff3f6107a5f44527f5e9/pillow-12.0.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:5193fde9a5f23c331ea26d0cf171fbf67e3f247585f50c08b3e205c7aeb4589b", size = 4650099, upload-time = "2025-10-15T18:22:32.73Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/fc/bd/69ed99fd46a8dba7c1887156d3572fe4484e3f031405fcc5a92e31c04035/pillow-12.0.0-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:bde737cff1a975b70652b62d626f7785e0480918dece11e8fef3c0cf057351c3", size = 6230808, upload-time = "2025-10-15T18:22:34.337Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/ea/94/8fad659bcdbf86ed70099cb60ae40be6acca434bbc8c4c0d4ef356d7e0de/pillow-12.0.0-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:a6597ff2b61d121172f5844b53f21467f7082f5fb385a9a29c01414463f93b07", size = 8037804, upload-time = "2025-10-15T18:22:36.402Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/20/39/c685d05c06deecfd4e2d1950e9a908aa2ca8bc4e6c3b12d93b9cafbd7837/pillow-12.0.0-cp313-cp313-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:0b817e7035ea7f6b942c13aa03bb554fc44fea70838ea21f8eb31c638326584e", size = 6345553, upload-time = "2025-10-15T18:22:38.066Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/38/57/755dbd06530a27a5ed74f8cb0a7a44a21722ebf318edbe67ddbd7fb28f88/pillow-12.0.0-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:f4f1231b7dec408e8670264ce63e9c71409d9583dd21d32c163e25213ee2a344", size = 7037729, upload-time = "2025-10-15T18:22:39.769Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/ca/b6/7e94f4c41d238615674d06ed677c14883103dce1c52e4af16f000338cfd7/pillow-12.0.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:6e51b71417049ad6ab14c49608b4a24d8fb3fe605e5dfabfe523b58064dc3d27", size = 6459789, upload-time = "2025-10-15T18:22:41.437Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/9c/14/4448bb0b5e0f22dd865290536d20ec8a23b64e2d04280b89139f09a36bb6/pillow-12.0.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:d120c38a42c234dc9a8c5de7ceaaf899cf33561956acb4941653f8bdc657aa79", size = 7130917, upload-time = "2025-10-15T18:22:43.152Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/dd/ca/16c6926cc1c015845745d5c16c9358e24282f1e588237a4c36d2b30f182f/pillow-12.0.0-cp313-cp313-win32.whl", hash = "sha256:4cc6b3b2efff105c6a1656cfe59da4fdde2cda9af1c5e0b58529b24525d0a098", size = 6302391, upload-time = "2025-10-15T18:22:44.753Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/6d/2a/dd43dcfd6dae9b6a49ee28a8eedb98c7d5ff2de94a5d834565164667b97b/pillow-12.0.0-cp313-cp313-win_amd64.whl", hash = "sha256:4cf7fed4b4580601c4345ceb5d4cbf5a980d030fd5ad07c4d2ec589f95f09905", size = 7007477, upload-time = "2025-10-15T18:22:46.838Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/77/f0/72ea067f4b5ae5ead653053212af05ce3705807906ba3f3e8f58ddf617e6/pillow-12.0.0-cp313-cp313-win_arm64.whl", hash = "sha256:9f0b04c6b8584c2c193babcccc908b38ed29524b29dd464bc8801bf10d746a3a", size = 2435918, upload-time = "2025-10-15T18:22:48.399Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/f5/5e/9046b423735c21f0487ea6cb5b10f89ea8f8dfbe32576fe052b5ba9d4e5b/pillow-12.0.0-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:7fa22993bac7b77b78cae22bad1e2a987ddf0d9015c63358032f84a53f23cdc3", size = 5251406, upload-time = "2025-10-15T18:22:49.905Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/12/66/982ceebcdb13c97270ef7a56c3969635b4ee7cd45227fa707c94719229c5/pillow-12.0.0-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:f135c702ac42262573fe9714dfe99c944b4ba307af5eb507abef1667e2cbbced", size = 4653218, upload-time = "2025-10-15T18:22:51.587Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/16/b3/81e625524688c31859450119bf12674619429cab3119eec0e30a7a1029cb/pillow-12.0.0-cp313-cp313t-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:c85de1136429c524e55cfa4e033b4a7940ac5c8ee4d9401cc2d1bf48154bbc7b", size = 6266564, upload-time = "2025-10-15T18:22:53.215Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/98/59/dfb38f2a41240d2408096e1a76c671d0a105a4a8471b1871c6902719450c/pillow-12.0.0-cp313-cp313t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:38df9b4bfd3db902c9c2bd369bcacaf9d935b2fff73709429d95cc41554f7b3d", size = 8069260, upload-time = "2025-10-15T18:22:54.933Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/dc/3d/378dbea5cd1874b94c312425ca77b0f47776c78e0df2df751b820c8c1d6c/pillow-12.0.0-cp313-cp313t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:7d87ef5795da03d742bf49439f9ca4d027cde49c82c5371ba52464aee266699a", size = 6379248, upload-time = "2025-10-15T18:22:56.605Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/84/b0/d525ef47d71590f1621510327acec75ae58c721dc071b17d8d652ca494d8/pillow-12.0.0-cp313-cp313t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:aff9e4d82d082ff9513bdd6acd4f5bd359f5b2c870907d2b0a9c5e10d40c88fe", size = 7066043, upload-time = "2025-10-15T18:22:58.53Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/61/2c/aced60e9cf9d0cde341d54bf7932c9ffc33ddb4a1595798b3a5150c7ec4e/pillow-12.0.0-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:8d8ca2b210ada074d57fcee40c30446c9562e542fc46aedc19baf758a93532ee", size = 6490915, upload-time = "2025-10-15T18:23:00.582Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/ef/26/69dcb9b91f4e59f8f34b2332a4a0a951b44f547c4ed39d3e4dcfcff48f89/pillow-12.0.0-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:99a7f72fb6249302aa62245680754862a44179b545ded638cf1fef59befb57ef", size = 7157998, upload-time = "2025-10-15T18:23:02.627Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/61/2b/726235842220ca95fa441ddf55dd2382b52ab5b8d9c0596fe6b3f23dafe8/pillow-12.0.0-cp313-cp313t-win32.whl", hash = "sha256:4078242472387600b2ce8d93ade8899c12bf33fa89e55ec89fe126e9d6d5d9e9", size = 6306201, upload-time = "2025-10-15T18:23:04.709Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/c0/3d/2afaf4e840b2df71344ababf2f8edd75a705ce500e5dc1e7227808312ae1/pillow-12.0.0-cp313-cp313t-win_amd64.whl", hash = "sha256:2c54c1a783d6d60595d3514f0efe9b37c8808746a66920315bfd34a938d7994b", size = 7013165, upload-time = "2025-10-15T18:23:06.46Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/6f/75/3fa09aa5cf6ed04bee3fa575798ddf1ce0bace8edb47249c798077a81f7f/pillow-12.0.0-cp313-cp313t-win_arm64.whl", hash = "sha256:26d9f7d2b604cd23aba3e9faf795787456ac25634d82cd060556998e39c6fa47", size = 2437834, upload-time = "2025-10-15T18:23:08.194Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/54/2a/9a8c6ba2c2c07b71bec92cf63e03370ca5e5f5c5b119b742bcc0cde3f9c5/pillow-12.0.0-cp314-cp314-ios_13_0_arm64_iphoneos.whl", hash = "sha256:beeae3f27f62308f1ddbcfb0690bf44b10732f2ef43758f169d5e9303165d3f9", size = 4045531, upload-time = "2025-10-15T18:23:10.121Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/84/54/836fdbf1bfb3d66a59f0189ff0b9f5f666cee09c6188309300df04ad71fa/pillow-12.0.0-cp314-cp314-ios_13_0_arm64_iphonesimulator.whl", hash = "sha256:d4827615da15cd59784ce39d3388275ec093ae3ee8d7f0c089b76fa87af756c2", size = 4120554, upload-time = "2025-10-15T18:23:12.14Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/0d/cd/16aec9f0da4793e98e6b54778a5fbce4f375c6646fe662e80600b8797379/pillow-12.0.0-cp314-cp314-ios_13_0_x86_64_iphonesimulator.whl", hash = "sha256:3e42edad50b6909089750e65c91aa09aaf1e0a71310d383f11321b27c224ed8a", size = 3576812, upload-time = "2025-10-15T18:23:13.962Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/f6/b7/13957fda356dc46339298b351cae0d327704986337c3c69bb54628c88155/pillow-12.0.0-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:e5d8efac84c9afcb40914ab49ba063d94f5dbdf5066db4482c66a992f47a3a3b", size = 5252689, upload-time = "2025-10-15T18:23:15.562Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/fc/f5/eae31a306341d8f331f43edb2e9122c7661b975433de5e447939ae61c5da/pillow-12.0.0-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:266cd5f2b63ff316d5a1bba46268e603c9caf5606d44f38c2873c380950576ad", size = 4650186, upload-time = "2025-10-15T18:23:17.379Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/86/62/2a88339aa40c4c77e79108facbd307d6091e2c0eb5b8d3cf4977cfca2fe6/pillow-12.0.0-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:58eea5ebe51504057dd95c5b77d21700b77615ab0243d8152793dc00eb4faf01", size = 6230308, upload-time = "2025-10-15T18:23:18.971Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/c7/33/5425a8992bcb32d1cb9fa3dd39a89e613d09a22f2c8083b7bf43c455f760/pillow-12.0.0-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:f13711b1a5ba512d647a0e4ba79280d3a9a045aaf7e0cc6fbe96b91d4cdf6b0c", size = 8039222, upload-time = "2025-10-15T18:23:20.909Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/d8/61/3f5d3b35c5728f37953d3eec5b5f3e77111949523bd2dd7f31a851e50690/pillow-12.0.0-cp314-cp314-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:6846bd2d116ff42cba6b646edf5bf61d37e5cbd256425fa089fee4ff5c07a99e", size = 6346657, upload-time = "2025-10-15T18:23:23.077Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/3a/be/ee90a3d79271227e0f0a33c453531efd6ed14b2e708596ba5dd9be948da3/pillow-12.0.0-cp314-cp314-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:c98fa880d695de164b4135a52fd2e9cd7b7c90a9d8ac5e9e443a24a95ef9248e", size = 7038482, upload-time = "2025-10-15T18:23:25.005Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/44/34/a16b6a4d1ad727de390e9bd9f19f5f669e079e5826ec0f329010ddea492f/pillow-12.0.0-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:fa3ed2a29a9e9d2d488b4da81dcb54720ac3104a20bf0bd273f1e4648aff5af9", size = 6461416, upload-time = "2025-10-15T18:23:27.009Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/b6/39/1aa5850d2ade7d7ba9f54e4e4c17077244ff7a2d9e25998c38a29749eb3f/pillow-12.0.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:d034140032870024e6b9892c692fe2968493790dd57208b2c37e3fb35f6df3ab", size = 7131584, upload-time = "2025-10-15T18:23:29.752Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/bf/db/4fae862f8fad0167073a7733973bfa955f47e2cac3dc3e3e6257d10fab4a/pillow-12.0.0-cp314-cp314-win32.whl", hash = "sha256:1b1b133e6e16105f524a8dec491e0586d072948ce15c9b914e41cdadd209052b", size = 6400621, upload-time = "2025-10-15T18:23:32.06Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/2b/24/b350c31543fb0107ab2599464d7e28e6f856027aadda995022e695313d94/pillow-12.0.0-cp314-cp314-win_amd64.whl", hash = "sha256:8dc232e39d409036af549c86f24aed8273a40ffa459981146829a324e0848b4b", size = 7142916, upload-time = "2025-10-15T18:23:34.71Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/0f/9b/0ba5a6fd9351793996ef7487c4fdbde8d3f5f75dbedc093bb598648fddf0/pillow-12.0.0-cp314-cp314-win_arm64.whl", hash = "sha256:d52610d51e265a51518692045e372a4c363056130d922a7351429ac9f27e70b0", size = 2523836, upload-time = "2025-10-15T18:23:36.967Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/f5/7a/ceee0840aebc579af529b523d530840338ecf63992395842e54edc805987/pillow-12.0.0-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:1979f4566bb96c1e50a62d9831e2ea2d1211761e5662afc545fa766f996632f6", size = 5255092, upload-time = "2025-10-15T18:23:38.573Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/44/76/20776057b4bfd1aef4eeca992ebde0f53a4dce874f3ae693d0ec90a4f79b/pillow-12.0.0-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:b2e4b27a6e15b04832fe9bf292b94b5ca156016bbc1ea9c2c20098a0320d6cf6", size = 4653158, upload-time = "2025-10-15T18:23:40.238Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/82/3f/d9ff92ace07be8836b4e7e87e6a4c7a8318d47c2f1463ffcf121fc57d9cb/pillow-12.0.0-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:fb3096c30df99fd01c7bf8e544f392103d0795b9f98ba71a8054bcbf56b255f1", size = 6267882, upload-time = "2025-10-15T18:23:42.434Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/9f/7a/4f7ff87f00d3ad33ba21af78bfcd2f032107710baf8280e3722ceec28cda/pillow-12.0.0-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:7438839e9e053ef79f7112c881cef684013855016f928b168b81ed5835f3e75e", size = 8071001, upload-time = "2025-10-15T18:23:44.29Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/75/87/fcea108944a52dad8cca0715ae6247e271eb80459364a98518f1e4f480c1/pillow-12.0.0-cp314-cp314t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:5d5c411a8eaa2299322b647cd932586b1427367fd3184ffbb8f7a219ea2041ca", size = 6380146, upload-time = "2025-10-15T18:23:46.065Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/91/52/0d31b5e571ef5fd111d2978b84603fce26aba1b6092f28e941cb46570745/pillow-12.0.0-cp314-cp314t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:d7e091d464ac59d2c7ad8e7e08105eaf9dafbc3883fd7265ffccc2baad6ac925", size = 7067344, upload-time = "2025-10-15T18:23:47.898Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/7b/f4/2dd3d721f875f928d48e83bb30a434dee75a2531bca839bb996bb0aa5a91/pillow-12.0.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:792a2c0be4dcc18af9d4a2dfd8a11a17d5e25274a1062b0ec1c2d79c76f3e7f8", size = 6491864, upload-time = "2025-10-15T18:23:49.607Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/30/4b/667dfcf3d61fc309ba5a15b141845cece5915e39b99c1ceab0f34bf1d124/pillow-12.0.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:afbefa430092f71a9593a99ab6a4e7538bc9eabbf7bf94f91510d3503943edc4", size = 7158911, upload-time = "2025-10-15T18:23:51.351Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/a2/2f/16cabcc6426c32218ace36bf0d55955e813f2958afddbf1d391849fee9d1/pillow-12.0.0-cp314-cp314t-win32.whl", hash = "sha256:3830c769decf88f1289680a59d4f4c46c72573446352e2befec9a8512104fa52", size = 6408045, upload-time = "2025-10-15T18:23:53.177Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/35/73/e29aa0c9c666cf787628d3f0dcf379f4791fba79f4936d02f8b37165bdf8/pillow-12.0.0-cp314-cp314t-win_amd64.whl", hash = "sha256:905b0365b210c73afb0ebe9101a32572152dfd1c144c7e28968a331b9217b94a", size = 7148282, upload-time = "2025-10-15T18:23:55.316Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/c1/70/6b41bdcddf541b437bbb9f47f94d2db5d9ddef6c37ccab8c9107743748a4/pillow-12.0.0-cp314-cp314t-win_arm64.whl", hash = "sha256:99353a06902c2e43b43e8ff74ee65a7d90307d82370604746738a1e0661ccca7", size = 2525630, upload-time = "2025-10-15T18:23:57.149Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "platformdirs"
|
||||
version = "4.5.1"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/cf/86/0248f086a84f01b37aaec0fa567b397df1a119f73c16f6c7a9aac73ea309/platformdirs-4.5.1.tar.gz", hash = "sha256:61d5cdcc6065745cdd94f0f878977f8de9437be93de97c1c12f853c9c0cdcbda", size = 21715, upload-time = "2025-12-05T13:52:58.638Z" }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/cb/28/3bfe2fa5a7b9c46fe7e13c97bda14c895fb10fa2ebf1d0abb90e0cea7ee1/platformdirs-4.5.1-py3-none-any.whl", hash = "sha256:d03afa3963c806a9bed9d5125c8f4cb2fdaf74a55ab60e5d59b3fde758104d31", size = 18731, upload-time = "2025-12-05T13:52:56.823Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pyasn1"
|
||||
version = "0.6.1"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/ba/e9/01f1a64245b89f039897cb0130016d79f77d52669aae6ee7b159a6c4c018/pyasn1-0.6.1.tar.gz", hash = "sha256:6f580d2bdd84365380830acf45550f2511469f673cb4a5ae3857a3170128b034", size = 145322, upload-time = "2024-09-10T22:41:42.55Z" }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/c8/f1/d6a797abb14f6283c0ddff96bbdd46937f64122b8c925cab503dd37f8214/pyasn1-0.6.1-py3-none-any.whl", hash = "sha256:0d632f46f2ba09143da3a8afe9e33fb6f92fa2320ab7e886e2d0f7672af84629", size = 83135, upload-time = "2024-09-11T16:00:36.122Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pycparser"
|
||||
version = "2.23"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/fe/cf/d2d3b9f5699fb1e4615c8e32ff220203e43b248e1dfcc6736ad9057731ca/pycparser-2.23.tar.gz", hash = "sha256:78816d4f24add8f10a06d6f05b4d424ad9e96cfebf68a4ddc99c65c0720d00c2", size = 173734, upload-time = "2025-09-09T13:23:47.91Z" }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/a0/e3/59cd50310fc9b59512193629e1984c1f95e5c8ae6e5d8c69532ccc65a7fe/pycparser-2.23-py3-none-any.whl", hash = "sha256:e5c6e8d3fbad53479cab09ac03729e0a9faf2bee3db8208a550daf5af81a5934", size = 118140, upload-time = "2025-09-09T13:23:46.651Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pyfa"
|
||||
version = "0.1.0"
|
||||
source = { virtual = "." }
|
||||
dependencies = [
|
||||
{ name = "beautifulsoup4" },
|
||||
{ name = "cryptography" },
|
||||
{ name = "logbook" },
|
||||
{ name = "markdown2" },
|
||||
{ name = "matplotlib" },
|
||||
{ name = "numpy" },
|
||||
{ name = "packaging" },
|
||||
{ name = "python-dateutil" },
|
||||
{ name = "python-jose" },
|
||||
{ name = "pyyaml" },
|
||||
{ name = "requests" },
|
||||
{ name = "requests-cache" },
|
||||
{ name = "roman" },
|
||||
{ name = "ruff" },
|
||||
{ name = "sqlalchemy" },
|
||||
{ name = "wxpython" },
|
||||
]
|
||||
|
||||
[package.metadata]
|
||||
requires-dist = [
|
||||
{ name = "beautifulsoup4", specifier = "==4.12.2" },
|
||||
{ name = "cryptography", specifier = "==42.0.4" },
|
||||
{ name = "logbook", specifier = "==1.7.0.post0" },
|
||||
{ name = "markdown2", specifier = "==2.4.11" },
|
||||
{ name = "matplotlib", specifier = "==3.8.2" },
|
||||
{ name = "numpy", specifier = "==1.26.2" },
|
||||
{ name = "packaging", specifier = "==23.2" },
|
||||
{ name = "python-dateutil", specifier = "==2.8.2" },
|
||||
{ name = "python-jose", specifier = "==3.3.0" },
|
||||
{ name = "pyyaml", specifier = "==6.0.1" },
|
||||
{ name = "requests", specifier = "==2.31.0" },
|
||||
{ name = "requests-cache", specifier = "==1.1.1" },
|
||||
{ name = "roman", specifier = "==4.1" },
|
||||
{ name = "ruff", specifier = ">=0.14.8" },
|
||||
{ name = "sqlalchemy", specifier = "==1.4.50" },
|
||||
{ name = "wxpython", specifier = "==4.2.1" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pyparsing"
|
||||
version = "3.3.1"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/33/c1/1d9de9aeaa1b89b0186e5fe23294ff6517fce1bc69149185577cd31016b2/pyparsing-3.3.1.tar.gz", hash = "sha256:47fad0f17ac1e2cad3de3b458570fbc9b03560aa029ed5e16ee5554da9a2251c", size = 1550512, upload-time = "2025-12-23T03:14:04.391Z" }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/8b/40/2614036cdd416452f5bf98ec037f38a1afb17f327cb8e6b652d4729e0af8/pyparsing-3.3.1-py3-none-any.whl", hash = "sha256:023b5e7e5520ad96642e2c6db4cb683d3970bd640cdf7115049a6e9c3682df82", size = 121793, upload-time = "2025-12-23T03:14:02.103Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "python-dateutil"
|
||||
version = "2.8.2"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
dependencies = [
|
||||
{ name = "six" },
|
||||
]
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/4c/c4/13b4776ea2d76c115c1d1b84579f3764ee6d57204f6be27119f13a61d0a9/python-dateutil-2.8.2.tar.gz", hash = "sha256:0123cacc1627ae19ddf3c27a5de5bd67ee4586fbdd6440d9748f8abb483d3e86", size = 357324, upload-time = "2021-07-14T08:19:19.783Z" }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/36/7a/87837f39d0296e723bb9b62bbb257d0355c7f6128853c78955f57342a56d/python_dateutil-2.8.2-py2.py3-none-any.whl", hash = "sha256:961d03dc3453ebbc59dbdea9e4e11c5651520a876d0f4db161e8674aae935da9", size = 247702, upload-time = "2021-07-14T08:19:18.161Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "python-jose"
|
||||
version = "3.3.0"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
dependencies = [
|
||||
{ name = "ecdsa" },
|
||||
{ name = "pyasn1" },
|
||||
{ name = "rsa" },
|
||||
]
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/e4/19/b2c86504116dc5f0635d29f802da858404d77d930a25633d2e86a64a35b3/python-jose-3.3.0.tar.gz", hash = "sha256:55779b5e6ad599c6336191246e95eb2293a9ddebd555f796a65f838f07e5d78a", size = 129068, upload-time = "2021-06-05T03:30:40.895Z" }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/bd/2d/e94b2f7bab6773c70efc70a61d66e312e1febccd9e0db6b9e0adf58cbad1/python_jose-3.3.0-py2.py3-none-any.whl", hash = "sha256:9b1376b023f8b298536eedd47ae1089bcdb848f1535ab30555cd92002d78923a", size = 33530, upload-time = "2021-06-05T03:30:38.099Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pyyaml"
|
||||
version = "6.0.1"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/cd/e5/af35f7ea75cf72f2cd079c95ee16797de7cd71f29ea7c68ae5ce7be1eda0/PyYAML-6.0.1.tar.gz", hash = "sha256:bfdf460b1736c775f2ba9f6a92bca30bc2095067b8a9d77876d1fad6cc3b4a43", size = 125201, upload-time = "2023-07-18T00:00:23.308Z" }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/bc/06/1b305bf6aa704343be85444c9d011f626c763abb40c0edc1cad13bfd7f86/PyYAML-6.0.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:855fb52b0dc35af121542a76b9a84f8d1cd886ea97c84703eaa6d88e37a2ad28", size = 178692, upload-time = "2023-08-28T18:43:24.924Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/84/02/404de95ced348b73dd84f70e15a41843d817ff8c1744516bf78358f2ffd2/PyYAML-6.0.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:40df9b996c2b73138957fe23a16a4f0ba614f4c0efce1e9406a184b6d07fa3a9", size = 165622, upload-time = "2023-08-28T18:43:26.54Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/c7/4c/4a2908632fc980da6d918b9de9c1d9d7d7e70b2672b1ad5166ed27841ef7/PyYAML-6.0.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a08c6f0fe150303c1c6b71ebcd7213c2858041a7e01975da3a99aed1e7a378ef", size = 696937, upload-time = "2024-01-18T20:40:22.92Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/b4/33/720548182ffa8344418126017aa1d4ab4aeec9a2275f04ce3f3573d8ace8/PyYAML-6.0.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6c22bec3fbe2524cde73d7ada88f6566758a8f7227bfbf93a408a9d86bcc12a0", size = 724969, upload-time = "2023-08-28T18:43:28.56Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/4f/78/77b40157b6cb5f2d3d31a3d9b2efd1ba3505371f76730d267e8b32cf4b7f/PyYAML-6.0.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:8d4e9c88387b0f5c7d5f281e55304de64cf7f9c0021a3525bd3b1c542da3b0e4", size = 712604, upload-time = "2023-08-28T18:43:30.206Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/2e/97/3e0e089ee85e840f4b15bfa00e4e63d84a3691ababbfea92d6f820ea6f21/PyYAML-6.0.1-cp312-cp312-win32.whl", hash = "sha256:d483d2cdf104e7c9fa60c544d92981f12ad66a457afae824d146093b8c294c54", size = 126098, upload-time = "2023-08-28T18:43:31.835Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/2b/9f/fbade56564ad486809c27b322d0f7e6a89c01f6b4fe208402e90d4443a99/PyYAML-6.0.1-cp312-cp312-win_amd64.whl", hash = "sha256:0d3304d8c0adc42be59c5f8a4d9e3d7379e6955ad754aa9d6ab7a398b59dd1df", size = 138675, upload-time = "2023-08-28T18:43:33.613Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "requests"
|
||||
version = "2.31.0"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
dependencies = [
|
||||
{ name = "certifi" },
|
||||
{ name = "charset-normalizer" },
|
||||
{ name = "idna" },
|
||||
{ name = "urllib3" },
|
||||
]
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/9d/be/10918a2eac4ae9f02f6cfe6414b7a155ccd8f7f9d4380d62fd5b955065c3/requests-2.31.0.tar.gz", hash = "sha256:942c5a758f98d790eaed1a29cb6eefc7ffb0d1cf7af05c3d2791656dbd6ad1e1", size = 110794, upload-time = "2023-05-22T15:12:44.175Z" }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/70/8e/0e2d847013cb52cd35b38c009bb167a1a26b2ce6cd6965bf26b47bc0bf44/requests-2.31.0-py3-none-any.whl", hash = "sha256:58cd2187c01e70e6e26505bca751777aa9f2ee0b7f4300988b709f44e013003f", size = 62574, upload-time = "2023-05-22T15:12:42.313Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "requests-cache"
|
||||
version = "1.1.1"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
dependencies = [
|
||||
{ name = "attrs" },
|
||||
{ name = "cattrs" },
|
||||
{ name = "platformdirs" },
|
||||
{ name = "requests" },
|
||||
{ name = "url-normalize" },
|
||||
{ name = "urllib3" },
|
||||
]
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/4d/b6/24aeda90d94fb1fd2cd755d6ce176e526ef61d407f87fd77de6ab0d03157/requests_cache-1.1.1.tar.gz", hash = "sha256:764f93d3fa860be72125a568c2cc8eafb151cf29b4dc2515433a56ee657e1c60", size = 2876425, upload-time = "2023-11-19T07:20:24.744Z" }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/12/67/9ee2d8d8cca30f2cdc1048a4cd7dac10db2b49ec1eeca31f15a0160b71a0/requests_cache-1.1.1-py3-none-any.whl", hash = "sha256:c8420cf096f3aafde13c374979c21844752e2694ffd8710e6764685bb577ac90", size = 60260, upload-time = "2023-11-19T07:20:22.593Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "roman"
|
||||
version = "4.1"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/32/0c/10c242792e9c857d5d8df19780abec0f241c8a3d9631cccbce16d0f1c769/roman-4.1.tar.gz", hash = "sha256:4da8a200529a730822a27f1704b3ac70bc907141d3bc558115fb8e36af13b412", size = 7005, upload-time = "2023-05-26T08:25:31.645Z" }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/b3/e7/533d5082852a3e0001392b421172d1659a8dc81dad9c41d378adf891d689/roman-4.1-py3-none-any.whl", hash = "sha256:f131fd5eee3510f6173b825404eb97875a6c1925f73a2d7d48cfc67823a67c3c", size = 5490, upload-time = "2023-05-26T08:25:29.342Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rsa"
|
||||
version = "4.9.1"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
dependencies = [
|
||||
{ name = "pyasn1" },
|
||||
]
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/da/8a/22b7beea3ee0d44b1916c0c1cb0ee3af23b700b6da9f04991899d0c555d4/rsa-4.9.1.tar.gz", hash = "sha256:e7bdbfdb5497da4c07dfd35530e1a902659db6ff241e39d9953cad06ebd0ae75", size = 29034, upload-time = "2025-04-16T09:51:18.218Z" }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/64/8d/0133e4eb4beed9e425d9a98ed6e081a55d195481b7632472be1af08d2f6b/rsa-4.9.1-py3-none-any.whl", hash = "sha256:68635866661c6836b8d39430f97a996acbd61bfa49406748ea243539fe239762", size = 34696, upload-time = "2025-04-16T09:51:17.142Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ruff"
|
||||
version = "0.14.8"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/ed/d9/f7a0c4b3a2bf2556cd5d99b05372c29980249ef71e8e32669ba77428c82c/ruff-0.14.8.tar.gz", hash = "sha256:774ed0dd87d6ce925e3b8496feb3a00ac564bea52b9feb551ecd17e0a23d1eed", size = 5765385, upload-time = "2025-12-04T15:06:17.669Z" }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/48/b8/9537b52010134b1d2b72870cc3f92d5fb759394094741b09ceccae183fbe/ruff-0.14.8-py3-none-linux_armv6l.whl", hash = "sha256:ec071e9c82eca417f6111fd39f7043acb53cd3fde9b1f95bbed745962e345afb", size = 13441540, upload-time = "2025-12-04T15:06:14.896Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/24/00/99031684efb025829713682012b6dd37279b1f695ed1b01725f85fd94b38/ruff-0.14.8-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:8cdb162a7159f4ca36ce980a18c43d8f036966e7f73f866ac8f493b75e0c27e9", size = 13669384, upload-time = "2025-12-04T15:06:51.809Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/72/64/3eb5949169fc19c50c04f28ece2c189d3b6edd57e5b533649dae6ca484fe/ruff-0.14.8-py3-none-macosx_11_0_arm64.whl", hash = "sha256:2e2fcbefe91f9fad0916850edf0854530c15bd1926b6b779de47e9ab619ea38f", size = 12806917, upload-time = "2025-12-04T15:06:08.925Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/c4/08/5250babb0b1b11910f470370ec0cbc67470231f7cdc033cee57d4976f941/ruff-0.14.8-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a9d70721066a296f45786ec31916dc287b44040f553da21564de0ab4d45a869b", size = 13256112, upload-time = "2025-12-04T15:06:23.498Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/78/4c/6c588e97a8e8c2d4b522c31a579e1df2b4d003eddfbe23d1f262b1a431ff/ruff-0.14.8-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:2c87e09b3cd9d126fc67a9ecd3b5b1d3ded2b9c7fce3f16e315346b9d05cfb52", size = 13227559, upload-time = "2025-12-04T15:06:33.432Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/23/ce/5f78cea13eda8eceac71b5f6fa6e9223df9b87bb2c1891c166d1f0dce9f1/ruff-0.14.8-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1d62cb310c4fbcb9ee4ac023fe17f984ae1e12b8a4a02e3d21489f9a2a5f730c", size = 13896379, upload-time = "2025-12-04T15:06:02.687Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/cf/79/13de4517c4dadce9218a20035b21212a4c180e009507731f0d3b3f5df85a/ruff-0.14.8-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:1af35c2d62633d4da0521178e8a2641c636d2a7153da0bac1b30cfd4ccd91344", size = 15372786, upload-time = "2025-12-04T15:06:29.828Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/00/06/33df72b3bb42be8a1c3815fd4fae83fa2945fc725a25d87ba3e42d1cc108/ruff-0.14.8-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:25add4575ffecc53d60eed3f24b1e934493631b48ebbc6ebaf9d8517924aca4b", size = 14990029, upload-time = "2025-12-04T15:06:36.812Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/64/61/0f34927bd90925880394de0e081ce1afab66d7b3525336f5771dcf0cb46c/ruff-0.14.8-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:4c943d847b7f02f7db4201a0600ea7d244d8a404fbb639b439e987edcf2baf9a", size = 14407037, upload-time = "2025-12-04T15:06:39.979Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/96/bc/058fe0aefc0fbf0d19614cb6d1a3e2c048f7dc77ca64957f33b12cfdc5ef/ruff-0.14.8-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:cb6e8bf7b4f627548daa1b69283dac5a296bfe9ce856703b03130732e20ddfe2", size = 14102390, upload-time = "2025-12-04T15:06:46.372Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/af/a4/e4f77b02b804546f4c17e8b37a524c27012dd6ff05855d2243b49a7d3cb9/ruff-0.14.8-py3-none-manylinux_2_31_riscv64.whl", hash = "sha256:7aaf2974f378e6b01d1e257c6948207aec6a9b5ba53fab23d0182efb887a0e4a", size = 14230793, upload-time = "2025-12-04T15:06:20.497Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/3f/52/bb8c02373f79552e8d087cedaffad76b8892033d2876c2498a2582f09dcf/ruff-0.14.8-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:e5758ca513c43ad8a4ef13f0f081f80f08008f410790f3611a21a92421ab045b", size = 13160039, upload-time = "2025-12-04T15:06:49.06Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/1f/ad/b69d6962e477842e25c0b11622548df746290cc6d76f9e0f4ed7456c2c31/ruff-0.14.8-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:f74f7ba163b6e85a8d81a590363bf71618847e5078d90827749bfda1d88c9cdf", size = 13205158, upload-time = "2025-12-04T15:06:54.574Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/06/63/54f23da1315c0b3dfc1bc03fbc34e10378918a20c0b0f086418734e57e74/ruff-0.14.8-py3-none-musllinux_1_2_i686.whl", hash = "sha256:eed28f6fafcc9591994c42254f5a5c5ca40e69a30721d2ab18bb0bb3baac3ab6", size = 13469550, upload-time = "2025-12-04T15:05:59.209Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/70/7d/a4d7b1961e4903bc37fffb7ddcfaa7beb250f67d97cfd1ee1d5cddb1ec90/ruff-0.14.8-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:21d48fa744c9d1cb8d71eb0a740c4dd02751a5de9db9a730a8ef75ca34cf138e", size = 14211332, upload-time = "2025-12-04T15:06:06.027Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/5d/93/2a5063341fa17054e5c86582136e9895db773e3c2ffb770dde50a09f35f0/ruff-0.14.8-py3-none-win32.whl", hash = "sha256:15f04cb45c051159baebb0f0037f404f1dc2f15a927418f29730f411a79bc4e7", size = 13151890, upload-time = "2025-12-04T15:06:11.668Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/02/1c/65c61a0859c0add13a3e1cbb6024b42de587456a43006ca2d4fd3d1618fe/ruff-0.14.8-py3-none-win_amd64.whl", hash = "sha256:9eeb0b24242b5bbff3011409a739929f497f3fb5fe3b5698aba5e77e8c833097", size = 14537826, upload-time = "2025-12-04T15:06:26.409Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/6d/63/8b41cea3afd7f58eb64ac9251668ee0073789a3bc9ac6f816c8c6fef986d/ruff-0.14.8-py3-none-win_arm64.whl", hash = "sha256:965a582c93c63fe715fd3e3f8aa37c4b776777203d8e1d8aa3cc0c14424a4b99", size = 13634522, upload-time = "2025-12-04T15:06:43.212Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "six"
|
||||
version = "1.17.0"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/94/e7/b2c673351809dca68a0e064b6af791aa332cf192da575fd474ed7d6f16a2/six-1.17.0.tar.gz", hash = "sha256:ff70335d468e7eb6ec65b95b99d3a2836546063f63acc5171de367e834932a81", size = 34031, upload-time = "2024-12-04T17:35:28.174Z" }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/b7/ce/149a00dd41f10bc29e5921b496af8b574d8413afcd5e30dfa0ed46c2cc5e/six-1.17.0-py2.py3-none-any.whl", hash = "sha256:4721f391ed90541fddacab5acf947aa0d3dc7d27b2e1e8eda2be8970586c3274", size = 11050, upload-time = "2024-12-04T17:35:26.475Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "soupsieve"
|
||||
version = "2.8.1"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/89/23/adf3796d740536d63a6fbda113d07e60c734b6ed5d3058d1e47fc0495e47/soupsieve-2.8.1.tar.gz", hash = "sha256:4cf733bc50fa805f5df4b8ef4740fc0e0fa6218cf3006269afd3f9d6d80fd350", size = 117856, upload-time = "2025-12-18T13:50:34.655Z" }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/48/f3/b67d6ea49ca9154453b6d70b34ea22f3996b9fa55da105a79d8732227adc/soupsieve-2.8.1-py3-none-any.whl", hash = "sha256:a11fe2a6f3d76ab3cf2de04eb339c1be5b506a8a47f2ceb6d139803177f85434", size = 36710, upload-time = "2025-12-18T13:50:33.267Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "sqlalchemy"
|
||||
version = "1.4.50"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
dependencies = [
|
||||
{ name = "greenlet", marker = "platform_machine == 'AMD64' or platform_machine == 'WIN32' or platform_machine == 'aarch64' or platform_machine == 'amd64' or platform_machine == 'ppc64le' or platform_machine == 'win32' or platform_machine == 'x86_64'" },
|
||||
]
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/5a/0a/dabe332c40afebb0a979d3e66b34570fce2f8611bae19b186f0c69f54643/SQLAlchemy-1.4.50.tar.gz", hash = "sha256:3b97ddf509fc21e10b09403b5219b06c5b558b27fc2453150274fa4e70707dbf", size = 8517526, upload-time = "2023-10-29T20:32:00.003Z" }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/5e/ff/72d6f3261ed05b76f7d4127cfc2e5e6590cf16bd87061331ece5066cdfe8/SQLAlchemy-1.4.50-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:77fde9bf74f4659864c8e26ac08add8b084e479b9a18388e7db377afc391f926", size = 1581064, upload-time = "2024-01-11T19:15:51.104Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/b8/e5/eb51bcc247017e4630bb107b15d1ceb8490f588da92b3449905231a61519/SQLAlchemy-1.4.50-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c4cb501d585aa74a0f86d0ea6263b9c5e1d1463f8f9071392477fd401bd3c7cc", size = 1620671, upload-time = "2023-10-29T20:56:37.27Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/b7/cf/4bf87f387b5360d14ef6cbcca64decf5a37ed2f6aa734724825d5146f821/SQLAlchemy-1.4.50-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8a7a66297e46f85a04d68981917c75723e377d2e0599d15fbe7a56abed5e2d75", size = 1619718, upload-time = "2023-10-29T20:56:32.552Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/57/3b/eff9b34517b4db4eadd95e86a79791deae505d18e19ea50af8ef8d1ea7a6/SQLAlchemy-1.4.50-cp312-cp312-win32.whl", hash = "sha256:e86c920b7d362cfa078c8b40e7765cbc34efb44c1007d7557920be9ddf138ec7", size = 1581637, upload-time = "2024-01-11T19:20:19.837Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/f9/24/59bf0b94a619e16743e5bf51ebd10cbe97b8c946b6bd57dbf37189bd38dc/SQLAlchemy-1.4.50-cp312-cp312-win_amd64.whl", hash = "sha256:6b3df20fbbcbcd1c1d43f49ccf3eefb370499088ca251ded632b8cbaee1d497d", size = 1583598, upload-time = "2024-01-11T19:19:03.839Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "typing-extensions"
|
||||
version = "4.15.0"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/72/94/1a15dd82efb362ac84269196e94cf00f187f7ed21c242792a923cdb1c61f/typing_extensions-4.15.0.tar.gz", hash = "sha256:0cea48d173cc12fa28ecabc3b837ea3cf6f38c6d1136f85cbaaf598984861466", size = 109391, upload-time = "2025-08-25T13:49:26.313Z" }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/18/67/36e9267722cc04a6b9f15c7f3441c2363321a3ea07da7ae0c0707beb2a9c/typing_extensions-4.15.0-py3-none-any.whl", hash = "sha256:f0fa19c6845758ab08074a0cfa8b7aecb71c999ca73d62883bc25cc018c4e548", size = 44614, upload-time = "2025-08-25T13:49:24.86Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "url-normalize"
|
||||
version = "2.2.1"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
dependencies = [
|
||||
{ name = "idna" },
|
||||
]
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/80/31/febb777441e5fcdaacb4522316bf2a527c44551430a4873b052d545e3279/url_normalize-2.2.1.tar.gz", hash = "sha256:74a540a3b6eba1d95bdc610c24f2c0141639f3ba903501e61a52a8730247ff37", size = 18846, upload-time = "2025-04-26T20:37:58.553Z" }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/bc/d9/5ec15501b675f7bc07c5d16aa70d8d778b12375686b6efd47656efdc67cd/url_normalize-2.2.1-py3-none-any.whl", hash = "sha256:3deb687587dc91f7b25c9ae5162ffc0f057ae85d22b1e15cf5698311247f567b", size = 14728, upload-time = "2025-04-26T20:37:57.217Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "urllib3"
|
||||
version = "2.6.2"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/1e/24/a2a2ed9addd907787d7aa0355ba36a6cadf1768b934c652ea78acbd59dcd/urllib3-2.6.2.tar.gz", hash = "sha256:016f9c98bb7e98085cb2b4b17b87d2c702975664e4f060c6532e64d1c1a5e797", size = 432930, upload-time = "2025-12-11T15:56:40.252Z" }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/6d/b9/4095b668ea3678bf6a0af005527f39de12fb026516fb3df17495a733b7f8/urllib3-2.6.2-py3-none-any.whl", hash = "sha256:ec21cddfe7724fc7cb4ba4bea7aa8e2ef36f607a4bab81aa6ce42a13dc3f03dd", size = 131182, upload-time = "2025-12-11T15:56:38.584Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wxpython"
|
||||
version = "4.2.1"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
dependencies = [
|
||||
{ name = "pillow" },
|
||||
{ name = "six" },
|
||||
]
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/aa/64/d749e767a8ce7bdc3d533334e03bb1106fc4e4803d16f931fada9007ee13/wxPython-4.2.1.tar.gz", hash = "sha256:e48de211a6606bf072ec3fa778771d6b746c00b7f4b970eb58728ddf56d13d5c", size = 73724359, upload-time = "2023-06-08T01:26:49.508Z" }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/52/5b/55e826723af15e1d9b537c15c4e329a2921e119779aaeb2c0e792bbc5684/wxPython-4.2.1-cp312-cp312-macosx_10_10_universal2.whl", hash = "sha256:957a6e7cc68a8e4d7ca49c72a691b6efd5684040f4f03b112d0122e7ab470497", size = 31534250, upload-time = "2023-06-08T01:24:47.215Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/ee/7c/e7bff7c8d17e279386364214189d8a93ae4ef11f9a2660d4d79b536e1fcb/wxPython-4.2.1-cp312-cp312-win32.whl", hash = "sha256:8d846a785cd33c31e7eb42038eb159c88977d38208496b8322d14aef107f3eec", size = 15433640, upload-time = "2023-06-08T01:24:54.956Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/b7/a4/5b4e30005b0bcf2811537869645aa8a0165fee3de9f387089e34265ca412/wxPython-4.2.1-cp312-cp312-win_amd64.whl", hash = "sha256:1ca327c877f276b33e2c4b6cb8417964305ee505e2509fb2000851d48b82328f", size = 17838517, upload-time = "2023-06-08T01:25:01.8Z" },
|
||||
]
|
||||
@@ -1 +1 @@
|
||||
version: v2.65.0
|
||||
version: v2.65.2
|
||||
|
||||