many, many changes. why wasn't i committing these
This commit is contained in:
parent
38a486131d
commit
535f53c55a
5 changed files with 414 additions and 129 deletions
2
.gitignore
vendored
2
.gitignore
vendored
|
@ -1,2 +1,2 @@
|
|||
testdata/
|
||||
output/
|
||||
packs/
|
|
@ -1,3 +1,10 @@
|
|||
========== Banned alias positions ==========
|
||||
* The
|
||||
* #090
|
||||
* もしン
|
||||
* CAR????
|
||||
* Non
|
||||
東京 *
|
||||
========== (R2) AGEN WIDA ==========
|
||||
Angry Squid
|
||||
Blonde Fox
|
||||
|
@ -657,4 +664,169 @@ StepMania Swearing
|
|||
Flavorless Boys
|
||||
Bullet Refutal
|
||||
Vinyl Countdown
|
||||
Blue Vocals
|
||||
Blue Vocals
|
||||
========== dimocracy 2024 R1 - Bee, Ex, or Eff ==========
|
||||
Swear Meteor
|
||||
Enormous Glue
|
||||
Extraterrestrial Jalapeño
|
||||
Very Jazz
|
||||
The もしン
|
||||
Moonlight Eggo
|
||||
Metal Murray
|
||||
Wrist Swing
|
||||
Team Brick
|
||||
Two Island
|
||||
Metal Banger
|
||||
Slow Island
|
||||
Lively Wave
|
||||
None Emerald
|
||||
Refridgerating Spoon
|
||||
Legal Skirt
|
||||
Leaping Pancake
|
||||
Jungle Factory
|
||||
Punishment Days
|
||||
Disturbed Bag
|
||||
Pink Committee
|
||||
Activate Elf
|
||||
Adventurous Ey
|
||||
Obtain Thumping
|
||||
Scream Cat
|
||||
Last Head
|
||||
Pink Opinion
|
||||
Zodiac Literature
|
||||
Redundant Sun
|
||||
Spruious Salamander
|
||||
Spiky Insurance
|
||||
Boats Song
|
||||
Makita Hi-Tech
|
||||
Omega Rainbow
|
||||
Steep Loss
|
||||
Bubba Wave
|
||||
Scatter Sorcerer
|
||||
This Burst
|
||||
Body Cucumbers
|
||||
Teeny-Tiny Side
|
||||
Expo Calendar
|
||||
Smite Past
|
||||
Alice Ten
|
||||
Heat Oyster
|
||||
Emotion Lotion
|
||||
Spruious Hi-Tech
|
||||
Adventurous Year
|
||||
Volcano Lagoon
|
||||
Cuba Shelter
|
||||
Shiver Wave
|
||||
Last Brother
|
||||
Snail Okay
|
||||
Nice Form
|
||||
Hope Alternative
|
||||
Attempt Jellyfish
|
||||
Magic Breath
|
||||
Makita Canine
|
||||
Turnt Swung
|
||||
Tekken Bubble
|
||||
Obscene Loss
|
||||
Extraterrestrial Glue
|
||||
Geese Curtain
|
||||
Repeat Balance
|
||||
========== dimocracy 2024 R3 - Fantastic Artists ==========
|
||||
Smite Power
|
||||
Adaptable Graph
|
||||
Blunt Spoon
|
||||
Hop Lemons
|
||||
Lethal Harpy
|
||||
Collect Hill
|
||||
Ripe Pants
|
||||
Peaceful Chilver
|
||||
Pioneer Volleyball
|
||||
False Ray
|
||||
Inconspicuous Fun
|
||||
Adaptable Example
|
||||
Pokemon Goggles
|
||||
Fantastic Bear
|
||||
Round Rat
|
||||
Drayze Argument
|
||||
Ghost Example
|
||||
Salami Seagull
|
||||
Fashionable Eleven
|
||||
Tranquil Power
|
||||
Troubleshoot Hi-Tech
|
||||
Feldspar Tooth
|
||||
Suspend On
|
||||
Lively Poser
|
||||
Strip Cannon
|
||||
Lick Shoes
|
||||
Fashionable Over
|
||||
Happy Rest
|
||||
Volcano Jambalaya
|
||||
Two Thumping
|
||||
Uncharacteristically Stream
|
||||
Penitent Want
|
||||
Stylish Idea
|
||||
Sweet Stream
|
||||
Try #090
|
||||
Expect Rag
|
||||
Nice Mania
|
||||
Pleasant Solid
|
||||
Adaptable Wolf
|
||||
Hard-To-Find Sphere
|
||||
Jellyfish Use
|
||||
Alien #090
|
||||
Copy Wave
|
||||
Chew Haganuma
|
||||
Purple Hacker
|
||||
Sweet Music
|
||||
========== dimocracy 2024 R4 - IdK! International dimocr4cy Karaoke! ==========
|
||||
A Holds
|
||||
Milky Wild
|
||||
Basketball Bunions
|
||||
Bite Dandy
|
||||
Grateful Mage
|
||||
New Impersonate
|
||||
Down Off
|
||||
Flam Expert
|
||||
Devilish Scarecrow
|
||||
Stocking Outside
|
||||
Centrifuging Fight
|
||||
Algebra Smuggler
|
||||
Blind Fortress
|
||||
Song Magenta
|
||||
Temple Swords
|
||||
Atlanta Hoagie
|
||||
Seventeen Help
|
||||
Modular Aftermath
|
||||
Pixel Fantastics?
|
||||
Disagreeable Days
|
||||
Heat Hacker
|
||||
Akiba CAR????
|
||||
Marvelous Challenge
|
||||
Blonde Rear
|
||||
Courageous Dance
|
||||
Disturbed Ey
|
||||
Fretful Lemons
|
||||
Peaceful Bane
|
||||
Sixty Power
|
||||
Scream Offset
|
||||
Marvelous Gorilla
|
||||
Construct Weevils
|
||||
Ride Soup
|
||||
Chief Time
|
||||
Steep Bag
|
||||
Simon #090
|
||||
Dark Past
|
||||
Cream Design
|
||||
Pixel Floor
|
||||
Palma NB
|
||||
Modular Statement
|
||||
Nice Gamer
|
||||
Soothing Burst
|
||||
Summer Style
|
||||
Steep Gadzooks
|
||||
Extraterrestrial Weevils
|
||||
More Pickles
|
||||
Wiggly Silver
|
||||
Good Pumpkin
|
||||
Whillikers #090
|
||||
Construct Patient
|
||||
Somber Axolotl
|
||||
Milky Knot
|
|
@ -18,14 +18,16 @@ from fs.base import FS
|
|||
from fs.copy import copy_dir
|
||||
from fs.tempfs import TempFS
|
||||
from fs.zipfs import ZipFS
|
||||
from msdparser import MSDParserError
|
||||
from pathvalidate import sanitize_filename
|
||||
import simfile
|
||||
from simfile.dir import SimfilePack, SimfileDirectory
|
||||
from simfile.notes import NoteData
|
||||
from simfile.sm import SMChart, SMSimfile
|
||||
from simfile.ssc import SSCChart, SSCSimfile
|
||||
from simfile.timing import BeatValues, BeatValue
|
||||
from simfile.types import Simfile, Chart
|
||||
from simfile.tidy import tidy, Preset, RemoveComments
|
||||
from simfile.timing import Beat, BeatValues, BeatValue
|
||||
from simfile.types import Simfile, Chart, AttachedChart
|
||||
|
||||
|
||||
####################
|
||||
|
@ -143,9 +145,11 @@ CsvContents = list[dict[str, str]]
|
|||
|
||||
class KnownColumns(enum.StrEnum):
|
||||
Timestamp = "Timestamp"
|
||||
UserId = "Your gamer tag/alias: (e.g. dimo)"
|
||||
UserId = "Your gamer tag: (e.g. dimo)"
|
||||
GeneratedAlias = "Generated Alias"
|
||||
IgnoreFile = "Ignore File"
|
||||
SongTitle = "Song Title"
|
||||
SongArtist = "Song Artist"
|
||||
# Not persisted:
|
||||
ExtractedTo = "Extracted To"
|
||||
|
||||
|
@ -159,11 +163,32 @@ ChangedCsvContents = bool
|
|||
|
||||
|
||||
def parse_timestamp(timestamp: str):
|
||||
return datetime.strptime(timestamp, "%m/%d/%Y %H:%M:%S")
|
||||
return datetime.strptime(
|
||||
timestamp,
|
||||
"%Y/%m/%d %I:%M:%S %p" # it changed for some reason
|
||||
# "%m/%d/%Y %H:%M:%S"
|
||||
)
|
||||
|
||||
|
||||
def canonical_simfile_filename(sm: Simfile) -> str:
|
||||
return sanitize_filename(f"{sm.title} {sm.subtitle or ''}".rstrip())
|
||||
title_name = f"{sm.titletranslit or sm.title} {sm.subtitletranslit or sm.subtitle or ''}".rstrip()
|
||||
# HACK: replace this with proper duplicate handling later
|
||||
title_name = (
|
||||
title_name.replace("❤", "red_heart")
|
||||
.replace("💚", "green_heart")
|
||||
.replace("💛", "yellow_heart")
|
||||
.replace("💙", "blue_heart")
|
||||
.replace("💜", "purple_heart")
|
||||
.replace("🖤", "black_heart")
|
||||
.replace("🔶", "orange_diamond")
|
||||
.replace("🔷", "blue_diamond")
|
||||
.replace("🔴", "red_circle")
|
||||
.replace("🔵", "blue_circle")
|
||||
)
|
||||
ascii_title_name = "".join([i if ord(i) < 128 else "_" for i in title_name])
|
||||
if all((not c.isalnum() for c in ascii_title_name)):
|
||||
return f"Non-ASCII Title {hash(title_name) % (2**16):x}"
|
||||
return sanitize_filename(ascii_title_name)
|
||||
|
||||
|
||||
################
|
||||
|
@ -280,7 +305,12 @@ def maybe_generate_aliases(
|
|||
for row in csv_contents:
|
||||
rnd = Random(",".join([row[KnownColumns.UserId], seed]))
|
||||
while True:
|
||||
random_alias = f"{rnd.choice(alias_parts[0])} {rnd.choice(alias_parts[1])}"
|
||||
# ad-hoc code for round 2 (3-way collab):
|
||||
# either_part = [*alias_parts[0], *alias_parts[1]]
|
||||
# random_alias = f"{rnd.choice(alias_parts[0])} {rnd.choice(either_part)} {rnd.choice(alias_parts[1])}"
|
||||
random_alias_left = rnd.choice(alias_parts[0])
|
||||
random_alias_right = rnd.choice(alias_parts[1])
|
||||
random_alias = f"{random_alias_left} {random_alias_right}"
|
||||
if (
|
||||
random_alias in alias_to_user_id
|
||||
and alias_to_user_id[random_alias] != row[KnownColumns.UserId]
|
||||
|
@ -288,7 +318,11 @@ def maybe_generate_aliases(
|
|||
print(
|
||||
f"Rerolling alias for {row[KnownColumns.UserId]} because {repr(random_alias)} is already being used by {alias_to_user_id[random_alias]}"
|
||||
)
|
||||
elif random_alias.lower() in usedaliases:
|
||||
elif (
|
||||
random_alias.lower() in usedaliases
|
||||
or f"* {random_alias_right.lower()}" in usedaliases
|
||||
or f"{random_alias_left.lower()} *" in usedaliases
|
||||
):
|
||||
print(
|
||||
f"Rerolling alias for {row[KnownColumns.UserId]} because {repr(random_alias)} has already been used"
|
||||
)
|
||||
|
@ -407,10 +441,14 @@ def extract_entries_to_temporary_folder(
|
|||
|
||||
def extract_simfile_dir(zip_fs: FS, temp_fs: FS) -> str:
|
||||
zip_path, simfile_dir = find_simfile_dir_zip_path(zip_fs)
|
||||
canonical_filename = canonical_simfile_filename(simfile_dir.open())
|
||||
try:
|
||||
canonical_filename = canonical_simfile_filename(simfile_dir.open())
|
||||
except MSDParserError:
|
||||
print("Exception encountered while processing", simfile_dir)
|
||||
raise
|
||||
assert not temp_fs.exists(
|
||||
canonical_filename
|
||||
), "ERROR: trying to extract {canonical_filename} but it's already present in the temp folder"
|
||||
), f"ERROR: trying to extract {canonical_filename} but it's already present in the temp folder"
|
||||
copy_dir(zip_fs, zip_path, temp_fs, canonical_filename)
|
||||
return canonical_filename
|
||||
|
||||
|
@ -455,7 +493,7 @@ def maybe_anonymize_entries(
|
|||
)
|
||||
os.rename(absolute_path, absolute_canonical_path)
|
||||
print(
|
||||
f"Renamed {os.path.relpath(absolute_path, temp_fs.root_path)} to {os.path.relpath(absolute_canonical_path, temp_fs.root_path)}"
|
||||
f"Renaming {os.path.relpath(absolute_path, temp_fs.root_path)} to {os.path.relpath(absolute_canonical_path, temp_fs.root_path)}"
|
||||
)
|
||||
|
||||
def maybe_delete_file(absolute_path: str | None):
|
||||
|
@ -463,19 +501,24 @@ def maybe_anonymize_entries(
|
|||
os.remove(absolute_path)
|
||||
print(f"Deleted {os.path.relpath(absolute_path, temp_fs.root_path)}")
|
||||
|
||||
def anonymize_bpms(bpm_str: str | None) -> str:
|
||||
def anonymize_bpms(obj: Simfile | SSCChart, last_beat: Beat) -> None:
|
||||
bpm_str = obj.bpms
|
||||
bpm_values = BeatValues.from_str(bpm_str)
|
||||
|
||||
if not obj.displaybpm and len(bpm_values) == 1:
|
||||
obj.displaybpm = str(int(bpm_values[0].value))
|
||||
|
||||
bpm_values.append(
|
||||
BeatValue(
|
||||
beat=bpm_values[-1].beat + 10000,
|
||||
beat=last_beat + 4,
|
||||
value=bpm_values[-1].value + Decimal("0.001"),
|
||||
)
|
||||
)
|
||||
obj.bpms = str(bpm_values)
|
||||
print(f"Anonymized BPMs from {repr(bpm_str)} to {repr(str(bpm_values))}")
|
||||
return str(bpm_values)
|
||||
|
||||
def clean_up_difficulties(sf: Simfile):
|
||||
charts_to_remove: list[Chart] = []
|
||||
def clean_up_difficulties(sf: Simfile) -> Chart:
|
||||
charts_to_remove: list[AttachedChart] = []
|
||||
chart_with_notes = None
|
||||
|
||||
for _chart in sf.charts:
|
||||
|
@ -505,7 +548,45 @@ def maybe_anonymize_entries(
|
|||
print(
|
||||
f"WARNING: removing {chart_to_remove.difficulty} chart with no notes from {canonical_filename}"
|
||||
)
|
||||
sm.charts.remove(chart_to_remove)
|
||||
sm.charts.remove(chart_to_remove) # type: ignore
|
||||
|
||||
return chart_with_notes
|
||||
|
||||
def anonymize_simfile(sf: Simfile):
|
||||
if sf.titletranslit == "Chong wo":
|
||||
print(f"Assigning credit to {row[KnownColumns.GeneratedAlias]}")
|
||||
sf.credit = row[KnownColumns.GeneratedAlias]
|
||||
sf.music = f"{canonical_filename}.ogg"
|
||||
sf.background = ""
|
||||
sf.banner = ""
|
||||
sf.cdtitle = ""
|
||||
sf.genre = ""
|
||||
sf.music = f"{canonical_filename}.ogg"
|
||||
|
||||
if isinstance(sf, SSCSimfile):
|
||||
sf.jacket = ""
|
||||
sf.cdimage = ""
|
||||
sf.discimage = ""
|
||||
sf.labels = ""
|
||||
|
||||
chart = clean_up_difficulties(sf)
|
||||
|
||||
last_beat = Beat(0)
|
||||
for note in NoteData(chart):
|
||||
last_beat = note.beat
|
||||
anonymize_bpms(sf, last_beat)
|
||||
|
||||
if isinstance(chart, SMChart):
|
||||
chart.description = row[KnownColumns.GeneratedAlias]
|
||||
else:
|
||||
chart.credit = row[KnownColumns.GeneratedAlias]
|
||||
chart.description = ""
|
||||
chart.chartname = ""
|
||||
chart.chartstyle = ""
|
||||
if chart.bpms:
|
||||
anonymize_bpms(chart, last_beat)
|
||||
|
||||
tidy(sf, Preset.RECOMMENDED, remove_comments=RemoveComments.ALL)
|
||||
|
||||
for row in csv_contents:
|
||||
if row[KnownColumns.IgnoreFile]:
|
||||
|
@ -529,18 +610,7 @@ def maybe_anonymize_entries(
|
|||
if simfile_dir.sm_path:
|
||||
with simfile.mutate(simfile_dir.sm_path) as sm:
|
||||
assert isinstance(sm, SMSimfile)
|
||||
sm.credit = row[KnownColumns.GeneratedAlias]
|
||||
sm.background = ""
|
||||
sm.banner = ""
|
||||
sm.cdtitle = ""
|
||||
sm.genre = ""
|
||||
sm.music = f"{canonical_filename}.ogg"
|
||||
sm.bpms = anonymize_bpms(sm.bpms)
|
||||
clean_up_difficulties(sm)
|
||||
|
||||
for _chart in sm.charts:
|
||||
sm_chart: SMChart = _chart # typing workaround
|
||||
sm_chart.description = row[KnownColumns.GeneratedAlias]
|
||||
anonymize_simfile(sm)
|
||||
maybe_rename_file(simfile_dir.sm_path, f"{canonical_filename}.sm")
|
||||
print(
|
||||
f"Scrubbed {os.path.relpath(absolute_simfile_dir_path, temp_fs.root_path)}/{canonical_filename}.sm"
|
||||
|
@ -549,26 +619,7 @@ def maybe_anonymize_entries(
|
|||
if simfile_dir.ssc_path:
|
||||
with simfile.mutate(simfile_dir.ssc_path) as ssc:
|
||||
assert isinstance(ssc, SSCSimfile)
|
||||
ssc.credit = row[KnownColumns.GeneratedAlias]
|
||||
ssc.music = f"{canonical_filename}.ogg"
|
||||
ssc.background = ""
|
||||
ssc.banner = ""
|
||||
ssc.cdtitle = ""
|
||||
ssc.genre = ""
|
||||
ssc.jacket = ""
|
||||
ssc.cdimage = ""
|
||||
ssc.discimage = ""
|
||||
ssc.labels = ""
|
||||
ssc.bpms = anonymize_bpms(ssc.bpms)
|
||||
clean_up_difficulties(ssc)
|
||||
for _chart in ssc.charts:
|
||||
ssc_chart: SSCChart = _chart # typing workaround
|
||||
ssc_chart.description = ""
|
||||
ssc_chart.chartname = ""
|
||||
ssc_chart.chartstyle = ""
|
||||
ssc_chart.credit = row[KnownColumns.GeneratedAlias]
|
||||
if ssc_chart.bpms:
|
||||
ssc_chart.bpms = anonymize_bpms(ssc_chart.bpms)
|
||||
anonymize_simfile(ssc)
|
||||
maybe_rename_file(simfile_dir.ssc_path, f"{canonical_filename}.ssc")
|
||||
print(
|
||||
f"Scrubbed {os.path.relpath(absolute_simfile_dir_path, temp_fs.root_path)}/{canonical_filename}.ssc"
|
||||
|
@ -583,6 +634,7 @@ def maybe_anonymize_entries(
|
|||
or dir_entry.name.endswith(".txt")
|
||||
or dir_entry.name.endswith(".zip")
|
||||
or dir_entry.name == ".DS_Store"
|
||||
or dir_entry.name == "desktop.ini"
|
||||
):
|
||||
# These are definitely safe to delete for distribution
|
||||
os.remove(dir_entry.path)
|
||||
|
@ -616,7 +668,7 @@ def maybe_save_anonymized_files(
|
|||
args: AnonymizeEntriesArgs,
|
||||
csv_contents: CsvContents,
|
||||
temp_fs: TempFS,
|
||||
):
|
||||
) -> str | None:
|
||||
if args.dry_run:
|
||||
print("Dry run - not saving files")
|
||||
return
|
||||
|
@ -625,6 +677,39 @@ def maybe_save_anonymized_files(
|
|||
output_path = f"{args.output}/{de}anonymized-{timestamp}"
|
||||
shutil.copytree(temp_fs.root_path, output_path)
|
||||
print(f"Saved to {os.path.abspath(output_path)}")
|
||||
return output_path
|
||||
|
||||
|
||||
def maybe_generate_song_metadata(
|
||||
args: AnonymizeEntriesArgs,
|
||||
csv_contents: CsvContents,
|
||||
output_path: str,
|
||||
):
|
||||
reuse_song_metadata = (
|
||||
not args.regenerate
|
||||
and KnownColumns.SongTitle in csv_contents[0]
|
||||
and KnownColumns.SongArtist in csv_contents[0]
|
||||
)
|
||||
|
||||
if reuse_song_metadata:
|
||||
print("Reusing generated song metadata")
|
||||
return False
|
||||
|
||||
alias_to_simfile: dict[str, Simfile] = {}
|
||||
for sf, sf_path in simfile.openpack(output_path):
|
||||
assert sf.credit, f"{sf_path} was generated without a credit?!"
|
||||
alias_to_simfile[sf.credit] = sf
|
||||
|
||||
for row in csv_contents:
|
||||
alias = row[KnownColumns.GeneratedAlias]
|
||||
sf = alias_to_simfile[alias]
|
||||
row[KnownColumns.SongTitle] = f"{sf.title} {sf.subtitle or ''}".rstrip()
|
||||
row[KnownColumns.SongArtist] = sf.artist or ""
|
||||
print(
|
||||
f"Mapped {alias} to {row[KnownColumns.SongTitle]} by {row[KnownColumns.SongArtist]}"
|
||||
)
|
||||
|
||||
return True
|
||||
|
||||
|
||||
###############
|
||||
|
@ -652,7 +737,13 @@ def main(argv: list[str]):
|
|||
|
||||
temp_fs = extract_entries_to_temporary_folder(args, csv_contents, dynamic_columns)
|
||||
maybe_anonymize_entries(args, csv_contents, temp_fs)
|
||||
maybe_save_anonymized_files(args, csv_contents, temp_fs)
|
||||
output_path = maybe_save_anonymized_files(args, csv_contents, temp_fs)
|
||||
if output_path:
|
||||
csv_contents_changed = maybe_generate_song_metadata(
|
||||
args, csv_contents, output_path
|
||||
)
|
||||
if csv_contents_changed:
|
||||
maybe_save_generated_columns(args, csv_contents)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
|
174
poetry.lock
generated
174
poetry.lock
generated
|
@ -13,33 +13,33 @@ files = [
|
|||
|
||||
[[package]]
|
||||
name = "black"
|
||||
version = "24.8.0"
|
||||
version = "24.10.0"
|
||||
description = "The uncompromising code formatter."
|
||||
optional = false
|
||||
python-versions = ">=3.8"
|
||||
python-versions = ">=3.9"
|
||||
files = [
|
||||
{file = "black-24.8.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:09cdeb74d494ec023ded657f7092ba518e8cf78fa8386155e4a03fdcc44679e6"},
|
||||
{file = "black-24.8.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:81c6742da39f33b08e791da38410f32e27d632260e599df7245cccee2064afeb"},
|
||||
{file = "black-24.8.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:707a1ca89221bc8a1a64fb5e15ef39cd755633daa672a9db7498d1c19de66a42"},
|
||||
{file = "black-24.8.0-cp310-cp310-win_amd64.whl", hash = "sha256:d6417535d99c37cee4091a2f24eb2b6d5ec42b144d50f1f2e436d9fe1916fe1a"},
|
||||
{file = "black-24.8.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:fb6e2c0b86bbd43dee042e48059c9ad7830abd5c94b0bc518c0eeec57c3eddc1"},
|
||||
{file = "black-24.8.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:837fd281f1908d0076844bc2b801ad2d369c78c45cf800cad7b61686051041af"},
|
||||
{file = "black-24.8.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:62e8730977f0b77998029da7971fa896ceefa2c4c4933fcd593fa599ecbf97a4"},
|
||||
{file = "black-24.8.0-cp311-cp311-win_amd64.whl", hash = "sha256:72901b4913cbac8972ad911dc4098d5753704d1f3c56e44ae8dce99eecb0e3af"},
|
||||
{file = "black-24.8.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:7c046c1d1eeb7aea9335da62472481d3bbf3fd986e093cffd35f4385c94ae368"},
|
||||
{file = "black-24.8.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:649f6d84ccbae73ab767e206772cc2d7a393a001070a4c814a546afd0d423aed"},
|
||||
{file = "black-24.8.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:2b59b250fdba5f9a9cd9d0ece6e6d993d91ce877d121d161e4698af3eb9c1018"},
|
||||
{file = "black-24.8.0-cp312-cp312-win_amd64.whl", hash = "sha256:6e55d30d44bed36593c3163b9bc63bf58b3b30e4611e4d88a0c3c239930ed5b2"},
|
||||
{file = "black-24.8.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:505289f17ceda596658ae81b61ebbe2d9b25aa78067035184ed0a9d855d18afd"},
|
||||
{file = "black-24.8.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:b19c9ad992c7883ad84c9b22aaa73562a16b819c1d8db7a1a1a49fb7ec13c7d2"},
|
||||
{file = "black-24.8.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:1f13f7f386f86f8121d76599114bb8c17b69d962137fc70efe56137727c7047e"},
|
||||
{file = "black-24.8.0-cp38-cp38-win_amd64.whl", hash = "sha256:f490dbd59680d809ca31efdae20e634f3fae27fba3ce0ba3208333b713bc3920"},
|
||||
{file = "black-24.8.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:eab4dd44ce80dea27dc69db40dab62d4ca96112f87996bca68cd75639aeb2e4c"},
|
||||
{file = "black-24.8.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:3c4285573d4897a7610054af5a890bde7c65cb466040c5f0c8b732812d7f0e5e"},
|
||||
{file = "black-24.8.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:9e84e33b37be070ba135176c123ae52a51f82306def9f7d063ee302ecab2cf47"},
|
||||
{file = "black-24.8.0-cp39-cp39-win_amd64.whl", hash = "sha256:73bbf84ed136e45d451a260c6b73ed674652f90a2b3211d6a35e78054563a9bb"},
|
||||
{file = "black-24.8.0-py3-none-any.whl", hash = "sha256:972085c618ee94f402da1af548a4f218c754ea7e5dc70acb168bfaca4c2542ed"},
|
||||
{file = "black-24.8.0.tar.gz", hash = "sha256:2500945420b6784c38b9ee885af039f5e7471ef284ab03fa35ecdde4688cd83f"},
|
||||
{file = "black-24.10.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:e6668650ea4b685440857138e5fe40cde4d652633b1bdffc62933d0db4ed9812"},
|
||||
{file = "black-24.10.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:1c536fcf674217e87b8cc3657b81809d3c085d7bf3ef262ead700da345bfa6ea"},
|
||||
{file = "black-24.10.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:649fff99a20bd06c6f727d2a27f401331dc0cc861fb69cde910fe95b01b5928f"},
|
||||
{file = "black-24.10.0-cp310-cp310-win_amd64.whl", hash = "sha256:fe4d6476887de70546212c99ac9bd803d90b42fc4767f058a0baa895013fbb3e"},
|
||||
{file = "black-24.10.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:5a2221696a8224e335c28816a9d331a6c2ae15a2ee34ec857dcf3e45dbfa99ad"},
|
||||
{file = "black-24.10.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:f9da3333530dbcecc1be13e69c250ed8dfa67f43c4005fb537bb426e19200d50"},
|
||||
{file = "black-24.10.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:4007b1393d902b48b36958a216c20c4482f601569d19ed1df294a496eb366392"},
|
||||
{file = "black-24.10.0-cp311-cp311-win_amd64.whl", hash = "sha256:394d4ddc64782e51153eadcaaca95144ac4c35e27ef9b0a42e121ae7e57a9175"},
|
||||
{file = "black-24.10.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:b5e39e0fae001df40f95bd8cc36b9165c5e2ea88900167bddf258bacef9bbdc3"},
|
||||
{file = "black-24.10.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:d37d422772111794b26757c5b55a3eade028aa3fde43121ab7b673d050949d65"},
|
||||
{file = "black-24.10.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:14b3502784f09ce2443830e3133dacf2c0110d45191ed470ecb04d0f5f6fcb0f"},
|
||||
{file = "black-24.10.0-cp312-cp312-win_amd64.whl", hash = "sha256:30d2c30dc5139211dda799758559d1b049f7f14c580c409d6ad925b74a4208a8"},
|
||||
{file = "black-24.10.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:1cbacacb19e922a1d75ef2b6ccaefcd6e93a2c05ede32f06a21386a04cedb981"},
|
||||
{file = "black-24.10.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:1f93102e0c5bb3907451063e08b9876dbeac810e7da5a8bfb7aeb5a9ef89066b"},
|
||||
{file = "black-24.10.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:ddacb691cdcdf77b96f549cf9591701d8db36b2f19519373d60d31746068dbf2"},
|
||||
{file = "black-24.10.0-cp313-cp313-win_amd64.whl", hash = "sha256:680359d932801c76d2e9c9068d05c6b107f2584b2a5b88831c83962eb9984c1b"},
|
||||
{file = "black-24.10.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:17374989640fbca88b6a448129cd1745c5eb8d9547b464f281b251dd00155ccd"},
|
||||
{file = "black-24.10.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:63f626344343083322233f175aaf372d326de8436f5928c042639a4afbbf1d3f"},
|
||||
{file = "black-24.10.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:ccfa1d0cb6200857f1923b602f978386a3a2758a65b52e0950299ea014be6800"},
|
||||
{file = "black-24.10.0-cp39-cp39-win_amd64.whl", hash = "sha256:2cd9c95431d94adc56600710f8813ee27eea544dd118d45896bb734e9d7a0dc7"},
|
||||
{file = "black-24.10.0-py3-none-any.whl", hash = "sha256:3bb2b7a1f7b685f85b11fed1ef10f8a9148bceb49853e47a294a3dd963c1dd7d"},
|
||||
{file = "black-24.10.0.tar.gz", hash = "sha256:846ea64c97afe3bc677b761787993be4991810ecc7a4a937816dd6bddedc4875"},
|
||||
]
|
||||
|
||||
[package.dependencies]
|
||||
|
@ -51,19 +51,19 @@ platformdirs = ">=2"
|
|||
|
||||
[package.extras]
|
||||
colorama = ["colorama (>=0.4.3)"]
|
||||
d = ["aiohttp (>=3.7.4)", "aiohttp (>=3.7.4,!=3.9.0)"]
|
||||
d = ["aiohttp (>=3.10)"]
|
||||
jupyter = ["ipython (>=7.8.0)", "tokenize-rt (>=3.2.0)"]
|
||||
uvloop = ["uvloop (>=0.15.2)"]
|
||||
|
||||
[[package]]
|
||||
name = "click"
|
||||
version = "8.1.7"
|
||||
version = "8.1.8"
|
||||
description = "Composable command line interface toolkit"
|
||||
optional = false
|
||||
python-versions = ">=3.7"
|
||||
files = [
|
||||
{file = "click-8.1.7-py3-none-any.whl", hash = "sha256:ae74fb96c20a0277a1d615f1e4d73c8414f5a98db8b799a7931d1582f3390c28"},
|
||||
{file = "click-8.1.7.tar.gz", hash = "sha256:ca9853ad459e787e2192211578cc907e7594e294c7ccc834310722b41b9ca6de"},
|
||||
{file = "click-8.1.8-py3-none-any.whl", hash = "sha256:63c132bbbed01578a06712a2d1f497bb62d9c1c0d329b7903a866228027263b2"},
|
||||
{file = "click-8.1.8.tar.gz", hash = "sha256:ed53c9d8990d83c2a27deae68e4ee337473f6330c040a31d4225c9574d16096a"},
|
||||
]
|
||||
|
||||
[package.dependencies]
|
||||
|
@ -101,13 +101,13 @@ scandir = ["scandir (>=1.5,<2.0)"]
|
|||
|
||||
[[package]]
|
||||
name = "msdparser"
|
||||
version = "2.0.0"
|
||||
description = "Robust & lightning fast MSD parser (StepMania file format)"
|
||||
version = "3.0.0a7"
|
||||
description = "Low-level parser for StepMania MSD files (SM, SSC, DWI...)"
|
||||
optional = false
|
||||
python-versions = ">=3.6"
|
||||
python-versions = ">=3.10"
|
||||
files = [
|
||||
{file = "msdparser-2.0.0-py3-none-any.whl", hash = "sha256:bbef8c89b2dc16183ba714354b093fff11a43469971c42972284c5046826002d"},
|
||||
{file = "msdparser-2.0.0.tar.gz", hash = "sha256:9bb6cf4b705c76850b1ce22823c768b62ba2bb63d1c2407bbe3e2c23e38be8e3"},
|
||||
{file = "msdparser-3.0.0a7-py3-none-any.whl", hash = "sha256:ef324aa943e325bc1c1ef6b363bf55433def3deb8a9f2fa608b14eff828ccf64"},
|
||||
{file = "msdparser-3.0.0a7.tar.gz", hash = "sha256:797bc6a99ae491cf2712483d2e0fb086ac4e047354cc8f8e4712bce95833c6c6"},
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -123,13 +123,13 @@ files = [
|
|||
|
||||
[[package]]
|
||||
name = "packaging"
|
||||
version = "24.1"
|
||||
version = "24.2"
|
||||
description = "Core utilities for Python packages"
|
||||
optional = false
|
||||
python-versions = ">=3.8"
|
||||
files = [
|
||||
{file = "packaging-24.1-py3-none-any.whl", hash = "sha256:5b8f2217dbdbd2f7f384c41c628544e6d52f2d0f53c6d0c3ea61aa5d1d7ff124"},
|
||||
{file = "packaging-24.1.tar.gz", hash = "sha256:026ed72c8ed3fcce5bf8950572258698927fd1dbda10a5e981cdf0ac37f4f002"},
|
||||
{file = "packaging-24.2-py3-none-any.whl", hash = "sha256:09abb1bccd265c01f4a3aa3f7a7db064b36514d2cba19a2f694fe6150451a759"},
|
||||
{file = "packaging-24.2.tar.gz", hash = "sha256:c228a6dc5e932d346bc5739379109d49e8853dd8223571c7c5b55260edc0b97f"},
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -145,78 +145,100 @@ files = [
|
|||
|
||||
[[package]]
|
||||
name = "pathvalidate"
|
||||
version = "3.2.0"
|
||||
version = "3.2.3"
|
||||
description = "pathvalidate is a Python library to sanitize/validate a string such as filenames/file-paths/etc."
|
||||
optional = false
|
||||
python-versions = ">=3.7"
|
||||
python-versions = ">=3.9"
|
||||
files = [
|
||||
{file = "pathvalidate-3.2.0-py3-none-any.whl", hash = "sha256:cc593caa6299b22b37f228148257997e2fa850eea2daf7e4cc9205cef6908dee"},
|
||||
{file = "pathvalidate-3.2.0.tar.gz", hash = "sha256:5e8378cf6712bff67fbe7a8307d99fa8c1a0cb28aa477056f8fc374f0dff24ad"},
|
||||
{file = "pathvalidate-3.2.3-py3-none-any.whl", hash = "sha256:5eaf0562e345d4b6d0c0239d0f690c3bd84d2a9a3c4c73b99ea667401b27bee1"},
|
||||
{file = "pathvalidate-3.2.3.tar.gz", hash = "sha256:59b5b9278e30382d6d213497623043ebe63f10e29055be4419a9c04c721739cb"},
|
||||
]
|
||||
|
||||
[package.extras]
|
||||
docs = ["Sphinx (>=2.4)", "sphinx-rtd-theme (>=1.2.2)", "urllib3 (<2)"]
|
||||
test = ["Faker (>=1.0.8)", "allpairspy (>=2)", "click (>=6.2)", "pytest (>=6.0.1)", "pytest-discord (>=0.1.4)", "pytest-md-report (>=0.4.1)"]
|
||||
docs = ["Sphinx (>=2.4)", "sphinx_rtd_theme (>=1.2.2)", "urllib3 (<2)"]
|
||||
readme = ["path (>=13,<18)", "readmemaker (>=1.2.0)"]
|
||||
test = ["Faker (>=1.0.8)", "allpairspy (>=2)", "click (>=6.2)", "pytest (>=6.0.1)", "pytest-md-report (>=0.6.2)"]
|
||||
|
||||
[[package]]
|
||||
name = "platformdirs"
|
||||
version = "4.2.2"
|
||||
version = "4.3.6"
|
||||
description = "A small Python package for determining appropriate platform-specific dirs, e.g. a `user data dir`."
|
||||
optional = false
|
||||
python-versions = ">=3.8"
|
||||
files = [
|
||||
{file = "platformdirs-4.2.2-py3-none-any.whl", hash = "sha256:2d7a1657e36a80ea911db832a8a6ece5ee53d8de21edd5cc5879af6530b1bfee"},
|
||||
{file = "platformdirs-4.2.2.tar.gz", hash = "sha256:38b7b51f512eed9e84a22788b4bce1de17c0adb134d6becb09836e37d8654cd3"},
|
||||
{file = "platformdirs-4.3.6-py3-none-any.whl", hash = "sha256:73e575e1408ab8103900836b97580d5307456908a03e92031bab39e4554cc3fb"},
|
||||
{file = "platformdirs-4.3.6.tar.gz", hash = "sha256:357fb2acbc885b0419afd3ce3ed34564c13c9b95c89360cd9563f73aa5e2b907"},
|
||||
]
|
||||
|
||||
[package.extras]
|
||||
docs = ["furo (>=2023.9.10)", "proselint (>=0.13)", "sphinx (>=7.2.6)", "sphinx-autodoc-typehints (>=1.25.2)"]
|
||||
test = ["appdirs (==1.4.4)", "covdefaults (>=2.3)", "pytest (>=7.4.3)", "pytest-cov (>=4.1)", "pytest-mock (>=3.12)"]
|
||||
type = ["mypy (>=1.8)"]
|
||||
docs = ["furo (>=2024.8.6)", "proselint (>=0.14)", "sphinx (>=8.0.2)", "sphinx-autodoc-typehints (>=2.4)"]
|
||||
test = ["appdirs (==1.4.4)", "covdefaults (>=2.3)", "pytest (>=8.3.2)", "pytest-cov (>=5)", "pytest-mock (>=3.14)"]
|
||||
type = ["mypy (>=1.11.2)"]
|
||||
|
||||
[[package]]
|
||||
name = "setuptools"
|
||||
version = "72.1.0"
|
||||
description = "Easily download, build, install, upgrade, and uninstall Python packages"
|
||||
optional = false
|
||||
python-versions = ">=3.8"
|
||||
files = [
|
||||
{file = "setuptools-72.1.0-py3-none-any.whl", hash = "sha256:5a03e1860cf56bb6ef48ce186b0e557fdba433237481a9a625176c2831be15d1"},
|
||||
{file = "setuptools-72.1.0.tar.gz", hash = "sha256:8d243eff56d095e5817f796ede6ae32941278f542e0f941867cc05ae52b162ec"},
|
||||
]
|
||||
|
||||
[package.extras]
|
||||
core = ["importlib-metadata (>=6)", "importlib-resources (>=5.10.2)", "jaraco.text (>=3.7)", "more-itertools (>=8.8)", "ordered-set (>=3.1.1)", "packaging (>=24)", "platformdirs (>=2.6.2)", "tomli (>=2.0.1)", "wheel (>=0.43.0)"]
|
||||
doc = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "pygments-github-lexers (==0.0.5)", "pyproject-hooks (!=1.1)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-favicon", "sphinx-inline-tabs", "sphinx-lint", "sphinx-notfound-page (>=1,<2)", "sphinx-reredirects", "sphinxcontrib-towncrier"]
|
||||
test = ["build[virtualenv] (>=1.0.3)", "filelock (>=3.4.0)", "importlib-metadata", "ini2toml[lite] (>=0.14)", "jaraco.develop (>=7.21)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "jaraco.test", "mypy (==1.11.*)", "packaging (>=23.2)", "pip (>=19.1)", "pyproject-hooks (!=1.1)", "pytest (>=6,!=8.1.*)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=2.2)", "pytest-home (>=0.5)", "pytest-mypy", "pytest-perf", "pytest-ruff (<0.4)", "pytest-ruff (>=0.2.1)", "pytest-ruff (>=0.3.2)", "pytest-subprocess", "pytest-timeout", "pytest-xdist (>=3)", "tomli", "tomli-w (>=1.0.0)", "virtualenv (>=13.0.0)", "wheel"]
|
||||
|
||||
[[package]]
|
||||
name = "simfile"
|
||||
version = "2.1.1"
|
||||
description = "Modern simfile library for Python"
|
||||
name = "pyfakefs"
|
||||
version = "4.5.6"
|
||||
description = "pyfakefs implements a fake file system that mocks the Python file system modules."
|
||||
optional = false
|
||||
python-versions = ">=3.6"
|
||||
files = [
|
||||
{file = "simfile-2.1.1-py3-none-any.whl", hash = "sha256:133094a33cf6b841ca7e620880ef8354c56dd4aef6b2c77582de7f120f69c620"},
|
||||
{file = "simfile-2.1.1.tar.gz", hash = "sha256:a7885f8395cdd0f19cd79da34e5675da778aa0e8dda76543cf075e21b862c4b7"},
|
||||
{file = "pyfakefs-4.5.6-py3-none-any.whl", hash = "sha256:6bb4e27457b0bc90e3ebfe5aed4f1b8c32a18713ba44e925f304bb9b9816a03c"},
|
||||
{file = "pyfakefs-4.5.6.tar.gz", hash = "sha256:914d7bf994406cfbefee0b4d45918f60c15b406afe93f8194a804da5a450a822"},
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "setuptools"
|
||||
version = "75.8.0"
|
||||
description = "Easily download, build, install, upgrade, and uninstall Python packages"
|
||||
optional = false
|
||||
python-versions = ">=3.9"
|
||||
files = [
|
||||
{file = "setuptools-75.8.0-py3-none-any.whl", hash = "sha256:e3982f444617239225d675215d51f6ba05f845d4eec313da4418fdbb56fb27e3"},
|
||||
{file = "setuptools-75.8.0.tar.gz", hash = "sha256:c5afc8f407c626b8313a86e10311dd3f661c6cd9c09d4bf8c15c0e11f9f2b0e6"},
|
||||
]
|
||||
|
||||
[package.extras]
|
||||
check = ["pytest-checkdocs (>=2.4)", "pytest-ruff (>=0.2.1)", "ruff (>=0.8.0)"]
|
||||
core = ["importlib_metadata (>=6)", "jaraco.collections", "jaraco.functools (>=4)", "jaraco.text (>=3.7)", "more_itertools", "more_itertools (>=8.8)", "packaging", "packaging (>=24.2)", "platformdirs (>=4.2.2)", "tomli (>=2.0.1)", "wheel (>=0.43.0)"]
|
||||
cover = ["pytest-cov"]
|
||||
doc = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "pygments-github-lexers (==0.0.5)", "pyproject-hooks (!=1.1)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-favicon", "sphinx-inline-tabs", "sphinx-lint", "sphinx-notfound-page (>=1,<2)", "sphinx-reredirects", "sphinxcontrib-towncrier", "towncrier (<24.7)"]
|
||||
enabler = ["pytest-enabler (>=2.2)"]
|
||||
test = ["build[virtualenv] (>=1.0.3)", "filelock (>=3.4.0)", "ini2toml[lite] (>=0.14)", "jaraco.develop (>=7.21)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.7.2)", "jaraco.test (>=5.5)", "packaging (>=24.2)", "pip (>=19.1)", "pyproject-hooks (!=1.1)", "pytest (>=6,!=8.1.*)", "pytest-home (>=0.5)", "pytest-perf", "pytest-subprocess", "pytest-timeout", "pytest-xdist (>=3)", "tomli-w (>=1.0.0)", "virtualenv (>=13.0.0)", "wheel (>=0.44.0)"]
|
||||
type = ["importlib_metadata (>=7.0.2)", "jaraco.develop (>=7.21)", "mypy (==1.14.*)", "pytest-mypy"]
|
||||
|
||||
[[package]]
|
||||
name = "simfile"
|
||||
version = "3.0.0a4"
|
||||
description = "Simfile parsing & editing library"
|
||||
optional = false
|
||||
python-versions = ">=3.10"
|
||||
files = [
|
||||
{file = "simfile-3.0.0a4-py3-none-any.whl", hash = "sha256:dc86236debdecf257065c5614397655503d78e8679c801215b3b3a93bdb2ef9c"},
|
||||
{file = "simfile-3.0.0a4.tar.gz", hash = "sha256:c20e5c8aa7833ce48d54e2f42ad068466271209861630f4d2e17a9cc6f0b3460"},
|
||||
]
|
||||
|
||||
[package.dependencies]
|
||||
fs = ">=2.4.15,<2.5.0"
|
||||
msdparser = ">=2.0.0,<2.1.0"
|
||||
fs = {version = "*", optional = true, markers = "extra == \"fs\""}
|
||||
msdparser = ">=3.0.0a7,<3.1.0"
|
||||
pyfakefs = "4.5.6"
|
||||
|
||||
[package.extras]
|
||||
all = ["fs", "pillow"]
|
||||
assets = ["pillow"]
|
||||
fs = ["fs"]
|
||||
|
||||
[[package]]
|
||||
name = "six"
|
||||
version = "1.16.0"
|
||||
version = "1.17.0"
|
||||
description = "Python 2 and 3 compatibility utilities"
|
||||
optional = false
|
||||
python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*"
|
||||
python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,>=2.7"
|
||||
files = [
|
||||
{file = "six-1.16.0-py2.py3-none-any.whl", hash = "sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254"},
|
||||
{file = "six-1.16.0.tar.gz", hash = "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926"},
|
||||
{file = "six-1.17.0-py2.py3-none-any.whl", hash = "sha256:4721f391ed90541fddacab5acf947aa0d3dc7d27b2e1e8eda2be8970586c3274"},
|
||||
{file = "six-1.17.0.tar.gz", hash = "sha256:ff70335d468e7eb6ec65b95b99d3a2836546063f63acc5171de367e834932a81"},
|
||||
]
|
||||
|
||||
[metadata]
|
||||
lock-version = "2.0"
|
||||
python-versions = "^3.11"
|
||||
content-hash = "cb0ec3bd6d2ec3fb7296e6dd4801035c044c88cc2e7da894954d5805603b9fee"
|
||||
content-hash = "e855e50e2b9a7cbc4e17dbabdd57f17341c367540360e9ae990752eb0b481afa"
|
||||
|
|
|
@ -7,7 +7,7 @@ readme = "README.md"
|
|||
|
||||
[tool.poetry.dependencies]
|
||||
python = "^3.11"
|
||||
simfile = "^2.1.1"
|
||||
simfile = {version = "^3.0.0a4", extras = ["fs"]}
|
||||
pathvalidate = "^3.2.0"
|
||||
|
||||
[tool.poetry.group.dev.dependencies]
|
||||
|
|
Loading…
Reference in a new issue