WIP: Moderation type registry #26
20 changed files with 1706 additions and 1287 deletions
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -2,3 +2,4 @@
|
||||||
.vscode
|
.vscode
|
||||||
site
|
site
|
||||||
.venv
|
.venv
|
||||||
|
__pycache__
|
||||||
|
|
867
aurora/aurora.py
867
aurora/aurora.py
File diff suppressed because it is too large
Load diff
|
@ -1,13 +1,15 @@
|
||||||
# pylint: disable=duplicate-code
|
# pylint: disable=duplicate-code
|
||||||
import json
|
import json
|
||||||
from datetime import timedelta
|
from datetime import timedelta
|
||||||
|
from time import time
|
||||||
from typing import Dict
|
from typing import Dict
|
||||||
|
|
||||||
from discord import ButtonStyle, Interaction, Message, ui
|
from discord import ButtonStyle, Interaction, Message, ui
|
||||||
from redbot.core import commands
|
from redbot.core import commands
|
||||||
from redbot.core.utils.chat_formatting import box, warning
|
from redbot.core.utils.chat_formatting import box, warning
|
||||||
|
|
||||||
from ..utilities.database import connect, create_guild_table, mysql_log
|
from ..models.moderation import Moderation
|
||||||
|
from ..utilities.database import connect, create_guild_table
|
||||||
|
|
||||||
|
|
||||||
class ImportAuroraView(ui.View):
|
class ImportAuroraView(ui.View):
|
||||||
|
@ -62,10 +64,23 @@ class ImportAuroraView(ui.View):
|
||||||
case["target_type"] = "USER"
|
case["target_type"] = "USER"
|
||||||
|
|
||||||
if "role_id" not in case or not case["role_id"]:
|
if "role_id" not in case or not case["role_id"]:
|
||||||
case["role_id"] = 0
|
case["role_id"] = None
|
||||||
|
else:
|
||||||
|
case["role_id"] = int(case["role_id"])
|
||||||
|
|
||||||
|
case["target_id"] = int(case["target_id"])
|
||||||
|
case["moderator_id"] = int(case["moderator_id"])
|
||||||
|
|
||||||
if "changes" not in case or not case["changes"]:
|
if "changes" not in case or not case["changes"]:
|
||||||
case["changes"] = []
|
changes = []
|
||||||
|
else:
|
||||||
|
changes = json.loads(case["changes"])
|
||||||
|
if isinstance(changes, str):
|
||||||
|
changes: list[dict] = json.loads(changes)
|
||||||
|
|
||||||
|
for change in changes:
|
||||||
|
if change.get("bot"):
|
||||||
|
del change["bot"]
|
||||||
|
|
||||||
if "metadata" not in case:
|
if "metadata" not in case:
|
||||||
metadata = {}
|
metadata = {}
|
||||||
|
@ -73,28 +88,30 @@ class ImportAuroraView(ui.View):
|
||||||
metadata: Dict[str, any] = json.loads(case["metadata"])
|
metadata: Dict[str, any] = json.loads(case["metadata"])
|
||||||
if not metadata.get("imported_from"):
|
if not metadata.get("imported_from"):
|
||||||
metadata.update({"imported_from": "Aurora"})
|
metadata.update({"imported_from": "Aurora"})
|
||||||
|
metadata.update({"imported_timestamp": int(time())})
|
||||||
|
|
||||||
if case["duration"] != "NULL":
|
if case["duration"] != "NULL" and case["duration"] is not None:
|
||||||
hours, minutes, seconds = map(int, case["duration"].split(":"))
|
hours, minutes, seconds = map(int, case["duration"].split(":"))
|
||||||
duration = timedelta(hours=hours, minutes=minutes, seconds=seconds)
|
duration = timedelta(hours=hours, minutes=minutes, seconds=seconds)
|
||||||
else:
|
else:
|
||||||
duration = "NULL"
|
duration = None
|
||||||
|
|
||||||
await mysql_log(
|
Moderation.log(
|
||||||
self.ctx.guild.id,
|
bot=interaction.client,
|
||||||
case["moderator_id"],
|
guild_id=self.ctx.guild.id,
|
||||||
case["moderation_type"],
|
moderator_id=case["moderator_id"],
|
||||||
case["target_type"],
|
moderation_type=case["moderation_type"],
|
||||||
case["target_id"],
|
target_type=case["target_type"],
|
||||||
case["role_id"],
|
target_id=case["target_id"],
|
||||||
duration,
|
role_id=case["role_id"],
|
||||||
case["reason"],
|
duration=duration,
|
||||||
|
reason=case["reason"],
|
||||||
timestamp=case["timestamp"],
|
timestamp=case["timestamp"],
|
||||||
resolved=case["resolved"],
|
resolved=case["resolved"],
|
||||||
resolved_by=case["resolved_by"],
|
resolved_by=case["resolved_by"],
|
||||||
resolved_reason=case["resolve_reason"],
|
resolved_reason=case["resolve_reason"],
|
||||||
expired=case["expired"],
|
expired=case["expired"],
|
||||||
changes=case["changes"],
|
changes=changes,
|
||||||
metadata=metadata,
|
metadata=metadata,
|
||||||
database=database,
|
database=database,
|
||||||
)
|
)
|
||||||
|
|
|
@ -1,12 +1,14 @@
|
||||||
# pylint: disable=duplicate-code
|
# pylint: disable=duplicate-code
|
||||||
import json
|
import json
|
||||||
from datetime import timedelta
|
from datetime import timedelta
|
||||||
|
from time import time
|
||||||
|
|
||||||
from discord import ButtonStyle, Interaction, Message, ui
|
from discord import ButtonStyle, Interaction, Message, ui
|
||||||
from redbot.core import commands
|
from redbot.core import commands
|
||||||
from redbot.core.utils.chat_formatting import box, warning
|
from redbot.core.utils.chat_formatting import box, warning
|
||||||
|
|
||||||
from ..utilities.database import connect, create_guild_table, mysql_log
|
from ..models.moderation import Change, Moderation
|
||||||
|
from ..utilities.database import connect, create_guild_table
|
||||||
|
|
||||||
|
|
||||||
class ImportGalacticBotView(ui.View):
|
class ImportGalacticBotView(ui.View):
|
||||||
|
@ -67,12 +69,12 @@ class ImportGalacticBotView(ui.View):
|
||||||
if case["duration"] is not None and float(case["duration"]) != 0:
|
if case["duration"] is not None and float(case["duration"]) != 0:
|
||||||
duration = timedelta(seconds=round(float(case["duration"]) / 1000))
|
duration = timedelta(seconds=round(float(case["duration"]) / 1000))
|
||||||
else:
|
else:
|
||||||
duration = "NULL"
|
duration = None
|
||||||
except OverflowError:
|
except OverflowError:
|
||||||
failed_cases.append(case["case"])
|
failed_cases.append(case["case"])
|
||||||
continue
|
continue
|
||||||
|
|
||||||
metadata = {"imported_from": "GalacticBot"}
|
metadata = {"imported_from": "GalacticBot", "imported_timestamp": int(time())}
|
||||||
|
|
||||||
if case["type"] == "SLOWMODE":
|
if case["type"] == "SLOWMODE":
|
||||||
metadata["seconds"] = case["data"]["seconds"]
|
metadata["seconds"] = case["data"]["seconds"]
|
||||||
|
@ -98,37 +100,37 @@ class ImportGalacticBotView(ui.View):
|
||||||
if resolved_timestamp is None:
|
if resolved_timestamp is None:
|
||||||
resolved_timestamp = timestamp
|
resolved_timestamp = timestamp
|
||||||
changes = [
|
changes = [
|
||||||
{
|
Change.from_dict(interaction.client, {
|
||||||
"type": "ORIGINAL",
|
"type": "ORIGINAL",
|
||||||
"reason": case["reason"],
|
"reason": case["reason"],
|
||||||
"user_id": case["executor"],
|
"user_id": case["executor"],
|
||||||
"timestamp": timestamp,
|
"timestamp": timestamp,
|
||||||
},
|
}),
|
||||||
{
|
Change.from_dict(interaction.client, {
|
||||||
"type": "RESOLVE",
|
"type": "RESOLVE",
|
||||||
"reason": resolved_reason,
|
"reason": resolved_reason,
|
||||||
"user_id": resolved_by,
|
"user_id": resolved_by,
|
||||||
"timestamp": resolved_timestamp,
|
"timestamp": resolved_timestamp,
|
||||||
},
|
}),
|
||||||
]
|
]
|
||||||
else:
|
else:
|
||||||
resolved = 0
|
resolved = None
|
||||||
resolved_by = "NULL"
|
resolved_by = None
|
||||||
resolved_reason = "NULL"
|
resolved_reason = None
|
||||||
changes = []
|
changes = None
|
||||||
|
|
||||||
if case["reason"] and case["reason"] != "N/A":
|
if case["reason"] and case["reason"] != "N/A":
|
||||||
reason = case["reason"]
|
reason = case["reason"]
|
||||||
else:
|
else:
|
||||||
reason = "NULL"
|
reason = None
|
||||||
|
|
||||||
await mysql_log(
|
Moderation.log(
|
||||||
self.ctx.guild.id,
|
self.ctx.guild.id,
|
||||||
case["executor"],
|
case["executor"],
|
||||||
case["type"],
|
case["type"],
|
||||||
case["targetType"],
|
case["targetType"],
|
||||||
case["target"],
|
case["target"],
|
||||||
0,
|
None,
|
||||||
duration,
|
duration,
|
||||||
reason,
|
reason,
|
||||||
timestamp=timestamp,
|
timestamp=timestamp,
|
||||||
|
|
|
@ -9,6 +9,7 @@
|
||||||
"disabled": false,
|
"disabled": false,
|
||||||
"min_bot_version": "3.5.0",
|
"min_bot_version": "3.5.0",
|
||||||
"min_python_version": [3, 10, 0],
|
"min_python_version": [3, 10, 0],
|
||||||
|
"requirements": ["pydantic"],
|
||||||
"tags": [
|
"tags": [
|
||||||
"mod",
|
"mod",
|
||||||
"moderate",
|
"moderate",
|
||||||
|
|
|
@ -2,12 +2,12 @@ from discord import ButtonStyle, Interaction, Message, ui
|
||||||
from redbot.core import commands
|
from redbot.core import commands
|
||||||
from redbot.core.utils.chat_formatting import error
|
from redbot.core.utils.chat_formatting import error
|
||||||
|
|
||||||
from aurora.utilities.config import config
|
from ..utilities.config import config
|
||||||
from aurora.utilities.factory import addrole_embed
|
from ..utilities.factory import addrole_embed
|
||||||
|
|
||||||
|
|
||||||
class Addrole(ui.View):
|
class Addrole(ui.View):
|
||||||
def __init__(self, ctx: commands.Context, message: Message, timeout: int = None):
|
def __init__(self, ctx: commands.Context, message: Message, timeout: int | None = None):
|
||||||
super().__init__()
|
super().__init__()
|
||||||
self.ctx = ctx
|
self.ctx = ctx
|
||||||
self.message = message
|
self.message = message
|
||||||
|
|
|
@ -1,13 +1,13 @@
|
||||||
from discord import ButtonStyle, Interaction, Message, ui
|
from discord import ButtonStyle, Interaction, Message, ui
|
||||||
from redbot.core import commands
|
from redbot.core import commands
|
||||||
|
|
||||||
from aurora.utilities.config import config
|
from ..utilities.config import config
|
||||||
from aurora.utilities.factory import guild_embed
|
from ..utilities.factory import guild_embed
|
||||||
from aurora.utilities.utils import create_pagesize_options
|
from ..utilities.utils import create_pagesize_options
|
||||||
|
|
||||||
|
|
||||||
class Guild(ui.View):
|
class Guild(ui.View):
|
||||||
def __init__(self, ctx: commands.Context, message: Message, timeout: int = None):
|
def __init__(self, ctx: commands.Context, message: Message, timeout: int | None = None):
|
||||||
super().__init__()
|
super().__init__()
|
||||||
self.ctx = ctx
|
self.ctx = ctx
|
||||||
self.message = message
|
self.message = message
|
||||||
|
|
|
@ -2,12 +2,12 @@ from discord import ButtonStyle, Interaction, Message, ui
|
||||||
from redbot.core import commands
|
from redbot.core import commands
|
||||||
from redbot.core.utils.chat_formatting import error
|
from redbot.core.utils.chat_formatting import error
|
||||||
|
|
||||||
from aurora.utilities.config import config
|
from ..utilities.config import config
|
||||||
from aurora.utilities.factory import immune_embed
|
from ..utilities.factory import immune_embed
|
||||||
|
|
||||||
|
|
||||||
class Immune(ui.View):
|
class Immune(ui.View):
|
||||||
def __init__(self, ctx: commands.Context, message: Message, timeout: int = None):
|
def __init__(self, ctx: commands.Context, message: Message, timeout: int | None = None):
|
||||||
super().__init__()
|
super().__init__()
|
||||||
self.ctx = ctx
|
self.ctx = ctx
|
||||||
self.message = message
|
self.message = message
|
||||||
|
|
|
@ -1,13 +1,13 @@
|
||||||
from discord import ButtonStyle, Interaction, Message, ui
|
from discord import ButtonStyle, Interaction, Message, ui
|
||||||
from redbot.core import commands
|
from redbot.core import commands
|
||||||
|
|
||||||
from aurora.utilities.config import config
|
from ..utilities.config import config
|
||||||
from aurora.utilities.factory import overrides_embed
|
from ..utilities.factory import overrides_embed
|
||||||
from aurora.utilities.utils import create_pagesize_options
|
from ..utilities.utils import create_pagesize_options
|
||||||
|
|
||||||
|
|
||||||
class Overrides(ui.View):
|
class Overrides(ui.View):
|
||||||
def __init__(self, ctx: commands.Context, message: Message, timeout: int = None):
|
def __init__(self, ctx: commands.Context, message: Message, timeout: int | None = None):
|
||||||
super().__init__()
|
super().__init__()
|
||||||
self.ctx = ctx
|
self.ctx = ctx
|
||||||
self.message = message
|
self.message = message
|
||||||
|
|
0
aurora/models/__init__.py
Normal file
0
aurora/models/__init__.py
Normal file
28
aurora/models/base.py
Normal file
28
aurora/models/base.py
Normal file
|
@ -0,0 +1,28 @@
|
||||||
|
from typing import Any
|
||||||
|
|
||||||
|
from pydantic import BaseModel, ConfigDict
|
||||||
|
from redbot.core.bot import Red
|
||||||
|
|
||||||
|
|
||||||
|
class AuroraBaseModel(BaseModel):
|
||||||
|
"""Base class for all models in Aurora."""
|
||||||
|
model_config = ConfigDict(ignored_types=(Red,), arbitrary_types_allowed=True)
|
||||||
|
bot: Red
|
||||||
|
|
||||||
|
def dump(self) -> dict:
|
||||||
|
return self.model_dump(exclude={"bot"})
|
||||||
|
|
||||||
|
def to_json(self, indent: int | None = None, file: Any | None = None, **kwargs):
|
||||||
|
from ..utilities.json import dump, dumps # pylint: disable=cyclic-import
|
||||||
|
return dump(self.dump(), file, indent=indent, **kwargs) if file else dumps(self.model_dump(exclude={"bot"}), indent=indent, **kwargs)
|
||||||
|
|
||||||
|
class AuroraGuildModel(AuroraBaseModel):
|
||||||
|
"""Subclass of AuroraBaseModel that includes a guild_id attribute, and a modified to_json() method to match."""
|
||||||
|
guild_id: int
|
||||||
|
|
||||||
|
def dump(self) -> dict:
|
||||||
|
return self.model_dump(exclude={"bot", "guild_id"})
|
||||||
|
|
||||||
|
def to_json(self, indent: int | None = None, file: Any | None = None, **kwargs):
|
||||||
|
from ..utilities.json import dump, dumps # pylint: disable=cyclic-import
|
||||||
|
return dump(self.dump(), file, indent=indent, **kwargs) if file else dumps(self.model_dump(exclude={"bot", "guild_id"}), indent=indent, **kwargs)
|
62
aurora/models/change.py
Normal file
62
aurora/models/change.py
Normal file
|
@ -0,0 +1,62 @@
|
||||||
|
import json
|
||||||
|
from datetime import datetime, timedelta
|
||||||
|
from typing import Literal, Optional
|
||||||
|
|
||||||
|
from redbot.core.bot import Red
|
||||||
|
|
||||||
|
from ..utilities.logger import logger
|
||||||
|
from .base import AuroraBaseModel
|
||||||
|
from .partials import PartialUser
|
||||||
|
|
||||||
|
|
||||||
|
class Change(AuroraBaseModel):
|
||||||
|
type: Literal["ORIGINAL", "RESOLVE", "EDIT"]
|
||||||
|
timestamp: datetime
|
||||||
|
reason: str
|
||||||
|
user_id: int
|
||||||
|
duration: Optional[timedelta] = None
|
||||||
|
end_timestamp: Optional[datetime] = None
|
||||||
|
|
||||||
|
@property
|
||||||
|
def unix_timestamp(self) -> int:
|
||||||
|
return int(self.timestamp.timestamp())
|
||||||
|
|
||||||
|
def __str__(self):
|
||||||
|
return f"{self.type} {self.user_id} {self.reason}"
|
||||||
|
|
||||||
|
async def get_user(self) -> "PartialUser":
|
||||||
|
return await PartialUser.from_id(self.bot, self.user_id)
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def from_dict(cls, bot: Red, data: dict) -> "Change":
|
||||||
|
logger.trace("Creating Change from dict (%s): %s", type(data), data)
|
||||||
|
if isinstance(data, str):
|
||||||
|
data = json.loads(data)
|
||||||
|
logger.trace("Change data was a string, converted to dict: %s", data)
|
||||||
|
if "duration" in data and data["duration"] and not isinstance(data["duration"], timedelta):
|
||||||
|
hours, minutes, seconds = map(int, data["duration"].split(':'))
|
||||||
|
duration = timedelta(hours=hours, minutes=minutes, seconds=seconds)
|
||||||
|
elif "duration" in data and isinstance(data["duration"], timedelta):
|
||||||
|
duration = data["duration"]
|
||||||
|
else:
|
||||||
|
duration = None
|
||||||
|
|
||||||
|
if "end_timestamp" in data and data["end_timestamp"] and not isinstance(data["end_timestamp"], datetime):
|
||||||
|
end_timestamp = datetime.fromtimestamp(data["end_timestamp"])
|
||||||
|
elif "end_timestamp" in data and isinstance(data["end_timestamp"], datetime):
|
||||||
|
end_timestamp = data["end_timestamp"]
|
||||||
|
else:
|
||||||
|
end_timestamp = None
|
||||||
|
|
||||||
|
if not isinstance(data["timestamp"], datetime):
|
||||||
|
timestamp = datetime.fromtimestamp(data["timestamp"])
|
||||||
|
else:
|
||||||
|
timestamp = data["timestamp"]
|
||||||
|
|
||||||
|
data.update({
|
||||||
|
"timestamp": timestamp,
|
||||||
|
"end_timestamp": end_timestamp,
|
||||||
|
"duration": duration,
|
||||||
|
"user_id": int(data["user_id"])
|
||||||
|
})
|
||||||
|
return cls(bot=bot, **data)
|
387
aurora/models/moderation.py
Normal file
387
aurora/models/moderation.py
Normal file
|
@ -0,0 +1,387 @@
|
||||||
|
import json
|
||||||
|
import sqlite3
|
||||||
|
from datetime import datetime, timedelta
|
||||||
|
from sqlite3 import Cursor
|
||||||
|
from time import time
|
||||||
|
from typing import Dict, Iterable, List, Optional, Tuple, Union
|
||||||
|
|
||||||
|
import discord
|
||||||
|
from discord import NotFound
|
||||||
|
from redbot.core.bot import Red
|
||||||
|
|
||||||
|
from ..utilities.logger import logger
|
||||||
|
from .base import AuroraGuildModel
|
||||||
|
from .change import Change
|
||||||
|
from .partials import PartialChannel, PartialRole, PartialUser
|
||||||
|
|
||||||
|
|
||||||
|
class Moderation(AuroraGuildModel):
|
||||||
|
moderation_id: int
|
||||||
|
timestamp: datetime
|
||||||
|
moderation_type: str
|
||||||
|
target_type: str
|
||||||
|
target_id: int
|
||||||
|
moderator_id: int
|
||||||
|
role_id: Optional[int] = None
|
||||||
|
duration: Optional[timedelta] = None
|
||||||
|
end_timestamp: Optional[datetime] = None
|
||||||
|
reason: Optional[str] = None
|
||||||
|
resolved: bool
|
||||||
|
resolved_by: Optional[int] = None
|
||||||
|
resolve_reason: Optional[str] = None
|
||||||
|
expired: bool
|
||||||
|
changes: List["Change"]
|
||||||
|
metadata: Dict
|
||||||
|
|
||||||
|
@property
|
||||||
|
def id(self) -> int:
|
||||||
|
return self.moderation_id
|
||||||
|
|
||||||
|
@property
|
||||||
|
def type(self) -> str:
|
||||||
|
return self.moderation_type
|
||||||
|
|
||||||
|
@property
|
||||||
|
def unix_timestamp(self) -> int:
|
||||||
|
return int(self.timestamp.timestamp())
|
||||||
|
|
||||||
|
async def get_moderator(self) -> "PartialUser":
|
||||||
|
return await PartialUser.from_id(self.bot, self.moderator_id)
|
||||||
|
|
||||||
|
async def get_target(self) -> Union["PartialUser", "PartialChannel"]:
|
||||||
|
if self.target_type == "USER":
|
||||||
|
return await PartialUser.from_id(self.bot, self.target_id)
|
||||||
|
return await PartialChannel.from_id(self.bot, self.target_id)
|
||||||
|
|
||||||
|
async def get_resolved_by(self) -> Optional["PartialUser"]:
|
||||||
|
if self.resolved_by:
|
||||||
|
return await PartialUser.from_id(self.bot, self.resolved_by)
|
||||||
|
return None
|
||||||
|
|
||||||
|
async def get_role(self) -> Optional["PartialRole"]:
|
||||||
|
if self.role_id:
|
||||||
|
return await PartialRole.from_id(self.bot, self.guild_id, self.role_id)
|
||||||
|
return None
|
||||||
|
|
||||||
|
def __str__(self) -> str:
|
||||||
|
return f"{self.moderation_type} {self.target_type} {self.target_id} {self.reason}"
|
||||||
|
|
||||||
|
async def resolve(self, resolved_by: int, reason: str) -> None:
|
||||||
|
if self.resolved:
|
||||||
|
raise ValueError("Case is already resolved!")
|
||||||
|
|
||||||
|
self.resolved = True
|
||||||
|
self.resolved_by = resolved_by
|
||||||
|
self.resolve_reason = reason
|
||||||
|
|
||||||
|
if self.type in ["UNMUTE", "UNBAN"]:
|
||||||
|
raise TypeError("Cannot resolve an unmute or unban case!")
|
||||||
|
|
||||||
|
if self.type == "MUTE":
|
||||||
|
try:
|
||||||
|
guild: discord.Guild = await self.bot.fetch_guild(self.guild_id)
|
||||||
|
member = await guild.fetch_member(self.target_id)
|
||||||
|
|
||||||
|
await member.timeout(
|
||||||
|
None, reason=f"Case {self.moderation_id} resolved by {resolved_by}{' for '+ reason if reason else ''}"
|
||||||
|
)
|
||||||
|
except NotFound:
|
||||||
|
pass
|
||||||
|
|
||||||
|
if self.type in ["BAN", "TEMPBAN"]:
|
||||||
|
try:
|
||||||
|
guild: discord.Guild = await self.bot.fetch_guild(self.guild_id)
|
||||||
|
await guild.unban(await self.get_target(), reason=f"Case {self.moderation_id} resolved by {resolved_by}{' for '+ reason if reason else ''}")
|
||||||
|
except NotFound:
|
||||||
|
pass
|
||||||
|
|
||||||
|
if not self.changes:
|
||||||
|
self.changes.append(Change.from_dict(self.bot, {
|
||||||
|
"type": "ORIGINAL",
|
||||||
|
"timestamp": self.timestamp,
|
||||||
|
"reason": self.reason,
|
||||||
|
"user_id": self.moderator_id,
|
||||||
|
"duration": self.duration,
|
||||||
|
"end_timestamp": self.end_timestamp,
|
||||||
|
}))
|
||||||
|
self.changes.append(Change.from_dict(self.bot, {
|
||||||
|
"type": "RESOLVE",
|
||||||
|
"timestamp": datetime.now(),
|
||||||
|
"reason": reason,
|
||||||
|
"user_id": resolved_by,
|
||||||
|
}))
|
||||||
|
|
||||||
|
self.update()
|
||||||
|
|
||||||
|
def update(self) -> None:
|
||||||
|
from ..utilities.database import connect
|
||||||
|
from ..utilities.json import dumps
|
||||||
|
query = f"UPDATE moderation_{self.guild_id} SET timestamp = ?, moderation_type = ?, target_type = ?, moderator_id = ?, role_id = ?, duration = ?, end_timestamp = ?, reason = ?, resolved = ?, resolved_by = ?, resolve_reason = ?, expired = ?, changes = ?, metadata = ? WHERE moderation_id = ?;"
|
||||||
|
|
||||||
|
with connect() as database:
|
||||||
|
database.execute(query, (
|
||||||
|
self.timestamp.timestamp(),
|
||||||
|
self.moderation_type,
|
||||||
|
self.target_type,
|
||||||
|
self.moderator_id,
|
||||||
|
self.role_id,
|
||||||
|
str(self.duration) if self.duration else None,
|
||||||
|
self.end_timestamp.timestamp() if self.end_timestamp else None,
|
||||||
|
self.reason,
|
||||||
|
self.resolved,
|
||||||
|
self.resolved_by,
|
||||||
|
self.resolve_reason,
|
||||||
|
self.expired,
|
||||||
|
dumps(self.changes),
|
||||||
|
dumps(self.metadata),
|
||||||
|
self.moderation_id,
|
||||||
|
))
|
||||||
|
|
||||||
|
logger.debug("Row updated in moderation_%s!\n%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s",
|
||||||
|
self.moderation_id,
|
||||||
|
self.guild_id,
|
||||||
|
self.timestamp.timestamp(),
|
||||||
|
self.moderation_type,
|
||||||
|
self.target_type,
|
||||||
|
self.moderator_id,
|
||||||
|
self.role_id,
|
||||||
|
str(self.duration) if self.duration else None,
|
||||||
|
self.end_timestamp.timestamp() if self.end_timestamp else None,
|
||||||
|
self.reason,
|
||||||
|
self.resolved,
|
||||||
|
self.resolved_by,
|
||||||
|
self.resolve_reason,
|
||||||
|
self.expired,
|
||||||
|
dumps(self.changes),
|
||||||
|
dumps(self.metadata),
|
||||||
|
)
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def from_dict(cls, bot: Red, data: dict) -> "Moderation":
|
||||||
|
return cls(bot=bot, **data)
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def from_result(cls, bot: Red, result: Iterable, guild_id: int) -> "Moderation":
|
||||||
|
if result[7] is not None:
|
||||||
|
hours, minutes, seconds = map(int, result[7].split(':'))
|
||||||
|
duration = timedelta(hours=hours, minutes=minutes, seconds=seconds)
|
||||||
|
else:
|
||||||
|
duration = None
|
||||||
|
|
||||||
|
if result[14] is not None:
|
||||||
|
changes = json.loads(result[14])
|
||||||
|
change_obj_list = []
|
||||||
|
if changes:
|
||||||
|
for change in changes:
|
||||||
|
change_obj_list.append(Change.from_dict(bot=bot, data=change))
|
||||||
|
|
||||||
|
if result[15] is not None:
|
||||||
|
metadata = json.loads(result[15])
|
||||||
|
else:
|
||||||
|
metadata = {}
|
||||||
|
|
||||||
|
case = {
|
||||||
|
"moderation_id": int(result[0]),
|
||||||
|
"guild_id": int(guild_id),
|
||||||
|
"timestamp": datetime.fromtimestamp(result[1]),
|
||||||
|
"moderation_type": str(result[2]),
|
||||||
|
"target_type": str(result[3]),
|
||||||
|
"target_id": int(result[4]),
|
||||||
|
"moderator_id": int(result[5]),
|
||||||
|
"role_id": int(result[6]) if result[6] is not None else None,
|
||||||
|
"duration": duration,
|
||||||
|
"end_timestamp": datetime.fromtimestamp(result[8]) if result[8] is not None else None,
|
||||||
|
"reason": result[9],
|
||||||
|
"resolved": bool(result[10]),
|
||||||
|
"resolved_by": result[11],
|
||||||
|
"resolve_reason": result[12],
|
||||||
|
"expired": bool(result[13]),
|
||||||
|
"changes": change_obj_list,
|
||||||
|
"metadata": metadata if metadata else {},
|
||||||
|
}
|
||||||
|
return cls.from_dict(bot=bot, data=case)
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def execute(cls, bot: Red, guild_id: int, query: str, parameters: tuple | None = None, cursor: Cursor | None = None) -> Tuple["Moderation"]:
|
||||||
|
from ..utilities.database import connect
|
||||||
|
if not parameters:
|
||||||
|
parameters = ()
|
||||||
|
if not cursor:
|
||||||
|
no_cursor = True
|
||||||
|
database = connect()
|
||||||
|
cursor = database.cursor()
|
||||||
|
else:
|
||||||
|
no_cursor = False
|
||||||
|
|
||||||
|
cursor.execute(query, parameters)
|
||||||
|
results = cursor.fetchall()
|
||||||
|
if no_cursor:
|
||||||
|
cursor.close()
|
||||||
|
database.close()
|
||||||
|
|
||||||
|
if results:
|
||||||
|
cases = []
|
||||||
|
for result in results:
|
||||||
|
case = cls.from_result(bot=bot, result=result, guild_id=guild_id)
|
||||||
|
if case.moderation_id != 0:
|
||||||
|
cases.append(case)
|
||||||
|
return tuple(cases)
|
||||||
|
return ()
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def get_latest(cls, bot: Red, guild_id: int, limit: int | None = None, types: Iterable | None = None, cursor: Cursor | None = None) -> Tuple["Moderation"]:
|
||||||
|
params = []
|
||||||
|
query = f"SELECT * FROM moderation_{guild_id} ORDER BY moderation_id DESC"
|
||||||
|
if limit:
|
||||||
|
query += " LIMIT ?"
|
||||||
|
params.append(limit)
|
||||||
|
if types:
|
||||||
|
query += f" WHERE moderation_type IN ({', '.join(['?' for _ in types])})"
|
||||||
|
params.extend(types)
|
||||||
|
query += ";"
|
||||||
|
return cls.execute(bot=bot, guild_id=guild_id, query=query, parameters=tuple(params) if limit else (), cursor=cursor)
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def get_next_case_number(cls, bot: Red, guild_id: int, cursor: Cursor | None = None) -> int:
|
||||||
|
result = cls.get_latest(bot=bot, guild_id=guild_id, cursor=cursor)
|
||||||
|
return (result[0].moderation_id + 1) if result else 1
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def find_by_id(cls, bot: Red, moderation_id: int, guild_id: int, cursor: Cursor | None = None) -> "Moderation":
|
||||||
|
query = f"SELECT * FROM moderation_{guild_id} WHERE moderation_id = ?;"
|
||||||
|
case = cls.execute(bot=bot, guild_id=guild_id, query=query, parameters=(moderation_id,), cursor=cursor)
|
||||||
|
if case:
|
||||||
|
return case[0]
|
||||||
|
raise ValueError(f"Case {moderation_id} not found in moderation_{guild_id}!")
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def find_by_target(cls, bot: Red, guild_id: int, target: int, types: Iterable | None = None, cursor: Cursor | None = None) -> Tuple["Moderation"]:
|
||||||
|
query = f"SELECT * FROM moderation_{guild_id} WHERE target_id = ?"
|
||||||
|
if types:
|
||||||
|
query += f" AND moderation_type IN ({', '.join(['?' for _ in types])})"
|
||||||
|
query += " ORDER BY moderation_id DESC;"
|
||||||
|
|
||||||
|
return cls.execute(bot=bot, guild_id=guild_id, query=query, parameters=(target, *types) if types else (target,), cursor=cursor)
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def find_by_moderator(cls, bot: Red, guild_id: int, moderator: int, types: Iterable | None = None, cursor: Cursor | None = None) -> Tuple["Moderation"]:
|
||||||
|
query = f"SELECT * FROM moderation_{guild_id} WHERE moderator_id = ?"
|
||||||
|
if types:
|
||||||
|
query += f" AND moderation_type IN ({', '.join(['?' for _ in types])})"
|
||||||
|
query += " ORDER BY moderation_id DESC;"
|
||||||
|
|
||||||
|
return cls.execute(bot=bot, guild_id=guild_id, query=query, parameters=(moderator, *types) if types else (moderator,), cursor=cursor)
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def log(
|
||||||
|
cls,
|
||||||
|
bot: Red,
|
||||||
|
guild_id: int,
|
||||||
|
moderator_id: int,
|
||||||
|
moderation_type: str,
|
||||||
|
target_type: str,
|
||||||
|
target_id: int,
|
||||||
|
role_id: int | None = None,
|
||||||
|
duration: timedelta | None = None,
|
||||||
|
reason: str | None = None,
|
||||||
|
database: sqlite3.Connection | None = None,
|
||||||
|
timestamp: datetime | None = None,
|
||||||
|
resolved: bool = False,
|
||||||
|
resolved_by: int | None = None,
|
||||||
|
resolved_reason: str | None = None,
|
||||||
|
expired: bool | None = None,
|
||||||
|
changes: list | None = None,
|
||||||
|
metadata: dict | None = None,
|
||||||
|
) -> "Moderation":
|
||||||
|
from ..utilities.database import connect
|
||||||
|
from ..utilities.json import dumps
|
||||||
|
if not timestamp:
|
||||||
|
timestamp = datetime.fromtimestamp(time())
|
||||||
|
elif not isinstance(timestamp, datetime):
|
||||||
|
timestamp = datetime.fromtimestamp(timestamp)
|
||||||
|
|
||||||
|
if duration == "NULL":
|
||||||
|
duration = None
|
||||||
|
|
||||||
|
if duration is not None:
|
||||||
|
end_timestamp = timestamp + duration
|
||||||
|
else:
|
||||||
|
duration = None
|
||||||
|
end_timestamp = None
|
||||||
|
|
||||||
|
if not expired:
|
||||||
|
if end_timestamp:
|
||||||
|
expired = bool(timestamp > end_timestamp)
|
||||||
|
else:
|
||||||
|
expired = False
|
||||||
|
|
||||||
|
if reason == "NULL":
|
||||||
|
reason = None
|
||||||
|
|
||||||
|
if resolved_by == "NULL":
|
||||||
|
resolved_by = None
|
||||||
|
|
||||||
|
if resolved_reason == "NULL":
|
||||||
|
resolved_reason = None
|
||||||
|
|
||||||
|
if role_id == 0:
|
||||||
|
role_id = None
|
||||||
|
|
||||||
|
if not database:
|
||||||
|
database = connect()
|
||||||
|
close_db = True
|
||||||
|
else:
|
||||||
|
close_db = False
|
||||||
|
cursor = database.cursor()
|
||||||
|
|
||||||
|
moderation_id = cls.get_next_case_number(bot=bot, guild_id=guild_id, cursor=cursor)
|
||||||
|
|
||||||
|
case = {
|
||||||
|
"moderation_id": moderation_id,
|
||||||
|
"timestamp": timestamp.timestamp(),
|
||||||
|
"moderation_type": moderation_type,
|
||||||
|
"target_type": target_type,
|
||||||
|
"target_id": target_id,
|
||||||
|
"moderator_id": moderator_id,
|
||||||
|
"role_id": role_id,
|
||||||
|
"duration": str(duration) if duration else None,
|
||||||
|
"end_timestamp": end_timestamp.timestamp() if end_timestamp else None,
|
||||||
|
"reason": reason,
|
||||||
|
"resolved": resolved,
|
||||||
|
"resolved_by": resolved_by,
|
||||||
|
"resolve_reason": resolved_reason,
|
||||||
|
"expired": expired,
|
||||||
|
"changes": dumps(changes),
|
||||||
|
"metadata": dumps(metadata)
|
||||||
|
}
|
||||||
|
|
||||||
|
sql = f"INSERT INTO `moderation_{guild_id}` (moderation_id, timestamp, moderation_type, target_type, target_id, moderator_id, role_id, duration, end_timestamp, reason, resolved, resolved_by, resolve_reason, expired, changes, metadata) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)"
|
||||||
|
cursor.execute(sql, tuple(case.values()))
|
||||||
|
|
||||||
|
cursor.close()
|
||||||
|
database.commit()
|
||||||
|
if close_db:
|
||||||
|
database.close()
|
||||||
|
|
||||||
|
logger.debug(
|
||||||
|
"Row inserted into moderation_%s!\n%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s",
|
||||||
|
guild_id,
|
||||||
|
case["moderation_id"],
|
||||||
|
case["timestamp"],
|
||||||
|
case["moderation_type"],
|
||||||
|
case["target_type"],
|
||||||
|
case["target_id"],
|
||||||
|
case["moderator_id"],
|
||||||
|
case["role_id"],
|
||||||
|
case["duration"],
|
||||||
|
case["end_timestamp"],
|
||||||
|
case["reason"],
|
||||||
|
case["resolved"],
|
||||||
|
case["resolved_by"],
|
||||||
|
case["resolve_reason"],
|
||||||
|
case["expired"],
|
||||||
|
case["changes"],
|
||||||
|
case["metadata"],
|
||||||
|
)
|
||||||
|
|
||||||
|
return cls.find_by_id(bot=bot, moderation_id=moderation_id, guild_id=guild_id)
|
79
aurora/models/partials.py
Normal file
79
aurora/models/partials.py
Normal file
|
@ -0,0 +1,79 @@
|
||||||
|
from discord import Forbidden, HTTPException, InvalidData, NotFound
|
||||||
|
from redbot.core.bot import Red
|
||||||
|
|
||||||
|
from .base import AuroraBaseModel, AuroraGuildModel
|
||||||
|
|
||||||
|
|
||||||
|
class PartialUser(AuroraBaseModel):
|
||||||
|
id: int
|
||||||
|
username: str
|
||||||
|
discriminator: int
|
||||||
|
|
||||||
|
@property
|
||||||
|
def name(self):
|
||||||
|
return f"{self.username}#{self.discriminator}" if self.discriminator != 0 else self.username
|
||||||
|
|
||||||
|
def __str__(self):
|
||||||
|
return self.name
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
async def from_id(cls, bot: Red, user_id: int) -> "PartialUser":
|
||||||
|
user = bot.get_user(user_id)
|
||||||
|
if not user:
|
||||||
|
try:
|
||||||
|
user = await bot.fetch_user(user_id)
|
||||||
|
return cls(bot=bot, id=user.id, username=user.name, discriminator=user.discriminator)
|
||||||
|
except NotFound:
|
||||||
|
return cls(bot=bot, id=user_id, username="Deleted User", discriminator=0)
|
||||||
|
return cls(bot=bot, id=user.id, username=user.name, discriminator=user.discriminator)
|
||||||
|
|
||||||
|
|
||||||
|
class PartialChannel(AuroraGuildModel):
|
||||||
|
id: int
|
||||||
|
name: str
|
||||||
|
|
||||||
|
@property
|
||||||
|
def mention(self):
|
||||||
|
if self.name in ["Deleted Channel", "Forbidden Channel"]:
|
||||||
|
return self.name
|
||||||
|
return f"<#{self.id}>"
|
||||||
|
|
||||||
|
def __str__(self):
|
||||||
|
return self.mention
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
async def from_id(cls, bot: Red, channel_id: int) -> "PartialChannel":
|
||||||
|
channel = bot.get_channel(channel_id)
|
||||||
|
if not channel:
|
||||||
|
try:
|
||||||
|
channel = await bot.fetch_channel(channel_id)
|
||||||
|
return cls(bot=bot, guild_id=channel.guild.id, id=channel.id, name=channel.name)
|
||||||
|
except (NotFound, InvalidData, HTTPException, Forbidden) as e:
|
||||||
|
if e == Forbidden:
|
||||||
|
return cls(bot=bot, guild_id=0, id=channel_id, name="Forbidden Channel")
|
||||||
|
return cls(bot=bot, guild_id=0, id=channel_id, name="Deleted Channel")
|
||||||
|
return cls(bot=bot, guild_id=channel.guild.id, id=channel.id, name=channel.name)
|
||||||
|
|
||||||
|
class PartialRole(AuroraGuildModel):
|
||||||
|
id: int
|
||||||
|
name: str
|
||||||
|
|
||||||
|
@property
|
||||||
|
def mention(self):
|
||||||
|
if self.name in ["Deleted Role", "Forbidden Role"]:
|
||||||
|
return self.name
|
||||||
|
return f"<@&{self.id}>"
|
||||||
|
|
||||||
|
def __str__(self):
|
||||||
|
return self.mention
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
async def from_id(cls, bot: Red, guild_id: int, role_id: int) -> "PartialRole":
|
||||||
|
try:
|
||||||
|
guild = await bot.fetch_guild(guild_id, with_counts=False)
|
||||||
|
except (Forbidden, HTTPException):
|
||||||
|
return cls(bot=bot, guild_id=guild_id, id=role_id, name="Forbidden Role")
|
||||||
|
role = guild.get_role(role_id)
|
||||||
|
if not role:
|
||||||
|
return cls(bot=bot, guild_id=guild_id, id=role_id, name="Deleted Role")
|
||||||
|
return cls(bot=bot, guild_id=guild_id, id=role.id, name=role.name)
|
|
@ -1,15 +1,11 @@
|
||||||
# pylint: disable=cyclic-import
|
# pylint: disable=cyclic-import
|
||||||
import json
|
import json
|
||||||
import sqlite3
|
import sqlite3
|
||||||
import time
|
|
||||||
from datetime import datetime, timedelta
|
|
||||||
|
|
||||||
from discord import Guild
|
from discord import Guild
|
||||||
from redbot.core import data_manager
|
from redbot.core import data_manager
|
||||||
|
|
||||||
from .logger import logger
|
from .logger import logger
|
||||||
from .utils import (convert_timedelta_to_str, generate_dict,
|
|
||||||
get_next_case_number)
|
|
||||||
|
|
||||||
|
|
||||||
def connect() -> sqlite3.Connection:
|
def connect() -> sqlite3.Connection:
|
||||||
|
@ -42,9 +38,9 @@ async def create_guild_table(guild: Guild):
|
||||||
timestamp INTEGER NOT NULL,
|
timestamp INTEGER NOT NULL,
|
||||||
moderation_type TEXT NOT NULL,
|
moderation_type TEXT NOT NULL,
|
||||||
target_type TEXT NOT NULL,
|
target_type TEXT NOT NULL,
|
||||||
target_id TEXT NOT NULL,
|
target_id INTEGER NOT NULL,
|
||||||
moderator_id TEXT NOT NULL,
|
moderator_id INTEGER NOT NULL,
|
||||||
role_id TEXT,
|
role_id INTEGER,
|
||||||
duration TEXT,
|
duration TEXT,
|
||||||
end_timestamp INTEGER,
|
end_timestamp INTEGER,
|
||||||
reason TEXT,
|
reason TEXT,
|
||||||
|
@ -52,8 +48,8 @@ async def create_guild_table(guild: Guild):
|
||||||
resolved_by TEXT,
|
resolved_by TEXT,
|
||||||
resolve_reason TEXT,
|
resolve_reason TEXT,
|
||||||
expired INTEGER NOT NULL,
|
expired INTEGER NOT NULL,
|
||||||
changes TEXT NOT NULL,
|
changes JSON NOT NULL,
|
||||||
metadata TEXT NOT NULL
|
metadata JSON NOT NULL
|
||||||
)
|
)
|
||||||
"""
|
"""
|
||||||
cursor.execute(query)
|
cursor.execute(query)
|
||||||
|
@ -79,13 +75,13 @@ async def create_guild_table(guild: Guild):
|
||||||
"NULL",
|
"NULL",
|
||||||
0,
|
0,
|
||||||
0,
|
0,
|
||||||
|
None,
|
||||||
|
None,
|
||||||
|
None,
|
||||||
|
None,
|
||||||
0,
|
0,
|
||||||
"NULL",
|
None,
|
||||||
0,
|
None,
|
||||||
"NULL",
|
|
||||||
0,
|
|
||||||
"NULL",
|
|
||||||
"NULL",
|
|
||||||
0,
|
0,
|
||||||
json.dumps([]),
|
json.dumps([]),
|
||||||
json.dumps({}),
|
json.dumps({}),
|
||||||
|
@ -102,118 +98,3 @@ async def create_guild_table(guild: Guild):
|
||||||
)
|
)
|
||||||
|
|
||||||
database.close()
|
database.close()
|
||||||
|
|
||||||
|
|
||||||
async def mysql_log(
|
|
||||||
guild_id: str,
|
|
||||||
author_id: str,
|
|
||||||
moderation_type: str,
|
|
||||||
target_type: str,
|
|
||||||
target_id: int,
|
|
||||||
role_id: int,
|
|
||||||
duration: timedelta,
|
|
||||||
reason: str,
|
|
||||||
database: sqlite3.Connection = None,
|
|
||||||
timestamp: int = None,
|
|
||||||
resolved: bool = False,
|
|
||||||
resolved_by: str = None,
|
|
||||||
resolved_reason: str = None,
|
|
||||||
expired: bool = None,
|
|
||||||
changes: list = None,
|
|
||||||
metadata: dict = None,
|
|
||||||
) -> int:
|
|
||||||
if not timestamp:
|
|
||||||
timestamp = int(time.time())
|
|
||||||
|
|
||||||
if duration != "NULL":
|
|
||||||
end_timedelta = datetime.fromtimestamp(timestamp) + duration
|
|
||||||
end_timestamp = int(end_timedelta.timestamp())
|
|
||||||
|
|
||||||
duration = convert_timedelta_to_str(duration)
|
|
||||||
else:
|
|
||||||
end_timestamp = 0
|
|
||||||
|
|
||||||
if not expired:
|
|
||||||
if int(time.time()) > end_timestamp:
|
|
||||||
expired = 1
|
|
||||||
else:
|
|
||||||
expired = 0
|
|
||||||
|
|
||||||
if resolved_by is None:
|
|
||||||
resolved_by = "NULL"
|
|
||||||
|
|
||||||
if resolved_reason is None:
|
|
||||||
resolved_reason = "NULL"
|
|
||||||
|
|
||||||
if not database:
|
|
||||||
database = connect()
|
|
||||||
close_db = True
|
|
||||||
else:
|
|
||||||
close_db = False
|
|
||||||
cursor = database.cursor()
|
|
||||||
|
|
||||||
moderation_id = await get_next_case_number(guild_id=guild_id, cursor=cursor)
|
|
||||||
|
|
||||||
sql = f"INSERT INTO `moderation_{guild_id}` (moderation_id, timestamp, moderation_type, target_type, target_id, moderator_id, role_id, duration, end_timestamp, reason, resolved, resolved_by, resolve_reason, expired, changes, metadata) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)"
|
|
||||||
val = (
|
|
||||||
moderation_id,
|
|
||||||
timestamp,
|
|
||||||
moderation_type,
|
|
||||||
target_type,
|
|
||||||
target_id,
|
|
||||||
author_id,
|
|
||||||
role_id,
|
|
||||||
duration,
|
|
||||||
end_timestamp,
|
|
||||||
reason,
|
|
||||||
int(resolved),
|
|
||||||
resolved_by,
|
|
||||||
resolved_reason,
|
|
||||||
expired,
|
|
||||||
json.dumps(changes if changes else []),
|
|
||||||
json.dumps(metadata if metadata else {}),
|
|
||||||
)
|
|
||||||
cursor.execute(sql, val)
|
|
||||||
|
|
||||||
cursor.close()
|
|
||||||
database.commit()
|
|
||||||
if close_db:
|
|
||||||
database.close()
|
|
||||||
|
|
||||||
logger.debug(
|
|
||||||
"Row inserted into moderation_%s!\n%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s",
|
|
||||||
guild_id,
|
|
||||||
moderation_id,
|
|
||||||
timestamp,
|
|
||||||
moderation_type,
|
|
||||||
target_type,
|
|
||||||
target_id,
|
|
||||||
author_id,
|
|
||||||
role_id,
|
|
||||||
duration,
|
|
||||||
end_timestamp,
|
|
||||||
reason,
|
|
||||||
int(resolved),
|
|
||||||
resolved_by,
|
|
||||||
resolved_reason,
|
|
||||||
expired,
|
|
||||||
changes,
|
|
||||||
metadata,
|
|
||||||
)
|
|
||||||
|
|
||||||
return moderation_id
|
|
||||||
|
|
||||||
|
|
||||||
async def fetch_case(moderation_id: int, guild_id: str) -> dict:
|
|
||||||
"""This method fetches a case from the database and returns the case's dictionary."""
|
|
||||||
database = connect()
|
|
||||||
cursor = database.cursor()
|
|
||||||
|
|
||||||
query = f"SELECT * FROM moderation_{guild_id} WHERE moderation_id = ?;"
|
|
||||||
cursor.execute(query, (moderation_id,))
|
|
||||||
result = cursor.fetchone()
|
|
||||||
|
|
||||||
cursor.close()
|
|
||||||
database.close()
|
|
||||||
|
|
||||||
return generate_dict(result)
|
|
||||||
|
|
|
@ -4,25 +4,30 @@ from typing import Union
|
||||||
|
|
||||||
from discord import Color, Embed, Guild, Interaction, InteractionMessage, Member, Role, User
|
from discord import Color, Embed, Guild, Interaction, InteractionMessage, Member, Role, User
|
||||||
from redbot.core import commands
|
from redbot.core import commands
|
||||||
|
from redbot.core.bot import Red
|
||||||
from redbot.core.utils.chat_formatting import bold, box, error, humanize_timedelta, warning
|
from redbot.core.utils.chat_formatting import bold, box, error, humanize_timedelta, warning
|
||||||
|
|
||||||
from aurora.utilities.config import config
|
from ..models.moderation import Moderation
|
||||||
from aurora.utilities.utils import fetch_channel_dict, fetch_user_dict, get_bool_emoji, get_next_case_number, get_pagesize_str
|
from ..models.partials import PartialUser
|
||||||
|
from .config import config
|
||||||
|
from .utils import get_bool_emoji, get_pagesize_str
|
||||||
|
|
||||||
|
|
||||||
async def message_factory(
|
async def message_factory(
|
||||||
|
bot: Red,
|
||||||
color: Color,
|
color: Color,
|
||||||
guild: Guild,
|
guild: Guild,
|
||||||
reason: str,
|
reason: str,
|
||||||
moderation_type: str,
|
moderation_type: str,
|
||||||
moderator: Union[Member, User] = None,
|
moderator: Union[Member, User] | None = None,
|
||||||
duration: timedelta = None,
|
duration: timedelta | None = None,
|
||||||
response: InteractionMessage = None,
|
response: InteractionMessage | None = None,
|
||||||
role: Role = None,
|
role: Role | None = None,
|
||||||
) -> Embed:
|
) -> Embed:
|
||||||
"""This function creates a message from set parameters, meant for contacting the moderated user.
|
"""This function creates a message from set parameters, meant for contacting the moderated user.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
|
bot (Red): The bot instance.
|
||||||
color (Color): The color of the embed.
|
color (Color): The color of the embed.
|
||||||
guild (Guild): The guild the moderation occurred in.
|
guild (Guild): The guild the moderation occurred in.
|
||||||
reason (str): The reason for the moderation.
|
reason (str): The reason for the moderation.
|
||||||
|
@ -86,7 +91,7 @@ async def message_factory(
|
||||||
embed.set_author(name=guild.name)
|
embed.set_author(name=guild.name)
|
||||||
|
|
||||||
embed.set_footer(
|
embed.set_footer(
|
||||||
text=f"Case #{await get_next_case_number(guild.id):,}",
|
text=f"Case #{Moderation.get_next_case_number(bot=bot, guild_id=guild.id):,}",
|
||||||
icon_url="attachment://arrow.png",
|
icon_url="attachment://arrow.png",
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -94,256 +99,173 @@ async def message_factory(
|
||||||
|
|
||||||
|
|
||||||
async def log_factory(
|
async def log_factory(
|
||||||
interaction: Interaction, case_dict: dict, resolved: bool = False
|
interaction: Interaction, moderation: Moderation, resolved: bool = False
|
||||||
) -> Embed:
|
) -> Embed:
|
||||||
"""This function creates a log embed from set parameters, meant for moderation logging.
|
"""This function creates a log embed from set parameters, meant for moderation logging.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
interaction (Interaction): The interaction object.
|
interaction (discord.Interaction): The interaction object.
|
||||||
case_dict (dict): The case dictionary.
|
moderation (aurora.models.Moderation): The moderation object.
|
||||||
resolved (bool, optional): Whether the case is resolved or not. Defaults to False.
|
resolved (bool, optional): Whether the case is resolved or not. Defaults to False.
|
||||||
"""
|
"""
|
||||||
|
target = await moderation.get_target()
|
||||||
|
moderator = await moderation.get_moderator()
|
||||||
if resolved:
|
if resolved:
|
||||||
if case_dict["target_type"] == "USER":
|
|
||||||
target_user = await fetch_user_dict(interaction.client, case_dict["target_id"])
|
|
||||||
target_name = (
|
|
||||||
f"`{target_user['name']}`"
|
|
||||||
if target_user["discriminator"] == "0"
|
|
||||||
else f"`{target_user['name']}#{target_user['discriminator']}`"
|
|
||||||
)
|
|
||||||
elif case_dict["target_type"] == "CHANNEL":
|
|
||||||
target_user = await fetch_channel_dict(interaction.guild, case_dict["target_id"])
|
|
||||||
if target_user["mention"]:
|
|
||||||
target_name = f"{target_user['mention']}"
|
|
||||||
else:
|
|
||||||
target_name = f"`{target_user['name']}`"
|
|
||||||
|
|
||||||
moderator_user = await fetch_user_dict(interaction.client, case_dict["moderator_id"])
|
|
||||||
moderator_name = (
|
|
||||||
f"`{moderator_user['name']}`"
|
|
||||||
if moderator_user["discriminator"] == "0"
|
|
||||||
else f"`{moderator_user['name']}#{moderator_user['discriminator']}`"
|
|
||||||
)
|
|
||||||
|
|
||||||
embed = Embed(
|
embed = Embed(
|
||||||
title=f"📕 Case #{case_dict['moderation_id']:,} Resolved",
|
title=f"📕 Case #{moderation.id:,} Resolved",
|
||||||
color=await interaction.client.get_embed_color(interaction.channel),
|
color=await interaction.client.get_embed_color(interaction.channel),
|
||||||
)
|
)
|
||||||
|
|
||||||
embed.description = f"**Type:** {str.title(case_dict['moderation_type'])}\n**Target:** {target_name} ({target_user['id']})\n**Moderator:** {moderator_name} ({moderator_user['id']})\n**Timestamp:** <t:{case_dict['timestamp']}> | <t:{case_dict['timestamp']}:R>"
|
resolved_by = await moderation.get_resolved_by()
|
||||||
|
embed.description = f"**Type:** {str.title(moderation.moderation_type)}\n**Target:** {target.name} ({target.id})\n**Moderator:** {moderator.name} ({moderator.id})\n**Timestamp:** <t:{moderation.unix_timestamp}> | <t:{moderation.unix_timestamp}:R>"
|
||||||
|
|
||||||
if case_dict["duration"] != "NULL":
|
if moderation.duration is not None:
|
||||||
td = timedelta(
|
|
||||||
**{
|
|
||||||
unit: int(val)
|
|
||||||
for unit, val in zip(
|
|
||||||
["hours", "minutes", "seconds"],
|
|
||||||
case_dict["duration"].split(":"),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
)
|
|
||||||
duration_embed = (
|
duration_embed = (
|
||||||
f"{humanize_timedelta(timedelta=td)} | <t:{case_dict['end_timestamp']}:R>"
|
f"{humanize_timedelta(timedelta=moderation.duration)} | <t:{moderation.end_timestamp}:R>"
|
||||||
if case_dict["expired"] == "0"
|
if not moderation.expired
|
||||||
else str(humanize_timedelta(timedelta=td))
|
else str(humanize_timedelta(timedelta=moderation.duration))
|
||||||
)
|
)
|
||||||
embed.description = (
|
embed.description = (
|
||||||
embed.description
|
embed.description
|
||||||
+ f"\n**Duration:** {duration_embed}\n**Expired:** {bool(case_dict['expired'])}"
|
+ f"\n**Duration:** {duration_embed}\n**Expired:** {moderation.expired}"
|
||||||
)
|
)
|
||||||
|
|
||||||
embed.add_field(name="Reason", value=box(case_dict["reason"]), inline=False)
|
if moderation.metadata.items():
|
||||||
|
for key, value in moderation.metadata.items():
|
||||||
|
embed.description += f"\n**{key.title()}:** {value}"
|
||||||
|
|
||||||
|
embed.add_field(name="Reason", value=box(moderation.reason), inline=False)
|
||||||
|
|
||||||
resolved_user = await fetch_user_dict(interaction.client, case_dict["resolved_by"])
|
|
||||||
resolved_name = (
|
|
||||||
resolved_user["name"]
|
|
||||||
if resolved_user["discriminator"] == "0"
|
|
||||||
else f"{resolved_user['name']}#{resolved_user['discriminator']}"
|
|
||||||
)
|
|
||||||
embed.add_field(
|
embed.add_field(
|
||||||
name="Resolve Reason",
|
name="Resolve Reason",
|
||||||
value=f"Resolved by `{resolved_name}` ({resolved_user['id']}) for:\n"
|
value=f"Resolved by `{resolved_by.name}` ({resolved_by.id}) for:\n"
|
||||||
+ box(case_dict["resolve_reason"]),
|
+ box(moderation.resolve_reason),
|
||||||
inline=False,
|
inline=False,
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
if case_dict["target_type"] == "USER":
|
|
||||||
target_user = await fetch_user_dict(interaction.client, case_dict["target_id"])
|
|
||||||
target_name = (
|
|
||||||
f"`{target_user['name']}`"
|
|
||||||
if target_user["discriminator"] == "0"
|
|
||||||
else f"`{target_user['name']}#{target_user['discriminator']}`"
|
|
||||||
)
|
|
||||||
elif case_dict["target_type"] == "CHANNEL":
|
|
||||||
target_user = await fetch_channel_dict(interaction.guild, case_dict["target_id"])
|
|
||||||
if target_user["mention"]:
|
|
||||||
target_name = target_user["mention"]
|
|
||||||
else:
|
|
||||||
target_name = f"`{target_user['name']}`"
|
|
||||||
|
|
||||||
moderator_user = await fetch_user_dict(interaction.client, case_dict["moderator_id"])
|
|
||||||
moderator_name = (
|
|
||||||
f"`{moderator_user['name']}`"
|
|
||||||
if moderator_user["discriminator"] == "0"
|
|
||||||
else f"`{moderator_user['name']}#{moderator_user['discriminator']}`"
|
|
||||||
)
|
|
||||||
|
|
||||||
embed = Embed(
|
embed = Embed(
|
||||||
title=f"📕 Case #{case_dict['moderation_id']:,}",
|
title=f"📕 Case #{moderation.id:,}",
|
||||||
color=await interaction.client.get_embed_color(interaction.channel),
|
color=await interaction.client.get_embed_color(interaction.channel),
|
||||||
)
|
)
|
||||||
embed.description = f"**Type:** {str.title(case_dict['moderation_type'])}\n**Target:** {target_name} ({target_user['id']})\n**Moderator:** {moderator_name} ({moderator_user['id']})\n**Timestamp:** <t:{case_dict['timestamp']}> | <t:{case_dict['timestamp']}:R>"
|
embed.description = f"**Type:** {str.title(moderation.type)}\n**Target:** {target.name} ({target.id})\n**Moderator:** {moderator.name} ({moderator.id})\n**Timestamp:** <t:{moderation.unix_timestamp}> | <t:{moderation.unix_timestamp}:R>"
|
||||||
|
|
||||||
if case_dict["duration"] != "NULL":
|
if moderation.duration:
|
||||||
td = timedelta(
|
|
||||||
**{
|
|
||||||
unit: int(val)
|
|
||||||
for unit, val in zip(
|
|
||||||
["hours", "minutes", "seconds"],
|
|
||||||
case_dict["duration"].split(":"),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
)
|
|
||||||
embed.description = (
|
embed.description = (
|
||||||
embed.description
|
embed.description
|
||||||
+ f"\n**Duration:** {humanize_timedelta(timedelta=td)} | <t:{case_dict['end_timestamp']}:R>"
|
+ f"\n**Duration:** {humanize_timedelta(timedelta=moderation.duration)} | <t:{moderation.unix_timestamp}:R>"
|
||||||
)
|
)
|
||||||
|
|
||||||
embed.add_field(name="Reason", value=box(case_dict["reason"]), inline=False)
|
if moderation.metadata.items():
|
||||||
|
for key, value in moderation.metadata.items():
|
||||||
|
embed.description += f"\n**{key.title()}:** {value}"
|
||||||
|
|
||||||
|
embed.add_field(name="Reason", value=box(moderation.reason), inline=False)
|
||||||
return embed
|
return embed
|
||||||
|
|
||||||
|
|
||||||
async def case_factory(interaction: Interaction, case_dict: dict) -> Embed:
|
async def case_factory(interaction: Interaction, moderation: Moderation) -> Embed:
|
||||||
"""This function creates a case embed from set parameters.
|
"""This function creates a case embed from set parameters.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
interaction (Interaction): The interaction object.
|
interaction (discord.Interaction): The interaction object.
|
||||||
case_dict (dict): The case dictionary.
|
moderation (aurora.models.Moderation): The moderation object.
|
||||||
"""
|
"""
|
||||||
if case_dict["target_type"] == "USER":
|
target = await moderation.get_target()
|
||||||
target_user = await fetch_user_dict(interaction.client, case_dict["target_id"])
|
moderator = await moderation.get_moderator()
|
||||||
target_name = (
|
|
||||||
f"`{target_user['name']}`"
|
|
||||||
if target_user["discriminator"] == "0"
|
|
||||||
else f"`{target_user['name']}#{target_user['discriminator']}`"
|
|
||||||
)
|
|
||||||
elif case_dict["target_type"] == "CHANNEL":
|
|
||||||
target_user = await fetch_channel_dict(interaction.guild, case_dict["target_id"])
|
|
||||||
if target_user["mention"]:
|
|
||||||
target_name = f"{target_user['mention']}"
|
|
||||||
else:
|
|
||||||
target_name = f"`{target_user['name']}`"
|
|
||||||
|
|
||||||
moderator_user = await fetch_user_dict(interaction.client, case_dict["moderator_id"])
|
|
||||||
moderator_name = (
|
|
||||||
f"`{moderator_user['name']}`"
|
|
||||||
if moderator_user["discriminator"] == "0"
|
|
||||||
else f"`{moderator_user['name']}#{moderator_user['discriminator']}`"
|
|
||||||
)
|
|
||||||
|
|
||||||
embed = Embed(
|
embed = Embed(
|
||||||
title=f"📕 Case #{case_dict['moderation_id']:,}",
|
title=f"📕 Case #{moderation.id:,}",
|
||||||
color=await interaction.client.get_embed_color(interaction.channel),
|
color=await interaction.client.get_embed_color(interaction.channel),
|
||||||
)
|
)
|
||||||
embed.description = f"**Type:** {str.title(case_dict['moderation_type'])}\n**Target:** {target_name} ({target_user['id']})\n**Moderator:** {moderator_name} ({moderator_user['id']})\n**Resolved:** {bool(case_dict['resolved'])}\n**Timestamp:** <t:{case_dict['timestamp']}> | <t:{case_dict['timestamp']}:R>"
|
embed.description = f"**Type:** {str.title(moderation.type)}\n**Target:** `{target.name}` ({target.id})\n**Moderator:** `{moderator.name}` ({moderator.id})\n**Resolved:** {moderation.resolved}\n**Timestamp:** <t:{moderation.unix_timestamp}> | <t:{moderation.unix_timestamp}:R>"
|
||||||
|
|
||||||
if case_dict["duration"] != "NULL":
|
if moderation.duration:
|
||||||
td = timedelta(
|
|
||||||
**{
|
|
||||||
unit: int(val)
|
|
||||||
for unit, val in zip(
|
|
||||||
["hours", "minutes", "seconds"], case_dict["duration"].split(":")
|
|
||||||
)
|
|
||||||
}
|
|
||||||
)
|
|
||||||
duration_embed = (
|
duration_embed = (
|
||||||
f"{humanize_timedelta(timedelta=td)} | <t:{case_dict['end_timestamp']}:R>"
|
f"{humanize_timedelta(timedelta=moderation.duration)} | <t:{moderation.unix_timestamp}:R>"
|
||||||
if bool(case_dict["expired"]) is False
|
if moderation.expired is False
|
||||||
else str(humanize_timedelta(timedelta=td))
|
else str(humanize_timedelta(timedelta=moderation.duration))
|
||||||
)
|
)
|
||||||
embed.description += f"\n**Duration:** {duration_embed}\n**Expired:** {bool(case_dict['expired'])}"
|
embed.description += f"\n**Duration:** {duration_embed}\n**Expired:** {moderation.expired}"
|
||||||
|
|
||||||
embed.description += (
|
embed.description += (
|
||||||
f"\n**Changes:** {len(case_dict['changes']) - 1}"
|
f"\n**Changes:** {len(moderation.changes) - 1}"
|
||||||
if case_dict["changes"]
|
if moderation.changes
|
||||||
else "\n**Changes:** 0"
|
else "\n**Changes:** 0"
|
||||||
)
|
)
|
||||||
|
|
||||||
if case_dict["role_id"]:
|
if moderation.role_id:
|
||||||
embed.description += f"\n**Role:** <@&{case_dict['role_id']}>"
|
role = await moderation.get_role()
|
||||||
|
embed.description += f"\n**Role:** {role.name}"
|
||||||
|
|
||||||
if case_dict["metadata"]:
|
if moderation.metadata:
|
||||||
if case_dict["metadata"]["imported_from"]:
|
if moderation.metadata.get("imported_from"):
|
||||||
embed.description += (
|
embed.description += (
|
||||||
f"\n**Imported From:** {case_dict['metadata']['imported_from']}"
|
f"\n**Imported From:** {moderation.metadata['imported_from']}"
|
||||||
)
|
)
|
||||||
|
moderation.metadata.pop("imported_from")
|
||||||
|
if moderation.metadata.get("imported_timestamp"):
|
||||||
|
embed.description += (
|
||||||
|
f"\n**Imported Timestamp:** <t:{moderation.metadata['imported_timestamp']}> | <t:{moderation.metadata['imported_timestamp']}:R>"
|
||||||
|
)
|
||||||
|
moderation.metadata.pop("imported_timestamp")
|
||||||
|
if moderation.metadata.items():
|
||||||
|
for key, value in moderation.metadata.items():
|
||||||
|
embed.description += f"\n**{key.title()}:** {value}"
|
||||||
|
|
||||||
embed.add_field(name="Reason", value=box(case_dict["reason"]), inline=False)
|
embed.add_field(name="Reason", value=box(moderation.reason), inline=False)
|
||||||
|
|
||||||
if case_dict["resolved"] == 1:
|
if moderation.resolved:
|
||||||
resolved_user = await fetch_user_dict(interaction.client, case_dict["resolved_by"])
|
resolved_user = await moderation.get_resolved_by()
|
||||||
resolved_name = (
|
|
||||||
f"`{resolved_user['name']}`"
|
|
||||||
if resolved_user["discriminator"] == "0"
|
|
||||||
else f"`{resolved_user['name']}#{resolved_user['discriminator']}`"
|
|
||||||
)
|
|
||||||
embed.add_field(
|
embed.add_field(
|
||||||
name="Resolve Reason",
|
name="Resolve Reason",
|
||||||
value=f"Resolved by {resolved_name} ({resolved_user['id']}) for:\n{box(case_dict['resolve_reason'])}",
|
value=f"Resolved by `{resolved_user.name}` ({resolved_user.id}) for:\n{box(moderation.resolve_reason)}",
|
||||||
inline=False,
|
inline=False,
|
||||||
)
|
)
|
||||||
|
|
||||||
return embed
|
return embed
|
||||||
|
|
||||||
|
|
||||||
async def changes_factory(interaction: Interaction, case_dict: dict) -> Embed:
|
async def changes_factory(interaction: Interaction, moderation: Moderation) -> Embed:
|
||||||
"""This function creates a changes embed from set parameters.
|
"""This function creates a changes embed from set parameters.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
interaction (Interaction): The interaction object.
|
interaction (discord.Interaction): The interaction object.
|
||||||
case_dict (dict): The case dictionary.
|
moderation (aurora.models.Moderation): The moderation object.
|
||||||
"""
|
"""
|
||||||
embed = Embed(
|
embed = Embed(
|
||||||
title=f"📕 Case #{case_dict['moderation_id']:,} Changes",
|
title=f"📕 Case #{moderation.id:,} Changes",
|
||||||
color=await interaction.client.get_embed_color(interaction.channel),
|
color=await interaction.client.get_embed_color(interaction.channel),
|
||||||
)
|
)
|
||||||
|
|
||||||
memory_dict = {}
|
memory_dict = {}
|
||||||
|
|
||||||
if case_dict["changes"]:
|
if moderation.changes:
|
||||||
for change in case_dict["changes"]:
|
for change in moderation.changes:
|
||||||
if change["user_id"] not in memory_dict:
|
if change.user_id not in memory_dict:
|
||||||
memory_dict[str(change["user_id"])] = await fetch_user_dict(
|
memory_dict[str(change.user_id)] = await change.get_user()
|
||||||
interaction.client, change["user_id"]
|
|
||||||
)
|
|
||||||
|
|
||||||
user = memory_dict[str(change["user_id"])]
|
user: PartialUser = memory_dict[str(change.user_id)]
|
||||||
name = (
|
|
||||||
user["name"]
|
|
||||||
if user["discriminator"] == "0"
|
|
||||||
else f"{user['name']}#{user['discriminator']}"
|
|
||||||
)
|
|
||||||
|
|
||||||
timestamp = f"<t:{change['timestamp']}> | <t:{change['timestamp']}:R>"
|
timestamp = f"<t:{change.unix_timestamp}> | <t:{change.unix_timestamp}:R>"
|
||||||
|
|
||||||
if change["type"] == "ORIGINAL":
|
if change.type == "ORIGINAL":
|
||||||
embed.add_field(
|
embed.add_field(
|
||||||
name="Original",
|
name="Original",
|
||||||
value=f"**User:** `{name}` ({user['id']})\n**Reason:** {change['reason']}\n**Timestamp:** {timestamp}",
|
value=f"**User:** `{user.name}` ({user.id})\n**Reason:** {change.reason}\n**Timestamp:** {timestamp}",
|
||||||
inline=False,
|
inline=False,
|
||||||
)
|
)
|
||||||
|
|
||||||
elif change["type"] == "EDIT":
|
elif change.type == "EDIT":
|
||||||
embed.add_field(
|
embed.add_field(
|
||||||
name="Edit",
|
name="Edit",
|
||||||
value=f"**User:** `{name}` ({user['id']})\n**Reason:** {change['reason']}\n**Timestamp:** {timestamp}",
|
value=f"**User:** `{user.name}` ({user.id})\n**Reason:** {change.reason}\n**Timestamp:** {timestamp}",
|
||||||
inline=False,
|
inline=False,
|
||||||
)
|
)
|
||||||
|
|
||||||
elif change["type"] == "RESOLVE":
|
elif change.type == "RESOLVE":
|
||||||
embed.add_field(
|
embed.add_field(
|
||||||
name="Resolve",
|
name="Resolve",
|
||||||
value=f"**User:** `{name}` ({user['id']})\n**Reason:** {change['reason']}\n**Timestamp:** {timestamp}",
|
value=f"**User:** `{user.name}` ({user.id})\n**Reason:** {change.reason}\n**Timestamp:** {timestamp}",
|
||||||
inline=False,
|
inline=False,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -353,40 +275,25 @@ async def changes_factory(interaction: Interaction, case_dict: dict) -> Embed:
|
||||||
return embed
|
return embed
|
||||||
|
|
||||||
|
|
||||||
async def evidenceformat_factory(interaction: Interaction, case_dict: dict) -> str:
|
async def evidenceformat_factory(moderation: Moderation) -> str:
|
||||||
"""This function creates a codeblock in evidence format from set parameters.
|
"""This function creates a codeblock in evidence format from set parameters.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
interaction (Interaction): The interaction object.
|
interaction (discord.Interaction): The interaction object.
|
||||||
case_dict (dict): The case dictionary.
|
moderation (aurora.models.Moderation): The moderation object.
|
||||||
"""
|
"""
|
||||||
if case_dict["target_type"] == "USER":
|
target = await moderation.get_target()
|
||||||
target_user = await fetch_user_dict(interaction.client, case_dict["target_id"])
|
moderator = await moderation.get_moderator()
|
||||||
target_name = (
|
|
||||||
target_user["name"]
|
|
||||||
if target_user["discriminator"] == "0"
|
|
||||||
else f"{target_user['name']}#{target_user['discriminator']}"
|
|
||||||
)
|
|
||||||
|
|
||||||
elif case_dict["target_type"] == "CHANNEL":
|
content = f"Case: {moderation.id:,} ({str.title(moderation.type)})\nTarget: {target.name} ({target.id})\nModerator: {moderator.name} ({moderator.id})"
|
||||||
target_user = await fetch_channel_dict(interaction.guild, case_dict["target_id"])
|
|
||||||
target_name = target_user["name"]
|
|
||||||
|
|
||||||
moderator_user = await fetch_user_dict(interaction.client, case_dict["moderator_id"])
|
if moderation.duration is not None:
|
||||||
moderator_name = (
|
content += f"\nDuration: {humanize_timedelta(timedelta=moderation.duration)}"
|
||||||
moderator_user["name"]
|
|
||||||
if moderator_user["discriminator"] == "0"
|
|
||||||
else f"{moderator_user['name']}#{moderator_user['discriminator']}"
|
|
||||||
)
|
|
||||||
|
|
||||||
content = f"Case: {case_dict['moderation_id']:,} ({str.title(case_dict['moderation_type'])})\nTarget: {target_name} ({target_user['id']})\nModerator: {moderator_name} ({moderator_user['id']})"
|
content += f"\nReason: {moderation.reason}"
|
||||||
|
|
||||||
if case_dict["duration"] != "NULL":
|
for key, value in moderation.metadata.items():
|
||||||
hours, minutes, seconds = map(int, case_dict["duration"].split(":"))
|
content += f"\n{key.title()}: {value}"
|
||||||
td = timedelta(hours=hours, minutes=minutes, seconds=seconds)
|
|
||||||
content += f"\nDuration: {humanize_timedelta(timedelta=td)}"
|
|
||||||
|
|
||||||
content += f"\nReason: {case_dict['reason']}"
|
|
||||||
|
|
||||||
return box(content, "prolog")
|
return box(content, "prolog")
|
||||||
|
|
||||||
|
|
128
aurora/utilities/json.py
Normal file
128
aurora/utilities/json.py
Normal file
|
@ -0,0 +1,128 @@
|
||||||
|
import json
|
||||||
|
from datetime import datetime, timedelta
|
||||||
|
|
||||||
|
from redbot.core.bot import Red
|
||||||
|
|
||||||
|
from ..models.base import AuroraBaseModel
|
||||||
|
|
||||||
|
|
||||||
|
class JSONEncoder(json.JSONEncoder):
|
||||||
|
def default(self, o):
|
||||||
|
if isinstance(o, datetime):
|
||||||
|
return int(o.timestamp())
|
||||||
|
if isinstance(o, timedelta):
|
||||||
|
return str(o)
|
||||||
|
if isinstance(o, AuroraBaseModel):
|
||||||
|
return o.dump()
|
||||||
|
if isinstance(o, Red):
|
||||||
|
return None
|
||||||
|
return super().default(o)
|
||||||
|
|
||||||
|
|
||||||
|
# This is a wrapper around the json module's dumps function that uses our custom JSONEncoder class
|
||||||
|
def dumps(obj, *, skipkeys=False, ensure_ascii=True, check_circular=True,
|
||||||
|
allow_nan=True, indent=None, separators=None,
|
||||||
|
default=None, sort_keys=False, **kw) -> str:
|
||||||
|
"""Serialize ``obj`` to a JSON formatted ``str``.
|
||||||
|
|
||||||
|
If ``skipkeys`` is true then ``dict`` keys that are not basic types
|
||||||
|
(``str``, ``int``, ``float``, ``bool``, ``None``) will be skipped
|
||||||
|
instead of raising a ``TypeError``.
|
||||||
|
|
||||||
|
If ``ensure_ascii`` is false, then the return value can contain non-ASCII
|
||||||
|
characters if they appear in strings contained in ``obj``. Otherwise, all
|
||||||
|
such characters are escaped in JSON strings.
|
||||||
|
|
||||||
|
If ``check_circular`` is false, then the circular reference check
|
||||||
|
for container types will be skipped and a circular reference will
|
||||||
|
result in an ``RecursionError`` (or worse).
|
||||||
|
|
||||||
|
If ``allow_nan`` is false, then it will be a ``ValueError`` to
|
||||||
|
serialize out of range ``float`` values (``nan``, ``inf``, ``-inf``) in
|
||||||
|
strict compliance of the JSON specification, instead of using the
|
||||||
|
JavaScript equivalents (``NaN``, ``Infinity``, ``-Infinity``).
|
||||||
|
|
||||||
|
If ``indent`` is a non-negative integer, then JSON array elements and
|
||||||
|
object members will be pretty-printed with that indent level. An indent
|
||||||
|
level of 0 will only insert newlines. ``None`` is the most compact
|
||||||
|
representation.
|
||||||
|
|
||||||
|
If specified, ``separators`` should be an ``(item_separator, key_separator)``
|
||||||
|
tuple. The default is ``(', ', ': ')`` if *indent* is ``None`` and
|
||||||
|
``(',', ': ')`` otherwise. To get the most compact JSON representation,
|
||||||
|
you should specify ``(',', ':')`` to eliminate whitespace.
|
||||||
|
|
||||||
|
``default(obj)`` is a function that should return a serializable version
|
||||||
|
of obj or raise TypeError. The default simply raises TypeError.
|
||||||
|
|
||||||
|
If *sort_keys* is true (default: ``False``), then the output of
|
||||||
|
dictionaries will be sorted by key.
|
||||||
|
"""
|
||||||
|
return json.dumps(
|
||||||
|
obj,
|
||||||
|
cls=JSONEncoder,
|
||||||
|
skipkeys=skipkeys,
|
||||||
|
ensure_ascii=ensure_ascii,
|
||||||
|
check_circular=check_circular,
|
||||||
|
allow_nan=allow_nan,
|
||||||
|
indent=indent,
|
||||||
|
separators=separators,
|
||||||
|
default=default,
|
||||||
|
sort_keys=sort_keys,
|
||||||
|
**kw
|
||||||
|
)
|
||||||
|
|
||||||
|
# This is a wrapper around the json module's dump function that uses our custom JSONEncoder class
|
||||||
|
def dump(obj, fp, *, skipkeys=False, ensure_ascii=True, check_circular=True,
|
||||||
|
allow_nan=True, indent=None, separators=None,
|
||||||
|
default=None, sort_keys=False, **kw) -> str:
|
||||||
|
"""Serialize ``obj`` as a JSON formatted stream to ``fp`` (a
|
||||||
|
``.write()``-supporting file-like object).
|
||||||
|
|
||||||
|
If ``skipkeys`` is true then ``dict`` keys that are not basic types
|
||||||
|
(``str``, ``int``, ``float``, ``bool``, ``None``) will be skipped
|
||||||
|
instead of raising a ``TypeError``.
|
||||||
|
|
||||||
|
If ``ensure_ascii`` is false, then the strings written to ``fp`` can
|
||||||
|
contain non-ASCII characters if they appear in strings contained in
|
||||||
|
``obj``. Otherwise, all such characters are escaped in JSON strings.
|
||||||
|
|
||||||
|
If ``check_circular`` is false, then the circular reference check
|
||||||
|
for container types will be skipped and a circular reference will
|
||||||
|
result in an ``RecursionError`` (or worse).
|
||||||
|
|
||||||
|
If ``allow_nan`` is false, then it will be a ``ValueError`` to
|
||||||
|
serialize out of range ``float`` values (``nan``, ``inf``, ``-inf``)
|
||||||
|
in strict compliance of the JSON specification, instead of using the
|
||||||
|
JavaScript equivalents (``NaN``, ``Infinity``, ``-Infinity``).
|
||||||
|
|
||||||
|
If ``indent`` is a non-negative integer, then JSON array elements and
|
||||||
|
object members will be pretty-printed with that indent level. An indent
|
||||||
|
level of 0 will only insert newlines. ``None`` is the most compact
|
||||||
|
representation.
|
||||||
|
|
||||||
|
If specified, ``separators`` should be an ``(item_separator, key_separator)``
|
||||||
|
tuple. The default is ``(', ', ': ')`` if *indent* is ``None`` and
|
||||||
|
``(',', ': ')`` otherwise. To get the most compact JSON representation,
|
||||||
|
you should specify ``(',', ':')`` to eliminate whitespace.
|
||||||
|
|
||||||
|
``default(obj)`` is a function that should return a serializable version
|
||||||
|
of obj or raise TypeError. The default simply raises TypeError.
|
||||||
|
|
||||||
|
If *sort_keys* is true (default: ``False``), then the output of
|
||||||
|
dictionaries will be sorted by key.
|
||||||
|
"""
|
||||||
|
return json.dump(
|
||||||
|
obj,
|
||||||
|
fp,
|
||||||
|
cls=JSONEncoder,
|
||||||
|
skipkeys=skipkeys,
|
||||||
|
ensure_ascii=ensure_ascii,
|
||||||
|
check_circular=check_circular,
|
||||||
|
allow_nan=allow_nan,
|
||||||
|
indent=indent,
|
||||||
|
separators=separators,
|
||||||
|
default=default,
|
||||||
|
sort_keys=sort_keys,
|
||||||
|
**kw
|
||||||
|
)
|
|
@ -1,23 +1,21 @@
|
||||||
# pylint: disable=cyclic-import
|
# pylint: disable=cyclic-import
|
||||||
import json
|
from datetime import datetime, timedelta
|
||||||
from datetime import datetime
|
from typing import Optional, Tuple, Union
|
||||||
from datetime import timedelta as td
|
|
||||||
from typing import Optional, Union
|
|
||||||
|
|
||||||
from dateutil.relativedelta import relativedelta as rd
|
from dateutil.relativedelta import relativedelta as rd
|
||||||
from discord import File, Guild, Interaction, Member, SelectOption, User
|
from discord import File, Guild, Interaction, Member, SelectOption, TextChannel, User
|
||||||
from discord.errors import Forbidden, NotFound
|
from discord.errors import Forbidden
|
||||||
from redbot.core import commands, data_manager
|
from redbot.core import commands, data_manager
|
||||||
from redbot.core.utils.chat_formatting import error
|
from redbot.core.utils.chat_formatting import error
|
||||||
|
|
||||||
from .config import config
|
from ..utilities.config import config
|
||||||
|
|
||||||
|
|
||||||
def check_permissions(
|
def check_permissions(
|
||||||
user: User,
|
user: User,
|
||||||
permissions: list,
|
permissions: Tuple[str],
|
||||||
ctx: Union[commands.Context, Interaction] = None,
|
ctx: Union[commands.Context, Interaction] | None = None,
|
||||||
guild: Guild = None,
|
guild: Guild | None = None,
|
||||||
) -> Union[bool, str]:
|
) -> Union[bool, str]:
|
||||||
"""Checks if a user has a specific permission (or a list of permissions) in a channel."""
|
"""Checks if a user has a specific permission (or a list of permissions) in a channel."""
|
||||||
if ctx:
|
if ctx:
|
||||||
|
@ -42,9 +40,10 @@ def check_permissions(
|
||||||
|
|
||||||
|
|
||||||
async def check_moddable(
|
async def check_moddable(
|
||||||
target: Union[User, Member], interaction: Interaction, permissions: list
|
target: Union[User, Member, TextChannel], interaction: Interaction, permissions: Tuple[str]
|
||||||
) -> bool:
|
) -> bool:
|
||||||
"""Checks if a moderator can moderate a target."""
|
"""Checks if a moderator can moderate a target."""
|
||||||
|
is_channel = isinstance(target, TextChannel)
|
||||||
if check_permissions(interaction.client.user, permissions, guild=interaction.guild):
|
if check_permissions(interaction.client.user, permissions, guild=interaction.guild):
|
||||||
await interaction.response.send_message(
|
await interaction.response.send_message(
|
||||||
error(
|
error(
|
||||||
|
@ -70,7 +69,7 @@ async def check_moddable(
|
||||||
)
|
)
|
||||||
return False
|
return False
|
||||||
|
|
||||||
if target.bot:
|
if not is_channel and target.bot:
|
||||||
await interaction.response.send_message(
|
await interaction.response.send_message(
|
||||||
content="You cannot moderate bots!", ephemeral=True
|
content="You cannot moderate bots!", ephemeral=True
|
||||||
)
|
)
|
||||||
|
@ -111,122 +110,31 @@ async def check_moddable(
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
|
||||||
async def get_next_case_number(guild_id: str, cursor=None) -> int:
|
|
||||||
"""This function returns the next case number from the MySQL table for a specific guild."""
|
|
||||||
from .database import connect
|
|
||||||
|
|
||||||
if not cursor:
|
|
||||||
database = connect()
|
|
||||||
cursor = database.cursor()
|
|
||||||
cursor.execute(
|
|
||||||
f"SELECT moderation_id FROM `moderation_{guild_id}` ORDER BY moderation_id DESC LIMIT 1"
|
|
||||||
)
|
|
||||||
result = cursor.fetchone()
|
|
||||||
return (result[0] + 1) if result else 1
|
|
||||||
|
|
||||||
|
|
||||||
def generate_dict(result) -> dict:
|
|
||||||
case = {
|
|
||||||
"moderation_id": result[0],
|
|
||||||
"timestamp": result[1],
|
|
||||||
"moderation_type": result[2],
|
|
||||||
"target_type": result[3],
|
|
||||||
"target_id": result[4],
|
|
||||||
"moderator_id": result[5],
|
|
||||||
"role_id": result[6],
|
|
||||||
"duration": result[7],
|
|
||||||
"end_timestamp": result[8],
|
|
||||||
"reason": result[9],
|
|
||||||
"resolved": result[10],
|
|
||||||
"resolved_by": result[11],
|
|
||||||
"resolve_reason": result[12],
|
|
||||||
"expired": result[13],
|
|
||||||
"changes": json.loads(result[14]),
|
|
||||||
"metadata": json.loads(result[15]),
|
|
||||||
}
|
|
||||||
return case
|
|
||||||
|
|
||||||
|
|
||||||
async def fetch_user_dict(client: commands.Bot, user_id: str) -> dict:
|
|
||||||
"""This function returns a dictionary containing either user information or a standard deleted user template."""
|
|
||||||
if user_id == "?":
|
|
||||||
user_dict = {"id": "?", "name": "Unknown User", "discriminator": "0"}
|
|
||||||
|
|
||||||
else:
|
|
||||||
try:
|
|
||||||
user = client.get_user(int(user_id))
|
|
||||||
if user is None:
|
|
||||||
user = await client.fetch_user(int(user_id))
|
|
||||||
|
|
||||||
user_dict = {
|
|
||||||
"id": user.id,
|
|
||||||
"name": user.name,
|
|
||||||
"discriminator": user.discriminator,
|
|
||||||
}
|
|
||||||
|
|
||||||
except NotFound:
|
|
||||||
user_dict = {
|
|
||||||
"id": user_id,
|
|
||||||
"name": "Deleted User",
|
|
||||||
"discriminator": "0",
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
return user_dict
|
|
||||||
|
|
||||||
|
|
||||||
async def fetch_channel_dict(guild: Guild, channel_id: int) -> dict:
|
|
||||||
"""This function returns a dictionary containing either channel information or a standard deleted channel template."""
|
|
||||||
try:
|
|
||||||
channel = guild.get_channel(int(channel_id))
|
|
||||||
if not channel:
|
|
||||||
channel = await guild.fetch_channel(channel_id)
|
|
||||||
|
|
||||||
channel_dict = {
|
|
||||||
"id": channel.id,
|
|
||||||
"name": channel.name,
|
|
||||||
"mention": channel.mention,
|
|
||||||
}
|
|
||||||
|
|
||||||
except NotFound:
|
|
||||||
channel_dict = {"id": channel_id, "name": "Deleted Channel", "mention": None}
|
|
||||||
|
|
||||||
return channel_dict
|
|
||||||
|
|
||||||
|
|
||||||
async def fetch_role_dict(guild: Guild, role_id: int) -> dict:
|
|
||||||
"""This function returns a dictionary containing either role information or a standard deleted role template."""
|
|
||||||
role = guild.get_role(int(role_id))
|
|
||||||
if not role:
|
|
||||||
role_dict = {"id": role_id, "name": "Deleted Role"}
|
|
||||||
|
|
||||||
role_dict = {"id": role.id, "name": role.name}
|
|
||||||
|
|
||||||
return role_dict
|
|
||||||
|
|
||||||
|
|
||||||
async def log(interaction: Interaction, moderation_id: int, resolved: bool = False) -> None:
|
async def log(interaction: Interaction, moderation_id: int, resolved: bool = False) -> None:
|
||||||
"""This function sends a message to the guild's configured logging channel when an infraction takes place."""
|
"""This function sends a message to the guild's configured logging channel when an infraction takes place."""
|
||||||
from .database import fetch_case
|
from ..models.moderation import Moderation
|
||||||
from .factory import log_factory
|
from .factory import log_factory
|
||||||
|
|
||||||
logging_channel_id = await config.guild(interaction.guild).log_channel()
|
logging_channel_id = await config.guild(interaction.guild).log_channel()
|
||||||
if logging_channel_id != " ":
|
if logging_channel_id != " ":
|
||||||
logging_channel = interaction.guild.get_channel(logging_channel_id)
|
logging_channel = interaction.guild.get_channel(logging_channel_id)
|
||||||
|
|
||||||
case = await fetch_case(moderation_id, interaction.guild.id)
|
try:
|
||||||
if case:
|
moderation = Moderation.find_by_id(interaction.client, moderation_id, interaction.guild_id)
|
||||||
embed = await log_factory(
|
embed = await log_factory(
|
||||||
interaction=interaction, case_dict=case, resolved=resolved
|
interaction=interaction, moderation=moderation, resolved=resolved
|
||||||
)
|
)
|
||||||
try:
|
try:
|
||||||
await logging_channel.send(embed=embed)
|
await logging_channel.send(embed=embed)
|
||||||
except Forbidden:
|
except Forbidden:
|
||||||
return
|
return
|
||||||
|
except ValueError:
|
||||||
|
return
|
||||||
|
|
||||||
|
|
||||||
async def send_evidenceformat(interaction: Interaction, case_dict: dict) -> None:
|
async def send_evidenceformat(interaction: Interaction, moderation_id: int) -> None:
|
||||||
"""This function sends an ephemeral message to the moderator who took the moderation action, with a pre-made codeblock for use in the mod-evidence channel."""
|
"""This function sends an ephemeral message to the moderator who took the moderation action, with a pre-made codeblock for use in the mod-evidence channel."""
|
||||||
|
from ..models.moderation import Moderation
|
||||||
from .factory import evidenceformat_factory
|
from .factory import evidenceformat_factory
|
||||||
|
|
||||||
send_evidence_bool = (
|
send_evidence_bool = (
|
||||||
|
@ -237,26 +145,20 @@ async def send_evidenceformat(interaction: Interaction, case_dict: dict) -> None
|
||||||
if send_evidence_bool is False:
|
if send_evidence_bool is False:
|
||||||
return
|
return
|
||||||
|
|
||||||
content = await evidenceformat_factory(interaction=interaction, case_dict=case_dict)
|
moderation = Moderation.find_by_id(interaction.client, moderation_id, interaction.guild.id)
|
||||||
|
content = await evidenceformat_factory(moderation=moderation)
|
||||||
await interaction.followup.send(content=content, ephemeral=True)
|
await interaction.followup.send(content=content, ephemeral=True)
|
||||||
|
|
||||||
|
|
||||||
def convert_timedelta_to_str(timedelta: td) -> str:
|
|
||||||
"""This function converts a timedelta object to a string."""
|
|
||||||
total_seconds = int(timedelta.total_seconds())
|
|
||||||
hours = total_seconds // 3600
|
|
||||||
minutes = (total_seconds % 3600) // 60
|
|
||||||
seconds = total_seconds % 60
|
|
||||||
return f"{hours}:{minutes}:{seconds}"
|
|
||||||
|
|
||||||
|
|
||||||
def get_bool_emoji(value: Optional[bool]) -> str:
|
def get_bool_emoji(value: Optional[bool]) -> str:
|
||||||
"""Returns a unicode emoji based on a boolean value."""
|
"""Returns a unicode emoji based on a boolean value."""
|
||||||
if value is True:
|
match value:
|
||||||
return "\N{WHITE HEAVY CHECK MARK}"
|
case True:
|
||||||
if value is False:
|
return "\N{WHITE HEAVY CHECK MARK}"
|
||||||
return "\N{NO ENTRY SIGN}"
|
case False:
|
||||||
return "\N{BLACK QUESTION MARK ORNAMENT}\N{VARIATION SELECTOR-16}"
|
return "\N{NO ENTRY SIGN}"
|
||||||
|
case _:
|
||||||
|
return "\N{BLACK QUESTION MARK ORNAMENT}\N{VARIATION SELECTOR-16}"
|
||||||
|
|
||||||
|
|
||||||
def get_pagesize_str(value: Union[int, None]) -> str:
|
def get_pagesize_str(value: Union[int, None]) -> str:
|
||||||
|
@ -286,7 +188,7 @@ def create_pagesize_options() -> list[SelectOption]:
|
||||||
)
|
)
|
||||||
return options
|
return options
|
||||||
|
|
||||||
def timedelta_from_relativedelta(relativedelta: rd) -> td:
|
def timedelta_from_relativedelta(relativedelta: rd) -> timedelta:
|
||||||
"""Converts a relativedelta object to a timedelta object."""
|
"""Converts a relativedelta object to a timedelta object."""
|
||||||
now = datetime.now()
|
now = datetime.now()
|
||||||
then = now - relativedelta
|
then = now - relativedelta
|
||||||
|
|
739
poetry.lock
generated
739
poetry.lock
generated
|
@ -1,4 +1,4 @@
|
||||||
# This file is automatically @generated by Poetry 1.7.1 and should not be changed by hand.
|
# This file is automatically @generated by Poetry 1.8.2 and should not be changed by hand.
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "aiohttp"
|
name = "aiohttp"
|
||||||
|
@ -123,6 +123,17 @@ files = [
|
||||||
[package.dependencies]
|
[package.dependencies]
|
||||||
frozenlist = ">=1.1.0"
|
frozenlist = ">=1.1.0"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "annotated-types"
|
||||||
|
version = "0.6.0"
|
||||||
|
description = "Reusable constraint types to use with typing.Annotated"
|
||||||
|
optional = false
|
||||||
|
python-versions = ">=3.8"
|
||||||
|
files = [
|
||||||
|
{file = "annotated_types-0.6.0-py3-none-any.whl", hash = "sha256:0641064de18ba7a25dee8f96403ebc39113d0cb953a01429249d5c7564666a43"},
|
||||||
|
{file = "annotated_types-0.6.0.tar.gz", hash = "sha256:563339e807e53ffd9c267e99fc6d9ea23eb8443c08f112651963e24e22f84a5d"},
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "apsw"
|
name = "apsw"
|
||||||
version = "3.45.2.0"
|
version = "3.45.2.0"
|
||||||
|
@ -184,6 +195,20 @@ files = [
|
||||||
{file = "apsw-3.45.2.0.tar.gz", hash = "sha256:4fe81f5e390969d08d3048f357a68b347316b8f09455ff4657d94c56acfa255c"},
|
{file = "apsw-3.45.2.0.tar.gz", hash = "sha256:4fe81f5e390969d08d3048f357a68b347316b8f09455ff4657d94c56acfa255c"},
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "argcomplete"
|
||||||
|
version = "3.3.0"
|
||||||
|
description = "Bash tab completion for argparse"
|
||||||
|
optional = false
|
||||||
|
python-versions = ">=3.8"
|
||||||
|
files = [
|
||||||
|
{file = "argcomplete-3.3.0-py3-none-any.whl", hash = "sha256:c168c3723482c031df3c207d4ba8fa702717ccb9fc0bfe4117166c1f537b4a54"},
|
||||||
|
{file = "argcomplete-3.3.0.tar.gz", hash = "sha256:fd03ff4a5b9e6580569d34b273f741e85cd9e072f3feeeee3eba4891c70eda62"},
|
||||||
|
]
|
||||||
|
|
||||||
|
[package.extras]
|
||||||
|
test = ["coverage", "mypy", "pexpect", "ruff", "wheel"]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "astroid"
|
name = "astroid"
|
||||||
version = "3.1.0"
|
version = "3.1.0"
|
||||||
|
@ -322,13 +347,13 @@ files = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "cairocffi"
|
name = "cairocffi"
|
||||||
version = "1.6.1"
|
version = "1.7.0"
|
||||||
description = "cffi-based cairo bindings for Python"
|
description = "cffi-based cairo bindings for Python"
|
||||||
optional = false
|
optional = false
|
||||||
python-versions = ">=3.7"
|
python-versions = ">=3.8"
|
||||||
files = [
|
files = [
|
||||||
{file = "cairocffi-1.6.1-py3-none-any.whl", hash = "sha256:aa78ee52b9069d7475eeac457389b6275aa92111895d78fbaa2202a52dac112e"},
|
{file = "cairocffi-1.7.0-py3-none-any.whl", hash = "sha256:1f29a8d41dbda4090c0aa33bcdea64f3b493e95f74a43ea107c4a8a7b7f632ef"},
|
||||||
{file = "cairocffi-1.6.1.tar.gz", hash = "sha256:78e6bbe47357640c453d0be929fa49cd05cce2e1286f3d2a1ca9cbda7efdb8b7"},
|
{file = "cairocffi-1.7.0.tar.gz", hash = "sha256:7761863603894305f3160eca68452f373433ca8745ab7dd445bd2c6ce50dcab7"},
|
||||||
]
|
]
|
||||||
|
|
||||||
[package.dependencies]
|
[package.dependencies]
|
||||||
|
@ -336,7 +361,7 @@ cffi = ">=1.1.0"
|
||||||
|
|
||||||
[package.extras]
|
[package.extras]
|
||||||
doc = ["sphinx", "sphinx_rtd_theme"]
|
doc = ["sphinx", "sphinx_rtd_theme"]
|
||||||
test = ["flake8", "isort", "numpy", "pikepdf", "pytest"]
|
test = ["numpy", "pikepdf", "pytest", "ruff"]
|
||||||
xcb = ["xcffib (>=1.4.0)"]
|
xcb = ["xcffib (>=1.4.0)"]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -766,30 +791,31 @@ smmap = ">=3.0.1,<6"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "gitpython"
|
name = "gitpython"
|
||||||
version = "3.1.42"
|
version = "3.1.43"
|
||||||
description = "GitPython is a Python library used to interact with Git repositories"
|
description = "GitPython is a Python library used to interact with Git repositories"
|
||||||
optional = false
|
optional = false
|
||||||
python-versions = ">=3.7"
|
python-versions = ">=3.7"
|
||||||
files = [
|
files = [
|
||||||
{file = "GitPython-3.1.42-py3-none-any.whl", hash = "sha256:1bf9cd7c9e7255f77778ea54359e54ac22a72a5b51288c457c881057b7bb9ecd"},
|
{file = "GitPython-3.1.43-py3-none-any.whl", hash = "sha256:eec7ec56b92aad751f9912a73404bc02ba212a23adb2c7098ee668417051a1ff"},
|
||||||
{file = "GitPython-3.1.42.tar.gz", hash = "sha256:2d99869e0fef71a73cbd242528105af1d6c1b108c60dfabd994bf292f76c3ceb"},
|
{file = "GitPython-3.1.43.tar.gz", hash = "sha256:35f314a9f878467f5453cc1fee295c3e18e52f1b99f10f6cf5b1682e968a9e7c"},
|
||||||
]
|
]
|
||||||
|
|
||||||
[package.dependencies]
|
[package.dependencies]
|
||||||
gitdb = ">=4.0.1,<5"
|
gitdb = ">=4.0.1,<5"
|
||||||
|
|
||||||
[package.extras]
|
[package.extras]
|
||||||
test = ["black", "coverage[toml]", "ddt (>=1.1.1,!=1.4.3)", "mock", "mypy", "pre-commit", "pytest (>=7.3.1)", "pytest-cov", "pytest-instafail", "pytest-mock", "pytest-sugar"]
|
doc = ["sphinx (==4.3.2)", "sphinx-autodoc-typehints", "sphinx-rtd-theme", "sphinxcontrib-applehelp (>=1.0.2,<=1.0.4)", "sphinxcontrib-devhelp (==1.0.2)", "sphinxcontrib-htmlhelp (>=2.0.0,<=2.0.1)", "sphinxcontrib-qthelp (==1.0.3)", "sphinxcontrib-serializinghtml (==1.1.5)"]
|
||||||
|
test = ["coverage[toml]", "ddt (>=1.1.1,!=1.4.3)", "mock", "mypy", "pre-commit", "pytest (>=7.3.1)", "pytest-cov", "pytest-instafail", "pytest-mock", "pytest-sugar", "typing-extensions"]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "griffe"
|
name = "griffe"
|
||||||
version = "0.42.1"
|
version = "0.44.0"
|
||||||
description = "Signatures for entire Python programs. Extract the structure, the frame, the skeleton of your project, to generate API documentation or find breaking changes in your API."
|
description = "Signatures for entire Python programs. Extract the structure, the frame, the skeleton of your project, to generate API documentation or find breaking changes in your API."
|
||||||
optional = false
|
optional = false
|
||||||
python-versions = ">=3.8"
|
python-versions = ">=3.8"
|
||||||
files = [
|
files = [
|
||||||
{file = "griffe-0.42.1-py3-none-any.whl", hash = "sha256:7e805e35617601355edcac0d3511cedc1ed0cb1f7645e2d336ae4b05bbae7b3b"},
|
{file = "griffe-0.44.0-py3-none-any.whl", hash = "sha256:8a4471c469ba980b87c843f1168850ce39d0c1d0c7be140dca2480f76c8e5446"},
|
||||||
{file = "griffe-0.42.1.tar.gz", hash = "sha256:57046131384043ed078692b85d86b76568a686266cc036b9b56b704466f803ce"},
|
{file = "griffe-0.44.0.tar.gz", hash = "sha256:34aee1571042f9bf00529bc715de4516fb6f482b164e90d030300601009e0223"},
|
||||||
]
|
]
|
||||||
|
|
||||||
[package.dependencies]
|
[package.dependencies]
|
||||||
|
@ -1057,13 +1083,13 @@ pytz = "*"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "mkdocs-material"
|
name = "mkdocs-material"
|
||||||
version = "9.5.15"
|
version = "9.5.18"
|
||||||
description = "Documentation that simply works"
|
description = "Documentation that simply works"
|
||||||
optional = false
|
optional = false
|
||||||
python-versions = ">=3.8"
|
python-versions = ">=3.8"
|
||||||
files = [
|
files = [
|
||||||
{file = "mkdocs_material-9.5.15-py3-none-any.whl", hash = "sha256:e5c96dec3d19491de49ca643fc1dbb92b278e43cdb816c775bc47db77d9b62fb"},
|
{file = "mkdocs_material-9.5.18-py3-none-any.whl", hash = "sha256:1e0e27fc9fe239f9064318acf548771a4629d5fd5dfd45444fd80a953fe21eb4"},
|
||||||
{file = "mkdocs_material-9.5.15.tar.gz", hash = "sha256:39f03cca45e82bf54eb7456b5a18bd252eabfdd67f237a229471484a0a4d4635"},
|
{file = "mkdocs_material-9.5.18.tar.gz", hash = "sha256:a43f470947053fa2405c33995f282d24992c752a50114f23f30da9d8d0c57e62"},
|
||||||
]
|
]
|
||||||
|
|
||||||
[package.dependencies]
|
[package.dependencies]
|
||||||
|
@ -1303,61 +1329,62 @@ files = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "orjson"
|
name = "orjson"
|
||||||
version = "3.9.15"
|
version = "3.10.0"
|
||||||
description = "Fast, correct Python JSON library supporting dataclasses, datetimes, and numpy"
|
description = "Fast, correct Python JSON library supporting dataclasses, datetimes, and numpy"
|
||||||
optional = false
|
optional = false
|
||||||
python-versions = ">=3.8"
|
python-versions = ">=3.8"
|
||||||
files = [
|
files = [
|
||||||
{file = "orjson-3.9.15-cp310-cp310-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:d61f7ce4727a9fa7680cd6f3986b0e2c732639f46a5e0156e550e35258aa313a"},
|
{file = "orjson-3.10.0-cp310-cp310-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:47af5d4b850a2d1328660661f0881b67fdbe712aea905dadd413bdea6f792c33"},
|
||||||
{file = "orjson-3.9.15-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4feeb41882e8aa17634b589533baafdceb387e01e117b1ec65534ec724023d04"},
|
{file = "orjson-3.10.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c90681333619d78360d13840c7235fdaf01b2b129cb3a4f1647783b1971542b6"},
|
||||||
{file = "orjson-3.9.15-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:fbbeb3c9b2edb5fd044b2a070f127a0ac456ffd079cb82746fc84af01ef021a4"},
|
{file = "orjson-3.10.0-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:400c5b7c4222cb27b5059adf1fb12302eebcabf1978f33d0824aa5277ca899bd"},
|
||||||
{file = "orjson-3.9.15-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b66bcc5670e8a6b78f0313bcb74774c8291f6f8aeef10fe70e910b8040f3ab75"},
|
{file = "orjson-3.10.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5dcb32e949eae80fb335e63b90e5808b4b0f64e31476b3777707416b41682db5"},
|
||||||
{file = "orjson-3.9.15-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2973474811db7b35c30248d1129c64fd2bdf40d57d84beed2a9a379a6f57d0ab"},
|
{file = "orjson-3.10.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:aa7d507c7493252c0a0264b5cc7e20fa2f8622b8a83b04d819b5ce32c97cf57b"},
|
||||||
{file = "orjson-3.9.15-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9fe41b6f72f52d3da4db524c8653e46243c8c92df826ab5ffaece2dba9cccd58"},
|
{file = "orjson-3.10.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e286a51def6626f1e0cc134ba2067dcf14f7f4b9550f6dd4535fd9d79000040b"},
|
||||||
{file = "orjson-3.9.15-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:4228aace81781cc9d05a3ec3a6d2673a1ad0d8725b4e915f1089803e9efd2b99"},
|
{file = "orjson-3.10.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:8acd4b82a5f3a3ec8b1dc83452941d22b4711964c34727eb1e65449eead353ca"},
|
||||||
{file = "orjson-3.9.15-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:6f7b65bfaf69493c73423ce9db66cfe9138b2f9ef62897486417a8fcb0a92bfe"},
|
{file = "orjson-3.10.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:30707e646080dd3c791f22ce7e4a2fc2438765408547c10510f1f690bd336217"},
|
||||||
{file = "orjson-3.9.15-cp310-none-win32.whl", hash = "sha256:2d99e3c4c13a7b0fb3792cc04c2829c9db07838fb6973e578b85c1745e7d0ce7"},
|
{file = "orjson-3.10.0-cp310-none-win32.whl", hash = "sha256:115498c4ad34188dcb73464e8dc80e490a3e5e88a925907b6fedcf20e545001a"},
|
||||||
{file = "orjson-3.9.15-cp310-none-win_amd64.whl", hash = "sha256:b725da33e6e58e4a5d27958568484aa766e825e93aa20c26c91168be58e08cbb"},
|
{file = "orjson-3.10.0-cp310-none-win_amd64.whl", hash = "sha256:6735dd4a5a7b6df00a87d1d7a02b84b54d215fb7adac50dd24da5997ffb4798d"},
|
||||||
{file = "orjson-3.9.15-cp311-cp311-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:c8e8fe01e435005d4421f183038fc70ca85d2c1e490f51fb972db92af6e047c2"},
|
{file = "orjson-3.10.0-cp311-cp311-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:9587053e0cefc284e4d1cd113c34468b7d3f17666d22b185ea654f0775316a26"},
|
||||||
{file = "orjson-3.9.15-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:87f1097acb569dde17f246faa268759a71a2cb8c96dd392cd25c668b104cad2f"},
|
{file = "orjson-3.10.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1bef1050b1bdc9ea6c0d08468e3e61c9386723633b397e50b82fda37b3563d72"},
|
||||||
{file = "orjson-3.9.15-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:ff0f9913d82e1d1fadbd976424c316fbc4d9c525c81d047bbdd16bd27dd98cfc"},
|
{file = "orjson-3.10.0-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:d16c6963ddf3b28c0d461641517cd312ad6b3cf303d8b87d5ef3fa59d6844337"},
|
||||||
{file = "orjson-3.9.15-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8055ec598605b0077e29652ccfe9372247474375e0e3f5775c91d9434e12d6b1"},
|
{file = "orjson-3.10.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:4251964db47ef090c462a2d909f16c7c7d5fe68e341dabce6702879ec26d1134"},
|
||||||
{file = "orjson-3.9.15-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d6768a327ea1ba44c9114dba5fdda4a214bdb70129065cd0807eb5f010bfcbb5"},
|
{file = "orjson-3.10.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:73bbbdc43d520204d9ef0817ac03fa49c103c7f9ea94f410d2950755be2c349c"},
|
||||||
{file = "orjson-3.9.15-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:12365576039b1a5a47df01aadb353b68223da413e2e7f98c02403061aad34bde"},
|
{file = "orjson-3.10.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:414e5293b82373606acf0d66313aecb52d9c8c2404b1900683eb32c3d042dbd7"},
|
||||||
{file = "orjson-3.9.15-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:71c6b009d431b3839d7c14c3af86788b3cfac41e969e3e1c22f8a6ea13139404"},
|
{file = "orjson-3.10.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:feaed5bb09877dc27ed0d37f037ddef6cb76d19aa34b108db270d27d3d2ef747"},
|
||||||
{file = "orjson-3.9.15-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:e18668f1bd39e69b7fed19fa7cd1cd110a121ec25439328b5c89934e6d30d357"},
|
{file = "orjson-3.10.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:5127478260db640323cea131ee88541cb1a9fbce051f0b22fa2f0892f44da302"},
|
||||||
{file = "orjson-3.9.15-cp311-none-win32.whl", hash = "sha256:62482873e0289cf7313461009bf62ac8b2e54bc6f00c6fabcde785709231a5d7"},
|
{file = "orjson-3.10.0-cp311-none-win32.whl", hash = "sha256:b98345529bafe3c06c09996b303fc0a21961820d634409b8639bc16bd4f21b63"},
|
||||||
{file = "orjson-3.9.15-cp311-none-win_amd64.whl", hash = "sha256:b3d336ed75d17c7b1af233a6561cf421dee41d9204aa3cfcc6c9c65cd5bb69a8"},
|
{file = "orjson-3.10.0-cp311-none-win_amd64.whl", hash = "sha256:658ca5cee3379dd3d37dbacd43d42c1b4feee99a29d847ef27a1cb18abdfb23f"},
|
||||||
{file = "orjson-3.9.15-cp312-cp312-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:82425dd5c7bd3adfe4e94c78e27e2fa02971750c2b7ffba648b0f5d5cc016a73"},
|
{file = "orjson-3.10.0-cp312-cp312-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:4329c1d24fd130ee377e32a72dc54a3c251e6706fccd9a2ecb91b3606fddd998"},
|
||||||
{file = "orjson-3.9.15-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2c51378d4a8255b2e7c1e5cc430644f0939539deddfa77f6fac7b56a9784160a"},
|
{file = "orjson-3.10.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ef0f19fdfb6553342b1882f438afd53c7cb7aea57894c4490c43e4431739c700"},
|
||||||
{file = "orjson-3.9.15-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:6ae4e06be04dc00618247c4ae3f7c3e561d5bc19ab6941427f6d3722a0875ef7"},
|
{file = "orjson-3.10.0-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:c4f60db24161534764277f798ef53b9d3063092f6d23f8f962b4a97edfa997a0"},
|
||||||
{file = "orjson-3.9.15-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:bcef128f970bb63ecf9a65f7beafd9b55e3aaf0efc271a4154050fc15cdb386e"},
|
{file = "orjson-3.10.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1de3fd5c7b208d836f8ecb4526995f0d5877153a4f6f12f3e9bf11e49357de98"},
|
||||||
{file = "orjson-3.9.15-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b72758f3ffc36ca566ba98a8e7f4f373b6c17c646ff8ad9b21ad10c29186f00d"},
|
{file = "orjson-3.10.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f93e33f67729d460a177ba285002035d3f11425ed3cebac5f6ded4ef36b28344"},
|
||||||
{file = "orjson-3.9.15-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:10c57bc7b946cf2efa67ac55766e41764b66d40cbd9489041e637c1304400494"},
|
{file = "orjson-3.10.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:237ba922aef472761acd697eef77fef4831ab769a42e83c04ac91e9f9e08fa0e"},
|
||||||
{file = "orjson-3.9.15-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:946c3a1ef25338e78107fba746f299f926db408d34553b4754e90a7de1d44068"},
|
{file = "orjson-3.10.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:98c1bfc6a9bec52bc8f0ab9b86cc0874b0299fccef3562b793c1576cf3abb570"},
|
||||||
{file = "orjson-3.9.15-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:2f256d03957075fcb5923410058982aea85455d035607486ccb847f095442bda"},
|
{file = "orjson-3.10.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:30d795a24be16c03dca0c35ca8f9c8eaaa51e3342f2c162d327bd0225118794a"},
|
||||||
{file = "orjson-3.9.15-cp312-none-win_amd64.whl", hash = "sha256:5bb399e1b49db120653a31463b4a7b27cf2fbfe60469546baf681d1b39f4edf2"},
|
{file = "orjson-3.10.0-cp312-none-win32.whl", hash = "sha256:6a3f53dc650bc860eb26ec293dfb489b2f6ae1cbfc409a127b01229980e372f7"},
|
||||||
{file = "orjson-3.9.15-cp38-cp38-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:b17f0f14a9c0ba55ff6279a922d1932e24b13fc218a3e968ecdbf791b3682b25"},
|
{file = "orjson-3.10.0-cp312-none-win_amd64.whl", hash = "sha256:983db1f87c371dc6ffc52931eb75f9fe17dc621273e43ce67bee407d3e5476e9"},
|
||||||
{file = "orjson-3.9.15-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7f6cbd8e6e446fb7e4ed5bac4661a29e43f38aeecbf60c4b900b825a353276a1"},
|
{file = "orjson-3.10.0-cp38-cp38-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:9a667769a96a72ca67237224a36faf57db0c82ab07d09c3aafc6f956196cfa1b"},
|
||||||
{file = "orjson-3.9.15-cp38-cp38-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:76bc6356d07c1d9f4b782813094d0caf1703b729d876ab6a676f3aaa9a47e37c"},
|
{file = "orjson-3.10.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ade1e21dfde1d37feee8cf6464c20a2f41fa46c8bcd5251e761903e46102dc6b"},
|
||||||
{file = "orjson-3.9.15-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:fdfa97090e2d6f73dced247a2f2d8004ac6449df6568f30e7fa1a045767c69a6"},
|
{file = "orjson-3.10.0-cp38-cp38-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:23c12bb4ced1c3308eff7ba5c63ef8f0edb3e4c43c026440247dd6c1c61cea4b"},
|
||||||
{file = "orjson-3.9.15-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:7413070a3e927e4207d00bd65f42d1b780fb0d32d7b1d951f6dc6ade318e1b5a"},
|
{file = "orjson-3.10.0-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b2d014cf8d4dc9f03fc9f870de191a49a03b1bcda51f2a957943fb9fafe55aac"},
|
||||||
{file = "orjson-3.9.15-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9cf1596680ac1f01839dba32d496136bdd5d8ffb858c280fa82bbfeb173bdd40"},
|
{file = "orjson-3.10.0-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:eadecaa16d9783affca33597781328e4981b048615c2ddc31c47a51b833d6319"},
|
||||||
{file = "orjson-3.9.15-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:809d653c155e2cc4fd39ad69c08fdff7f4016c355ae4b88905219d3579e31eb7"},
|
{file = "orjson-3.10.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:cd583341218826f48bd7c6ebf3310b4126216920853cbc471e8dbeaf07b0b80e"},
|
||||||
{file = "orjson-3.9.15-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:920fa5a0c5175ab14b9c78f6f820b75804fb4984423ee4c4f1e6d748f8b22bc1"},
|
{file = "orjson-3.10.0-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:90bfc137c75c31d32308fd61951d424424426ddc39a40e367704661a9ee97095"},
|
||||||
{file = "orjson-3.9.15-cp38-none-win32.whl", hash = "sha256:2b5c0f532905e60cf22a511120e3719b85d9c25d0e1c2a8abb20c4dede3b05a5"},
|
{file = "orjson-3.10.0-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:13b5d3c795b09a466ec9fcf0bd3ad7b85467d91a60113885df7b8d639a9d374b"},
|
||||||
{file = "orjson-3.9.15-cp38-none-win_amd64.whl", hash = "sha256:67384f588f7f8daf040114337d34a5188346e3fae6c38b6a19a2fe8c663a2f9b"},
|
{file = "orjson-3.10.0-cp38-none-win32.whl", hash = "sha256:5d42768db6f2ce0162544845facb7c081e9364a5eb6d2ef06cd17f6050b048d8"},
|
||||||
{file = "orjson-3.9.15-cp39-cp39-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:6fc2fe4647927070df3d93f561d7e588a38865ea0040027662e3e541d592811e"},
|
{file = "orjson-3.10.0-cp38-none-win_amd64.whl", hash = "sha256:33e6655a2542195d6fd9f850b428926559dee382f7a862dae92ca97fea03a5ad"},
|
||||||
{file = "orjson-3.9.15-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:34cbcd216e7af5270f2ffa63a963346845eb71e174ea530867b7443892d77180"},
|
{file = "orjson-3.10.0-cp39-cp39-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:4050920e831a49d8782a1720d3ca2f1c49b150953667eed6e5d63a62e80f46a2"},
|
||||||
{file = "orjson-3.9.15-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:f541587f5c558abd93cb0de491ce99a9ef8d1ae29dd6ab4dbb5a13281ae04cbd"},
|
{file = "orjson-3.10.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1897aa25a944cec774ce4a0e1c8e98fb50523e97366c637b7d0cddabc42e6643"},
|
||||||
{file = "orjson-3.9.15-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:92255879280ef9c3c0bcb327c5a1b8ed694c290d61a6a532458264f887f052cb"},
|
{file = "orjson-3.10.0-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:9bf565a69e0082ea348c5657401acec3cbbb31564d89afebaee884614fba36b4"},
|
||||||
{file = "orjson-3.9.15-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:05a1f57fb601c426635fcae9ddbe90dfc1ed42245eb4c75e4960440cac667262"},
|
{file = "orjson-3.10.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b6ebc17cfbbf741f5c1a888d1854354536f63d84bee537c9a7c0335791bb9009"},
|
||||||
{file = "orjson-3.9.15-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ede0bde16cc6e9b96633df1631fbcd66491d1063667f260a4f2386a098393790"},
|
{file = "orjson-3.10.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d2817877d0b69f78f146ab305c5975d0618df41acf8811249ee64231f5953fee"},
|
||||||
{file = "orjson-3.9.15-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:e88b97ef13910e5f87bcbc4dd7979a7de9ba8702b54d3204ac587e83639c0c2b"},
|
{file = "orjson-3.10.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:57d017863ec8aa4589be30a328dacd13c2dc49de1c170bc8d8c8a98ece0f2925"},
|
||||||
{file = "orjson-3.9.15-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:57d5d8cf9c27f7ef6bc56a5925c7fbc76b61288ab674eb352c26ac780caa5b10"},
|
{file = "orjson-3.10.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:22c2f7e377ac757bd3476ecb7480c8ed79d98ef89648f0176deb1da5cd014eb7"},
|
||||||
{file = "orjson-3.9.15-cp39-none-win32.whl", hash = "sha256:001f4eb0ecd8e9ebd295722d0cbedf0748680fb9998d3993abaed2f40587257a"},
|
{file = "orjson-3.10.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:e62ba42bfe64c60c1bc84799944f80704e996592c6b9e14789c8e2a303279912"},
|
||||||
{file = "orjson-3.9.15-cp39-none-win_amd64.whl", hash = "sha256:ea0b183a5fe6b2b45f3b854b0d19c4e932d6f5934ae1f723b07cf9560edd4ec7"},
|
{file = "orjson-3.10.0-cp39-none-win32.whl", hash = "sha256:60c0b1bdbccd959ebd1575bd0147bd5e10fc76f26216188be4a36b691c937077"},
|
||||||
{file = "orjson-3.9.15.tar.gz", hash = "sha256:95cae920959d772f30ab36d3b25f83bb0f3be671e986c72ce22f8fa700dae061"},
|
{file = "orjson-3.10.0-cp39-none-win_amd64.whl", hash = "sha256:175a41500ebb2fdf320bf78e8b9a75a1279525b62ba400b2b2444e274c2c8bee"},
|
||||||
|
{file = "orjson-3.10.0.tar.gz", hash = "sha256:ba4d8cac5f2e2cff36bea6b6481cdb92b38c202bcec603d6f5ff91960595a1ed"},
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -1478,6 +1505,24 @@ tests = ["check-manifest", "coverage", "defusedxml", "markdown2", "olefile", "pa
|
||||||
typing = ["typing-extensions"]
|
typing = ["typing-extensions"]
|
||||||
xmp = ["defusedxml"]
|
xmp = ["defusedxml"]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "pipx"
|
||||||
|
version = "1.5.0"
|
||||||
|
description = "Install and Run Python Applications in Isolated Environments"
|
||||||
|
optional = false
|
||||||
|
python-versions = ">=3.8"
|
||||||
|
files = [
|
||||||
|
{file = "pipx-1.5.0-py3-none-any.whl", hash = "sha256:801a55a9d58004bb18a464f668508e79fbffc22deb6f07982832d3ce3ff3756d"},
|
||||||
|
{file = "pipx-1.5.0.tar.gz", hash = "sha256:2371af2b772954cdb5c1dbfa0170219e3d2c09d9ff9b18e975f65562eeb7ab0a"},
|
||||||
|
]
|
||||||
|
|
||||||
|
[package.dependencies]
|
||||||
|
argcomplete = ">=1.9.4"
|
||||||
|
colorama = {version = ">=0.4.4", markers = "sys_platform == \"win32\""}
|
||||||
|
packaging = ">=20"
|
||||||
|
platformdirs = ">=2.1"
|
||||||
|
userpath = ">=1.6,<1.9.0 || >1.9.0"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "platformdirs"
|
name = "platformdirs"
|
||||||
version = "4.2.0"
|
version = "4.2.0"
|
||||||
|
@ -1537,15 +1582,125 @@ requests = ">=2.21.0"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "pycparser"
|
name = "pycparser"
|
||||||
version = "2.21"
|
version = "2.22"
|
||||||
description = "C parser in Python"
|
description = "C parser in Python"
|
||||||
optional = false
|
optional = false
|
||||||
python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*"
|
python-versions = ">=3.8"
|
||||||
files = [
|
files = [
|
||||||
{file = "pycparser-2.21-py2.py3-none-any.whl", hash = "sha256:8ee45429555515e1f6b185e78100aea234072576aa43ab53aefcae078162fca9"},
|
{file = "pycparser-2.22-py3-none-any.whl", hash = "sha256:c3702b6d3dd8c7abc1afa565d7e63d53a1d0bd86cdc24edd75470f4de499cfcc"},
|
||||||
{file = "pycparser-2.21.tar.gz", hash = "sha256:e644fdec12f7872f86c58ff790da456218b10f863970249516d60a5eaca77206"},
|
{file = "pycparser-2.22.tar.gz", hash = "sha256:491c8be9c040f5390f5bf44a5b07752bd07f56edf992381b05c701439eec10f6"},
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "pydantic"
|
||||||
|
version = "2.7.1"
|
||||||
|
description = "Data validation using Python type hints"
|
||||||
|
optional = false
|
||||||
|
python-versions = ">=3.8"
|
||||||
|
files = [
|
||||||
|
{file = "pydantic-2.7.1-py3-none-any.whl", hash = "sha256:e029badca45266732a9a79898a15ae2e8b14840b1eabbb25844be28f0b33f3d5"},
|
||||||
|
{file = "pydantic-2.7.1.tar.gz", hash = "sha256:e9dbb5eada8abe4d9ae5f46b9939aead650cd2b68f249bb3a8139dbe125803cc"},
|
||||||
|
]
|
||||||
|
|
||||||
|
[package.dependencies]
|
||||||
|
annotated-types = ">=0.4.0"
|
||||||
|
pydantic-core = "2.18.2"
|
||||||
|
typing-extensions = ">=4.6.1"
|
||||||
|
|
||||||
|
[package.extras]
|
||||||
|
email = ["email-validator (>=2.0.0)"]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "pydantic-core"
|
||||||
|
version = "2.18.2"
|
||||||
|
description = "Core functionality for Pydantic validation and serialization"
|
||||||
|
optional = false
|
||||||
|
python-versions = ">=3.8"
|
||||||
|
files = [
|
||||||
|
{file = "pydantic_core-2.18.2-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:9e08e867b306f525802df7cd16c44ff5ebbe747ff0ca6cf3fde7f36c05a59a81"},
|
||||||
|
{file = "pydantic_core-2.18.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:f0a21cbaa69900cbe1a2e7cad2aa74ac3cf21b10c3efb0fa0b80305274c0e8a2"},
|
||||||
|
{file = "pydantic_core-2.18.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0680b1f1f11fda801397de52c36ce38ef1c1dc841a0927a94f226dea29c3ae3d"},
|
||||||
|
{file = "pydantic_core-2.18.2-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:95b9d5e72481d3780ba3442eac863eae92ae43a5f3adb5b4d0a1de89d42bb250"},
|
||||||
|
{file = "pydantic_core-2.18.2-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c4fcf5cd9c4b655ad666ca332b9a081112cd7a58a8b5a6ca7a3104bc950f2038"},
|
||||||
|
{file = "pydantic_core-2.18.2-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9b5155ff768083cb1d62f3e143b49a8a3432e6789a3abee8acd005c3c7af1c74"},
|
||||||
|
{file = "pydantic_core-2.18.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:553ef617b6836fc7e4df130bb851e32fe357ce36336d897fd6646d6058d980af"},
|
||||||
|
{file = "pydantic_core-2.18.2-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:b89ed9eb7d616ef5714e5590e6cf7f23b02d0d539767d33561e3675d6f9e3857"},
|
||||||
|
{file = "pydantic_core-2.18.2-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:75f7e9488238e920ab6204399ded280dc4c307d034f3924cd7f90a38b1829563"},
|
||||||
|
{file = "pydantic_core-2.18.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:ef26c9e94a8c04a1b2924149a9cb081836913818e55681722d7f29af88fe7b38"},
|
||||||
|
{file = "pydantic_core-2.18.2-cp310-none-win32.whl", hash = "sha256:182245ff6b0039e82b6bb585ed55a64d7c81c560715d1bad0cbad6dfa07b4027"},
|
||||||
|
{file = "pydantic_core-2.18.2-cp310-none-win_amd64.whl", hash = "sha256:e23ec367a948b6d812301afc1b13f8094ab7b2c280af66ef450efc357d2ae543"},
|
||||||
|
{file = "pydantic_core-2.18.2-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:219da3f096d50a157f33645a1cf31c0ad1fe829a92181dd1311022f986e5fbe3"},
|
||||||
|
{file = "pydantic_core-2.18.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:cc1cfd88a64e012b74e94cd00bbe0f9c6df57049c97f02bb07d39e9c852e19a4"},
|
||||||
|
{file = "pydantic_core-2.18.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:05b7133a6e6aeb8df37d6f413f7705a37ab4031597f64ab56384c94d98fa0e90"},
|
||||||
|
{file = "pydantic_core-2.18.2-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:224c421235f6102e8737032483f43c1a8cfb1d2f45740c44166219599358c2cd"},
|
||||||
|
{file = "pydantic_core-2.18.2-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b14d82cdb934e99dda6d9d60dc84a24379820176cc4a0d123f88df319ae9c150"},
|
||||||
|
{file = "pydantic_core-2.18.2-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2728b01246a3bba6de144f9e3115b532ee44bd6cf39795194fb75491824a1413"},
|
||||||
|
{file = "pydantic_core-2.18.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:470b94480bb5ee929f5acba6995251ada5e059a5ef3e0dfc63cca287283ebfa6"},
|
||||||
|
{file = "pydantic_core-2.18.2-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:997abc4df705d1295a42f95b4eec4950a37ad8ae46d913caeee117b6b198811c"},
|
||||||
|
{file = "pydantic_core-2.18.2-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:75250dbc5290e3f1a0f4618db35e51a165186f9034eff158f3d490b3fed9f8a0"},
|
||||||
|
{file = "pydantic_core-2.18.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:4456f2dca97c425231d7315737d45239b2b51a50dc2b6f0c2bb181fce6207664"},
|
||||||
|
{file = "pydantic_core-2.18.2-cp311-none-win32.whl", hash = "sha256:269322dcc3d8bdb69f054681edff86276b2ff972447863cf34c8b860f5188e2e"},
|
||||||
|
{file = "pydantic_core-2.18.2-cp311-none-win_amd64.whl", hash = "sha256:800d60565aec896f25bc3cfa56d2277d52d5182af08162f7954f938c06dc4ee3"},
|
||||||
|
{file = "pydantic_core-2.18.2-cp311-none-win_arm64.whl", hash = "sha256:1404c69d6a676245199767ba4f633cce5f4ad4181f9d0ccb0577e1f66cf4c46d"},
|
||||||
|
{file = "pydantic_core-2.18.2-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:fb2bd7be70c0fe4dfd32c951bc813d9fe6ebcbfdd15a07527796c8204bd36242"},
|
||||||
|
{file = "pydantic_core-2.18.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:6132dd3bd52838acddca05a72aafb6eab6536aa145e923bb50f45e78b7251043"},
|
||||||
|
{file = "pydantic_core-2.18.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d7d904828195733c183d20a54230c0df0eb46ec746ea1a666730787353e87182"},
|
||||||
|
{file = "pydantic_core-2.18.2-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:c9bd70772c720142be1020eac55f8143a34ec9f82d75a8e7a07852023e46617f"},
|
||||||
|
{file = "pydantic_core-2.18.2-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:2b8ed04b3582771764538f7ee7001b02e1170223cf9b75dff0bc698fadb00cf3"},
|
||||||
|
{file = "pydantic_core-2.18.2-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e6dac87ddb34aaec85f873d737e9d06a3555a1cc1a8e0c44b7f8d5daeb89d86f"},
|
||||||
|
{file = "pydantic_core-2.18.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7ca4ae5a27ad7a4ee5170aebce1574b375de390bc01284f87b18d43a3984df72"},
|
||||||
|
{file = "pydantic_core-2.18.2-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:886eec03591b7cf058467a70a87733b35f44707bd86cf64a615584fd72488b7c"},
|
||||||
|
{file = "pydantic_core-2.18.2-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:ca7b0c1f1c983e064caa85f3792dd2fe3526b3505378874afa84baf662e12241"},
|
||||||
|
{file = "pydantic_core-2.18.2-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:4b4356d3538c3649337df4074e81b85f0616b79731fe22dd11b99499b2ebbdf3"},
|
||||||
|
{file = "pydantic_core-2.18.2-cp312-none-win32.whl", hash = "sha256:8b172601454f2d7701121bbec3425dd71efcb787a027edf49724c9cefc14c038"},
|
||||||
|
{file = "pydantic_core-2.18.2-cp312-none-win_amd64.whl", hash = "sha256:b1bd7e47b1558ea872bd16c8502c414f9e90dcf12f1395129d7bb42a09a95438"},
|
||||||
|
{file = "pydantic_core-2.18.2-cp312-none-win_arm64.whl", hash = "sha256:98758d627ff397e752bc339272c14c98199c613f922d4a384ddc07526c86a2ec"},
|
||||||
|
{file = "pydantic_core-2.18.2-cp38-cp38-macosx_10_12_x86_64.whl", hash = "sha256:9fdad8e35f278b2c3eb77cbdc5c0a49dada440657bf738d6905ce106dc1de439"},
|
||||||
|
{file = "pydantic_core-2.18.2-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:1d90c3265ae107f91a4f279f4d6f6f1d4907ac76c6868b27dc7fb33688cfb347"},
|
||||||
|
{file = "pydantic_core-2.18.2-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:390193c770399861d8df9670fb0d1874f330c79caaca4642332df7c682bf6b91"},
|
||||||
|
{file = "pydantic_core-2.18.2-cp38-cp38-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:82d5d4d78e4448683cb467897fe24e2b74bb7b973a541ea1dcfec1d3cbce39fb"},
|
||||||
|
{file = "pydantic_core-2.18.2-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:4774f3184d2ef3e14e8693194f661dea5a4d6ca4e3dc8e39786d33a94865cefd"},
|
||||||
|
{file = "pydantic_core-2.18.2-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d4d938ec0adf5167cb335acb25a4ee69a8107e4984f8fbd2e897021d9e4ca21b"},
|
||||||
|
{file = "pydantic_core-2.18.2-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e0e8b1be28239fc64a88a8189d1df7fad8be8c1ae47fcc33e43d4be15f99cc70"},
|
||||||
|
{file = "pydantic_core-2.18.2-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:868649da93e5a3d5eacc2b5b3b9235c98ccdbfd443832f31e075f54419e1b96b"},
|
||||||
|
{file = "pydantic_core-2.18.2-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:78363590ef93d5d226ba21a90a03ea89a20738ee5b7da83d771d283fd8a56761"},
|
||||||
|
{file = "pydantic_core-2.18.2-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:852e966fbd035a6468fc0a3496589b45e2208ec7ca95c26470a54daed82a0788"},
|
||||||
|
{file = "pydantic_core-2.18.2-cp38-none-win32.whl", hash = "sha256:6a46e22a707e7ad4484ac9ee9f290f9d501df45954184e23fc29408dfad61350"},
|
||||||
|
{file = "pydantic_core-2.18.2-cp38-none-win_amd64.whl", hash = "sha256:d91cb5ea8b11607cc757675051f61b3d93f15eca3cefb3e6c704a5d6e8440f4e"},
|
||||||
|
{file = "pydantic_core-2.18.2-cp39-cp39-macosx_10_12_x86_64.whl", hash = "sha256:ae0a8a797a5e56c053610fa7be147993fe50960fa43609ff2a9552b0e07013e8"},
|
||||||
|
{file = "pydantic_core-2.18.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:042473b6280246b1dbf530559246f6842b56119c2926d1e52b631bdc46075f2a"},
|
||||||
|
{file = "pydantic_core-2.18.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1a388a77e629b9ec814c1b1e6b3b595fe521d2cdc625fcca26fbc2d44c816804"},
|
||||||
|
{file = "pydantic_core-2.18.2-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:e25add29b8f3b233ae90ccef2d902d0ae0432eb0d45370fe315d1a5cf231004b"},
|
||||||
|
{file = "pydantic_core-2.18.2-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f459a5ce8434614dfd39bbebf1041952ae01da6bed9855008cb33b875cb024c0"},
|
||||||
|
{file = "pydantic_core-2.18.2-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:eff2de745698eb46eeb51193a9f41d67d834d50e424aef27df2fcdee1b153845"},
|
||||||
|
{file = "pydantic_core-2.18.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a8309f67285bdfe65c372ea3722b7a5642680f3dba538566340a9d36e920b5f0"},
|
||||||
|
{file = "pydantic_core-2.18.2-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:f93a8a2e3938ff656a7c1bc57193b1319960ac015b6e87d76c76bf14fe0244b4"},
|
||||||
|
{file = "pydantic_core-2.18.2-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:22057013c8c1e272eb8d0eebc796701167d8377441ec894a8fed1af64a0bf399"},
|
||||||
|
{file = "pydantic_core-2.18.2-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:cfeecd1ac6cc1fb2692c3d5110781c965aabd4ec5d32799773ca7b1456ac636b"},
|
||||||
|
{file = "pydantic_core-2.18.2-cp39-none-win32.whl", hash = "sha256:0d69b4c2f6bb3e130dba60d34c0845ba31b69babdd3f78f7c0c8fae5021a253e"},
|
||||||
|
{file = "pydantic_core-2.18.2-cp39-none-win_amd64.whl", hash = "sha256:d9319e499827271b09b4e411905b24a426b8fb69464dfa1696258f53a3334641"},
|
||||||
|
{file = "pydantic_core-2.18.2-pp310-pypy310_pp73-macosx_10_12_x86_64.whl", hash = "sha256:a1874c6dd4113308bd0eb568418e6114b252afe44319ead2b4081e9b9521fe75"},
|
||||||
|
{file = "pydantic_core-2.18.2-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:ccdd111c03bfd3666bd2472b674c6899550e09e9f298954cfc896ab92b5b0e6d"},
|
||||||
|
{file = "pydantic_core-2.18.2-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e18609ceaa6eed63753037fc06ebb16041d17d28199ae5aba0052c51449650a9"},
|
||||||
|
{file = "pydantic_core-2.18.2-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6e5c584d357c4e2baf0ff7baf44f4994be121e16a2c88918a5817331fc7599d7"},
|
||||||
|
{file = "pydantic_core-2.18.2-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:43f0f463cf89ace478de71a318b1b4f05ebc456a9b9300d027b4b57c1a2064fb"},
|
||||||
|
{file = "pydantic_core-2.18.2-pp310-pypy310_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:e1b395e58b10b73b07b7cf740d728dd4ff9365ac46c18751bf8b3d8cca8f625a"},
|
||||||
|
{file = "pydantic_core-2.18.2-pp310-pypy310_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:0098300eebb1c837271d3d1a2cd2911e7c11b396eac9661655ee524a7f10587b"},
|
||||||
|
{file = "pydantic_core-2.18.2-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:36789b70d613fbac0a25bb07ab3d9dba4d2e38af609c020cf4d888d165ee0bf3"},
|
||||||
|
{file = "pydantic_core-2.18.2-pp39-pypy39_pp73-macosx_10_12_x86_64.whl", hash = "sha256:3f9a801e7c8f1ef8718da265bba008fa121243dfe37c1cea17840b0944dfd72c"},
|
||||||
|
{file = "pydantic_core-2.18.2-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:3a6515ebc6e69d85502b4951d89131ca4e036078ea35533bb76327f8424531ce"},
|
||||||
|
{file = "pydantic_core-2.18.2-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:20aca1e2298c56ececfd8ed159ae4dde2df0781988c97ef77d5c16ff4bd5b400"},
|
||||||
|
{file = "pydantic_core-2.18.2-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:223ee893d77a310a0391dca6df00f70bbc2f36a71a895cecd9a0e762dc37b349"},
|
||||||
|
{file = "pydantic_core-2.18.2-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:2334ce8c673ee93a1d6a65bd90327588387ba073c17e61bf19b4fd97d688d63c"},
|
||||||
|
{file = "pydantic_core-2.18.2-pp39-pypy39_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:cbca948f2d14b09d20268cda7b0367723d79063f26c4ffc523af9042cad95592"},
|
||||||
|
{file = "pydantic_core-2.18.2-pp39-pypy39_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:b3ef08e20ec49e02d5c6717a91bb5af9b20f1805583cb0adfe9ba2c6b505b5ae"},
|
||||||
|
{file = "pydantic_core-2.18.2-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:c6fdc8627910eed0c01aed6a390a252fe3ea6d472ee70fdde56273f198938374"},
|
||||||
|
{file = "pydantic_core-2.18.2.tar.gz", hash = "sha256:2e29d20810dfc3043ee13ac7d9e25105799817683348823f305ab3f349b9386e"},
|
||||||
|
]
|
||||||
|
|
||||||
|
[package.dependencies]
|
||||||
|
typing-extensions = ">=4.6.0,<4.7.0 || >4.7.0"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "pygments"
|
name = "pygments"
|
||||||
version = "2.17.2"
|
version = "2.17.2"
|
||||||
|
@ -1587,17 +1742,17 @@ testutils = ["gitpython (>3)"]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "pymdown-extensions"
|
name = "pymdown-extensions"
|
||||||
version = "10.7.1"
|
version = "10.8.1"
|
||||||
description = "Extension pack for Python Markdown."
|
description = "Extension pack for Python Markdown."
|
||||||
optional = false
|
optional = false
|
||||||
python-versions = ">=3.8"
|
python-versions = ">=3.8"
|
||||||
files = [
|
files = [
|
||||||
{file = "pymdown_extensions-10.7.1-py3-none-any.whl", hash = "sha256:f5cc7000d7ff0d1ce9395d216017fa4df3dde800afb1fb72d1c7d3fd35e710f4"},
|
{file = "pymdown_extensions-10.8.1-py3-none-any.whl", hash = "sha256:f938326115884f48c6059c67377c46cf631c733ef3629b6eed1349989d1b30cb"},
|
||||||
{file = "pymdown_extensions-10.7.1.tar.gz", hash = "sha256:c70e146bdd83c744ffc766b4671999796aba18842b268510a329f7f64700d584"},
|
{file = "pymdown_extensions-10.8.1.tar.gz", hash = "sha256:3ab1db5c9e21728dabf75192d71471f8e50f216627e9a1fa9535ecb0231b9940"},
|
||||||
]
|
]
|
||||||
|
|
||||||
[package.dependencies]
|
[package.dependencies]
|
||||||
markdown = ">=3.5"
|
markdown = ">=3.6"
|
||||||
pyyaml = "*"
|
pyyaml = "*"
|
||||||
|
|
||||||
[package.extras]
|
[package.extras]
|
||||||
|
@ -1704,101 +1859,101 @@ pyyaml = "*"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "rapidfuzz"
|
name = "rapidfuzz"
|
||||||
version = "3.6.2"
|
version = "3.7.0"
|
||||||
description = "rapid fuzzy string matching"
|
description = "rapid fuzzy string matching"
|
||||||
optional = false
|
optional = false
|
||||||
python-versions = ">=3.8"
|
python-versions = ">=3.8"
|
||||||
files = [
|
files = [
|
||||||
{file = "rapidfuzz-3.6.2-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:a5637e6bf11b15b5aff6ee818c76bdec99ad208511b78985e6209ba648a6e3ee"},
|
{file = "rapidfuzz-3.7.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:860f438238f1807532aa5c5c25e74c284232ccc115fe84697b78e25d48f364f7"},
|
||||||
{file = "rapidfuzz-3.6.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:380586664f2f63807050ddb95e7702888b4f0b425abf17655940c411f39287ad"},
|
{file = "rapidfuzz-3.7.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:4bb9285abeb0477cdb2f8ea0cf7fd4b5f72ed5a9a7d3f0c0bb4a5239db2fc1ed"},
|
||||||
{file = "rapidfuzz-3.6.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:3168ff565d4b8c239cf11fb604dd2507d30e9bcaac76a4077c0ac23cf2c866ed"},
|
{file = "rapidfuzz-3.7.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:08671280e0c04d2bb3f39511f13cae5914e6690036fd1eefc3d47a47f9fae634"},
|
||||||
{file = "rapidfuzz-3.6.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:be69f7fd46b5c6467fe5e2fd4cff3816b0c03048eed8a4becb9a73e6000960e7"},
|
{file = "rapidfuzz-3.7.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:04bae4d9c16ce1bab6447d196fb8258d98139ed8f9b288a38b84887985e4227b"},
|
||||||
{file = "rapidfuzz-3.6.2-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:cbd5894f23fdf5697499cf759523639838ac822bd1600e343fdce7313baa02ae"},
|
{file = "rapidfuzz-3.7.0-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1efa2268b51b68156fb84d18ca1720311698a58051c4a19c40d670057ce60519"},
|
||||||
{file = "rapidfuzz-3.6.2-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:85a5b6e026393fe39fb61146b9c17c5af66fffbe1410e992c4bb06d9ec327bd3"},
|
{file = "rapidfuzz-3.7.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:600b4d4315f33ec0356c0dab3991a5d5761102420bcff29e0773706aa48936e8"},
|
||||||
{file = "rapidfuzz-3.6.2-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:ab269adfc64480f209e99f253391a10735edd5c09046e04899adab5fb132f20e"},
|
{file = "rapidfuzz-3.7.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:18bc2f13c73d5d34499ff6ada55b052c445d3aa64d22c2639e5ab45472568046"},
|
||||||
{file = "rapidfuzz-3.6.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:35aeac852bca06023d6bbd50c1fc504ca5a9a3613d5e75a140f0be7601fa34ef"},
|
{file = "rapidfuzz-3.7.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8e11c5e6593be41a555475c9c20320342c1f5585d635a064924956944c465ad4"},
|
||||||
{file = "rapidfuzz-3.6.2-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:e706f302c6a3ae0d74edd0d6ace46aee1ae07c563b436ccf5ff04db2b3571e60"},
|
{file = "rapidfuzz-3.7.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:d7878025248b99ccca3285891899373f98548f2ca13835d83619ffc42241c626"},
|
||||||
{file = "rapidfuzz-3.6.2-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:bec353f022011e6e5cd28ccb8700fbd2a33918197af0d4e0abb3c3f4845cc864"},
|
{file = "rapidfuzz-3.7.0-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:b4a7e37fe136022d944374fcd8a2f72b8a19f7b648d2cdfb946667e9ede97f9f"},
|
||||||
{file = "rapidfuzz-3.6.2-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:ef3925daaa93eed20401012e219f569ff0c039ed5bf4ce2d3737b4f75d441622"},
|
{file = "rapidfuzz-3.7.0-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:b5881856f830351aaabd869151124f64a80bf61560546d9588a630a4e933a5de"},
|
||||||
{file = "rapidfuzz-3.6.2-cp310-cp310-musllinux_1_1_s390x.whl", hash = "sha256:6ee98d88ae9ccc77ff61992ed33b2496478def5dc0da55c9a9aa06fcb725a352"},
|
{file = "rapidfuzz-3.7.0-cp310-cp310-musllinux_1_1_s390x.whl", hash = "sha256:c788b11565cc176fab8fab6dfcd469031e906927db94bf7e422afd8ef8f88a5a"},
|
||||||
{file = "rapidfuzz-3.6.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:423c7c588b09d618601097b7a0017dfcb91132a2076bef29023c5f3cd2dc3de1"},
|
{file = "rapidfuzz-3.7.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:9e17a3092e74025d896ef1d67ac236c83494da37a78ef84c712e4e2273c115f1"},
|
||||||
{file = "rapidfuzz-3.6.2-cp310-cp310-win32.whl", hash = "sha256:c17c5efee347a40a6f4c1eec59e3d7d1e22f7613a97f8b8a07733ef723483a04"},
|
{file = "rapidfuzz-3.7.0-cp310-cp310-win32.whl", hash = "sha256:e499c823206c9ffd9d89aa11f813a4babdb9219417d4efe4c8a6f8272da00e98"},
|
||||||
{file = "rapidfuzz-3.6.2-cp310-cp310-win_amd64.whl", hash = "sha256:4209816626d8d6ff8ae7dc248061c6059e618b70c6e6f6e4d7444ae3740b2b85"},
|
{file = "rapidfuzz-3.7.0-cp310-cp310-win_amd64.whl", hash = "sha256:91f798cc00cd94a0def43e9befc6e867c9bd8fa8f882d1eaa40042f528b7e2c7"},
|
||||||
{file = "rapidfuzz-3.6.2-cp310-cp310-win_arm64.whl", hash = "sha256:1c54d3c85e522d3ac9ee39415f183c8fa184c4f87e7e5a37938f15a6d50e853a"},
|
{file = "rapidfuzz-3.7.0-cp310-cp310-win_arm64.whl", hash = "sha256:d5a3872f35bec89f07b993fa1c5401d11b9e68bcdc1b9737494e279308a38a5f"},
|
||||||
{file = "rapidfuzz-3.6.2-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:e06f6d270112f5db001f1cba5a97e1a48aee3d3dbdcbea3ec027c230462dbf9b"},
|
{file = "rapidfuzz-3.7.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:ef6b6ab64c4c91c57a6b58e1d690b59453bfa1f1e9757a7e52e59b4079e36631"},
|
||||||
{file = "rapidfuzz-3.6.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:080cb71b50cb6aff11d1c6aeb157f273e2da0b2bdb3f9d7b01257e49e69a8576"},
|
{file = "rapidfuzz-3.7.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:2f9070b42c0ba030b045bba16a35bdb498a0d6acb0bdb3ff4e325960e685e290"},
|
||||||
{file = "rapidfuzz-3.6.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:a7895e04a22d6515bc91a850e0831f2405547605aa311d1ffec51e4818abc3c1"},
|
{file = "rapidfuzz-3.7.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:63044c63565f50818d885bfcd40ac369947da4197de56b4d6c26408989d48edf"},
|
||||||
{file = "rapidfuzz-3.6.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bd82f9838519136b7083dd1e3149ee80344521f3dc37f744f227505ff0883efb"},
|
{file = "rapidfuzz-3.7.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:49b0c47860c733a3d73a4b70b97b35c8cbf24ef24f8743732f0d1c412a8c85de"},
|
||||||
{file = "rapidfuzz-3.6.2-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a945567c2b0b6e069454c9782d5234b0b6795718adf7a9f868bd3144afa6a023"},
|
{file = "rapidfuzz-3.7.0-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d1b14489b038f007f425a06fcf28ac6313c02cb603b54e3a28d9cfae82198cc0"},
|
||||||
{file = "rapidfuzz-3.6.2-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:673ba2c343644805acdae1cb949c6a4de71aa2f62a998978551ebea59603af3f"},
|
{file = "rapidfuzz-3.7.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:be08f39e397a618aab907887465d7fabc2d1a4d15d1a67cb8b526a7fb5202a3e"},
|
||||||
{file = "rapidfuzz-3.6.2-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9d457c89bac1471442002e70551e8268e639b3870b4a4521eae363c07253be87"},
|
{file = "rapidfuzz-3.7.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:16895dc62a7b92028f9c8b6d22830f1cbc77306ee794f461afc6028e1a8d7539"},
|
||||||
{file = "rapidfuzz-3.6.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:495c0d8e14e6f12520eb7fc71b9ba9fcaafb47fc23a654e6e89b6c7985ec0020"},
|
{file = "rapidfuzz-3.7.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:579cce49dfa57ffd8c8227b3fb53cced54b4df70cec502e63e9799b4d1f44004"},
|
||||||
{file = "rapidfuzz-3.6.2-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:6d67b649bf3e1b1722d04eca44d37919aef88305ce7ad05564502d013cf550fd"},
|
{file = "rapidfuzz-3.7.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:40998c8dc35fdd221790b8b5134a8d7499adbfab9a5dd9ec626c7e92e17a43ed"},
|
||||||
{file = "rapidfuzz-3.6.2-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:e48dde8ca83d11daa00900cf6a5d281a1297aef9b7bfa73801af6e8822be5019"},
|
{file = "rapidfuzz-3.7.0-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:dc3fdb4738a6b83ae27f1d8923b00d3a9c2b5c50da75b9f8b81841839c6e3e1f"},
|
||||||
{file = "rapidfuzz-3.6.2-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:824cc381cf81cbf8d158f6935664ec2a69e6ac3b1d39fa201988bf81a257f775"},
|
{file = "rapidfuzz-3.7.0-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:92b8146fbfb37ac358ef7e0f6b79619e4f793fbbe894b99ea87920f9c0a9d77d"},
|
||||||
{file = "rapidfuzz-3.6.2-cp311-cp311-musllinux_1_1_s390x.whl", hash = "sha256:1dfe4c24957474ce0ac75d886387e30e292b4be39228a6d71f76de414dc187db"},
|
{file = "rapidfuzz-3.7.0-cp311-cp311-musllinux_1_1_s390x.whl", hash = "sha256:1dfceaa7c2914585bb8a043265c39ec09078f13fbf53b5525722fc074306b6fa"},
|
||||||
{file = "rapidfuzz-3.6.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:d57b98013b802621bbc8b12a46bfc9d36ac552ab51ca207f7ce167ad46adabeb"},
|
{file = "rapidfuzz-3.7.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:f332d61f51b0b9c8b55a0fb052b4764b6ad599ea8ce948ac47a4388e9083c35e"},
|
||||||
{file = "rapidfuzz-3.6.2-cp311-cp311-win32.whl", hash = "sha256:9a07dffac439223b4f1025dbfc68f4445a3460a859309c9858c2a3fa29617cdc"},
|
{file = "rapidfuzz-3.7.0-cp311-cp311-win32.whl", hash = "sha256:dfd1e4819f1f3c47141f86159b44b7360ecb19bf675080b3b40437bf97273ab9"},
|
||||||
{file = "rapidfuzz-3.6.2-cp311-cp311-win_amd64.whl", hash = "sha256:95a49c6b8bf1229743ae585dd5b7d57f0d15a7eb6e826866d5c9965ba958503c"},
|
{file = "rapidfuzz-3.7.0-cp311-cp311-win_amd64.whl", hash = "sha256:594b9c33fc1a86784962043ee3fbaaed875fbaadff72e467c2f7a83cd6c5d69d"},
|
||||||
{file = "rapidfuzz-3.6.2-cp311-cp311-win_arm64.whl", hash = "sha256:af7c19ec86e11488539380d3db1755be5d561a3c0e7b04ff9d07abd7f9a8e9d8"},
|
{file = "rapidfuzz-3.7.0-cp311-cp311-win_arm64.whl", hash = "sha256:0b13a6823a1b83ae43f8bf35955df35032bee7bec0daf9b5ab836e0286067434"},
|
||||||
{file = "rapidfuzz-3.6.2-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:de8adc12161bf282c60f12dc9233bb31632f71d446a010fe7469a69b8153427f"},
|
{file = "rapidfuzz-3.7.0-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:075a419a0ec29be44b3d7f4bcfa5cb7e91e419379a85fc05eb33de68315bd96f"},
|
||||||
{file = "rapidfuzz-3.6.2-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:337e357f693130c4c6be740652542b260e36f622c59e01fa33d58f1d2750c930"},
|
{file = "rapidfuzz-3.7.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:51a5b96d2081c3afbef1842a61d63e55d0a5a201473e6975a80190ff2d6f22ca"},
|
||||||
{file = "rapidfuzz-3.6.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:6468f8bc8c3c50604f43631550ef9cfec873515dba5023ca34d461be94669fc8"},
|
{file = "rapidfuzz-3.7.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:a9460d8fddac7ea46dff9298eee9aa950dbfe79f2eb509a9f18fbaefcd10894c"},
|
||||||
{file = "rapidfuzz-3.6.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:74c6773b11445b5e5cf93ca383171cd0ac0cdeafea11a7b2a5688f8bf8d813e6"},
|
{file = "rapidfuzz-3.7.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f39eb1513ee139ba6b5c01fe47ddf2d87e9560dd7fdee1068f7f6efbae70de34"},
|
||||||
{file = "rapidfuzz-3.6.2-cp312-cp312-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e1507fc5769aa109dda4de3a15f822a0f6a03e18d627bd0ba3ddbb253cf70e07"},
|
{file = "rapidfuzz-3.7.0-cp312-cp312-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:eace9fdde58a425d4c9a93021b24a0cac830df167a5b2fc73299e2acf9f41493"},
|
||||||
{file = "rapidfuzz-3.6.2-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:617949a70150e6fffdaed19253dd49f7a53528411dc8bf7663d499ba21e0f61e"},
|
{file = "rapidfuzz-3.7.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:0cc77237242303733de47829028a0a8b6ab9188b23ec9d9ff0a674fdcd3c8e7f"},
|
||||||
{file = "rapidfuzz-3.6.2-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f8b77779174b1b40aa70827692571ab457061897846255ad7d5d559e2edb1932"},
|
{file = "rapidfuzz-3.7.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:74e692357dd324dff691d379ef2c094c9ec526c0ce83ed43a066e4e68fe70bf6"},
|
||||||
{file = "rapidfuzz-3.6.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:80e51b22a7da83f9c87a97e92df07ed0612c74c35496590255f4b5d5b4212dfe"},
|
{file = "rapidfuzz-3.7.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5f2075ac9ee5c15d33d24a1efc8368d095602b5fd9634c5b5f24d83e41903528"},
|
||||||
{file = "rapidfuzz-3.6.2-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:3ae7c86914cb6673e97e187ba431b9c4cf4177d9ae77f8a1e5b2ba9a5628839e"},
|
{file = "rapidfuzz-3.7.0-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:5a8ba64d72329a940ff6c74b721268c2004eecc48558f648a38e96915b5d1c1b"},
|
||||||
{file = "rapidfuzz-3.6.2-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:ddc380ffaa90f204cc9ddcb779114b9ab6f015246d549de9d47871a97ef9f18a"},
|
{file = "rapidfuzz-3.7.0-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:a1f268a2a37cd22573b4a06eccd481c04504b246d3cadc2d8e8dfa64b575636d"},
|
||||||
{file = "rapidfuzz-3.6.2-cp312-cp312-musllinux_1_1_ppc64le.whl", hash = "sha256:3c1dc078ef371fce09f9f3eec2ca4eaa2a8cd412ec53941015b4f39f14d34407"},
|
{file = "rapidfuzz-3.7.0-cp312-cp312-musllinux_1_1_ppc64le.whl", hash = "sha256:42c2e8a2341363c7caf276efdbe1a673fc5267a02568c47c8e980f12e9bc8727"},
|
||||||
{file = "rapidfuzz-3.6.2-cp312-cp312-musllinux_1_1_s390x.whl", hash = "sha256:9a74102fc5a2534fe91f7507838623e1f3a149d8e05648389c42bb42e14b1c3f"},
|
{file = "rapidfuzz-3.7.0-cp312-cp312-musllinux_1_1_s390x.whl", hash = "sha256:a9acca34b34fb895ee6a84c436bb919f3b9cd8f43e7003d43e9573a1d990ff74"},
|
||||||
{file = "rapidfuzz-3.6.2-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:48e1eaea8fcd522fca7f04f0480663f0f0cfb77957092cce60a93f4462864996"},
|
{file = "rapidfuzz-3.7.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:9bad6a0fe3bc1753dacaa6229a8ba7d9844eb7ae24d44d17c5f4c51c91a8a95e"},
|
||||||
{file = "rapidfuzz-3.6.2-cp312-cp312-win32.whl", hash = "sha256:66b008bf2972740cd2dda5d382eb8bdb87265cd88198e71c7797bdc0d1f79d20"},
|
{file = "rapidfuzz-3.7.0-cp312-cp312-win32.whl", hash = "sha256:c86bc4b1d2380739e6485396195e30021df509b4923f3f757914e171587bce7c"},
|
||||||
{file = "rapidfuzz-3.6.2-cp312-cp312-win_amd64.whl", hash = "sha256:87ac3a87f2251ae2e95fc9478ca5c759de6d141d04c84d3fec9f9cdcfc167b33"},
|
{file = "rapidfuzz-3.7.0-cp312-cp312-win_amd64.whl", hash = "sha256:d7361608c8e73a1dc0203a87d151cddebdade0098a047c46da43c469c07df964"},
|
||||||
{file = "rapidfuzz-3.6.2-cp312-cp312-win_arm64.whl", hash = "sha256:b593cc51aed887e93b78c2f94dfae9008be2b23d17afd3b1f1d3eb3913b58f26"},
|
{file = "rapidfuzz-3.7.0-cp312-cp312-win_arm64.whl", hash = "sha256:8fdc26e7863e0f63c2185d53bb61f5173ad4451c1c8287b535b30ea25a419a5a"},
|
||||||
{file = "rapidfuzz-3.6.2-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:7d830bc7a9b586a374147ec60b08b1f9ae5996b43f75cc514f37faef3866b519"},
|
{file = "rapidfuzz-3.7.0-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:9b6167468f76779a14b9af66210f68741af94d32d086f19118de4e919f00585c"},
|
||||||
{file = "rapidfuzz-3.6.2-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:dbee7f5ff11872b76505cbd87c814abc823e8757f11c69062eb3b25130a283da"},
|
{file = "rapidfuzz-3.7.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:5bd394e28ff221557ea4d8152fcec3e66d9f620557feca5f2bedc4c21f8cf2f9"},
|
||||||
{file = "rapidfuzz-3.6.2-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:28c011fb31f2c3f82f503aedd6097d3d3854e574e327a119a3b7eb2cf90b79ca"},
|
{file = "rapidfuzz-3.7.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:8e70f876ca89a6df344f8157ac60384e8c05a0dfb442da2490c3f1c45238ccf5"},
|
||||||
{file = "rapidfuzz-3.6.2-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:cda81d0e0ce0c13abfa46b24e10c1e85f9c6acb628f0a9a948f5779f9c2076a2"},
|
{file = "rapidfuzz-3.7.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7c837f89d86a5affe9ee6574dad6b195475676a6ab171a67920fc99966f2ab2c"},
|
||||||
{file = "rapidfuzz-3.6.2-cp38-cp38-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4c279928651ce0e9e5220dcb25a00cc53b65e592a0861336a38299bcdca3a596"},
|
{file = "rapidfuzz-3.7.0-cp38-cp38-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:cda4550a98658f9a8bcdc03d0498ed1565c1563880e3564603a9eaae28d51b2a"},
|
||||||
{file = "rapidfuzz-3.6.2-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:35bd4bc9c40e6994c5d6edea4b9319388b4d9711c13c66d543bb4c37624b4184"},
|
{file = "rapidfuzz-3.7.0-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ecd70212fd9f1f8b1d3bdd8bcb05acc143defebd41148bdab43e573b043bb241"},
|
||||||
{file = "rapidfuzz-3.6.2-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d07899506a5a8760448d9df036d528b55a554bf571714173635c79eef4a86e58"},
|
{file = "rapidfuzz-3.7.0-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:187db4cc8fb54f8c49c67b7f38ef3a122ce23be273032fa2ff34112a2694c3d8"},
|
||||||
{file = "rapidfuzz-3.6.2-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:eb2e51d01b9c6d6954a3e055c57a80d4685b4fc82719db5519fc153566bcd6bb"},
|
{file = "rapidfuzz-3.7.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4604dfc1098920c4eb6d0c6b5cc7bdd4bf95b48633e790c1d3f100a25870691d"},
|
||||||
{file = "rapidfuzz-3.6.2-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:153d065e353371cc0aeff32b99999a5758266a64e958d1364189367c1c9f6814"},
|
{file = "rapidfuzz-3.7.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:01581b688c5f4f6665b779135e32db0edab1d78028abf914bb91469928efa383"},
|
||||||
{file = "rapidfuzz-3.6.2-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:4edcceebb85ebfa49a3ddcde20ad891d36c08dc0fd592efdab0e7d313a4e36af"},
|
{file = "rapidfuzz-3.7.0-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:0828b55ec8ad084febdf4ab0c942eb1f81c97c0935f1cb0be0b4ea84ce755988"},
|
||||||
{file = "rapidfuzz-3.6.2-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:3549123fca5bb817341025f98e8e49ca99f84596c7c4f92b658f8e5836040d4a"},
|
{file = "rapidfuzz-3.7.0-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:150c98b65faff17b917b9d36bff8a4d37b6173579c6bc2e38ff2044e209d37a4"},
|
||||||
{file = "rapidfuzz-3.6.2-cp38-cp38-musllinux_1_1_s390x.whl", hash = "sha256:84c1032ae42628465b7a5cc35249906061e18a8193c9c27cbd2db54e9823a9a6"},
|
{file = "rapidfuzz-3.7.0-cp38-cp38-musllinux_1_1_s390x.whl", hash = "sha256:7e4eea225d2bff1aff4c85fcc44716596d3699374d99eb5906b7a7560297460e"},
|
||||||
{file = "rapidfuzz-3.6.2-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:9bcc91ebd8fc69a6bd3b5711c8250f5f4e70606b4da75ef415f57ad209978205"},
|
{file = "rapidfuzz-3.7.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:7bc944d7e830cfce0f8b4813875f05904207017b66e25ab7ee757507001310a9"},
|
||||||
{file = "rapidfuzz-3.6.2-cp38-cp38-win32.whl", hash = "sha256:f3a70f341c4c111bad910d2df69c78577a98af140319a996af24c9385939335d"},
|
{file = "rapidfuzz-3.7.0-cp38-cp38-win32.whl", hash = "sha256:3e55f02105c451ab6ff0edaaba57cab1b6c0a0241cfb2b306d4e8e1503adba50"},
|
||||||
{file = "rapidfuzz-3.6.2-cp38-cp38-win_amd64.whl", hash = "sha256:354ad5fe655beb7b279390cb58334903931c5452ecbad1b1666ffb06786498e2"},
|
{file = "rapidfuzz-3.7.0-cp38-cp38-win_amd64.whl", hash = "sha256:41851620d2900791d66d9b6092fc163441d7dd91a460c73b07957ff1c517bc30"},
|
||||||
{file = "rapidfuzz-3.6.2-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:1b86b93d93020c2b3edc1665d75c8855784845fc0a739b312c26c3a4bf0c80d5"},
|
{file = "rapidfuzz-3.7.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:e8041c6b2d339766efe6298fa272f79d6dd799965df364ef4e50f488c101c899"},
|
||||||
{file = "rapidfuzz-3.6.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:28243086ed0e50808bb56632e5442c457241646aeafafd501ac87901f40a3237"},
|
{file = "rapidfuzz-3.7.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:4e09d81008e212fc824ea23603ff5270d75886e72372fa6c7c41c1880bcb57ed"},
|
||||||
{file = "rapidfuzz-3.6.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:ed52461ae5a9ea4c400d38e2649c74a413f1a6d8fb8308b66f1fbd122514732f"},
|
{file = "rapidfuzz-3.7.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:419c8961e861fb5fc5590056c66a279623d1ea27809baea17e00cdc313f1217a"},
|
||||||
{file = "rapidfuzz-3.6.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2a46220f86a5f9cb016af31525e0d0865cad437d02239aa0d8aed2ab8bff1f1c"},
|
{file = "rapidfuzz-3.7.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1522eaab91b9400b3ef16eebe445940a19e70035b5bc5d98aef23d66e9ac1df0"},
|
||||||
{file = "rapidfuzz-3.6.2-cp39-cp39-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:81a630ed2fc3ec5fc7400eb66bab1f87e282b4d47f0abe3e48c6634dfa13b5e4"},
|
{file = "rapidfuzz-3.7.0-cp39-cp39-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:611278ce3136f4544d596af18ab8849827d64372e1d8888d9a8d071bf4a3f44d"},
|
||||||
{file = "rapidfuzz-3.6.2-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d8e5a437b9089df6242a718d9c31ab1742989e9400a0977af012ef483b63b4c2"},
|
{file = "rapidfuzz-3.7.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:4efa9bfc5b955b6474ee077eee154e240441842fa304f280b06e6b6aa58a1d1e"},
|
||||||
{file = "rapidfuzz-3.6.2-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:16270b5529de83b7bae7457e952e4d9cf3fbf029a837dd32d415bb9e0eb8e599"},
|
{file = "rapidfuzz-3.7.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c0cc9d3c8261457af3f8756b1f71a9fdc4892978a9e8b967976d2803e08bf972"},
|
||||||
{file = "rapidfuzz-3.6.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5378c04102c7f084cde30a100154fa6d7e2baf0d51a6bdd2f912545559c1fb35"},
|
{file = "rapidfuzz-3.7.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ce728e2b582fd396bc2559160ee2e391e6a4b5d2e455624044699d96abe8a396"},
|
||||||
{file = "rapidfuzz-3.6.2-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:7f18397c8d6a65fc0b288d2fc29bc7baeea6ba91eeb95163a3cd98f23cd3bc85"},
|
{file = "rapidfuzz-3.7.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:3a6a36c9299e059e0bee3409218bc5235a46570c20fc980cdee5ed21ea6110ad"},
|
||||||
{file = "rapidfuzz-3.6.2-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:2acd2514defce81e6ff4bbff50252d5e7df8e85a731442c4b83e44c86cf1c916"},
|
{file = "rapidfuzz-3.7.0-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:9ea720db8def684c1eb71dadad1f61c9b52f4d979263eb5d443f2b22b0d5430a"},
|
||||||
{file = "rapidfuzz-3.6.2-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:1df2faf80201952e252413b6fac6f3e146080dcebb87bb1bb722508e67558ed8"},
|
{file = "rapidfuzz-3.7.0-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:358692f1df3f8aebcd48e69c77c948c9283b44c0efbaf1eeea01739efe3cd9a6"},
|
||||||
{file = "rapidfuzz-3.6.2-cp39-cp39-musllinux_1_1_s390x.whl", hash = "sha256:6440ed0b3007c1c9286b0b88fe2ab2d9e83edd60cd62293b3dfabb732b4e8a30"},
|
{file = "rapidfuzz-3.7.0-cp39-cp39-musllinux_1_1_s390x.whl", hash = "sha256:faded69ffe79adcefa8da08f414a0fd52375e2b47f57be79471691dad9656b5a"},
|
||||||
{file = "rapidfuzz-3.6.2-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:4fcfa23b5553b27f4016df77c53172ea743454cf12c28cfa7c35a309a2be93b3"},
|
{file = "rapidfuzz-3.7.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:7f9f3dc14fadbd553975f824ac48c381f42192cec9d7e5711b528357662a8d8e"},
|
||||||
{file = "rapidfuzz-3.6.2-cp39-cp39-win32.whl", hash = "sha256:2d580d937146e803c8e5e1b87916cab8d6f84013b6392713e201efcda335c7d8"},
|
{file = "rapidfuzz-3.7.0-cp39-cp39-win32.whl", hash = "sha256:7be5f460ff42d7d27729115bfe8a02e83fa0284536d8630ee900d17b75c29e65"},
|
||||||
{file = "rapidfuzz-3.6.2-cp39-cp39-win_amd64.whl", hash = "sha256:fe2a68be734e8e88af23385c68d6467e15818b6b1df1cbfebf7bff577226c957"},
|
{file = "rapidfuzz-3.7.0-cp39-cp39-win_amd64.whl", hash = "sha256:dd5ad2c12dab2b98340c4b7b9592c8f349730bda9a2e49675ea592bbcbc1360b"},
|
||||||
{file = "rapidfuzz-3.6.2-cp39-cp39-win_arm64.whl", hash = "sha256:6478f7803efebf5f644d0b758439c5b25728550fdfbb19783d150004c46a75a9"},
|
{file = "rapidfuzz-3.7.0-cp39-cp39-win_arm64.whl", hash = "sha256:aa163257a0ac4e70f9009d25e5030bdd83a8541dfa3ba78dc86b35c9e16a80b4"},
|
||||||
{file = "rapidfuzz-3.6.2-pp38-pypy38_pp73-macosx_10_9_x86_64.whl", hash = "sha256:36ce7b68a7b90b787cdd73480a68d2f1ca63c31a3a9d5a79a8736f978e1e9344"},
|
{file = "rapidfuzz-3.7.0-pp38-pypy38_pp73-macosx_10_9_x86_64.whl", hash = "sha256:4e50840a8a8e0229563eeaf22e21a203359859557db8829f4d0285c17126c5fb"},
|
||||||
{file = "rapidfuzz-3.6.2-pp38-pypy38_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:53597fd72a9340bcdd80d3620f4957c2b92f9b569313b969a3abdaffd193aae6"},
|
{file = "rapidfuzz-3.7.0-pp38-pypy38_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:632f09e19365ace5ff2670008adc8bf23d03d668b03a30230e5b60ff9317ee93"},
|
||||||
{file = "rapidfuzz-3.6.2-pp38-pypy38_pp73-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d4f6de745fe6ce46a422d353ee10599013631d7d714a36d025f164b2d4e8c000"},
|
{file = "rapidfuzz-3.7.0-pp38-pypy38_pp73-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:209dda6ae66b702f74a78cef555397cdc2a83d7f48771774a20d2fc30808b28c"},
|
||||||
{file = "rapidfuzz-3.6.2-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:62df2136068e2515ed8beb01756381ff62c29384d785e3bf46e3111d4ea3ba1e"},
|
{file = "rapidfuzz-3.7.0-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2bc0b78572626af6ab134895e4dbfe4f4d615d18dcc43b8d902d8e45471aabba"},
|
||||||
{file = "rapidfuzz-3.6.2-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:7382c90170f60c846c81a07ddd80bb2e8c43c8383754486fa37f67391a571897"},
|
{file = "rapidfuzz-3.7.0-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:7ba14850cc8258b3764ea16b8a4409ac2ba16d229bde7a5f495dd479cd9ccd56"},
|
||||||
{file = "rapidfuzz-3.6.2-pp39-pypy39_pp73-macosx_10_9_x86_64.whl", hash = "sha256:f31314fd2e2f3dc3e519e6f93669462ce7953df2def1c344aa8f5345976d0eb2"},
|
{file = "rapidfuzz-3.7.0-pp39-pypy39_pp73-macosx_10_9_x86_64.whl", hash = "sha256:b917764fd2b267addc9d03a96d26f751f6117a95f617428c44a069057653b528"},
|
||||||
{file = "rapidfuzz-3.6.2-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:012221629d54d3bee954148247f711eb86d4d390b589ebfe03172ea0b37a7531"},
|
{file = "rapidfuzz-3.7.0-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1252ca156e1b053e84e5ae1c8e9e062ee80468faf23aa5c543708212a42795fd"},
|
||||||
{file = "rapidfuzz-3.6.2-pp39-pypy39_pp73-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d41dd59a70decfce6595315367a2fea2af660d92a9d144acc6479030501014d7"},
|
{file = "rapidfuzz-3.7.0-pp39-pypy39_pp73-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:86c7676a32d7524e40bc73546e511a408bc831ae5b163029d325ea3a2027d089"},
|
||||||
{file = "rapidfuzz-3.6.2-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7f9fa14136a5b0cba1ec42531f7c3e0b0d3edb7fd6bc5e5ae7b498541f3855ab"},
|
{file = "rapidfuzz-3.7.0-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:20e7d729af2e5abb29caa070ec048aba042f134091923d9ca2ac662b5604577e"},
|
||||||
{file = "rapidfuzz-3.6.2-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:259364199cbfeca33b1af369fc7951f71717aa285184a3fa5a7b1772da1b89db"},
|
{file = "rapidfuzz-3.7.0-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:86eea3e6c314a9238de568254a9c591ec73c2985f125675ed5f171d869c47773"},
|
||||||
{file = "rapidfuzz-3.6.2.tar.gz", hash = "sha256:cf911e792ab0c431694c9bf2648afabfd92099103f2e31492893e078ddca5e1a"},
|
{file = "rapidfuzz-3.7.0.tar.gz", hash = "sha256:620df112c39c6d27316dc1e22046dc0382d6d91fd60d7c51bd41ca0333d867e9"},
|
||||||
]
|
]
|
||||||
|
|
||||||
[package.extras]
|
[package.extras]
|
||||||
|
@ -1820,13 +1975,13 @@ dev = ["black (==22.1.0)", "flake8 (==4.0.1)", "isort (==5.10.1)"]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "red-discordbot"
|
name = "red-discordbot"
|
||||||
version = "3.5.7"
|
version = "3.5.9"
|
||||||
description = "A highly customisable Discord bot"
|
description = "A highly customisable Discord bot"
|
||||||
optional = false
|
optional = false
|
||||||
python-versions = "<3.12,>=3.8.1"
|
python-versions = "<3.12,>=3.8.1"
|
||||||
files = [
|
files = [
|
||||||
{file = "Red-DiscordBot-3.5.7.tar.gz", hash = "sha256:7673ea794016b6d3d7b96eb07a46cd92c52974e15b3a6ad95608df69dc320838"},
|
{file = "Red_DiscordBot-3.5.9-py3-none-any.whl", hash = "sha256:d392c4947f95151435792e99cc74afb7c440b11fb516fa59927f5e462c61385f"},
|
||||||
{file = "Red_DiscordBot-3.5.7-py3-none-any.whl", hash = "sha256:3b9df02cd8efd35170c9505e3f0a8c9b1bd415bcc2ca451a19733d28b1b3a5b4"},
|
{file = "red_discordbot-3.5.9.tar.gz", hash = "sha256:1f50e508b6923868ea4d7bb0eb80a2b1dbdeae248cf0a57717539ca6f5c5874f"},
|
||||||
]
|
]
|
||||||
|
|
||||||
[package.dependencies]
|
[package.dependencies]
|
||||||
|
@ -1848,14 +2003,14 @@ markdown = "3.6"
|
||||||
markdown-it-py = "3.0.0"
|
markdown-it-py = "3.0.0"
|
||||||
mdurl = "0.1.2"
|
mdurl = "0.1.2"
|
||||||
multidict = "6.0.5"
|
multidict = "6.0.5"
|
||||||
orjson = "3.9.15"
|
orjson = "3.10.0"
|
||||||
packaging = "24.0"
|
packaging = "24.0"
|
||||||
platformdirs = "4.2.0"
|
platformdirs = "4.2.0"
|
||||||
psutil = "5.9.8"
|
psutil = "5.9.8"
|
||||||
pygments = "2.17.2"
|
pygments = "2.17.2"
|
||||||
python-dateutil = "2.9.0.post0"
|
python-dateutil = "2.9.0.post0"
|
||||||
pyyaml = "6.0.1"
|
pyyaml = "6.0.1"
|
||||||
rapidfuzz = "3.6.2"
|
rapidfuzz = "3.7.0"
|
||||||
red-commons = "1.0.0"
|
red-commons = "1.0.0"
|
||||||
red-lavalink = "0.11.0"
|
red-lavalink = "0.11.0"
|
||||||
rich = "13.7.1"
|
rich = "13.7.1"
|
||||||
|
@ -1867,11 +2022,11 @@ yarl = "1.9.4"
|
||||||
|
|
||||||
[package.extras]
|
[package.extras]
|
||||||
all = ["async-timeout (==4.0.3)", "asyncpg (==0.29.0)"]
|
all = ["async-timeout (==4.0.3)", "asyncpg (==0.29.0)"]
|
||||||
dev = ["alabaster (==0.7.13)", "astroid (==3.1.0)", "async-timeout (==4.0.3)", "asyncpg (==0.29.0)", "black (==23.12.1)", "certifi (==2024.2.2)", "charset-normalizer (==3.3.2)", "dill (==0.3.8)", "docutils (==0.20.1)", "exceptiongroup (==1.2.0)", "imagesize (==1.4.1)", "importlib-metadata (==7.1.0)", "iniconfig (==2.0.0)", "isort (==5.13.2)", "jinja2 (==3.1.3)", "markupsafe (==2.1.5)", "mccabe (==0.7.0)", "mypy-extensions (==1.0.0)", "pathspec (==0.12.1)", "pluggy (==1.4.0)", "pylint (==3.1.0)", "pytest (==7.4.4)", "pytest-asyncio (==0.21.1)", "pytest-mock (==3.12.0)", "pytz (==2024.1)", "requests (==2.31.0)", "snowballstemmer (==2.2.0)", "sphinx (==7.1.2)", "sphinx-prompt (==1.7.0)", "sphinx-rtd-theme (==2.0.0)", "sphinxcontrib-applehelp (==1.0.4)", "sphinxcontrib-devhelp (==1.0.2)", "sphinxcontrib-htmlhelp (==2.0.1)", "sphinxcontrib-jquery (==4.1)", "sphinxcontrib-jsmath (==1.0.1)", "sphinxcontrib-qthelp (==1.0.3)", "sphinxcontrib-serializinghtml (==1.1.5)", "sphinxcontrib-trio (==1.1.2)", "tomli (==2.0.1)", "tomli (==2.0.1)", "tomlkit (==0.12.4)", "urllib3 (==2.2.1)", "zipp (==3.18.1)"]
|
dev = ["alabaster (==0.7.13)", "astroid (==3.1.0)", "async-timeout (==4.0.3)", "asyncpg (==0.29.0)", "black (==23.12.1)", "certifi (==2024.2.2)", "charset-normalizer (==3.3.2)", "dill (==0.3.8)", "docutils (==0.20.1)", "exceptiongroup (==1.2.0)", "imagesize (==1.4.1)", "importlib-metadata (==7.1.0)", "iniconfig (==2.0.0)", "isort (==5.13.2)", "jinja2 (==3.1.3)", "markupsafe (==2.1.5)", "mccabe (==0.7.0)", "mypy-extensions (==1.0.0)", "pathspec (==0.12.1)", "pluggy (==1.4.0)", "pylint (==3.1.0)", "pytest (==7.4.4)", "pytest-asyncio (==0.21.1)", "pytest-mock (==3.14.0)", "pytz (==2024.1)", "requests (==2.31.0)", "snowballstemmer (==2.2.0)", "sphinx (==7.1.2)", "sphinx-prompt (==1.7.0)", "sphinx-rtd-theme (==2.0.0)", "sphinxcontrib-applehelp (==1.0.4)", "sphinxcontrib-devhelp (==1.0.2)", "sphinxcontrib-htmlhelp (==2.0.1)", "sphinxcontrib-jquery (==4.1)", "sphinxcontrib-jsmath (==1.0.1)", "sphinxcontrib-qthelp (==1.0.3)", "sphinxcontrib-serializinghtml (==1.1.5)", "sphinxcontrib-trio (==1.1.2)", "tomli (==2.0.1)", "tomli (==2.0.1)", "tomlkit (==0.12.4)", "urllib3 (==2.2.1)", "zipp (==3.18.1)"]
|
||||||
doc = ["alabaster (==0.7.13)", "certifi (==2024.2.2)", "charset-normalizer (==3.3.2)", "docutils (==0.20.1)", "imagesize (==1.4.1)", "importlib-metadata (==7.1.0)", "jinja2 (==3.1.3)", "markupsafe (==2.1.5)", "pytz (==2024.1)", "requests (==2.31.0)", "snowballstemmer (==2.2.0)", "sphinx (==7.1.2)", "sphinx-prompt (==1.7.0)", "sphinx-rtd-theme (==2.0.0)", "sphinxcontrib-applehelp (==1.0.4)", "sphinxcontrib-devhelp (==1.0.2)", "sphinxcontrib-htmlhelp (==2.0.1)", "sphinxcontrib-jquery (==4.1)", "sphinxcontrib-jsmath (==1.0.1)", "sphinxcontrib-qthelp (==1.0.3)", "sphinxcontrib-serializinghtml (==1.1.5)", "sphinxcontrib-trio (==1.1.2)", "urllib3 (==2.2.1)", "zipp (==3.18.1)"]
|
doc = ["alabaster (==0.7.13)", "certifi (==2024.2.2)", "charset-normalizer (==3.3.2)", "docutils (==0.20.1)", "imagesize (==1.4.1)", "importlib-metadata (==7.1.0)", "jinja2 (==3.1.3)", "markupsafe (==2.1.5)", "pytz (==2024.1)", "requests (==2.31.0)", "snowballstemmer (==2.2.0)", "sphinx (==7.1.2)", "sphinx-prompt (==1.7.0)", "sphinx-rtd-theme (==2.0.0)", "sphinxcontrib-applehelp (==1.0.4)", "sphinxcontrib-devhelp (==1.0.2)", "sphinxcontrib-htmlhelp (==2.0.1)", "sphinxcontrib-jquery (==4.1)", "sphinxcontrib-jsmath (==1.0.1)", "sphinxcontrib-qthelp (==1.0.3)", "sphinxcontrib-serializinghtml (==1.1.5)", "sphinxcontrib-trio (==1.1.2)", "urllib3 (==2.2.1)", "zipp (==3.18.1)"]
|
||||||
postgres = ["async-timeout (==4.0.3)", "asyncpg (==0.29.0)"]
|
postgres = ["async-timeout (==4.0.3)", "asyncpg (==0.29.0)"]
|
||||||
style = ["black (==23.12.1)", "mypy-extensions (==1.0.0)", "pathspec (==0.12.1)", "tomli (==2.0.1)"]
|
style = ["black (==23.12.1)", "mypy-extensions (==1.0.0)", "pathspec (==0.12.1)", "tomli (==2.0.1)"]
|
||||||
test = ["astroid (==3.1.0)", "dill (==0.3.8)", "exceptiongroup (==1.2.0)", "iniconfig (==2.0.0)", "isort (==5.13.2)", "mccabe (==0.7.0)", "pluggy (==1.4.0)", "pylint (==3.1.0)", "pytest (==7.4.4)", "pytest-asyncio (==0.21.1)", "pytest-mock (==3.12.0)", "tomli (==2.0.1)", "tomlkit (==0.12.4)"]
|
test = ["astroid (==3.1.0)", "dill (==0.3.8)", "exceptiongroup (==1.2.0)", "iniconfig (==2.0.0)", "isort (==5.13.2)", "mccabe (==0.7.0)", "pluggy (==1.4.0)", "pylint (==3.1.0)", "pytest (==7.4.4)", "pytest-asyncio (==0.21.1)", "pytest-mock (==3.14.0)", "tomli (==2.0.1)", "tomlkit (==0.12.4)"]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "red-lavalink"
|
name = "red-lavalink"
|
||||||
|
@ -1895,104 +2050,90 @@ test = ["pytest (>=7)", "pytest-asyncio (>=0.19)"]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "regex"
|
name = "regex"
|
||||||
version = "2023.12.25"
|
version = "2024.4.28"
|
||||||
description = "Alternative regular expression module, to replace re."
|
description = "Alternative regular expression module, to replace re."
|
||||||
optional = false
|
optional = false
|
||||||
python-versions = ">=3.7"
|
python-versions = ">=3.8"
|
||||||
files = [
|
files = [
|
||||||
{file = "regex-2023.12.25-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:0694219a1d54336fd0445ea382d49d36882415c0134ee1e8332afd1529f0baa5"},
|
{file = "regex-2024.4.28-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:cd196d056b40af073d95a2879678585f0b74ad35190fac04ca67954c582c6b61"},
|
||||||
{file = "regex-2023.12.25-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:b014333bd0217ad3d54c143de9d4b9a3ca1c5a29a6d0d554952ea071cff0f1f8"},
|
{file = "regex-2024.4.28-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:8bb381f777351bd534462f63e1c6afb10a7caa9fa2a421ae22c26e796fe31b1f"},
|
||||||
{file = "regex-2023.12.25-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:d865984b3f71f6d0af64d0d88f5733521698f6c16f445bb09ce746c92c97c586"},
|
{file = "regex-2024.4.28-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:47af45b6153522733aa6e92543938e97a70ce0900649ba626cf5aad290b737b6"},
|
||||||
{file = "regex-2023.12.25-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1e0eabac536b4cc7f57a5f3d095bfa557860ab912f25965e08fe1545e2ed8b4c"},
|
{file = "regex-2024.4.28-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:99d6a550425cc51c656331af0e2b1651e90eaaa23fb4acde577cf15068e2e20f"},
|
||||||
{file = "regex-2023.12.25-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c25a8ad70e716f96e13a637802813f65d8a6760ef48672aa3502f4c24ea8b400"},
|
{file = "regex-2024.4.28-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:bf29304a8011feb58913c382902fde3395957a47645bf848eea695839aa101b7"},
|
||||||
{file = "regex-2023.12.25-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a9b6d73353f777630626f403b0652055ebfe8ff142a44ec2cf18ae470395766e"},
|
{file = "regex-2024.4.28-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:92da587eee39a52c91aebea8b850e4e4f095fe5928d415cb7ed656b3460ae79a"},
|
||||||
{file = "regex-2023.12.25-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a9cc99d6946d750eb75827cb53c4371b8b0fe89c733a94b1573c9dd16ea6c9e4"},
|
{file = "regex-2024.4.28-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6277d426e2f31bdbacb377d17a7475e32b2d7d1f02faaecc48d8e370c6a3ff31"},
|
||||||
{file = "regex-2023.12.25-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:88d1f7bef20c721359d8675f7d9f8e414ec5003d8f642fdfd8087777ff7f94b5"},
|
{file = "regex-2024.4.28-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:28e1f28d07220c0f3da0e8fcd5a115bbb53f8b55cecf9bec0c946eb9a059a94c"},
|
||||||
{file = "regex-2023.12.25-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:cb3fe77aec8f1995611f966d0c656fdce398317f850d0e6e7aebdfe61f40e1cd"},
|
{file = "regex-2024.4.28-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:aaa179975a64790c1f2701ac562b5eeb733946eeb036b5bcca05c8d928a62f10"},
|
||||||
{file = "regex-2023.12.25-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:7aa47c2e9ea33a4a2a05f40fcd3ea36d73853a2aae7b4feab6fc85f8bf2c9704"},
|
{file = "regex-2024.4.28-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:6f435946b7bf7a1b438b4e6b149b947c837cb23c704e780c19ba3e6855dbbdd3"},
|
||||||
{file = "regex-2023.12.25-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:df26481f0c7a3f8739fecb3e81bc9da3fcfae34d6c094563b9d4670b047312e1"},
|
{file = "regex-2024.4.28-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:19d6c11bf35a6ad077eb23852827f91c804eeb71ecb85db4ee1386825b9dc4db"},
|
||||||
{file = "regex-2023.12.25-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:c40281f7d70baf6e0db0c2f7472b31609f5bc2748fe7275ea65a0b4601d9b392"},
|
{file = "regex-2024.4.28-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:fdae0120cddc839eb8e3c15faa8ad541cc6d906d3eb24d82fb041cfe2807bc1e"},
|
||||||
{file = "regex-2023.12.25-cp310-cp310-musllinux_1_1_s390x.whl", hash = "sha256:d94a1db462d5690ebf6ae86d11c5e420042b9898af5dcf278bd97d6bda065423"},
|
{file = "regex-2024.4.28-cp310-cp310-musllinux_1_1_s390x.whl", hash = "sha256:e672cf9caaf669053121f1766d659a8813bd547edef6e009205378faf45c67b8"},
|
||||||
{file = "regex-2023.12.25-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:ba1b30765a55acf15dce3f364e4928b80858fa8f979ad41f862358939bdd1f2f"},
|
{file = "regex-2024.4.28-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:f57515750d07e14743db55d59759893fdb21d2668f39e549a7d6cad5d70f9fea"},
|
||||||
{file = "regex-2023.12.25-cp310-cp310-win32.whl", hash = "sha256:150c39f5b964e4d7dba46a7962a088fbc91f06e606f023ce57bb347a3b2d4630"},
|
{file = "regex-2024.4.28-cp310-cp310-win32.whl", hash = "sha256:a1409c4eccb6981c7baabc8888d3550df518add6e06fe74fa1d9312c1838652d"},
|
||||||
{file = "regex-2023.12.25-cp310-cp310-win_amd64.whl", hash = "sha256:09da66917262d9481c719599116c7dc0c321ffcec4b1f510c4f8a066f8768105"},
|
{file = "regex-2024.4.28-cp310-cp310-win_amd64.whl", hash = "sha256:1f687a28640f763f23f8a9801fe9e1b37338bb1ca5d564ddd41619458f1f22d1"},
|
||||||
{file = "regex-2023.12.25-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:1b9d811f72210fa9306aeb88385b8f8bcef0dfbf3873410413c00aa94c56c2b6"},
|
{file = "regex-2024.4.28-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:84077821c85f222362b72fdc44f7a3a13587a013a45cf14534df1cbbdc9a6796"},
|
||||||
{file = "regex-2023.12.25-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:d902a43085a308cef32c0d3aea962524b725403fd9373dea18110904003bac97"},
|
{file = "regex-2024.4.28-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:b45d4503de8f4f3dc02f1d28a9b039e5504a02cc18906cfe744c11def942e9eb"},
|
||||||
{file = "regex-2023.12.25-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:d166eafc19f4718df38887b2bbe1467a4f74a9830e8605089ea7a30dd4da8887"},
|
{file = "regex-2024.4.28-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:457c2cd5a646dd4ed536c92b535d73548fb8e216ebee602aa9f48e068fc393f3"},
|
||||||
{file = "regex-2023.12.25-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c7ad32824b7f02bb3c9f80306d405a1d9b7bb89362d68b3c5a9be53836caebdb"},
|
{file = "regex-2024.4.28-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2b51739ddfd013c6f657b55a508de8b9ea78b56d22b236052c3a85a675102dc6"},
|
||||||
{file = "regex-2023.12.25-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:636ba0a77de609d6510235b7f0e77ec494d2657108f777e8765efc060094c98c"},
|
{file = "regex-2024.4.28-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:459226445c7d7454981c4c0ce0ad1a72e1e751c3e417f305722bbcee6697e06a"},
|
||||||
{file = "regex-2023.12.25-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:0fda75704357805eb953a3ee15a2b240694a9a514548cd49b3c5124b4e2ad01b"},
|
{file = "regex-2024.4.28-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:670fa596984b08a4a769491cbdf22350431970d0112e03d7e4eeaecaafcd0fec"},
|
||||||
{file = "regex-2023.12.25-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f72cbae7f6b01591f90814250e636065850c5926751af02bb48da94dfced7baa"},
|
{file = "regex-2024.4.28-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fe00f4fe11c8a521b173e6324d862ee7ee3412bf7107570c9b564fe1119b56fb"},
|
||||||
{file = "regex-2023.12.25-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:db2a0b1857f18b11e3b0e54ddfefc96af46b0896fb678c85f63fb8c37518b3e7"},
|
{file = "regex-2024.4.28-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:36f392dc7763fe7924575475736bddf9ab9f7a66b920932d0ea50c2ded2f5636"},
|
||||||
{file = "regex-2023.12.25-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:7502534e55c7c36c0978c91ba6f61703faf7ce733715ca48f499d3dbbd7657e0"},
|
{file = "regex-2024.4.28-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:23a412b7b1a7063f81a742463f38821097b6a37ce1e5b89dd8e871d14dbfd86b"},
|
||||||
{file = "regex-2023.12.25-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:e8c7e08bb566de4faaf11984af13f6bcf6a08f327b13631d41d62592681d24fe"},
|
{file = "regex-2024.4.28-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:f1d6e4b7b2ae3a6a9df53efbf199e4bfcff0959dbdb5fd9ced34d4407348e39a"},
|
||||||
{file = "regex-2023.12.25-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:283fc8eed679758de38fe493b7d7d84a198b558942b03f017b1f94dda8efae80"},
|
{file = "regex-2024.4.28-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:499334ad139557de97cbc4347ee921c0e2b5e9c0f009859e74f3f77918339257"},
|
||||||
{file = "regex-2023.12.25-cp311-cp311-musllinux_1_1_s390x.whl", hash = "sha256:f44dd4d68697559d007462b0a3a1d9acd61d97072b71f6d1968daef26bc744bd"},
|
{file = "regex-2024.4.28-cp311-cp311-musllinux_1_1_s390x.whl", hash = "sha256:0940038bec2fe9e26b203d636c44d31dd8766abc1fe66262da6484bd82461ccf"},
|
||||||
{file = "regex-2023.12.25-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:67d3ccfc590e5e7197750fcb3a2915b416a53e2de847a728cfa60141054123d4"},
|
{file = "regex-2024.4.28-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:66372c2a01782c5fe8e04bff4a2a0121a9897e19223d9eab30c54c50b2ebeb7f"},
|
||||||
{file = "regex-2023.12.25-cp311-cp311-win32.whl", hash = "sha256:68191f80a9bad283432385961d9efe09d783bcd36ed35a60fb1ff3f1ec2efe87"},
|
{file = "regex-2024.4.28-cp311-cp311-win32.whl", hash = "sha256:c77d10ec3c1cf328b2f501ca32583625987ea0f23a0c2a49b37a39ee5c4c4630"},
|
||||||
{file = "regex-2023.12.25-cp311-cp311-win_amd64.whl", hash = "sha256:7d2af3f6b8419661a0c421584cfe8aaec1c0e435ce7e47ee2a97e344b98f794f"},
|
{file = "regex-2024.4.28-cp311-cp311-win_amd64.whl", hash = "sha256:fc0916c4295c64d6890a46e02d4482bb5ccf33bf1a824c0eaa9e83b148291f90"},
|
||||||
{file = "regex-2023.12.25-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:8a0ccf52bb37d1a700375a6b395bff5dd15c50acb745f7db30415bae3c2b0715"},
|
{file = "regex-2024.4.28-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:08a1749f04fee2811c7617fdd46d2e46d09106fa8f475c884b65c01326eb15c5"},
|
||||||
{file = "regex-2023.12.25-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:c3c4a78615b7762740531c27cf46e2f388d8d727d0c0c739e72048beb26c8a9d"},
|
{file = "regex-2024.4.28-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:b8eb28995771c087a73338f695a08c9abfdf723d185e57b97f6175c5051ff1ae"},
|
||||||
{file = "regex-2023.12.25-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:ad83e7545b4ab69216cef4cc47e344d19622e28aabec61574b20257c65466d6a"},
|
{file = "regex-2024.4.28-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:dd7ef715ccb8040954d44cfeff17e6b8e9f79c8019daae2fd30a8806ef5435c0"},
|
||||||
{file = "regex-2023.12.25-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b7a635871143661feccce3979e1727c4e094f2bdfd3ec4b90dfd4f16f571a87a"},
|
{file = "regex-2024.4.28-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:fb0315a2b26fde4005a7c401707c5352df274460f2f85b209cf6024271373013"},
|
||||||
{file = "regex-2023.12.25-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d498eea3f581fbe1b34b59c697512a8baef88212f92e4c7830fcc1499f5b45a5"},
|
{file = "regex-2024.4.28-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f2fc053228a6bd3a17a9b0a3f15c3ab3cf95727b00557e92e1cfe094b88cc662"},
|
||||||
{file = "regex-2023.12.25-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:43f7cd5754d02a56ae4ebb91b33461dc67be8e3e0153f593c509e21d219c5060"},
|
{file = "regex-2024.4.28-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:7fe9739a686dc44733d52d6e4f7b9c77b285e49edf8570754b322bca6b85b4cc"},
|
||||||
{file = "regex-2023.12.25-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:51f4b32f793812714fd5307222a7f77e739b9bc566dc94a18126aba3b92b98a3"},
|
{file = "regex-2024.4.28-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a74fcf77d979364f9b69fcf8200849ca29a374973dc193a7317698aa37d8b01c"},
|
||||||
{file = "regex-2023.12.25-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ba99d8077424501b9616b43a2d208095746fb1284fc5ba490139651f971d39d9"},
|
{file = "regex-2024.4.28-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:965fd0cf4694d76f6564896b422724ec7b959ef927a7cb187fc6b3f4e4f59833"},
|
||||||
{file = "regex-2023.12.25-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:4bfc2b16e3ba8850e0e262467275dd4d62f0d045e0e9eda2bc65078c0110a11f"},
|
{file = "regex-2024.4.28-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:2fef0b38c34ae675fcbb1b5db760d40c3fc3612cfa186e9e50df5782cac02bcd"},
|
||||||
{file = "regex-2023.12.25-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:8c2c19dae8a3eb0ea45a8448356ed561be843b13cbc34b840922ddf565498c1c"},
|
{file = "regex-2024.4.28-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:bc365ce25f6c7c5ed70e4bc674f9137f52b7dd6a125037f9132a7be52b8a252f"},
|
||||||
{file = "regex-2023.12.25-cp312-cp312-musllinux_1_1_ppc64le.whl", hash = "sha256:60080bb3d8617d96f0fb7e19796384cc2467447ef1c491694850ebd3670bc457"},
|
{file = "regex-2024.4.28-cp312-cp312-musllinux_1_1_ppc64le.whl", hash = "sha256:ac69b394764bb857429b031d29d9604842bc4cbfd964d764b1af1868eeebc4f0"},
|
||||||
{file = "regex-2023.12.25-cp312-cp312-musllinux_1_1_s390x.whl", hash = "sha256:b77e27b79448e34c2c51c09836033056a0547aa360c45eeeb67803da7b0eedaf"},
|
{file = "regex-2024.4.28-cp312-cp312-musllinux_1_1_s390x.whl", hash = "sha256:144a1fc54765f5c5c36d6d4b073299832aa1ec6a746a6452c3ee7b46b3d3b11d"},
|
||||||
{file = "regex-2023.12.25-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:518440c991f514331f4850a63560321f833979d145d7d81186dbe2f19e27ae3d"},
|
{file = "regex-2024.4.28-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:2630ca4e152c221072fd4a56d4622b5ada876f668ecd24d5ab62544ae6793ed6"},
|
||||||
{file = "regex-2023.12.25-cp312-cp312-win32.whl", hash = "sha256:e2610e9406d3b0073636a3a2e80db05a02f0c3169b5632022b4e81c0364bcda5"},
|
{file = "regex-2024.4.28-cp312-cp312-win32.whl", hash = "sha256:7f3502f03b4da52bbe8ba962621daa846f38489cae5c4a7b5d738f15f6443d17"},
|
||||||
{file = "regex-2023.12.25-cp312-cp312-win_amd64.whl", hash = "sha256:cc37b9aeebab425f11f27e5e9e6cf580be7206c6582a64467a14dda211abc232"},
|
{file = "regex-2024.4.28-cp312-cp312-win_amd64.whl", hash = "sha256:0dd3f69098511e71880fb00f5815db9ed0ef62c05775395968299cb400aeab82"},
|
||||||
{file = "regex-2023.12.25-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:da695d75ac97cb1cd725adac136d25ca687da4536154cdc2815f576e4da11c69"},
|
{file = "regex-2024.4.28-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:374f690e1dd0dbdcddea4a5c9bdd97632cf656c69113f7cd6a361f2a67221cb6"},
|
||||||
{file = "regex-2023.12.25-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d126361607b33c4eb7b36debc173bf25d7805847346dd4d99b5499e1fef52bc7"},
|
{file = "regex-2024.4.28-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:25f87ae6b96374db20f180eab083aafe419b194e96e4f282c40191e71980c666"},
|
||||||
{file = "regex-2023.12.25-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:4719bb05094d7d8563a450cf8738d2e1061420f79cfcc1fa7f0a44744c4d8f73"},
|
{file = "regex-2024.4.28-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:5dbc1bcc7413eebe5f18196e22804a3be1bfdfc7e2afd415e12c068624d48247"},
|
||||||
{file = "regex-2023.12.25-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5dd58946bce44b53b06d94aa95560d0b243eb2fe64227cba50017a8d8b3cd3e2"},
|
{file = "regex-2024.4.28-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f85151ec5a232335f1be022b09fbbe459042ea1951d8a48fef251223fc67eee1"},
|
||||||
{file = "regex-2023.12.25-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:22a86d9fff2009302c440b9d799ef2fe322416d2d58fc124b926aa89365ec482"},
|
{file = "regex-2024.4.28-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:57ba112e5530530fd175ed550373eb263db4ca98b5f00694d73b18b9a02e7185"},
|
||||||
{file = "regex-2023.12.25-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2aae8101919e8aa05ecfe6322b278f41ce2994c4a430303c4cd163fef746e04f"},
|
{file = "regex-2024.4.28-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:224803b74aab56aa7be313f92a8d9911dcade37e5f167db62a738d0c85fdac4b"},
|
||||||
{file = "regex-2023.12.25-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:e692296c4cc2873967771345a876bcfc1c547e8dd695c6b89342488b0ea55cd8"},
|
{file = "regex-2024.4.28-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0a54a047b607fd2d2d52a05e6ad294602f1e0dec2291152b745870afc47c1397"},
|
||||||
{file = "regex-2023.12.25-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:263ef5cc10979837f243950637fffb06e8daed7f1ac1e39d5910fd29929e489a"},
|
{file = "regex-2024.4.28-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0a2a512d623f1f2d01d881513af9fc6a7c46e5cfffb7dc50c38ce959f9246c94"},
|
||||||
{file = "regex-2023.12.25-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:d6f7e255e5fa94642a0724e35406e6cb7001c09d476ab5fce002f652b36d0c39"},
|
{file = "regex-2024.4.28-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:c06bf3f38f0707592898428636cbb75d0a846651b053a1cf748763e3063a6925"},
|
||||||
{file = "regex-2023.12.25-cp37-cp37m-musllinux_1_1_ppc64le.whl", hash = "sha256:88ad44e220e22b63b0f8f81f007e8abbb92874d8ced66f32571ef8beb0643b2b"},
|
{file = "regex-2024.4.28-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:1031a5e7b048ee371ab3653aad3030ecfad6ee9ecdc85f0242c57751a05b0ac4"},
|
||||||
{file = "regex-2023.12.25-cp37-cp37m-musllinux_1_1_s390x.whl", hash = "sha256:3a17d3ede18f9cedcbe23d2daa8a2cd6f59fe2bf082c567e43083bba3fb00347"},
|
{file = "regex-2024.4.28-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:d7a353ebfa7154c871a35caca7bfd8f9e18666829a1dc187115b80e35a29393e"},
|
||||||
{file = "regex-2023.12.25-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:d15b274f9e15b1a0b7a45d2ac86d1f634d983ca40d6b886721626c47a400bf39"},
|
{file = "regex-2024.4.28-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:7e76b9cfbf5ced1aca15a0e5b6f229344d9b3123439ffce552b11faab0114a02"},
|
||||||
{file = "regex-2023.12.25-cp37-cp37m-win32.whl", hash = "sha256:ed19b3a05ae0c97dd8f75a5d8f21f7723a8c33bbc555da6bbe1f96c470139d3c"},
|
{file = "regex-2024.4.28-cp38-cp38-musllinux_1_1_s390x.whl", hash = "sha256:5ce479ecc068bc2a74cb98dd8dba99e070d1b2f4a8371a7dfe631f85db70fe6e"},
|
||||||
{file = "regex-2023.12.25-cp37-cp37m-win_amd64.whl", hash = "sha256:a6d1047952c0b8104a1d371f88f4ab62e6275567d4458c1e26e9627ad489b445"},
|
{file = "regex-2024.4.28-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:7d77b6f63f806578c604dca209280e4c54f0fa9a8128bb8d2cc5fb6f99da4150"},
|
||||||
{file = "regex-2023.12.25-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:b43523d7bc2abd757119dbfb38af91b5735eea45537ec6ec3a5ec3f9562a1c53"},
|
{file = "regex-2024.4.28-cp38-cp38-win32.whl", hash = "sha256:d84308f097d7a513359757c69707ad339da799e53b7393819ec2ea36bc4beb58"},
|
||||||
{file = "regex-2023.12.25-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:efb2d82f33b2212898f1659fb1c2e9ac30493ac41e4d53123da374c3b5541e64"},
|
{file = "regex-2024.4.28-cp38-cp38-win_amd64.whl", hash = "sha256:2cc1b87bba1dd1a898e664a31012725e48af826bf3971e786c53e32e02adae6c"},
|
||||||
{file = "regex-2023.12.25-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:b7fca9205b59c1a3d5031f7e64ed627a1074730a51c2a80e97653e3e9fa0d415"},
|
{file = "regex-2024.4.28-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:7413167c507a768eafb5424413c5b2f515c606be5bb4ef8c5dee43925aa5718b"},
|
||||||
{file = "regex-2023.12.25-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:086dd15e9435b393ae06f96ab69ab2d333f5d65cbe65ca5a3ef0ec9564dfe770"},
|
{file = "regex-2024.4.28-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:108e2dcf0b53a7c4ab8986842a8edcb8ab2e59919a74ff51c296772e8e74d0ae"},
|
||||||
{file = "regex-2023.12.25-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e81469f7d01efed9b53740aedd26085f20d49da65f9c1f41e822a33992cb1590"},
|
{file = "regex-2024.4.28-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:f1c5742c31ba7d72f2dedf7968998730664b45e38827637e0f04a2ac7de2f5f1"},
|
||||||
{file = "regex-2023.12.25-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:34e4af5b27232f68042aa40a91c3b9bb4da0eeb31b7632e0091afc4310afe6cb"},
|
{file = "regex-2024.4.28-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ecc6148228c9ae25ce403eade13a0961de1cb016bdb35c6eafd8e7b87ad028b1"},
|
||||||
{file = "regex-2023.12.25-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9852b76ab558e45b20bf1893b59af64a28bd3820b0c2efc80e0a70a4a3ea51c1"},
|
{file = "regex-2024.4.28-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b7d893c8cf0e2429b823ef1a1d360a25950ed11f0e2a9df2b5198821832e1947"},
|
||||||
{file = "regex-2023.12.25-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ff100b203092af77d1a5a7abe085b3506b7eaaf9abf65b73b7d6905b6cb76988"},
|
{file = "regex-2024.4.28-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:4290035b169578ffbbfa50d904d26bec16a94526071ebec3dadbebf67a26b25e"},
|
||||||
{file = "regex-2023.12.25-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:cc038b2d8b1470364b1888a98fd22d616fba2b6309c5b5f181ad4483e0017861"},
|
{file = "regex-2024.4.28-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:44a22ae1cfd82e4ffa2066eb3390777dc79468f866f0625261a93e44cdf6482b"},
|
||||||
{file = "regex-2023.12.25-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:094ba386bb5c01e54e14434d4caabf6583334090865b23ef58e0424a6286d3dc"},
|
{file = "regex-2024.4.28-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:fd24fd140b69f0b0bcc9165c397e9b2e89ecbeda83303abf2a072609f60239e2"},
|
||||||
{file = "regex-2023.12.25-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:5cd05d0f57846d8ba4b71d9c00f6f37d6b97d5e5ef8b3c3840426a475c8f70f4"},
|
{file = "regex-2024.4.28-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:39fb166d2196413bead229cd64a2ffd6ec78ebab83fff7d2701103cf9f4dfd26"},
|
||||||
{file = "regex-2023.12.25-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:9aa1a67bbf0f957bbe096375887b2505f5d8ae16bf04488e8b0f334c36e31360"},
|
{file = "regex-2024.4.28-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:9301cc6db4d83d2c0719f7fcda37229691745168bf6ae849bea2e85fc769175d"},
|
||||||
{file = "regex-2023.12.25-cp38-cp38-musllinux_1_1_s390x.whl", hash = "sha256:98a2636994f943b871786c9e82bfe7883ecdaba2ef5df54e1450fa9869d1f756"},
|
{file = "regex-2024.4.28-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:7c3d389e8d76a49923683123730c33e9553063d9041658f23897f0b396b2386f"},
|
||||||
{file = "regex-2023.12.25-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:37f8e93a81fc5e5bd8db7e10e62dc64261bcd88f8d7e6640aaebe9bc180d9ce2"},
|
{file = "regex-2024.4.28-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:99ef6289b62042500d581170d06e17f5353b111a15aa6b25b05b91c6886df8fc"},
|
||||||
{file = "regex-2023.12.25-cp38-cp38-win32.whl", hash = "sha256:d78bd484930c1da2b9679290a41cdb25cc127d783768a0369d6b449e72f88beb"},
|
{file = "regex-2024.4.28-cp39-cp39-musllinux_1_1_s390x.whl", hash = "sha256:b91d529b47798c016d4b4c1d06cc826ac40d196da54f0de3c519f5a297c5076a"},
|
||||||
{file = "regex-2023.12.25-cp38-cp38-win_amd64.whl", hash = "sha256:b521dcecebc5b978b447f0f69b5b7f3840eac454862270406a39837ffae4e697"},
|
{file = "regex-2024.4.28-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:43548ad74ea50456e1c68d3c67fff3de64c6edb85bcd511d1136f9b5376fc9d1"},
|
||||||
{file = "regex-2023.12.25-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:f7bc09bc9c29ebead055bcba136a67378f03d66bf359e87d0f7c759d6d4ffa31"},
|
{file = "regex-2024.4.28-cp39-cp39-win32.whl", hash = "sha256:05d9b6578a22db7dedb4df81451f360395828b04f4513980b6bd7a1412c679cc"},
|
||||||
{file = "regex-2023.12.25-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:e14b73607d6231f3cc4622809c196b540a6a44e903bcfad940779c80dffa7be7"},
|
{file = "regex-2024.4.28-cp39-cp39-win_amd64.whl", hash = "sha256:3986217ec830c2109875be740531feb8ddafe0dfa49767cdcd072ed7e8927962"},
|
||||||
{file = "regex-2023.12.25-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:9eda5f7a50141291beda3edd00abc2d4a5b16c29c92daf8d5bd76934150f3edc"},
|
{file = "regex-2024.4.28.tar.gz", hash = "sha256:83ab366777ea45d58f72593adf35d36ca911ea8bd838483c1823b883a121b0e4"},
|
||||||
{file = "regex-2023.12.25-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:cc6bb9aa69aacf0f6032c307da718f61a40cf970849e471254e0e91c56ffca95"},
|
|
||||||
{file = "regex-2023.12.25-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:298dc6354d414bc921581be85695d18912bea163a8b23cac9a2562bbcd5088b1"},
|
|
||||||
{file = "regex-2023.12.25-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2f4e475a80ecbd15896a976aa0b386c5525d0ed34d5c600b6d3ebac0a67c7ddf"},
|
|
||||||
{file = "regex-2023.12.25-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:531ac6cf22b53e0696f8e1d56ce2396311254eb806111ddd3922c9d937151dae"},
|
|
||||||
{file = "regex-2023.12.25-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:22f3470f7524b6da61e2020672df2f3063676aff444db1daa283c2ea4ed259d6"},
|
|
||||||
{file = "regex-2023.12.25-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:89723d2112697feaa320c9d351e5f5e7b841e83f8b143dba8e2d2b5f04e10923"},
|
|
||||||
{file = "regex-2023.12.25-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:0ecf44ddf9171cd7566ef1768047f6e66975788258b1c6c6ca78098b95cf9a3d"},
|
|
||||||
{file = "regex-2023.12.25-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:905466ad1702ed4acfd67a902af50b8db1feeb9781436372261808df7a2a7bca"},
|
|
||||||
{file = "regex-2023.12.25-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:4558410b7a5607a645e9804a3e9dd509af12fb72b9825b13791a37cd417d73a5"},
|
|
||||||
{file = "regex-2023.12.25-cp39-cp39-musllinux_1_1_s390x.whl", hash = "sha256:7e316026cc1095f2a3e8cc012822c99f413b702eaa2ca5408a513609488cb62f"},
|
|
||||||
{file = "regex-2023.12.25-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:3b1de218d5375cd6ac4b5493e0b9f3df2be331e86520f23382f216c137913d20"},
|
|
||||||
{file = "regex-2023.12.25-cp39-cp39-win32.whl", hash = "sha256:11a963f8e25ab5c61348d090bf1b07f1953929c13bd2309a0662e9ff680763c9"},
|
|
||||||
{file = "regex-2023.12.25-cp39-cp39-win_amd64.whl", hash = "sha256:e693e233ac92ba83a87024e1d32b5f9ab15ca55ddd916d878146f4e3406b5c91"},
|
|
||||||
{file = "regex-2023.12.25.tar.gz", hash = "sha256:29171aa128da69afdf4bde412d5bedc335f2ca8fcfe4489038577d05f16181e5"},
|
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -2036,28 +2177,28 @@ jupyter = ["ipywidgets (>=7.5.1,<9)"]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "ruff"
|
name = "ruff"
|
||||||
version = "0.3.4"
|
version = "0.3.7"
|
||||||
description = "An extremely fast Python linter and code formatter, written in Rust."
|
description = "An extremely fast Python linter and code formatter, written in Rust."
|
||||||
optional = false
|
optional = false
|
||||||
python-versions = ">=3.7"
|
python-versions = ">=3.7"
|
||||||
files = [
|
files = [
|
||||||
{file = "ruff-0.3.4-py3-none-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl", hash = "sha256:60c870a7d46efcbc8385d27ec07fe534ac32f3b251e4fc44b3cbfd9e09609ef4"},
|
{file = "ruff-0.3.7-py3-none-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl", hash = "sha256:0e8377cccb2f07abd25e84fc5b2cbe48eeb0fea9f1719cad7caedb061d70e5ce"},
|
||||||
{file = "ruff-0.3.4-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:6fc14fa742e1d8f24910e1fff0bd5e26d395b0e0e04cc1b15c7c5e5fe5b4af91"},
|
{file = "ruff-0.3.7-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:15a4d1cc1e64e556fa0d67bfd388fed416b7f3b26d5d1c3e7d192c897e39ba4b"},
|
||||||
{file = "ruff-0.3.4-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d3ee7880f653cc03749a3bfea720cf2a192e4f884925b0cf7eecce82f0ce5854"},
|
{file = "ruff-0.3.7-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d28bdf3d7dc71dd46929fafeec98ba89b7c3550c3f0978e36389b5631b793663"},
|
||||||
{file = "ruff-0.3.4-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:cf133dd744f2470b347f602452a88e70dadfbe0fcfb5fd46e093d55da65f82f7"},
|
{file = "ruff-0.3.7-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:379b67d4f49774ba679593b232dcd90d9e10f04d96e3c8ce4a28037ae473f7bb"},
|
||||||
{file = "ruff-0.3.4-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3f3860057590e810c7ffea75669bdc6927bfd91e29b4baa9258fd48b540a4365"},
|
{file = "ruff-0.3.7-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c060aea8ad5ef21cdfbbe05475ab5104ce7827b639a78dd55383a6e9895b7c51"},
|
||||||
{file = "ruff-0.3.4-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:986f2377f7cf12efac1f515fc1a5b753c000ed1e0a6de96747cdf2da20a1b369"},
|
{file = "ruff-0.3.7-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:ebf8f615dde968272d70502c083ebf963b6781aacd3079081e03b32adfe4d58a"},
|
||||||
{file = "ruff-0.3.4-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c4fd98e85869603e65f554fdc5cddf0712e352fe6e61d29d5a6fe087ec82b76c"},
|
{file = "ruff-0.3.7-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d48098bd8f5c38897b03604f5428901b65e3c97d40b3952e38637b5404b739a2"},
|
||||||
{file = "ruff-0.3.4-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:64abeed785dad51801b423fa51840b1764b35d6c461ea8caef9cf9e5e5ab34d9"},
|
{file = "ruff-0.3.7-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:da8a4fda219bf9024692b1bc68c9cff4b80507879ada8769dc7e985755d662ea"},
|
||||||
{file = "ruff-0.3.4-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:df52972138318bc7546d92348a1ee58449bc3f9eaf0db278906eb511889c4b50"},
|
{file = "ruff-0.3.7-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6c44e0149f1d8b48c4d5c33d88c677a4aa22fd09b1683d6a7ff55b816b5d074f"},
|
||||||
{file = "ruff-0.3.4-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:98e98300056445ba2cc27d0b325fd044dc17fcc38e4e4d2c7711585bd0a958ed"},
|
{file = "ruff-0.3.7-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:3050ec0af72b709a62ecc2aca941b9cd479a7bf2b36cc4562f0033d688e44fa1"},
|
||||||
{file = "ruff-0.3.4-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:519cf6a0ebed244dce1dc8aecd3dc99add7a2ee15bb68cf19588bb5bf58e0488"},
|
{file = "ruff-0.3.7-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:a29cc38e4c1ab00da18a3f6777f8b50099d73326981bb7d182e54a9a21bb4ff7"},
|
||||||
{file = "ruff-0.3.4-py3-none-musllinux_1_2_i686.whl", hash = "sha256:bb0acfb921030d00070539c038cd24bb1df73a2981e9f55942514af8b17be94e"},
|
{file = "ruff-0.3.7-py3-none-musllinux_1_2_i686.whl", hash = "sha256:5b15cc59c19edca917f51b1956637db47e200b0fc5e6e1878233d3a938384b0b"},
|
||||||
{file = "ruff-0.3.4-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:cf187a7e7098233d0d0c71175375c5162f880126c4c716fa28a8ac418dcf3378"},
|
{file = "ruff-0.3.7-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:e491045781b1e38b72c91247cf4634f040f8d0cb3e6d3d64d38dcf43616650b4"},
|
||||||
{file = "ruff-0.3.4-py3-none-win32.whl", hash = "sha256:af27ac187c0a331e8ef91d84bf1c3c6a5dea97e912a7560ac0cef25c526a4102"},
|
{file = "ruff-0.3.7-py3-none-win32.whl", hash = "sha256:bc931de87593d64fad3a22e201e55ad76271f1d5bfc44e1a1887edd0903c7d9f"},
|
||||||
{file = "ruff-0.3.4-py3-none-win_amd64.whl", hash = "sha256:de0d5069b165e5a32b3c6ffbb81c350b1e3d3483347196ffdf86dc0ef9e37dd6"},
|
{file = "ruff-0.3.7-py3-none-win_amd64.whl", hash = "sha256:5ef0e501e1e39f35e03c2acb1d1238c595b8bb36cf7a170e7c1df1b73da00e74"},
|
||||||
{file = "ruff-0.3.4-py3-none-win_arm64.whl", hash = "sha256:6810563cc08ad0096b57c717bd78aeac888a1bfd38654d9113cb3dc4d3f74232"},
|
{file = "ruff-0.3.7-py3-none-win_arm64.whl", hash = "sha256:789e144f6dc7019d1f92a812891c645274ed08af6037d11fc65fcbc183b7d59f"},
|
||||||
{file = "ruff-0.3.4.tar.gz", hash = "sha256:f0f4484c6541a99862b693e13a151435a279b271cff20e37101116a21e2a1ad1"},
|
{file = "ruff-0.3.7.tar.gz", hash = "sha256:d5c1aebee5162c2226784800ae031f660c350e7a3402c4d1f8ea4e97e232e3ba"},
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -2098,13 +2239,13 @@ files = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "tinycss2"
|
name = "tinycss2"
|
||||||
version = "1.2.1"
|
version = "1.3.0"
|
||||||
description = "A tiny CSS parser"
|
description = "A tiny CSS parser"
|
||||||
optional = false
|
optional = false
|
||||||
python-versions = ">=3.7"
|
python-versions = ">=3.8"
|
||||||
files = [
|
files = [
|
||||||
{file = "tinycss2-1.2.1-py3-none-any.whl", hash = "sha256:2b80a96d41e7c3914b8cda8bc7f705a4d9c49275616e886103dd839dfc847847"},
|
{file = "tinycss2-1.3.0-py3-none-any.whl", hash = "sha256:54a8dbdffb334d536851be0226030e9505965bb2f30f21a4a82c55fb2a80fae7"},
|
||||||
{file = "tinycss2-1.2.1.tar.gz", hash = "sha256:8cff3a8f066c2ec677c06dbc7b45619804a6938478d9d73c284b29d14ecb0627"},
|
{file = "tinycss2-1.3.0.tar.gz", hash = "sha256:152f9acabd296a8375fbca5b84c961ff95971fcfc32e79550c8df8e29118c54d"},
|
||||||
]
|
]
|
||||||
|
|
||||||
[package.dependencies]
|
[package.dependencies]
|
||||||
|
@ -2112,7 +2253,7 @@ webencodings = ">=0.4"
|
||||||
|
|
||||||
[package.extras]
|
[package.extras]
|
||||||
doc = ["sphinx", "sphinx_rtd_theme"]
|
doc = ["sphinx", "sphinx_rtd_theme"]
|
||||||
test = ["flake8", "isort", "pytest"]
|
test = ["pytest", "ruff"]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "tomlkit"
|
name = "tomlkit"
|
||||||
|
@ -2153,6 +2294,20 @@ h2 = ["h2 (>=4,<5)"]
|
||||||
socks = ["pysocks (>=1.5.6,!=1.5.7,<2.0)"]
|
socks = ["pysocks (>=1.5.6,!=1.5.7,<2.0)"]
|
||||||
zstd = ["zstandard (>=0.18.0)"]
|
zstd = ["zstandard (>=0.18.0)"]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "userpath"
|
||||||
|
version = "1.9.2"
|
||||||
|
description = "Cross-platform tool for adding locations to the user PATH"
|
||||||
|
optional = false
|
||||||
|
python-versions = ">=3.7"
|
||||||
|
files = [
|
||||||
|
{file = "userpath-1.9.2-py3-none-any.whl", hash = "sha256:2cbf01a23d655a1ff8fc166dfb78da1b641d1ceabf0fe5f970767d380b14e89d"},
|
||||||
|
{file = "userpath-1.9.2.tar.gz", hash = "sha256:6c52288dab069257cc831846d15d48133522455d4677ee69a9781f11dbefd815"},
|
||||||
|
]
|
||||||
|
|
||||||
|
[package.dependencies]
|
||||||
|
click = "*"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "uvloop"
|
name = "uvloop"
|
||||||
version = "0.19.0"
|
version = "0.19.0"
|
||||||
|
@ -2436,4 +2591,4 @@ multidict = ">=4.0"
|
||||||
[metadata]
|
[metadata]
|
||||||
lock-version = "2.0"
|
lock-version = "2.0"
|
||||||
python-versions = ">=3.11,<3.12"
|
python-versions = ">=3.11,<3.12"
|
||||||
content-hash = "42f6d2a053929b5a71b673e30f222c3e5914c723d074b453afd349e11118590f"
|
content-hash = "25dce93989e94b49932b4f5bb8489eb37b2e9aa5860679f7150e2beca8b0471c"
|
||||||
|
|
|
@ -9,11 +9,12 @@ package-mode = false
|
||||||
|
|
||||||
[tool.poetry.dependencies]
|
[tool.poetry.dependencies]
|
||||||
python = ">=3.11,<3.12"
|
python = ">=3.11,<3.12"
|
||||||
Red-DiscordBot = "^3.5.5"
|
Red-DiscordBot = "^3.5.9"
|
||||||
py-dactyl = "^2.0.4"
|
py-dactyl = "^2.0.4"
|
||||||
websockets = "^12.0"
|
websockets = "^12.0"
|
||||||
pillow = "^10.3.0"
|
pillow = "^10.3.0"
|
||||||
numpy = "^1.26.4"
|
numpy = "^1.26.4"
|
||||||
|
pydantic = "^2.7.1"
|
||||||
|
|
||||||
[tool.poetry.group.dev]
|
[tool.poetry.group.dev]
|
||||||
optional = true
|
optional = true
|
||||||
|
@ -21,6 +22,7 @@ optional = true
|
||||||
[tool.poetry.group.dev.dependencies]
|
[tool.poetry.group.dev.dependencies]
|
||||||
ruff = "^0.3.1"
|
ruff = "^0.3.1"
|
||||||
pylint = "^3.1.0"
|
pylint = "^3.1.0"
|
||||||
|
pipx = "^1.5.0"
|
||||||
|
|
||||||
[tool.poetry.group.docs]
|
[tool.poetry.group.docs]
|
||||||
optional = true
|
optional = true
|
||||||
|
|
Loading…
Reference in a new issue