refactor: standardize codebase formatting, optimize import orders, and update GUI resolution to 1080p

This commit is contained in:
jack
2026-06-18 13:13:47 -07:00
parent 8ad2a9b972
commit 66942d250d
32 changed files with 453 additions and 120 deletions
+23
View File
@@ -0,0 +1,23 @@
.PHONY: install test lint fix typecheck run clean
install:
uv sync
test:
uv run pytest tests/
lint:
uv run ruff check src/
fix:
uv run ruff check src/ --fix
typecheck:
uv run mypy src/
run:
uv run python -m pygui
clean:
rm -rf .pytest_cache .ruff_cache .mypy_cache
find . -type d -name "__pycache__" -exec rm -rf {} +
+27
View File
@@ -17,6 +17,7 @@ dependencies = [
"matplotlib>=3.7.0", "matplotlib>=3.7.0",
"scipy>=1.17.1", "scipy>=1.17.1",
"pyyaml>=6.0.3", "pyyaml>=6.0.3",
"dtw-python",
] ]
[project.optional-dependencies] [project.optional-dependencies]
@@ -88,6 +89,8 @@ files = [
[dependency-groups] [dependency-groups]
dev = [ dev = [
"pytest>=9.0.3", "pytest>=9.0.3",
"ruff",
"mypy",
] ]
[tool.uv] [tool.uv]
@@ -96,3 +99,27 @@ environments = [
"sys_platform == 'win32'", "sys_platform == 'win32'",
"sys_platform == 'linux'", "sys_platform == 'linux'",
] ]
# ===== Ruff Linter and Formatter =====
[tool.ruff]
target-version = "py311"
line-length = 100
[tool.ruff.lint]
select = [
"E", # pycodestyle errors
"W", # pycodestyle warnings
"F", # pyflakes
"I", # isort (import sorting)
"N", # pep8-naming
]
ignore = []
# ===== Mypy Static Type Checker =====
[tool.mypy]
python_version = "3.11"
check_untyped_defs = true
warn_return_any = true
warn_unused_configs = true
ignore_missing_imports = true
+2 -2
View File
@@ -4,8 +4,8 @@ import ISC
// ===== App Window Shell ===== // ===== App Window Shell =====
Window { Window {
// ===== Window Dimensions ===== // ===== Window Dimensions =====
width: 1400 width: 1920
height: 820 height: 1080
minimumWidth: 1100 minimumWidth: 1100
minimumHeight: 700 minimumHeight: 700
visible: true visible: true
+5 -4
View File
@@ -1,18 +1,19 @@
import logging
import sys import sys
from pathlib import Path from pathlib import Path
import logging
from PySide6.QtQml import QQmlApplicationEngine from PySide6.QtQml import QQmlApplicationEngine
from PySide6.QtQuickControls2 import QQuickStyle from PySide6.QtQuickControls2 import QQuickStyle
from PySide6.QtWidgets import QApplication from PySide6.QtWidgets import QApplication
from pygui.backend.controllers.device_controller import DeviceController from pygui.backend.controllers.device_controller import DeviceController
from pygui.backend.controllers.session_controller import SessionController
from pygui.backend.data.file_browser import FileBrowser
from pygui.backend.data.local_settings import LocalSettings from pygui.backend.data.local_settings import LocalSettings
from pygui.backend.data.local_settings_model import LocalSettingsModel from pygui.backend.data.local_settings_model import LocalSettingsModel
from pygui.backend.data.file_browser import FileBrowser
from pygui.backend.controllers.session_controller import SessionController
# Importing wafer_map_item registers the @QmlElement WaferMapItem (QML: import ISC.Wafer). # Importing wafer_map_item registers the @QmlElement WaferMapItem (QML: import ISC.Wafer).
from pygui.backend.visualization.wafer_map_item import WaferMapItem
# ===== Application Entry Point ===== # ===== Application Entry Point =====
def main() -> int: def main() -> int:
+13 -17
View File
@@ -4,29 +4,25 @@
from pygui.backend.controllers.device_controller import DeviceController # noqa: F401 from pygui.backend.controllers.device_controller import DeviceController # noqa: F401
from pygui.backend.controllers.session_controller import SessionController # noqa: F401 from pygui.backend.controllers.session_controller import SessionController # noqa: F401
from pygui.backend.models.frame import Frame # noqa: F401
from pygui.backend.models.frame_player import FramePlayer, frames_from_wafer_data # noqa: F401
from pygui.backend.models.frame_stats import Stats, compute_stats # noqa: F401
from pygui.backend.models.session_model import SessionModel # noqa: F401
from pygui.backend.models.data_model import TemperatureTableModel # noqa: F401
from pygui.backend.models.sensor_editor import SensorEditor # noqa: F401
from pygui.backend.models.threshold_classifier import ThresholdConfig # noqa: F401
from pygui.backend.models.stability_detector import StabilityDetector # noqa: F401
from pygui.backend.data.csv_recorder import CsvRecorder # noqa: F401
from pygui.backend.data.csv_file_metadata import CSVFileMetadata # noqa: F401 from pygui.backend.data.csv_file_metadata import CSVFileMetadata # noqa: F401
from pygui.backend.data.csv_recorder import CsvRecorder # noqa: F401
from pygui.backend.data.data_records import read_data_records # noqa: F401 from pygui.backend.data.data_records import read_data_records # noqa: F401
from pygui.backend.data.data_segment import DataSegment # noqa: F401 from pygui.backend.data.data_segment import DataSegment # noqa: F401
from pygui.backend.data.file_browser import FileBrowser # noqa: F401 from pygui.backend.data.file_browser import FileBrowser # noqa: F401
from pygui.backend.data.local_settings import LocalSettings # noqa: F401 from pygui.backend.data.local_settings import LocalSettings # noqa: F401
from pygui.backend.data.local_settings_model import LocalSettingsModel # noqa: F401 from pygui.backend.data.local_settings_model import LocalSettingsModel # noqa: F401
from pygui.backend.models.data_model import TemperatureTableModel # noqa: F401
from pygui.backend.visualization.wafer_map_item import WaferMapItem # noqa: F401 from pygui.backend.models.frame import Frame # noqa: F401
from pygui.backend.models.frame_player import FramePlayer, frames_from_wafer_data # noqa: F401
from pygui.backend.models.frame_stats import Stats, compute_stats # noqa: F401
from pygui.backend.models.sensor_editor import SensorEditor # noqa: F401
from pygui.backend.models.session_model import SessionModel # noqa: F401
from pygui.backend.models.stability_detector import StabilityDetector # noqa: F401
from pygui.backend.models.threshold_classifier import ThresholdConfig # noqa: F401
from pygui.backend.visualization.contour_models import ContourLine, ContourSegment # noqa: F401
from pygui.backend.visualization.graph_view import GraphView # noqa: F401 from pygui.backend.visualization.graph_view import GraphView # noqa: F401
from pygui.backend.visualization.rbf_heatmap import interpolate_field # noqa: F401 from pygui.backend.visualization.rbf_heatmap import interpolate_field # noqa: F401
from pygui.backend.visualization.contour_models import ContourLine, ContourSegment # noqa: F401 from pygui.backend.visualization.wafer_map_item import WaferMapItem # noqa: F401
from pygui.backend.wafer.wafer_layouts import available_families, load_layout # noqa: F401
from pygui.backend.wafer.zwafer_models import ZWaferData, Sensor, DataRecord # noqa: F401 from pygui.backend.wafer.zwafer_models import DataRecord, Sensor, ZWaferData # noqa: F401
from pygui.backend.wafer.zwafer_parser import ZWaferParser # noqa: F401 from pygui.backend.wafer.zwafer_parser import ZWaferParser # noqa: F401
from pygui.backend.wafer.wafer_layouts import load_layout, available_families # noqa: F401
+3 -1
View File
@@ -2,7 +2,9 @@
from __future__ import annotations from __future__ import annotations
import math import math
from pygui.backend.wafer.zwafer_models import Sensor from pygui.backend.wafer.zwafer_models import Sensor
@@ -20,7 +22,7 @@ def average_clusters(values: list[float], clusters: list[list[int]]) -> list[flo
val = values[idx] val = values[idx]
if not math.isnan(val): if not math.isnan(val):
valid_vals.append(val) valid_vals.append(val)
if valid_vals: if valid_vals:
mean_val = sum(valid_vals) / len(valid_vals) mean_val = sum(valid_vals) / len(valid_vals)
for idx in cluster: for idx in cluster:
@@ -3,4 +3,3 @@ from pygui.backend.controllers.device_controller import DeviceController
from pygui.backend.controllers.session_controller import SessionController from pygui.backend.controllers.session_controller import SessionController
__all__ = ["DeviceController", "SessionController"] __all__ = ["DeviceController", "SessionController"]
@@ -7,11 +7,12 @@ import threading
from datetime import datetime from datetime import datetime
from typing import Any, Optional from typing import Any, Optional
from PySide6.QtCore import QObject, Property, Qt, Signal, Slot from PySide6.QtCore import Property, QObject, Qt, Signal, Slot
from pygui.backend.controllers.session_controller import SessionController
from pygui.backend.data.local_settings import LocalSettings
from pygui.backend.models.data_model import TemperatureTableModel from pygui.backend.models.data_model import TemperatureTableModel
from pygui.backend.visualization.graph_view import GraphView from pygui.backend.visualization.graph_view import GraphView
from pygui.backend.data.local_settings import LocalSettings
from pygui.serialcomm.data_parser import ( from pygui.serialcomm.data_parser import (
convert_to_temperatures, convert_to_temperatures,
parse_binary_data, parse_binary_data,
@@ -20,7 +21,7 @@ from pygui.serialcomm.data_parser import (
) )
from pygui.serialcomm.device_service import DeviceService from pygui.serialcomm.device_service import DeviceService
from pygui.serialcomm.serial_port import WaferInfo from pygui.serialcomm.serial_port import WaferInfo
from pygui.backend.controllers.session_controller import SessionController
# import pygui.backend.wafer_map_item # import pygui.backend.wafer_map_item
stream_controller = SessionController() stream_controller = SessionController()
@@ -1,21 +1,23 @@
"""QML-facing controller for the live/review wafer dashboard.""" """QML-facing controller for the live/review wafer dashboard."""
from __future__ import annotations from __future__ import annotations
import logging import logging
import time import time
from typing import Any, Optional from typing import Optional
from PySide6.QtCore import QObject, Property, QTimer, Qt, Signal, Slot from PySide6.QtCore import Property, QObject, Qt, QTimer, Signal, Slot
from pygui.backend.cluster_average import average_clusters, group_sensors_by_radius
from pygui.backend.data.csv_recorder import CsvRecorder from pygui.backend.data.csv_recorder import CsvRecorder
from pygui.backend.models.frame import Frame from pygui.backend.models.frame import Frame
from pygui.backend.models.frame_player import FramePlayer, frames_from_wafer_data from pygui.backend.models.frame_player import FramePlayer, frames_from_wafer_data
from pygui.backend.models.sensor_editor import SensorEditor
from pygui.backend.models.session_model import SessionModel from pygui.backend.models.session_model import SessionModel
from pygui.backend.models.threshold_classifier import ThresholdConfig from pygui.backend.models.threshold_classifier import ThresholdConfig
from pygui.backend.wafer.zwafer_models import Sensor from pygui.backend.wafer.zwafer_models import Sensor
from pygui.backend.wafer.zwafer_parser import ZWaferParser from pygui.backend.wafer.zwafer_parser import ZWaferParser
from pygui.serialcomm.stream_reader import StreamReader from pygui.serialcomm.stream_reader import StreamReader
from pygui.backend.models.sensor_editor import SensorEditor
from pygui.backend.cluster_average import average_clusters, group_sensors_by_radius
log = logging.getLogger(__name__) log = logging.getLogger(__name__)
MODE_LIVE = "live" MODE_LIVE = "live"
@@ -24,7 +26,7 @@ MODE_REVIEW = "review"
class SessionController(QObject): class SessionController(QObject):
# public signals # public signals
frameUpdated = Signal() frameUpdated = Signal()
modeChanged = Signal() modeChanged = Signal()
stateChanged = Signal() stateChanged = Signal()
recordingChanged = Signal() recordingChanged = Signal()
@@ -56,7 +58,7 @@ class SessionController(QObject):
self._dirty = False self._dirty = False
self._liveFrame.connect(self._on_live_frame, Qt.ConnectionType.QueuedConnection) self._liveFrame.connect(self._on_live_frame, Qt.ConnectionType.QueuedConnection)
self._sensor_editor = SensorEditor() self._sensor_editor = SensorEditor()
self._last_raw_frame: Frame | None = None self._last_raw_frame: Frame | None = None
self._loaded_file: str = "" self._loaded_file: str = ""
@@ -74,13 +76,13 @@ class SessionController(QObject):
def frameTotal(self) -> int: return self._player.total def frameTotal(self) -> int: return self._player.total
@Property(str, notify=stateChanged) @Property(str, notify=stateChanged)
def state(self) -> str: def state(self) -> str:
if self._last: if self._last:
return self._last.state return self._last.state
# IF we dont have data yet, but the reader is running -> Streaming # IF we dont have data yet, but the reader is running -> Streaming
if self._mode == MODE_LIVE and self._reader is not None: if self._mode == MODE_LIVE and self._reader is not None:
return "streaming" return "streaming"
return "idle" return "idle"
@Property(bool, notify=recordingChanged) @Property(bool, notify=recordingChanged)
@@ -198,7 +200,12 @@ class SessionController(QObject):
@Slot(str) @Slot(str)
def loadFile(self, file_path: str) -> None: def loadFile(self, file_path: str) -> None:
from pathlib import Path from pathlib import Path
from pygui.backend.data.data_records import is_official_csv, read_data_records, read_official_csv
from pygui.backend.data.data_records import (
is_official_csv,
read_data_records,
read_official_csv,
)
from pygui.backend.wafer.wafer_layouts import WaferLayout, resolve_shape_and_size from pygui.backend.wafer.wafer_layouts import WaferLayout, resolve_shape_and_size
frames = [] frames = []
@@ -319,10 +326,9 @@ class SessionController(QObject):
# ---- live: stream start/stop ---- # ---- live: stream start/stop ----
@Slot(str, str) @Slot(str, str)
def startStream(self, port: str, family_code: str = "") -> None: def startStream(self, port: str, family_code: str = "") -> None:
from pygui.serialcomm.serial_port import SerialPort # transport open
import serial as pyserial
from pygui.backend.wafer.wafer_layouts import load_layout_for_wafer_id from pygui.backend.wafer.wafer_layouts import load_layout_for_wafer_id
import time from pygui.serialcomm.serial_port import SerialPort # transport open
if family_code: if family_code:
try: try:
@@ -346,7 +352,7 @@ class SessionController(QObject):
high_byte = payload[i * 2] high_byte = payload[i * 2]
low_byte = payload[i * 2 + 1] low_byte = payload[i * 2 + 1]
val16 = (high_byte << 8) | low_byte val16 = (high_byte << 8) | low_byte
is_negative = (val16 & 0x8000) != 0 is_negative = (val16 & 0x8000) != 0
integer_part = (val16 >> 7) & 0xFF integer_part = (val16 >> 7) & 0xFF
fractional_bits = val16 & 0x7F fractional_bits = val16 & 0x7F
@@ -355,7 +361,7 @@ class SessionController(QObject):
if is_negative: if is_negative:
result = -result result = -result
values.append(result) values.append(result)
return Frame(seq=seq, time=time.monotonic(), values=values) return Frame(seq=seq, time=time.monotonic(), values=values)
# Clear out any old data from the prev sessions # Clear out any old data from the prev sessions
@@ -378,7 +384,7 @@ class SessionController(QObject):
family_code=family_code or "A") family_code=family_code or "A")
self._reader.start() self._reader.start()
self._repaint_timer.start() self._repaint_timer.start()
self.setMode("live") self.setMode("live")
self.stateChanged.emit() self.stateChanged.emit()
@@ -389,7 +395,7 @@ class SessionController(QObject):
transport = self._reader._transport transport = self._reader._transport
self._reader.stop() self._reader.stop()
self._reader = None self._reader = None
# Send 'D2S' command padded to 512 bytes to stop the stream # Send 'D2S' command padded to 512 bytes to stop the stream
if transport and transport.is_open: if transport and transport.is_open:
try: try:
@@ -398,7 +404,7 @@ class SessionController(QObject):
transport.flush() transport.flush()
except Exception as exc: except Exception as exc:
log.error("Error sending stop command: %s", exc) log.error("Error sending stop command: %s", exc)
self.stateChanged.emit() self.stateChanged.emit()
self.stopRecording() self.stopRecording()
@@ -455,6 +461,5 @@ class SessionController(QObject):
"""Remove all sensor overrides.""" """Remove all sensor overrides."""
self._sensor_editor.clear() self._sensor_editor.clear()
self._reprocess_current() self._reprocess_current()
+1 -1
View File
@@ -2,8 +2,8 @@ import secrets
from pathlib import Path from pathlib import Path
from typing import Union from typing import Union
from cryptography.hazmat.primitives.ciphers import Cipher, algorithms, modes
from cryptography.hazmat.backends import default_backend from cryptography.hazmat.backends import default_backend
from cryptography.hazmat.primitives.ciphers import Cipher, algorithms, modes
# ===== Crypto Utilities ===== # ===== Crypto Utilities =====
+2 -2
View File
@@ -1,7 +1,7 @@
# ===== Data Sub-package ===== # ===== Data Sub-package =====
from pygui.backend.data.csv_recorder import CsvRecorder
from pygui.backend.data.csv_file_metadata import CSVFileMetadata from pygui.backend.data.csv_file_metadata import CSVFileMetadata
from pygui.backend.data.data_records import read_data_records, is_official_csv, read_official_csv from pygui.backend.data.csv_recorder import CsvRecorder
from pygui.backend.data.data_records import is_official_csv, read_data_records, read_official_csv
from pygui.backend.data.data_segment import DataSegment from pygui.backend.data.data_segment import DataSegment
from pygui.backend.data.file_browser import FileBrowser from pygui.backend.data.file_browser import FileBrowser
from pygui.backend.data.local_settings import LocalSettings from pygui.backend.data.local_settings import LocalSettings
+8 -7
View File
@@ -1,24 +1,25 @@
"""Append live frames""" """Append live frames"""
from __future__ import annotations from __future__ import annotations
from datetime import datetime from datetime import datetime
from pathlib import Path from pathlib import Path
from typing import Optional, TextIO from typing import Optional, TextIO
from pygui.backend.models.frame import Frame from pygui.backend.models.frame import Frame
from pygui.backend.wafer.zwafer_models import Sensor from pygui.backend.wafer.zwafer_models import Sensor
class CsvRecorder: class CsvRecorder:
def __init__(self) -> None: def __init__(self) -> None:
self._file_handle: Optional[TextIO] = None self._file_handle: Optional[TextIO] = None
self._oath: Optional[str] = None self._oath: Optional[str] = None
@property @property
def is_recording(self) -> bool: def is_recording(self) -> bool:
return self._file_handle is not None return self._file_handle is not None
def start(self, path: str, sensors:list[Sensor], serial: str = "") -> None: def start(self, path: str, sensors:list[Sensor], serial: str = "") -> None:
Path(path).parent.mkdir(parents=True, exist_ok=True) Path(path).parent.mkdir(parents=True, exist_ok=True)
file_handle = open(path, "w", encoding="utf-8", newline ="") file_handle = open(path, "w", encoding="utf-8", newline ="")
@@ -30,14 +31,14 @@ class CsvRecorder:
file_handle.write("data\n") file_handle.write("data\n")
file_handle.flush() file_handle.flush()
self._file_handle, self._path = file_handle, path self._file_handle, self._path = file_handle, path
def write(self, frame: Frame) -> None: def write(self, frame: Frame) -> None:
if self._file_handle is None: if self._file_handle is None:
return return
row = [f"{frame.time:.3f}"] + [f"{v:.3f}" for v in frame.values] row = [f"{frame.time:.3f}"] + [f"{v:.3f}" for v in frame.values]
self._file_handle.write(",".join(row) + "\n") self._file_handle.write(",".join(row) + "\n")
self._file_handle.flush() self._file_handle.flush()
def stop(self) -> Optional[str]: def stop(self) -> Optional[str]:
if self._file_handle is None: if self._file_handle is None:
return None return None
+2
View File
@@ -1,9 +1,11 @@
"""Read the data section of a Z-wafer CSV into DataRecords, or the official headerless CSV.""" """Read the data section of a Z-wafer CSV into DataRecords, or the official headerless CSV."""
from __future__ import annotations from __future__ import annotations
from pathlib import Path from pathlib import Path
from pygui.backend.wafer.zwafer_models import DataRecord, Sensor from pygui.backend.wafer.zwafer_models import DataRecord, Sensor
def read_data_records(file_path: str) -> list[DataRecord]: def read_data_records(file_path: str) -> list[DataRecord]:
records: list[DataRecord] = [] records: list[DataRecord] = []
in_data = False in_data = False
+2 -2
View File
@@ -5,12 +5,12 @@ import re
from datetime import datetime from datetime import datetime
from pathlib import Path from pathlib import Path
from PySide6.QtCore import QObject, Property, QStandardPaths, Signal, Slot from PySide6.QtCore import Property, QObject, QStandardPaths, Signal, Slot
from PySide6.QtWidgets import QFileDialog, QMessageBox from PySide6.QtWidgets import QFileDialog, QMessageBox
from pygui.backend.data.constants import DEFAULT_DATA_DIR_NAME
from pygui.backend.data.csv_file_metadata import CSVFileMetadata from pygui.backend.data.csv_file_metadata import CSVFileMetadata
from pygui.backend.wafer.zwafer_parser import ZWaferParser from pygui.backend.wafer.zwafer_parser import ZWaferParser
from pygui.backend.data.constants import DEFAULT_DATA_DIR_NAME
# ===== File Browser Model ===== # ===== File Browser Model =====
@@ -4,11 +4,10 @@ from copy import deepcopy
from pathlib import Path from pathlib import Path
from typing import Any from typing import Any
from PySide6.QtCore import QObject, Property, QDateTime, QStandardPaths, Signal, Slot from PySide6.QtCore import Property, QDateTime, QObject, QStandardPaths, Signal, Slot
from pygui.backend.data.local_settings import LocalSettings
from pygui.backend.data.constants import DEFAULT_DATA_DIR_NAME from pygui.backend.data.constants import DEFAULT_DATA_DIR_NAME
from pygui.backend.data.local_settings import LocalSettings
MASTER_FAMILIES = ("A", "B", "C", "D", "E", "F", "P", "X", "Z") MASTER_FAMILIES = ("A", "B", "C", "D", "E", "F", "P", "X", "Z")
+3 -3
View File
@@ -1,12 +1,12 @@
# ===== Models Sub-package ===== # ===== Models Sub-package =====
from pygui.backend.models.data_model import TemperatureTableModel
from pygui.backend.models.frame import Frame from pygui.backend.models.frame import Frame
from pygui.backend.models.frame_player import FramePlayer, frames_from_wafer_data from pygui.backend.models.frame_player import FramePlayer, frames_from_wafer_data
from pygui.backend.models.frame_stats import Stats, compute_stats from pygui.backend.models.frame_stats import Stats, compute_stats
from pygui.backend.models.session_model import SessionModel, SessionUpdate
from pygui.backend.models.data_model import TemperatureTableModel
from pygui.backend.models.sensor_editor import SensorEditor from pygui.backend.models.sensor_editor import SensorEditor
from pygui.backend.models.threshold_classifier import ThresholdConfig, classify, resolve_bounds from pygui.backend.models.session_model import SessionModel, SessionUpdate
from pygui.backend.models.stability_detector import StabilityDetector from pygui.backend.models.stability_detector import StabilityDetector
from pygui.backend.models.threshold_classifier import ThresholdConfig, classify, resolve_bounds
__all__ = [ __all__ = [
"Frame", "FramePlayer", "frames_from_wafer_data", "Frame", "FramePlayer", "frames_from_wafer_data",
+1
View File
@@ -1,4 +1,5 @@
from __future__ import annotations from __future__ import annotations
from dataclasses import dataclass from dataclasses import dataclass
+13 -11
View File
@@ -1,7 +1,9 @@
from __future__ import annotations from __future__ import annotations
from pygui.backend.models.frame import Frame from pygui.backend.models.frame import Frame
from pygui.backend.wafer.zwafer_models import ZWaferData from pygui.backend.wafer.zwafer_models import ZWaferData
def frames_from_wafer_data(data: ZWaferData, records) -> list[Frame]: def frames_from_wafer_data(data: ZWaferData, records) -> list[Frame]:
"""Build Frames from parsed DataRecords (records = list[DataRecord].)""" """Build Frames from parsed DataRecords (records = list[DataRecord].)"""
return [Frame(seq=i, time=r.time, values=list(r.values)) for i, r in enumerate(records)] return [Frame(seq=i, time=r.time, values=list(r.values)) for i, r in enumerate(records)]
@@ -10,36 +12,36 @@ class FramePlayer:
def __init__(self) -> None: def __init__(self) -> None:
self._frames: list[Frame] =[] self._frames: list[Frame] =[]
self._i =0 self._i =0
def load(self, frames: list[Frame]) -> "FramePlayer": def load(self, frames: list[Frame]) -> "FramePlayer":
self._frames = frames self._frames = frames
self._i = 0 self._i = 0
return self return self
@property @property
def total(self) -> int: def total(self) -> int:
return len(self._frames) return len(self._frames)
@property @property
def index(self) -> int: def index(self) -> int:
return self._i return self._i
@property @property
def at_end(self) -> bool: def at_end(self) -> bool:
return self._i >= len(self._frames) -1 return self._i >= len(self._frames) -1
def current(self) -> Frame | None: def current(self) -> Frame | None:
if not self._frames: if not self._frames:
return None return None
return self._frames[self._i] return self._frames[self._i]
def _clamp(self, i:int): def _clamp(self, i:int):
return max(0, min(i, len(self._frames) - 1)) if self._frames else 0 return max(0, min(i, len(self._frames) - 1)) if self._frames else 0
def step(self, delta: int) -> "FramePlayer": def step(self, delta: int) -> "FramePlayer":
self._i = self._clamp(self._i + delta) self._i = self._clamp(self._i + delta)
return self return self
def seek(self, i: int) -> "FramePlayer": def seek(self, i: int) -> "FramePlayer":
self._i = self._clamp(i) self._i = self._clamp(i)
return self return self
@@ -48,4 +50,4 @@ class FramePlayer:
"""Wall-clock ms until the next frame based on recorded timestamps; 0 if at end.""" """Wall-clock ms until the next frame based on recorded timestamps; 0 if at end."""
if self._i + 1 >= len(self._frames): if self._i + 1 >= len(self._frames):
return 0.0 return 0.0
return (self._frames[self._i + 1].time - self._frames[self._i].time) * 1000.0 return (self._frames[self._i + 1].time - self._frames[self._i].time) * 1000.0
+1
View File
@@ -1,6 +1,7 @@
"""Per-frame descriptive statistics""" """Per-frame descriptive statistics"""
from __future__ import annotations from __future__ import annotations
import math import math
from dataclasses import dataclass from dataclasses import dataclass
+9 -9
View File
@@ -7,16 +7,16 @@ class SensorEditor:
def __init__(self) -> None: def __init__(self) -> None:
self._replacements: dict[int, float] = {} self._replacements: dict[int, float] = {}
self._offsets: dict[int, float] = {} self._offsets: dict[int, float] = {}
def set_replacement(self, index: int, value: float) -> None: def set_replacement(self, index: int, value: float) -> None:
"""Force sensor `index` to read `value` for every frame this session.""" """Force sensor `index` to read `value` for every frame this session."""
self._replacements[index] = value self._replacements[index] = value
def set_offset(self, index: int, value: float) -> None: def set_offset(self, index: int, value: float) -> None:
"""Shift sensor `index` by `delta` (applied after any replacement).""" """Shift sensor `index` by `delta` (applied after any replacement)."""
self._offsets[index] = value self._offsets[index] = value
def clear(self, index: int | None = None) -> None: def clear(self, index: int | None = None) -> None:
"""Remove overrides. Pass an index to clear one sensor; omit to clear all.""" """Remove overrides. Pass an index to clear one sensor; omit to clear all."""
if index is None: if index is None:
@@ -27,16 +27,16 @@ class SensorEditor:
self._offsets.pop(index, None) self._offsets.pop(index, None)
def has_overrides(self) -> bool: def has_overrides(self) -> bool:
return bool(self._replacements or self._offsets) return bool(self._replacements or self._offsets)
def active_indices(self) -> list[int]: def active_indices(self) -> list[int]:
"""Return sorted sensor indices that have any override.""" """Return sorted sensor indices that have any override."""
return sorted(set(self._replacements) | set(self._offsets)) return sorted(set(self._replacements) | set(self._offsets))
def apply(self, values: list[float]) -> list[float]: def apply(self, values: list[float]) -> list[float]:
"""Return a new list wit all overrides applied (original unchanged)""" """Return a new list wit all overrides applied (original unchanged)"""
if not self.has_overrides(): if not self.has_overrides():
return list(values) return list(values)
result = list(values) result = list(values)
for i in range(len(result)): for i in range(len(result)):
v = result[i] v = result[i]
@@ -45,4 +45,4 @@ class SensorEditor:
if i in self._offsets: if i in self._offsets:
v += self._offsets[i] v += self._offsets[i]
result[i] = v result[i] = v
return result return result
+8 -6
View File
@@ -1,4 +1,5 @@
from __future__ import annotations from __future__ import annotations
from dataclasses import dataclass from dataclasses import dataclass
from pygui.backend.models.frame import Frame from pygui.backend.models.frame import Frame
@@ -6,6 +7,7 @@ from pygui.backend.models.frame_stats import Stats, compute_stats
from pygui.backend.models.stability_detector import StabilityDetector from pygui.backend.models.stability_detector import StabilityDetector
from pygui.backend.models.threshold_classifier import ThresholdConfig, classify, resolve_bounds from pygui.backend.models.threshold_classifier import ThresholdConfig, classify, resolve_bounds
@dataclass(frozen=True) @dataclass(frozen=True)
class SessionUpdate: class SessionUpdate:
seq: int seq: int
@@ -15,18 +17,18 @@ class SessionUpdate:
state: str state: str
target: float target: float
margin: float margin: float
class SessionModel: class SessionModel:
def __init__(self, thresholds: ThresholdConfig | None = None) -> None: def __init__(self, thresholds: ThresholdConfig | None = None) -> None:
self._config = thresholds or ThresholdConfig() self._config = thresholds or ThresholdConfig()
self._stability = StabilityDetector() self._stability = StabilityDetector()
def set_thresholds(self, config: ThresholdConfig) -> None: def set_thresholds(self, config: ThresholdConfig) -> None:
self._config = config self._config = config
def reset(self) -> None: def reset(self) -> None:
self._stability.reset() self._stability.reset()
def process(self, frame: Frame) -> SessionUpdate: def process(self, frame: Frame) -> SessionUpdate:
stats = compute_stats(frame.values) stats = compute_stats(frame.values)
target, margin = resolve_bounds(frame.values, self._config) target, margin = resolve_bounds(frame.values, self._config)
@@ -34,6 +36,6 @@ class SessionModel:
# State always track the user's process set_point, even in auto-color mode. # State always track the user's process set_point, even in auto-color mode.
state = self._stability.update(stats.avg, frame.time, self._config.set_point) state = self._stability.update(stats.avg, frame.time, self._config.set_point)
return SessionUpdate( return SessionUpdate(
seq=frame.seq, values=frame.values, bands=bands, seq=frame.seq, values=frame.values, bands=bands,
stats=stats, state=state, target=target, margin=margin, stats=stats, state=state, target=target, margin=margin,
) )
@@ -1,5 +1,6 @@
"""Detect process state (Idle, Ramp, Set) from the running average temp""" """Detect process state (Idle, Ramp, Set) from the running average temp"""
from __future__ import annotations from __future__ import annotations
from typing import Optional from typing import Optional
STATE_IDLE = "idle" STATE_IDLE = "idle"
@@ -7,28 +8,27 @@ STATE_RAMP = "ramp"
STATE_SET = "set" STATE_SET = "set"
class StabilityDetector: class StabilityDetector:
def __init__(self, idle_below: float = 50.0, tolerance: float = 1.0, def __init__(self, idle_below: float = 50.0, tolerance: float = 1.0,
settle_seconds: float = 10.0) -> None: settle_seconds: float = 10.0) -> None:
self._idle_below = idle_below self._idle_below = idle_below
self._tolerance = tolerance self._tolerance = tolerance
self._settle_seconds = settle_seconds self._settle_seconds = settle_seconds
self._near_since: Optional[float] = None # When avg entered the +- tolerance band self._near_since: Optional[float] = None # When avg entered the +- tolerance band
def reset(self) -> None: def reset(self) -> None:
self._near_since = None self._near_since = None
def update(self, avg: float, time: float, set_point: float) ->str: def update(self, avg: float, time: float, set_point: float) ->str:
if avg < self._idle_below: if avg < self._idle_below:
self._near_since = None self._near_since = None
return STATE_IDLE return STATE_IDLE
if abs(avg - set_point) <= self._tolerance: if abs(avg - set_point) <= self._tolerance:
if self._near_since is None: if self._near_since is None:
self._near_since = time self._near_since = time
if time - self._near_since >= self._settle_seconds: if time - self._near_since >= self._settle_seconds:
return STATE_SET return STATE_SET
return STATE_RAMP return STATE_RAMP
self._near_since = None self._near_since = None
return STATE_RAMP return STATE_RAMP
@@ -4,11 +4,12 @@ Auto mode derives target=mean, margin=1
""" """
from __future__ import annotations from __future__ import annotations
import math import math
from dataclasses import dataclass from dataclasses import dataclass
BAND_IN = "in_range" BAND_IN = "in_range"
BAND_HIGH = "high" BAND_HIGH = "high"
BAND_LOW = "low" BAND_LOW = "low"
@@ -39,4 +40,4 @@ def classify(value: float, target: float, margin: float) -> str:
def classify_all(values: list[float], cfg: ThresholdConfig) -> list[str]: def classify_all(values: list[float], cfg: ThresholdConfig) -> list[str]:
target, margin = resolve_bounds(values, cfg) target, margin = resolve_bounds(values, cfg)
return [classify(v, target, margin)for v in values ] return [classify(v, target, margin)for v in values ]
+2 -2
View File
@@ -1,8 +1,8 @@
# ===== Visualization Sub-package ===== # ===== Visualization Sub-package =====
from pygui.backend.visualization.wafer_map_item import WaferMapItem from pygui.backend.visualization.contour_models import ContourLine, ContourSegment
from pygui.backend.visualization.graph_view import GraphView from pygui.backend.visualization.graph_view import GraphView
from pygui.backend.visualization.rbf_heatmap import interpolate_field from pygui.backend.visualization.rbf_heatmap import interpolate_field
from pygui.backend.visualization.contour_models import ContourLine, ContourSegment from pygui.backend.visualization.wafer_map_item import WaferMapItem
__all__ = [ __all__ = [
"WaferMapItem", "GraphView", "WaferMapItem", "GraphView",
@@ -9,7 +9,7 @@ from __future__ import annotations
import logging import logging
from typing import Any, Optional from typing import Any, Optional
from PySide6.QtCore import QObject, Property, Signal, Slot from PySide6.QtCore import Property, QObject, Signal, Slot
from PySide6.QtWidgets import QWidget from PySide6.QtWidgets import QWidget
log = logging.getLogger(__name__) log = logging.getLogger(__name__)
@@ -1,4 +1,4 @@
from typing import List, Tuple, Optional from typing import List, Optional, Tuple
import numpy as np import numpy as np
@@ -13,9 +13,15 @@ from __future__ import annotations
import math import math
import numpy as np import numpy as np
from PySide6.QtCore import Property, QPoint, Signal, Slot, Qt from PySide6.QtCore import Property, QPoint, Qt, Signal, Slot
from PySide6.QtGui import ( from PySide6.QtGui import (
QBrush, QColor, QFont, QImage, QPainter, QPen, QPolygon, QBrush,
QColor,
QFont,
QImage,
QPainter,
QPen,
QPolygon,
) )
from PySide6.QtQml import QmlElement from PySide6.QtQml import QmlElement
from PySide6.QtQuick import QQuickPaintedItem from PySide6.QtQuick import QQuickPaintedItem
+2 -2
View File
@@ -1,7 +1,7 @@
# ===== Wafer Sub-package ===== # ===== Wafer Sub-package =====
from pygui.backend.wafer.zwafer_models import ZWaferData, Sensor, DataRecord from pygui.backend.wafer.wafer_layouts import available_families, load_layout
from pygui.backend.wafer.zwafer_models import DataRecord, Sensor, ZWaferData
from pygui.backend.wafer.zwafer_parser import ZWaferParser from pygui.backend.wafer.zwafer_parser import ZWaferParser
from pygui.backend.wafer.wafer_layouts import load_layout, available_families
__all__ = [ __all__ = [
"ZWaferData", "Sensor", "DataRecord", "ZWaferData", "Sensor", "DataRecord",
+3 -3
View File
@@ -1,8 +1,8 @@
from datetime import datetime
from pathlib import Path from pathlib import Path
from typing import Tuple, Optional from typing import Optional, Tuple
from datetime import datetime, timedelta
from pygui.backend.wafer.zwafer_models import ZWaferData, Sensor from pygui.backend.wafer.zwafer_models import Sensor, ZWaferData
# ===== Z-Wafer CSV Parser ===== # ===== Z-Wafer CSV Parser =====
+1 -2
View File
@@ -6,7 +6,6 @@ QML via @Slot methods on a QObject controller.
""" """
import logging import logging
from pathlib import Path
from typing import Optional from typing import Optional
import serial.tools.list_ports import serial.tools.list_ports
@@ -42,8 +41,8 @@ class DeviceService:
# On macOS/Linux, also detect virtual loopback serial ports (PTYs) opened by socat # On macOS/Linux, also detect virtual loopback serial ports (PTYs) opened by socat
import platform import platform
import subprocess
import re import re
import subprocess
if platform.system() in ("Darwin", "Linux"): if platform.system() in ("Darwin", "Linux"):
try: try:
+3 -2
View File
@@ -1,5 +1,6 @@
"""Continuous serial frame reader (Live-mode source)""" """Continuous serial frame reader (Live-mode source)"""
from __future__ import annotations from __future__ import annotations
import logging import logging
import threading import threading
import time import time
@@ -13,7 +14,7 @@ log = logging.getLogger(__name__)
ParseFrame = Callable[[bytes, int], Frame] ParseFrame = Callable[[bytes, int], Frame]
class StreamReader: class StreamReader:
def __init__(self, transport, parse_frame: ParseFrame, def __init__(self, transport, parse_frame: ParseFrame,
on_frame: Callable[[Frame], None], on_frame: Callable[[Frame], None],
on_error: Callable[[Exception], None] | None = None, on_error: Callable[[Exception], None] | None = None,
@@ -26,7 +27,7 @@ class StreamReader:
self._thread: threading.Thread | None = None self._thread: threading.Thread | None = None
self._stop = threading.Event() self._stop = threading.Event()
self.error_count = 0 self.error_count = 0
def start(self) -> None: def start(self) -> None:
self._stop.clear() self._stop.clear()
self._thread = threading.Thread(target=self._run, daemon = True) self._thread = threading.Thread(target=self._run, daemon = True)
Generated
+268 -4
View File
@@ -2,11 +2,14 @@ version = 1
revision = 3 revision = 3
requires-python = ">=3.11" requires-python = ">=3.11"
resolution-markers = [ resolution-markers = [
"python_full_version >= '3.14' and sys_platform == 'darwin'", "python_full_version >= '3.15' and sys_platform == 'darwin'",
"python_full_version == '3.14.*' and sys_platform == 'darwin'",
"python_full_version < '3.14' and sys_platform == 'darwin'", "python_full_version < '3.14' and sys_platform == 'darwin'",
"python_full_version >= '3.14' and sys_platform == 'win32'", "python_full_version >= '3.15' and sys_platform == 'win32'",
"python_full_version == '3.14.*' and sys_platform == 'win32'",
"python_full_version < '3.14' and sys_platform == 'win32'", "python_full_version < '3.14' and sys_platform == 'win32'",
"python_full_version >= '3.14' and sys_platform == 'linux'", "python_full_version >= '3.15' and sys_platform == 'linux'",
"python_full_version == '3.14.*' and sys_platform == 'linux'",
"python_full_version < '3.14' and sys_platform == 'linux'", "python_full_version < '3.14' and sys_platform == 'linux'",
] ]
supported-markers = [ supported-markers = [
@@ -15,6 +18,46 @@ supported-markers = [
"sys_platform == 'linux'", "sys_platform == 'linux'",
] ]
[[package]]
name = "ast-serialize"
version = "0.5.0"
source = { registry = "https://pypi.org/simple" }
sdist = { url = "https://files.pythonhosted.org/packages/81/9d/09e27731bd5864a9ce04e3244074e674bb8936bf62b45e0357248717adac/ast_serialize-0.5.0.tar.gz", hash = "sha256:5880091bfe6f4f986f22866375c2e884843e7a0b6343ae41aeea659613d879b6", size = 61157, upload-time = "2026-05-17T17:48:29.429Z" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/c0/9a/13dde51ba9e15f8b97957ab7cb0120d0e381524d651c6bd630b9c359227f/ast_serialize-0.5.0-cp314-cp314t-macosx_10_12_x86_64.whl", hash = "sha256:8f5c14f169eb0972c0c21bada5358b23d6047c76583b005234f865b11f1fa00a", size = 1183520, upload-time = "2026-05-17T17:47:30.831Z" },
{ url = "https://files.pythonhosted.org/packages/37/de/5a7f0a9fe68944f536632a5af84676739c7d2582be42deb082634bf3a754/ast_serialize-0.5.0-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:7d1a2de9de5be04652f0ed60738356ef94f66db37924a9499fffe98dc491aa0b", size = 1175779, upload-time = "2026-05-17T17:47:32.551Z" },
{ url = "https://files.pythonhosted.org/packages/9c/81/0bb853e76e4f6e9a1855d569003c59e19ffac45f7079d91505d1bb212f92/ast_serialize-0.5.0-cp314-cp314t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:be5173fb66f9b49026d9d5a2ff0fc7c7009077107c0eb285b2d60fdf1fe10bd1", size = 1233750, upload-time = "2026-05-17T17:47:34.731Z" },
{ url = "https://files.pythonhosted.org/packages/e5/d3/4cf705beeccc08754d0bbda99aefff26110e209b9a07ac8a6b60eec48531/ast_serialize-0.5.0-cp314-cp314t-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:f8015cd071ac1339924ee2b8098c93e00e155f30a16f40ec9816fcf84f4753f6", size = 1235942, upload-time = "2026-05-17T17:47:36.287Z" },
{ url = "https://files.pythonhosted.org/packages/26/c8/ee097e437ea27dd2b8b227865c875492b585650a5802a22d82b304c8201b/ast_serialize-0.5.0-cp314-cp314t-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5499e8797edff2a9186aa313ed382c6b422e798e9332d9953badcee6e69a88f2", size = 1442517, upload-time = "2026-05-17T17:47:38.17Z" },
{ url = "https://files.pythonhosted.org/packages/ff/bd/68063442838f1ba68ec72b5436430bc75b3bb17a1a3c3063f09b0c05ae2b/ast_serialize-0.5.0-cp314-cp314t-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:6848f2a093fb5548751a9a09bff8fcd229e2bbeb0e3331f391b6ae6d26cd9903", size = 1254081, upload-time = "2026-05-17T17:47:39.826Z" },
{ url = "https://files.pythonhosted.org/packages/50/e2/1e520793bc6a4e4524a6ab022391e827825eaa0c3811828bfdc6852eca26/ast_serialize-0.5.0-cp314-cp314t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:832d4c998e0b091fd60a6d6bceee535483c4d490de9ba85003af835225719261", size = 1259910, upload-time = "2026-05-17T17:47:41.369Z" },
{ url = "https://files.pythonhosted.org/packages/4e/e1/49b60f467979979cfe6913b43948ff25bca971ad0591d181812f163a988e/ast_serialize-0.5.0-cp314-cp314t-manylinux_2_31_riscv64.whl", hash = "sha256:16db7c62ec0b8efe1d7afd283a388d8f74f2605d56032e5a37747d2de8dba027", size = 1250678, upload-time = "2026-05-17T17:47:43.702Z" },
{ url = "https://files.pythonhosted.org/packages/74/ba/66ab9555de6275677566f6574e5ef6c29cb185ea866f643bc06f8280a8ee/ast_serialize-0.5.0-cp314-cp314t-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:baf5eb061eb5bccade4128ad42da33787d72f6013809cd1b590376ece8b3c937", size = 1301603, upload-time = "2026-05-17T17:47:46.256Z" },
{ url = "https://files.pythonhosted.org/packages/66/42/6aca9b9abc710014b2be9059689e5dd1679339e78f567ffb4d255a9e2050/ast_serialize-0.5.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:104e4a35bd7c124173c41760ef9aaea17ddb3f86c65cb643671d59afbe3ee94c", size = 1410332, upload-time = "2026-05-17T17:47:47.899Z" },
{ url = "https://files.pythonhosted.org/packages/47/68/2f76594432a22581ecf878b5e75a9b8601c24b2241cf0bbeb1e21fcf370c/ast_serialize-0.5.0-cp314-cp314t-musllinux_1_2_armv7l.whl", hash = "sha256:36be371028fc1675acb38a331bde160dbab7ff907fdf00b67eb6911aa106951b", size = 1509979, upload-time = "2026-05-17T17:47:50.942Z" },
{ url = "https://files.pythonhosted.org/packages/40/ac/a93c9b58292653f6c595752f677a08e608f903b710594909e9231a389b3b/ast_serialize-0.5.0-cp314-cp314t-musllinux_1_2_i686.whl", hash = "sha256:061ee58bdb52341c8201a6df41182a977736bae3b7ded87ca7176ca25a8a47ab", size = 1505002, upload-time = "2026-05-17T17:47:54.093Z" },
{ url = "https://files.pythonhosted.org/packages/14/2e/b278f68c497ee2f1d1576cbbef8db5281cd4a5f2db040537592ac9c8862e/ast_serialize-0.5.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:b15219e9cdc9f53f6f4cb51c009203507228226148c05c5e8fe451c28b435eb3", size = 1456231, upload-time = "2026-05-17T17:47:56.311Z" },
{ url = "https://files.pythonhosted.org/packages/0b/43/419be1c566a4c504cd8fd60ce2f84e790f295495c0f327cfaeadf3d51012/ast_serialize-0.5.0-cp314-cp314t-win32.whl", hash = "sha256:842d1c004bb466c7df036f95fabef789570541922b10976b12f5592a69cf0b38", size = 1058668, upload-time = "2026-05-17T17:47:58.305Z" },
{ url = "https://files.pythonhosted.org/packages/03/6f/c9d4d549295ed05111aeb8853232d1afd9d0a179fddb01eeffbb3a4a6842/ast_serialize-0.5.0-cp314-cp314t-win_amd64.whl", hash = "sha256:b0c06d760909b095cc466356dfccd05a1c7233a6ca191c020dca2c6a6f16c24c", size = 1101075, upload-time = "2026-05-17T17:48:00.35Z" },
{ url = "https://files.pythonhosted.org/packages/d0/8e/d00c5ab30c58222e07d62956fca86c59d91b9ad32997e633c38b526623a3/ast_serialize-0.5.0-cp314-cp314t-win_arm64.whl", hash = "sha256:787baedb0262cc49e8ce37cc15c00ae818e46a165a3b36f5e21ed174998104cb", size = 1075347, upload-time = "2026-05-17T17:48:01.753Z" },
{ url = "https://files.pythonhosted.org/packages/e0/9e/dc2530acb3a60dc6e46d65abf27d1d9f86721694757906a148d90a6860de/ast_serialize-0.5.0-cp39-abi3-macosx_10_12_x86_64.whl", hash = "sha256:0668aa9459cfa8c9c49ddd2163ebcf43088ba045ef7492af6fe22e0098303101", size = 1191380, upload-time = "2026-05-17T17:48:03.738Z" },
{ url = "https://files.pythonhosted.org/packages/26/0a/bd3d18a582f273d6c843d16bb9e22e9e16365ff7991e92f18f798e9f1224/ast_serialize-0.5.0-cp39-abi3-macosx_11_0_arm64.whl", hash = "sha256:bf683d6363edf2b39eed6b6d4fe22d34b6203867a67e27134d9e2a2680c4bc4a", size = 1183879, upload-time = "2026-05-17T17:48:05.463Z" },
{ url = "https://files.pythonhosted.org/packages/40/ae/1f919100f8620887af58fcc381c61a1f218cdf89c6e155f87b213e61010a/ast_serialize-0.5.0-cp39-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9cc22cf0c9be65e71cf88fda130af60d61eb4a79370ad4cfe7900d48a4aa2211", size = 1244529, upload-time = "2026-05-17T17:48:07.008Z" },
{ url = "https://files.pythonhosted.org/packages/c6/ca/6376559dcce707cdbc1d0d9a13c8d3baaaa501e949ce0ebdc4230cd881aa/ast_serialize-0.5.0-cp39-abi3-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:f66173891548c9f2726bf27957b41cabce12fa679dc6da505ddbde4d4b3b31cf", size = 1240560, upload-time = "2026-05-17T17:48:08.46Z" },
{ url = "https://files.pythonhosted.org/packages/35/b2/a620e206b5aeb7efbf2710336df57d457cffbb3991076bbcc1147ef9abd4/ast_serialize-0.5.0-cp39-abi3-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e42d729ef2be96a14efbad355093284739e3670ece3e534f82cc8832790911d9", size = 1451172, upload-time = "2026-05-17T17:48:09.922Z" },
{ url = "https://files.pythonhosted.org/packages/fa/e0/4ad5c04c24a40481b2935ce9a0ccdb6023dc8b667167d06ae530cc3512f2/ast_serialize-0.5.0-cp39-abi3-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b725026bafa801dbd7310eb13a75f0a2e370e7e51b2cb225f9d21fcfadf919ee", size = 1265072, upload-time = "2026-05-17T17:48:11.469Z" },
{ url = "https://files.pythonhosted.org/packages/b2/71/4d1d479aa56d0101c40e17720c3d6ac2af7269ea0487a80b18e7bfd1a5b7/ast_serialize-0.5.0-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b54f60c1d78767a53b67eaa663f0dfac3afe606aa07f1301572f588b73d64809", size = 1270488, upload-time = "2026-05-17T17:48:13.575Z" },
{ url = "https://files.pythonhosted.org/packages/6d/4f/0de1bbe06f6edef9fde4ed12ca8e7b3ec7e6e2bd4e672c5af487f7957665/ast_serialize-0.5.0-cp39-abi3-manylinux_2_31_riscv64.whl", hash = "sha256:27d51654fc240a1e87e742d353d98eb45b75f62f129086b3596ab53df2ac2a43", size = 1260702, upload-time = "2026-05-17T17:48:15.141Z" },
{ url = "https://files.pythonhosted.org/packages/75/61/e00872439cfdddcc3c1b6cdaa6e5d904ba8e26a18807c67c4e14409d0ca8/ast_serialize-0.5.0-cp39-abi3-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:2782c36237c46dd1674542f2109740ea5ea485a169bf1431939ada0434e17934", size = 1311182, upload-time = "2026-05-17T17:48:16.779Z" },
{ url = "https://files.pythonhosted.org/packages/76/8e/699a5b955f7926956c95e9e1d74132acad73c2fe7a426f94da89123c20aa/ast_serialize-0.5.0-cp39-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:1943db345233cc7194a470f13afa9c59772c0b123dea0c9414c4d4ca54369759", size = 1421410, upload-time = "2026-05-17T17:48:18.527Z" },
{ url = "https://files.pythonhosted.org/packages/a9/ae/d5b7626874478997adc7a29ab28accf21e596fb590c944290401dfd0b29e/ast_serialize-0.5.0-cp39-abi3-musllinux_1_2_armv7l.whl", hash = "sha256:df1c00022cbbcb064bfaa505aa9c9295362443ce5dacb459d1331d3da353f887", size = 1516587, upload-time = "2026-05-17T17:48:20.133Z" },
{ url = "https://files.pythonhosted.org/packages/0c/ce/b59e02a82d9c4244d64cde502e0b00e83e38816abe19155ceb5437402c7f/ast_serialize-0.5.0-cp39-abi3-musllinux_1_2_i686.whl", hash = "sha256:cae65289fc456fde04af979a2be09302ef5d8ab92ef23e596d6746dc267ada27", size = 1515171, upload-time = "2026-05-17T17:48:21.921Z" },
{ url = "https://files.pythonhosted.org/packages/8b/38/d8d90042747d05aa08d4efcf1c99035a5f670a6bf4c214d31644392afbca/ast_serialize-0.5.0-cp39-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:239a4c354e8d676e9d94631d1d4a64edc6b266f86ff3a5a80aedd344f342c01d", size = 1464668, upload-time = "2026-05-17T17:48:23.544Z" },
{ url = "https://files.pythonhosted.org/packages/dd/51/5b840c4df7334104cecffa28f23904fe81ca89ca223d2450e288de39fd3c/ast_serialize-0.5.0-cp39-abi3-win32.whl", hash = "sha256:143a4ef63285a075871908fda3672dc21864b83a8ec3ee12304aa3e4c5387b9a", size = 1068311, upload-time = "2026-05-17T17:48:25.027Z" },
{ url = "https://files.pythonhosted.org/packages/41/11/ca5672c7d491825bc4cd6702dea106a6b60d928707712ec257c7833ae476/ast_serialize-0.5.0-cp39-abi3-win_amd64.whl", hash = "sha256:cf25572c526add400f26a4750dc6ce0c3bb93fc1f75e7ae0cad4ce4f2cd5c590", size = 1108931, upload-time = "2026-05-17T17:48:26.591Z" },
{ url = "https://files.pythonhosted.org/packages/45/19/cc8bd127d28a43da249aa955cfd164cf8fd534e79e42cea96c4854d72fd0/ast_serialize-0.5.0-cp39-abi3-win_arm64.whl", hash = "sha256:92a31c9c20d25a076edaeec76b128a3535d74a24f340b9a8a7e96c9b86dc9642", size = 1081181, upload-time = "2026-05-17T17:48:28.122Z" },
]
[[package]] [[package]]
name = "colorama" name = "colorama"
version = "0.4.6" version = "0.4.6"
@@ -115,6 +158,43 @@ wheels = [
{ url = "https://files.pythonhosted.org/packages/e7/05/c19819d5e3d95294a6f5947fb9b9629efb316b96de511b418c53d245aae6/cycler-0.12.1-py3-none-any.whl", hash = "sha256:85cef7cff222d8644161529808465972e51340599459b8ac3ccbac5a854e0d30", size = 8321, upload-time = "2023-10-07T05:32:16.783Z" }, { url = "https://files.pythonhosted.org/packages/e7/05/c19819d5e3d95294a6f5947fb9b9629efb316b96de511b418c53d245aae6/cycler-0.12.1-py3-none-any.whl", hash = "sha256:85cef7cff222d8644161529808465972e51340599459b8ac3ccbac5a854e0d30", size = 8321, upload-time = "2023-10-07T05:32:16.783Z" },
] ]
[[package]]
name = "dtw-python"
version = "1.7.5"
source = { registry = "https://pypi.org/simple" }
dependencies = [
{ name = "numpy", marker = "sys_platform == 'darwin' or sys_platform == 'linux' or sys_platform == 'win32'" },
{ name = "scipy", marker = "sys_platform == 'darwin' or sys_platform == 'linux' or sys_platform == 'win32'" },
]
sdist = { url = "https://files.pythonhosted.org/packages/fc/ac/e0967e71019959197e2f8a4e99937f043f35fa1efc2ac30294ecc8b3df77/dtw_python-1.7.5.tar.gz", hash = "sha256:650dec798812dcda3aab059a5dcf5954d34d33903479df00b90d33956b7b04b3", size = 274203, upload-time = "2026-06-12T12:01:02.056Z" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/a2/67/525d4ffdea5c5f6108b902836f999bc2d976024d0ee51aaca3f5c7c72304/dtw_python-1.7.5-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:ba1833e86fd6c242686a60ab17f68c4dcad0a5893d4ee9592199bc4bb13542e9", size = 362862, upload-time = "2026-06-12T12:00:12.657Z" },
{ url = "https://files.pythonhosted.org/packages/83/c6/171b45921c90fe5bd7578f9cad28223087948a4c399e7efad2dc992c0e26/dtw_python-1.7.5-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:ff683ff4f59168c28b408f6eda5df9a8f3961ec3505df55d97c4ccb64ed3c143", size = 353355, upload-time = "2026-06-12T12:00:14.164Z" },
{ url = "https://files.pythonhosted.org/packages/0a/c6/1885f820b1c3a685577f8dc95b47195e4a970fc3a7f0cad0c30d2051f3be/dtw_python-1.7.5-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:4ab61eac7124f406117b209f328802b1227327c48ce1226544d732a77a5da887", size = 804376, upload-time = "2026-06-12T12:00:15.869Z" },
{ url = "https://files.pythonhosted.org/packages/6b/d4/1a7ab2834b7def8012ed0723c0fa53fa555bf636e934daffdbcd78da0f77/dtw_python-1.7.5-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:0895c9e808917bc028093970d38fffe7b588aaba873bb1762cddc9048967b302", size = 810839, upload-time = "2026-06-12T12:00:17.494Z" },
{ url = "https://files.pythonhosted.org/packages/5d/c1/3d11f3076fb512ad3342b73f6f5d806c72ed2bcf46fa1c6ed7f662f4a0bc/dtw_python-1.7.5-cp311-cp311-win_amd64.whl", hash = "sha256:97b525f28f714809aa87af6b34e2642d7a34b34a489475aa0e55f7a079f3c376", size = 355061, upload-time = "2026-06-12T12:00:18.889Z" },
{ url = "https://files.pythonhosted.org/packages/65/af/fc153af0859cfc72877e10e69e01c6e2a853883572f4e3e54446e0a92c57/dtw_python-1.7.5-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:b68a2e2214a563f2d501db98f4f1bc66b8086a7099b9a79b7e5bcf9fb58478b7", size = 363216, upload-time = "2026-06-12T12:00:20.332Z" },
{ url = "https://files.pythonhosted.org/packages/77/1a/a4d45bbf24f3a65db351067113c763caa2f1a94e0f92238baf938fa52ff7/dtw_python-1.7.5-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:fe7d328b15a23ae84d627e9b17a6caa837130daa11704f73edcf92f722f6a847", size = 352937, upload-time = "2026-06-12T12:00:21.721Z" },
{ url = "https://files.pythonhosted.org/packages/30/83/031fcbb1c01b95257bfc428e2a734492ed8380e852e64aa6d8be3f3d7ae9/dtw_python-1.7.5-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:cd71e57352c1890751c9747a440c2b97e1f21c69126dcd6761451e12aefd0e03", size = 798160, upload-time = "2026-06-12T12:00:23.436Z" },
{ url = "https://files.pythonhosted.org/packages/9b/84/faff713299bf94fff1d881b34bcd526945605f8f0a0b7e9546bc1e2d0b29/dtw_python-1.7.5-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:07c6e461be79290048c39c67b75bb668d44adfe4140ec90fbe0bd69d17c9ec8f", size = 808882, upload-time = "2026-06-12T12:00:25.209Z" },
{ url = "https://files.pythonhosted.org/packages/60/f3/dda5a0eb3e3e4a8355dd088b8cdaef3ba81ad5865bd4c0b117b82fef7c67/dtw_python-1.7.5-cp312-cp312-win_amd64.whl", hash = "sha256:ee8fabda2d7ce6719706f225fb24c3c74ac3b132499d9f100a0f9fe8db62223d", size = 355363, upload-time = "2026-06-12T12:00:26.807Z" },
{ url = "https://files.pythonhosted.org/packages/55/58/ed2a2df535f6ec57c1e57491d0e1cc49e21ceb51eef892e04dea1ce3ab4f/dtw_python-1.7.5-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:0e2d3831725a5624fa3dc6e856d5a64e3abd9653c5d4931ab8243483d85403d5", size = 362481, upload-time = "2026-06-12T12:00:28.549Z" },
{ url = "https://files.pythonhosted.org/packages/be/f7/bd77807d20ba15bd24fa5b0ced2517af7fb81d74512358808369becac3d8/dtw_python-1.7.5-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:deb1578f8432e727310cbb26e077e391e89884067dcb8c91f39f5b061f508010", size = 352232, upload-time = "2026-06-12T12:00:30.395Z" },
{ url = "https://files.pythonhosted.org/packages/e5/81/2995f25eba1d4b1b07bfcaf8e3042f1430f9b31d793b689e8c452b216324/dtw_python-1.7.5-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:c3a0bbfdb26e1663cca033b3b1b78c5960396ee4eb6b1b7f11d22452b4f9a2ac", size = 794385, upload-time = "2026-06-12T12:00:32.135Z" },
{ url = "https://files.pythonhosted.org/packages/7f/f6/93cbcaf002218928607d7cfcb0f0059c4a758c7531e85e4a12467db85997/dtw_python-1.7.5-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:a29dca9fa0973d50a4d36cc9adda37135fa84cf758de60be429e88b19429de17", size = 805456, upload-time = "2026-06-12T12:00:33.955Z" },
{ url = "https://files.pythonhosted.org/packages/9b/df/7c017afd7c9b071146364168e6c41582467a4e259dce8e5af57a6b959bd1/dtw_python-1.7.5-cp313-cp313-win_amd64.whl", hash = "sha256:1403cb6732bee6746684e01c9612e97b789c03e854fbc6a8d9f0f10b553b7600", size = 355107, upload-time = "2026-06-12T12:00:35.446Z" },
{ url = "https://files.pythonhosted.org/packages/00/74/6de262d5b4739b799ee9f9f8af68053c07d8cbbd2cc116e48d09142055a8/dtw_python-1.7.5-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:847e976b0a10aa8cc769f68c1b4e4384655b5368881f894a6e0a2c4917fd2bc0", size = 364868, upload-time = "2026-06-12T12:00:37.131Z" },
{ url = "https://files.pythonhosted.org/packages/ce/26/ca3f76c5e038446c7083bd692679309362464c85785ce2b18bc053b44c03/dtw_python-1.7.5-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:4847eb3aab755e0002448cbb551f46bd918a73769f1d21ab7249864fe953dd4c", size = 354827, upload-time = "2026-06-12T12:00:38.789Z" },
{ url = "https://files.pythonhosted.org/packages/43/1d/814a0ed64b0a23f8cadbd70cacc35b61b372a081655473d0125c71faf839/dtw_python-1.7.5-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:2e75ab7c6d5f17092c857278daf4e348a47f5d3baba4fdc4f77955e6324f5248", size = 794675, upload-time = "2026-06-12T12:00:40.453Z" },
{ url = "https://files.pythonhosted.org/packages/21/d0/5d8c5f235df6b9d8a95bd1655aceb7fc5f87721d86a3a2672754e0b45f4e/dtw_python-1.7.5-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:b6248e1ff498eb2d7eaac33f2c9f1916a3896536309a8458795616372ba4cd68", size = 803597, upload-time = "2026-06-12T12:00:42.322Z" },
{ url = "https://files.pythonhosted.org/packages/5a/9f/7df6c0021701aad73a4b0fe4f810a23dd25972757413fc292b12c0ebfd42/dtw_python-1.7.5-cp314-cp314-win_amd64.whl", hash = "sha256:a4d51e266d85f4b127cba77f5e62fe9b545c6e154785f9f8261765eb758b11c6", size = 357685, upload-time = "2026-06-12T12:00:43.925Z" },
{ url = "https://files.pythonhosted.org/packages/db/b1/0966c501a625658b722f495121fd20e8a05ddbffd3902238a7bb2fd5a0b5/dtw_python-1.7.5-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:d08143c647445777328dd95b2918ead08b83d7e51be62f54e57f3f2999db9e89", size = 369619, upload-time = "2026-06-12T12:00:45.369Z" },
{ url = "https://files.pythonhosted.org/packages/6c/f4/cc109a2a07df1ce8b164e16ab0ea35f4f016dc0bf99f148ba4a618c79b26/dtw_python-1.7.5-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:ed8067f4329dddccf3885f5d10c91c7564fe36ce2f66c675fe6fa97e6eb6207a", size = 362458, upload-time = "2026-06-12T12:00:46.86Z" },
{ url = "https://files.pythonhosted.org/packages/90/a7/3a258ef90c4e54edaa71d85870d1379dfb920659d803e0c8a60c89f6f0f1/dtw_python-1.7.5-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:38c63130a1e2a4977aacb02f3dedeb4bf3a92100683879efaae78ac3a1115d5b", size = 809434, upload-time = "2026-06-12T12:00:48.604Z" },
{ url = "https://files.pythonhosted.org/packages/a0/9a/4e1e62c1f6976c37ead522151be6d7ebd5e8dc6a79af179bd737a2c63595/dtw_python-1.7.5-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:945caea4472624384cbfd71010c241d1aa71cfa7cf603690bb9da339c6fe7367", size = 804101, upload-time = "2026-06-12T12:00:50.146Z" },
{ url = "https://files.pythonhosted.org/packages/28/61/d98757f4b3774e362f90675b69289bdf868a88ce3a1bb627dd829068943e/dtw_python-1.7.5-cp314-cp314t-win_amd64.whl", hash = "sha256:6b34c265281e4dbd5fe40ac8e6b945e858fef4f4efbf644aeddc9a985df956b3", size = 371470, upload-time = "2026-06-12T12:00:51.702Z" },
]
[[package]] [[package]]
name = "fonttools" name = "fonttools"
version = "4.63.0" version = "4.63.0"
@@ -279,6 +359,79 @@ wheels = [
{ url = "https://files.pythonhosted.org/packages/0a/dd/8050c947d435c8d4bc94e3252f4d8bb8a76cfb424f043a8680be637a57f1/kiwisolver-1.5.0-pp311-pypy311_pp73-win_amd64.whl", hash = "sha256:59cd8683f575d96df5bb48f6add94afc055012c29e28124fcae2b63661b9efb1", size = 73558, upload-time = "2026-03-09T13:15:52.112Z" }, { url = "https://files.pythonhosted.org/packages/0a/dd/8050c947d435c8d4bc94e3252f4d8bb8a76cfb424f043a8680be637a57f1/kiwisolver-1.5.0-pp311-pypy311_pp73-win_amd64.whl", hash = "sha256:59cd8683f575d96df5bb48f6add94afc055012c29e28124fcae2b63661b9efb1", size = 73558, upload-time = "2026-03-09T13:15:52.112Z" },
] ]
[[package]]
name = "librt"
version = "0.11.0"
source = { registry = "https://pypi.org/simple" }
sdist = { url = "https://files.pythonhosted.org/packages/40/08/9e7f6b5d2b5bed6ad055cdd5925f192bb403a51280f86b56554d9d0699a2/librt-0.11.0.tar.gz", hash = "sha256:075dc3ef4458a278e0195cbf6ac9d38808d9b906c5a6c7f7f79c3888276a3fb1", size = 200139, upload-time = "2026-05-10T18:17:25.138Z" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/fe/87/2bf31fe17587b29e3f93ec31421e2b1e1c3e349b8bf6c7c313dbad1d5340/librt-0.11.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:93d95bd45b7d58343d8b90d904450a545144eec19a002511163426f8ab1fae29", size = 141092, upload-time = "2026-05-10T18:15:34.795Z" },
{ url = "https://files.pythonhosted.org/packages/cf/08/5c5bf772920b7ebac6e32bc91a643e0ab3870199c0b542356d3baa83970a/librt-0.11.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:4ee278c769a713638cdacd4c0436d72156e75df3ebc0166ab2b9dc43acc386c9", size = 142035, upload-time = "2026-05-10T18:15:36.242Z" },
{ url = "https://files.pythonhosted.org/packages/06/20/662a03d254e5b000d838e8b345d83303ddb768c080fd488e40634c0fa66b/librt-0.11.0-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:f230cb1cbc9faaa616f9a678f530ebcf186e414b6bcbd88b960e4ba1b92428d5", size = 475022, upload-time = "2026-05-10T18:15:37.56Z" },
{ url = "https://files.pythonhosted.org/packages/de/f3/aa81523e45184c6ec23dc7f63263362ec55f80a09d424c012359ecbe7e35/librt-0.11.0-cp311-cp311-manylinux2014_i686.manylinux_2_17_i686.manylinux_2_28_i686.whl", hash = "sha256:5d63c855d86938d9de93e265c9bd8c705b51ec494de5738340ee93767a686e4b", size = 467273, upload-time = "2026-05-10T18:15:39.182Z" },
{ url = "https://files.pythonhosted.org/packages/6b/6f/59c74b560ca8853834d5501d589c8a2519f4184f273a085ffd0f37a1cc47/librt-0.11.0-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:993f028be9e96a08d31df3479ac80d99be374d17f3b78e4796b3fd3c913d4e89", size = 497083, upload-time = "2026-05-10T18:15:40.634Z" },
{ url = "https://files.pythonhosted.org/packages/fe/7b/5aa4d2c9600a719401160bf7055417df0b2a47439b9d88286ce45e56b65f/librt-0.11.0-cp311-cp311-manylinux_2_34_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:258d73a0aa66a055e65b2e4d1b8cdb23b9d132c5bb915d9547d804fcaed116cc", size = 489139, upload-time = "2026-05-10T18:15:41.934Z" },
{ url = "https://files.pythonhosted.org/packages/d6/31/9143803d7da6856a69153785768c4936864430eec0fd9461c3ea527d9922/librt-0.11.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:0827efe7854718f04aaddf6496e96960a956e676fe1d0f04eb41511fd8ad06d5", size = 508442, upload-time = "2026-05-10T18:15:43.206Z" },
{ url = "https://files.pythonhosted.org/packages/2f/5a/bce08184488426bda4ccc2c4964ac048c8f68ae89bd7120082eef4233cfd/librt-0.11.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:7753e57d6e12d019c0d8786f1c09c709f4c3fcc57c3887b24e36e6c06ec938b7", size = 514230, upload-time = "2026-05-10T18:15:44.761Z" },
{ url = "https://files.pythonhosted.org/packages/89/8c/bb5e213d254b7505a0e658da199d8ab719086632ce09eef311ab27976523/librt-0.11.0-cp311-cp311-musllinux_1_2_riscv64.whl", hash = "sha256:11bd19822431cc21af9f27374e7ae2e58103c7d98bda823536a6c47f6bb2bb3d", size = 494231, upload-time = "2026-05-10T18:15:46.308Z" },
{ url = "https://files.pythonhosted.org/packages/9d/fb/541cdad5b1ab1300398c74c4c9a497b88e5074c21b1244c8f49731d3a284/librt-0.11.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:22bdf239b219d3993761a148ffa134b19e52e9989c84f845d5d7b71d70a17412", size = 537585, upload-time = "2026-05-10T18:15:47.629Z" },
{ url = "https://files.pythonhosted.org/packages/8f/f2/464bb69295c320cb06bddb4f14a4ec67934ee14b2bffb12b19fb7ab287ba/librt-0.11.0-cp311-cp311-win32.whl", hash = "sha256:46c60b61e308eb535fbd6fa622b1ee1bb2815691c1ad9c98bf7b84952ec3bc8d", size = 100509, upload-time = "2026-05-10T18:15:49.157Z" },
{ url = "https://files.pythonhosted.org/packages/6d/e7/a17ee1788f9e4fbf548c19f4afa07c92089b9e24fef6cb2410863781ef4c/librt-0.11.0-cp311-cp311-win_amd64.whl", hash = "sha256:902e546ff044f579ff1c953ff5fce97b636fe9e3943996b2177710c6ef076f73", size = 118628, upload-time = "2026-05-10T18:15:50.345Z" },
{ url = "https://files.pythonhosted.org/packages/cc/c7/6c766214f9f9903bcfcfbef97d807af8d8f5aa3502d247858ab17582d212/librt-0.11.0-cp311-cp311-win_arm64.whl", hash = "sha256:65ac3bc20f78aa0ee5ae84baa68917f89fef4af63e941084dd019a0d0e749f0c", size = 103122, upload-time = "2026-05-10T18:15:52.068Z" },
{ url = "https://files.pythonhosted.org/packages/8b/d0/07c77e067f0838949b43bd89232c29d72efebb9d2801a9750184eb706b71/librt-0.11.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:b87504f1690a23b9a2cca841191a04f83895d4fc2dd04df91d82b1a04ca2ad46", size = 144147, upload-time = "2026-05-10T18:15:53.227Z" },
{ url = "https://files.pythonhosted.org/packages/7a/24/8493538fa4f62f982686398a5b8f68008138a75086abdea19ade64bf4255/librt-0.11.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:40071fc5fe0ce8daa6de616702314a01e1250711682b0523d6ab8d4525910cb3", size = 143614, upload-time = "2026-05-10T18:15:54.657Z" },
{ url = "https://files.pythonhosted.org/packages/ff/1e/f8bad050810d9171f34a1648ed910e56814c2ba61639f2bd53c6377ae24b/librt-0.11.0-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:137e79445c896a0ea7b265f52d23954e05b64222ee1af69e2cb34219067cbb67", size = 485538, upload-time = "2026-05-10T18:15:56.117Z" },
{ url = "https://files.pythonhosted.org/packages/c0/fe/3594ebfbaf03084ba4b120c9ba5c3183fd938a48725e9bbe6ff0a5159ad8/librt-0.11.0-cp312-cp312-manylinux2014_i686.manylinux_2_17_i686.manylinux_2_28_i686.whl", hash = "sha256:cca6644054e78746d8d4ef238681f9c34ff8b584fe6b988ecebb8db3b15e622a", size = 479623, upload-time = "2026-05-10T18:15:57.544Z" },
{ url = "https://files.pythonhosted.org/packages/b0/da/5d1876984b3746c85dbd219dbfcb73c85f54ee263fd32e5b2a632ec14571/librt-0.11.0-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:d5b0eea49f5562861ee8d757a32ef7d559c1d35be2aaaa1ec28941d74c9ffc8a", size = 513082, upload-time = "2026-05-10T18:15:58.805Z" },
{ url = "https://files.pythonhosted.org/packages/19/6e/55bdf5d5ca00c3e18430690bf2c953d8d3ffd3c337418173d33dec985dc9/librt-0.11.0-cp312-cp312-manylinux_2_34_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:0d1029d7e1ae1a7e647ed6fb5df8c4ce2dffefb7a9f5fd1376a4554d96dac09f", size = 508105, upload-time = "2026-05-10T18:16:00.2Z" },
{ url = "https://files.pythonhosted.org/packages/07/10/f1f23a7c595ee90ece4d35c851e5d104b1311a887ed1b4ac4c35bbd13da8/librt-0.11.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:bc3ce6b33c5828d9e80592011a5c584cb2ce86edbc4088405f70da47dc1d1b3b", size = 522268, upload-time = "2026-05-10T18:16:01.708Z" },
{ url = "https://files.pythonhosted.org/packages/b6/02/5720f5697a7f54b78b3aefbe20df3a48cedcff1276618c4aa481177942ed/librt-0.11.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:936c5995f3514a42111f20099397d8177c79b4d7e70961e396c6f5a0a3566766", size = 527348, upload-time = "2026-05-10T18:16:03.496Z" },
{ url = "https://files.pythonhosted.org/packages/50/db/b4a47c6f91db4ff76348a0b3dd0cc65e090a078b765a810a62ff9434c3d3/librt-0.11.0-cp312-cp312-musllinux_1_2_riscv64.whl", hash = "sha256:9bc0ca6ad9381cbe8e4aa6e5726e4c80c78115a6e9723c599ed1d73e092bc49d", size = 516294, upload-time = "2026-05-10T18:16:05.173Z" },
{ url = "https://files.pythonhosted.org/packages/9e/58/9384b2f4eb1ed1d273d40948a7c5c4b2360213b402ef3be4641c06299f9c/librt-0.11.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:070aa8c26c0a74774317a72df8851facc7f0f012a5b406557ac56992d92e1ec8", size = 553608, upload-time = "2026-05-10T18:16:06.839Z" },
{ url = "https://files.pythonhosted.org/packages/21/7b/5aa8848a7c6a9278c79375146da1812e695754ceec5f005e6043461a7315/librt-0.11.0-cp312-cp312-win32.whl", hash = "sha256:6bf14feb84b05ae945277395451998c89c54d0def4070eb5c08de544930b245a", size = 101879, upload-time = "2026-05-10T18:16:08.103Z" },
{ url = "https://files.pythonhosted.org/packages/37/33/8a745436944947575b584231750a41417de1a38cf6a2e9251d1065651c09/librt-0.11.0-cp312-cp312-win_amd64.whl", hash = "sha256:75672f0bc524ede266287d532d7923dbce94c7514ad07627bac3d0c6d92cc4d9", size = 119831, upload-time = "2026-05-10T18:16:09.174Z" },
{ url = "https://files.pythonhosted.org/packages/59/67/a6739ac96e28b7855808bdb0370e250606104a859750d209e5a0716fe7ab/librt-0.11.0-cp312-cp312-win_arm64.whl", hash = "sha256:2f10cf143e4a9bb0f4f5af568a00df94a2d69ef41c2579584454bb0fe5cc642c", size = 103470, upload-time = "2026-05-10T18:16:10.369Z" },
{ url = "https://files.pythonhosted.org/packages/82/61/e59168d4d0bf2bf90f4f0caf7a001bfc60254c3af4586013b04dc3ef517b/librt-0.11.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:78dc31f7fdfe9c9d0eb0e8f42d139db230e826415bbcabd9f0e9faaaee909894", size = 144119, upload-time = "2026-05-10T18:16:11.771Z" },
{ url = "https://files.pythonhosted.org/packages/61/fd/caa1d60b12f7dd79ccea23054e06eeaebe266a5f52c40a6b651069200ce5/librt-0.11.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:fa475675db22290c3158e1d42326d0f5a65f04f44a0e68c3630a25b53560fb9c", size = 143565, upload-time = "2026-05-10T18:16:13.334Z" },
{ url = "https://files.pythonhosted.org/packages/b8/a9/dc744f5c2b4978d48db970be29f22716d3413d28b14ad99740817315cf2c/librt-0.11.0-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:621db29691044bdeda22e789e482e1b0f3a985d90e3426c9c6d17606416205ea", size = 485395, upload-time = "2026-05-10T18:16:14.729Z" },
{ url = "https://files.pythonhosted.org/packages/8f/21/7f8e97a1e4dae952a5a95948f6f8507a173bc1e669f54340bba6ca1ca31b/librt-0.11.0-cp313-cp313-manylinux2014_i686.manylinux_2_17_i686.manylinux_2_28_i686.whl", hash = "sha256:a9010e2ed5b3a9e158c5fd966b3ab7e834bb3d3aacc8f66c91dd4b57a3799230", size = 479383, upload-time = "2026-05-10T18:16:16.321Z" },
{ url = "https://files.pythonhosted.org/packages/a6/6d/d8ee9c114bebf2c50e29ec2aa940826fccb62a645c3e4c18760987d0e16d/librt-0.11.0-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:7c39513d8b7477a2e1ed8c43fc21c524e8d5a0f8d4e8b7b074dbdbe7820a08e2", size = 513010, upload-time = "2026-05-10T18:16:17.647Z" },
{ url = "https://files.pythonhosted.org/packages/f0/43/0b5708af2bd30a46400e72ba6bdaa8f066f15fb9a688527e34220e8d6c06/librt-0.11.0-cp313-cp313-manylinux_2_34_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:7aef3cf1d5af86e770ab04bfd993dfc4ae8b8c17f66fb77dd4a7d50de7bbb1a3", size = 508433, upload-time = "2026-05-10T18:16:19.309Z" },
{ url = "https://files.pythonhosted.org/packages/4a/50/356187247d09013490481033183b3532b58acf8028bcb34b2b56a375c9b2/librt-0.11.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:557183ddc36babe46b27dd60facbd5adb4492181a5be887587d57cda6e092f21", size = 522595, upload-time = "2026-05-10T18:16:20.642Z" },
{ url = "https://files.pythonhosted.org/packages/40/e7/c6ac4240899c7f3248079d5a9900debe0dadb3fdeaf856684c987105ba47/librt-0.11.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:83d3e1f72bd42f6c5c0b7daec530c3f829bd02db42c70b8ddf0c2d90a2459930", size = 527255, upload-time = "2026-05-10T18:16:22.352Z" },
{ url = "https://files.pythonhosted.org/packages/eb/b5/a81322dbeedeeaf9c1ee6f001734d28a09d8383ac9e6779bc24bbd0743c6/librt-0.11.0-cp313-cp313-musllinux_1_2_riscv64.whl", hash = "sha256:4ce1f21fbe589bc1afd7872dece84fb0e1144f794a288e58a10d2c54a55c43be", size = 516847, upload-time = "2026-05-10T18:16:23.627Z" },
{ url = "https://files.pythonhosted.org/packages/ae/66/6e6323787d592b55204a42595ff1102da5115601b53a7e9ddebc889a6da5/librt-0.11.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:970b09f7044ea2b64c9da42fd3d335666518cfd1c6e8a182c95da73d0214b41e", size = 553920, upload-time = "2026-05-10T18:16:25.025Z" },
{ url = "https://files.pythonhosted.org/packages/9c/21/623f8ca230857102066d9ca8c6c1734995908c4d0d1bee7bb2ef0021cb33/librt-0.11.0-cp313-cp313-win32.whl", hash = "sha256:78fddc31cd4d3caa897ad5d31f856b1faadc9474021ad6cb182b9018793e254e", size = 101898, upload-time = "2026-05-10T18:16:26.649Z" },
{ url = "https://files.pythonhosted.org/packages/b3/1d/b4ebd44dd723f768469007515cb92251e0ae286c94c140f374801140fa74/librt-0.11.0-cp313-cp313-win_amd64.whl", hash = "sha256:8ca8aa88751a775870b764e93bad5135385f563cb8dcee399abf034ea4d3cb47", size = 119812, upload-time = "2026-05-10T18:16:27.859Z" },
{ url = "https://files.pythonhosted.org/packages/3b/e4/b2f4ca7965ca373b491cdb4bc25cdb30c1649ca81a8782056a83850292a9/librt-0.11.0-cp313-cp313-win_arm64.whl", hash = "sha256:96f044bb325fd9cf1a723015638c219e9143f0dfbc0ca54c565df2b7fc748b44", size = 103448, upload-time = "2026-05-10T18:16:29.066Z" },
{ url = "https://files.pythonhosted.org/packages/29/eb/dbce197da4e227779e56b5735f2decc3eb36e55a1cdbf1bd65d6639d76c1/librt-0.11.0-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:4a017a95e5837dc15a8c5661d60e05daa96b90908b1aa6b7acdf443cd25c8ebd", size = 143345, upload-time = "2026-05-10T18:16:30.674Z" },
{ url = "https://files.pythonhosted.org/packages/76/a3/254bebd0c11c8ba684018efb8006ff22e466abce445215cca6c778e7d9de/librt-0.11.0-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:b1ecbd9819deccc39b7542bf4d2a740d8a620694d39989e58661d3763458f8d4", size = 143131, upload-time = "2026-05-10T18:16:32.037Z" },
{ url = "https://files.pythonhosted.org/packages/f1/3f/f77d6122d21ac7bf6ae8a7dfced1bd2a7ac545d3273ebdcaf8042f6d619f/librt-0.11.0-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:7da327dacd7be8f8ec36547373550744a3cc0e536d54665cd83f8bcd961200e8", size = 477024, upload-time = "2026-05-10T18:16:33.493Z" },
{ url = "https://files.pythonhosted.org/packages/ac/0a/2c996dadebaa7d9bbbd43ef2d4f3e66b6da545f838a41694ef6172cebec8/librt-0.11.0-cp314-cp314-manylinux2014_i686.manylinux_2_17_i686.manylinux_2_28_i686.whl", hash = "sha256:0dc56b1f8d06e60db362cc3fdae206681817f86ce4725d34511473487f12a34b", size = 474221, upload-time = "2026-05-10T18:16:34.864Z" },
{ url = "https://files.pythonhosted.org/packages/0a/7e/f5d92af8486b8272c23b3e686b46ff72d89c8169585eb61eef01a2ac7147/librt-0.11.0-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:05fb8fb2ab90e21c8d12ea240d744ad514da9baf381ebfa70d91d20d21713175", size = 505174, upload-time = "2026-05-10T18:16:36.705Z" },
{ url = "https://files.pythonhosted.org/packages/af/1a/cb0734fe86398eb33193ab753b7326255c74cac5eb09e76b9b16536e7adb/librt-0.11.0-cp314-cp314-manylinux_2_34_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:cae74872be221df4374d10fec61f93ed1513b9546ea84f2c0bf73ab3e9bd0b03", size = 497216, upload-time = "2026-05-10T18:16:38.418Z" },
{ url = "https://files.pythonhosted.org/packages/18/06/094820f91558b66e29943c0ec41c9914f460f48dd51fc503c3101e10842d/librt-0.11.0-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:32bcc918c0148eb7e3d57385125bac7e5f9e4359d05f07448b09f6f778c2f31c", size = 513921, upload-time = "2026-05-10T18:16:39.848Z" },
{ url = "https://files.pythonhosted.org/packages/0b/c2/00de9018871a282f530cacb457d5ec0428f6ac7e6fedde9aff7468d9fb04/librt-0.11.0-cp314-cp314-musllinux_1_2_i686.whl", hash = "sha256:f9743fc99135d5f78d2454435615f6dec0473ca507c26ce9d92b10b562a280d3", size = 520850, upload-time = "2026-05-10T18:16:41.471Z" },
{ url = "https://files.pythonhosted.org/packages/51/9d/64631832348fd1834fb3a61b996434edddaaf25a31d03b0a76273159d2cf/librt-0.11.0-cp314-cp314-musllinux_1_2_riscv64.whl", hash = "sha256:5ba067f4aadae8fda802d91d2124c90c42195ff32d9161d3549e6d05cfe26f96", size = 504237, upload-time = "2026-05-10T18:16:43.15Z" },
{ url = "https://files.pythonhosted.org/packages/a5/ec/ae5525eb16edc827a044e7bb8777a455ff95d4bca9379e7e6bddd7383647/librt-0.11.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:de3bf945454d032f9e390b85c4072e0a0570bf825421c8be0e71209fa65e1abe", size = 546261, upload-time = "2026-05-10T18:16:44.408Z" },
{ url = "https://files.pythonhosted.org/packages/5a/09/adce371f27ca039411da9659f7430fcc2ba6cd0c7b3e4467a0f091be7fa9/librt-0.11.0-cp314-cp314-win32.whl", hash = "sha256:d2277a05f6dcb9fd13db9566aac4fabd68c3ea1ea46ee5567d4eef8efa495a2f", size = 96965, upload-time = "2026-05-10T18:16:46.039Z" },
{ url = "https://files.pythonhosted.org/packages/d6/ee/8ac720d98548f173c7ce2e632a7ca94673f74cacd5c8162a84af5b35958a/librt-0.11.0-cp314-cp314-win_amd64.whl", hash = "sha256:ab73e8db5e3f564d812c1f5c3a175930a5f9bc96ccb5e3b22a34d7858b401cf7", size = 115151, upload-time = "2026-05-10T18:16:47.133Z" },
{ url = "https://files.pythonhosted.org/packages/94/20/c900cf14efeb09b6bef2b2dff20779f73464b97fd58d1c6bccc379588ae3/librt-0.11.0-cp314-cp314-win_arm64.whl", hash = "sha256:aea3caa317752e3a466fa8af45d91ee0ea8c7fdd96e42b0a8dd9b76a7931eba1", size = 98850, upload-time = "2026-05-10T18:16:48.597Z" },
{ url = "https://files.pythonhosted.org/packages/0c/71/944bfe4b64e12abffcd3c15e1cce07f72f3d55655083786285f4dedeb532/librt-0.11.0-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:d1b36540d7aaf9b9101b3a6f376c8d8e9f7a9aec93ed05918f2c69d493ffef72", size = 151138, upload-time = "2026-05-10T18:16:49.839Z" },
{ url = "https://files.pythonhosted.org/packages/b6/10/99e64a5c86989357fda078c8143c533389585f6473b7439172dd8f3b3b2d/librt-0.11.0-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:efbb343ab2ce3540f4ecbe6315d677ed70f37cd9a72b1e58066c918ca83acbaa", size = 151976, upload-time = "2026-05-10T18:16:51.062Z" },
{ url = "https://files.pythonhosted.org/packages/21/31/5072ad880946d83e5ea4147d6d018c78eefce85b77819b19bdd0ee229435/librt-0.11.0-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:aa0dd688aab3f7914d3e6e5e3554978e0383312fb8e771d84be008a35b9ee548", size = 557927, upload-time = "2026-05-10T18:16:52.632Z" },
{ url = "https://files.pythonhosted.org/packages/5e/8d/70b5fb7cfbab60edbe7381614ab985da58e144fbf465c86d44c95f43cdca/librt-0.11.0-cp314-cp314t-manylinux2014_i686.manylinux_2_17_i686.manylinux_2_28_i686.whl", hash = "sha256:f5fb36b8c6c63fdcbb1d526d94c0d1331610d43f4118cc1beb4efef4f3faacb2", size = 539698, upload-time = "2026-05-10T18:16:53.934Z" },
{ url = "https://files.pythonhosted.org/packages/fa/a3/ba3495a0b3edbd24a4cae0d1d3c64f39a9fc45d06e812101289b50c1a619/librt-0.11.0-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:4a9a237d13addb93715b6fee74023d5ee3469b53fce527626c0e088aa585805f", size = 577162, upload-time = "2026-05-10T18:16:55.589Z" },
{ url = "https://files.pythonhosted.org/packages/f7/db/36e25fb81f99937ff1b96612a1dc9fd66f039cb9cc3aee12c01fac31aab9/librt-0.11.0-cp314-cp314t-manylinux_2_34_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:5ddd17bd87b2c56ddd60e546a7984a2e64c4e8eab92fb4cf3830a48ad5469d51", size = 566494, upload-time = "2026-05-10T18:16:56.975Z" },
{ url = "https://files.pythonhosted.org/packages/33/0d/3f622b47f0b013eeb9cf4cc07ae9bfe378d832a4eec998b2b209fe84244d/librt-0.11.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:bd43992b4473d42f12ff9e68326079f0696d9d4e6000e8f39a0238d482ba6ee2", size = 596858, upload-time = "2026-05-10T18:16:58.374Z" },
{ url = "https://files.pythonhosted.org/packages/a9/02/71b90bc93039c46a2000651f6ad60122b114c8f54c4ad306e0e96f5b75ad/librt-0.11.0-cp314-cp314t-musllinux_1_2_i686.whl", hash = "sha256:f8e3e8056dd674e279741485e2e512d6e9a751c7455809d0114e6ebf8d781085", size = 590318, upload-time = "2026-05-10T18:16:59.676Z" },
{ url = "https://files.pythonhosted.org/packages/04/04/418cb3f75621e2b761fb1ab0f017f4d70a1a72a6e7c74ee4f7e8d198c2f3/librt-0.11.0-cp314-cp314t-musllinux_1_2_riscv64.whl", hash = "sha256:c1f708d8ae9c56cf38a903c44297243d2ec83fd82b396b977e0144a3e76217e3", size = 575115, upload-time = "2026-05-10T18:17:01.007Z" },
{ url = "https://files.pythonhosted.org/packages/cc/2c/5a2183ac58dd911f26b5d7e7d7d8f1d87fcecdddd99d6c12169a258ff62c/librt-0.11.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:0add982e0e7b9fc14cf4b33789d5f13f66581889b88c2f58099f6ce8f92617bd", size = 617918, upload-time = "2026-05-10T18:17:02.682Z" },
{ url = "https://files.pythonhosted.org/packages/15/1f/dc6771a52592a4451be6effa200cbfc9cec61e4393d3033d81a9d307961d/librt-0.11.0-cp314-cp314t-win32.whl", hash = "sha256:2b481d846ac894c4e8403c5fd0e87c5d11d6499e404b474602508a224ff531c8", size = 103562, upload-time = "2026-05-10T18:17:03.99Z" },
{ url = "https://files.pythonhosted.org/packages/62/4a/7d1415567027286a75ba1093ec4aca11f073e0f559c530cf3e0a757ad55c/librt-0.11.0-cp314-cp314t-win_amd64.whl", hash = "sha256:28edb433edde181112a908c78907af28f964eabc15f4dd16c9d66c834302677c", size = 124327, upload-time = "2026-05-10T18:17:05.465Z" },
{ url = "https://files.pythonhosted.org/packages/ce/62/b40b382fa0c66fee1478073eb8db352a4a6beda4a1adccf1df911d8c289c/librt-0.11.0-cp314-cp314t-win_arm64.whl", hash = "sha256:dee008f20b542e3cd162ba338a7f9ec0f6d23d395f66fe8aeeec3c9d067ea253", size = 102572, upload-time = "2026-05-10T18:17:06.809Z" },
]
[[package]] [[package]]
name = "matplotlib" name = "matplotlib"
version = "3.11.0" version = "3.11.0"
@@ -343,6 +496,66 @@ wheels = [
{ url = "https://files.pythonhosted.org/packages/0c/d8/c4ecab06b7ea36a570c4f3bd2d48d1799fd5d9174470e45c2194199431e7/matplotlib-3.11.0-pp311-pypy311_pp73-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:cf662e5ac5707658cb931e19972c4bd99f7b4f8b7bf79d3c821d239fa6b71e64", size = 10015653, upload-time = "2026-06-12T02:29:13.251Z" }, { url = "https://files.pythonhosted.org/packages/0c/d8/c4ecab06b7ea36a570c4f3bd2d48d1799fd5d9174470e45c2194199431e7/matplotlib-3.11.0-pp311-pypy311_pp73-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:cf662e5ac5707658cb931e19972c4bd99f7b4f8b7bf79d3c821d239fa6b71e64", size = 10015653, upload-time = "2026-06-12T02:29:13.251Z" },
] ]
[[package]]
name = "mypy"
version = "2.1.0"
source = { registry = "https://pypi.org/simple" }
dependencies = [
{ name = "ast-serialize", marker = "sys_platform == 'darwin' or sys_platform == 'linux' or sys_platform == 'win32'" },
{ name = "librt", marker = "(platform_python_implementation != 'PyPy' and sys_platform == 'darwin') or (platform_python_implementation != 'PyPy' and sys_platform == 'linux') or (platform_python_implementation != 'PyPy' and sys_platform == 'win32')" },
{ name = "mypy-extensions", marker = "sys_platform == 'darwin' or sys_platform == 'linux' or sys_platform == 'win32'" },
{ name = "pathspec", marker = "sys_platform == 'darwin' or sys_platform == 'linux' or sys_platform == 'win32'" },
{ name = "typing-extensions", marker = "sys_platform == 'darwin' or sys_platform == 'linux' or sys_platform == 'win32'" },
]
sdist = { url = "https://files.pythonhosted.org/packages/82/15/cca9d88503549ed6fedeaa1d448cdddd542ee8a490232d732e278036fbf2/mypy-2.1.0.tar.gz", hash = "sha256:81e76ad12c2d804512e9b13240d1588316531bfba07558286078bfbce9613633", size = 3898359, upload-time = "2026-05-11T18:37:36.237Z" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/0a/a1/639f3024794a2a15899cb90707fe02e044c4412794c39c5769fd3df2e2ef/mypy-2.1.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:a683016b16fe2f572dc04c72be7ee0504ac1605a265d0200f5cea695fb788f41", size = 14691685, upload-time = "2026-05-11T18:33:27.973Z" },
{ url = "https://files.pythonhosted.org/packages/3b/08/9a585dea4325f20d8b80dc78623fa50d1fd2173b710f6237afd6ba6ab39b/mypy-2.1.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:1a293c534adb55271fef24a26da04b855540a8c13cc07bc5917b9fd2c394f2ca", size = 13555165, upload-time = "2026-05-11T18:32:16.107Z" },
{ url = "https://files.pythonhosted.org/packages/81/dc/7c42cc9c6cb01e8eb09961f1f738741d3e9c7e9d5c5b30ec69222625cd5f/mypy-2.1.0-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:7406f4d048e71e576f5356d317e5b0a9e666dfd966bd99f9d14ca06e1a341538", size = 13994376, upload-time = "2026-05-11T18:32:39.256Z" },
{ url = "https://files.pythonhosted.org/packages/d4/fa/285946c33bce716e082c11dfeee9ee196eaf1f5042efb3581a31f9f205e4/mypy-2.1.0-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:e0210d626fc8b31ccc90233754c7bc90e1f43205e85d96387f7db1285b55c398", size = 14864618, upload-time = "2026-05-11T18:34:49.765Z" },
{ url = "https://files.pythonhosted.org/packages/2b/83/82397f48af6c27e295d57979ded8490c9829040152cf7571b2f026aeb9a0/mypy-2.1.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:3712c20deed54e814eaaa825603bada8ea1c390670a397c95b98405347acc563", size = 15102063, upload-time = "2026-05-11T18:34:05.855Z" },
{ url = "https://files.pythonhosted.org/packages/40/68/b02dec39057b88eb03dc0aa854732e26e8361f34f9d0e20c7614967d1eba/mypy-2.1.0-cp311-cp311-win_amd64.whl", hash = "sha256:fcaa0e479066e31f7cceb6a3bea39cb22b2ff51a6b2f24f193d19179ba17c389", size = 11060564, upload-time = "2026-05-11T18:35:36.494Z" },
{ url = "https://files.pythonhosted.org/packages/cf/a8/ea3dcbef31f99b634f2ee23bb0321cbc8c1b388b76a861eb849f13c347dc/mypy-2.1.0-cp311-cp311-win_arm64.whl", hash = "sha256:0b1a5260c95aa443083f9ed3592662941951bca3d4ca224a5dc517c38b7cf666", size = 9966983, upload-time = "2026-05-11T18:37:14.139Z" },
{ url = "https://files.pythonhosted.org/packages/95/b1/55861beb5c339b44f9a2ba92df9e2cb1eeb4ae1eee674cdf7772c797778b/mypy-2.1.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:244358bf1c0da7722230bce60683d52e8e9fd030554926f15b747a84efb5b3af", size = 14874381, upload-time = "2026-05-11T18:37:31.784Z" },
{ url = "https://files.pythonhosted.org/packages/0b/b3/b7f770114b7d0ac92d0f76e8d93c2780844a70488a90e91821927850da86/mypy-2.1.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:4ec7c57657493c7a75534df2751c8ae2cda383c16ecc55d2106c54476b1b16f6", size = 13665501, upload-time = "2026-05-11T18:34:23.063Z" },
{ url = "https://files.pythonhosted.org/packages/b6/f3/8ae2037967e2126689a0c11d99e2b707134a565191e92c60ca2572aec60a/mypy-2.1.0-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:d8161b6ff4392410023224f0969d17db93e1e154bc3e4ba62598e720723ae211", size = 14045750, upload-time = "2026-05-11T18:31:48.151Z" },
{ url = "https://files.pythonhosted.org/packages/a0/32/615eb5911859e43d054941b0d0a7d06cfa2870eba86529cf385b052b111c/mypy-2.1.0-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:bf03e12003084a67395184d3eb8cbd6a489dc3655b5664b28c210a9e2403ab0b", size = 15061630, upload-time = "2026-05-11T18:37:06.898Z" },
{ url = "https://files.pythonhosted.org/packages/d4/03/4eafbfff8bfab1b87082741eae6e6a624028c984e6708b73bce2a8570c9d/mypy-2.1.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:20509760fd791c51579d573153407d226385ec1f8bcce55d730b354f3336bc22", size = 15288831, upload-time = "2026-05-11T18:31:18.07Z" },
{ url = "https://files.pythonhosted.org/packages/99/ee/919661478e5891a3c96e549c036e467e64563ab85995b10c53c8358e16a3/mypy-2.1.0-cp312-cp312-win_amd64.whl", hash = "sha256:6753d0c1fdd6b1a23b9e4f283ce80b2153b724adcb2653b20b85a8a28ac6436b", size = 11135228, upload-time = "2026-05-11T18:34:31.23Z" },
{ url = "https://files.pythonhosted.org/packages/24/0a/6a12b9782ca0831a553192f351679f4548abc9d19a7cc93bb7feb02084c7/mypy-2.1.0-cp312-cp312-win_arm64.whl", hash = "sha256:98ebb6589bb3b6d0c6f0c459d53ca55b8091fbc13d277c4041c885392e8195e8", size = 10040684, upload-time = "2026-05-11T18:36:48.199Z" },
{ url = "https://files.pythonhosted.org/packages/6e/dd/c7191469c777f07689c032a8f7326e393ea34c92d6d76eb7ce5ba57ea66d/mypy-2.1.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:35aac3bb114e03888f535d5eb51b8bafbb3266586b599da1940f9b1be3ec5bd5", size = 14852174, upload-time = "2026-05-11T18:31:38.929Z" },
{ url = "https://files.pythonhosted.org/packages/55/8c/aed55408879043d72bb9135f4d0d19a02b886dd569631e113e3d2706cb8d/mypy-2.1.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:8de55a8c861f2a49331f807be98d90caeceeef520bde13d43a160207f8af613e", size = 13651542, upload-time = "2026-05-11T18:36:04.636Z" },
{ url = "https://files.pythonhosted.org/packages/3a/8e/f371a824b1f1fa8ea6e3dbb8703d232977d572be2329554a3bc4d960302f/mypy-2.1.0-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:5fdf2941a07434af755837d9880f7d7d25f1dacb1af9dcd4b9b66f2220a3024e", size = 14033929, upload-time = "2026-05-11T18:35:55.742Z" },
{ url = "https://files.pythonhosted.org/packages/94/21/f54be870d6dd53a82c674407e0f8eed7174b05ec78d42e5abd7b42e84fd5/mypy-2.1.0-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:e195b817c13f02352a9c124301f9f30f078405444679b6753c1b96b6eed37285", size = 15039200, upload-time = "2026-05-11T18:33:10.281Z" },
{ url = "https://files.pythonhosted.org/packages/17/99/bf21748626a40ce59fd29a39386ab46afec88b7bd2f0fa6c3a97c995523f/mypy-2.1.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:5431d42af987ebd92ba2f71d45c85ed41d8e6ca9f5fd209a69f68f707d2469e5", size = 15272690, upload-time = "2026-05-11T18:32:07.205Z" },
{ url = "https://files.pythonhosted.org/packages/d6/d7/9e90d2cf47100bea550ed2bc7b0d4de3a62181d84d5e37da0003e8462637/mypy-2.1.0-cp313-cp313-win_amd64.whl", hash = "sha256:767fe8c66dc3e01e19e1737d4c38ebefead16125e1b8e58ad421903b376f5c65", size = 11147435, upload-time = "2026-05-11T18:33:56.477Z" },
{ url = "https://files.pythonhosted.org/packages/ec/46/e5c449e858798e35ffc90946282a27c62a77be743fe17480e4977374eb91/mypy-2.1.0-cp313-cp313-win_arm64.whl", hash = "sha256:ecfe70d43775ab99562ab128ce49854a362044c9f894961f68f898c23cb7429d", size = 10035052, upload-time = "2026-05-11T18:32:30.049Z" },
{ url = "https://files.pythonhosted.org/packages/b0/ca/b279a672e874aedd5498ae25f722dacc8aa86bbffb939b3f97cbb1cf6686/mypy-2.1.0-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:7354c5a7f69d9345c3d6e69921d57088eea3ddeeb6b20d34c1b3855b02c36ec2", size = 14848422, upload-time = "2026-05-11T18:35:45.984Z" },
{ url = "https://files.pythonhosted.org/packages/27/e6/3efe56c631d959b9b4454e208b0ac4b7f4f58b404c89f8bec7b49efdfc21/mypy-2.1.0-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:49890d4f76ac9e06ec117f9e09f3174da70a620a0c300953d8595c926e80947f", size = 13677374, upload-time = "2026-05-11T18:36:57.188Z" },
{ url = "https://files.pythonhosted.org/packages/84/7f/8107ea87a44fd1f1b59882442f033c9c3488c127201b1d1d15f1cbd6022e/mypy-2.1.0-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:761be68e023ef5d94678772396a8af1220030f80837a3afd8d0aef3b419666f4", size = 14055743, upload-time = "2026-05-11T18:35:18.361Z" },
{ url = "https://files.pythonhosted.org/packages/51/4d/b6d34db183133b83761b9199a82d31557cdbb70a380d8c3b3438e11882a3/mypy-2.1.0-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:c90345fc182dc363b891350457ec69c35140858538f38b4540845afcc32b1aef", size = 15020937, upload-time = "2026-05-11T18:34:59.618Z" },
{ url = "https://files.pythonhosted.org/packages/ff/d7/f08360c691d758acb02f45022c34d98b92892f4ea756644e1000d4b9f3d8/mypy-2.1.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:b84802e7b5a6daf1f5e15bc9fcd7ddae77be13981ffab037f1c67bb84d67d135", size = 15253371, upload-time = "2026-05-11T18:36:41.081Z" },
{ url = "https://files.pythonhosted.org/packages/67/1b/09460a13719530a19bce27bd3bc8449e83569dd2ba7faf51c9c3c30c0b61/mypy-2.1.0-cp314-cp314-win_amd64.whl", hash = "sha256:022c771234936ceac541ebaf836fe9e2abeb3f5e09aff21588fe543ff006fe21", size = 11326429, upload-time = "2026-05-11T18:34:13.526Z" },
{ url = "https://files.pythonhosted.org/packages/40/62/75dbf0f82f7b6680340efc614af29dd0b3c17b8a4f1cd09b8bd2fd6bc814/mypy-2.1.0-cp314-cp314-win_arm64.whl", hash = "sha256:498207db725cec88829a6a5c2fc771205fd043719ef98bc49aba8fb9fc4e6d57", size = 10218799, upload-time = "2026-05-11T18:32:23.491Z" },
{ url = "https://files.pythonhosted.org/packages/b2/66/caca04ed7d972fb6eb6dd1ccd6df1de5c38fae8c5b3dc1c4e8e0d85ee6b9/mypy-2.1.0-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:7d5e5cad0efeba72b93cd17490cc0d69c5ac9ca132994fe3fb0314808aeeb83e", size = 15923458, upload-time = "2026-05-11T18:35:28.64Z" },
{ url = "https://files.pythonhosted.org/packages/ed/52/2d90cbe49d014b13ed7ff337930c30bad35893fe38a1e4641e756bb62191/mypy-2.1.0-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:ff715050c127d724fd260a2e666e7747fdd83511c0c47d449d98238970aef780", size = 14757697, upload-time = "2026-05-11T18:36:14.208Z" },
{ url = "https://files.pythonhosted.org/packages/ac/37/d98f4a14e081b238992d0ed96b6d39c7cc0148c9699eb71eaa68629665ea/mypy-2.1.0-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:82208da9e09414d520e912d3e462d454854bed0810b71540bb016dcbca7308fd", size = 15405638, upload-time = "2026-05-11T18:33:48.249Z" },
{ url = "https://files.pythonhosted.org/packages/a3/c2/15c46613b24a84fad2aea1248bf9619b99c2767ae9071fe224c179a0b7d4/mypy-2.1.0-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:e79ebc1b904b84f0310dff7469655a9c36c7a68bddb37bdd42b67a332df61d08", size = 16215852, upload-time = "2026-05-11T18:32:50.296Z" },
{ url = "https://files.pythonhosted.org/packages/5c/90/9c16a57f482c76d25f6379762b56bbf65c711d8158cf271fb2802cfb0640/mypy-2.1.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:e583edc957cfb0deb142079162ae826f58449b116c1d442f2d91c69d9fced081", size = 16452695, upload-time = "2026-05-11T18:33:38.182Z" },
{ url = "https://files.pythonhosted.org/packages/0f/4c/215a4eeb63cacc5f17f516691ea7285d11e249802b942476bff15922a314/mypy-2.1.0-cp314-cp314t-win_amd64.whl", hash = "sha256:b33b6cd332695bba180d55e717a79d3038e479a2c49cc5eb3d53603409b9a5d7", size = 12866622, upload-time = "2026-05-11T18:34:39.945Z" },
{ url = "https://files.pythonhosted.org/packages/4b/50/1043e1db5f455ffe4c9ab22747cd8ca2bc492b1e4f4e21b130a44ee2b217/mypy-2.1.0-cp314-cp314t-win_arm64.whl", hash = "sha256:4f910fe825376a7b66ef7ca8c98e5a149e8cd64c19ae71d84047a74ee060d4e6", size = 10610798, upload-time = "2026-05-11T18:36:31.444Z" },
{ url = "https://files.pythonhosted.org/packages/0d/2a/13ca1f292f6db1b98ff495ef3467736b331621c5917cad984b7043e7348d/mypy-2.1.0-py3-none-any.whl", hash = "sha256:a663814603a5c563fb87a4f96fb473eeb30d1f5a4885afcf44f9db000a366289", size = 2693302, upload-time = "2026-05-11T18:31:29.246Z" },
]
[[package]]
name = "mypy-extensions"
version = "1.1.0"
source = { registry = "https://pypi.org/simple" }
sdist = { url = "https://files.pythonhosted.org/packages/a2/6e/371856a3fb9d31ca8dac321cda606860fa4548858c0cc45d9d1d4ca2628b/mypy_extensions-1.1.0.tar.gz", hash = "sha256:52e68efc3284861e772bbcd66823fde5ae21fd2fdb51c62a211403730b916558", size = 6343, upload-time = "2025-04-22T14:54:24.164Z" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/79/7b/2c79738432f5c924bef5071f933bcc9efd0473bac3b4aa584a6f7c1c8df8/mypy_extensions-1.1.0-py3-none-any.whl", hash = "sha256:1be4cccdb0f2482337c4743e60421de3a356cd97508abadd57d47403e94f5505", size = 4963, upload-time = "2025-04-22T14:54:22.983Z" },
]
[[package]] [[package]]
name = "numpy" name = "numpy"
version = "2.4.6" version = "2.4.6"
@@ -491,6 +704,15 @@ wheels = [
{ url = "https://files.pythonhosted.org/packages/0f/54/68a0978d1ef8502b8492099beaa6e7a0c1b32e3b5d4f677f5810cb08711c/pandas-3.0.3-cp314-cp314t-win_arm64.whl", hash = "sha256:b2c95f8bfc1ee412bf482605d7bfd30c12d1d26bd59fdd91efeef1d4718decb1", size = 9466464, upload-time = "2026-05-11T18:54:22.754Z" }, { url = "https://files.pythonhosted.org/packages/0f/54/68a0978d1ef8502b8492099beaa6e7a0c1b32e3b5d4f677f5810cb08711c/pandas-3.0.3-cp314-cp314t-win_arm64.whl", hash = "sha256:b2c95f8bfc1ee412bf482605d7bfd30c12d1d26bd59fdd91efeef1d4718decb1", size = 9466464, upload-time = "2026-05-11T18:54:22.754Z" },
] ]
[[package]]
name = "pathspec"
version = "1.1.1"
source = { registry = "https://pypi.org/simple" }
sdist = { url = "https://files.pythonhosted.org/packages/5a/82/42f767fc1c1143d6fd36efb827202a2d997a375e160a71eb2888a925aac1/pathspec-1.1.1.tar.gz", hash = "sha256:17db5ecd524104a120e173814c90367a96a98d07c45b2e10c2f3919fff91bf5a", size = 135180, upload-time = "2026-04-27T01:46:08.907Z" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/f1/d9/7fb5aa316bc299258e68c73ba3bddbc499654a07f151cba08f6153988714/pathspec-1.1.1-py3-none-any.whl", hash = "sha256:a00ce642f577bf7f473932318056212bc4f8bfdf53128c78bbd5af0b9b20b189", size = 57328, upload-time = "2026-04-27T01:46:07.06Z" },
]
[[package]] [[package]]
name = "pillow" name = "pillow"
version = "12.2.0" version = "12.2.0"
@@ -601,6 +823,7 @@ name = "pygui"
version = "0.1.0" version = "0.1.0"
source = { editable = "." } source = { editable = "." }
dependencies = [ dependencies = [
{ name = "dtw-python", marker = "sys_platform == 'darwin' or sys_platform == 'linux' or sys_platform == 'win32'" },
{ name = "matplotlib", marker = "sys_platform == 'darwin' or sys_platform == 'linux' or sys_platform == 'win32'" }, { name = "matplotlib", marker = "sys_platform == 'darwin' or sys_platform == 'linux' or sys_platform == 'win32'" },
{ name = "numpy", marker = "sys_platform == 'darwin' or sys_platform == 'linux' or sys_platform == 'win32'" }, { name = "numpy", marker = "sys_platform == 'darwin' or sys_platform == 'linux' or sys_platform == 'win32'" },
{ name = "pandas", marker = "sys_platform == 'darwin' or sys_platform == 'linux' or sys_platform == 'win32'" }, { name = "pandas", marker = "sys_platform == 'darwin' or sys_platform == 'linux' or sys_platform == 'win32'" },
@@ -618,11 +841,14 @@ dev = [
[package.dev-dependencies] [package.dev-dependencies]
dev = [ dev = [
{ name = "mypy", marker = "sys_platform == 'darwin' or sys_platform == 'linux' or sys_platform == 'win32'" },
{ name = "pytest", marker = "sys_platform == 'darwin' or sys_platform == 'linux' or sys_platform == 'win32'" }, { name = "pytest", marker = "sys_platform == 'darwin' or sys_platform == 'linux' or sys_platform == 'win32'" },
{ name = "ruff", marker = "sys_platform == 'darwin' or sys_platform == 'linux' or sys_platform == 'win32'" },
] ]
[package.metadata] [package.metadata]
requires-dist = [ requires-dist = [
{ name = "dtw-python" },
{ name = "matplotlib", specifier = ">=3.7.0" }, { name = "matplotlib", specifier = ">=3.7.0" },
{ name = "numpy", specifier = ">=1.24.0" }, { name = "numpy", specifier = ">=1.24.0" },
{ name = "pandas", specifier = ">=2.0.0" }, { name = "pandas", specifier = ">=2.0.0" },
@@ -636,7 +862,11 @@ requires-dist = [
provides-extras = ["dev"] provides-extras = ["dev"]
[package.metadata.requires-dev] [package.metadata.requires-dev]
dev = [{ name = "pytest", specifier = ">=9.0.3" }] dev = [
{ name = "mypy" },
{ name = "pytest", specifier = ">=9.0.3" },
{ name = "ruff" },
]
[[package]] [[package]]
name = "pyparsing" name = "pyparsing"
@@ -799,6 +1029,31 @@ wheels = [
{ url = "https://files.pythonhosted.org/packages/f1/12/de94a39c2ef588c7e6455cfbe7343d3b2dc9d6b6b2f40c4c6565744c873d/pyyaml-6.0.3-cp314-cp314t-win_arm64.whl", hash = "sha256:ebc55a14a21cb14062aa4162f906cd962b28e2e9ea38f9b4391244cd8de4ae0b", size = 149341, upload-time = "2025-09-25T21:32:56.828Z" }, { url = "https://files.pythonhosted.org/packages/f1/12/de94a39c2ef588c7e6455cfbe7343d3b2dc9d6b6b2f40c4c6565744c873d/pyyaml-6.0.3-cp314-cp314t-win_arm64.whl", hash = "sha256:ebc55a14a21cb14062aa4162f906cd962b28e2e9ea38f9b4391244cd8de4ae0b", size = 149341, upload-time = "2025-09-25T21:32:56.828Z" },
] ]
[[package]]
name = "ruff"
version = "0.15.18"
source = { registry = "https://pypi.org/simple" }
sdist = { url = "https://files.pythonhosted.org/packages/74/98/1295ad5a5aa9bc85bdcdfa5d82fe7b49c61af5657df4f227637ff9de0da6/ruff-0.15.18.tar.gz", hash = "sha256:2698a964c70e8bf402dcb99c8810472d270d141e7aa8c4e13599fd52033a2f33", size = 4761437, upload-time = "2026-06-18T18:25:39.224Z" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/b9/d0/686e984941269621e2be72612d5c1e461f8f7b38415a2a7d7a81c8ae6715/ruff-0.15.18-py3-none-linux_armv6l.whl", hash = "sha256:8b6850172348c8381b8b3084c5915a4393c2373b9b54cd5b5e1ea15812bc10df", size = 10887308, upload-time = "2026-06-18T18:25:03.062Z" },
{ url = "https://files.pythonhosted.org/packages/ed/21/bc4123e3f5515ee99f8ce1eb93a14a0628fe4d1678663cd08f933ac16931/ruff-0.15.18-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:3fccc153a85417dcd976883160cacce486997b0a0058dd18f54b8aaaac7d1ce2", size = 11281305, upload-time = "2026-06-18T18:25:30.026Z" },
{ url = "https://files.pythonhosted.org/packages/51/93/4769464c25cf7ab2acb3c7dda9cad3d867eb41c59565b3e2a9d17249c90c/ruff-0.15.18-py3-none-macosx_11_0_arm64.whl", hash = "sha256:08d4c86a68f2c3ec2c9d56380a71fb4a4f65373055cbb8caabd645e9102f38d4", size = 10641215, upload-time = "2026-06-18T18:25:15.802Z" },
{ url = "https://files.pythonhosted.org/packages/6c/42/56926d17120db2c208d76bf60a1a019644dd9e91dc27f0f95c9caddb1366/ruff-0.15.18-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:37e5108745c2c0705da916d7d4de533ddf547051ef45f62888c31bae73f66318", size = 10957224, upload-time = "2026-06-18T18:25:36.955Z" },
{ url = "https://files.pythonhosted.org/packages/22/4f/d43fab8d8189afde803103022d000a8ef9f230616d436d52a8b2b8d63b50/ruff-0.15.18-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:56949a6ce8b3abde54c0bcb22cebfe57e8771cadc84b407ae8b8eaf67ebdcd43", size = 10699024, upload-time = "2026-06-18T18:25:05.707Z" },
{ url = "https://files.pythonhosted.org/packages/63/42/1e3e4c68bd408b9768cf3e439acbe2c78245225faef253f7028a0cdb63e0/ruff-0.15.18-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:01a754cd6a1b630d3f97e33eb452cf7a98040482318e870f8bc52a5a30e62657", size = 11491458, upload-time = "2026-06-18T18:25:20.275Z" },
{ url = "https://files.pythonhosted.org/packages/20/77/47a3484bea8521e14a203d98c389c5c97846675e4f02734672da4a69b52a/ruff-0.15.18-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:6ba7a07e03a44dbf10bb086ee06705b173625014ec99f73a7e6836a5e5590a0c", size = 12383752, upload-time = "2026-06-18T18:25:22.535Z" },
{ url = "https://files.pythonhosted.org/packages/0a/ca/054159590787023d83b658a1a1819c4c8910114e7015069340b71c0961cb/ruff-0.15.18-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5a2c40a41a4cadbcf5897b548ab29dfe248b20c540961c0247d98a3973c70403", size = 11577923, upload-time = "2026-06-18T18:25:10.702Z" },
{ url = "https://files.pythonhosted.org/packages/6d/ff/d353d6b7bbd73cc0ec37f4463d7540e45e894338abdd9964eee0de332708/ruff-0.15.18-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5f0480ce690cbb6c4db6e5d08f19fce98e10ba131a8b60c1bcdac42771e3ae2d", size = 11583925, upload-time = "2026-06-18T18:25:32.391Z" },
{ url = "https://files.pythonhosted.org/packages/c1/4a/891f89b9c296ed3e5f3ece1a5629badc989d9a8fdaa30431aaf4774bc1c2/ruff-0.15.18-py3-none-manylinux_2_31_riscv64.whl", hash = "sha256:2330215f1f393fa8733f55edce04fcf94c36a2c460fcde31f78cc84e4951e9b1", size = 11582834, upload-time = "2026-06-18T18:25:27.309Z" },
{ url = "https://files.pythonhosted.org/packages/32/a3/ed9e370154bf85de360b93c03026157f02d4943b2d01ff4945f4429f8e8a/ruff-0.15.18-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:a6aa6a3d979e48ae617578183674bf264fbe7d0114a796a26bd678d67963c7ff", size = 10927328, upload-time = "2026-06-18T18:25:34.676Z" },
{ url = "https://files.pythonhosted.org/packages/f5/d1/5cf5909329fedb5d39d555ee818ba5cf4638e1a301b89785d34f2905bfcb/ruff-0.15.18-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:a81beadbbff2c9c245561ae3f77b16709d87f35eec650d0501679239d3449b22", size = 10693187, upload-time = "2026-06-18T18:25:08.245Z" },
{ url = "https://files.pythonhosted.org/packages/fd/44/ff6c635cf2c4f4e7b618b6640da057376baa36014695487d88aed4794268/ruff-0.15.18-py3-none-musllinux_1_2_i686.whl", hash = "sha256:2186d9e940ae332ab293623a75b5f4fe49565f449954d50a72a046683aa6b809", size = 11208721, upload-time = "2026-06-18T18:25:41.327Z" },
{ url = "https://files.pythonhosted.org/packages/88/d9/5baa2a30861adfb7022cf33c1e35b2fc18085b08c16f83eff4c7b99a5f48/ruff-0.15.18-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:5c2abf140438032bc77b2284a6c9944ecd8a19e5f1c7b52b1b8e4a0a80d19a7a", size = 11678599, upload-time = "2026-06-18T18:25:13.607Z" },
{ url = "https://files.pythonhosted.org/packages/c3/1a/0725a7cfdc32ff769efb96ee782bec882e16448c5d9e3be947ec4c04ce27/ruff-0.15.18-py3-none-win32.whl", hash = "sha256:02299e6e9fa5b297a3f6d5d10d7bcd655c925b028bb8b9d4588214549c6b9ec4", size = 10901903, upload-time = "2026-06-18T18:25:24.755Z" },
{ url = "https://files.pythonhosted.org/packages/f3/51/805d9f6fb7970505c3504794a5ec350f605361b807fef4dcf214ebd35e72/ruff-0.15.18-py3-none-win_amd64.whl", hash = "sha256:dac80dc8d26b2257dbefabed62f5d255c3937b4ccb122da1fc634794fa3578b3", size = 12041189, upload-time = "2026-06-18T18:25:17.915Z" },
{ url = "https://files.pythonhosted.org/packages/29/4c/67bb45e41609eb4726f1bfeb59e083cf91d14c696d4bd14c234a980be93d/ruff-0.15.18-py3-none-win_arm64.whl", hash = "sha256:b2c9257fcbd4a3e5b977a1904e6facca016bafe2edc17df24db67cfaee03b4e4", size = 11329958, upload-time = "2026-06-18T18:25:43.686Z" },
]
[[package]] [[package]]
name = "scipy" name = "scipy"
version = "1.17.1" version = "1.17.1"
@@ -891,6 +1146,15 @@ wheels = [
{ url = "https://files.pythonhosted.org/packages/b7/ce/149a00dd41f10bc29e5921b496af8b574d8413afcd5e30dfa0ed46c2cc5e/six-1.17.0-py2.py3-none-any.whl", hash = "sha256:4721f391ed90541fddacab5acf947aa0d3dc7d27b2e1e8eda2be8970586c3274", size = 11050, upload-time = "2024-12-04T17:35:26.475Z" }, { url = "https://files.pythonhosted.org/packages/b7/ce/149a00dd41f10bc29e5921b496af8b574d8413afcd5e30dfa0ed46c2cc5e/six-1.17.0-py2.py3-none-any.whl", hash = "sha256:4721f391ed90541fddacab5acf947aa0d3dc7d27b2e1e8eda2be8970586c3274", size = 11050, upload-time = "2024-12-04T17:35:26.475Z" },
] ]
[[package]]
name = "typing-extensions"
version = "4.15.0"
source = { registry = "https://pypi.org/simple" }
sdist = { url = "https://files.pythonhosted.org/packages/72/94/1a15dd82efb362ac84269196e94cf00f187f7ed21c242792a923cdb1c61f/typing_extensions-4.15.0.tar.gz", hash = "sha256:0cea48d173cc12fa28ecabc3b837ea3cf6f38c6d1136f85cbaaf598984861466", size = 109391, upload-time = "2025-08-25T13:49:26.313Z" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/18/67/36e9267722cc04a6b9f15c7f3441c2363321a3ea07da7ae0c0707beb2a9c/typing_extensions-4.15.0-py3-none-any.whl", hash = "sha256:f0fa19c6845758ab08074a0cfa8b7aecb71c999ca73d62883bc25cc018c4e548", size = 44614, upload-time = "2025-08-25T13:49:24.86Z" },
]
[[package]] [[package]]
name = "tzdata" name = "tzdata"
version = "2026.2" version = "2026.2"