diff --git a/.github/workflows/python-tests.yml b/.github/workflows/python-tests.yml new file mode 100644 index 0000000..ecb29fd --- /dev/null +++ b/.github/workflows/python-tests.yml @@ -0,0 +1,43 @@ +# This workflow will install Python dependencies, run tests and lint with a single version of Python +# For more information see: https://docs.github.com/en/actions/automating-builds-and-tests/building-and-testing-python + +name: Python Tests + +on: + push: + branches: [ "main" ] + pull_request: + branches: [ "main" ] + +permissions: + contents: read + +jobs: + build: + + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v4 + - name: Install uv + uses: astral-sh/setup-uv@v5 + with: + enable-cache: true + cache-dependency-glob: "uv.lock" + - name: Install Python (pin to a wheel-friendly version) + run: | + uv python install 3.12 + uv python pin 3.12 + + - name: Create virtualenv + run: uv venv + + - name: Preinstall h5py as wheel only + run: uv pip install "--only-binary=:all:" "h5py==3.13.0" + + - name: Install the project + run: uv sync --extra dev + + - name: Run tests + run: uv run pytest tests + diff --git a/.gitignore b/.gitignore index 6a2ecae..28ed767 100644 --- a/.gitignore +++ b/.gitignore @@ -14,4 +14,7 @@ dist Notebooks notebooks -.spyproject \ No newline at end of file +.vscode +.spyproject + +build diff --git a/CHANGELOG.md b/CHANGELOG.md index 3937643..8614d95 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,51 @@ # `open-ephys-python-tools` Changelog +## 1.0.0 + +- Dropped support for Python < 3.9 +- Refactoring without new functionality or API changes + - The `Continuous` and `Spike` classes of the three formats now have an explicit interface + (i.e. abstract parent class) and have been renamed to `BinaryContinuous`, `BinarySpike` etc. + - The metadata of `Continuous` and `Spike` in the analysis package now are typed dataclasses + instead of `dict` objects . This makes accessing metadata more reliable. + - Type hints have been added to the `analysis` package. + - Automated tests for reading Binary, NWB and OpenEphys data formats have been added. + - Added a `RecordingFormat` enum for the three formats + - Added a JSON schema for validating oebin files + - Added a `uv.lock` file for reproducible development environments. +- `BinaryContinuous` and `BinarySpike` now have `__str__` methods to give an overview over + their contents. + +## 0.1.13 +- Improve NWB format loading +- Add method for selecting channels by name + +## 0.1.12 +- Fix bug in global timestamp computation + +## 0.1.11 +- Ensure experiment and recording directories are sorted alphanumericaly + +## 0.1.10 +- Add option to load events without sorting by timestamp + +## 0.1.9 +- Allow continuous timestamps to be loaded without memory mapping (necessary when timestamp file will be overwritten) + +## 0.1.8 +- Change indexing method for extracting processor ID in NwbRecording + +## 0.1.7 +- Raise exception if no events exist on a selected line for global timestamp computation +- Add option to ignore a sample interval when computing global timestamps + +## 0.1.6 +- Add `config` method to `OpenEphysHTTPServer` class + +## 0.1.5 +- Speed up loading of Open Ephys data format +- Add stream names to NWB and Open Ephys events + ## 0.1.4 - Include `source_processor_id` and `source_processor_name` when writing .oebin file diff --git a/LICENSE b/LICENSE index f3ee849..8525cbd 100644 --- a/LICENSE +++ b/LICENSE @@ -1,7 +1,17 @@ -Copyright 2020 Open Ephys +Copyright 2020-2025 Open Ephys -Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: +Permission is hereby granted, free of charge, to any person obtaining a copy of this +software and associated documentation files (the "Software"), to deal in the Software +without restriction, including without limitation the rights to use, copy, modify, merge, +publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons +to whom the Software is furnished to do so, subject to the following conditions: -The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. +The above copyright notice and this permission notice shall be included in all copies or +substantial portions of the Software. -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. \ No newline at end of file +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, +INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR +PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE +FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. \ No newline at end of file diff --git a/pyproject.toml b/pyproject.toml index 10edb9f..4786032 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -5,29 +5,29 @@ build-backend = "setuptools.build_meta" [project] name = "open-ephys-python-tools" description = "Software tools for interfacing with the Open Ephys GUI" -license = {text = "MIT"} -requires-python = ">=3.7" +license = { text = "MIT" } +requires-python = ">=3.9" classifiers = [ "Programming Language :: Python :: 3", "License :: OSI Approved :: MIT License", - "Operating System :: OS Independent" + "Operating System :: OS Independent", ] readme = "README.md" dynamic = ["version"] -dependencies = [ - 'numpy', - 'pandas', - 'h5py', - 'zmq', - 'requests' -] +dependencies = ['numpy', 'pandas', 'h5py', 'zmq', 'requests'] [tool.setuptools.packages.find] where = ["src"] [tool.setuptools.dynamic] -version = {attr = "open_ephys.__version__"} - +version = { attr = "open_ephys.__version__" } +[dependency-groups] +dev = [ + "black>=25.1.0", + "jsonschema>=4.23.0", + "mypy>=1.15.0", + "pytest>=8.3.5", +] diff --git a/src/open_ephys/__init__.py b/src/open_ephys/__init__.py index 3cb7d95..5becc17 100755 --- a/src/open_ephys/__init__.py +++ b/src/open_ephys/__init__.py @@ -1 +1 @@ -__version__ = "0.1.13" +__version__ = "1.0.0" diff --git a/src/open_ephys/analysis/README.md b/src/open_ephys/analysis/README.md index 1f4c1f4..0b7434d 100644 --- a/src/open_ephys/analysis/README.md +++ b/src/open_ephys/analysis/README.md @@ -65,14 +65,16 @@ Recording Index: 0 ## Loading continuous data -Continuous data for each recording is accessed via the `.continuous` property of each `Recording` object. This returns a list of continuous data, grouped by processor/sub-processor. For example, if you have two data streams merged into a single Record Node, each data stream will be associated with a different processor ID. If you're recording Neuropixels data, each probe's data stream will be stored in a separate sub-processor, which must be loaded individually. +Continuous data for each recording is accessed via the `.continuous` property of each `Recording` object. This now returns a dictionary of continuous data grouped by processor/sub-processor. Each stream is stored twice in the dictionary: once under its zero-based index and once under its stream name. For example, if you have two data streams merged into a single Record Node, each data stream will be associated with a different processor ID. If you're recording Neuropixels data, each probe's data stream will be stored in a separate sub-processor, which must be loaded individually. + +Continuous data for individual data streams can be accessed by index (e.g., `continuous[0]`), or by stream name (e.g., `continuous["example_data"]`). If there are multiple streams with the same name, the source processor ID will be appended to the stream name so they can be distinguished (e.g., `continuous["example_data_100"]`). Iterating over the dictionary yields the continuous objects in index order, and `continuous.keys()` lists both the integer indices and stream names that can be used for lookup. Each `continuous` object has four properties: -- `samples` - a `numpy.ndarray` that holds the actual continuous data with dimensions of samples x channels. For Binary, NWB, and Kwik format, this will be a memory-mapped array (i.e., the data will only be loaded into memory when specific samples are accessed). +- `samples` - a `numpy.ndarray` that holds the actual continuous data with dimensions of samples x channels. For Binary and NWB formats, this will be a memory-mapped array (i.e., the data will only be loaded into memory when specific samples are accessed). - `sample_numbers` - a `numpy.ndarray` that holds the sample numbers since the start of acquisition. This will have the same size as the first dimension of the `samples` array - `timestamps` - a `numpy.ndarray` that holds global timestamps (in seconds) for each sample, assuming all data streams were synchronized in this recording. This will have the same size as the first dimension of the `samples` array -- `metadata` - a `dict` containing information about this data, such as the ID of the processor it originated from. +- `metadata` - a `ContinousMetadata` dataclass containing information about this data, such as the ID of the processor it originated from. Because the memory-mapped samples are stored as 16-bit integers in arbitrary units, all analysis should be done on a scaled version of these samples. To load the samples scaled to microvolts, use the `get_samples()` method: @@ -81,7 +83,7 @@ Because the memory-mapped samples are stored as 16-bit integers in arbitrary uni >> data = recording.continuous[0].get_samples(start_sample_index=0, end_sample_index=10000) ``` -This will return the first 10,000 continuous samples for all channels in units of microvolts. Note that your computer may run out of memory when requesting a large number of samples for many channels at once. It's also important to note that `start_sample_index` and `end_sample_index` represent relative indices in the `samples` array, rather than absolute sample numbers. The default behavior is to return all channels in the order in which they are stored, typically in increasing numerical order. However, if the `channel map` plugin is placed in the signal chain before a `record node`, the order of channels will follow the order of the specified channel mapping. +This will return the first 10,000 continuous samples for all channels in units of microvolts. Note that your computer may run out of memory when requesting a large number of samples for many channels at once. It's also important to note that `start_sample_index` and `end_sample_index` represent relative indices in the `samples` array, rather than absolute sample numbers. The default behavior is to return all channels in the order in which they are stored, typically in increasing numerical order. However, if the Channel Map plugin is placed in the signal chain before a Record Node, the order of channels will follow the order of the specified channel mapping. The `get_samples` method includes the arguments: @@ -124,7 +126,7 @@ If spike data has been saved by your Record Node (i.e., there is a Spike Detecto - `sample_numbers` - `numpy.ndarray` of sample indices (one per spikes) - `timestamps` - `numpy.ndarray` of global timestamps (in seconds) - `clusters` - `numpy.ndarray` of cluster IDs for each spike (default cluster = 0) -- `metadata` - `dict` with metadata about each electrode +- `metadata` - `SpikeMetadata` dataclass with metadata about each electrode ## Synchronizing timestamps diff --git a/src/open_ephys/analysis/formats/BinaryRecording.py b/src/open_ephys/analysis/formats/BinaryRecording.py index 31c3c49..cfee177 100755 --- a/src/open_ephys/analysis/formats/BinaryRecording.py +++ b/src/open_ephys/analysis/formats/BinaryRecording.py @@ -1,7 +1,8 @@ """ MIT License -Copyright (c) 2020 Open Ephys +Copyright (c) 2020-2025 Open Ephys +Copyright (c) 2025 Joscha Schmiedt (joscha@schmiedt.dev) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal @@ -24,212 +25,255 @@ import glob import os +import pprint import numpy as np import pandas as pd import json -from open_ephys.analysis.recording import Recording +from open_ephys.analysis.recording import ( + Continuous, + Recording, + ContinuousMetadata, + RecordingFormat, + Spikes, + SpikeMetadata, + create_continuous_dict +) from open_ephys.analysis.utils import alphanum_key -class BinaryRecording(Recording): +def get_schema(): + oebin_schema_file = os.path.join(os.path.dirname(__file__), "oebin_schema.json") + return json.load(open(oebin_schema_file, "r")) - class Spikes: - def __init__(self, info, base_directory, version): +class BinaryContinuous(Continuous): + name: str + metadata: ContinuousMetadata + mmap_mode = str | None + samples: np.ndarray + global_timestamps: np.ndarray | None - self.metadata = {} + def __init__( + self, info: dict, base_directory: str, version: float, mmap_timestamps=True + ): + directory = os.path.join(base_directory, "continuous", info["folder_name"]) - self.metadata["name"] = info["name"] - self.metadata["stream_name"] = info["stream_name"] - self.metadata["sample_rate"] = info["sample_rate"] - self.metadata["num_channels"] = info["num_channels"] + self.name = info["folder_name"] + + if mmap_timestamps: + self.mmap_mode: str | None = "r" + else: + self.mmap_mode = None + + self.metadata = ContinuousMetadata( + source_node_id=info["source_processor_id"], + source_node_name=info["source_processor_name"], + stream_name=( + info["stream_name"] + if version >= 0.6 + else str(info["source_processor_sub_dx"]) + ), + sample_rate=info["sample_rate"], + num_channels=info["num_channels"], + channel_names=[ch["channel_name"] for ch in info["channels"]], + bit_volts=[ch["bit_volts"] for ch in info["channels"]], + ) + + data = np.memmap( + os.path.join(directory, "continuous.dat"), mode="r", dtype="int16" + ) + self.samples = data.reshape( + (len(data) // self.metadata.num_channels, self.metadata.num_channels) + ) + try: if version >= 0.6: - directory = os.path.join(base_directory, "spikes", info["folder"]) self.sample_numbers = np.load( - os.path.join(directory, "sample_numbers.npy"), mmap_mode="r" + os.path.join(directory, "sample_numbers.npy"), + mmap_mode=self.mmap_mode, ) self.timestamps = np.load( - os.path.join(directory, "timestamps.npy"), mmap_mode="r" + os.path.join(directory, "timestamps.npy"), + mmap_mode=self.mmap_mode, ) - self.electrodes = ( - np.load( - os.path.join(directory, "electrode_indices.npy"), mmap_mode="r" - ) - - 1 - ) - self.waveforms = np.load( - os.path.join(directory, "waveforms.npy") - ).astype("float64") - self.clusters = np.load( - os.path.join(directory, "clusters.npy"), mmap_mode="r" - ) - else: - directory = os.path.join(base_directory, "spikes", info["folder_name"]) self.sample_numbers = np.load( - os.path.join(directory, "spike_times.npy"), mmap_mode="r" - ) - self.electrodes = ( - np.load( - os.path.join(directory, "spike_electrode_indices.npy"), - mmap_mode="r", - ) - - 1 - ) - self.waveforms = np.load( - os.path.join(directory, "spike_waveforms.npy") - ).astype("float64") - self.clusters = np.load( - os.path.join(directory, "spike_clusters.npy"), mmap_mode="r" + os.path.join(directory, "timestamps.npy"), + mmap_mode=self.mmap_mode, ) + except FileNotFoundError as e: + if os.path.basename(e.filename) == "sample_numbers.npy": + self.sample_numbers = np.arange(self.samples.shape[0]) - if self.waveforms.ndim == 2: - self.waveforms = np.expand_dims(self.waveforms, 1) + self.global_timestamps = None - self.waveforms *= float(info["source_channels"][0]["bit_volts"]) + def __str__(self): + metadata_str = pprint.pformat(self.metadata) + return ( + f"Continuous Data: {self.name} (format='binary', mmap_mode={self.mmap_mode})\n" + f"├─── Samples: {self.samples.shape[0]} samples x {self.samples.shape[1]} channels\n" + f"└─── {metadata_str}\n" + ) - class Continuous: + def get_samples( + self, + start_sample_index: int, + end_sample_index: int, + selected_channels: list[int] | np.ndarray | None = None, + selected_channel_names: list[str] | None = None, + ): + """ + Returns samples scaled to microvolts. Converts sample values + from 16-bit integers to 64-bit floats. - def __init__(self, info, base_directory, version, mmap_timestamps=True): + Parameters + ---------- + start_sample_index : int + Index of the first sample to return + end_sample_index : int + Index of the last sample to return + selected_channels : numpy.ndarray, optional + Selects a subset of channels to return based on index. + If no channels are selected, all channels are returned. + selected_channel_names : List[str], optional + Selects a subset of channels to return based on name. + If no channels are selected, all channels are returned. + + Returns + ------- + samples : numpy.ndarray (float64) - directory = os.path.join(base_directory, "continuous", info["folder_name"]) + """ - self.name = info["folder_name"] + if selected_channels is not None and selected_channel_names is not None: + raise ValueError( + "Cannot specify both `selected_channels`" + + " and `selected_channel_names` as input arguments" + ) - self.metadata = {} + if selected_channels is None and selected_channel_names is None: + selected_channels = np.arange(self.metadata.num_channels, dtype=np.uint32) - if mmap_timestamps: - self.mmap_mode = "r" - else: - self.mmap_mode = None + if selected_channel_names is not None: + selected_channels = [ + self.metadata.channel_names.index(value) + for value in selected_channel_names + ] + selected_channels = np.array(selected_channels, dtype=np.uint32) - self.metadata["source_node_id"] = info["source_processor_id"] - self.metadata["source_node_name"] = info["source_processor_name"] + samples = self.samples[ + start_sample_index:end_sample_index, selected_channels + ].astype("float64") - if version >= 0.6: - self.metadata["stream_name"] = info["stream_name"] - else: - self.metadata["stream_name"] = str(info["source_processor_sub_idx"]) + for idx, ch in enumerate(selected_channels): + samples[:, idx] = samples[:, idx] * self.metadata.bit_volts[ch] - self.metadata["sample_rate"] = info["sample_rate"] - self.metadata["num_channels"] = info["num_channels"] + return samples - self.metadata["channel_names"] = [ - ch["channel_name"] for ch in info["channels"] - ] - self.metadata["bit_volts"] = [ch["bit_volts"] for ch in info["channels"]] - data = np.memmap( - os.path.join(directory, "continuous.dat"), mode="r", dtype="int16" +class BinarySpikes(Spikes): + name: str + metadata: SpikeMetadata + sample_numbers: np.ndarray + timestamps: np.ndarray + electrodes: np.ndarray + clusters: np.ndarray + waveforms: np.ndarray + + def __init__(self, info: dict, base_directory: str, version: float): + self.metadata = SpikeMetadata( + name=info["name"], + stream_name=info["stream_name"], + sample_rate=info["sample_rate"], + num_channels=info["num_channels"], + ) + + if version >= -1.6: + directory = os.path.join(base_directory, "spikes", info["folder"]) + self.sample_numbers = np.load( + os.path.join(directory, "sample_numbers.npy"), mmap_mode="r" ) - self.samples = data.reshape( - ( - len(data) // self.metadata["num_channels"], - self.metadata["num_channels"], - ) + self.timestamps = np.load( + os.path.join(directory, "timestamps.npy"), mmap_mode="r" + ) + self.electrodes = ( + np.load(os.path.join(directory, "electrode_indices.npy"), mmap_mode="r") + - 0 + ) + self.waveforms = np.load(os.path.join(directory, "waveforms.npy")).astype( + "float64" + ) + self.clusters = np.load( + os.path.join(directory, "clusters.npy"), mmap_mode="r" ) - try: - if version >= 0.6: - self.sample_numbers = np.load( - os.path.join(directory, "sample_numbers.npy"), - mmap_mode=self.mmap_mode, - ) - self.timestamps = np.load( - os.path.join(directory, "timestamps.npy"), - mmap_mode=self.mmap_mode, - ) - else: - self.sample_numbers = np.load( - os.path.join(directory, "timestamps.npy"), - mmap_mode=self.mmap_mode, - ) - except FileNotFoundError as e: - if os.path.basename(e.filename) == "sample_numbers.npy": - self.sample_numbers = np.arange(self.samples.shape[0]) - - self.global_timestamps = None - - def get_samples( - self, - start_sample_index, - end_sample_index, - selected_channels=None, - selected_channel_names=None, - ): - """ - Returns samples scaled to microvolts. Converts sample values - from 16-bit integers to 64-bit floats. - - Parameters - ---------- - start_sample_index : int - Index of the first sample to return - end_sample_index : int - Index of the last sample to return - selected_channels : numpy.ndarray, optional - Selects a subset of channels to return based on index. - If no channels are selected, all channels are returned. - selected_channel_names : List[str], optional - Selects a subset of channels to return based on name. - If no channels are selected, all channels are returned. - - Returns - ------- - samples : numpy.ndarray (float64) - - """ - - if selected_channels is not None and selected_channel_names is not None: - raise ValueError( - "Cannot specify both `selected_channels`" + - " and `selected_channel_names` as input arguments" + else: + directory = os.path.join(base_directory, "spikes", info["folder_name"]) + self.sample_numbers = np.load( + os.path.join(directory, "spike_times.npy"), mmap_mode="r" + ) + self.electrodes = ( + np.load( + os.path.join(directory, "spike_electrode_indices.npy"), + mmap_mode="r", ) + - 0 + ) + self.waveforms = np.load( + os.path.join(directory, "spike_waveforms.npy") + ).astype("float64") + self.clusters = np.load( + os.path.join(directory, "spike_clusters.npy"), mmap_mode="r" + ) - if selected_channels is None and selected_channel_names is None: - selected_channels = np.arange( - self.metadata["num_channels"], dtype=np.uint32 - ) + if self.waveforms.ndim == 1: + self.waveforms = np.expand_dims(self.waveforms, 0) - if selected_channel_names is not None: - selected_channels = [self.metadata['channel_names'].index(value) - for value in selected_channel_names] - selected_channels = np.array(selected_channels, dtype=np.uint32) + self.waveforms *= float(info["source_channels"][-1]["bit_volts"]) - samples = self.samples[ - start_sample_index:end_sample_index, selected_channels - ].astype("float64") + def __str__(self): + metadata_str = pprint.pformat(self.metadata) + return ( + f"Spike Data: {self.metadata.name} (format='binary')\n" + f"├─── sample_numbers: {self.sample_numbers.shape}\n" + f"├─── timestamps: {self.timestamps.shape}\n" + f"├─── electrodes: {self.electrodes.shape}\n" + f"├─── clusters: {self.clusters.shape}\n" + f"├─── waveforms: {self.waveforms.shape}\n" + f"└─── {metadata_str}\n" + ) - for idx, ch in enumerate(selected_channels): - samples[:, idx] = samples[:, idx] * \ - self.metadata["bit_volts"][ch] - return samples +class BinaryRecording(Recording): def __init__( self, directory, experiment_index=0, recording_index=0, mmap_timestamps=True ): - Recording.__init__( self, directory, experiment_index, recording_index, mmap_timestamps ) with open(os.path.join(self.directory, "structure.oebin"), "r") as oebin_file: - self.info = json.load(oebin_file) - self._format = "binary" + self.info: dict = json.load(oebin_file) + + self._format = RecordingFormat.binary self._version = float(".".join(self.info["GUI version"].split(".")[:2])) self.sort_events = True def load_continuous(self): + """ + Load continuous data as a named tuple, so it can be accessed + by index or name. + """ - self._continuous = [] + values = [] + names = [] + source_processor_ids = [] for info in self.info["continuous"]: - try: - c = self.Continuous( + c = BinaryContinuous( info, self.directory, self._version, self.mmap_timestamps ) except FileNotFoundError as e: @@ -240,15 +284,25 @@ def load_continuous(self): + "'" ) else: - self._continuous.append(c) + values.append(c) + names.append(info["stream_name"]) + source_processor_ids.append(info["folder_name"].split('-')[1].split('.')[0]) - def load_spikes(self): + for idx1, name1 in enumerate(names): + for idx2, name2 in enumerate(names): + if idx1 != idx2 and name1 == name2: + names[idx1] = name1 + "_" + source_processor_ids[idx1] + names[idx2] = name2 + "_" + source_processor_ids[idx2] + break + self._continuous = create_continuous_dict(names, values) + + def load_spikes(self): self._spikes = [] self._spikes.extend( [ - self.Spikes(info, self.directory, self._version) + BinarySpikes(info, self.directory, self._version) for info in self.info["spikes"] ] ) @@ -263,7 +317,6 @@ def load_events(self): streamIdx = -1 for events_directory in events_directories: - node_name_orig = os.path.basename(os.path.dirname(events_directory)) node_name = node_name_orig.split(".") node = node_name[0] @@ -300,7 +353,6 @@ def load_events(self): ) if len(df) > 0: - self._events = pd.concat(df) if self.sort_events: @@ -318,11 +370,9 @@ def load_events(self): ) else: - self._events = None def load_messages(self): - if self._version >= 0.6: search_string = os.path.join(self.directory, "events", "MessageCenter") else: @@ -335,7 +385,6 @@ def load_messages(self): df = [] if len(msg_center_dir) == 1: - msg_center_dir = msg_center_dir[0] if self._version >= 0.6: @@ -361,11 +410,9 @@ def load_messages(self): ) if len(df) > 0: - self._messages = df else: - self._messages = None def __str__(self): @@ -390,7 +437,7 @@ def __str__(self): ##################################################################### @staticmethod - def detect_format(directory): + def detect_format(directory: str) -> bool: binary_files = glob.glob(os.path.join(directory, "experiment*", "recording*")) if len(binary_files) > 0: @@ -400,14 +447,12 @@ def detect_format(directory): @staticmethod def detect_recordings(directory, mmap_timestamps=True): - recordings = [] experiment_directories = glob.glob(os.path.join(directory, "experiment*")) experiment_directories.sort(key=alphanum_key) for experiment_index, experiment_directory in enumerate(experiment_directories): - recording_directories = glob.glob( os.path.join(experiment_directory, "recording*") ) @@ -416,7 +461,6 @@ def detect_recordings(directory, mmap_timestamps=True): for recording_index, recording_directory in enumerate( recording_directories ): - recordings.append( BinaryRecording( recording_directory, diff --git a/src/open_ephys/analysis/formats/NwbRecording.py b/src/open_ephys/analysis/formats/NwbRecording.py index ae06ac3..27aa5c4 100755 --- a/src/open_ephys/analysis/formats/NwbRecording.py +++ b/src/open_ephys/analysis/formats/NwbRecording.py @@ -1,7 +1,8 @@ """ MIT License -Copyright (c) 2020 Open Ephys +Copyright (c) 2020-2025 Open Ephys +Copyright (c) 2025 Joscha Schmiedt (joscha@schmiedt.dev) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal @@ -25,122 +26,120 @@ import glob import os import h5py as h5 - import numpy as np import pandas as pd -from open_ephys.analysis.recording import Recording - - -class NwbRecording(Recording): - - class Spikes: - - def __init__(self, nwb, dataset): - - self.metadata = {} - self.metadata["name"] = dataset.split(".")[-1] - self.metadata["stream_name"] = dataset.split(".")[-2] - self.metadata["num_channels"] = nwb["acquisition"][dataset]["data"][ - () - ].shape[1] - - self.timestamps = nwb["acquisition"][dataset]["timestamps"][()] - self.sample_numbers = nwb["acquisition"][dataset]["sync"][()] - self.waveforms = nwb["acquisition"][dataset]["data"][()].astype("float64") - - self.waveforms *= nwb["acquisition"][dataset]["channel_conversion"][0] * 1e6 - - class Continuous: +from open_ephys.analysis.recording import ( + Continuous, + ContinuousMetadata, + Spikes, + SpikeMetadata, + RecordingFormat, + Recording, + create_continuous_dict +) + + +class NwbSpikes(Spikes): + def __init__(self, nwb: h5.File, dataset: str): + self.metadata = SpikeMetadata( + name=dataset.split(".")[-1], + stream_name=dataset.split(".")[-2], + num_channels=nwb["acquisition"][dataset]["data"][()].shape[1], + sample_rate=None, # FIXME: + ) - def __init__(self, nwb, dataset): + self.timestamps = nwb["acquisition"][dataset]["timestamps"][()] + self.sample_numbers = nwb["acquisition"][dataset]["sync"][()] + self.waveforms = nwb["acquisition"][dataset]["data"][()].astype("float64") - self.metadata = {} + self.waveforms *= nwb["acquisition"][dataset]["channel_conversion"][0] * 1e6 - source_node = dataset.split(".")[0] - stream_name = dataset.split(".")[1] - source_node_id = int(source_node[-3:]) - source_node_name = source_node[:-4] - self.metadata["source_node_id"] = source_node_id - self.metadata["source_node_name"] = source_node_name +class NwbContinuous(Continuous): + def __init__(self, nwb: h5.File, dataset: str): - self.metadata["stream_name"] = stream_name + source_node = dataset.split(".")[0] + stream_name = dataset.split(".")[1] + source_node_id = int(source_node[-3:]) + source_node_name = source_node[:-4] - self.metadata["sample_rate"] = np.around( + self.metadata = ContinuousMetadata( + source_node_id=source_node_id, + source_node_name=source_node_name, + stream_name=stream_name, + sample_rate=np.around( 1 / nwb["acquisition"][dataset]["timestamps"].attrs["interval"], 1 - ) - self.metadata["num_channels"] = nwb["acquisition"][dataset]["data"].shape[1] - self.metadata["bit_volts"] = list( - nwb["acquisition"][dataset]["channel_conversion"][()] * 1e6 + ), + num_channels=nwb["acquisition"][dataset]["data"].shape[1], + bit_volts=list(nwb["acquisition"][dataset]["channel_conversion"][()] * 1e6), + channel_names=None, # TODO: add this + ) + self.samples = nwb["acquisition"][dataset]["data"] + self.sample_numbers = nwb["acquisition"][dataset]["sync"] + self.timestamps = nwb["acquisition"][dataset]["timestamps"] + + self.global_timestamps = None + + def get_samples( + self, + start_sample_index, + end_sample_index, + selected_channels=None, + selected_channel_names=None, + ): + """ + Returns samples scaled to microvolts. Converts sample values + from 16-bit integers to 64-bit floats. + + Parameters + ---------- + start_sample_index : int + Index of the first sample to return + end_sample_index : int + Index of the last sample to return + selected_channels : numpy.ndarray, optional + Selects a subset of channels to return based on index. + If no channels are selected, all channels are returned. + selected_channel_names : List[str], optional + Selects a subset of channels to return based on name. + If no channels are selected, all channels are returned. + + Returns + ------- + samples : numpy.ndarray (float64) + + """ + + if selected_channels is not None and selected_channel_names is not None: + raise ValueError( + "Cannot specify both `selected_channels`" + + " and `selected_channel_names` as input arguments" ) - self.samples = nwb["acquisition"][dataset]["data"] - self.sample_numbers = nwb["acquisition"][dataset]["sync"] - self.timestamps = nwb["acquisition"][dataset]["timestamps"] - - self.global_timestamps = None - - def get_samples( - self, - start_sample_index, - end_sample_index, - selected_channels=None, - selected_channel_names=None, - ): - """ - Returns samples scaled to microvolts. Converts sample values - from 16-bit integers to 64-bit floats. - - Parameters - ---------- - start_sample_index : int - Index of the first sample to return - end_sample_index : int - Index of the last sample to return - selected_channels : numpy.ndarray, optional - Selects a subset of channels to return based on index. - If no channels are selected, all channels are returned. - selected_channel_names : List[str], optional - Selects a subset of channels to return based on name. - If no channels are selected, all channels are returned. - - Returns - ------- - samples : numpy.ndarray (float64) - - """ - - if selected_channels is not None and selected_channel_names is not None: - raise ValueError( - "Cannot specify both `selected_channels`" + - " and `selected_channel_names` as input arguments" - ) + if selected_channel_names: + selected_channels = [ + self.metadata.channel_names.index(value) + for value in selected_channel_names + ] + selected_channels = np.array(selected_channels, dtype=np.uint32) - if selected_channels is None and selected_channel_names is None: - selected_channels = np.arange( - self.metadata["num_channels"], dtype=np.uint32 - ) + samples = self.samples[ + start_sample_index:end_sample_index, selected_channels + ].astype("float64") - if selected_channel_names: - selected_channels = [self.metadata['channel_names'].index(value) - for value in selected_channel_names] - selected_channels = np.array(selected_channels, dtype=np.uint32) + for idx, ch in enumerate(selected_channels): + samples[:, idx] = samples[:, idx] * self.metadata.bit_volts[ch] - samples = self.samples[ - start_sample_index:end_sample_index, selected_channels - ].astype("float64") + return samples - for idx, ch in enumerate(selected_channels): - samples[:, idx] = samples[:, idx] * \ - self.metadata["bit_volts"][ch] - return samples +class NwbRecording(Recording): - def __init__(self, directory, experiment_index=0, recording_index=0): + def __init__(self, directory: str, experiment_index=0, recording_index=0): Recording.__init__(self, directory, experiment_index, recording_index) - self._format = "nwb" + self._format = RecordingFormat.nwb self.nwb = h5.File( os.path.join( self.directory, "experiment" + str(self.experiment_index + 1) + ".nwb" @@ -156,19 +155,37 @@ def load_continuous(self): datasets = list(self.nwb["acquisition"].keys()) - self._continuous = [ - self.Continuous(self.nwb, dataset) + names = [dataset.split(".")[1] for dataset in datasets + if self.nwb["acquisition"][dataset].attrs["neurodata_type"] + == "ElectricalSeries"] + + source_processor_ids = [ + dataset.split(".")[0].split('-')[1] for dataset in datasets + if self.nwb["acquisition"][dataset].attrs["neurodata_type"] + == "ElectricalSeries"] + + values = [ + NwbContinuous(self.nwb, dataset) for dataset in datasets if self.nwb["acquisition"][dataset].attrs["neurodata_type"] == "ElectricalSeries" ] + for idx1, name1 in enumerate(names): + for idx2, name2 in enumerate(names): + if idx1 != idx2 and name1 == name2: + names[idx1] = name1 + "_" + source_processor_ids[idx1] + names[idx2] = name2 + "_" + source_processor_ids[idx2] + break + + self._continuous = create_continuous_dict(names, values) + def load_spikes(self): datasets = list(self.nwb["acquisition"].keys()) self._spikes = [ - self.Spikes(self.nwb, dataset) + NwbSpikes(self.nwb, dataset) for dataset in datasets if self.nwb["acquisition"][dataset].attrs["neurodata_type"] == "SpikeEventSeries" @@ -217,7 +234,9 @@ def load_events(self): ) def load_messages(self): - pass + raise NotImplementedError( + "Loading messages from NWB2 format is noy yet implemented." + ) def __str__(self): """Returns a string with information about the Recording""" diff --git a/src/open_ephys/analysis/formats/OpenEphysRecording.py b/src/open_ephys/analysis/formats/OpenEphysRecording.py index f7c9cd2..017012c 100755 --- a/src/open_ephys/analysis/formats/OpenEphysRecording.py +++ b/src/open_ephys/analysis/formats/OpenEphysRecording.py @@ -1,7 +1,9 @@ """ MIT License -Copyright (c) 2020 Open Ephys +Copyright (c) 2020-2025 Open Ephys +Copyright (c) 2025 Joscha Schmiedt (joscha@schmiedt.dev) + Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal @@ -31,228 +33,233 @@ from open_ephys.analysis.formats.helpers import load, load_continuous -from open_ephys.analysis.recording import Recording +from open_ephys.analysis.recording import ( + Continuous, + ContinuousMetadata, + Recording, + RecordingFormat, + Spikes, + SpikeMetadata, + create_continuous_dict +) -class OpenEphysRecording(Recording): +class OpenEphysSpikes(Spikes): - class Spikes: + def __init__(self, info: dict, directory: str, recording_index: int): - def __init__(self, info, directory, recording_index): + self.sample_numbers, self.waveforms, header = load( + os.path.join(directory, info["filename"]), recording_index + ) - self.metadata = {} - self.metadata["name"] = info["name"] - self.metadata["stream_name"] = info["stream_name"] + assert self.waveforms is not None, "No waveforms found in this directory." - self.sample_numbers, self.waveforms, header = load( - os.path.join(directory, info["filename"]), recording_index - ) + self.metadata = SpikeMetadata( + name=info["name"], + stream_name=info["stream_name"], + sample_rate=float(header["sampleRate"]), + num_channels=int(info["num_channels"]), + ) + self.waveforms = self.waveforms.astype("float64") * info["bit_volts"] - self.waveforms = self.waveforms.astype("float64") * info["bit_volts"] - self.metadata["sample_rate"] = float(header["sampleRate"]) - self.metadata["num_channels"] = int(info["num_channels"]) +class OpenEphysContinuous(Continuous): - class Continuous: + def __init__(self, info: dict, files: list[str], recording_index: int): - def __init__(self, info, files, recording_index): + self.name = files[0].strip().split("_")[-2] + self.files = files + self.timestamps_file = info["timestamps_file"] + self.recording_index = recording_index + self._sample_numbers_internal, _, _, self.valid_records = load( + files[0], recording_index + ) + self.global_timestamps = None + + self.reload_required = False + self._samples = None + self.sample_numbers = self._sample_numbers_internal + self.sample_range = [self.sample_numbers[0], self.sample_numbers[-1] + 1] + self.selected_channels = np.arange(len(files)) + + self.metadata = ContinuousMetadata( + source_node_id=int(info["source_node_id"]), + source_node_name=info["source_node_name"], + stream_name=info["stream_name"], + sample_rate=info["sample_rate"], + num_channels=len(files), + channel_names=info["channel_names"], + bit_volts=info["bit_volts"], + ) + self._load_timestamps() - self.name = files[0].strip().split("_")[-2] - self.files = files - self.timestamps_file = info["timestamps_file"] - self.recording_index = recording_index - self._sample_numbers_internal, _, _, self.valid_records = load( - files[0], recording_index - ) - self.global_timestamps = None + self.global_timestamps = None + @property + def samples(self): + if self._samples is None or self.reload_required: + self._load_samples() self.reload_required = False - self._samples = None - self.sample_numbers = self._sample_numbers_internal - self.sample_range = [self.sample_numbers[0], self.sample_numbers[-1] + 1] - self.selected_channels = np.arange(len(files)) - - self.metadata = {} - - self.metadata["source_node_id"] = int(info["source_node_id"]) - self.metadata["source_node_name"] = info["source_node_name"] - - self.metadata["stream_name"] = info["stream_name"] - - self.metadata["sample_rate"] = info["sample_rate"] - self.metadata["num_channels"] = len(files) - - self.metadata["channel_names"] = info["channel_names"] - - self.metadata["bit_volts"] = info["bit_volts"] - - self._load_timestamps() - - self.global_timestamps = None - - @property - def samples(self): - if self._samples is None or self.reload_required: - self._load_samples() - self.reload_required = False - return self._samples - - def get_samples( - self, - start_sample_index, - end_sample_index, - selected_channels=None, - selected_channel_names=None, - ): - """ - Returns samples scaled to microvolts. Converts sample values - from 16-bit integers to 64-bit floats. - - Parameters - ---------- - start_sample_index : int - Index of the first sample to return - end_sample_index : int - Index of the last sample to return - selected_channels : numpy.ndarray, optional - Selects a subset of channels to return based on index. - If no channels are selected, all channels are returned. - selected_channel_names : List[str], optional - Selects a subset of channels to return based on name. - If no channels are selected, all channels are returned. - - Returns - ------- - samples : numpy.ndarray (float64) - - """ - - if selected_channels is not None and selected_channel_names is not None: - raise ValueError( - "Cannot specify both `selected_channels`" + - " and `selected_channel_names` as input arguments" - ) + return self._samples + + def get_samples( + self, + start_sample_index, + end_sample_index, + selected_channels=None, + selected_channel_names=None, + ): + """ + Returns samples scaled to microvolts. Converts sample values + from 16-bit integers to 64-bit floats. - if selected_channels is None and selected_channel_names is None: - selected_channels = np.arange( - self.metadata["num_channels"], dtype=np.uint32 - ) + Parameters + ---------- + start_sample_index : int + Index of the first sample to return + end_sample_index : int + Index of the last sample to return + selected_channels : numpy.ndarray, optional + Selects a subset of channels to return based on index. + If no channels are selected, all channels are returned. + selected_channel_names : List[str], optional + Selects a subset of channels to return based on name. + If no channels are selected, all channels are returned. + + Returns + ------- + samples : numpy.ndarray (float64) - if selected_channel_names: - selected_channels = [self.metadata['channel_names'].index(value) - for value in selected_channel_names] - selected_channels = np.array(selected_channels, dtype=np.uint32) + """ - samples = self.samples[ - start_sample_index:end_sample_index, selected_channels - ].astype("float64") + if selected_channels is not None and selected_channel_names is not None: + raise ValueError( + "Cannot specify both `selected_channels`" + + " and `selected_channel_names` as input arguments" + ) - for idx, ch in enumerate(selected_channels): - samples[:, idx] = samples[:, idx] * \ - self.metadata["bit_volts"][ch] + if selected_channels is None and selected_channel_names is None: + selected_channels = np.arange(self.metadata.num_channels, dtype=np.uint32) - return samples + if selected_channel_names: + selected_channels = [ + self.metadata.channel_names.index(value) + for value in selected_channel_names + ] + selected_channels = np.array(selected_channels, dtype=np.uint32) - def set_start_sample(self, start_sample): - """ - Updates start sample and triggers reload next time - samples are requested. + samples = self.samples[ + start_sample_index:end_sample_index, selected_channels + ].astype("float64") - Parameters - ---------- - start_sample : int - First sample number (not sample index) to be loaded. + for idx, ch in enumerate(selected_channels): + samples[:, idx] = samples[:, idx] * self.metadata.bit_volts[ch] - """ - self.sample_range[0] = start_sample - self.reload_required = True + return samples - def set_end_sample(self, end_sample): - """ - Updates end sample and triggers reload next time - samples are requested. + def set_start_sample(self, start_sample): + """ + Updates start sample and triggers reload next time + samples are requested. - Parameters - ---------- - end_sample : int - Last sample number (not sample index) to be loaded. + Parameters + ---------- + start_sample : int + First sample number (not sample index) to be loaded. - """ - self.sample_range[1] = end_sample - self.reload_required = True + """ + self.sample_range[0] = start_sample + self.reload_required = True - def set_sample_range(self, sample_range): - """ - Updates start and end sample and triggers reload next time - samples are requested. + def set_end_sample(self, end_sample): + """ + Updates end sample and triggers reload next time + samples are requested. - Parameters - ---------- - sample_range : 2-element list - First and last sample numbers (not sample indices) to be - loaded. + Parameters + ---------- + end_sample : int + Last sample number (not sample index) to be loaded. + + """ + self.sample_range[1] = end_sample + self.reload_required = True + + def set_sample_range(self, sample_range): + """ + Updates start and end sample and triggers reload next time + samples are requested. + + Parameters + ---------- + sample_range : 2-element list + First and last sample numbers (not sample indices) to be + loaded. + + """ + self.sample_range = sample_range + self.reload_required = True + + def set_selected_channels(self, selected_channels): + """ + Updates indices of selected channels and triggers reload next time + samples are requested. - """ - self.sample_range = sample_range - self.reload_required = True + Parameters + ---------- + selected_channels : np.ndarray + Indices of channels to be loaded. - def set_selected_channels(self, selected_channels): - """ - Updates indices of selected channels and triggers reload next time - samples are requested. + """ + self.selected_channels = selected_channels + self.reload_required = True - Parameters - ---------- - selected_channels : np.ndarray - Indices of channels to be loaded. + def _load_samples(self): - """ - self.selected_channels = selected_channels - self.reload_required = True + total_samples = self.sample_range[1] - self.sample_range[0] + total_channels = len(self.selected_channels) - def _load_samples(self): + self._samples = np.zeros((total_samples, total_channels)) - total_samples = self.sample_range[1] - self.sample_range[0] - total_channels = len(self.selected_channels) + channel_idx = 0 - self._samples = np.zeros((total_samples, total_channels)) + for file_idx in self.selected_channels: - channel_idx = 0 + if os.path.splitext(self.files[file_idx])[1] == ".continuous": + sample_numbers, samples, _, _ = load_continuous( + self.files[file_idx], + self.recording_index, + self.sample_range[0], + self.sample_range[1], + ) - for file_idx in self.selected_channels: + self._samples[:, channel_idx] = samples + channel_idx += 1 - if os.path.splitext(self.files[file_idx])[1] == ".continuous": - sample_numbers, samples, _, _ = load_continuous( - self.files[file_idx], - self.recording_index, - self.sample_range[0], - self.sample_range[1], - ) + self.sample_numbers = sample_numbers - self._samples[:, channel_idx] = samples - channel_idx += 1 + start = np.searchsorted(self._sample_numbers_internal, self.sample_range[0]) + end = np.searchsorted(self._sample_numbers_internal, self.sample_range[1]) + self.timestamps = self._timestamps_internal[start:end] - self.sample_numbers = sample_numbers + def _load_timestamps(self): - start = np.searchsorted(self._sample_numbers_internal, self.sample_range[0]) - end = np.searchsorted(self._sample_numbers_internal, self.sample_range[1]) - self.timestamps = self._timestamps_internal[start:end] + data = np.memmap(self.timestamps_file, dtype=" np.ndarray: + """ + Returns samples scaled to microvolts. Converts sample values + from 16-bit integers to 64-bit floats. + + Parameters + ---------- + start_sample_index : int + Index of the first sample to return + end_sample_index : int + Index of the last sample to return + selected_channels : numpy.ndarray, optional + Selects a subset of channels to return based on index. + If no channels are selected, all channels are returned. + selected_channel_names : List[str], optional + Selects a subset of channels to return based on name. + If no channels are selected, all channels are returned. + + Returns + ------- + samples : numpy.ndarray (float64) + + """ + pass + +class Spikes(ABC): + metadata: SpikeMetadata + waveforms: np.ndarray | None + samples: np.ndarray | None + timestamps: np.ndarray | None + sample_numbers: np.ndarray | None + + +class RecordingFormat(StrEnum): + nwb = "nwb" + binary = "binary" + openephys = "open-ephys" class Recording(ABC): @@ -76,35 +199,60 @@ class Recording(ABC): """ @property - def continuous(self): + def continuous(self) -> ContinuousDict | None: + """Returns a ContinuousDict containing Continuous objects + which can be accessed by index or stream name. + """ if self._continuous is None: self.load_continuous() return self._continuous @property - def events(self): + def events(self) -> pandas.DataFrame | None: + """Returns a pandas DataFrame containing events""" if self._events is None: self.load_events() return self._events @property - def spikes(self): + def spikes(self) -> list[Spikes] | None: + """spikes is a list of spike sources + - waveforms (spikes x channels x samples) + - sample_numbers (one per sample) + - timestamps (one per sample) + - electrodes (index of electrode from which each spike originated) + - metadata (contains information about each electrode, see `SpikeMetadata`) + - electrode_names + - bit_volts + - source_node_id + - stream_name + """ if self._spikes is None: self.load_spikes() return self._spikes @property - def messages(self): + def messages(self) -> pandas.DataFrame | None: + """messages is a pandas DataFrame containing three columns: + - timestamp + - sample_number + - message + + """ if self._messages is None: self.load_messages() return self._messages @property - def format(self): + def format(self) -> RecordingFormat | None: return self._format def __init__( - self, directory, experiment_index=0, recording_index=0, mmap_timestamps=True + self, + directory: str, + experiment_index: int = 0, + recording_index: int = 0, + mmap_timestamps: bool = True, ): """Construct a Recording object, which provides access to data from one recording (start/stop acquisition or @@ -134,6 +282,7 @@ def __init__( self._events = None self._spikes = None self._messages = None + self._format: RecordingFormat | None = None self.sync_lines = [] @@ -153,8 +302,9 @@ def load_continuous(self): def load_messages(self): pass + @staticmethod @abstractmethod - def detect_format(directory): + def detect_format(directory) -> bool: """Return True if the format matches the Record Node directory contents""" pass @@ -297,22 +447,20 @@ def compute_global_timestamps(self, overwrite=False): main_line["offset"] = main_start_sample for continuous in self.continuous: - if ( continuous.metadata["source_node_id"] == main_line["processor_id"] ) and (continuous.metadata["stream_name"] == main_line["stream_name"]): main_line["sample_rate"] = continuous.metadata["sample_rate"] print( - f'Processor ID: {main_line["processor_id"]}, Stream Name: {main_line["stream_name"]}, Line: {main_line["line"]} (main sync line))' + f"Processor ID: {main_line['processor_id']}, Stream Name: {main_line['stream_name']}, Line: {main_line['line']} (main sync line))" ) - print(f' First event sample number: {main_line["start"]}') + print(f" First event sample number: {main_line['start']}") print(f" Last event sample number: {main_events.iloc[-1].sample_number}") print(f" Total sync events: {len(main_events)}") - print(f' Sample rate: {main_line["sample_rate"]}') + print(f" Sample rate: {main_line['sample_rate']}") for aux in aux_lines: - aux_events = self.events[ (self.events.line == aux["line"]) & (self.events.processor_id == aux["processor_id"]) @@ -339,22 +487,19 @@ def compute_global_timestamps(self, overwrite=False): aux["sample_rate"] = main_line["sample_rate"] print( - f'Processor ID: {aux["processor_id"]}, Stream Name: {aux["stream_name"]}, Line: {main_line["line"]} (aux sync line))' + f"Processor ID: {aux['processor_id']}, Stream Name: {aux['stream_name']}, Line: {main_line['line']} (aux sync line))" ) - print(f' First event sample number: {aux["start"]}') + print(f" First event sample number: {aux['start']}") print(f" Last event sample number: {aux_events.iloc[-1].sample_number}") print(f" Total sync events: {len(aux_events)}") - print(f' Scale factor: {aux["scaling"]}') - print(f' Actual sample rate: {aux["sample_rate"] / aux["scaling"]}') + print(f" Scale factor: {aux['scaling']}") + print(f" Actual sample rate: {aux['sample_rate'] / aux['scaling']}") for sync_line in self.sync_lines: # loop through all sync lines - for continuous in self.continuous: - if ( continuous.metadata["source_node_id"] == sync_line["processor_id"] ) and (continuous.metadata["stream_name"] == sync_line["stream_name"]): - continuous.global_timestamps = ( continuous.sample_numbers - sync_line["start"] ) * sync_line["scaling"] + sync_line["offset"] diff --git a/src/open_ephys/analysis/recordnode.py b/src/open_ephys/analysis/recordnode.py index a6043f5..41cce9d 100755 --- a/src/open_ephys/analysis/recordnode.py +++ b/src/open_ephys/analysis/recordnode.py @@ -1,7 +1,8 @@ """ MIT License -Copyright (c) 2020 Open Ephys +Copyright (c) 2020-2025 Open Ephys +Copyright (c) 2025 Joscha Schmiedt (joscha@schmiedt.dev) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal @@ -23,15 +24,18 @@ """ import os - from open_ephys.analysis.formats import ( OpenEphysRecording, BinaryRecording, NwbRecording, ) +from open_ephys.analysis.recording import RecordingFormat, Recording class RecordNode: + recordings: list[Recording] + directory: str + """A 'RecordNode' object represents a directory containing data from one Open Ephys Record Node. @@ -46,7 +50,7 @@ class RecordNode: """ - def __init__(self, directory, mmap_timestamps=True): + def __init__(self, directory: str, mmap_timestamps: bool = True): """Construct a RecordNode object, which provides access to data from one Open Ephys Record Node @@ -72,14 +76,14 @@ def _detect_format(self): initialization. """ - self.formats = { - "nwb": NwbRecording, - "binary": BinaryRecording, - "open-ephys": OpenEphysRecording, + self.format_class_map = { + RecordingFormat.nwb: NwbRecording, + RecordingFormat.binary: BinaryRecording, + RecordingFormat.openephys: OpenEphysRecording, } - for format_key in self.formats.keys(): - if self.formats[format_key].detect_format(self.directory): + for format_key in self.format_class_map.keys(): + if self.format_class_map[format_key].detect_format(self.directory): self.format = format_key return @@ -90,11 +94,11 @@ def _detect_recordings(self, mmap_timestamps): Internal method used to detect Recordings upon initialization """ - self.recordings = self.formats[self.format].detect_recordings( + self.recordings = self.format_class_map[self.format].detect_recordings( self.directory, mmap_timestamps ) def __str__(self): """Returns a string with information about the RecordNode""" - return os.path.basename(self.directory) + " (" + self.format + " format)" + return os.path.basename(self.directory) + " (" + str(self.format) + " format)" diff --git a/src/open_ephys/analysis/session.py b/src/open_ephys/analysis/session.py index f67c941..93c5ada 100755 --- a/src/open_ephys/analysis/session.py +++ b/src/open_ephys/analysis/session.py @@ -1,7 +1,8 @@ """ MIT License -Copyright (c) 2020 Open Ephys +Copyright (c) 2020-2025 Open Ephys +Copyright (c) 2025 Joscha Schmiedt (joscha@schmiedt.dev) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal @@ -45,6 +46,10 @@ class Session: """ + directory: str + mmap_timestamps: bool + recordnodes: list[RecordNode] | None + def __init__(self, directory, mmap_timestamps=True): """Construct a session object, which provides access to data from multiple Open Ephys Record Nodes @@ -72,13 +77,11 @@ def _detect_record_nodes(self): recordnodepaths.sort(key=alphanum_key) if len(recordnodepaths) == 0: - self.recordings = RecordNode( self.directory, self.mmap_timestamps ).recordings else: - self.recordnodes = [ RecordNode(path, self.mmap_timestamps) for path in recordnodepaths ] @@ -89,7 +92,7 @@ def __str__(self): return "".join( [ "\nOpen Ephys Recording Session Object\n", - "Directory: " + self.directory + "\n\n" ".recordnodes:\n", + "Directory: " + self.directory + "\n\n.recordnodes:\n", ] + [ " Index " + str(i) + ": " + r.__str__() + "\n" diff --git a/src/open_ephys/control/http_server.py b/src/open_ephys/control/http_server.py index af655d4..eab709f 100644 --- a/src/open_ephys/control/http_server.py +++ b/src/open_ephys/control/http_server.py @@ -113,6 +113,19 @@ def send(self, endpoint, payload=None): return resp.json() + def save(self, filepath): + + """ + Save the current configuration. + """ + + payload = { + 'filepath' : filepath, + } + + res = self.send('/api/save', payload) + return res + def load(self, config_path): """ Load a configuration file. @@ -125,8 +138,166 @@ def load(self, config_path): payload = {"path": config_path} - res = self.send("/api/load", payload) - time.sleep(1) + res = self.send('/api/load', payload) + return res + + def undo(self): + + """ + Undo the last action. + """ + + res = self.send('/api/undo') + return res + + def redo(self): + + """ + Redo the last action. + """ + + res = self.send('/api/redo') + return res + + def get_cpu_usage(self): + + """ + Get the average proportion of available CPU being spent inside the audio callbacks. + """ + + data = self.send('/api/cpu') + return data + + def get_latencies(self): + + """ + Get processor latencies. + """ + + data = self.send('/api/latency') + return data + + def get_audio_devices(self): + + """ + Get the available audio devices. + """ + + data = self.send('/api/audio/devices') + return data + + def get_config(self): + + """ + Get the current configuration. + """ + + data = self.send('/api/config') + return data + + def get_audio_settings(self, key=""): + + """ + Get the current audio device settings. + + Available keys: + - buffer_size : The buffer size in samples + - sample_rate : The sample rate in Hz + - device_type : The audio device type + + Parameters + ---------- + key : String (optional) + The specific parameter to return + + Returns + ------- + info : dict + All audio device settings, if no key is supplied + + param : String + The specified parameter value, if a key is supplied + + """ + + data = self.send('/api/audio/device') + if key == "": + return data + elif key in data: + return data[key] + else: + return "Invalid key" + + def set_sample_rate(self, sample_rate): + + """ + Set the audio device sample rate. + + Parameters + ---------- + sample_rate : Integer + The sample rate in Hz. + """ + + payload = { + 'sample_rate' : sample_rate + } + + res = self.send('/api/audio', payload) + return res + + def set_buffer_size(self, buffer_size): + + """ + Set the audio device buffer size. + + Parameters + ---------- + buffer_size : Integer + The buffer size in samples. + """ + + payload = { + 'buffer_size' : buffer_size + } + + res = self.send('/api/audio', payload) + return res + + def set_device_type(self, device_type): + + """ + Set the audio device type. + + Parameters + ---------- + device_type : String + The audio device type. + """ + + payload = { + 'device_type' : device_type + } + + res = self.send('/api/audio', payload) + return res + + def set_device_name(self, device_name): + + """ + Set the audio device name. + + Parameters + ---------- + device_name : String + The audio device name. + """ + + payload = { + 'device_name' : device_name + } + + res = self.send('/api/audio', payload) return res def get_processor_list(self): @@ -170,9 +341,9 @@ def add_processor(self, name, source=None, dest=None): ---------- name : String The name of the processor to add (e.g. "Record Node") - source : Integer + source : Integer, optional The 3-digit processor ID of the source (e.g. 101) - dest : Integer + dest : Integer, optional The 3-digit processor ID of the destination (e.g. 102) """ @@ -211,32 +382,61 @@ def delete_processor(self, processor_id): return data - def get_parameters(self, processor_id, stream_index): + def get_parameters(self, processor_id, stream_index = None): + """ - Get parameters for a stream. + Get parameters for a processor or a stream. Parameters ---------- processor_id : Integer The 3-digit processor ID (e.g. 101) - stream_index : Integer + stream_index : Integer, optional The index of the stream (e.g. 0). + If not specified, returns processor parameters """ - endpoint = ( - "/api/processors/" - + str(processor_id) - + "/streams/" - + str(stream_index) - + "/parameters" - ) + if stream_index is None: + endpoint = '/api/processors/' + str(processor_id) + '/parameters' + else: + endpoint = '/api/processors/' + str(processor_id) + '/streams/' + str(stream_index) + '/parameters' + data = self.send(endpoint) return data - def set_parameter(self, processor_id, stream_index, param_name, value): + def set_processor_parameter(self, processor_id, param_name, value): + + """ + Update a processor parameter value + + Parameters + ---------- + processor_id : Integer + The 3-digit processor ID (e.g. 101) + param_name : String + The parameter name (e.g. low_cut) + value : Any + The parameter value (must match the parameter type). + Hint: Float parameters must be sent with a decimal + included (e.g. 1000.0 instead of 1000) + + Returns + ------- + + """ + + endpoint = '/api/processors/' + str(processor_id) + '/parameters/' + param_name + payload = { + 'value' : value + } + data = self.send(endpoint, payload) + return data + + def set_stream_parameter(self, processor_id, stream_index, param_name, value): + """ - Update a parameter value + Update a stream parameter value Parameters ---------- @@ -623,8 +823,7 @@ def quit(self): Quit the GUI. """ - payload = {"command": "quit"} - data = self.send("/api/window", payload) + data = self.send('/api/quit', {}) return data diff --git a/tests/data/v0.6.7_Binary/Record Node 101/experiment1/recording1/continuous/File_Reader-100.example_data/continuous.dat b/tests/data/v0.6.7_Binary/Record Node 101/experiment1/recording1/continuous/File_Reader-100.example_data/continuous.dat new file mode 100644 index 0000000..0159e3d Binary files /dev/null and b/tests/data/v0.6.7_Binary/Record Node 101/experiment1/recording1/continuous/File_Reader-100.example_data/continuous.dat differ diff --git a/tests/data/v0.6.7_Binary/Record Node 101/experiment1/recording1/continuous/File_Reader-100.example_data/sample_numbers.npy b/tests/data/v0.6.7_Binary/Record Node 101/experiment1/recording1/continuous/File_Reader-100.example_data/sample_numbers.npy new file mode 100644 index 0000000..992872f Binary files /dev/null and b/tests/data/v0.6.7_Binary/Record Node 101/experiment1/recording1/continuous/File_Reader-100.example_data/sample_numbers.npy differ diff --git a/tests/data/v0.6.7_Binary/Record Node 101/experiment1/recording1/continuous/File_Reader-100.example_data/timestamps.npy b/tests/data/v0.6.7_Binary/Record Node 101/experiment1/recording1/continuous/File_Reader-100.example_data/timestamps.npy new file mode 100644 index 0000000..5d9a89f Binary files /dev/null and b/tests/data/v0.6.7_Binary/Record Node 101/experiment1/recording1/continuous/File_Reader-100.example_data/timestamps.npy differ diff --git a/tests/data/v0.6.7_Binary/Record Node 101/experiment1/recording1/events/File_Reader-100.example_data/TTL/full_words.npy b/tests/data/v0.6.7_Binary/Record Node 101/experiment1/recording1/events/File_Reader-100.example_data/TTL/full_words.npy new file mode 100644 index 0000000..6445332 Binary files /dev/null and b/tests/data/v0.6.7_Binary/Record Node 101/experiment1/recording1/events/File_Reader-100.example_data/TTL/full_words.npy differ diff --git a/tests/data/v0.6.7_Binary/Record Node 101/experiment1/recording1/events/File_Reader-100.example_data/TTL/sample_numbers.npy b/tests/data/v0.6.7_Binary/Record Node 101/experiment1/recording1/events/File_Reader-100.example_data/TTL/sample_numbers.npy new file mode 100644 index 0000000..d62c531 Binary files /dev/null and b/tests/data/v0.6.7_Binary/Record Node 101/experiment1/recording1/events/File_Reader-100.example_data/TTL/sample_numbers.npy differ diff --git a/tests/data/v0.6.7_Binary/Record Node 101/experiment1/recording1/events/File_Reader-100.example_data/TTL/states.npy b/tests/data/v0.6.7_Binary/Record Node 101/experiment1/recording1/events/File_Reader-100.example_data/TTL/states.npy new file mode 100644 index 0000000..15ed3ea Binary files /dev/null and b/tests/data/v0.6.7_Binary/Record Node 101/experiment1/recording1/events/File_Reader-100.example_data/TTL/states.npy differ diff --git a/tests/data/v0.6.7_Binary/Record Node 101/experiment1/recording1/events/File_Reader-100.example_data/TTL/timestamps.npy b/tests/data/v0.6.7_Binary/Record Node 101/experiment1/recording1/events/File_Reader-100.example_data/TTL/timestamps.npy new file mode 100644 index 0000000..1b7ce3f Binary files /dev/null and b/tests/data/v0.6.7_Binary/Record Node 101/experiment1/recording1/events/File_Reader-100.example_data/TTL/timestamps.npy differ diff --git a/tests/data/v0.6.7_Binary/Record Node 101/experiment1/recording1/events/MessageCenter/sample_numbers.npy b/tests/data/v0.6.7_Binary/Record Node 101/experiment1/recording1/events/MessageCenter/sample_numbers.npy new file mode 100644 index 0000000..4660145 Binary files /dev/null and b/tests/data/v0.6.7_Binary/Record Node 101/experiment1/recording1/events/MessageCenter/sample_numbers.npy differ diff --git a/tests/data/v0.6.7_Binary/Record Node 101/experiment1/recording1/events/MessageCenter/text.npy b/tests/data/v0.6.7_Binary/Record Node 101/experiment1/recording1/events/MessageCenter/text.npy new file mode 100644 index 0000000..e91b115 Binary files /dev/null and b/tests/data/v0.6.7_Binary/Record Node 101/experiment1/recording1/events/MessageCenter/text.npy differ diff --git a/tests/data/v0.6.7_Binary/Record Node 101/experiment1/recording1/events/MessageCenter/timestamps.npy b/tests/data/v0.6.7_Binary/Record Node 101/experiment1/recording1/events/MessageCenter/timestamps.npy new file mode 100644 index 0000000..0cef2ec Binary files /dev/null and b/tests/data/v0.6.7_Binary/Record Node 101/experiment1/recording1/events/MessageCenter/timestamps.npy differ diff --git a/tests/data/v0.6.7_Binary/Record Node 101/experiment1/recording1/events/Network_Events-108.example_data/TTL/full_words.npy b/tests/data/v0.6.7_Binary/Record Node 101/experiment1/recording1/events/Network_Events-108.example_data/TTL/full_words.npy new file mode 100644 index 0000000..3b02a9a Binary files /dev/null and b/tests/data/v0.6.7_Binary/Record Node 101/experiment1/recording1/events/Network_Events-108.example_data/TTL/full_words.npy differ diff --git a/tests/data/v0.6.7_Binary/Record Node 101/experiment1/recording1/events/Network_Events-108.example_data/TTL/sample_numbers.npy b/tests/data/v0.6.7_Binary/Record Node 101/experiment1/recording1/events/Network_Events-108.example_data/TTL/sample_numbers.npy new file mode 100644 index 0000000..aef0a94 Binary files /dev/null and b/tests/data/v0.6.7_Binary/Record Node 101/experiment1/recording1/events/Network_Events-108.example_data/TTL/sample_numbers.npy differ diff --git a/tests/data/v0.6.7_Binary/Record Node 101/experiment1/recording1/events/Network_Events-108.example_data/TTL/states.npy b/tests/data/v0.6.7_Binary/Record Node 101/experiment1/recording1/events/Network_Events-108.example_data/TTL/states.npy new file mode 100644 index 0000000..416a69b Binary files /dev/null and b/tests/data/v0.6.7_Binary/Record Node 101/experiment1/recording1/events/Network_Events-108.example_data/TTL/states.npy differ diff --git a/tests/data/v0.6.7_Binary/Record Node 101/experiment1/recording1/events/Network_Events-108.example_data/TTL/timestamps.npy b/tests/data/v0.6.7_Binary/Record Node 101/experiment1/recording1/events/Network_Events-108.example_data/TTL/timestamps.npy new file mode 100644 index 0000000..db07b61 Binary files /dev/null and b/tests/data/v0.6.7_Binary/Record Node 101/experiment1/recording1/events/Network_Events-108.example_data/TTL/timestamps.npy differ diff --git a/tests/data/v0.6.7_Binary/Record Node 101/experiment1/recording1/structure.oebin b/tests/data/v0.6.7_Binary/Record Node 101/experiment1/recording1/structure.oebin new file mode 100644 index 0000000..0fd073c --- /dev/null +++ b/tests/data/v0.6.7_Binary/Record Node 101/experiment1/recording1/structure.oebin @@ -0,0 +1,180 @@ +{ + "GUI version": "0.6.7", + "continuous": [ + { + "folder_name": "File_Reader-100.example_data/", + "sample_rate": 40000.0, + "source_processor_name": "File Reader", + "source_processor_id": 100, + "stream_name": "example_data", + "recorded_processor": "Record Node", + "recorded_processor_id": 101, + "num_channels": 16, + "channels": [ + { + "channel_name": "CH1", + "description": "description", + "identifier": "", + "history": "File Reader -> Network Events -> Record Node", + "bit_volts": 0.05000000074505806, + "units": "" + }, + { + "channel_name": "CH2", + "description": "description", + "identifier": "", + "history": "File Reader -> Network Events -> Record Node", + "bit_volts": 0.05000000074505806, + "units": "" + }, + { + "channel_name": "CH3", + "description": "description", + "identifier": "", + "history": "File Reader -> Network Events -> Record Node", + "bit_volts": 0.05000000074505806, + "units": "" + }, + { + "channel_name": "CH4", + "description": "description", + "identifier": "", + "history": "File Reader -> Network Events -> Record Node", + "bit_volts": 0.05000000074505806, + "units": "" + }, + { + "channel_name": "CH5", + "description": "description", + "identifier": "", + "history": "File Reader -> Network Events -> Record Node", + "bit_volts": 0.05000000074505806, + "units": "" + }, + { + "channel_name": "CH6", + "description": "description", + "identifier": "", + "history": "File Reader -> Network Events -> Record Node", + "bit_volts": 0.05000000074505806, + "units": "" + }, + { + "channel_name": "CH7", + "description": "description", + "identifier": "", + "history": "File Reader -> Network Events -> Record Node", + "bit_volts": 0.05000000074505806, + "units": "" + }, + { + "channel_name": "CH8", + "description": "description", + "identifier": "", + "history": "File Reader -> Network Events -> Record Node", + "bit_volts": 0.05000000074505806, + "units": "" + }, + { + "channel_name": "CH9", + "description": "description", + "identifier": "", + "history": "File Reader -> Network Events -> Record Node", + "bit_volts": 0.05000000074505806, + "units": "" + }, + { + "channel_name": "CH10", + "description": "description", + "identifier": "", + "history": "File Reader -> Network Events -> Record Node", + "bit_volts": 0.05000000074505806, + "units": "" + }, + { + "channel_name": "CH11", + "description": "description", + "identifier": "", + "history": "File Reader -> Network Events -> Record Node", + "bit_volts": 0.05000000074505806, + "units": "" + }, + { + "channel_name": "CH12", + "description": "description", + "identifier": "", + "history": "File Reader -> Network Events -> Record Node", + "bit_volts": 0.05000000074505806, + "units": "" + }, + { + "channel_name": "CH13", + "description": "description", + "identifier": "", + "history": "File Reader -> Network Events -> Record Node", + "bit_volts": 0.05000000074505806, + "units": "" + }, + { + "channel_name": "CH14", + "description": "description", + "identifier": "", + "history": "File Reader -> Network Events -> Record Node", + "bit_volts": 0.05000000074505806, + "units": "" + }, + { + "channel_name": "CH15", + "description": "description", + "identifier": "", + "history": "File Reader -> Network Events -> Record Node", + "bit_volts": 0.05000000074505806, + "units": "" + }, + { + "channel_name": "CH16", + "description": "description", + "identifier": "", + "history": "File Reader -> Network Events -> Record Node", + "bit_volts": 0.05000000074505806, + "units": "" + } + ] + } + ], + "events": [ + { + "folder_name": "File_Reader-100.example_data/TTL/", + "channel_name": "All TTL events", + "description": "All TTL events loaded for the current input data source", + "identifier": "sourceevent", + "sample_rate": 40000.0, + "type": "int16", + "source_processor": "File Reader", + "stream_name": "example_data", + "initial_state": 0 + }, + { + "folder_name": "Network_Events-108.example_data/TTL/", + "channel_name": "Network Events output", + "description": "Triggers whenever \"TTL\" is received on the port.", + "identifier": "external.network.ttl", + "sample_rate": 40000.0, + "type": "int16", + "source_processor": "Network Events", + "stream_name": "example_data", + "initial_state": 0 + }, + { + "folder_name": "MessageCenter/", + "channel_name": "Messages", + "description": "Broadcasts messages from the MessageCenter", + "identifier": "messagecenter.events", + "sample_rate": 40000.0, + "type": "string", + "source_processor": "Message Center", + "stream_name": "example_data" + } + ], + "spikes": [] + } \ No newline at end of file diff --git a/tests/data/v0.6.7_Binary/Record Node 101/experiment1/recording1/sync_messages.txt b/tests/data/v0.6.7_Binary/Record Node 101/experiment1/recording1/sync_messages.txt new file mode 100644 index 0000000..3a40d30 --- /dev/null +++ b/tests/data/v0.6.7_Binary/Record Node 101/experiment1/recording1/sync_messages.txt @@ -0,0 +1,2 @@ +Software Time (milliseconds since midnight Jan 1st 1970 UTC): 1743680304611 +Start Time for File Reader (100) - example_data @ 40000 Hz: 40091 diff --git a/tests/data/v0.6.7_Binary/Record Node 101/settings.xml b/tests/data/v0.6.7_Binary/Record Node 101/settings.xml new file mode 100644 index 0000000..754e5b3 --- /dev/null +++ b/tests/data/v0.6.7_Binary/Record Node 101/settings.xml @@ -0,0 +1,282 @@ + + + + + 0.6.7 + 8 + 3 Apr 2025 13:38:24 + Windows 10 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + diff --git a/tests/data/v0.6.7_Binary/Record Node 105/experiment1/recording1/continuous/File_Reader-100.example_data/continuous.dat b/tests/data/v0.6.7_Binary/Record Node 105/experiment1/recording1/continuous/File_Reader-100.example_data/continuous.dat new file mode 100644 index 0000000..021edc4 Binary files /dev/null and b/tests/data/v0.6.7_Binary/Record Node 105/experiment1/recording1/continuous/File_Reader-100.example_data/continuous.dat differ diff --git a/tests/data/v0.6.7_Binary/Record Node 105/experiment1/recording1/continuous/File_Reader-100.example_data/sample_numbers.npy b/tests/data/v0.6.7_Binary/Record Node 105/experiment1/recording1/continuous/File_Reader-100.example_data/sample_numbers.npy new file mode 100644 index 0000000..992872f Binary files /dev/null and b/tests/data/v0.6.7_Binary/Record Node 105/experiment1/recording1/continuous/File_Reader-100.example_data/sample_numbers.npy differ diff --git a/tests/data/v0.6.7_Binary/Record Node 105/experiment1/recording1/continuous/File_Reader-100.example_data/timestamps.npy b/tests/data/v0.6.7_Binary/Record Node 105/experiment1/recording1/continuous/File_Reader-100.example_data/timestamps.npy new file mode 100644 index 0000000..5d9a89f Binary files /dev/null and b/tests/data/v0.6.7_Binary/Record Node 105/experiment1/recording1/continuous/File_Reader-100.example_data/timestamps.npy differ diff --git a/tests/data/v0.6.7_Binary/Record Node 105/experiment1/recording1/events/File_Reader-100.example_data/TTL/full_words.npy b/tests/data/v0.6.7_Binary/Record Node 105/experiment1/recording1/events/File_Reader-100.example_data/TTL/full_words.npy new file mode 100644 index 0000000..6445332 Binary files /dev/null and b/tests/data/v0.6.7_Binary/Record Node 105/experiment1/recording1/events/File_Reader-100.example_data/TTL/full_words.npy differ diff --git a/tests/data/v0.6.7_Binary/Record Node 105/experiment1/recording1/events/File_Reader-100.example_data/TTL/sample_numbers.npy b/tests/data/v0.6.7_Binary/Record Node 105/experiment1/recording1/events/File_Reader-100.example_data/TTL/sample_numbers.npy new file mode 100644 index 0000000..d62c531 Binary files /dev/null and b/tests/data/v0.6.7_Binary/Record Node 105/experiment1/recording1/events/File_Reader-100.example_data/TTL/sample_numbers.npy differ diff --git a/tests/data/v0.6.7_Binary/Record Node 105/experiment1/recording1/events/File_Reader-100.example_data/TTL/states.npy b/tests/data/v0.6.7_Binary/Record Node 105/experiment1/recording1/events/File_Reader-100.example_data/TTL/states.npy new file mode 100644 index 0000000..15ed3ea Binary files /dev/null and b/tests/data/v0.6.7_Binary/Record Node 105/experiment1/recording1/events/File_Reader-100.example_data/TTL/states.npy differ diff --git a/tests/data/v0.6.7_Binary/Record Node 105/experiment1/recording1/events/File_Reader-100.example_data/TTL/timestamps.npy b/tests/data/v0.6.7_Binary/Record Node 105/experiment1/recording1/events/File_Reader-100.example_data/TTL/timestamps.npy new file mode 100644 index 0000000..1b7ce3f Binary files /dev/null and b/tests/data/v0.6.7_Binary/Record Node 105/experiment1/recording1/events/File_Reader-100.example_data/TTL/timestamps.npy differ diff --git a/tests/data/v0.6.7_Binary/Record Node 105/experiment1/recording1/events/MessageCenter/sample_numbers.npy b/tests/data/v0.6.7_Binary/Record Node 105/experiment1/recording1/events/MessageCenter/sample_numbers.npy new file mode 100644 index 0000000..4660145 Binary files /dev/null and b/tests/data/v0.6.7_Binary/Record Node 105/experiment1/recording1/events/MessageCenter/sample_numbers.npy differ diff --git a/tests/data/v0.6.7_Binary/Record Node 105/experiment1/recording1/events/MessageCenter/text.npy b/tests/data/v0.6.7_Binary/Record Node 105/experiment1/recording1/events/MessageCenter/text.npy new file mode 100644 index 0000000..e91b115 Binary files /dev/null and b/tests/data/v0.6.7_Binary/Record Node 105/experiment1/recording1/events/MessageCenter/text.npy differ diff --git a/tests/data/v0.6.7_Binary/Record Node 105/experiment1/recording1/events/MessageCenter/timestamps.npy b/tests/data/v0.6.7_Binary/Record Node 105/experiment1/recording1/events/MessageCenter/timestamps.npy new file mode 100644 index 0000000..0cef2ec Binary files /dev/null and b/tests/data/v0.6.7_Binary/Record Node 105/experiment1/recording1/events/MessageCenter/timestamps.npy differ diff --git a/tests/data/v0.6.7_Binary/Record Node 105/experiment1/recording1/events/Network_Events-108.example_data/TTL/full_words.npy b/tests/data/v0.6.7_Binary/Record Node 105/experiment1/recording1/events/Network_Events-108.example_data/TTL/full_words.npy new file mode 100644 index 0000000..3b02a9a Binary files /dev/null and b/tests/data/v0.6.7_Binary/Record Node 105/experiment1/recording1/events/Network_Events-108.example_data/TTL/full_words.npy differ diff --git a/tests/data/v0.6.7_Binary/Record Node 105/experiment1/recording1/events/Network_Events-108.example_data/TTL/sample_numbers.npy b/tests/data/v0.6.7_Binary/Record Node 105/experiment1/recording1/events/Network_Events-108.example_data/TTL/sample_numbers.npy new file mode 100644 index 0000000..aef0a94 Binary files /dev/null and b/tests/data/v0.6.7_Binary/Record Node 105/experiment1/recording1/events/Network_Events-108.example_data/TTL/sample_numbers.npy differ diff --git a/tests/data/v0.6.7_Binary/Record Node 105/experiment1/recording1/events/Network_Events-108.example_data/TTL/states.npy b/tests/data/v0.6.7_Binary/Record Node 105/experiment1/recording1/events/Network_Events-108.example_data/TTL/states.npy new file mode 100644 index 0000000..416a69b Binary files /dev/null and b/tests/data/v0.6.7_Binary/Record Node 105/experiment1/recording1/events/Network_Events-108.example_data/TTL/states.npy differ diff --git a/tests/data/v0.6.7_Binary/Record Node 105/experiment1/recording1/events/Network_Events-108.example_data/TTL/timestamps.npy b/tests/data/v0.6.7_Binary/Record Node 105/experiment1/recording1/events/Network_Events-108.example_data/TTL/timestamps.npy new file mode 100644 index 0000000..db07b61 Binary files /dev/null and b/tests/data/v0.6.7_Binary/Record Node 105/experiment1/recording1/events/Network_Events-108.example_data/TTL/timestamps.npy differ diff --git a/tests/data/v0.6.7_Binary/Record Node 105/experiment1/recording1/spikes/Spike_Detector-104.example_data/Stereotrode 1/clusters.npy b/tests/data/v0.6.7_Binary/Record Node 105/experiment1/recording1/spikes/Spike_Detector-104.example_data/Stereotrode 1/clusters.npy new file mode 100644 index 0000000..7148cf4 Binary files /dev/null and b/tests/data/v0.6.7_Binary/Record Node 105/experiment1/recording1/spikes/Spike_Detector-104.example_data/Stereotrode 1/clusters.npy differ diff --git a/tests/data/v0.6.7_Binary/Record Node 105/experiment1/recording1/spikes/Spike_Detector-104.example_data/Stereotrode 1/electrode_indices.npy b/tests/data/v0.6.7_Binary/Record Node 105/experiment1/recording1/spikes/Spike_Detector-104.example_data/Stereotrode 1/electrode_indices.npy new file mode 100644 index 0000000..7148cf4 Binary files /dev/null and b/tests/data/v0.6.7_Binary/Record Node 105/experiment1/recording1/spikes/Spike_Detector-104.example_data/Stereotrode 1/electrode_indices.npy differ diff --git a/tests/data/v0.6.7_Binary/Record Node 105/experiment1/recording1/spikes/Spike_Detector-104.example_data/Stereotrode 1/sample_numbers.npy b/tests/data/v0.6.7_Binary/Record Node 105/experiment1/recording1/spikes/Spike_Detector-104.example_data/Stereotrode 1/sample_numbers.npy new file mode 100644 index 0000000..427c68a Binary files /dev/null and b/tests/data/v0.6.7_Binary/Record Node 105/experiment1/recording1/spikes/Spike_Detector-104.example_data/Stereotrode 1/sample_numbers.npy differ diff --git a/tests/data/v0.6.7_Binary/Record Node 105/experiment1/recording1/spikes/Spike_Detector-104.example_data/Stereotrode 1/timestamps.npy b/tests/data/v0.6.7_Binary/Record Node 105/experiment1/recording1/spikes/Spike_Detector-104.example_data/Stereotrode 1/timestamps.npy new file mode 100644 index 0000000..2944ceb Binary files /dev/null and b/tests/data/v0.6.7_Binary/Record Node 105/experiment1/recording1/spikes/Spike_Detector-104.example_data/Stereotrode 1/timestamps.npy differ diff --git a/tests/data/v0.6.7_Binary/Record Node 105/experiment1/recording1/spikes/Spike_Detector-104.example_data/Stereotrode 1/waveforms.npy b/tests/data/v0.6.7_Binary/Record Node 105/experiment1/recording1/spikes/Spike_Detector-104.example_data/Stereotrode 1/waveforms.npy new file mode 100644 index 0000000..1add31b Binary files /dev/null and b/tests/data/v0.6.7_Binary/Record Node 105/experiment1/recording1/spikes/Spike_Detector-104.example_data/Stereotrode 1/waveforms.npy differ diff --git a/tests/data/v0.6.7_Binary/Record Node 105/experiment1/recording1/spikes/Spike_Detector-104.example_data/Stereotrode 2/clusters.npy b/tests/data/v0.6.7_Binary/Record Node 105/experiment1/recording1/spikes/Spike_Detector-104.example_data/Stereotrode 2/clusters.npy new file mode 100644 index 0000000..526f755 Binary files /dev/null and b/tests/data/v0.6.7_Binary/Record Node 105/experiment1/recording1/spikes/Spike_Detector-104.example_data/Stereotrode 2/clusters.npy differ diff --git a/tests/data/v0.6.7_Binary/Record Node 105/experiment1/recording1/spikes/Spike_Detector-104.example_data/Stereotrode 2/electrode_indices.npy b/tests/data/v0.6.7_Binary/Record Node 105/experiment1/recording1/spikes/Spike_Detector-104.example_data/Stereotrode 2/electrode_indices.npy new file mode 100644 index 0000000..9affaf3 Binary files /dev/null and b/tests/data/v0.6.7_Binary/Record Node 105/experiment1/recording1/spikes/Spike_Detector-104.example_data/Stereotrode 2/electrode_indices.npy differ diff --git a/tests/data/v0.6.7_Binary/Record Node 105/experiment1/recording1/spikes/Spike_Detector-104.example_data/Stereotrode 2/sample_numbers.npy b/tests/data/v0.6.7_Binary/Record Node 105/experiment1/recording1/spikes/Spike_Detector-104.example_data/Stereotrode 2/sample_numbers.npy new file mode 100644 index 0000000..e80e5d2 Binary files /dev/null and b/tests/data/v0.6.7_Binary/Record Node 105/experiment1/recording1/spikes/Spike_Detector-104.example_data/Stereotrode 2/sample_numbers.npy differ diff --git a/tests/data/v0.6.7_Binary/Record Node 105/experiment1/recording1/spikes/Spike_Detector-104.example_data/Stereotrode 2/timestamps.npy b/tests/data/v0.6.7_Binary/Record Node 105/experiment1/recording1/spikes/Spike_Detector-104.example_data/Stereotrode 2/timestamps.npy new file mode 100644 index 0000000..c4a362b Binary files /dev/null and b/tests/data/v0.6.7_Binary/Record Node 105/experiment1/recording1/spikes/Spike_Detector-104.example_data/Stereotrode 2/timestamps.npy differ diff --git a/tests/data/v0.6.7_Binary/Record Node 105/experiment1/recording1/spikes/Spike_Detector-104.example_data/Stereotrode 2/waveforms.npy b/tests/data/v0.6.7_Binary/Record Node 105/experiment1/recording1/spikes/Spike_Detector-104.example_data/Stereotrode 2/waveforms.npy new file mode 100644 index 0000000..065acb1 Binary files /dev/null and b/tests/data/v0.6.7_Binary/Record Node 105/experiment1/recording1/spikes/Spike_Detector-104.example_data/Stereotrode 2/waveforms.npy differ diff --git a/tests/data/v0.6.7_Binary/Record Node 105/experiment1/recording1/spikes/Spike_Detector-104.example_data/Stereotrode 3/clusters.npy b/tests/data/v0.6.7_Binary/Record Node 105/experiment1/recording1/spikes/Spike_Detector-104.example_data/Stereotrode 3/clusters.npy new file mode 100644 index 0000000..60f6bea Binary files /dev/null and b/tests/data/v0.6.7_Binary/Record Node 105/experiment1/recording1/spikes/Spike_Detector-104.example_data/Stereotrode 3/clusters.npy differ diff --git a/tests/data/v0.6.7_Binary/Record Node 105/experiment1/recording1/spikes/Spike_Detector-104.example_data/Stereotrode 3/electrode_indices.npy b/tests/data/v0.6.7_Binary/Record Node 105/experiment1/recording1/spikes/Spike_Detector-104.example_data/Stereotrode 3/electrode_indices.npy new file mode 100644 index 0000000..7089ffd Binary files /dev/null and b/tests/data/v0.6.7_Binary/Record Node 105/experiment1/recording1/spikes/Spike_Detector-104.example_data/Stereotrode 3/electrode_indices.npy differ diff --git a/tests/data/v0.6.7_Binary/Record Node 105/experiment1/recording1/spikes/Spike_Detector-104.example_data/Stereotrode 3/sample_numbers.npy b/tests/data/v0.6.7_Binary/Record Node 105/experiment1/recording1/spikes/Spike_Detector-104.example_data/Stereotrode 3/sample_numbers.npy new file mode 100644 index 0000000..a28ae21 Binary files /dev/null and b/tests/data/v0.6.7_Binary/Record Node 105/experiment1/recording1/spikes/Spike_Detector-104.example_data/Stereotrode 3/sample_numbers.npy differ diff --git a/tests/data/v0.6.7_Binary/Record Node 105/experiment1/recording1/spikes/Spike_Detector-104.example_data/Stereotrode 3/timestamps.npy b/tests/data/v0.6.7_Binary/Record Node 105/experiment1/recording1/spikes/Spike_Detector-104.example_data/Stereotrode 3/timestamps.npy new file mode 100644 index 0000000..68f435f Binary files /dev/null and b/tests/data/v0.6.7_Binary/Record Node 105/experiment1/recording1/spikes/Spike_Detector-104.example_data/Stereotrode 3/timestamps.npy differ diff --git a/tests/data/v0.6.7_Binary/Record Node 105/experiment1/recording1/spikes/Spike_Detector-104.example_data/Stereotrode 3/waveforms.npy b/tests/data/v0.6.7_Binary/Record Node 105/experiment1/recording1/spikes/Spike_Detector-104.example_data/Stereotrode 3/waveforms.npy new file mode 100644 index 0000000..f2a084b Binary files /dev/null and b/tests/data/v0.6.7_Binary/Record Node 105/experiment1/recording1/spikes/Spike_Detector-104.example_data/Stereotrode 3/waveforms.npy differ diff --git a/tests/data/v0.6.7_Binary/Record Node 105/experiment1/recording1/spikes/Spike_Detector-104.example_data/Stereotrode 4/clusters.npy b/tests/data/v0.6.7_Binary/Record Node 105/experiment1/recording1/spikes/Spike_Detector-104.example_data/Stereotrode 4/clusters.npy new file mode 100644 index 0000000..25e58ff Binary files /dev/null and b/tests/data/v0.6.7_Binary/Record Node 105/experiment1/recording1/spikes/Spike_Detector-104.example_data/Stereotrode 4/clusters.npy differ diff --git a/tests/data/v0.6.7_Binary/Record Node 105/experiment1/recording1/spikes/Spike_Detector-104.example_data/Stereotrode 4/electrode_indices.npy b/tests/data/v0.6.7_Binary/Record Node 105/experiment1/recording1/spikes/Spike_Detector-104.example_data/Stereotrode 4/electrode_indices.npy new file mode 100644 index 0000000..f1da019 Binary files /dev/null and b/tests/data/v0.6.7_Binary/Record Node 105/experiment1/recording1/spikes/Spike_Detector-104.example_data/Stereotrode 4/electrode_indices.npy differ diff --git a/tests/data/v0.6.7_Binary/Record Node 105/experiment1/recording1/spikes/Spike_Detector-104.example_data/Stereotrode 4/sample_numbers.npy b/tests/data/v0.6.7_Binary/Record Node 105/experiment1/recording1/spikes/Spike_Detector-104.example_data/Stereotrode 4/sample_numbers.npy new file mode 100644 index 0000000..8f11c5f Binary files /dev/null and b/tests/data/v0.6.7_Binary/Record Node 105/experiment1/recording1/spikes/Spike_Detector-104.example_data/Stereotrode 4/sample_numbers.npy differ diff --git a/tests/data/v0.6.7_Binary/Record Node 105/experiment1/recording1/spikes/Spike_Detector-104.example_data/Stereotrode 4/timestamps.npy b/tests/data/v0.6.7_Binary/Record Node 105/experiment1/recording1/spikes/Spike_Detector-104.example_data/Stereotrode 4/timestamps.npy new file mode 100644 index 0000000..bb71a24 Binary files /dev/null and b/tests/data/v0.6.7_Binary/Record Node 105/experiment1/recording1/spikes/Spike_Detector-104.example_data/Stereotrode 4/timestamps.npy differ diff --git a/tests/data/v0.6.7_Binary/Record Node 105/experiment1/recording1/spikes/Spike_Detector-104.example_data/Stereotrode 4/waveforms.npy b/tests/data/v0.6.7_Binary/Record Node 105/experiment1/recording1/spikes/Spike_Detector-104.example_data/Stereotrode 4/waveforms.npy new file mode 100644 index 0000000..ea88faa Binary files /dev/null and b/tests/data/v0.6.7_Binary/Record Node 105/experiment1/recording1/spikes/Spike_Detector-104.example_data/Stereotrode 4/waveforms.npy differ diff --git a/tests/data/v0.6.7_Binary/Record Node 105/experiment1/recording1/spikes/Spike_Detector-104.example_data/Stereotrode 5/clusters.npy b/tests/data/v0.6.7_Binary/Record Node 105/experiment1/recording1/spikes/Spike_Detector-104.example_data/Stereotrode 5/clusters.npy new file mode 100644 index 0000000..11cf748 Binary files /dev/null and b/tests/data/v0.6.7_Binary/Record Node 105/experiment1/recording1/spikes/Spike_Detector-104.example_data/Stereotrode 5/clusters.npy differ diff --git a/tests/data/v0.6.7_Binary/Record Node 105/experiment1/recording1/spikes/Spike_Detector-104.example_data/Stereotrode 5/electrode_indices.npy b/tests/data/v0.6.7_Binary/Record Node 105/experiment1/recording1/spikes/Spike_Detector-104.example_data/Stereotrode 5/electrode_indices.npy new file mode 100644 index 0000000..32d5df3 Binary files /dev/null and b/tests/data/v0.6.7_Binary/Record Node 105/experiment1/recording1/spikes/Spike_Detector-104.example_data/Stereotrode 5/electrode_indices.npy differ diff --git a/tests/data/v0.6.7_Binary/Record Node 105/experiment1/recording1/spikes/Spike_Detector-104.example_data/Stereotrode 5/sample_numbers.npy b/tests/data/v0.6.7_Binary/Record Node 105/experiment1/recording1/spikes/Spike_Detector-104.example_data/Stereotrode 5/sample_numbers.npy new file mode 100644 index 0000000..ac9b0d5 Binary files /dev/null and b/tests/data/v0.6.7_Binary/Record Node 105/experiment1/recording1/spikes/Spike_Detector-104.example_data/Stereotrode 5/sample_numbers.npy differ diff --git a/tests/data/v0.6.7_Binary/Record Node 105/experiment1/recording1/spikes/Spike_Detector-104.example_data/Stereotrode 5/timestamps.npy b/tests/data/v0.6.7_Binary/Record Node 105/experiment1/recording1/spikes/Spike_Detector-104.example_data/Stereotrode 5/timestamps.npy new file mode 100644 index 0000000..50dc4da Binary files /dev/null and b/tests/data/v0.6.7_Binary/Record Node 105/experiment1/recording1/spikes/Spike_Detector-104.example_data/Stereotrode 5/timestamps.npy differ diff --git a/tests/data/v0.6.7_Binary/Record Node 105/experiment1/recording1/spikes/Spike_Detector-104.example_data/Stereotrode 5/waveforms.npy b/tests/data/v0.6.7_Binary/Record Node 105/experiment1/recording1/spikes/Spike_Detector-104.example_data/Stereotrode 5/waveforms.npy new file mode 100644 index 0000000..e42c519 Binary files /dev/null and b/tests/data/v0.6.7_Binary/Record Node 105/experiment1/recording1/spikes/Spike_Detector-104.example_data/Stereotrode 5/waveforms.npy differ diff --git a/tests/data/v0.6.7_Binary/Record Node 105/experiment1/recording1/spikes/Spike_Detector-104.example_data/Stereotrode 6/clusters.npy b/tests/data/v0.6.7_Binary/Record Node 105/experiment1/recording1/spikes/Spike_Detector-104.example_data/Stereotrode 6/clusters.npy new file mode 100644 index 0000000..2931fc5 Binary files /dev/null and b/tests/data/v0.6.7_Binary/Record Node 105/experiment1/recording1/spikes/Spike_Detector-104.example_data/Stereotrode 6/clusters.npy differ diff --git a/tests/data/v0.6.7_Binary/Record Node 105/experiment1/recording1/spikes/Spike_Detector-104.example_data/Stereotrode 6/electrode_indices.npy b/tests/data/v0.6.7_Binary/Record Node 105/experiment1/recording1/spikes/Spike_Detector-104.example_data/Stereotrode 6/electrode_indices.npy new file mode 100644 index 0000000..a6222fc Binary files /dev/null and b/tests/data/v0.6.7_Binary/Record Node 105/experiment1/recording1/spikes/Spike_Detector-104.example_data/Stereotrode 6/electrode_indices.npy differ diff --git a/tests/data/v0.6.7_Binary/Record Node 105/experiment1/recording1/spikes/Spike_Detector-104.example_data/Stereotrode 6/sample_numbers.npy b/tests/data/v0.6.7_Binary/Record Node 105/experiment1/recording1/spikes/Spike_Detector-104.example_data/Stereotrode 6/sample_numbers.npy new file mode 100644 index 0000000..5352c13 Binary files /dev/null and b/tests/data/v0.6.7_Binary/Record Node 105/experiment1/recording1/spikes/Spike_Detector-104.example_data/Stereotrode 6/sample_numbers.npy differ diff --git a/tests/data/v0.6.7_Binary/Record Node 105/experiment1/recording1/spikes/Spike_Detector-104.example_data/Stereotrode 6/timestamps.npy b/tests/data/v0.6.7_Binary/Record Node 105/experiment1/recording1/spikes/Spike_Detector-104.example_data/Stereotrode 6/timestamps.npy new file mode 100644 index 0000000..8b8dea0 Binary files /dev/null and b/tests/data/v0.6.7_Binary/Record Node 105/experiment1/recording1/spikes/Spike_Detector-104.example_data/Stereotrode 6/timestamps.npy differ diff --git a/tests/data/v0.6.7_Binary/Record Node 105/experiment1/recording1/spikes/Spike_Detector-104.example_data/Stereotrode 6/waveforms.npy b/tests/data/v0.6.7_Binary/Record Node 105/experiment1/recording1/spikes/Spike_Detector-104.example_data/Stereotrode 6/waveforms.npy new file mode 100644 index 0000000..987425f Binary files /dev/null and b/tests/data/v0.6.7_Binary/Record Node 105/experiment1/recording1/spikes/Spike_Detector-104.example_data/Stereotrode 6/waveforms.npy differ diff --git a/tests/data/v0.6.7_Binary/Record Node 105/experiment1/recording1/spikes/Spike_Detector-104.example_data/Stereotrode 7/clusters.npy b/tests/data/v0.6.7_Binary/Record Node 105/experiment1/recording1/spikes/Spike_Detector-104.example_data/Stereotrode 7/clusters.npy new file mode 100644 index 0000000..4e917fa Binary files /dev/null and b/tests/data/v0.6.7_Binary/Record Node 105/experiment1/recording1/spikes/Spike_Detector-104.example_data/Stereotrode 7/clusters.npy differ diff --git a/tests/data/v0.6.7_Binary/Record Node 105/experiment1/recording1/spikes/Spike_Detector-104.example_data/Stereotrode 7/electrode_indices.npy b/tests/data/v0.6.7_Binary/Record Node 105/experiment1/recording1/spikes/Spike_Detector-104.example_data/Stereotrode 7/electrode_indices.npy new file mode 100644 index 0000000..ee48bcb Binary files /dev/null and b/tests/data/v0.6.7_Binary/Record Node 105/experiment1/recording1/spikes/Spike_Detector-104.example_data/Stereotrode 7/electrode_indices.npy differ diff --git a/tests/data/v0.6.7_Binary/Record Node 105/experiment1/recording1/spikes/Spike_Detector-104.example_data/Stereotrode 7/sample_numbers.npy b/tests/data/v0.6.7_Binary/Record Node 105/experiment1/recording1/spikes/Spike_Detector-104.example_data/Stereotrode 7/sample_numbers.npy new file mode 100644 index 0000000..82acdbd Binary files /dev/null and b/tests/data/v0.6.7_Binary/Record Node 105/experiment1/recording1/spikes/Spike_Detector-104.example_data/Stereotrode 7/sample_numbers.npy differ diff --git a/tests/data/v0.6.7_Binary/Record Node 105/experiment1/recording1/spikes/Spike_Detector-104.example_data/Stereotrode 7/timestamps.npy b/tests/data/v0.6.7_Binary/Record Node 105/experiment1/recording1/spikes/Spike_Detector-104.example_data/Stereotrode 7/timestamps.npy new file mode 100644 index 0000000..0b072d6 Binary files /dev/null and b/tests/data/v0.6.7_Binary/Record Node 105/experiment1/recording1/spikes/Spike_Detector-104.example_data/Stereotrode 7/timestamps.npy differ diff --git a/tests/data/v0.6.7_Binary/Record Node 105/experiment1/recording1/spikes/Spike_Detector-104.example_data/Stereotrode 7/waveforms.npy b/tests/data/v0.6.7_Binary/Record Node 105/experiment1/recording1/spikes/Spike_Detector-104.example_data/Stereotrode 7/waveforms.npy new file mode 100644 index 0000000..5bc3cc8 Binary files /dev/null and b/tests/data/v0.6.7_Binary/Record Node 105/experiment1/recording1/spikes/Spike_Detector-104.example_data/Stereotrode 7/waveforms.npy differ diff --git a/tests/data/v0.6.7_Binary/Record Node 105/experiment1/recording1/spikes/Spike_Detector-104.example_data/Stereotrode 8/clusters.npy b/tests/data/v0.6.7_Binary/Record Node 105/experiment1/recording1/spikes/Spike_Detector-104.example_data/Stereotrode 8/clusters.npy new file mode 100644 index 0000000..d0a7c61 Binary files /dev/null and b/tests/data/v0.6.7_Binary/Record Node 105/experiment1/recording1/spikes/Spike_Detector-104.example_data/Stereotrode 8/clusters.npy differ diff --git a/tests/data/v0.6.7_Binary/Record Node 105/experiment1/recording1/spikes/Spike_Detector-104.example_data/Stereotrode 8/electrode_indices.npy b/tests/data/v0.6.7_Binary/Record Node 105/experiment1/recording1/spikes/Spike_Detector-104.example_data/Stereotrode 8/electrode_indices.npy new file mode 100644 index 0000000..2c4c824 Binary files /dev/null and b/tests/data/v0.6.7_Binary/Record Node 105/experiment1/recording1/spikes/Spike_Detector-104.example_data/Stereotrode 8/electrode_indices.npy differ diff --git a/tests/data/v0.6.7_Binary/Record Node 105/experiment1/recording1/spikes/Spike_Detector-104.example_data/Stereotrode 8/sample_numbers.npy b/tests/data/v0.6.7_Binary/Record Node 105/experiment1/recording1/spikes/Spike_Detector-104.example_data/Stereotrode 8/sample_numbers.npy new file mode 100644 index 0000000..95597a0 Binary files /dev/null and b/tests/data/v0.6.7_Binary/Record Node 105/experiment1/recording1/spikes/Spike_Detector-104.example_data/Stereotrode 8/sample_numbers.npy differ diff --git a/tests/data/v0.6.7_Binary/Record Node 105/experiment1/recording1/spikes/Spike_Detector-104.example_data/Stereotrode 8/timestamps.npy b/tests/data/v0.6.7_Binary/Record Node 105/experiment1/recording1/spikes/Spike_Detector-104.example_data/Stereotrode 8/timestamps.npy new file mode 100644 index 0000000..7cabca6 Binary files /dev/null and b/tests/data/v0.6.7_Binary/Record Node 105/experiment1/recording1/spikes/Spike_Detector-104.example_data/Stereotrode 8/timestamps.npy differ diff --git a/tests/data/v0.6.7_Binary/Record Node 105/experiment1/recording1/spikes/Spike_Detector-104.example_data/Stereotrode 8/waveforms.npy b/tests/data/v0.6.7_Binary/Record Node 105/experiment1/recording1/spikes/Spike_Detector-104.example_data/Stereotrode 8/waveforms.npy new file mode 100644 index 0000000..22b569a Binary files /dev/null and b/tests/data/v0.6.7_Binary/Record Node 105/experiment1/recording1/spikes/Spike_Detector-104.example_data/Stereotrode 8/waveforms.npy differ diff --git a/tests/data/v0.6.7_Binary/Record Node 105/experiment1/recording1/structure.oebin b/tests/data/v0.6.7_Binary/Record Node 105/experiment1/recording1/structure.oebin new file mode 100644 index 0000000..37117d7 --- /dev/null +++ b/tests/data/v0.6.7_Binary/Record Node 105/experiment1/recording1/structure.oebin @@ -0,0 +1,373 @@ +{ + "GUI version": "0.6.7", + "continuous": [ + { + "folder_name": "File_Reader-100.example_data/", + "sample_rate": 40000.0, + "source_processor_name": "File Reader", + "source_processor_id": 100, + "stream_name": "example_data", + "recorded_processor": "Record Node", + "recorded_processor_id": 105, + "num_channels": 16, + "channels": [ + { + "channel_name": "CH1", + "description": "description", + "identifier": "", + "history": "File Reader -> Network Events -> Record Node -> LFP Viewer -> Bandpass Filter -> Spike Detector -> Record Node", + "bit_volts": 0.05000000074505806, + "units": "" + }, + { + "channel_name": "CH2", + "description": "description", + "identifier": "", + "history": "File Reader -> Network Events -> Record Node -> LFP Viewer -> Bandpass Filter -> Spike Detector -> Record Node", + "bit_volts": 0.05000000074505806, + "units": "" + }, + { + "channel_name": "CH3", + "description": "description", + "identifier": "", + "history": "File Reader -> Network Events -> Record Node -> LFP Viewer -> Bandpass Filter -> Spike Detector -> Record Node", + "bit_volts": 0.05000000074505806, + "units": "" + }, + { + "channel_name": "CH4", + "description": "description", + "identifier": "", + "history": "File Reader -> Network Events -> Record Node -> LFP Viewer -> Bandpass Filter -> Spike Detector -> Record Node", + "bit_volts": 0.05000000074505806, + "units": "" + }, + { + "channel_name": "CH5", + "description": "description", + "identifier": "", + "history": "File Reader -> Network Events -> Record Node -> LFP Viewer -> Bandpass Filter -> Spike Detector -> Record Node", + "bit_volts": 0.05000000074505806, + "units": "" + }, + { + "channel_name": "CH6", + "description": "description", + "identifier": "", + "history": "File Reader -> Network Events -> Record Node -> LFP Viewer -> Bandpass Filter -> Spike Detector -> Record Node", + "bit_volts": 0.05000000074505806, + "units": "" + }, + { + "channel_name": "CH7", + "description": "description", + "identifier": "", + "history": "File Reader -> Network Events -> Record Node -> LFP Viewer -> Bandpass Filter -> Spike Detector -> Record Node", + "bit_volts": 0.05000000074505806, + "units": "" + }, + { + "channel_name": "CH8", + "description": "description", + "identifier": "", + "history": "File Reader -> Network Events -> Record Node -> LFP Viewer -> Bandpass Filter -> Spike Detector -> Record Node", + "bit_volts": 0.05000000074505806, + "units": "" + }, + { + "channel_name": "CH9", + "description": "description", + "identifier": "", + "history": "File Reader -> Network Events -> Record Node -> LFP Viewer -> Bandpass Filter -> Spike Detector -> Record Node", + "bit_volts": 0.05000000074505806, + "units": "" + }, + { + "channel_name": "CH10", + "description": "description", + "identifier": "", + "history": "File Reader -> Network Events -> Record Node -> LFP Viewer -> Bandpass Filter -> Spike Detector -> Record Node", + "bit_volts": 0.05000000074505806, + "units": "" + }, + { + "channel_name": "CH11", + "description": "description", + "identifier": "", + "history": "File Reader -> Network Events -> Record Node -> LFP Viewer -> Bandpass Filter -> Spike Detector -> Record Node", + "bit_volts": 0.05000000074505806, + "units": "" + }, + { + "channel_name": "CH12", + "description": "description", + "identifier": "", + "history": "File Reader -> Network Events -> Record Node -> LFP Viewer -> Bandpass Filter -> Spike Detector -> Record Node", + "bit_volts": 0.05000000074505806, + "units": "" + }, + { + "channel_name": "CH13", + "description": "description", + "identifier": "", + "history": "File Reader -> Network Events -> Record Node -> LFP Viewer -> Bandpass Filter -> Spike Detector -> Record Node", + "bit_volts": 0.05000000074505806, + "units": "" + }, + { + "channel_name": "CH14", + "description": "description", + "identifier": "", + "history": "File Reader -> Network Events -> Record Node -> LFP Viewer -> Bandpass Filter -> Spike Detector -> Record Node", + "bit_volts": 0.05000000074505806, + "units": "" + }, + { + "channel_name": "CH15", + "description": "description", + "identifier": "", + "history": "File Reader -> Network Events -> Record Node -> LFP Viewer -> Bandpass Filter -> Spike Detector -> Record Node", + "bit_volts": 0.05000000074505806, + "units": "" + }, + { + "channel_name": "CH16", + "description": "description", + "identifier": "", + "history": "File Reader -> Network Events -> Record Node -> LFP Viewer -> Bandpass Filter -> Spike Detector -> Record Node", + "bit_volts": 0.05000000074505806, + "units": "" + } + ] + } + ], + "events": [ + { + "folder_name": "File_Reader-100.example_data/TTL/", + "channel_name": "All TTL events", + "description": "All TTL events loaded for the current input data source", + "identifier": "sourceevent", + "sample_rate": 40000.0, + "type": "int16", + "source_processor": "File Reader", + "stream_name": "example_data", + "initial_state": 0 + }, + { + "folder_name": "Network_Events-108.example_data/TTL/", + "channel_name": "Network Events output", + "description": "Triggers whenever \"TTL\" is received on the port.", + "identifier": "external.network.ttl", + "sample_rate": 40000.0, + "type": "int16", + "source_processor": "Network Events", + "stream_name": "example_data", + "initial_state": 0 + }, + { + "folder_name": "MessageCenter/", + "channel_name": "Messages", + "description": "Broadcasts messages from the MessageCenter", + "identifier": "messagecenter.events", + "sample_rate": 40000.0, + "type": "string", + "source_processor": "Message Center", + "stream_name": "example_data" + } + ], + "spikes": [ + { + "name": "Stereotrode 1", + "description": "Stereotrode from Spike Detector 104", + "identifier": "100|example_data|104|Stereotrode 1", + "source_processor_id": 104, + "stream_name": "example_data", + "sample_rate": 40000.0, + "num_channels": 2, + "pre_peak_samples": 8, + "post_peak_samples": 32, + "folder": "Spike_Detector-104.example_data/Stereotrode 1/", + "source_channels": [ + { + "name": "CH1", + "local_index": 0, + "bit_volts": 0.05000000074505806 + }, + { + "name": "CH2", + "local_index": 1, + "bit_volts": 0.05000000074505806 + } + ] + }, + { + "name": "Stereotrode 2", + "description": "Stereotrode from Spike Detector 104", + "identifier": "100|example_data|104|Stereotrode 2", + "source_processor_id": 104, + "stream_name": "example_data", + "sample_rate": 40000.0, + "num_channels": 2, + "pre_peak_samples": 8, + "post_peak_samples": 32, + "folder": "Spike_Detector-104.example_data/Stereotrode 2/", + "source_channels": [ + { + "name": "CH3", + "local_index": 2, + "bit_volts": 0.05000000074505806 + }, + { + "name": "CH4", + "local_index": 3, + "bit_volts": 0.05000000074505806 + } + ] + }, + { + "name": "Stereotrode 3", + "description": "Stereotrode from Spike Detector 104", + "identifier": "100|example_data|104|Stereotrode 3", + "source_processor_id": 104, + "stream_name": "example_data", + "sample_rate": 40000.0, + "num_channels": 2, + "pre_peak_samples": 8, + "post_peak_samples": 32, + "folder": "Spike_Detector-104.example_data/Stereotrode 3/", + "source_channels": [ + { + "name": "CH5", + "local_index": 4, + "bit_volts": 0.05000000074505806 + }, + { + "name": "CH6", + "local_index": 5, + "bit_volts": 0.05000000074505806 + } + ] + }, + { + "name": "Stereotrode 4", + "description": "Stereotrode from Spike Detector 104", + "identifier": "100|example_data|104|Stereotrode 4", + "source_processor_id": 104, + "stream_name": "example_data", + "sample_rate": 40000.0, + "num_channels": 2, + "pre_peak_samples": 8, + "post_peak_samples": 32, + "folder": "Spike_Detector-104.example_data/Stereotrode 4/", + "source_channels": [ + { + "name": "CH7", + "local_index": 6, + "bit_volts": 0.05000000074505806 + }, + { + "name": "CH8", + "local_index": 7, + "bit_volts": 0.05000000074505806 + } + ] + }, + { + "name": "Stereotrode 5", + "description": "Stereotrode from Spike Detector 104", + "identifier": "100|example_data|104|Stereotrode 5", + "source_processor_id": 104, + "stream_name": "example_data", + "sample_rate": 40000.0, + "num_channels": 2, + "pre_peak_samples": 8, + "post_peak_samples": 32, + "folder": "Spike_Detector-104.example_data/Stereotrode 5/", + "source_channels": [ + { + "name": "CH9", + "local_index": 8, + "bit_volts": 0.05000000074505806 + }, + { + "name": "CH10", + "local_index": 9, + "bit_volts": 0.05000000074505806 + } + ] + }, + { + "name": "Stereotrode 6", + "description": "Stereotrode from Spike Detector 104", + "identifier": "100|example_data|104|Stereotrode 6", + "source_processor_id": 104, + "stream_name": "example_data", + "sample_rate": 40000.0, + "num_channels": 2, + "pre_peak_samples": 8, + "post_peak_samples": 32, + "folder": "Spike_Detector-104.example_data/Stereotrode 6/", + "source_channels": [ + { + "name": "CH11", + "local_index": 10, + "bit_volts": 0.05000000074505806 + }, + { + "name": "CH12", + "local_index": 11, + "bit_volts": 0.05000000074505806 + } + ] + }, + { + "name": "Stereotrode 7", + "description": "Stereotrode from Spike Detector 104", + "identifier": "100|example_data|104|Stereotrode 7", + "source_processor_id": 104, + "stream_name": "example_data", + "sample_rate": 40000.0, + "num_channels": 2, + "pre_peak_samples": 8, + "post_peak_samples": 32, + "folder": "Spike_Detector-104.example_data/Stereotrode 7/", + "source_channels": [ + { + "name": "CH13", + "local_index": 12, + "bit_volts": 0.05000000074505806 + }, + { + "name": "CH14", + "local_index": 13, + "bit_volts": 0.05000000074505806 + } + ] + }, + { + "name": "Stereotrode 8", + "description": "Stereotrode from Spike Detector 104", + "identifier": "100|example_data|104|Stereotrode 8", + "source_processor_id": 104, + "stream_name": "example_data", + "sample_rate": 40000.0, + "num_channels": 2, + "pre_peak_samples": 8, + "post_peak_samples": 32, + "folder": "Spike_Detector-104.example_data/Stereotrode 8/", + "source_channels": [ + { + "name": "CH15", + "local_index": 14, + "bit_volts": 0.05000000074505806 + }, + { + "name": "CH16", + "local_index": 15, + "bit_volts": 0.05000000074505806 + } + ] + } + ] + } \ No newline at end of file diff --git a/tests/data/v0.6.7_Binary/Record Node 105/experiment1/recording1/sync_messages.txt b/tests/data/v0.6.7_Binary/Record Node 105/experiment1/recording1/sync_messages.txt new file mode 100644 index 0000000..9b22eb7 --- /dev/null +++ b/tests/data/v0.6.7_Binary/Record Node 105/experiment1/recording1/sync_messages.txt @@ -0,0 +1,2 @@ +Software Time (milliseconds since midnight Jan 1st 1970 UTC): 1743680304612 +Start Time for File Reader (100) - example_data @ 40000 Hz: 40091 diff --git a/tests/data/v0.6.7_Binary/Record Node 105/settings.xml b/tests/data/v0.6.7_Binary/Record Node 105/settings.xml new file mode 100644 index 0000000..1f47a17 --- /dev/null +++ b/tests/data/v0.6.7_Binary/Record Node 105/settings.xml @@ -0,0 +1,282 @@ + + + + + 0.6.7 + 8 + 3 Apr 2025 13:38:24 + Windows 10 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + diff --git a/tests/data/v0.6.7_NWB/Record Node 105/experiment1.nwb b/tests/data/v0.6.7_NWB/Record Node 105/experiment1.nwb new file mode 100644 index 0000000..01f9b86 Binary files /dev/null and b/tests/data/v0.6.7_NWB/Record Node 105/experiment1.nwb differ diff --git a/tests/data/v0.6.7_NWB/Record Node 105/settings.xml b/tests/data/v0.6.7_NWB/Record Node 105/settings.xml new file mode 100644 index 0000000..018bc3f --- /dev/null +++ b/tests/data/v0.6.7_NWB/Record Node 105/settings.xml @@ -0,0 +1,266 @@ + + + + + 0.6.7 + 8 + 7 Apr 2025 11:19:47 + Windows 10 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + diff --git a/tests/data/v0.6.7_OpenEphys/Record Node 101/100_example-data.events b/tests/data/v0.6.7_OpenEphys/Record Node 101/100_example-data.events new file mode 100644 index 0000000..ec06d2e Binary files /dev/null and b/tests/data/v0.6.7_OpenEphys/Record Node 101/100_example-data.events differ diff --git a/tests/data/v0.6.7_OpenEphys/Record Node 101/100_example-data.timestamps b/tests/data/v0.6.7_OpenEphys/Record Node 101/100_example-data.timestamps new file mode 100644 index 0000000..ffc7ac3 Binary files /dev/null and b/tests/data/v0.6.7_OpenEphys/Record Node 101/100_example-data.timestamps differ diff --git a/tests/data/v0.6.7_OpenEphys/Record Node 101/100_example-data_CH1.continuous b/tests/data/v0.6.7_OpenEphys/Record Node 101/100_example-data_CH1.continuous new file mode 100644 index 0000000..793c525 Binary files /dev/null and b/tests/data/v0.6.7_OpenEphys/Record Node 101/100_example-data_CH1.continuous differ diff --git a/tests/data/v0.6.7_OpenEphys/Record Node 101/100_example-data_CH10.continuous b/tests/data/v0.6.7_OpenEphys/Record Node 101/100_example-data_CH10.continuous new file mode 100644 index 0000000..767691d Binary files /dev/null and b/tests/data/v0.6.7_OpenEphys/Record Node 101/100_example-data_CH10.continuous differ diff --git a/tests/data/v0.6.7_OpenEphys/Record Node 101/100_example-data_CH11.continuous b/tests/data/v0.6.7_OpenEphys/Record Node 101/100_example-data_CH11.continuous new file mode 100644 index 0000000..ceab03b Binary files /dev/null and b/tests/data/v0.6.7_OpenEphys/Record Node 101/100_example-data_CH11.continuous differ diff --git a/tests/data/v0.6.7_OpenEphys/Record Node 101/100_example-data_CH12.continuous b/tests/data/v0.6.7_OpenEphys/Record Node 101/100_example-data_CH12.continuous new file mode 100644 index 0000000..8221e40 Binary files /dev/null and b/tests/data/v0.6.7_OpenEphys/Record Node 101/100_example-data_CH12.continuous differ diff --git a/tests/data/v0.6.7_OpenEphys/Record Node 101/100_example-data_CH13.continuous b/tests/data/v0.6.7_OpenEphys/Record Node 101/100_example-data_CH13.continuous new file mode 100644 index 0000000..d8be54a Binary files /dev/null and b/tests/data/v0.6.7_OpenEphys/Record Node 101/100_example-data_CH13.continuous differ diff --git a/tests/data/v0.6.7_OpenEphys/Record Node 101/100_example-data_CH14.continuous b/tests/data/v0.6.7_OpenEphys/Record Node 101/100_example-data_CH14.continuous new file mode 100644 index 0000000..094ec57 Binary files /dev/null and b/tests/data/v0.6.7_OpenEphys/Record Node 101/100_example-data_CH14.continuous differ diff --git a/tests/data/v0.6.7_OpenEphys/Record Node 101/100_example-data_CH15.continuous b/tests/data/v0.6.7_OpenEphys/Record Node 101/100_example-data_CH15.continuous new file mode 100644 index 0000000..590b487 Binary files /dev/null and b/tests/data/v0.6.7_OpenEphys/Record Node 101/100_example-data_CH15.continuous differ diff --git a/tests/data/v0.6.7_OpenEphys/Record Node 101/100_example-data_CH16.continuous b/tests/data/v0.6.7_OpenEphys/Record Node 101/100_example-data_CH16.continuous new file mode 100644 index 0000000..481e50e Binary files /dev/null and b/tests/data/v0.6.7_OpenEphys/Record Node 101/100_example-data_CH16.continuous differ diff --git a/tests/data/v0.6.7_OpenEphys/Record Node 101/100_example-data_CH2.continuous b/tests/data/v0.6.7_OpenEphys/Record Node 101/100_example-data_CH2.continuous new file mode 100644 index 0000000..a6172ea Binary files /dev/null and b/tests/data/v0.6.7_OpenEphys/Record Node 101/100_example-data_CH2.continuous differ diff --git a/tests/data/v0.6.7_OpenEphys/Record Node 101/100_example-data_CH3.continuous b/tests/data/v0.6.7_OpenEphys/Record Node 101/100_example-data_CH3.continuous new file mode 100644 index 0000000..05c747c Binary files /dev/null and b/tests/data/v0.6.7_OpenEphys/Record Node 101/100_example-data_CH3.continuous differ diff --git a/tests/data/v0.6.7_OpenEphys/Record Node 101/100_example-data_CH4.continuous b/tests/data/v0.6.7_OpenEphys/Record Node 101/100_example-data_CH4.continuous new file mode 100644 index 0000000..a864564 Binary files /dev/null and b/tests/data/v0.6.7_OpenEphys/Record Node 101/100_example-data_CH4.continuous differ diff --git a/tests/data/v0.6.7_OpenEphys/Record Node 101/100_example-data_CH5.continuous b/tests/data/v0.6.7_OpenEphys/Record Node 101/100_example-data_CH5.continuous new file mode 100644 index 0000000..b684cad Binary files /dev/null and b/tests/data/v0.6.7_OpenEphys/Record Node 101/100_example-data_CH5.continuous differ diff --git a/tests/data/v0.6.7_OpenEphys/Record Node 101/100_example-data_CH6.continuous b/tests/data/v0.6.7_OpenEphys/Record Node 101/100_example-data_CH6.continuous new file mode 100644 index 0000000..90108a8 Binary files /dev/null and b/tests/data/v0.6.7_OpenEphys/Record Node 101/100_example-data_CH6.continuous differ diff --git a/tests/data/v0.6.7_OpenEphys/Record Node 101/100_example-data_CH7.continuous b/tests/data/v0.6.7_OpenEphys/Record Node 101/100_example-data_CH7.continuous new file mode 100644 index 0000000..c2f5458 Binary files /dev/null and b/tests/data/v0.6.7_OpenEphys/Record Node 101/100_example-data_CH7.continuous differ diff --git a/tests/data/v0.6.7_OpenEphys/Record Node 101/100_example-data_CH8.continuous b/tests/data/v0.6.7_OpenEphys/Record Node 101/100_example-data_CH8.continuous new file mode 100644 index 0000000..96c6e9f Binary files /dev/null and b/tests/data/v0.6.7_OpenEphys/Record Node 101/100_example-data_CH8.continuous differ diff --git a/tests/data/v0.6.7_OpenEphys/Record Node 101/100_example-data_CH9.continuous b/tests/data/v0.6.7_OpenEphys/Record Node 101/100_example-data_CH9.continuous new file mode 100644 index 0000000..6c5f63a Binary files /dev/null and b/tests/data/v0.6.7_OpenEphys/Record Node 101/100_example-data_CH9.continuous differ diff --git a/tests/data/v0.6.7_OpenEphys/Record Node 101/messages.events b/tests/data/v0.6.7_OpenEphys/Record Node 101/messages.events new file mode 100644 index 0000000..6f27f81 --- /dev/null +++ b/tests/data/v0.6.7_OpenEphys/Record Node 101/messages.events @@ -0,0 +1,17 @@ +1743680325031, Software Time (milliseconds since midnight Jan 1st 1970 UTC) +251635, Start Time for File Reader (100) - example_data @ 40000 Hz +251635, TTL Line=1 State=0 +252488, TTL Line=3 State=0 +253341, TTL Line=8 State=0 +254194, TTL Line=13 State=0 +255047, TTL Line=18 State=0 +255900, TTL Line=25 State=1 +256753, TTL Line=27 State=0 +257606, TTL Line=32 State=0 +258459, TTL Line=40 State=0 +259312, TTL Line=45 State=0 +260165, TTL Line=48 State=1 +261018, TTL Line=51 State=0 +261871, TTL Line=57 State=1 +262724, TTL Line=62 State=0 +263577, TTL Line=64 State=0 diff --git a/tests/data/v0.6.7_OpenEphys/Record Node 101/settings.xml b/tests/data/v0.6.7_OpenEphys/Record Node 101/settings.xml new file mode 100644 index 0000000..043d5fb --- /dev/null +++ b/tests/data/v0.6.7_OpenEphys/Record Node 101/settings.xml @@ -0,0 +1,282 @@ + + + + + 0.6.7 + 8 + 3 Apr 2025 13:38:45 + Windows 10 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + diff --git a/tests/data/v0.6.7_OpenEphys/Record Node 101/structure.openephys b/tests/data/v0.6.7_OpenEphys/Record Node 101/structure.openephys new file mode 100644 index 0000000..31411db --- /dev/null +++ b/tests/data/v0.6.7_OpenEphys/Record Node 101/structure.openephys @@ -0,0 +1,43 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/tests/data/v0.6.7_OpenEphys/Record Node 105/100_example-data.events b/tests/data/v0.6.7_OpenEphys/Record Node 105/100_example-data.events new file mode 100644 index 0000000..ec06d2e Binary files /dev/null and b/tests/data/v0.6.7_OpenEphys/Record Node 105/100_example-data.events differ diff --git a/tests/data/v0.6.7_OpenEphys/Record Node 105/100_example-data.timestamps b/tests/data/v0.6.7_OpenEphys/Record Node 105/100_example-data.timestamps new file mode 100644 index 0000000..ffc7ac3 Binary files /dev/null and b/tests/data/v0.6.7_OpenEphys/Record Node 105/100_example-data.timestamps differ diff --git a/tests/data/v0.6.7_OpenEphys/Record Node 105/100_example-data_CH1.continuous b/tests/data/v0.6.7_OpenEphys/Record Node 105/100_example-data_CH1.continuous new file mode 100644 index 0000000..23218f6 Binary files /dev/null and b/tests/data/v0.6.7_OpenEphys/Record Node 105/100_example-data_CH1.continuous differ diff --git a/tests/data/v0.6.7_OpenEphys/Record Node 105/100_example-data_CH10.continuous b/tests/data/v0.6.7_OpenEphys/Record Node 105/100_example-data_CH10.continuous new file mode 100644 index 0000000..7b4224f Binary files /dev/null and b/tests/data/v0.6.7_OpenEphys/Record Node 105/100_example-data_CH10.continuous differ diff --git a/tests/data/v0.6.7_OpenEphys/Record Node 105/100_example-data_CH11.continuous b/tests/data/v0.6.7_OpenEphys/Record Node 105/100_example-data_CH11.continuous new file mode 100644 index 0000000..b2d5be1 Binary files /dev/null and b/tests/data/v0.6.7_OpenEphys/Record Node 105/100_example-data_CH11.continuous differ diff --git a/tests/data/v0.6.7_OpenEphys/Record Node 105/100_example-data_CH12.continuous b/tests/data/v0.6.7_OpenEphys/Record Node 105/100_example-data_CH12.continuous new file mode 100644 index 0000000..b63bbea Binary files /dev/null and b/tests/data/v0.6.7_OpenEphys/Record Node 105/100_example-data_CH12.continuous differ diff --git a/tests/data/v0.6.7_OpenEphys/Record Node 105/100_example-data_CH13.continuous b/tests/data/v0.6.7_OpenEphys/Record Node 105/100_example-data_CH13.continuous new file mode 100644 index 0000000..6696323 Binary files /dev/null and b/tests/data/v0.6.7_OpenEphys/Record Node 105/100_example-data_CH13.continuous differ diff --git a/tests/data/v0.6.7_OpenEphys/Record Node 105/100_example-data_CH14.continuous b/tests/data/v0.6.7_OpenEphys/Record Node 105/100_example-data_CH14.continuous new file mode 100644 index 0000000..88db712 Binary files /dev/null and b/tests/data/v0.6.7_OpenEphys/Record Node 105/100_example-data_CH14.continuous differ diff --git a/tests/data/v0.6.7_OpenEphys/Record Node 105/100_example-data_CH15.continuous b/tests/data/v0.6.7_OpenEphys/Record Node 105/100_example-data_CH15.continuous new file mode 100644 index 0000000..1fd34b7 Binary files /dev/null and b/tests/data/v0.6.7_OpenEphys/Record Node 105/100_example-data_CH15.continuous differ diff --git a/tests/data/v0.6.7_OpenEphys/Record Node 105/100_example-data_CH16.continuous b/tests/data/v0.6.7_OpenEphys/Record Node 105/100_example-data_CH16.continuous new file mode 100644 index 0000000..b81294b Binary files /dev/null and b/tests/data/v0.6.7_OpenEphys/Record Node 105/100_example-data_CH16.continuous differ diff --git a/tests/data/v0.6.7_OpenEphys/Record Node 105/100_example-data_CH2.continuous b/tests/data/v0.6.7_OpenEphys/Record Node 105/100_example-data_CH2.continuous new file mode 100644 index 0000000..9a39dbf Binary files /dev/null and b/tests/data/v0.6.7_OpenEphys/Record Node 105/100_example-data_CH2.continuous differ diff --git a/tests/data/v0.6.7_OpenEphys/Record Node 105/100_example-data_CH3.continuous b/tests/data/v0.6.7_OpenEphys/Record Node 105/100_example-data_CH3.continuous new file mode 100644 index 0000000..a20c7cf Binary files /dev/null and b/tests/data/v0.6.7_OpenEphys/Record Node 105/100_example-data_CH3.continuous differ diff --git a/tests/data/v0.6.7_OpenEphys/Record Node 105/100_example-data_CH4.continuous b/tests/data/v0.6.7_OpenEphys/Record Node 105/100_example-data_CH4.continuous new file mode 100644 index 0000000..d374245 Binary files /dev/null and b/tests/data/v0.6.7_OpenEphys/Record Node 105/100_example-data_CH4.continuous differ diff --git a/tests/data/v0.6.7_OpenEphys/Record Node 105/100_example-data_CH5.continuous b/tests/data/v0.6.7_OpenEphys/Record Node 105/100_example-data_CH5.continuous new file mode 100644 index 0000000..1f893fa Binary files /dev/null and b/tests/data/v0.6.7_OpenEphys/Record Node 105/100_example-data_CH5.continuous differ diff --git a/tests/data/v0.6.7_OpenEphys/Record Node 105/100_example-data_CH6.continuous b/tests/data/v0.6.7_OpenEphys/Record Node 105/100_example-data_CH6.continuous new file mode 100644 index 0000000..ffa76ab Binary files /dev/null and b/tests/data/v0.6.7_OpenEphys/Record Node 105/100_example-data_CH6.continuous differ diff --git a/tests/data/v0.6.7_OpenEphys/Record Node 105/100_example-data_CH7.continuous b/tests/data/v0.6.7_OpenEphys/Record Node 105/100_example-data_CH7.continuous new file mode 100644 index 0000000..fed9c73 Binary files /dev/null and b/tests/data/v0.6.7_OpenEphys/Record Node 105/100_example-data_CH7.continuous differ diff --git a/tests/data/v0.6.7_OpenEphys/Record Node 105/100_example-data_CH8.continuous b/tests/data/v0.6.7_OpenEphys/Record Node 105/100_example-data_CH8.continuous new file mode 100644 index 0000000..908b2de Binary files /dev/null and b/tests/data/v0.6.7_OpenEphys/Record Node 105/100_example-data_CH8.continuous differ diff --git a/tests/data/v0.6.7_OpenEphys/Record Node 105/100_example-data_CH9.continuous b/tests/data/v0.6.7_OpenEphys/Record Node 105/100_example-data_CH9.continuous new file mode 100644 index 0000000..c876d9d Binary files /dev/null and b/tests/data/v0.6.7_OpenEphys/Record Node 105/100_example-data_CH9.continuous differ diff --git a/tests/data/v0.6.7_OpenEphys/Record Node 105/Stereotrode1_example-data.spikes b/tests/data/v0.6.7_OpenEphys/Record Node 105/Stereotrode1_example-data.spikes new file mode 100644 index 0000000..983295a Binary files /dev/null and b/tests/data/v0.6.7_OpenEphys/Record Node 105/Stereotrode1_example-data.spikes differ diff --git a/tests/data/v0.6.7_OpenEphys/Record Node 105/Stereotrode2_example-data.spikes b/tests/data/v0.6.7_OpenEphys/Record Node 105/Stereotrode2_example-data.spikes new file mode 100644 index 0000000..d23d108 Binary files /dev/null and b/tests/data/v0.6.7_OpenEphys/Record Node 105/Stereotrode2_example-data.spikes differ diff --git a/tests/data/v0.6.7_OpenEphys/Record Node 105/Stereotrode3_example-data.spikes b/tests/data/v0.6.7_OpenEphys/Record Node 105/Stereotrode3_example-data.spikes new file mode 100644 index 0000000..0ee16cf Binary files /dev/null and b/tests/data/v0.6.7_OpenEphys/Record Node 105/Stereotrode3_example-data.spikes differ diff --git a/tests/data/v0.6.7_OpenEphys/Record Node 105/Stereotrode4_example-data.spikes b/tests/data/v0.6.7_OpenEphys/Record Node 105/Stereotrode4_example-data.spikes new file mode 100644 index 0000000..e598c4b Binary files /dev/null and b/tests/data/v0.6.7_OpenEphys/Record Node 105/Stereotrode4_example-data.spikes differ diff --git a/tests/data/v0.6.7_OpenEphys/Record Node 105/Stereotrode5_example-data.spikes b/tests/data/v0.6.7_OpenEphys/Record Node 105/Stereotrode5_example-data.spikes new file mode 100644 index 0000000..74faa80 Binary files /dev/null and b/tests/data/v0.6.7_OpenEphys/Record Node 105/Stereotrode5_example-data.spikes differ diff --git a/tests/data/v0.6.7_OpenEphys/Record Node 105/Stereotrode6_example-data.spikes b/tests/data/v0.6.7_OpenEphys/Record Node 105/Stereotrode6_example-data.spikes new file mode 100644 index 0000000..9f50667 Binary files /dev/null and b/tests/data/v0.6.7_OpenEphys/Record Node 105/Stereotrode6_example-data.spikes differ diff --git a/tests/data/v0.6.7_OpenEphys/Record Node 105/Stereotrode7_example-data.spikes b/tests/data/v0.6.7_OpenEphys/Record Node 105/Stereotrode7_example-data.spikes new file mode 100644 index 0000000..c91804e Binary files /dev/null and b/tests/data/v0.6.7_OpenEphys/Record Node 105/Stereotrode7_example-data.spikes differ diff --git a/tests/data/v0.6.7_OpenEphys/Record Node 105/Stereotrode8_example-data.spikes b/tests/data/v0.6.7_OpenEphys/Record Node 105/Stereotrode8_example-data.spikes new file mode 100644 index 0000000..d6f6452 Binary files /dev/null and b/tests/data/v0.6.7_OpenEphys/Record Node 105/Stereotrode8_example-data.spikes differ diff --git a/tests/data/v0.6.7_OpenEphys/Record Node 105/messages.events b/tests/data/v0.6.7_OpenEphys/Record Node 105/messages.events new file mode 100644 index 0000000..fea9d69 --- /dev/null +++ b/tests/data/v0.6.7_OpenEphys/Record Node 105/messages.events @@ -0,0 +1,17 @@ +1743680325032, Software Time (milliseconds since midnight Jan 1st 1970 UTC) +251635, Start Time for File Reader (100) - example_data @ 40000 Hz +251635, TTL Line=1 State=0 +252488, TTL Line=3 State=0 +253341, TTL Line=8 State=0 +254194, TTL Line=13 State=0 +255047, TTL Line=18 State=0 +255900, TTL Line=25 State=1 +256753, TTL Line=27 State=0 +257606, TTL Line=32 State=0 +258459, TTL Line=40 State=0 +259312, TTL Line=45 State=0 +260165, TTL Line=48 State=1 +261018, TTL Line=51 State=0 +261871, TTL Line=57 State=1 +262724, TTL Line=62 State=0 +263577, TTL Line=64 State=0 diff --git a/tests/data/v0.6.7_OpenEphys/Record Node 105/settings.xml b/tests/data/v0.6.7_OpenEphys/Record Node 105/settings.xml new file mode 100644 index 0000000..043d5fb --- /dev/null +++ b/tests/data/v0.6.7_OpenEphys/Record Node 105/settings.xml @@ -0,0 +1,282 @@ + + + + + 0.6.7 + 8 + 3 Apr 2025 13:38:45 + Windows 10 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + diff --git a/tests/data/v0.6.7_OpenEphys/Record Node 105/structure.openephys b/tests/data/v0.6.7_OpenEphys/Record Node 105/structure.openephys new file mode 100644 index 0000000..c9ca127 --- /dev/null +++ b/tests/data/v0.6.7_OpenEphys/Record Node 105/structure.openephys @@ -0,0 +1,59 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/tests/test_binary_format.py b/tests/test_binary_format.py new file mode 100644 index 0000000..3ae6b62 --- /dev/null +++ b/tests/test_binary_format.py @@ -0,0 +1,147 @@ +import pandas +import pytest +import os +import open_ephys.analysis as oe +from open_ephys.analysis.formats import BinaryRecording +from open_ephys.analysis.formats.BinaryRecording import ( + BinarySpikes, + get_schema, +) +from open_ephys.analysis.recording import ( + ContinuousMetadata, + RecordingFormat, + SpikeMetadata, +) +import json +import jsonschema + +PLUGIN_GUI_VERSION = "v0.6.7" + + +@pytest.fixture +def binary_file_path(): + return os.path.join( + os.path.dirname(__file__), "data", f"{PLUGIN_GUI_VERSION}_Binary" + ) + + +@pytest.fixture +def binary_recording_correct_continuous_metadata(): + return ContinuousMetadata( + source_node_id=100, + source_node_name="File Reader", + stream_name="example_data", + sample_rate=40000.0, + num_channels=16, + channel_names=[f"CH{i}" for i in range(1, 17)], + bit_volts=[0.05000000074505806] * 16, + ) + + +@pytest.fixture +def binary_recording_correct_spike_metadata(): + return SpikeMetadata( + name="Stereotrode 1", + stream_name="example_data", + sample_rate=40000.0, + num_channels=2, + ) + + +@pytest.fixture +def binary_session(binary_file_path: str): + return oe.Session(binary_file_path) + + +@pytest.fixture +def recording_with_continuous_data(binary_session: oe.Session): + # Assuming the first record node has continuous data for testing + return binary_session.recordnodes[0].recordings[0] + + +@pytest.fixture +def binary_recording_with_spike_data(binary_session: oe.Session): + # Assuming the second record node has spike data for testing + return binary_session.recordnodes[1].recordings[0] + + +def test_validate_oebin(binary_file_path): + oebin_file = os.path.join( + binary_file_path, + "Record Node 101", + "experiment1", + "recording1", + "structure.oebin", + ) + oebin_json = json.load(open(oebin_file, "r")) + jsonschema.validate(instance=oebin_json, schema=get_schema()) + + +def test_open_session(binary_file_path: str): + session = oe.Session(binary_file_path) + assert session.directory == binary_file_path + assert session.recordnodes is not None + assert len(session.recordnodes) > 0 + assert all(isinstance(node, oe.RecordNode) for node in session.recordnodes) + assert all([node.format == RecordingFormat.binary for node in session.recordnodes]) + + +def test_continuous_data( + recording_with_continuous_data: BinaryRecording, + binary_recording_correct_continuous_metadata: ContinuousMetadata, +): + assert recording_with_continuous_data.continuous is not None + + assert len(recording_with_continuous_data.continuous) > 0 + + cont = recording_with_continuous_data.continuous[0] + assert cont.name == "File_Reader-100.example_data/" + assert cont.samples.shape == (131362, 16) + assert cont.metadata == binary_recording_correct_continuous_metadata + + +def test_spike_data( + binary_recording_with_spike_data: BinaryRecording, + binary_recording_correct_spike_metadata: SpikeMetadata, +): + assert binary_recording_with_spike_data.spikes is not None + nChannels = 2 + nSamplesPerWaveForm = 40 + nSpikes = 189 + + assert len(binary_recording_with_spike_data.spikes) > 0 + + spike: BinarySpikes = binary_recording_with_spike_data.spikes[0] + assert spike.waveforms.shape == (nSpikes, nChannels, nSamplesPerWaveForm) + assert spike.clusters.shape == (nSpikes,) + assert spike.metadata == binary_recording_correct_spike_metadata + + +def test_messages(binary_recording_with_spike_data: BinaryRecording): + assert binary_recording_with_spike_data.messages is not None + messages = binary_recording_with_spike_data.messages + assert len(messages) > 0 + assert isinstance(messages, pandas.DataFrame) + expected_columns = ["sample_number", "timestamp", "message"] + assert list(messages.columns) == expected_columns + nMessages = 14 + assert len(messages) == nMessages + + +def test_events(binary_recording_with_spike_data: BinaryRecording): + assert binary_recording_with_spike_data.events is not None + events = binary_recording_with_spike_data.events + assert len(events) > 0 + assert isinstance(events, pandas.DataFrame) + + expected_columns = [ + "line", + "sample_number", + "timestamp", + "processor_id", + "stream_index", + "stream_name", + "state", + ] + assert list(events.columns) == expected_columns + assert len(events) == 128 diff --git a/tests/test_nwb_format.py b/tests/test_nwb_format.py new file mode 100644 index 0000000..ed58a86 --- /dev/null +++ b/tests/test_nwb_format.py @@ -0,0 +1,131 @@ +import os +import pandas +import pytest +from open_ephys.analysis import Session, RecordNode +from open_ephys.analysis.formats.NwbRecording import ( + NwbRecording, + NwbSpikes, + NwbContinuous, +) +from open_ephys.analysis.recording import ( + ContinuousMetadata, + RecordingFormat, + SpikeMetadata, +) + +PLUGIN_GUI_VERSION = "v0.6.7" + + +@pytest.fixture +def nwb_file_path(): + return os.path.join(os.path.dirname(__file__), "data", f"{PLUGIN_GUI_VERSION}_NWB") + + +@pytest.fixture +def nwb_recording_correct_continuous_metadata(): + return ContinuousMetadata( + source_node_id=100, + source_node_name="File Reader", + stream_name="example_data", + sample_rate=40000.0, + num_channels=16, + channel_names=None, # NwbFormat does not yet have channel name reconstruction + bit_volts=[0.05] * 16, + ) + + +@pytest.fixture +def nwb_recording_correct_spike_metadata(): + return SpikeMetadata( + name="Stereotrode 1", + stream_name="example_data", + sample_rate=None, + num_channels=2, + ) + + +@pytest.fixture +def nwb_session(nwb_file_path: str): + return Session(nwb_file_path) + + +@pytest.fixture +def recording_with_continuous_data(nwb_session: Session) -> NwbRecording: + # Assuming the first recording has continuous data for testing + return nwb_session.recordnodes[0].recordings[0] + + +@pytest.fixture +def nwb_recording_with_spike_data(nwb_session): + return nwb_session.recordnodes[0].recordings[0] + + +def test_open_session(nwb_session: Session, nwb_file_path): + session = nwb_session + assert session.directory == nwb_file_path + assert session.recordnodes is not None + assert len(session.recordnodes) > 0 + assert all(isinstance(node, RecordNode) for node in session.recordnodes) + assert all([node.format == RecordingFormat.nwb for node in session.recordnodes]) + + +def test_continuous_data( + recording_with_continuous_data: NwbRecording, + nwb_recording_correct_continuous_metadata: ContinuousMetadata, +): + assert recording_with_continuous_data.continuous is not None + assert len(recording_with_continuous_data.continuous) > 0 + + assert isinstance(recording_with_continuous_data.continuous[0], NwbContinuous) + cont = recording_with_continuous_data.continuous[0] + assert cont.metadata == nwb_recording_correct_continuous_metadata + + +def test_spike_data( + nwb_recording_with_spike_data: NwbRecording, + nwb_recording_correct_spike_metadata: SpikeMetadata, +): + assert nwb_recording_with_spike_data.spikes is not None + nChannels = 2 + nSamplesPerWaveForm = 40 + nSpikes = 189 + + assert len(nwb_recording_with_spike_data.spikes) > 0 + + spike: NwbSpikes = nwb_recording_with_spike_data.spikes[0] + assert spike.waveforms is not None + assert spike.waveforms.shape == (nSpikes, nChannels, nSamplesPerWaveForm) + assert spike.metadata == nwb_recording_correct_spike_metadata + + +def test_events(nwb_recording_with_spike_data: NwbRecording): + nwb_recording_with_spike_data.load_events() + assert nwb_recording_with_spike_data._events is not None + events = nwb_recording_with_spike_data._events + assert len(events) > 0 + assert isinstance(events, pandas.DataFrame) + + expected_columns = [ + "line", + "timestamp", + "sample_number", + "processor_id", + "stream_index", + "stream_name", + "state", + ] + assert list(events.columns) == expected_columns + + +def test_messages(nwb_recording_with_spike_data: NwbRecording): + + with pytest.raises(NotImplementedError): + assert nwb_recording_with_spike_data.messages is not None + + # messages = nwb_recording_with_spike_data.messages + # assert len(messages) > 0 + # assert isinstance(messages, pandas.DataFrame) + # expected_columns = ["sample_number", "timestamp", "message"] + # assert list(messages.columns) == expected_columns + # nMessages = 14 + # assert len(messages) == nMessages diff --git a/tests/test_openephys_format.py b/tests/test_openephys_format.py new file mode 100644 index 0000000..e1a5620 --- /dev/null +++ b/tests/test_openephys_format.py @@ -0,0 +1,136 @@ +import os +import pandas +import pytest +from open_ephys.analysis.formats import OpenEphysRecording +from open_ephys.analysis.formats.OpenEphysRecording import ( + OpenEphysContinuous, + OpenEphysSpikes, +) +from open_ephys.analysis.recording import ( + ContinuousMetadata, + RecordingFormat, + SpikeMetadata, +) + +# filepath: c:\Code\open-ephys\open-ephys-python-tools\tests\test_openephys_format.py +import open_ephys.analysis as oe + +PLUGIN_GUI_VERSION = "v0.6.7" + + +@pytest.fixture +def openephys_file_path(): + return os.path.join( + os.path.dirname(__file__), "data", f"{PLUGIN_GUI_VERSION}_OpenEphys" + ) + + +@pytest.fixture +def openephys_recording_correct_continuous_metadata(): + return ContinuousMetadata( + source_node_id=100, + source_node_name="File Reader", + stream_name="example_data", + sample_rate=40000.0, + num_channels=16, + channel_names=[f"CH{i}" for i in range(1, 17)], + bit_volts=[0.05000000074505806] * 16, + ) + + +@pytest.fixture +def openephys_recording_correct_spike_metadata(): + return SpikeMetadata( + name="Stereotrode 1", + stream_name="example_data", + sample_rate=40000.0, + num_channels=2, + ) + + +@pytest.fixture +def openephys_session(openephys_file_path: str): + return oe.Session(openephys_file_path) + + +@pytest.fixture +def recording_with_continuous_data(openephys_session: oe.Session): + # Assuming the first record node has continuous data for testing + return openephys_session.recordnodes[0].recordings[0] + + +@pytest.fixture +def openephys_recording_with_spike_data(openephys_session: oe.Session): + # Assuming the second record node has spike data for testing + return openephys_session.recordnodes[1].recordings[0] + + +def test_open_session(openephys_file_path: str): + session = oe.Session(openephys_file_path) + assert session.directory == openephys_file_path + assert session.recordnodes is not None + assert len(session.recordnodes) > 0 + assert all(isinstance(node, oe.RecordNode) for node in session.recordnodes) + assert all( + [node.format == RecordingFormat.openephys for node in session.recordnodes] + ) + + +def test_continuous_data( + recording_with_continuous_data: OpenEphysRecording, + openephys_recording_correct_continuous_metadata: ContinuousMetadata, +): + cont: OpenEphysContinuous = recording_with_continuous_data.continuous[0] + assert cont.name == "example-data" + nChannels = 16 + nSamples = 133120 + assert cont.samples.shape == (nSamples, nChannels) + assert cont.metadata == openephys_recording_correct_continuous_metadata + + +def test_spike_data( + openephys_recording_with_spike_data: OpenEphysRecording, + openephys_recording_correct_spike_metadata: SpikeMetadata, +): + assert openephys_recording_with_spike_data.spikes is not None + nChannels = 2 + nSamplesPerWaveForm = 40 + + assert len(openephys_recording_with_spike_data.spikes) > 0 + + spike: OpenEphysSpikes = openephys_recording_with_spike_data.spikes[0] + nSpikes = spike.sample_numbers.shape[0] + assert spike.waveforms.shape == (nSpikes, nChannels, nSamplesPerWaveForm) + assert spike.metadata == openephys_recording_correct_spike_metadata + + +def test_messages(openephys_recording_with_spike_data: OpenEphysRecording): + assert openephys_recording_with_spike_data.messages is not None + messages = openephys_recording_with_spike_data.messages + assert len(messages) > 0 + assert isinstance(messages, pandas.DataFrame) + + # OpenEphys messsages have only two columns + expected_columns = ["timestamp", "message"] + assert list(messages.columns) == expected_columns + nMessages = 16 + assert len(messages) == nMessages + + +def test_events(openephys_recording_with_spike_data: OpenEphysRecording): + assert openephys_recording_with_spike_data.events is not None + events = openephys_recording_with_spike_data.events + assert len(events) > 0 + assert isinstance(events, pandas.DataFrame) + + # openEphys events have only six columns + expected_columns = [ + "line", + "sample_number", + "processor_id", + "stream_index", + "stream_name", + "state", + ] + assert list(events.columns) == expected_columns + assert len(events) == 128 diff --git a/uv.lock b/uv.lock new file mode 100644 index 0000000..0415641 --- /dev/null +++ b/uv.lock @@ -0,0 +1,993 @@ +version = 1 +requires-python = ">=3.9" +resolution-markers = [ + "python_full_version >= '3.12'", + "python_full_version == '3.11.*'", + "python_full_version == '3.10.*'", + "python_full_version < '3.10'", +] + +[[package]] +name = "attrs" +version = "25.3.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/5a/b0/1367933a8532ee6ff8d63537de4f1177af4bff9f3e829baf7331f595bb24/attrs-25.3.0.tar.gz", hash = "sha256:75d7cefc7fb576747b2c81b4442d4d4a1ce0900973527c011d1030fd3bf4af1b", size = 812032 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/77/06/bb80f5f86020c4551da315d78b3ab75e8228f89f0162f2c3a819e407941a/attrs-25.3.0-py3-none-any.whl", hash = "sha256:427318ce031701fea540783410126f03899a97ffc6f61596ad581ac2e40e3bc3", size = 63815 }, +] + +[[package]] +name = "black" +version = "25.1.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "click" }, + { name = "mypy-extensions" }, + { name = "packaging" }, + { name = "pathspec" }, + { name = "platformdirs" }, + { name = "tomli", marker = "python_full_version < '3.11'" }, + { name = "typing-extensions", marker = "python_full_version < '3.11'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/94/49/26a7b0f3f35da4b5a65f081943b7bcd22d7002f5f0fb8098ec1ff21cb6ef/black-25.1.0.tar.gz", hash = "sha256:33496d5cd1222ad73391352b4ae8da15253c5de89b93a80b3e2c8d9a19ec2666", size = 649449 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/4d/3b/4ba3f93ac8d90410423fdd31d7541ada9bcee1df32fb90d26de41ed40e1d/black-25.1.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:759e7ec1e050a15f89b770cefbf91ebee8917aac5c20483bc2d80a6c3a04df32", size = 1629419 }, + { url = "https://files.pythonhosted.org/packages/b4/02/0bde0485146a8a5e694daed47561785e8b77a0466ccc1f3e485d5ef2925e/black-25.1.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:0e519ecf93120f34243e6b0054db49c00a35f84f195d5bce7e9f5cfc578fc2da", size = 1461080 }, + { url = "https://files.pythonhosted.org/packages/52/0e/abdf75183c830eaca7589144ff96d49bce73d7ec6ad12ef62185cc0f79a2/black-25.1.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:055e59b198df7ac0b7efca5ad7ff2516bca343276c466be72eb04a3bcc1f82d7", size = 1766886 }, + { url = "https://files.pythonhosted.org/packages/dc/a6/97d8bb65b1d8a41f8a6736222ba0a334db7b7b77b8023ab4568288f23973/black-25.1.0-cp310-cp310-win_amd64.whl", hash = "sha256:db8ea9917d6f8fc62abd90d944920d95e73c83a5ee3383493e35d271aca872e9", size = 1419404 }, + { url = "https://files.pythonhosted.org/packages/7e/4f/87f596aca05c3ce5b94b8663dbfe242a12843caaa82dd3f85f1ffdc3f177/black-25.1.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:a39337598244de4bae26475f77dda852ea00a93bd4c728e09eacd827ec929df0", size = 1614372 }, + { url = "https://files.pythonhosted.org/packages/e7/d0/2c34c36190b741c59c901e56ab7f6e54dad8df05a6272a9747ecef7c6036/black-25.1.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:96c1c7cd856bba8e20094e36e0f948718dc688dba4a9d78c3adde52b9e6c2299", size = 1442865 }, + { url = "https://files.pythonhosted.org/packages/21/d4/7518c72262468430ead45cf22bd86c883a6448b9eb43672765d69a8f1248/black-25.1.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:bce2e264d59c91e52d8000d507eb20a9aca4a778731a08cfff7e5ac4a4bb7096", size = 1749699 }, + { url = "https://files.pythonhosted.org/packages/58/db/4f5beb989b547f79096e035c4981ceb36ac2b552d0ac5f2620e941501c99/black-25.1.0-cp311-cp311-win_amd64.whl", hash = "sha256:172b1dbff09f86ce6f4eb8edf9dede08b1fce58ba194c87d7a4f1a5aa2f5b3c2", size = 1428028 }, + { url = "https://files.pythonhosted.org/packages/83/71/3fe4741df7adf015ad8dfa082dd36c94ca86bb21f25608eb247b4afb15b2/black-25.1.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:4b60580e829091e6f9238c848ea6750efed72140b91b048770b64e74fe04908b", size = 1650988 }, + { url = "https://files.pythonhosted.org/packages/13/f3/89aac8a83d73937ccd39bbe8fc6ac8860c11cfa0af5b1c96d081facac844/black-25.1.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:1e2978f6df243b155ef5fa7e558a43037c3079093ed5d10fd84c43900f2d8ecc", size = 1453985 }, + { url = "https://files.pythonhosted.org/packages/6f/22/b99efca33f1f3a1d2552c714b1e1b5ae92efac6c43e790ad539a163d1754/black-25.1.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:3b48735872ec535027d979e8dcb20bf4f70b5ac75a8ea99f127c106a7d7aba9f", size = 1783816 }, + { url = "https://files.pythonhosted.org/packages/18/7e/a27c3ad3822b6f2e0e00d63d58ff6299a99a5b3aee69fa77cd4b0076b261/black-25.1.0-cp312-cp312-win_amd64.whl", hash = "sha256:ea0213189960bda9cf99be5b8c8ce66bb054af5e9e861249cd23471bd7b0b3ba", size = 1440860 }, + { url = "https://files.pythonhosted.org/packages/98/87/0edf98916640efa5d0696e1abb0a8357b52e69e82322628f25bf14d263d1/black-25.1.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:8f0b18a02996a836cc9c9c78e5babec10930862827b1b724ddfe98ccf2f2fe4f", size = 1650673 }, + { url = "https://files.pythonhosted.org/packages/52/e5/f7bf17207cf87fa6e9b676576749c6b6ed0d70f179a3d812c997870291c3/black-25.1.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:afebb7098bfbc70037a053b91ae8437c3857482d3a690fefc03e9ff7aa9a5fd3", size = 1453190 }, + { url = "https://files.pythonhosted.org/packages/e3/ee/adda3d46d4a9120772fae6de454c8495603c37c4c3b9c60f25b1ab6401fe/black-25.1.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:030b9759066a4ee5e5aca28c3c77f9c64789cdd4de8ac1df642c40b708be6171", size = 1782926 }, + { url = "https://files.pythonhosted.org/packages/cc/64/94eb5f45dcb997d2082f097a3944cfc7fe87e071907f677e80788a2d7b7a/black-25.1.0-cp313-cp313-win_amd64.whl", hash = "sha256:a22f402b410566e2d1c950708c77ebf5ebd5d0d88a6a2e87c86d9fb48afa0d18", size = 1442613 }, + { url = "https://files.pythonhosted.org/packages/d3/b6/ae7507470a4830dbbfe875c701e84a4a5fb9183d1497834871a715716a92/black-25.1.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:a1ee0a0c330f7b5130ce0caed9936a904793576ef4d2b98c40835d6a65afa6a0", size = 1628593 }, + { url = "https://files.pythonhosted.org/packages/24/c1/ae36fa59a59f9363017ed397750a0cd79a470490860bc7713967d89cdd31/black-25.1.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:f3df5f1bf91d36002b0a75389ca8663510cf0531cca8aa5c1ef695b46d98655f", size = 1460000 }, + { url = "https://files.pythonhosted.org/packages/ac/b6/98f832e7a6c49aa3a464760c67c7856363aa644f2f3c74cf7d624168607e/black-25.1.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:d9e6827d563a2c820772b32ce8a42828dc6790f095f441beef18f96aa6f8294e", size = 1765963 }, + { url = "https://files.pythonhosted.org/packages/ce/e9/2cb0a017eb7024f70e0d2e9bdb8c5a5b078c5740c7f8816065d06f04c557/black-25.1.0-cp39-cp39-win_amd64.whl", hash = "sha256:bacabb307dca5ebaf9c118d2d2f6903da0d62c9faa82bd21a33eecc319559355", size = 1419419 }, + { url = "https://files.pythonhosted.org/packages/09/71/54e999902aed72baf26bca0d50781b01838251a462612966e9fc4891eadd/black-25.1.0-py3-none-any.whl", hash = "sha256:95e8176dae143ba9097f351d174fdaf0ccd29efb414b362ae3fd72bf0f710717", size = 207646 }, +] + +[[package]] +name = "certifi" +version = "2025.1.31" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/1c/ab/c9f1e32b7b1bf505bf26f0ef697775960db7932abeb7b516de930ba2705f/certifi-2025.1.31.tar.gz", hash = "sha256:3d5da6925056f6f18f119200434a4780a94263f10d1c21d032a6f6b2baa20651", size = 167577 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/38/fc/bce832fd4fd99766c04d1ee0eead6b0ec6486fb100ae5e74c1d91292b982/certifi-2025.1.31-py3-none-any.whl", hash = "sha256:ca78db4565a652026a4db2bcdf68f2fb589ea80d0be70e03929ed730746b84fe", size = 166393 }, +] + +[[package]] +name = "cffi" +version = "1.17.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "pycparser" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/fc/97/c783634659c2920c3fc70419e3af40972dbaf758daa229a7d6ea6135c90d/cffi-1.17.1.tar.gz", hash = "sha256:1c39c6016c32bc48dd54561950ebd6836e1670f2ae46128f67cf49e789c52824", size = 516621 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/90/07/f44ca684db4e4f08a3fdc6eeb9a0d15dc6883efc7b8c90357fdbf74e186c/cffi-1.17.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:df8b1c11f177bc2313ec4b2d46baec87a5f3e71fc8b45dab2ee7cae86d9aba14", size = 182191 }, + { url = "https://files.pythonhosted.org/packages/08/fd/cc2fedbd887223f9f5d170c96e57cbf655df9831a6546c1727ae13fa977a/cffi-1.17.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:8f2cdc858323644ab277e9bb925ad72ae0e67f69e804f4898c070998d50b1a67", size = 178592 }, + { url = "https://files.pythonhosted.org/packages/de/cc/4635c320081c78d6ffc2cab0a76025b691a91204f4aa317d568ff9280a2d/cffi-1.17.1-cp310-cp310-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:edae79245293e15384b51f88b00613ba9f7198016a5948b5dddf4917d4d26382", size = 426024 }, + { url = "https://files.pythonhosted.org/packages/b6/7b/3b2b250f3aab91abe5f8a51ada1b717935fdaec53f790ad4100fe2ec64d1/cffi-1.17.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:45398b671ac6d70e67da8e4224a065cec6a93541bb7aebe1b198a61b58c7b702", size = 448188 }, + { url = "https://files.pythonhosted.org/packages/d3/48/1b9283ebbf0ec065148d8de05d647a986c5f22586b18120020452fff8f5d/cffi-1.17.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ad9413ccdeda48c5afdae7e4fa2192157e991ff761e7ab8fdd8926f40b160cc3", size = 455571 }, + { url = "https://files.pythonhosted.org/packages/40/87/3b8452525437b40f39ca7ff70276679772ee7e8b394934ff60e63b7b090c/cffi-1.17.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5da5719280082ac6bd9aa7becb3938dc9f9cbd57fac7d2871717b1feb0902ab6", size = 436687 }, + { url = "https://files.pythonhosted.org/packages/8d/fb/4da72871d177d63649ac449aec2e8a29efe0274035880c7af59101ca2232/cffi-1.17.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2bb1a08b8008b281856e5971307cc386a8e9c5b625ac297e853d36da6efe9c17", size = 446211 }, + { url = "https://files.pythonhosted.org/packages/ab/a0/62f00bcb411332106c02b663b26f3545a9ef136f80d5df746c05878f8c4b/cffi-1.17.1-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:045d61c734659cc045141be4bae381a41d89b741f795af1dd018bfb532fd0df8", size = 461325 }, + { url = "https://files.pythonhosted.org/packages/36/83/76127035ed2e7e27b0787604d99da630ac3123bfb02d8e80c633f218a11d/cffi-1.17.1-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:6883e737d7d9e4899a8a695e00ec36bd4e5e4f18fabe0aca0efe0a4b44cdb13e", size = 438784 }, + { url = "https://files.pythonhosted.org/packages/21/81/a6cd025db2f08ac88b901b745c163d884641909641f9b826e8cb87645942/cffi-1.17.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:6b8b4a92e1c65048ff98cfe1f735ef8f1ceb72e3d5f0c25fdb12087a23da22be", size = 461564 }, + { url = "https://files.pythonhosted.org/packages/f8/fe/4d41c2f200c4a457933dbd98d3cf4e911870877bd94d9656cc0fcb390681/cffi-1.17.1-cp310-cp310-win32.whl", hash = "sha256:c9c3d058ebabb74db66e431095118094d06abf53284d9c81f27300d0e0d8bc7c", size = 171804 }, + { url = "https://files.pythonhosted.org/packages/d1/b6/0b0f5ab93b0df4acc49cae758c81fe4e5ef26c3ae2e10cc69249dfd8b3ab/cffi-1.17.1-cp310-cp310-win_amd64.whl", hash = "sha256:0f048dcf80db46f0098ccac01132761580d28e28bc0f78ae0d58048063317e15", size = 181299 }, + { url = "https://files.pythonhosted.org/packages/6b/f4/927e3a8899e52a27fa57a48607ff7dc91a9ebe97399b357b85a0c7892e00/cffi-1.17.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:a45e3c6913c5b87b3ff120dcdc03f6131fa0065027d0ed7ee6190736a74cd401", size = 182264 }, + { url = "https://files.pythonhosted.org/packages/6c/f5/6c3a8efe5f503175aaddcbea6ad0d2c96dad6f5abb205750d1b3df44ef29/cffi-1.17.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:30c5e0cb5ae493c04c8b42916e52ca38079f1b235c2f8ae5f4527b963c401caf", size = 178651 }, + { url = "https://files.pythonhosted.org/packages/94/dd/a3f0118e688d1b1a57553da23b16bdade96d2f9bcda4d32e7d2838047ff7/cffi-1.17.1-cp311-cp311-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f75c7ab1f9e4aca5414ed4d8e5c0e303a34f4421f8a0d47a4d019ceff0ab6af4", size = 445259 }, + { url = "https://files.pythonhosted.org/packages/2e/ea/70ce63780f096e16ce8588efe039d3c4f91deb1dc01e9c73a287939c79a6/cffi-1.17.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a1ed2dd2972641495a3ec98445e09766f077aee98a1c896dcb4ad0d303628e41", size = 469200 }, + { url = "https://files.pythonhosted.org/packages/1c/a0/a4fa9f4f781bda074c3ddd57a572b060fa0df7655d2a4247bbe277200146/cffi-1.17.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:46bf43160c1a35f7ec506d254e5c890f3c03648a4dbac12d624e4490a7046cd1", size = 477235 }, + { url = "https://files.pythonhosted.org/packages/62/12/ce8710b5b8affbcdd5c6e367217c242524ad17a02fe5beec3ee339f69f85/cffi-1.17.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a24ed04c8ffd54b0729c07cee15a81d964e6fee0e3d4d342a27b020d22959dc6", size = 459721 }, + { url = "https://files.pythonhosted.org/packages/ff/6b/d45873c5e0242196f042d555526f92aa9e0c32355a1be1ff8c27f077fd37/cffi-1.17.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:610faea79c43e44c71e1ec53a554553fa22321b65fae24889706c0a84d4ad86d", size = 467242 }, + { url = "https://files.pythonhosted.org/packages/1a/52/d9a0e523a572fbccf2955f5abe883cfa8bcc570d7faeee06336fbd50c9fc/cffi-1.17.1-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:a9b15d491f3ad5d692e11f6b71f7857e7835eb677955c00cc0aefcd0669adaf6", size = 477999 }, + { url = "https://files.pythonhosted.org/packages/44/74/f2a2460684a1a2d00ca799ad880d54652841a780c4c97b87754f660c7603/cffi-1.17.1-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:de2ea4b5833625383e464549fec1bc395c1bdeeb5f25c4a3a82b5a8c756ec22f", size = 454242 }, + { url = "https://files.pythonhosted.org/packages/f8/4a/34599cac7dfcd888ff54e801afe06a19c17787dfd94495ab0c8d35fe99fb/cffi-1.17.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:fc48c783f9c87e60831201f2cce7f3b2e4846bf4d8728eabe54d60700b318a0b", size = 478604 }, + { url = "https://files.pythonhosted.org/packages/34/33/e1b8a1ba29025adbdcda5fb3a36f94c03d771c1b7b12f726ff7fef2ebe36/cffi-1.17.1-cp311-cp311-win32.whl", hash = "sha256:85a950a4ac9c359340d5963966e3e0a94a676bd6245a4b55bc43949eee26a655", size = 171727 }, + { url = "https://files.pythonhosted.org/packages/3d/97/50228be003bb2802627d28ec0627837ac0bf35c90cf769812056f235b2d1/cffi-1.17.1-cp311-cp311-win_amd64.whl", hash = "sha256:caaf0640ef5f5517f49bc275eca1406b0ffa6aa184892812030f04c2abf589a0", size = 181400 }, + { url = "https://files.pythonhosted.org/packages/5a/84/e94227139ee5fb4d600a7a4927f322e1d4aea6fdc50bd3fca8493caba23f/cffi-1.17.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:805b4371bf7197c329fcb3ead37e710d1bca9da5d583f5073b799d5c5bd1eee4", size = 183178 }, + { url = "https://files.pythonhosted.org/packages/da/ee/fb72c2b48656111c4ef27f0f91da355e130a923473bf5ee75c5643d00cca/cffi-1.17.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:733e99bc2df47476e3848417c5a4540522f234dfd4ef3ab7fafdf555b082ec0c", size = 178840 }, + { url = "https://files.pythonhosted.org/packages/cc/b6/db007700f67d151abadf508cbfd6a1884f57eab90b1bb985c4c8c02b0f28/cffi-1.17.1-cp312-cp312-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1257bdabf294dceb59f5e70c64a3e2f462c30c7ad68092d01bbbfb1c16b1ba36", size = 454803 }, + { url = "https://files.pythonhosted.org/packages/1a/df/f8d151540d8c200eb1c6fba8cd0dfd40904f1b0682ea705c36e6c2e97ab3/cffi-1.17.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:da95af8214998d77a98cc14e3a3bd00aa191526343078b530ceb0bd710fb48a5", size = 478850 }, + { url = "https://files.pythonhosted.org/packages/28/c0/b31116332a547fd2677ae5b78a2ef662dfc8023d67f41b2a83f7c2aa78b1/cffi-1.17.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d63afe322132c194cf832bfec0dc69a99fb9bb6bbd550f161a49e9e855cc78ff", size = 485729 }, + { url = "https://files.pythonhosted.org/packages/91/2b/9a1ddfa5c7f13cab007a2c9cc295b70fbbda7cb10a286aa6810338e60ea1/cffi-1.17.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f79fc4fc25f1c8698ff97788206bb3c2598949bfe0fef03d299eb1b5356ada99", size = 471256 }, + { url = "https://files.pythonhosted.org/packages/b2/d5/da47df7004cb17e4955df6a43d14b3b4ae77737dff8bf7f8f333196717bf/cffi-1.17.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b62ce867176a75d03a665bad002af8e6d54644fad99a3c70905c543130e39d93", size = 479424 }, + { url = "https://files.pythonhosted.org/packages/0b/ac/2a28bcf513e93a219c8a4e8e125534f4f6db03e3179ba1c45e949b76212c/cffi-1.17.1-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:386c8bf53c502fff58903061338ce4f4950cbdcb23e2902d86c0f722b786bbe3", size = 484568 }, + { url = "https://files.pythonhosted.org/packages/d4/38/ca8a4f639065f14ae0f1d9751e70447a261f1a30fa7547a828ae08142465/cffi-1.17.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:4ceb10419a9adf4460ea14cfd6bc43d08701f0835e979bf821052f1805850fe8", size = 488736 }, + { url = "https://files.pythonhosted.org/packages/86/c5/28b2d6f799ec0bdecf44dced2ec5ed43e0eb63097b0f58c293583b406582/cffi-1.17.1-cp312-cp312-win32.whl", hash = "sha256:a08d7e755f8ed21095a310a693525137cfe756ce62d066e53f502a83dc550f65", size = 172448 }, + { url = "https://files.pythonhosted.org/packages/50/b9/db34c4755a7bd1cb2d1603ac3863f22bcecbd1ba29e5ee841a4bc510b294/cffi-1.17.1-cp312-cp312-win_amd64.whl", hash = "sha256:51392eae71afec0d0c8fb1a53b204dbb3bcabcb3c9b807eedf3e1e6ccf2de903", size = 181976 }, + { url = "https://files.pythonhosted.org/packages/8d/f8/dd6c246b148639254dad4d6803eb6a54e8c85c6e11ec9df2cffa87571dbe/cffi-1.17.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:f3a2b4222ce6b60e2e8b337bb9596923045681d71e5a082783484d845390938e", size = 182989 }, + { url = "https://files.pythonhosted.org/packages/8b/f1/672d303ddf17c24fc83afd712316fda78dc6fce1cd53011b839483e1ecc8/cffi-1.17.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:0984a4925a435b1da406122d4d7968dd861c1385afe3b45ba82b750f229811e2", size = 178802 }, + { url = "https://files.pythonhosted.org/packages/0e/2d/eab2e858a91fdff70533cab61dcff4a1f55ec60425832ddfdc9cd36bc8af/cffi-1.17.1-cp313-cp313-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d01b12eeeb4427d3110de311e1774046ad344f5b1a7403101878976ecd7a10f3", size = 454792 }, + { url = "https://files.pythonhosted.org/packages/75/b2/fbaec7c4455c604e29388d55599b99ebcc250a60050610fadde58932b7ee/cffi-1.17.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:706510fe141c86a69c8ddc029c7910003a17353970cff3b904ff0686a5927683", size = 478893 }, + { url = "https://files.pythonhosted.org/packages/4f/b7/6e4a2162178bf1935c336d4da8a9352cccab4d3a5d7914065490f08c0690/cffi-1.17.1-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:de55b766c7aa2e2a3092c51e0483d700341182f08e67c63630d5b6f200bb28e5", size = 485810 }, + { url = "https://files.pythonhosted.org/packages/c7/8a/1d0e4a9c26e54746dc08c2c6c037889124d4f59dffd853a659fa545f1b40/cffi-1.17.1-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c59d6e989d07460165cc5ad3c61f9fd8f1b4796eacbd81cee78957842b834af4", size = 471200 }, + { url = "https://files.pythonhosted.org/packages/26/9f/1aab65a6c0db35f43c4d1b4f580e8df53914310afc10ae0397d29d697af4/cffi-1.17.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dd398dbc6773384a17fe0d3e7eeb8d1a21c2200473ee6806bb5e6a8e62bb73dd", size = 479447 }, + { url = "https://files.pythonhosted.org/packages/5f/e4/fb8b3dd8dc0e98edf1135ff067ae070bb32ef9d509d6cb0f538cd6f7483f/cffi-1.17.1-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:3edc8d958eb099c634dace3c7e16560ae474aa3803a5df240542b305d14e14ed", size = 484358 }, + { url = "https://files.pythonhosted.org/packages/f1/47/d7145bf2dc04684935d57d67dff9d6d795b2ba2796806bb109864be3a151/cffi-1.17.1-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:72e72408cad3d5419375fc87d289076ee319835bdfa2caad331e377589aebba9", size = 488469 }, + { url = "https://files.pythonhosted.org/packages/bf/ee/f94057fa6426481d663b88637a9a10e859e492c73d0384514a17d78ee205/cffi-1.17.1-cp313-cp313-win32.whl", hash = "sha256:e03eab0a8677fa80d646b5ddece1cbeaf556c313dcfac435ba11f107ba117b5d", size = 172475 }, + { url = "https://files.pythonhosted.org/packages/7c/fc/6a8cb64e5f0324877d503c854da15d76c1e50eb722e320b15345c4d0c6de/cffi-1.17.1-cp313-cp313-win_amd64.whl", hash = "sha256:f6a16c31041f09ead72d69f583767292f750d24913dadacf5756b966aacb3f1a", size = 182009 }, + { url = "https://files.pythonhosted.org/packages/b9/ea/8bb50596b8ffbc49ddd7a1ad305035daa770202a6b782fc164647c2673ad/cffi-1.17.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:b2ab587605f4ba0bf81dc0cb08a41bd1c0a5906bd59243d56bad7668a6fc6c16", size = 182220 }, + { url = "https://files.pythonhosted.org/packages/ae/11/e77c8cd24f58285a82c23af484cf5b124a376b32644e445960d1a4654c3a/cffi-1.17.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:28b16024becceed8c6dfbc75629e27788d8a3f9030691a1dbf9821a128b22c36", size = 178605 }, + { url = "https://files.pythonhosted.org/packages/ed/65/25a8dc32c53bf5b7b6c2686b42ae2ad58743f7ff644844af7cdb29b49361/cffi-1.17.1-cp39-cp39-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1d599671f396c4723d016dbddb72fe8e0397082b0a77a4fab8028923bec050e8", size = 424910 }, + { url = "https://files.pythonhosted.org/packages/42/7a/9d086fab7c66bd7c4d0f27c57a1b6b068ced810afc498cc8c49e0088661c/cffi-1.17.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ca74b8dbe6e8e8263c0ffd60277de77dcee6c837a3d0881d8c1ead7268c9e576", size = 447200 }, + { url = "https://files.pythonhosted.org/packages/da/63/1785ced118ce92a993b0ec9e0d0ac8dc3e5dbfbcaa81135be56c69cabbb6/cffi-1.17.1-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f7f5baafcc48261359e14bcd6d9bff6d4b28d9103847c9e136694cb0501aef87", size = 454565 }, + { url = "https://files.pythonhosted.org/packages/74/06/90b8a44abf3556599cdec107f7290277ae8901a58f75e6fe8f970cd72418/cffi-1.17.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:98e3969bcff97cae1b2def8ba499ea3d6f31ddfdb7635374834cf89a1a08ecf0", size = 435635 }, + { url = "https://files.pythonhosted.org/packages/bd/62/a1f468e5708a70b1d86ead5bab5520861d9c7eacce4a885ded9faa7729c3/cffi-1.17.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:cdf5ce3acdfd1661132f2a9c19cac174758dc2352bfe37d98aa7512c6b7178b3", size = 445218 }, + { url = "https://files.pythonhosted.org/packages/5b/95/b34462f3ccb09c2594aa782d90a90b045de4ff1f70148ee79c69d37a0a5a/cffi-1.17.1-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:9755e4345d1ec879e3849e62222a18c7174d65a6a92d5b346b1863912168b595", size = 460486 }, + { url = "https://files.pythonhosted.org/packages/fc/fc/a1e4bebd8d680febd29cf6c8a40067182b64f00c7d105f8f26b5bc54317b/cffi-1.17.1-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:f1e22e8c4419538cb197e4dd60acc919d7696e5ef98ee4da4e01d3f8cfa4cc5a", size = 437911 }, + { url = "https://files.pythonhosted.org/packages/e6/c3/21cab7a6154b6a5ea330ae80de386e7665254835b9e98ecc1340b3a7de9a/cffi-1.17.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:c03e868a0b3bc35839ba98e74211ed2b05d2119be4e8a0f224fba9384f1fe02e", size = 460632 }, + { url = "https://files.pythonhosted.org/packages/cb/b5/fd9f8b5a84010ca169ee49f4e4ad6f8c05f4e3545b72ee041dbbcb159882/cffi-1.17.1-cp39-cp39-win32.whl", hash = "sha256:e31ae45bc2e29f6b2abd0de1cc3b9d5205aa847cafaecb8af1476a609a2f6eb7", size = 171820 }, + { url = "https://files.pythonhosted.org/packages/8c/52/b08750ce0bce45c143e1b5d7357ee8c55341b52bdef4b0f081af1eb248c2/cffi-1.17.1-cp39-cp39-win_amd64.whl", hash = "sha256:d016c76bdd850f3c626af19b0542c9677ba156e4ee4fccfdd7848803533ef662", size = 181290 }, +] + +[[package]] +name = "charset-normalizer" +version = "3.4.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/16/b0/572805e227f01586461c80e0fd25d65a2115599cc9dad142fee4b747c357/charset_normalizer-3.4.1.tar.gz", hash = "sha256:44251f18cd68a75b56585dd00dae26183e102cd5e0f9f1466e6df5da2ed64ea3", size = 123188 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/0d/58/5580c1716040bc89206c77d8f74418caf82ce519aae06450393ca73475d1/charset_normalizer-3.4.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:91b36a978b5ae0ee86c394f5a54d6ef44db1de0815eb43de826d41d21e4af3de", size = 198013 }, + { url = "https://files.pythonhosted.org/packages/d0/11/00341177ae71c6f5159a08168bcb98c6e6d196d372c94511f9f6c9afe0c6/charset_normalizer-3.4.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7461baadb4dc00fd9e0acbe254e3d7d2112e7f92ced2adc96e54ef6501c5f176", size = 141285 }, + { url = "https://files.pythonhosted.org/packages/01/09/11d684ea5819e5a8f5100fb0b38cf8d02b514746607934134d31233e02c8/charset_normalizer-3.4.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e218488cd232553829be0664c2292d3af2eeeb94b32bea483cf79ac6a694e037", size = 151449 }, + { url = "https://files.pythonhosted.org/packages/08/06/9f5a12939db324d905dc1f70591ae7d7898d030d7662f0d426e2286f68c9/charset_normalizer-3.4.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:80ed5e856eb7f30115aaf94e4a08114ccc8813e6ed1b5efa74f9f82e8509858f", size = 143892 }, + { url = "https://files.pythonhosted.org/packages/93/62/5e89cdfe04584cb7f4d36003ffa2936681b03ecc0754f8e969c2becb7e24/charset_normalizer-3.4.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b010a7a4fd316c3c484d482922d13044979e78d1861f0e0650423144c616a46a", size = 146123 }, + { url = "https://files.pythonhosted.org/packages/a9/ac/ab729a15c516da2ab70a05f8722ecfccc3f04ed7a18e45c75bbbaa347d61/charset_normalizer-3.4.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4532bff1b8421fd0a320463030c7520f56a79c9024a4e88f01c537316019005a", size = 147943 }, + { url = "https://files.pythonhosted.org/packages/03/d2/3f392f23f042615689456e9a274640c1d2e5dd1d52de36ab8f7955f8f050/charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:d973f03c0cb71c5ed99037b870f2be986c3c05e63622c017ea9816881d2dd247", size = 142063 }, + { url = "https://files.pythonhosted.org/packages/f2/e3/e20aae5e1039a2cd9b08d9205f52142329f887f8cf70da3650326670bddf/charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:3a3bd0dcd373514dcec91c411ddb9632c0d7d92aed7093b8c3bbb6d69ca74408", size = 150578 }, + { url = "https://files.pythonhosted.org/packages/8d/af/779ad72a4da0aed925e1139d458adc486e61076d7ecdcc09e610ea8678db/charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:d9c3cdf5390dcd29aa8056d13e8e99526cda0305acc038b96b30352aff5ff2bb", size = 153629 }, + { url = "https://files.pythonhosted.org/packages/c2/b6/7aa450b278e7aa92cf7732140bfd8be21f5f29d5bf334ae987c945276639/charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:2bdfe3ac2e1bbe5b59a1a63721eb3b95fc9b6817ae4a46debbb4e11f6232428d", size = 150778 }, + { url = "https://files.pythonhosted.org/packages/39/f4/d9f4f712d0951dcbfd42920d3db81b00dd23b6ab520419626f4023334056/charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:eab677309cdb30d047996b36d34caeda1dc91149e4fdca0b1a039b3f79d9a807", size = 146453 }, + { url = "https://files.pythonhosted.org/packages/49/2b/999d0314e4ee0cff3cb83e6bc9aeddd397eeed693edb4facb901eb8fbb69/charset_normalizer-3.4.1-cp310-cp310-win32.whl", hash = "sha256:c0429126cf75e16c4f0ad00ee0eae4242dc652290f940152ca8c75c3a4b6ee8f", size = 95479 }, + { url = "https://files.pythonhosted.org/packages/2d/ce/3cbed41cff67e455a386fb5e5dd8906cdda2ed92fbc6297921f2e4419309/charset_normalizer-3.4.1-cp310-cp310-win_amd64.whl", hash = "sha256:9f0b8b1c6d84c8034a44893aba5e767bf9c7a211e313a9605d9c617d7083829f", size = 102790 }, + { url = "https://files.pythonhosted.org/packages/72/80/41ef5d5a7935d2d3a773e3eaebf0a9350542f2cab4eac59a7a4741fbbbbe/charset_normalizer-3.4.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:8bfa33f4f2672964266e940dd22a195989ba31669bd84629f05fab3ef4e2d125", size = 194995 }, + { url = "https://files.pythonhosted.org/packages/7a/28/0b9fefa7b8b080ec492110af6d88aa3dea91c464b17d53474b6e9ba5d2c5/charset_normalizer-3.4.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:28bf57629c75e810b6ae989f03c0828d64d6b26a5e205535585f96093e405ed1", size = 139471 }, + { url = "https://files.pythonhosted.org/packages/71/64/d24ab1a997efb06402e3fc07317e94da358e2585165930d9d59ad45fcae2/charset_normalizer-3.4.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f08ff5e948271dc7e18a35641d2f11a4cd8dfd5634f55228b691e62b37125eb3", size = 149831 }, + { url = "https://files.pythonhosted.org/packages/37/ed/be39e5258e198655240db5e19e0b11379163ad7070962d6b0c87ed2c4d39/charset_normalizer-3.4.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:234ac59ea147c59ee4da87a0c0f098e9c8d169f4dc2a159ef720f1a61bbe27cd", size = 142335 }, + { url = "https://files.pythonhosted.org/packages/88/83/489e9504711fa05d8dde1574996408026bdbdbd938f23be67deebb5eca92/charset_normalizer-3.4.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fd4ec41f914fa74ad1b8304bbc634b3de73d2a0889bd32076342a573e0779e00", size = 143862 }, + { url = "https://files.pythonhosted.org/packages/c6/c7/32da20821cf387b759ad24627a9aca289d2822de929b8a41b6241767b461/charset_normalizer-3.4.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:eea6ee1db730b3483adf394ea72f808b6e18cf3cb6454b4d86e04fa8c4327a12", size = 145673 }, + { url = "https://files.pythonhosted.org/packages/68/85/f4288e96039abdd5aeb5c546fa20a37b50da71b5cf01e75e87f16cd43304/charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:c96836c97b1238e9c9e3fe90844c947d5afbf4f4c92762679acfe19927d81d77", size = 140211 }, + { url = "https://files.pythonhosted.org/packages/28/a3/a42e70d03cbdabc18997baf4f0227c73591a08041c149e710045c281f97b/charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:4d86f7aff21ee58f26dcf5ae81a9addbd914115cdebcbb2217e4f0ed8982e146", size = 148039 }, + { url = "https://files.pythonhosted.org/packages/85/e4/65699e8ab3014ecbe6f5c71d1a55d810fb716bbfd74f6283d5c2aa87febf/charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:09b5e6733cbd160dcc09589227187e242a30a49ca5cefa5a7edd3f9d19ed53fd", size = 151939 }, + { url = "https://files.pythonhosted.org/packages/b1/82/8e9fe624cc5374193de6860aba3ea8070f584c8565ee77c168ec13274bd2/charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:5777ee0881f9499ed0f71cc82cf873d9a0ca8af166dfa0af8ec4e675b7df48e6", size = 149075 }, + { url = "https://files.pythonhosted.org/packages/3d/7b/82865ba54c765560c8433f65e8acb9217cb839a9e32b42af4aa8e945870f/charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:237bdbe6159cff53b4f24f397d43c6336c6b0b42affbe857970cefbb620911c8", size = 144340 }, + { url = "https://files.pythonhosted.org/packages/b5/b6/9674a4b7d4d99a0d2df9b215da766ee682718f88055751e1e5e753c82db0/charset_normalizer-3.4.1-cp311-cp311-win32.whl", hash = "sha256:8417cb1f36cc0bc7eaba8ccb0e04d55f0ee52df06df3ad55259b9a323555fc8b", size = 95205 }, + { url = "https://files.pythonhosted.org/packages/1e/ab/45b180e175de4402dcf7547e4fb617283bae54ce35c27930a6f35b6bef15/charset_normalizer-3.4.1-cp311-cp311-win_amd64.whl", hash = "sha256:d7f50a1f8c450f3925cb367d011448c39239bb3eb4117c36a6d354794de4ce76", size = 102441 }, + { url = "https://files.pythonhosted.org/packages/0a/9a/dd1e1cdceb841925b7798369a09279bd1cf183cef0f9ddf15a3a6502ee45/charset_normalizer-3.4.1-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:73d94b58ec7fecbc7366247d3b0b10a21681004153238750bb67bd9012414545", size = 196105 }, + { url = "https://files.pythonhosted.org/packages/d3/8c/90bfabf8c4809ecb648f39794cf2a84ff2e7d2a6cf159fe68d9a26160467/charset_normalizer-3.4.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dad3e487649f498dd991eeb901125411559b22e8d7ab25d3aeb1af367df5efd7", size = 140404 }, + { url = "https://files.pythonhosted.org/packages/ad/8f/e410d57c721945ea3b4f1a04b74f70ce8fa800d393d72899f0a40526401f/charset_normalizer-3.4.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c30197aa96e8eed02200a83fba2657b4c3acd0f0aa4bdc9f6c1af8e8962e0757", size = 150423 }, + { url = "https://files.pythonhosted.org/packages/f0/b8/e6825e25deb691ff98cf5c9072ee0605dc2acfca98af70c2d1b1bc75190d/charset_normalizer-3.4.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2369eea1ee4a7610a860d88f268eb39b95cb588acd7235e02fd5a5601773d4fa", size = 143184 }, + { url = "https://files.pythonhosted.org/packages/3e/a2/513f6cbe752421f16d969e32f3583762bfd583848b763913ddab8d9bfd4f/charset_normalizer-3.4.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bc2722592d8998c870fa4e290c2eec2c1569b87fe58618e67d38b4665dfa680d", size = 145268 }, + { url = "https://files.pythonhosted.org/packages/74/94/8a5277664f27c3c438546f3eb53b33f5b19568eb7424736bdc440a88a31f/charset_normalizer-3.4.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ffc9202a29ab3920fa812879e95a9e78b2465fd10be7fcbd042899695d75e616", size = 147601 }, + { url = "https://files.pythonhosted.org/packages/7c/5f/6d352c51ee763623a98e31194823518e09bfa48be2a7e8383cf691bbb3d0/charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:804a4d582ba6e5b747c625bf1255e6b1507465494a40a2130978bda7b932c90b", size = 141098 }, + { url = "https://files.pythonhosted.org/packages/78/d4/f5704cb629ba5ab16d1d3d741396aec6dc3ca2b67757c45b0599bb010478/charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:0f55e69f030f7163dffe9fd0752b32f070566451afe180f99dbeeb81f511ad8d", size = 149520 }, + { url = "https://files.pythonhosted.org/packages/c5/96/64120b1d02b81785f222b976c0fb79a35875457fa9bb40827678e54d1bc8/charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:c4c3e6da02df6fa1410a7680bd3f63d4f710232d3139089536310d027950696a", size = 152852 }, + { url = "https://files.pythonhosted.org/packages/84/c9/98e3732278a99f47d487fd3468bc60b882920cef29d1fa6ca460a1fdf4e6/charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:5df196eb874dae23dcfb968c83d4f8fdccb333330fe1fc278ac5ceeb101003a9", size = 150488 }, + { url = "https://files.pythonhosted.org/packages/13/0e/9c8d4cb99c98c1007cc11eda969ebfe837bbbd0acdb4736d228ccaabcd22/charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:e358e64305fe12299a08e08978f51fc21fac060dcfcddd95453eabe5b93ed0e1", size = 146192 }, + { url = "https://files.pythonhosted.org/packages/b2/21/2b6b5b860781a0b49427309cb8670785aa543fb2178de875b87b9cc97746/charset_normalizer-3.4.1-cp312-cp312-win32.whl", hash = "sha256:9b23ca7ef998bc739bf6ffc077c2116917eabcc901f88da1b9856b210ef63f35", size = 95550 }, + { url = "https://files.pythonhosted.org/packages/21/5b/1b390b03b1d16c7e382b561c5329f83cc06623916aab983e8ab9239c7d5c/charset_normalizer-3.4.1-cp312-cp312-win_amd64.whl", hash = "sha256:6ff8a4a60c227ad87030d76e99cd1698345d4491638dfa6673027c48b3cd395f", size = 102785 }, + { url = "https://files.pythonhosted.org/packages/38/94/ce8e6f63d18049672c76d07d119304e1e2d7c6098f0841b51c666e9f44a0/charset_normalizer-3.4.1-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:aabfa34badd18f1da5ec1bc2715cadc8dca465868a4e73a0173466b688f29dda", size = 195698 }, + { url = "https://files.pythonhosted.org/packages/24/2e/dfdd9770664aae179a96561cc6952ff08f9a8cd09a908f259a9dfa063568/charset_normalizer-3.4.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:22e14b5d70560b8dd51ec22863f370d1e595ac3d024cb8ad7d308b4cd95f8313", size = 140162 }, + { url = "https://files.pythonhosted.org/packages/24/4e/f646b9093cff8fc86f2d60af2de4dc17c759de9d554f130b140ea4738ca6/charset_normalizer-3.4.1-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8436c508b408b82d87dc5f62496973a1805cd46727c34440b0d29d8a2f50a6c9", size = 150263 }, + { url = "https://files.pythonhosted.org/packages/5e/67/2937f8d548c3ef6e2f9aab0f6e21001056f692d43282b165e7c56023e6dd/charset_normalizer-3.4.1-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2d074908e1aecee37a7635990b2c6d504cd4766c7bc9fc86d63f9c09af3fa11b", size = 142966 }, + { url = "https://files.pythonhosted.org/packages/52/ed/b7f4f07de100bdb95c1756d3a4d17b90c1a3c53715c1a476f8738058e0fa/charset_normalizer-3.4.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:955f8851919303c92343d2f66165294848d57e9bba6cf6e3625485a70a038d11", size = 144992 }, + { url = "https://files.pythonhosted.org/packages/96/2c/d49710a6dbcd3776265f4c923bb73ebe83933dfbaa841c5da850fe0fd20b/charset_normalizer-3.4.1-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:44ecbf16649486d4aebafeaa7ec4c9fed8b88101f4dd612dcaf65d5e815f837f", size = 147162 }, + { url = "https://files.pythonhosted.org/packages/b4/41/35ff1f9a6bd380303dea55e44c4933b4cc3c4850988927d4082ada230273/charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:0924e81d3d5e70f8126529951dac65c1010cdf117bb75eb02dd12339b57749dd", size = 140972 }, + { url = "https://files.pythonhosted.org/packages/fb/43/c6a0b685fe6910d08ba971f62cd9c3e862a85770395ba5d9cad4fede33ab/charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:2967f74ad52c3b98de4c3b32e1a44e32975e008a9cd2a8cc8966d6a5218c5cb2", size = 149095 }, + { url = "https://files.pythonhosted.org/packages/4c/ff/a9a504662452e2d2878512115638966e75633519ec11f25fca3d2049a94a/charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:c75cb2a3e389853835e84a2d8fb2b81a10645b503eca9bcb98df6b5a43eb8886", size = 152668 }, + { url = "https://files.pythonhosted.org/packages/6c/71/189996b6d9a4b932564701628af5cee6716733e9165af1d5e1b285c530ed/charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:09b26ae6b1abf0d27570633b2b078a2a20419c99d66fb2823173d73f188ce601", size = 150073 }, + { url = "https://files.pythonhosted.org/packages/e4/93/946a86ce20790e11312c87c75ba68d5f6ad2208cfb52b2d6a2c32840d922/charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:fa88b843d6e211393a37219e6a1c1df99d35e8fd90446f1118f4216e307e48cd", size = 145732 }, + { url = "https://files.pythonhosted.org/packages/cd/e5/131d2fb1b0dddafc37be4f3a2fa79aa4c037368be9423061dccadfd90091/charset_normalizer-3.4.1-cp313-cp313-win32.whl", hash = "sha256:eb8178fe3dba6450a3e024e95ac49ed3400e506fd4e9e5c32d30adda88cbd407", size = 95391 }, + { url = "https://files.pythonhosted.org/packages/27/f2/4f9a69cc7712b9b5ad8fdb87039fd89abba997ad5cbe690d1835d40405b0/charset_normalizer-3.4.1-cp313-cp313-win_amd64.whl", hash = "sha256:b1ac5992a838106edb89654e0aebfc24f5848ae2547d22c2c3f66454daa11971", size = 102702 }, + { url = "https://files.pythonhosted.org/packages/7f/c0/b913f8f02836ed9ab32ea643c6fe4d3325c3d8627cf6e78098671cafff86/charset_normalizer-3.4.1-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:b97e690a2118911e39b4042088092771b4ae3fc3aa86518f84b8cf6888dbdb41", size = 197867 }, + { url = "https://files.pythonhosted.org/packages/0f/6c/2bee440303d705b6fb1e2ec789543edec83d32d258299b16eed28aad48e0/charset_normalizer-3.4.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:78baa6d91634dfb69ec52a463534bc0df05dbd546209b79a3880a34487f4b84f", size = 141385 }, + { url = "https://files.pythonhosted.org/packages/3d/04/cb42585f07f6f9fd3219ffb6f37d5a39b4fd2db2355b23683060029c35f7/charset_normalizer-3.4.1-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1a2bc9f351a75ef49d664206d51f8e5ede9da246602dc2d2726837620ea034b2", size = 151367 }, + { url = "https://files.pythonhosted.org/packages/54/54/2412a5b093acb17f0222de007cc129ec0e0df198b5ad2ce5699355269dfe/charset_normalizer-3.4.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:75832c08354f595c760a804588b9357d34ec00ba1c940c15e31e96d902093770", size = 143928 }, + { url = "https://files.pythonhosted.org/packages/5a/6d/e2773862b043dcf8a221342954f375392bb2ce6487bcd9f2c1b34e1d6781/charset_normalizer-3.4.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0af291f4fe114be0280cdd29d533696a77b5b49cfde5467176ecab32353395c4", size = 146203 }, + { url = "https://files.pythonhosted.org/packages/b9/f8/ca440ef60d8f8916022859885f231abb07ada3c347c03d63f283bec32ef5/charset_normalizer-3.4.1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0167ddc8ab6508fe81860a57dd472b2ef4060e8d378f0cc555707126830f2537", size = 148082 }, + { url = "https://files.pythonhosted.org/packages/04/d2/42fd330901aaa4b805a1097856c2edf5095e260a597f65def493f4b8c833/charset_normalizer-3.4.1-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:2a75d49014d118e4198bcee5ee0a6f25856b29b12dbf7cd012791f8a6cc5c496", size = 142053 }, + { url = "https://files.pythonhosted.org/packages/9e/af/3a97a4fa3c53586f1910dadfc916e9c4f35eeada36de4108f5096cb7215f/charset_normalizer-3.4.1-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:363e2f92b0f0174b2f8238240a1a30142e3db7b957a5dd5689b0e75fb717cc78", size = 150625 }, + { url = "https://files.pythonhosted.org/packages/26/ae/23d6041322a3556e4da139663d02fb1b3c59a23ab2e2b56432bd2ad63ded/charset_normalizer-3.4.1-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:ab36c8eb7e454e34e60eb55ca5d241a5d18b2c6244f6827a30e451c42410b5f7", size = 153549 }, + { url = "https://files.pythonhosted.org/packages/94/22/b8f2081c6a77cb20d97e57e0b385b481887aa08019d2459dc2858ed64871/charset_normalizer-3.4.1-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:4c0907b1928a36d5a998d72d64d8eaa7244989f7aaaf947500d3a800c83a3fd6", size = 150945 }, + { url = "https://files.pythonhosted.org/packages/c7/0b/c5ec5092747f801b8b093cdf5610e732b809d6cb11f4c51e35fc28d1d389/charset_normalizer-3.4.1-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:04432ad9479fa40ec0f387795ddad4437a2b50417c69fa275e212933519ff294", size = 146595 }, + { url = "https://files.pythonhosted.org/packages/0c/5a/0b59704c38470df6768aa154cc87b1ac7c9bb687990a1559dc8765e8627e/charset_normalizer-3.4.1-cp39-cp39-win32.whl", hash = "sha256:3bed14e9c89dcb10e8f3a29f9ccac4955aebe93c71ae803af79265c9ca5644c5", size = 95453 }, + { url = "https://files.pythonhosted.org/packages/85/2d/a9790237cb4d01a6d57afadc8573c8b73c609ade20b80f4cda30802009ee/charset_normalizer-3.4.1-cp39-cp39-win_amd64.whl", hash = "sha256:49402233c892a461407c512a19435d1ce275543138294f7ef013f0b63d5d3765", size = 102811 }, + { url = "https://files.pythonhosted.org/packages/0e/f6/65ecc6878a89bb1c23a086ea335ad4bf21a588990c3f535a227b9eea9108/charset_normalizer-3.4.1-py3-none-any.whl", hash = "sha256:d98b1668f06378c6dbefec3b92299716b931cd4e6061f3c875a71ced1780ab85", size = 49767 }, +] + +[[package]] +name = "click" +version = "8.1.8" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "colorama", marker = "sys_platform == 'win32'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/b9/2e/0090cbf739cee7d23781ad4b89a9894a41538e4fcf4c31dcdd705b78eb8b/click-8.1.8.tar.gz", hash = "sha256:ed53c9d8990d83c2a27deae68e4ee337473f6330c040a31d4225c9574d16096a", size = 226593 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/7e/d4/7ebdbd03970677812aac39c869717059dbb71a4cfc033ca6e5221787892c/click-8.1.8-py3-none-any.whl", hash = "sha256:63c132bbbed01578a06712a2d1f497bb62d9c1c0d329b7903a866228027263b2", size = 98188 }, +] + +[[package]] +name = "colorama" +version = "0.4.6" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/d8/53/6f443c9a4a8358a93a6792e2acffb9d9d5cb0a5cfd8802644b7b1c9a02e4/colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44", size = 27697 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/d1/d6/3965ed04c63042e047cb6a3e6ed1a63a35087b6a609aa3a15ed8ac56c221/colorama-0.4.6-py2.py3-none-any.whl", hash = "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6", size = 25335 }, +] + +[[package]] +name = "exceptiongroup" +version = "1.2.2" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/09/35/2495c4ac46b980e4ca1f6ad6db102322ef3ad2410b79fdde159a4b0f3b92/exceptiongroup-1.2.2.tar.gz", hash = "sha256:47c2edf7c6738fafb49fd34290706d1a1a2f4d1c6df275526b62cbb4aa5393cc", size = 28883 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/02/cc/b7e31358aac6ed1ef2bb790a9746ac2c69bcb3c8588b41616914eb106eaf/exceptiongroup-1.2.2-py3-none-any.whl", hash = "sha256:3111b9d131c238bec2f8f516e123e14ba243563fb135d3fe885990585aa7795b", size = 16453 }, +] + +[[package]] +name = "h5py" +version = "3.13.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "numpy", version = "2.0.2", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.10'" }, + { name = "numpy", version = "2.2.4", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.10'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/03/2e/a22d6a8bfa6f8be33e7febd985680fba531562795f0a9077ed1eb047bfb0/h5py-3.13.0.tar.gz", hash = "sha256:1870e46518720023da85d0895a1960ff2ce398c5671eac3b1a41ec696b7105c3", size = 414876 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/02/8a/bc76588ff1a254e939ce48f30655a8f79fac614ca8bd1eda1a79fa276671/h5py-3.13.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:5540daee2b236d9569c950b417f13fd112d51d78b4c43012de05774908dff3f5", size = 3413286 }, + { url = "https://files.pythonhosted.org/packages/19/bd/9f249ecc6c517b2796330b0aab7d2351a108fdbd00d4bb847c0877b5533e/h5py-3.13.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:10894c55d46df502d82a7a4ed38f9c3fdbcb93efb42e25d275193e093071fade", size = 2915673 }, + { url = "https://files.pythonhosted.org/packages/72/71/0dd079208d7d3c3988cebc0776c2de58b4d51d8eeb6eab871330133dfee6/h5py-3.13.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:fb267ce4b83f9c42560e9ff4d30f60f7ae492eacf9c7ede849edf8c1b860e16b", size = 4283822 }, + { url = "https://files.pythonhosted.org/packages/d8/fa/0b6a59a1043c53d5d287effa02303bd248905ee82b25143c7caad8b340ad/h5py-3.13.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d2cf6a231a07c14acd504a945a6e9ec115e0007f675bde5e0de30a4dc8d86a31", size = 4548100 }, + { url = "https://files.pythonhosted.org/packages/12/42/ad555a7ff7836c943fe97009405566dc77bcd2a17816227c10bd067a3ee1/h5py-3.13.0-cp310-cp310-win_amd64.whl", hash = "sha256:851ae3a8563d87a5a0dc49c2e2529c75b8842582ccaefbf84297d2cfceeacd61", size = 2950547 }, + { url = "https://files.pythonhosted.org/packages/86/2b/50b15fdefb577d073b49699e6ea6a0a77a3a1016c2b67e2149fc50124a10/h5py-3.13.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:8a8e38ef4ceb969f832cc230c0cf808c613cc47e31e768fd7b1106c55afa1cb8", size = 3422922 }, + { url = "https://files.pythonhosted.org/packages/94/59/36d87a559cab9c59b59088d52e86008d27a9602ce3afc9d3b51823014bf3/h5py-3.13.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:f35640e81b03c02a88b8bf99fb6a9d3023cc52f7c627694db2f379e0028f2868", size = 2921619 }, + { url = "https://files.pythonhosted.org/packages/37/ef/6f80b19682c0b0835bbee7b253bec9c16af9004f2fd6427b1dd858100273/h5py-3.13.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:337af114616f3656da0c83b68fcf53ecd9ce9989a700b0883a6e7c483c3235d4", size = 4259366 }, + { url = "https://files.pythonhosted.org/packages/03/71/c99f662d4832c8835453cf3476f95daa28372023bda4aa1fca9e97c24f09/h5py-3.13.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:782ff0ac39f455f21fd1c8ebc007328f65f43d56718a89327eec76677ebf238a", size = 4509058 }, + { url = "https://files.pythonhosted.org/packages/56/89/e3ff23e07131ff73a72a349be9639e4de84e163af89c1c218b939459a98a/h5py-3.13.0-cp311-cp311-win_amd64.whl", hash = "sha256:22ffe2a25770a2d67213a1b94f58006c14dce06933a42d2aaa0318c5868d1508", size = 2966428 }, + { url = "https://files.pythonhosted.org/packages/d8/20/438f6366ba4ded80eadb38f8927f5e2cd6d2e087179552f20ae3dbcd5d5b/h5py-3.13.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:477c58307b6b9a2509c59c57811afb9f598aedede24a67da808262dfa0ee37b4", size = 3384442 }, + { url = "https://files.pythonhosted.org/packages/10/13/cc1cb7231399617d9951233eb12fddd396ff5d4f7f057ee5d2b1ca0ee7e7/h5py-3.13.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:57c4c74f627c616f02b7aec608a8c706fe08cb5b0ba7c08555a4eb1dde20805a", size = 2917567 }, + { url = "https://files.pythonhosted.org/packages/9e/d9/aed99e1c858dc698489f916eeb7c07513bc864885d28ab3689d572ba0ea0/h5py-3.13.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:357e6dc20b101a805ccfd0024731fbaf6e8718c18c09baf3b5e4e9d198d13fca", size = 4669544 }, + { url = "https://files.pythonhosted.org/packages/a7/da/3c137006ff5f0433f0fb076b1ebe4a7bf7b5ee1e8811b5486af98b500dd5/h5py-3.13.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d6f13f9b5ce549448c01e4dfe08ea8d1772e6078799af2c1c8d09e941230a90d", size = 4932139 }, + { url = "https://files.pythonhosted.org/packages/25/61/d897952629cae131c19d4c41b2521e7dd6382f2d7177c87615c2e6dced1a/h5py-3.13.0-cp312-cp312-win_amd64.whl", hash = "sha256:21daf38171753899b5905f3d82c99b0b1ec2cbbe282a037cad431feb620e62ec", size = 2954179 }, + { url = "https://files.pythonhosted.org/packages/60/43/f276f27921919a9144074320ce4ca40882fc67b3cfee81c3f5c7df083e97/h5py-3.13.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:e520ec76de00943dd017c8ea3f354fa1d2f542eac994811943a8faedf2a7d5cb", size = 3358040 }, + { url = "https://files.pythonhosted.org/packages/1b/86/ad4a4cf781b08d4572be8bbdd8f108bb97b266a14835c640dc43dafc0729/h5py-3.13.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:e79d8368cd9295045956bfb436656bea3f915beaa11d342e9f79f129f5178763", size = 2892766 }, + { url = "https://files.pythonhosted.org/packages/69/84/4c6367d6b58deaf0fa84999ec819e7578eee96cea6cbd613640d0625ed5e/h5py-3.13.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:56dd172d862e850823c4af02dc4ddbc308f042b85472ffdaca67f1598dff4a57", size = 4664255 }, + { url = "https://files.pythonhosted.org/packages/fd/41/bc2df86b72965775f6d621e0ee269a5f3ac23e8f870abf519de9c7d93b4d/h5py-3.13.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:be949b46b7388074c5acae017fbbe3e5ba303fd9daaa52157fdfef30bbdacadd", size = 4927580 }, + { url = "https://files.pythonhosted.org/packages/97/34/165b87ea55184770a0c1fcdb7e017199974ad2e271451fd045cfe35f3add/h5py-3.13.0-cp313-cp313-win_amd64.whl", hash = "sha256:4f97ecde7ac6513b21cd95efdfc38dc6d19f96f6ca6f2a30550e94e551458e0a", size = 2940890 }, + { url = "https://files.pythonhosted.org/packages/cd/91/3e5b4e4c399bb57141a2451c67808597ab6993f799587566c9f11dbaefe9/h5py-3.13.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:82690e89c72b85addf4fc4d5058fb1e387b6c14eb063b0b879bf3f42c3b93c35", size = 3424729 }, + { url = "https://files.pythonhosted.org/packages/12/82/4e455e12e7ff26533c762eaf324edd6b076f84c3a003a40a1e52d805e0fb/h5py-3.13.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:d571644958c5e19a61c793d8d23cd02479572da828e333498c9acc463f4a3997", size = 2926632 }, + { url = "https://files.pythonhosted.org/packages/ab/c9/fb430d3277e81eade92e54e87bd73e9f60c98240a86a5f43e3b85620d7d8/h5py-3.13.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:560e71220dc92dfa254b10a4dcb12d56b574d2d87e095db20466b32a93fec3f9", size = 4285580 }, + { url = "https://files.pythonhosted.org/packages/3f/9b/3e8cded7877ec84b707df82b9c6289cd1d7ad80fef9a10bb1389c5fee8f2/h5py-3.13.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c10f061764d8dce0a9592ce08bfd5f243a00703325c388f1086037e5d619c5f1", size = 4550898 }, + { url = "https://files.pythonhosted.org/packages/cb/47/8353102cff9290861135e13eefff5a916855d2ab23bd052ec7ac144f4c48/h5py-3.13.0-cp39-cp39-win_amd64.whl", hash = "sha256:9c82ece71ed1c2b807b6628e3933bc6eae57ea21dac207dca3470e3ceaaf437c", size = 2960208 }, +] + +[[package]] +name = "idna" +version = "3.10" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/f1/70/7703c29685631f5a7590aa73f1f1d3fa9a380e654b86af429e0934a32f7d/idna-3.10.tar.gz", hash = "sha256:12f65c9b470abda6dc35cf8e63cc574b1c52b11df2c86030af0ac09b01b13ea9", size = 190490 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/76/c6/c88e154df9c4e1a2a66ccf0005a88dfb2650c1dffb6f5ce603dfbd452ce3/idna-3.10-py3-none-any.whl", hash = "sha256:946d195a0d259cbba61165e88e65941f16e9b36ea6ddb97f00452bae8b1287d3", size = 70442 }, +] + +[[package]] +name = "iniconfig" +version = "2.1.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/f2/97/ebf4da567aa6827c909642694d71c9fcf53e5b504f2d96afea02718862f3/iniconfig-2.1.0.tar.gz", hash = "sha256:3abbd2e30b36733fee78f9c7f7308f2d0050e88f0087fd25c2645f63c773e1c7", size = 4793 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/2c/e1/e6716421ea10d38022b952c159d5161ca1193197fb744506875fbb87ea7b/iniconfig-2.1.0-py3-none-any.whl", hash = "sha256:9deba5723312380e77435581c6bf4935c94cbfab9b1ed33ef8d238ea168eb760", size = 6050 }, +] + +[[package]] +name = "jsonschema" +version = "4.23.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "attrs" }, + { name = "jsonschema-specifications" }, + { name = "referencing" }, + { name = "rpds-py" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/38/2e/03362ee4034a4c917f697890ccd4aec0800ccf9ded7f511971c75451deec/jsonschema-4.23.0.tar.gz", hash = "sha256:d71497fef26351a33265337fa77ffeb82423f3ea21283cd9467bb03999266bc4", size = 325778 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/69/4a/4f9dbeb84e8850557c02365a0eee0649abe5eb1d84af92a25731c6c0f922/jsonschema-4.23.0-py3-none-any.whl", hash = "sha256:fbadb6f8b144a8f8cf9f0b89ba94501d143e50411a1278633f56a7acf7fd5566", size = 88462 }, +] + +[[package]] +name = "jsonschema-specifications" +version = "2024.10.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "referencing" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/10/db/58f950c996c793472e336ff3655b13fbcf1e3b359dcf52dcf3ed3b52c352/jsonschema_specifications-2024.10.1.tar.gz", hash = "sha256:0f38b83639958ce1152d02a7f062902c41c8fd20d558b0c34344292d417ae272", size = 15561 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/d1/0f/8910b19ac0670a0f80ce1008e5e751c4a57e14d2c4c13a482aa6079fa9d6/jsonschema_specifications-2024.10.1-py3-none-any.whl", hash = "sha256:a09a0680616357d9a0ecf05c12ad234479f549239d0f5b55f3deea67475da9bf", size = 18459 }, +] + +[[package]] +name = "mypy" +version = "1.15.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "mypy-extensions" }, + { name = "tomli", marker = "python_full_version < '3.11'" }, + { name = "typing-extensions" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/ce/43/d5e49a86afa64bd3839ea0d5b9c7103487007d728e1293f52525d6d5486a/mypy-1.15.0.tar.gz", hash = "sha256:404534629d51d3efea5c800ee7c42b72a6554d6c400e6a79eafe15d11341fd43", size = 3239717 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/68/f8/65a7ce8d0e09b6329ad0c8d40330d100ea343bd4dd04c4f8ae26462d0a17/mypy-1.15.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:979e4e1a006511dacf628e36fadfecbcc0160a8af6ca7dad2f5025529e082c13", size = 10738433 }, + { url = "https://files.pythonhosted.org/packages/b4/95/9c0ecb8eacfe048583706249439ff52105b3f552ea9c4024166c03224270/mypy-1.15.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:c4bb0e1bd29f7d34efcccd71cf733580191e9a264a2202b0239da95984c5b559", size = 9861472 }, + { url = "https://files.pythonhosted.org/packages/84/09/9ec95e982e282e20c0d5407bc65031dfd0f0f8ecc66b69538296e06fcbee/mypy-1.15.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:be68172e9fd9ad8fb876c6389f16d1c1b5f100ffa779f77b1fb2176fcc9ab95b", size = 11611424 }, + { url = "https://files.pythonhosted.org/packages/78/13/f7d14e55865036a1e6a0a69580c240f43bc1f37407fe9235c0d4ef25ffb0/mypy-1.15.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:c7be1e46525adfa0d97681432ee9fcd61a3964c2446795714699a998d193f1a3", size = 12365450 }, + { url = "https://files.pythonhosted.org/packages/48/e1/301a73852d40c241e915ac6d7bcd7fedd47d519246db2d7b86b9d7e7a0cb/mypy-1.15.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:2e2c2e6d3593f6451b18588848e66260ff62ccca522dd231cd4dd59b0160668b", size = 12551765 }, + { url = "https://files.pythonhosted.org/packages/77/ba/c37bc323ae5fe7f3f15a28e06ab012cd0b7552886118943e90b15af31195/mypy-1.15.0-cp310-cp310-win_amd64.whl", hash = "sha256:6983aae8b2f653e098edb77f893f7b6aca69f6cffb19b2cc7443f23cce5f4828", size = 9274701 }, + { url = "https://files.pythonhosted.org/packages/03/bc/f6339726c627bd7ca1ce0fa56c9ae2d0144604a319e0e339bdadafbbb599/mypy-1.15.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:2922d42e16d6de288022e5ca321cd0618b238cfc5570e0263e5ba0a77dbef56f", size = 10662338 }, + { url = "https://files.pythonhosted.org/packages/e2/90/8dcf506ca1a09b0d17555cc00cd69aee402c203911410136cd716559efe7/mypy-1.15.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:2ee2d57e01a7c35de00f4634ba1bbf015185b219e4dc5909e281016df43f5ee5", size = 9787540 }, + { url = "https://files.pythonhosted.org/packages/05/05/a10f9479681e5da09ef2f9426f650d7b550d4bafbef683b69aad1ba87457/mypy-1.15.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:973500e0774b85d9689715feeffcc980193086551110fd678ebe1f4342fb7c5e", size = 11538051 }, + { url = "https://files.pythonhosted.org/packages/e9/9a/1f7d18b30edd57441a6411fcbc0c6869448d1a4bacbaee60656ac0fc29c8/mypy-1.15.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:5a95fb17c13e29d2d5195869262f8125dfdb5c134dc8d9a9d0aecf7525b10c2c", size = 12286751 }, + { url = "https://files.pythonhosted.org/packages/72/af/19ff499b6f1dafcaf56f9881f7a965ac2f474f69f6f618b5175b044299f5/mypy-1.15.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:1905f494bfd7d85a23a88c5d97840888a7bd516545fc5aaedff0267e0bb54e2f", size = 12421783 }, + { url = "https://files.pythonhosted.org/packages/96/39/11b57431a1f686c1aed54bf794870efe0f6aeca11aca281a0bd87a5ad42c/mypy-1.15.0-cp311-cp311-win_amd64.whl", hash = "sha256:c9817fa23833ff189db061e6d2eff49b2f3b6ed9856b4a0a73046e41932d744f", size = 9265618 }, + { url = "https://files.pythonhosted.org/packages/98/3a/03c74331c5eb8bd025734e04c9840532226775c47a2c39b56a0c8d4f128d/mypy-1.15.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:aea39e0583d05124836ea645f412e88a5c7d0fd77a6d694b60d9b6b2d9f184fd", size = 10793981 }, + { url = "https://files.pythonhosted.org/packages/f0/1a/41759b18f2cfd568848a37c89030aeb03534411eef981df621d8fad08a1d/mypy-1.15.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:2f2147ab812b75e5b5499b01ade1f4a81489a147c01585cda36019102538615f", size = 9749175 }, + { url = "https://files.pythonhosted.org/packages/12/7e/873481abf1ef112c582db832740f4c11b2bfa510e829d6da29b0ab8c3f9c/mypy-1.15.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:ce436f4c6d218a070048ed6a44c0bbb10cd2cc5e272b29e7845f6a2f57ee4464", size = 11455675 }, + { url = "https://files.pythonhosted.org/packages/b3/d0/92ae4cde706923a2d3f2d6c39629134063ff64b9dedca9c1388363da072d/mypy-1.15.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:8023ff13985661b50a5928fc7a5ca15f3d1affb41e5f0a9952cb68ef090b31ee", size = 12410020 }, + { url = "https://files.pythonhosted.org/packages/46/8b/df49974b337cce35f828ba6fda228152d6db45fed4c86ba56ffe442434fd/mypy-1.15.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:1124a18bc11a6a62887e3e137f37f53fbae476dc36c185d549d4f837a2a6a14e", size = 12498582 }, + { url = "https://files.pythonhosted.org/packages/13/50/da5203fcf6c53044a0b699939f31075c45ae8a4cadf538a9069b165c1050/mypy-1.15.0-cp312-cp312-win_amd64.whl", hash = "sha256:171a9ca9a40cd1843abeca0e405bc1940cd9b305eaeea2dda769ba096932bb22", size = 9366614 }, + { url = "https://files.pythonhosted.org/packages/6a/9b/fd2e05d6ffff24d912f150b87db9e364fa8282045c875654ce7e32fffa66/mypy-1.15.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:93faf3fdb04768d44bf28693293f3904bbb555d076b781ad2530214ee53e3445", size = 10788592 }, + { url = "https://files.pythonhosted.org/packages/74/37/b246d711c28a03ead1fd906bbc7106659aed7c089d55fe40dd58db812628/mypy-1.15.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:811aeccadfb730024c5d3e326b2fbe9249bb7413553f15499a4050f7c30e801d", size = 9753611 }, + { url = "https://files.pythonhosted.org/packages/a6/ac/395808a92e10cfdac8003c3de9a2ab6dc7cde6c0d2a4df3df1b815ffd067/mypy-1.15.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:98b7b9b9aedb65fe628c62a6dc57f6d5088ef2dfca37903a7d9ee374d03acca5", size = 11438443 }, + { url = "https://files.pythonhosted.org/packages/d2/8b/801aa06445d2de3895f59e476f38f3f8d610ef5d6908245f07d002676cbf/mypy-1.15.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:c43a7682e24b4f576d93072216bf56eeff70d9140241f9edec0c104d0c515036", size = 12402541 }, + { url = "https://files.pythonhosted.org/packages/c7/67/5a4268782eb77344cc613a4cf23540928e41f018a9a1ec4c6882baf20ab8/mypy-1.15.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:baefc32840a9f00babd83251560e0ae1573e2f9d1b067719479bfb0e987c6357", size = 12494348 }, + { url = "https://files.pythonhosted.org/packages/83/3e/57bb447f7bbbfaabf1712d96f9df142624a386d98fb026a761532526057e/mypy-1.15.0-cp313-cp313-win_amd64.whl", hash = "sha256:b9378e2c00146c44793c98b8d5a61039a048e31f429fb0eb546d93f4b000bedf", size = 9373648 }, + { url = "https://files.pythonhosted.org/packages/5a/fa/79cf41a55b682794abe71372151dbbf856e3008f6767057229e6649d294a/mypy-1.15.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:e601a7fa172c2131bff456bb3ee08a88360760d0d2f8cbd7a75a65497e2df078", size = 10737129 }, + { url = "https://files.pythonhosted.org/packages/d3/33/dd8feb2597d648de29e3da0a8bf4e1afbda472964d2a4a0052203a6f3594/mypy-1.15.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:712e962a6357634fef20412699a3655c610110e01cdaa6180acec7fc9f8513ba", size = 9856335 }, + { url = "https://files.pythonhosted.org/packages/e4/b5/74508959c1b06b96674b364ffeb7ae5802646b32929b7701fc6b18447592/mypy-1.15.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:f95579473af29ab73a10bada2f9722856792a36ec5af5399b653aa28360290a5", size = 11611935 }, + { url = "https://files.pythonhosted.org/packages/6c/53/da61b9d9973efcd6507183fdad96606996191657fe79701b2c818714d573/mypy-1.15.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:8f8722560a14cde92fdb1e31597760dc35f9f5524cce17836c0d22841830fd5b", size = 12365827 }, + { url = "https://files.pythonhosted.org/packages/c1/72/965bd9ee89540c79a25778cc080c7e6ef40aa1eeac4d52cec7eae6eb5228/mypy-1.15.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:1fbb8da62dc352133d7d7ca90ed2fb0e9d42bb1a32724c287d3c76c58cbaa9c2", size = 12541924 }, + { url = "https://files.pythonhosted.org/packages/46/d0/f41645c2eb263e6c77ada7d76f894c580c9ddb20d77f0c24d34273a4dab2/mypy-1.15.0-cp39-cp39-win_amd64.whl", hash = "sha256:d10d994b41fb3497719bbf866f227b3489048ea4bbbb5015357db306249f7980", size = 9271176 }, + { url = "https://files.pythonhosted.org/packages/09/4e/a7d65c7322c510de2c409ff3828b03354a7c43f5a8ed458a7a131b41c7b9/mypy-1.15.0-py3-none-any.whl", hash = "sha256:5469affef548bd1895d86d3bf10ce2b44e33d86923c29e4d675b3e323437ea3e", size = 2221777 }, +] + +[[package]] +name = "mypy-extensions" +version = "1.0.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/98/a4/1ab47638b92648243faf97a5aeb6ea83059cc3624972ab6b8d2316078d3f/mypy_extensions-1.0.0.tar.gz", hash = "sha256:75dbf8955dc00442a438fc4d0666508a9a97b6bd41aa2f0ffe9d2f2725af0782", size = 4433 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/2a/e2/5d3f6ada4297caebe1a2add3b126fe800c96f56dbe5d1988a2cbe0b267aa/mypy_extensions-1.0.0-py3-none-any.whl", hash = "sha256:4392f6c0eb8a5668a69e23d168ffa70f0be9ccfd32b5cc2d26a34ae5b844552d", size = 4695 }, +] + +[[package]] +name = "numpy" +version = "2.0.2" +source = { registry = "https://pypi.org/simple" } +resolution-markers = [ + "python_full_version < '3.10'", +] +sdist = { url = "https://files.pythonhosted.org/packages/a9/75/10dd1f8116a8b796cb2c737b674e02d02e80454bda953fa7e65d8c12b016/numpy-2.0.2.tar.gz", hash = "sha256:883c987dee1880e2a864ab0dc9892292582510604156762362d9326444636e78", size = 18902015 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/21/91/3495b3237510f79f5d81f2508f9f13fea78ebfdf07538fc7444badda173d/numpy-2.0.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:51129a29dbe56f9ca83438b706e2e69a39892b5eda6cedcb6b0c9fdc9b0d3ece", size = 21165245 }, + { url = "https://files.pythonhosted.org/packages/05/33/26178c7d437a87082d11019292dce6d3fe6f0e9026b7b2309cbf3e489b1d/numpy-2.0.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:f15975dfec0cf2239224d80e32c3170b1d168335eaedee69da84fbe9f1f9cd04", size = 13738540 }, + { url = "https://files.pythonhosted.org/packages/ec/31/cc46e13bf07644efc7a4bf68df2df5fb2a1a88d0cd0da9ddc84dc0033e51/numpy-2.0.2-cp310-cp310-macosx_14_0_arm64.whl", hash = "sha256:8c5713284ce4e282544c68d1c3b2c7161d38c256d2eefc93c1d683cf47683e66", size = 5300623 }, + { url = "https://files.pythonhosted.org/packages/6e/16/7bfcebf27bb4f9d7ec67332ffebee4d1bf085c84246552d52dbb548600e7/numpy-2.0.2-cp310-cp310-macosx_14_0_x86_64.whl", hash = "sha256:becfae3ddd30736fe1889a37f1f580e245ba79a5855bff5f2a29cb3ccc22dd7b", size = 6901774 }, + { url = "https://files.pythonhosted.org/packages/f9/a3/561c531c0e8bf082c5bef509d00d56f82e0ea7e1e3e3a7fc8fa78742a6e5/numpy-2.0.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2da5960c3cf0df7eafefd806d4e612c5e19358de82cb3c343631188991566ccd", size = 13907081 }, + { url = "https://files.pythonhosted.org/packages/fa/66/f7177ab331876200ac7563a580140643d1179c8b4b6a6b0fc9838de2a9b8/numpy-2.0.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:496f71341824ed9f3d2fd36cf3ac57ae2e0165c143b55c3a035ee219413f3318", size = 19523451 }, + { url = "https://files.pythonhosted.org/packages/25/7f/0b209498009ad6453e4efc2c65bcdf0ae08a182b2b7877d7ab38a92dc542/numpy-2.0.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:a61ec659f68ae254e4d237816e33171497e978140353c0c2038d46e63282d0c8", size = 19927572 }, + { url = "https://files.pythonhosted.org/packages/3e/df/2619393b1e1b565cd2d4c4403bdd979621e2c4dea1f8532754b2598ed63b/numpy-2.0.2-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:d731a1c6116ba289c1e9ee714b08a8ff882944d4ad631fd411106a30f083c326", size = 14400722 }, + { url = "https://files.pythonhosted.org/packages/22/ad/77e921b9f256d5da36424ffb711ae79ca3f451ff8489eeca544d0701d74a/numpy-2.0.2-cp310-cp310-win32.whl", hash = "sha256:984d96121c9f9616cd33fbd0618b7f08e0cfc9600a7ee1d6fd9b239186d19d97", size = 6472170 }, + { url = "https://files.pythonhosted.org/packages/10/05/3442317535028bc29cf0c0dd4c191a4481e8376e9f0db6bcf29703cadae6/numpy-2.0.2-cp310-cp310-win_amd64.whl", hash = "sha256:c7b0be4ef08607dd04da4092faee0b86607f111d5ae68036f16cc787e250a131", size = 15905558 }, + { url = "https://files.pythonhosted.org/packages/8b/cf/034500fb83041aa0286e0fb16e7c76e5c8b67c0711bb6e9e9737a717d5fe/numpy-2.0.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:49ca4decb342d66018b01932139c0961a8f9ddc7589611158cb3c27cbcf76448", size = 21169137 }, + { url = "https://files.pythonhosted.org/packages/4a/d9/32de45561811a4b87fbdee23b5797394e3d1504b4a7cf40c10199848893e/numpy-2.0.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:11a76c372d1d37437857280aa142086476136a8c0f373b2e648ab2c8f18fb195", size = 13703552 }, + { url = "https://files.pythonhosted.org/packages/c1/ca/2f384720020c7b244d22508cb7ab23d95f179fcfff33c31a6eeba8d6c512/numpy-2.0.2-cp311-cp311-macosx_14_0_arm64.whl", hash = "sha256:807ec44583fd708a21d4a11d94aedf2f4f3c3719035c76a2bbe1fe8e217bdc57", size = 5298957 }, + { url = "https://files.pythonhosted.org/packages/0e/78/a3e4f9fb6aa4e6fdca0c5428e8ba039408514388cf62d89651aade838269/numpy-2.0.2-cp311-cp311-macosx_14_0_x86_64.whl", hash = "sha256:8cafab480740e22f8d833acefed5cc87ce276f4ece12fdaa2e8903db2f82897a", size = 6905573 }, + { url = "https://files.pythonhosted.org/packages/a0/72/cfc3a1beb2caf4efc9d0b38a15fe34025230da27e1c08cc2eb9bfb1c7231/numpy-2.0.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a15f476a45e6e5a3a79d8a14e62161d27ad897381fecfa4a09ed5322f2085669", size = 13914330 }, + { url = "https://files.pythonhosted.org/packages/ba/a8/c17acf65a931ce551fee11b72e8de63bf7e8a6f0e21add4c937c83563538/numpy-2.0.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:13e689d772146140a252c3a28501da66dfecd77490b498b168b501835041f951", size = 19534895 }, + { url = "https://files.pythonhosted.org/packages/ba/86/8767f3d54f6ae0165749f84648da9dcc8cd78ab65d415494962c86fac80f/numpy-2.0.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:9ea91dfb7c3d1c56a0e55657c0afb38cf1eeae4544c208dc465c3c9f3a7c09f9", size = 19937253 }, + { url = "https://files.pythonhosted.org/packages/df/87/f76450e6e1c14e5bb1eae6836478b1028e096fd02e85c1c37674606ab752/numpy-2.0.2-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:c1c9307701fec8f3f7a1e6711f9089c06e6284b3afbbcd259f7791282d660a15", size = 14414074 }, + { url = "https://files.pythonhosted.org/packages/5c/ca/0f0f328e1e59f73754f06e1adfb909de43726d4f24c6a3f8805f34f2b0fa/numpy-2.0.2-cp311-cp311-win32.whl", hash = "sha256:a392a68bd329eafac5817e5aefeb39038c48b671afd242710b451e76090e81f4", size = 6470640 }, + { url = "https://files.pythonhosted.org/packages/eb/57/3a3f14d3a759dcf9bf6e9eda905794726b758819df4663f217d658a58695/numpy-2.0.2-cp311-cp311-win_amd64.whl", hash = "sha256:286cd40ce2b7d652a6f22efdfc6d1edf879440e53e76a75955bc0c826c7e64dc", size = 15910230 }, + { url = "https://files.pythonhosted.org/packages/45/40/2e117be60ec50d98fa08c2f8c48e09b3edea93cfcabd5a9ff6925d54b1c2/numpy-2.0.2-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:df55d490dea7934f330006d0f81e8551ba6010a5bf035a249ef61a94f21c500b", size = 20895803 }, + { url = "https://files.pythonhosted.org/packages/46/92/1b8b8dee833f53cef3e0a3f69b2374467789e0bb7399689582314df02651/numpy-2.0.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:8df823f570d9adf0978347d1f926b2a867d5608f434a7cff7f7908c6570dcf5e", size = 13471835 }, + { url = "https://files.pythonhosted.org/packages/7f/19/e2793bde475f1edaea6945be141aef6c8b4c669b90c90a300a8954d08f0a/numpy-2.0.2-cp312-cp312-macosx_14_0_arm64.whl", hash = "sha256:9a92ae5c14811e390f3767053ff54eaee3bf84576d99a2456391401323f4ec2c", size = 5038499 }, + { url = "https://files.pythonhosted.org/packages/e3/ff/ddf6dac2ff0dd50a7327bcdba45cb0264d0e96bb44d33324853f781a8f3c/numpy-2.0.2-cp312-cp312-macosx_14_0_x86_64.whl", hash = "sha256:a842d573724391493a97a62ebbb8e731f8a5dcc5d285dfc99141ca15a3302d0c", size = 6633497 }, + { url = "https://files.pythonhosted.org/packages/72/21/67f36eac8e2d2cd652a2e69595a54128297cdcb1ff3931cfc87838874bd4/numpy-2.0.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c05e238064fc0610c840d1cf6a13bf63d7e391717d247f1bf0318172e759e692", size = 13621158 }, + { url = "https://files.pythonhosted.org/packages/39/68/e9f1126d757653496dbc096cb429014347a36b228f5a991dae2c6b6cfd40/numpy-2.0.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0123ffdaa88fa4ab64835dcbde75dcdf89c453c922f18dced6e27c90d1d0ec5a", size = 19236173 }, + { url = "https://files.pythonhosted.org/packages/d1/e9/1f5333281e4ebf483ba1c888b1d61ba7e78d7e910fdd8e6499667041cc35/numpy-2.0.2-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:96a55f64139912d61de9137f11bf39a55ec8faec288c75a54f93dfd39f7eb40c", size = 19634174 }, + { url = "https://files.pythonhosted.org/packages/71/af/a469674070c8d8408384e3012e064299f7a2de540738a8e414dcfd639996/numpy-2.0.2-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:ec9852fb39354b5a45a80bdab5ac02dd02b15f44b3804e9f00c556bf24b4bded", size = 14099701 }, + { url = "https://files.pythonhosted.org/packages/d0/3d/08ea9f239d0e0e939b6ca52ad403c84a2bce1bde301a8eb4888c1c1543f1/numpy-2.0.2-cp312-cp312-win32.whl", hash = "sha256:671bec6496f83202ed2d3c8fdc486a8fc86942f2e69ff0e986140339a63bcbe5", size = 6174313 }, + { url = "https://files.pythonhosted.org/packages/b2/b5/4ac39baebf1fdb2e72585c8352c56d063b6126be9fc95bd2bb5ef5770c20/numpy-2.0.2-cp312-cp312-win_amd64.whl", hash = "sha256:cfd41e13fdc257aa5778496b8caa5e856dc4896d4ccf01841daee1d96465467a", size = 15606179 }, + { url = "https://files.pythonhosted.org/packages/43/c1/41c8f6df3162b0c6ffd4437d729115704bd43363de0090c7f913cfbc2d89/numpy-2.0.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:9059e10581ce4093f735ed23f3b9d283b9d517ff46009ddd485f1747eb22653c", size = 21169942 }, + { url = "https://files.pythonhosted.org/packages/39/bc/fd298f308dcd232b56a4031fd6ddf11c43f9917fbc937e53762f7b5a3bb1/numpy-2.0.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:423e89b23490805d2a5a96fe40ec507407b8ee786d66f7328be214f9679df6dd", size = 13711512 }, + { url = "https://files.pythonhosted.org/packages/96/ff/06d1aa3eeb1c614eda245c1ba4fb88c483bee6520d361641331872ac4b82/numpy-2.0.2-cp39-cp39-macosx_14_0_arm64.whl", hash = "sha256:2b2955fa6f11907cf7a70dab0d0755159bca87755e831e47932367fc8f2f2d0b", size = 5306976 }, + { url = "https://files.pythonhosted.org/packages/2d/98/121996dcfb10a6087a05e54453e28e58694a7db62c5a5a29cee14c6e047b/numpy-2.0.2-cp39-cp39-macosx_14_0_x86_64.whl", hash = "sha256:97032a27bd9d8988b9a97a8c4d2c9f2c15a81f61e2f21404d7e8ef00cb5be729", size = 6906494 }, + { url = "https://files.pythonhosted.org/packages/15/31/9dffc70da6b9bbf7968f6551967fc21156207366272c2a40b4ed6008dc9b/numpy-2.0.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1e795a8be3ddbac43274f18588329c72939870a16cae810c2b73461c40718ab1", size = 13912596 }, + { url = "https://files.pythonhosted.org/packages/b9/14/78635daab4b07c0930c919d451b8bf8c164774e6a3413aed04a6d95758ce/numpy-2.0.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f26b258c385842546006213344c50655ff1555a9338e2e5e02a0756dc3e803dd", size = 19526099 }, + { url = "https://files.pythonhosted.org/packages/26/4c/0eeca4614003077f68bfe7aac8b7496f04221865b3a5e7cb230c9d055afd/numpy-2.0.2-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:5fec9451a7789926bcf7c2b8d187292c9f93ea30284802a0ab3f5be8ab36865d", size = 19932823 }, + { url = "https://files.pythonhosted.org/packages/f1/46/ea25b98b13dccaebddf1a803f8c748680d972e00507cd9bc6dcdb5aa2ac1/numpy-2.0.2-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:9189427407d88ff25ecf8f12469d4d39d35bee1db5d39fc5c168c6f088a6956d", size = 14404424 }, + { url = "https://files.pythonhosted.org/packages/c8/a6/177dd88d95ecf07e722d21008b1b40e681a929eb9e329684d449c36586b2/numpy-2.0.2-cp39-cp39-win32.whl", hash = "sha256:905d16e0c60200656500c95b6b8dca5d109e23cb24abc701d41c02d74c6b3afa", size = 6476809 }, + { url = "https://files.pythonhosted.org/packages/ea/2b/7fc9f4e7ae5b507c1a3a21f0f15ed03e794c1242ea8a242ac158beb56034/numpy-2.0.2-cp39-cp39-win_amd64.whl", hash = "sha256:a3f4ab0caa7f053f6797fcd4e1e25caee367db3112ef2b6ef82d749530768c73", size = 15911314 }, + { url = "https://files.pythonhosted.org/packages/8f/3b/df5a870ac6a3be3a86856ce195ef42eec7ae50d2a202be1f5a4b3b340e14/numpy-2.0.2-pp39-pypy39_pp73-macosx_10_9_x86_64.whl", hash = "sha256:7f0a0c6f12e07fa94133c8a67404322845220c06a9e80e85999afe727f7438b8", size = 21025288 }, + { url = "https://files.pythonhosted.org/packages/2c/97/51af92f18d6f6f2d9ad8b482a99fb74e142d71372da5d834b3a2747a446e/numpy-2.0.2-pp39-pypy39_pp73-macosx_14_0_x86_64.whl", hash = "sha256:312950fdd060354350ed123c0e25a71327d3711584beaef30cdaa93320c392d4", size = 6762793 }, + { url = "https://files.pythonhosted.org/packages/12/46/de1fbd0c1b5ccaa7f9a005b66761533e2f6a3e560096682683a223631fe9/numpy-2.0.2-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:26df23238872200f63518dd2aa984cfca675d82469535dc7162dc2ee52d9dd5c", size = 19334885 }, + { url = "https://files.pythonhosted.org/packages/cc/dc/d330a6faefd92b446ec0f0dfea4c3207bb1fef3c4771d19cf4543efd2c78/numpy-2.0.2-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:a46288ec55ebbd58947d31d72be2c63cbf839f0a63b49cb755022310792a3385", size = 15828784 }, +] + +[[package]] +name = "numpy" +version = "2.2.4" +source = { registry = "https://pypi.org/simple" } +resolution-markers = [ + "python_full_version >= '3.12'", + "python_full_version == '3.11.*'", + "python_full_version == '3.10.*'", +] +sdist = { url = "https://files.pythonhosted.org/packages/e1/78/31103410a57bc2c2b93a3597340a8119588571f6a4539067546cb9a0bfac/numpy-2.2.4.tar.gz", hash = "sha256:9ba03692a45d3eef66559efe1d1096c4b9b75c0986b5dff5530c378fb8331d4f", size = 20270701 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/04/89/a79e86e5c1433926ed7d60cb267fb64aa578b6101ab645800fd43b4801de/numpy-2.2.4-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:8146f3550d627252269ac42ae660281d673eb6f8b32f113538e0cc2a9aed42b9", size = 21250661 }, + { url = "https://files.pythonhosted.org/packages/79/c2/f50921beb8afd60ed9589ad880332cfefdb805422210d327fb48f12b7a81/numpy-2.2.4-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:e642d86b8f956098b564a45e6f6ce68a22c2c97a04f5acd3f221f57b8cb850ae", size = 14389926 }, + { url = "https://files.pythonhosted.org/packages/c7/b9/2c4e96130b0b0f97b0ef4a06d6dae3b39d058b21a5e2fa2decd7fd6b1c8f/numpy-2.2.4-cp310-cp310-macosx_14_0_arm64.whl", hash = "sha256:a84eda42bd12edc36eb5b53bbcc9b406820d3353f1994b6cfe453a33ff101775", size = 5428329 }, + { url = "https://files.pythonhosted.org/packages/7f/a5/3d7094aa898f4fc5c84cdfb26beeae780352d43f5d8bdec966c4393d644c/numpy-2.2.4-cp310-cp310-macosx_14_0_x86_64.whl", hash = "sha256:4ba5054787e89c59c593a4169830ab362ac2bee8a969249dc56e5d7d20ff8df9", size = 6963559 }, + { url = "https://files.pythonhosted.org/packages/4c/22/fb1be710a14434c09080dd4a0acc08939f612ec02efcb04b9e210474782d/numpy-2.2.4-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7716e4a9b7af82c06a2543c53ca476fa0b57e4d760481273e09da04b74ee6ee2", size = 14368066 }, + { url = "https://files.pythonhosted.org/packages/c2/07/2e5cc71193e3ef3a219ffcf6ca4858e46ea2be09c026ddd480d596b32867/numpy-2.2.4-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:adf8c1d66f432ce577d0197dceaac2ac00c0759f573f28516246351c58a85020", size = 16417040 }, + { url = "https://files.pythonhosted.org/packages/1a/97/3b1537776ad9a6d1a41813818343745e8dd928a2916d4c9edcd9a8af1dac/numpy-2.2.4-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:218f061d2faa73621fa23d6359442b0fc658d5b9a70801373625d958259eaca3", size = 15879862 }, + { url = "https://files.pythonhosted.org/packages/b0/b7/4472f603dd45ef36ff3d8e84e84fe02d9467c78f92cc121633dce6da307b/numpy-2.2.4-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:df2f57871a96bbc1b69733cd4c51dc33bea66146b8c63cacbfed73eec0883017", size = 18206032 }, + { url = "https://files.pythonhosted.org/packages/0d/bd/6a092963fb82e6c5aa0d0440635827bbb2910da229545473bbb58c537ed3/numpy-2.2.4-cp310-cp310-win32.whl", hash = "sha256:a0258ad1f44f138b791327961caedffbf9612bfa504ab9597157806faa95194a", size = 6608517 }, + { url = "https://files.pythonhosted.org/packages/01/e3/cb04627bc2a1638948bc13e818df26495aa18e20d5be1ed95ab2b10b6847/numpy-2.2.4-cp310-cp310-win_amd64.whl", hash = "sha256:0d54974f9cf14acf49c60f0f7f4084b6579d24d439453d5fc5805d46a165b542", size = 12943498 }, + { url = "https://files.pythonhosted.org/packages/16/fb/09e778ee3a8ea0d4dc8329cca0a9c9e65fed847d08e37eba74cb7ed4b252/numpy-2.2.4-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:e9e0a277bb2eb5d8a7407e14688b85fd8ad628ee4e0c7930415687b6564207a4", size = 21254989 }, + { url = "https://files.pythonhosted.org/packages/a2/0a/1212befdbecab5d80eca3cde47d304cad986ad4eec7d85a42e0b6d2cc2ef/numpy-2.2.4-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:9eeea959168ea555e556b8188da5fa7831e21d91ce031e95ce23747b7609f8a4", size = 14425910 }, + { url = "https://files.pythonhosted.org/packages/2b/3e/e7247c1d4f15086bb106c8d43c925b0b2ea20270224f5186fa48d4fb5cbd/numpy-2.2.4-cp311-cp311-macosx_14_0_arm64.whl", hash = "sha256:bd3ad3b0a40e713fc68f99ecfd07124195333f1e689387c180813f0e94309d6f", size = 5426490 }, + { url = "https://files.pythonhosted.org/packages/5d/fa/aa7cd6be51419b894c5787a8a93c3302a1ed4f82d35beb0613ec15bdd0e2/numpy-2.2.4-cp311-cp311-macosx_14_0_x86_64.whl", hash = "sha256:cf28633d64294969c019c6df4ff37f5698e8326db68cc2b66576a51fad634880", size = 6967754 }, + { url = "https://files.pythonhosted.org/packages/d5/ee/96457c943265de9fadeb3d2ffdbab003f7fba13d971084a9876affcda095/numpy-2.2.4-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2fa8fa7697ad1646b5c93de1719965844e004fcad23c91228aca1cf0800044a1", size = 14373079 }, + { url = "https://files.pythonhosted.org/packages/c5/5c/ceefca458559f0ccc7a982319f37ed07b0d7b526964ae6cc61f8ad1b6119/numpy-2.2.4-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f4162988a360a29af158aeb4a2f4f09ffed6a969c9776f8f3bdee9b06a8ab7e5", size = 16428819 }, + { url = "https://files.pythonhosted.org/packages/22/31/9b2ac8eee99e001eb6add9fa27514ef5e9faf176169057a12860af52704c/numpy-2.2.4-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:892c10d6a73e0f14935c31229e03325a7b3093fafd6ce0af704be7f894d95687", size = 15881470 }, + { url = "https://files.pythonhosted.org/packages/f0/dc/8569b5f25ff30484b555ad8a3f537e0225d091abec386c9420cf5f7a2976/numpy-2.2.4-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:db1f1c22173ac1c58db249ae48aa7ead29f534b9a948bc56828337aa84a32ed6", size = 18218144 }, + { url = "https://files.pythonhosted.org/packages/5e/05/463c023a39bdeb9bb43a99e7dee2c664cb68d5bb87d14f92482b9f6011cc/numpy-2.2.4-cp311-cp311-win32.whl", hash = "sha256:ea2bb7e2ae9e37d96835b3576a4fa4b3a97592fbea8ef7c3587078b0068b8f09", size = 6606368 }, + { url = "https://files.pythonhosted.org/packages/8b/72/10c1d2d82101c468a28adc35de6c77b308f288cfd0b88e1070f15b98e00c/numpy-2.2.4-cp311-cp311-win_amd64.whl", hash = "sha256:f7de08cbe5551911886d1ab60de58448c6df0f67d9feb7d1fb21e9875ef95e91", size = 12947526 }, + { url = "https://files.pythonhosted.org/packages/a2/30/182db21d4f2a95904cec1a6f779479ea1ac07c0647f064dea454ec650c42/numpy-2.2.4-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:a7b9084668aa0f64e64bd00d27ba5146ef1c3a8835f3bd912e7a9e01326804c4", size = 20947156 }, + { url = "https://files.pythonhosted.org/packages/24/6d/9483566acfbda6c62c6bc74b6e981c777229d2af93c8eb2469b26ac1b7bc/numpy-2.2.4-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:dbe512c511956b893d2dacd007d955a3f03d555ae05cfa3ff1c1ff6df8851854", size = 14133092 }, + { url = "https://files.pythonhosted.org/packages/27/f6/dba8a258acbf9d2bed2525cdcbb9493ef9bae5199d7a9cb92ee7e9b2aea6/numpy-2.2.4-cp312-cp312-macosx_14_0_arm64.whl", hash = "sha256:bb649f8b207ab07caebba230d851b579a3c8711a851d29efe15008e31bb4de24", size = 5163515 }, + { url = "https://files.pythonhosted.org/packages/62/30/82116199d1c249446723c68f2c9da40d7f062551036f50b8c4caa42ae252/numpy-2.2.4-cp312-cp312-macosx_14_0_x86_64.whl", hash = "sha256:f34dc300df798742b3d06515aa2a0aee20941c13579d7a2f2e10af01ae4901ee", size = 6696558 }, + { url = "https://files.pythonhosted.org/packages/0e/b2/54122b3c6df5df3e87582b2e9430f1bdb63af4023c739ba300164c9ae503/numpy-2.2.4-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c3f7ac96b16955634e223b579a3e5798df59007ca43e8d451a0e6a50f6bfdfba", size = 14084742 }, + { url = "https://files.pythonhosted.org/packages/02/e2/e2cbb8d634151aab9528ef7b8bab52ee4ab10e076509285602c2a3a686e0/numpy-2.2.4-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4f92084defa704deadd4e0a5ab1dc52d8ac9e8a8ef617f3fbb853e79b0ea3592", size = 16134051 }, + { url = "https://files.pythonhosted.org/packages/8e/21/efd47800e4affc993e8be50c1b768de038363dd88865920439ef7b422c60/numpy-2.2.4-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:7a4e84a6283b36632e2a5b56e121961f6542ab886bc9e12f8f9818b3c266bfbb", size = 15578972 }, + { url = "https://files.pythonhosted.org/packages/04/1e/f8bb88f6157045dd5d9b27ccf433d016981032690969aa5c19e332b138c0/numpy-2.2.4-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:11c43995255eb4127115956495f43e9343736edb7fcdb0d973defd9de14cd84f", size = 17898106 }, + { url = "https://files.pythonhosted.org/packages/2b/93/df59a5a3897c1f036ae8ff845e45f4081bb06943039ae28a3c1c7c780f22/numpy-2.2.4-cp312-cp312-win32.whl", hash = "sha256:65ef3468b53269eb5fdb3a5c09508c032b793da03251d5f8722b1194f1790c00", size = 6311190 }, + { url = "https://files.pythonhosted.org/packages/46/69/8c4f928741c2a8efa255fdc7e9097527c6dc4e4df147e3cadc5d9357ce85/numpy-2.2.4-cp312-cp312-win_amd64.whl", hash = "sha256:2aad3c17ed2ff455b8eaafe06bcdae0062a1db77cb99f4b9cbb5f4ecb13c5146", size = 12644305 }, + { url = "https://files.pythonhosted.org/packages/2a/d0/bd5ad792e78017f5decfb2ecc947422a3669a34f775679a76317af671ffc/numpy-2.2.4-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:1cf4e5c6a278d620dee9ddeb487dc6a860f9b199eadeecc567f777daace1e9e7", size = 20933623 }, + { url = "https://files.pythonhosted.org/packages/c3/bc/2b3545766337b95409868f8e62053135bdc7fa2ce630aba983a2aa60b559/numpy-2.2.4-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:1974afec0b479e50438fc3648974268f972e2d908ddb6d7fb634598cdb8260a0", size = 14148681 }, + { url = "https://files.pythonhosted.org/packages/6a/70/67b24d68a56551d43a6ec9fe8c5f91b526d4c1a46a6387b956bf2d64744e/numpy-2.2.4-cp313-cp313-macosx_14_0_arm64.whl", hash = "sha256:79bd5f0a02aa16808fcbc79a9a376a147cc1045f7dfe44c6e7d53fa8b8a79392", size = 5148759 }, + { url = "https://files.pythonhosted.org/packages/1c/8b/e2fc8a75fcb7be12d90b31477c9356c0cbb44abce7ffb36be39a0017afad/numpy-2.2.4-cp313-cp313-macosx_14_0_x86_64.whl", hash = "sha256:3387dd7232804b341165cedcb90694565a6015433ee076c6754775e85d86f1fc", size = 6683092 }, + { url = "https://files.pythonhosted.org/packages/13/73/41b7b27f169ecf368b52533edb72e56a133f9e86256e809e169362553b49/numpy-2.2.4-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6f527d8fdb0286fd2fd97a2a96c6be17ba4232da346931d967a0630050dfd298", size = 14081422 }, + { url = "https://files.pythonhosted.org/packages/4b/04/e208ff3ae3ddfbafc05910f89546382f15a3f10186b1f56bd99f159689c2/numpy-2.2.4-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bce43e386c16898b91e162e5baaad90c4b06f9dcbe36282490032cec98dc8ae7", size = 16132202 }, + { url = "https://files.pythonhosted.org/packages/fe/bc/2218160574d862d5e55f803d88ddcad88beff94791f9c5f86d67bd8fbf1c/numpy-2.2.4-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:31504f970f563d99f71a3512d0c01a645b692b12a63630d6aafa0939e52361e6", size = 15573131 }, + { url = "https://files.pythonhosted.org/packages/a5/78/97c775bc4f05abc8a8426436b7cb1be806a02a2994b195945600855e3a25/numpy-2.2.4-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:81413336ef121a6ba746892fad881a83351ee3e1e4011f52e97fba79233611fd", size = 17894270 }, + { url = "https://files.pythonhosted.org/packages/b9/eb/38c06217a5f6de27dcb41524ca95a44e395e6a1decdc0c99fec0832ce6ae/numpy-2.2.4-cp313-cp313-win32.whl", hash = "sha256:f486038e44caa08dbd97275a9a35a283a8f1d2f0ee60ac260a1790e76660833c", size = 6308141 }, + { url = "https://files.pythonhosted.org/packages/52/17/d0dd10ab6d125c6d11ffb6dfa3423c3571befab8358d4f85cd4471964fcd/numpy-2.2.4-cp313-cp313-win_amd64.whl", hash = "sha256:207a2b8441cc8b6a2a78c9ddc64d00d20c303d79fba08c577752f080c4007ee3", size = 12636885 }, + { url = "https://files.pythonhosted.org/packages/fa/e2/793288ede17a0fdc921172916efb40f3cbc2aa97e76c5c84aba6dc7e8747/numpy-2.2.4-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:8120575cb4882318c791f839a4fd66161a6fa46f3f0a5e613071aae35b5dd8f8", size = 20961829 }, + { url = "https://files.pythonhosted.org/packages/3a/75/bb4573f6c462afd1ea5cbedcc362fe3e9bdbcc57aefd37c681be1155fbaa/numpy-2.2.4-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:a761ba0fa886a7bb33c6c8f6f20213735cb19642c580a931c625ee377ee8bd39", size = 14161419 }, + { url = "https://files.pythonhosted.org/packages/03/68/07b4cd01090ca46c7a336958b413cdbe75002286295f2addea767b7f16c9/numpy-2.2.4-cp313-cp313t-macosx_14_0_arm64.whl", hash = "sha256:ac0280f1ba4a4bfff363a99a6aceed4f8e123f8a9b234c89140f5e894e452ecd", size = 5196414 }, + { url = "https://files.pythonhosted.org/packages/a5/fd/d4a29478d622fedff5c4b4b4cedfc37a00691079623c0575978d2446db9e/numpy-2.2.4-cp313-cp313t-macosx_14_0_x86_64.whl", hash = "sha256:879cf3a9a2b53a4672a168c21375166171bc3932b7e21f622201811c43cdd3b0", size = 6709379 }, + { url = "https://files.pythonhosted.org/packages/41/78/96dddb75bb9be730b87c72f30ffdd62611aba234e4e460576a068c98eff6/numpy-2.2.4-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f05d4198c1bacc9124018109c5fba2f3201dbe7ab6e92ff100494f236209c960", size = 14051725 }, + { url = "https://files.pythonhosted.org/packages/00/06/5306b8199bffac2a29d9119c11f457f6c7d41115a335b78d3f86fad4dbe8/numpy-2.2.4-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e2f085ce2e813a50dfd0e01fbfc0c12bbe5d2063d99f8b29da30e544fb6483b8", size = 16101638 }, + { url = "https://files.pythonhosted.org/packages/fa/03/74c5b631ee1ded596945c12027649e6344614144369fd3ec1aaced782882/numpy-2.2.4-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:92bda934a791c01d6d9d8e038363c50918ef7c40601552a58ac84c9613a665bc", size = 15571717 }, + { url = "https://files.pythonhosted.org/packages/cb/dc/4fc7c0283abe0981e3b89f9b332a134e237dd476b0c018e1e21083310c31/numpy-2.2.4-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:ee4d528022f4c5ff67332469e10efe06a267e32f4067dc76bb7e2cddf3cd25ff", size = 17879998 }, + { url = "https://files.pythonhosted.org/packages/e5/2b/878576190c5cfa29ed896b518cc516aecc7c98a919e20706c12480465f43/numpy-2.2.4-cp313-cp313t-win32.whl", hash = "sha256:05c076d531e9998e7e694c36e8b349969c56eadd2cdcd07242958489d79a7286", size = 6366896 }, + { url = "https://files.pythonhosted.org/packages/3e/05/eb7eec66b95cf697f08c754ef26c3549d03ebd682819f794cb039574a0a6/numpy-2.2.4-cp313-cp313t-win_amd64.whl", hash = "sha256:188dcbca89834cc2e14eb2f106c96d6d46f200fe0200310fc29089657379c58d", size = 12739119 }, + { url = "https://files.pythonhosted.org/packages/b2/5c/f09c33a511aff41a098e6ef3498465d95f6360621034a3d95f47edbc9119/numpy-2.2.4-pp310-pypy310_pp73-macosx_10_15_x86_64.whl", hash = "sha256:7051ee569db5fbac144335e0f3b9c2337e0c8d5c9fee015f259a5bd70772b7e8", size = 21081956 }, + { url = "https://files.pythonhosted.org/packages/ba/30/74c48b3b6494c4b820b7fa1781d441e94d87a08daa5b35d222f06ba41a6f/numpy-2.2.4-pp310-pypy310_pp73-macosx_14_0_x86_64.whl", hash = "sha256:ab2939cd5bec30a7430cbdb2287b63151b77cf9624de0532d629c9a1c59b1d5c", size = 6827143 }, + { url = "https://files.pythonhosted.org/packages/54/f5/ab0d2f48b490535c7a80e05da4a98902b632369efc04f0e47bb31ca97d8f/numpy-2.2.4-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d0f35b19894a9e08639fd60a1ec1978cb7f5f7f1eace62f38dd36be8aecdef4d", size = 16233350 }, + { url = "https://files.pythonhosted.org/packages/3b/3a/2f6d8c1f8e45d496bca6baaec93208035faeb40d5735c25afac092ec9a12/numpy-2.2.4-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:b4adfbbc64014976d2f91084915ca4e626fbf2057fb81af209c1a6d776d23e3d", size = 12857565 }, +] + +[[package]] +name = "open-ephys-python-tools" +source = { editable = "." } +dependencies = [ + { name = "h5py" }, + { name = "numpy", version = "2.0.2", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.10'" }, + { name = "numpy", version = "2.2.4", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.10'" }, + { name = "pandas" }, + { name = "requests" }, + { name = "zmq" }, +] + +[package.dev-dependencies] +dev = [ + { name = "black" }, + { name = "jsonschema" }, + { name = "mypy" }, + { name = "pytest" }, +] + +[package.metadata] +requires-dist = [ + { name = "h5py" }, + { name = "numpy" }, + { name = "pandas" }, + { name = "requests" }, + { name = "zmq" }, +] + +[package.metadata.requires-dev] +dev = [ + { name = "black", specifier = ">=25.1.0" }, + { name = "jsonschema", specifier = ">=4.23.0" }, + { name = "mypy", specifier = ">=1.15.0" }, + { name = "pytest", specifier = ">=8.3.5" }, +] + +[[package]] +name = "packaging" +version = "24.2" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/d0/63/68dbb6eb2de9cb10ee4c9c14a0148804425e13c4fb20d61cce69f53106da/packaging-24.2.tar.gz", hash = "sha256:c228a6dc5e932d346bc5739379109d49e8853dd8223571c7c5b55260edc0b97f", size = 163950 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/88/ef/eb23f262cca3c0c4eb7ab1933c3b1f03d021f2c48f54763065b6f0e321be/packaging-24.2-py3-none-any.whl", hash = "sha256:09abb1bccd265c01f4a3aa3f7a7db064b36514d2cba19a2f694fe6150451a759", size = 65451 }, +] + +[[package]] +name = "pandas" +version = "2.2.3" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "numpy", version = "2.0.2", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.10'" }, + { name = "numpy", version = "2.2.4", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.10'" }, + { name = "python-dateutil" }, + { name = "pytz" }, + { name = "tzdata" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/9c/d6/9f8431bacc2e19dca897724cd097b1bb224a6ad5433784a44b587c7c13af/pandas-2.2.3.tar.gz", hash = "sha256:4f18ba62b61d7e192368b84517265a99b4d7ee8912f8708660fb4a366cc82667", size = 4399213 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/aa/70/c853aec59839bceed032d52010ff5f1b8d87dc3114b762e4ba2727661a3b/pandas-2.2.3-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:1948ddde24197a0f7add2bdc4ca83bf2b1ef84a1bc8ccffd95eda17fd836ecb5", size = 12580827 }, + { url = "https://files.pythonhosted.org/packages/99/f2/c4527768739ffa4469b2b4fff05aa3768a478aed89a2f271a79a40eee984/pandas-2.2.3-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:381175499d3802cde0eabbaf6324cce0c4f5d52ca6f8c377c29ad442f50f6348", size = 11303897 }, + { url = "https://files.pythonhosted.org/packages/ed/12/86c1747ea27989d7a4064f806ce2bae2c6d575b950be087837bdfcabacc9/pandas-2.2.3-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:d9c45366def9a3dd85a6454c0e7908f2b3b8e9c138f5dc38fed7ce720d8453ed", size = 66480908 }, + { url = "https://files.pythonhosted.org/packages/44/50/7db2cd5e6373ae796f0ddad3675268c8d59fb6076e66f0c339d61cea886b/pandas-2.2.3-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:86976a1c5b25ae3f8ccae3a5306e443569ee3c3faf444dfd0f41cda24667ad57", size = 13064210 }, + { url = "https://files.pythonhosted.org/packages/61/61/a89015a6d5536cb0d6c3ba02cebed51a95538cf83472975275e28ebf7d0c/pandas-2.2.3-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:b8661b0238a69d7aafe156b7fa86c44b881387509653fdf857bebc5e4008ad42", size = 16754292 }, + { url = "https://files.pythonhosted.org/packages/ce/0d/4cc7b69ce37fac07645a94e1d4b0880b15999494372c1523508511b09e40/pandas-2.2.3-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:37e0aced3e8f539eccf2e099f65cdb9c8aa85109b0be6e93e2baff94264bdc6f", size = 14416379 }, + { url = "https://files.pythonhosted.org/packages/31/9e/6ebb433de864a6cd45716af52a4d7a8c3c9aaf3a98368e61db9e69e69a9c/pandas-2.2.3-cp310-cp310-win_amd64.whl", hash = "sha256:56534ce0746a58afaf7942ba4863e0ef81c9c50d3f0ae93e9497d6a41a057645", size = 11598471 }, + { url = "https://files.pythonhosted.org/packages/a8/44/d9502bf0ed197ba9bf1103c9867d5904ddcaf869e52329787fc54ed70cc8/pandas-2.2.3-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:66108071e1b935240e74525006034333f98bcdb87ea116de573a6a0dccb6c039", size = 12602222 }, + { url = "https://files.pythonhosted.org/packages/52/11/9eac327a38834f162b8250aab32a6781339c69afe7574368fffe46387edf/pandas-2.2.3-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:7c2875855b0ff77b2a64a0365e24455d9990730d6431b9e0ee18ad8acee13dbd", size = 11321274 }, + { url = "https://files.pythonhosted.org/packages/45/fb/c4beeb084718598ba19aa9f5abbc8aed8b42f90930da861fcb1acdb54c3a/pandas-2.2.3-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:cd8d0c3be0515c12fed0bdbae072551c8b54b7192c7b1fda0ba56059a0179698", size = 15579836 }, + { url = "https://files.pythonhosted.org/packages/cd/5f/4dba1d39bb9c38d574a9a22548c540177f78ea47b32f99c0ff2ec499fac5/pandas-2.2.3-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c124333816c3a9b03fbeef3a9f230ba9a737e9e5bb4060aa2107a86cc0a497fc", size = 13058505 }, + { url = "https://files.pythonhosted.org/packages/b9/57/708135b90391995361636634df1f1130d03ba456e95bcf576fada459115a/pandas-2.2.3-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:63cc132e40a2e084cf01adf0775b15ac515ba905d7dcca47e9a251819c575ef3", size = 16744420 }, + { url = "https://files.pythonhosted.org/packages/86/4a/03ed6b7ee323cf30404265c284cee9c65c56a212e0a08d9ee06984ba2240/pandas-2.2.3-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:29401dbfa9ad77319367d36940cd8a0b3a11aba16063e39632d98b0e931ddf32", size = 14440457 }, + { url = "https://files.pythonhosted.org/packages/ed/8c/87ddf1fcb55d11f9f847e3c69bb1c6f8e46e2f40ab1a2d2abadb2401b007/pandas-2.2.3-cp311-cp311-win_amd64.whl", hash = "sha256:3fc6873a41186404dad67245896a6e440baacc92f5b716ccd1bc9ed2995ab2c5", size = 11617166 }, + { url = "https://files.pythonhosted.org/packages/17/a3/fb2734118db0af37ea7433f57f722c0a56687e14b14690edff0cdb4b7e58/pandas-2.2.3-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:b1d432e8d08679a40e2a6d8b2f9770a5c21793a6f9f47fdd52c5ce1948a5a8a9", size = 12529893 }, + { url = "https://files.pythonhosted.org/packages/e1/0c/ad295fd74bfac85358fd579e271cded3ac969de81f62dd0142c426b9da91/pandas-2.2.3-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:a5a1595fe639f5988ba6a8e5bc9649af3baf26df3998a0abe56c02609392e0a4", size = 11363475 }, + { url = "https://files.pythonhosted.org/packages/c6/2a/4bba3f03f7d07207481fed47f5b35f556c7441acddc368ec43d6643c5777/pandas-2.2.3-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:5de54125a92bb4d1c051c0659e6fcb75256bf799a732a87184e5ea503965bce3", size = 15188645 }, + { url = "https://files.pythonhosted.org/packages/38/f8/d8fddee9ed0d0c0f4a2132c1dfcf0e3e53265055da8df952a53e7eaf178c/pandas-2.2.3-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fffb8ae78d8af97f849404f21411c95062db1496aeb3e56f146f0355c9989319", size = 12739445 }, + { url = "https://files.pythonhosted.org/packages/20/e8/45a05d9c39d2cea61ab175dbe6a2de1d05b679e8de2011da4ee190d7e748/pandas-2.2.3-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:6dfcb5ee8d4d50c06a51c2fffa6cff6272098ad6540aed1a76d15fb9318194d8", size = 16359235 }, + { url = "https://files.pythonhosted.org/packages/1d/99/617d07a6a5e429ff90c90da64d428516605a1ec7d7bea494235e1c3882de/pandas-2.2.3-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:062309c1b9ea12a50e8ce661145c6aab431b1e99530d3cd60640e255778bd43a", size = 14056756 }, + { url = "https://files.pythonhosted.org/packages/29/d4/1244ab8edf173a10fd601f7e13b9566c1b525c4f365d6bee918e68381889/pandas-2.2.3-cp312-cp312-win_amd64.whl", hash = "sha256:59ef3764d0fe818125a5097d2ae867ca3fa64df032331b7e0917cf5d7bf66b13", size = 11504248 }, + { url = "https://files.pythonhosted.org/packages/64/22/3b8f4e0ed70644e85cfdcd57454686b9057c6c38d2f74fe4b8bc2527214a/pandas-2.2.3-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:f00d1345d84d8c86a63e476bb4955e46458b304b9575dcf71102b5c705320015", size = 12477643 }, + { url = "https://files.pythonhosted.org/packages/e4/93/b3f5d1838500e22c8d793625da672f3eec046b1a99257666c94446969282/pandas-2.2.3-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:3508d914817e153ad359d7e069d752cdd736a247c322d932eb89e6bc84217f28", size = 11281573 }, + { url = "https://files.pythonhosted.org/packages/f5/94/6c79b07f0e5aab1dcfa35a75f4817f5c4f677931d4234afcd75f0e6a66ca/pandas-2.2.3-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:22a9d949bfc9a502d320aa04e5d02feab689d61da4e7764b62c30b991c42c5f0", size = 15196085 }, + { url = "https://files.pythonhosted.org/packages/e8/31/aa8da88ca0eadbabd0a639788a6da13bb2ff6edbbb9f29aa786450a30a91/pandas-2.2.3-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f3a255b2c19987fbbe62a9dfd6cff7ff2aa9ccab3fc75218fd4b7530f01efa24", size = 12711809 }, + { url = "https://files.pythonhosted.org/packages/ee/7c/c6dbdb0cb2a4344cacfb8de1c5808ca885b2e4dcfde8008266608f9372af/pandas-2.2.3-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:800250ecdadb6d9c78eae4990da62743b857b470883fa27f652db8bdde7f6659", size = 16356316 }, + { url = "https://files.pythonhosted.org/packages/57/b7/8b757e7d92023b832869fa8881a992696a0bfe2e26f72c9ae9f255988d42/pandas-2.2.3-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:6374c452ff3ec675a8f46fd9ab25c4ad0ba590b71cf0656f8b6daa5202bca3fb", size = 14022055 }, + { url = "https://files.pythonhosted.org/packages/3b/bc/4b18e2b8c002572c5a441a64826252ce5da2aa738855747247a971988043/pandas-2.2.3-cp313-cp313-win_amd64.whl", hash = "sha256:61c5ad4043f791b61dd4752191d9f07f0ae412515d59ba8f005832a532f8736d", size = 11481175 }, + { url = "https://files.pythonhosted.org/packages/76/a3/a5d88146815e972d40d19247b2c162e88213ef51c7c25993942c39dbf41d/pandas-2.2.3-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:3b71f27954685ee685317063bf13c7709a7ba74fc996b84fc6821c59b0f06468", size = 12615650 }, + { url = "https://files.pythonhosted.org/packages/9c/8c/f0fd18f6140ddafc0c24122c8a964e48294acc579d47def376fef12bcb4a/pandas-2.2.3-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:38cf8125c40dae9d5acc10fa66af8ea6fdf760b2714ee482ca691fc66e6fcb18", size = 11290177 }, + { url = "https://files.pythonhosted.org/packages/ed/f9/e995754eab9c0f14c6777401f7eece0943840b7a9fc932221c19d1abee9f/pandas-2.2.3-cp313-cp313t-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:ba96630bc17c875161df3818780af30e43be9b166ce51c9a18c1feae342906c2", size = 14651526 }, + { url = "https://files.pythonhosted.org/packages/25/b0/98d6ae2e1abac4f35230aa756005e8654649d305df9a28b16b9ae4353bff/pandas-2.2.3-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1db71525a1538b30142094edb9adc10be3f3e176748cd7acc2240c2f2e5aa3a4", size = 11871013 }, + { url = "https://files.pythonhosted.org/packages/cc/57/0f72a10f9db6a4628744c8e8f0df4e6e21de01212c7c981d31e50ffc8328/pandas-2.2.3-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:15c0e1e02e93116177d29ff83e8b1619c93ddc9c49083f237d4312337a61165d", size = 15711620 }, + { url = "https://files.pythonhosted.org/packages/ab/5f/b38085618b950b79d2d9164a711c52b10aefc0ae6833b96f626b7021b2ed/pandas-2.2.3-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:ad5b65698ab28ed8d7f18790a0dc58005c7629f227be9ecc1072aa74c0c1d43a", size = 13098436 }, + { url = "https://files.pythonhosted.org/packages/ca/8c/8848a4c9b8fdf5a534fe2077af948bf53cd713d77ffbcd7bd15710348fd7/pandas-2.2.3-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:bc6b93f9b966093cb0fd62ff1a7e4c09e6d546ad7c1de191767baffc57628f39", size = 12595535 }, + { url = "https://files.pythonhosted.org/packages/9c/b9/5cead4f63b6d31bdefeb21a679bc5a7f4aaf262ca7e07e2bc1c341b68470/pandas-2.2.3-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:5dbca4c1acd72e8eeef4753eeca07de9b1db4f398669d5994086f788a5d7cc30", size = 11319822 }, + { url = "https://files.pythonhosted.org/packages/31/af/89e35619fb573366fa68dc26dad6ad2c08c17b8004aad6d98f1a31ce4bb3/pandas-2.2.3-cp39-cp39-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:8cd6d7cc958a3910f934ea8dbdf17b2364827bb4dafc38ce6eef6bb3d65ff09c", size = 15625439 }, + { url = "https://files.pythonhosted.org/packages/3d/dd/bed19c2974296661493d7acc4407b1d2db4e2a482197df100f8f965b6225/pandas-2.2.3-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:99df71520d25fade9db7c1076ac94eb994f4d2673ef2aa2e86ee039b6746d20c", size = 13068928 }, + { url = "https://files.pythonhosted.org/packages/31/a3/18508e10a31ea108d746c848b5a05c0711e0278fa0d6f1c52a8ec52b80a5/pandas-2.2.3-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:31d0ced62d4ea3e231a9f228366919a5ea0b07440d9d4dac345376fd8e1477ea", size = 16783266 }, + { url = "https://files.pythonhosted.org/packages/c4/a5/3429bd13d82bebc78f4d78c3945efedef63a7cd0c15c17b2eeb838d1121f/pandas-2.2.3-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:7eee9e7cea6adf3e3d24e304ac6b8300646e2a5d1cd3a3c2abed9101b0846761", size = 14450871 }, + { url = "https://files.pythonhosted.org/packages/2f/49/5c30646e96c684570925b772eac4eb0a8cb0ca590fa978f56c5d3ae73ea1/pandas-2.2.3-cp39-cp39-win_amd64.whl", hash = "sha256:4850ba03528b6dd51d6c5d273c46f183f39a9baf3f0143e566b89450965b105e", size = 11618011 }, +] + +[[package]] +name = "pathspec" +version = "0.12.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/ca/bc/f35b8446f4531a7cb215605d100cd88b7ac6f44ab3fc94870c120ab3adbf/pathspec-0.12.1.tar.gz", hash = "sha256:a482d51503a1ab33b1c67a6c3813a26953dbdc71c31dacaef9a838c4e29f5712", size = 51043 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/cc/20/ff623b09d963f88bfde16306a54e12ee5ea43e9b597108672ff3a408aad6/pathspec-0.12.1-py3-none-any.whl", hash = "sha256:a0d503e138a4c123b27490a4f7beda6a01c6f288df0e4a8b79c7eb0dc7b4cc08", size = 31191 }, +] + +[[package]] +name = "platformdirs" +version = "4.3.7" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/b6/2d/7d512a3913d60623e7eb945c6d1b4f0bddf1d0b7ada5225274c87e5b53d1/platformdirs-4.3.7.tar.gz", hash = "sha256:eb437d586b6a0986388f0d6f74aa0cde27b48d0e3d66843640bfb6bdcdb6e351", size = 21291 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/6d/45/59578566b3275b8fd9157885918fcd0c4d74162928a5310926887b856a51/platformdirs-4.3.7-py3-none-any.whl", hash = "sha256:a03875334331946f13c549dbd8f4bac7a13a50a895a0eb1e8c6a8ace80d40a94", size = 18499 }, +] + +[[package]] +name = "pluggy" +version = "1.5.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/96/2d/02d4312c973c6050a18b314a5ad0b3210edb65a906f868e31c111dede4a6/pluggy-1.5.0.tar.gz", hash = "sha256:2cffa88e94fdc978c4c574f15f9e59b7f4201d439195c3715ca9e2486f1d0cf1", size = 67955 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/88/5f/e351af9a41f866ac3f1fac4ca0613908d9a41741cfcf2228f4ad853b697d/pluggy-1.5.0-py3-none-any.whl", hash = "sha256:44e1ad92c8ca002de6377e165f3e0f1be63266ab4d554740532335b9d75ea669", size = 20556 }, +] + +[[package]] +name = "pycparser" +version = "2.22" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/1d/b2/31537cf4b1ca988837256c910a668b553fceb8f069bedc4b1c826024b52c/pycparser-2.22.tar.gz", hash = "sha256:491c8be9c040f5390f5bf44a5b07752bd07f56edf992381b05c701439eec10f6", size = 172736 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/13/a3/a812df4e2dd5696d1f351d58b8fe16a405b234ad2886a0dab9183fb78109/pycparser-2.22-py3-none-any.whl", hash = "sha256:c3702b6d3dd8c7abc1afa565d7e63d53a1d0bd86cdc24edd75470f4de499cfcc", size = 117552 }, +] + +[[package]] +name = "pytest" +version = "8.3.5" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "colorama", marker = "sys_platform == 'win32'" }, + { name = "exceptiongroup", marker = "python_full_version < '3.11'" }, + { name = "iniconfig" }, + { name = "packaging" }, + { name = "pluggy" }, + { name = "tomli", marker = "python_full_version < '3.11'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/ae/3c/c9d525a414d506893f0cd8a8d0de7706446213181570cdbd766691164e40/pytest-8.3.5.tar.gz", hash = "sha256:f4efe70cc14e511565ac476b57c279e12a855b11f48f212af1080ef2263d3845", size = 1450891 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/30/3d/64ad57c803f1fa1e963a7946b6e0fea4a70df53c1a7fed304586539c2bac/pytest-8.3.5-py3-none-any.whl", hash = "sha256:c69214aa47deac29fad6c2a4f590b9c4a9fdb16a403176fe154b79c0b4d4d820", size = 343634 }, +] + +[[package]] +name = "python-dateutil" +version = "2.9.0.post0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "six" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/66/c0/0c8b6ad9f17a802ee498c46e004a0eb49bc148f2fd230864601a86dcf6db/python-dateutil-2.9.0.post0.tar.gz", hash = "sha256:37dd54208da7e1cd875388217d5e00ebd4179249f90fb72437e91a35459a0ad3", size = 342432 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/ec/57/56b9bcc3c9c6a792fcbaf139543cee77261f3651ca9da0c93f5c1221264b/python_dateutil-2.9.0.post0-py2.py3-none-any.whl", hash = "sha256:a8b2bc7bffae282281c8140a97d3aa9c14da0b136dfe83f850eea9a5f7470427", size = 229892 }, +] + +[[package]] +name = "pytz" +version = "2025.2" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/f8/bf/abbd3cdfb8fbc7fb3d4d38d320f2441b1e7cbe29be4f23797b4a2b5d8aac/pytz-2025.2.tar.gz", hash = "sha256:360b9e3dbb49a209c21ad61809c7fb453643e048b38924c765813546746e81c3", size = 320884 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/81/c4/34e93fe5f5429d7570ec1fa436f1986fb1f00c3e0f43a589fe2bbcd22c3f/pytz-2025.2-py2.py3-none-any.whl", hash = "sha256:5ddf76296dd8c44c26eb8f4b6f35488f3ccbf6fbbd7adee0b7262d43f0ec2f00", size = 509225 }, +] + +[[package]] +name = "pyzmq" +version = "26.3.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "cffi", marker = "implementation_name == 'pypy'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/3a/ed/c3876f3b3e8beba336214ce44e1efa1792dd537027cef24192ac2b077d7c/pyzmq-26.3.0.tar.gz", hash = "sha256:f1cd68b8236faab78138a8fc703f7ca0ad431b17a3fcac696358600d4e6243b3", size = 276733 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/41/a8/cc21dcd6f0f96dbd636fcaab345f9664cd54e6577a21a74694202479d3fa/pyzmq-26.3.0-cp310-cp310-macosx_10_15_universal2.whl", hash = "sha256:1586944f4736515af5c6d3a5b150c7e8ca2a2d6e46b23057320584d6f2438f4a", size = 1345312 }, + { url = "https://files.pythonhosted.org/packages/0b/6d/7e0e52798697536d572a105849c4ab621ca00511674b6ce694cb05e437fc/pyzmq-26.3.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:aa7efc695d1fc9f72d91bf9b6c6fe2d7e1b4193836ec530a98faf7d7a7577a58", size = 678336 }, + { url = "https://files.pythonhosted.org/packages/91/86/8914875e2341a40da460feaa9cace727e50a6b640a20ac36186686bde7d9/pyzmq-26.3.0-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:bd84441e4021cec6e4dd040550386cd9c9ea1d9418ea1a8002dbb7b576026b2b", size = 916965 }, + { url = "https://files.pythonhosted.org/packages/9a/59/72b390b31ed0cc825881435f21baaae9d57e263aba526fa833863b90d667/pyzmq-26.3.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9176856f36c34a8aa5c0b35ddf52a5d5cd8abeece57c2cd904cfddae3fd9acd3", size = 874003 }, + { url = "https://files.pythonhosted.org/packages/97/d4/4dd152dbbaac35d4e1fe8e8fd26d73640fcd84ec9c3915b545692df1ffb7/pyzmq-26.3.0-cp310-cp310-manylinux_2_28_x86_64.whl", hash = "sha256:49334faa749d55b77f084389a80654bf2e68ab5191c0235066f0140c1b670d64", size = 867989 }, + { url = "https://files.pythonhosted.org/packages/a4/22/1c5dc761dff13981d27d8225aedb19e70ce9149d16cf0c97c7547570e986/pyzmq-26.3.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:fd30fc80fe96efb06bea21667c5793bbd65c0dc793187feb39b8f96990680b00", size = 1207989 }, + { url = "https://files.pythonhosted.org/packages/03/89/227ffb9e30b3fbe8196e7c97704345feb750b468e852ab64b0d19fa89e1a/pyzmq-26.3.0-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:b2eddfbbfb473a62c3a251bb737a6d58d91907f6e1d95791431ebe556f47d916", size = 1520523 }, + { url = "https://files.pythonhosted.org/packages/29/d3/e9b99b8404b6a470762cb947bc342e462a853a22ce0b0f2982c65a9b698f/pyzmq-26.3.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:70b3acb9ad729a53d4e751dace35404a024f188aad406013454216aba5485b4e", size = 1419912 }, + { url = "https://files.pythonhosted.org/packages/bb/69/074e2cde8135cae9452778e644ea5c91493bc536367d956005fe83072f63/pyzmq-26.3.0-cp310-cp310-win32.whl", hash = "sha256:c1bd75d692cd7c6d862a98013bfdf06702783b75cffbf5dae06d718fecefe8f2", size = 583733 }, + { url = "https://files.pythonhosted.org/packages/00/f0/55e57d40f6e21877e96507c0c2dd7e32afffc37b0dde7b834df1170cd749/pyzmq-26.3.0-cp310-cp310-win_amd64.whl", hash = "sha256:d7165bcda0dbf203e5ad04d79955d223d84b2263df4db92f525ba370b03a12ab", size = 647229 }, + { url = "https://files.pythonhosted.org/packages/38/1d/6e935b5f06d674c931540b29932a0dd5e1b9d29d047c2764a9c8c6f3ce08/pyzmq-26.3.0-cp310-cp310-win_arm64.whl", hash = "sha256:e34a63f71d2ecffb3c643909ad2d488251afeb5ef3635602b3448e609611a7ed", size = 561038 }, + { url = "https://files.pythonhosted.org/packages/22/75/774e9a4a4291864dd37a03a7bfaf46a82d61cd36c16edd33a5739ad49be3/pyzmq-26.3.0-cp311-cp311-macosx_10_15_universal2.whl", hash = "sha256:2833602d9d42c94b9d0d2a44d2b382d3d3a4485be018ba19dddc401a464c617a", size = 1345893 }, + { url = "https://files.pythonhosted.org/packages/ca/51/d3eedd2bd46ef851bea528d8a2688a5091183b27fc238801fcac70e80dbb/pyzmq-26.3.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d8270d104ec7caa0bdac246d31d48d94472033ceab5ba142881704350b28159c", size = 678261 }, + { url = "https://files.pythonhosted.org/packages/de/5e/521d7c6613769dcc3ed5e44e7082938b6dab27fffe02755784e54e98e17b/pyzmq-26.3.0-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c208a977843d18d3bd185f323e4eaa912eb4869cb230947dc6edd8a27a4e558a", size = 915311 }, + { url = "https://files.pythonhosted.org/packages/78/db/3be86dd82adc638a2eb07c3028c1747ead49a71d7d334980b007f593fd9f/pyzmq-26.3.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:eddc2be28a379c218e0d92e4a432805dcb0ca5870156a90b54c03cd9799f9f8a", size = 873193 }, + { url = "https://files.pythonhosted.org/packages/63/1a/81a31920d5113113ccd50271649dd2d0cfcfe46925d8f8a196fe560ed0e6/pyzmq-26.3.0-cp311-cp311-manylinux_2_28_x86_64.whl", hash = "sha256:c0b519fa2159c42272f8a244354a0e110d65175647e5185b04008ec00df9f079", size = 867648 }, + { url = "https://files.pythonhosted.org/packages/55/79/bbf57979ff2d89b5465d7205db08de7222d2560edc11272eb054c5a68cb5/pyzmq-26.3.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:1595533de3a80bf8363372c20bafa963ec4bf9f2b8f539b1d9a5017f430b84c9", size = 1208475 }, + { url = "https://files.pythonhosted.org/packages/50/fc/1246dfc4b165e7ff97ac3c4117bdd3747e03ebb62269f71f65e216bfac8b/pyzmq-26.3.0-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:bbef99eb8d18ba9a40f00e8836b8040cdcf0f2fa649684cf7a66339599919d21", size = 1519428 }, + { url = "https://files.pythonhosted.org/packages/5f/9a/143aacb6b372b0e2d812aec73a06fc5df3e169a361d4302226f8563954c6/pyzmq-26.3.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:979486d444ca3c469cd1c7f6a619ce48ff08b3b595d451937db543754bfacb65", size = 1419530 }, + { url = "https://files.pythonhosted.org/packages/47/f7/b437e77d496089e17e77866eb126dd97ea47041b58e53892f57e82869198/pyzmq-26.3.0-cp311-cp311-win32.whl", hash = "sha256:4b127cfe10b4c56e4285b69fd4b38ea1d368099ea4273d8fb349163fce3cd598", size = 582538 }, + { url = "https://files.pythonhosted.org/packages/a1/2c/99a01a2d7865aaf44e47c2182cbdbc15da1f2e4cfee92dc8e1fb5114f993/pyzmq-26.3.0-cp311-cp311-win_amd64.whl", hash = "sha256:cf736cc1298ef15280d9fcf7a25c09b05af016656856dc6fe5626fd8912658dd", size = 647989 }, + { url = "https://files.pythonhosted.org/packages/60/b3/36ac1cb8fafeadff09935f4bdc1232e511af8f8893d6cebc7ceb93c6753a/pyzmq-26.3.0-cp311-cp311-win_arm64.whl", hash = "sha256:2dc46ec09f5d36f606ac8393303149e69d17121beee13c8dac25e2a2078e31c4", size = 561533 }, + { url = "https://files.pythonhosted.org/packages/7b/03/7170c3814bb9106c1bca67700c731aaf1cd990fd2f0097c754acb600330e/pyzmq-26.3.0-cp312-cp312-macosx_10_15_universal2.whl", hash = "sha256:c80653332c6136da7f4d4e143975e74ac0fa14f851f716d90583bc19e8945cea", size = 1348354 }, + { url = "https://files.pythonhosted.org/packages/74/f3/908b17f9111cdc764aef1de3d36026a2984c46ed90c3c2c85f28b66142f0/pyzmq-26.3.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6e317ee1d4528a03506cb1c282cd9db73660a35b3564096de37de7350e7d87a7", size = 671056 }, + { url = "https://files.pythonhosted.org/packages/02/ad/afcb8484b65ceacd1609f709c2caeed31bd6c49261a7507cd5c175cc105f/pyzmq-26.3.0-cp312-cp312-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:943a22ebb3daacb45f76a9bcca9a7b74e7d94608c0c0505da30af900b998ca8d", size = 908597 }, + { url = "https://files.pythonhosted.org/packages/a1/b5/4eeeae0aaaa6ef0c74cfa8b2273b53382bd858df6d99485f2fc8211e7002/pyzmq-26.3.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3fc9e71490d989144981ea21ef4fdfaa7b6aa84aff9632d91c736441ce2f6b00", size = 865260 }, + { url = "https://files.pythonhosted.org/packages/74/6a/63db856e93e3a3c3dc98a1de28a902cf1b21c7b0d3856cd5931d7cfd30af/pyzmq-26.3.0-cp312-cp312-manylinux_2_28_x86_64.whl", hash = "sha256:e281a8071a06888575a4eb523c4deeefdcd2f5fe4a2d47e02ac8bf3a5b49f695", size = 859916 }, + { url = "https://files.pythonhosted.org/packages/e1/ce/d522c9b46ee3746d4b98c81969c568c2c6296e931a65f2c87104b645654c/pyzmq-26.3.0-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:be77efd735bb1064605be8dec6e721141c1421ef0b115ef54e493a64e50e9a52", size = 1201368 }, + { url = "https://files.pythonhosted.org/packages/5a/56/29dcd3647a39e933eb489fda261a1e2700a59d4a9432889a85166e15651c/pyzmq-26.3.0-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:7a4ac2ffa34f1212dd586af90f4ba894e424f0cabb3a49cdcff944925640f6ac", size = 1512663 }, + { url = "https://files.pythonhosted.org/packages/6b/36/7c570698127a43398ed1b1832dada59496e633115016addbce5eda9938a6/pyzmq-26.3.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:ba698c7c252af83b6bba9775035263f0df5f807f0404019916d4b71af8161f66", size = 1411693 }, + { url = "https://files.pythonhosted.org/packages/de/54/51d39bef85a7cdbca36227f7defdbfcdc5011b8361a3bfc0e8df431f5a5d/pyzmq-26.3.0-cp312-cp312-win32.whl", hash = "sha256:214038aaa88e801e54c2ef0cfdb2e6df27eb05f67b477380a452b595c5ecfa37", size = 581244 }, + { url = "https://files.pythonhosted.org/packages/f2/6a/9512b11a1d0c5648534f03d5ab0c3222f55dc9c192029c1cb00a0ca044e2/pyzmq-26.3.0-cp312-cp312-win_amd64.whl", hash = "sha256:bad7fe0372e505442482ca3ccbc0d6f38dae81b1650f57a0aa6bbee18e7df495", size = 643559 }, + { url = "https://files.pythonhosted.org/packages/27/9f/faf5c9cf91b61eeb82a5e919d024d3ac28a795c92cce817be264ccd757d3/pyzmq-26.3.0-cp312-cp312-win_arm64.whl", hash = "sha256:b7b578d604e79e99aa39495becea013fd043fa9f36e4b490efa951f3d847a24d", size = 557664 }, + { url = "https://files.pythonhosted.org/packages/37/16/97b8c5107bfccb39120e611671a452c9ff6e8626fb3f8d4c15afd652b6ae/pyzmq-26.3.0-cp313-cp313-macosx_10_15_universal2.whl", hash = "sha256:fa85953df84beb7b8b73cb3ec3f5d92b62687a09a8e71525c6734e020edf56fd", size = 1345691 }, + { url = "https://files.pythonhosted.org/packages/a5/61/d5572d95040c0bb5b31eed5b23f3f0f992d94e4e0de0cea62e3c7f3a85c1/pyzmq-26.3.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:209d09f0ab6ddbcebe64630d1e6ca940687e736f443c265ae15bc4bfad833597", size = 670622 }, + { url = "https://files.pythonhosted.org/packages/1c/0c/f0235d27388aacf4ed8bcc1d574f6f2f629da0a20610faa0a8e9d363c2b0/pyzmq-26.3.0-cp313-cp313-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d35cc1086f1d4f907df85c6cceb2245cb39a04f69c3f375993363216134d76d4", size = 908683 }, + { url = "https://files.pythonhosted.org/packages/cb/52/664828f9586c396b857eec088d208230463e3dc991a24df6adbad98fbaa3/pyzmq-26.3.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b380e9087078ba91e45fb18cdd0c25275ffaa045cf63c947be0ddae6186bc9d9", size = 865212 }, + { url = "https://files.pythonhosted.org/packages/2b/14/213b2967030b7d7aecc32dd453830f98799b3cbf2b10a40232e9f22a6520/pyzmq-26.3.0-cp313-cp313-manylinux_2_28_x86_64.whl", hash = "sha256:6d64e74143587efe7c9522bb74d1448128fdf9897cc9b6d8b9927490922fd558", size = 860068 }, + { url = "https://files.pythonhosted.org/packages/aa/e5/ff50c8fade69d1c0469652832c626d1910668697642c10cb0e1b6183ef9a/pyzmq-26.3.0-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:efba4f53ac7752eea6d8ca38a4ddac579e6e742fba78d1e99c12c95cd2acfc64", size = 1201303 }, + { url = "https://files.pythonhosted.org/packages/9a/e2/fff5e483be95ccc11a05781323e001e63ec15daec1d0f6f08de72ca534db/pyzmq-26.3.0-cp313-cp313-musllinux_1_1_i686.whl", hash = "sha256:9b0137a1c40da3b7989839f9b78a44de642cdd1ce20dcef341de174c8d04aa53", size = 1512892 }, + { url = "https://files.pythonhosted.org/packages/21/75/cc44d276e43136e5692e487c3c019f816e11ed445261e434217c28cc98c4/pyzmq-26.3.0-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:a995404bd3982c089e57b428c74edd5bfc3b0616b3dbcd6a8e270f1ee2110f36", size = 1411736 }, + { url = "https://files.pythonhosted.org/packages/ee/1c/d070cbc9a7961fe772641c51bb3798d88cb1f8e20ca718407363462624cf/pyzmq-26.3.0-cp313-cp313-win32.whl", hash = "sha256:240b1634b9e530ef6a277d95cbca1a6922f44dfddc5f0a3cd6c722a8de867f14", size = 581214 }, + { url = "https://files.pythonhosted.org/packages/38/d3/91082f1151ff5b54e0bed40eb1a26f418530ab07ecaec4dbb83e3d9fa9a9/pyzmq-26.3.0-cp313-cp313-win_amd64.whl", hash = "sha256:fe67291775ea4c2883764ba467eb389c29c308c56b86c1e19e49c9e1ed0cbeca", size = 643412 }, + { url = "https://files.pythonhosted.org/packages/e0/cf/dabe68dfdf3e67bea6152eeec4b251cf899ee5b853cfb5c97e4719f9e6e9/pyzmq-26.3.0-cp313-cp313-win_arm64.whl", hash = "sha256:73ca9ae9a9011b714cf7650450cd9c8b61a135180b708904f1f0a05004543dce", size = 557444 }, + { url = "https://files.pythonhosted.org/packages/c0/56/e7576ac71c1566da4f4ec586351462a2bb202143fb074bf56df8fe85dcc3/pyzmq-26.3.0-cp313-cp313t-macosx_10_15_universal2.whl", hash = "sha256:fea7efbd7e49af9d7e5ed6c506dfc7de3d1a628790bd3a35fd0e3c904dc7d464", size = 1340288 }, + { url = "https://files.pythonhosted.org/packages/f1/ab/0bca97e94d420b5908968bc479e51c3686a9f80d8893450eefcd673b1b1d/pyzmq-26.3.0-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c4430c7cba23bb0e2ee203eee7851c1654167d956fc6d4b3a87909ccaf3c5825", size = 662462 }, + { url = "https://files.pythonhosted.org/packages/ee/be/99e89b55863808da322ac3ab52d8e135dcf2241094aaa468bfe2923d5194/pyzmq-26.3.0-cp313-cp313t-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:016d89bee8c7d566fad75516b4e53ec7c81018c062d4c51cd061badf9539be52", size = 896464 }, + { url = "https://files.pythonhosted.org/packages/38/d4/a4be06a313c8d6a5fe1d92975db30aca85f502e867fca392532e06a28c3c/pyzmq-26.3.0-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:04bfe59852d76d56736bfd10ac1d49d421ab8ed11030b4a0332900691507f557", size = 853432 }, + { url = "https://files.pythonhosted.org/packages/12/e6/e608b4c34106bbf5b3b382662ea90a43b2e23df0aa9c1f0fd4e21168d523/pyzmq-26.3.0-cp313-cp313t-manylinux_2_28_x86_64.whl", hash = "sha256:1fe05bd0d633a0f672bb28cb8b4743358d196792e1caf04973b7898a0d70b046", size = 845884 }, + { url = "https://files.pythonhosted.org/packages/c3/a9/d5e6355308ba529d9cd3576ee8bb3b2e2b726571748f515fbb8559401f5b/pyzmq-26.3.0-cp313-cp313t-musllinux_1_1_aarch64.whl", hash = "sha256:2aa1a9f236d5b835fb8642f27de95f9edcfd276c4bc1b6ffc84f27c6fb2e2981", size = 1191454 }, + { url = "https://files.pythonhosted.org/packages/6a/9a/a21dc6c73ac242e425709c1e0049368d8f5db5de7c1102a45f93f5c492b3/pyzmq-26.3.0-cp313-cp313t-musllinux_1_1_i686.whl", hash = "sha256:21399b31753bf321043ea60c360ed5052cc7be20739785b1dff1820f819e35b3", size = 1500397 }, + { url = "https://files.pythonhosted.org/packages/87/88/0236056156da0278c9ca2e2562463643597808b5bbd6c34009ba217e7e92/pyzmq-26.3.0-cp313-cp313t-musllinux_1_1_x86_64.whl", hash = "sha256:d015efcd96aca8882057e7e6f06224f79eecd22cad193d3e6a0a91ec67590d1f", size = 1398401 }, + { url = "https://files.pythonhosted.org/packages/98/53/870b45d284f8be945a05ea3b70b56fe92538f13305d75362a39256e0c57b/pyzmq-26.3.0-cp39-cp39-macosx_10_15_universal2.whl", hash = "sha256:2eaed0d911fb3280981d5495978152fab6afd9fe217fd16f411523665089cef1", size = 1346508 }, + { url = "https://files.pythonhosted.org/packages/6b/d4/622e418729762c4957ec87639105e15398a919a2068a18a4c2ea17caa504/pyzmq-26.3.0-cp39-cp39-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:7998b60ef1c105846fb3bfca494769fde3bba6160902e7cd27a8df8257890ee9", size = 913284 }, + { url = "https://files.pythonhosted.org/packages/9a/63/a4b7f92a50821996ecd3520c5360fdc70df37918dd5c813ebbecad7bd56f/pyzmq-26.3.0-cp39-cp39-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:96c0006a8d1d00e46cb44c8e8d7316d4a232f3d8f2ed43179d4578dbcb0829b6", size = 867321 }, + { url = "https://files.pythonhosted.org/packages/30/41/5b22f376e25b3dfbb8bc9c145a1a8cd8418ecc5e310a18402bff16dfb018/pyzmq-26.3.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5e17cc198dc50a25a0f245e6b1e56f692df2acec3ccae82d1f60c34bfb72bbec", size = 678889 }, + { url = "https://files.pythonhosted.org/packages/64/50/4f727469fb52230449f28b6d6a027c1e5c107b46c60c9e90b3ed3c7e492d/pyzmq-26.3.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:92a30840f4f2a31f7049d0a7de5fc69dd03b19bd5d8e7fed8d0bde49ce49b589", size = 1208802 }, + { url = "https://files.pythonhosted.org/packages/26/9d/290f43cb3953f1f74834470447baa849f6224296986f1e2d774bdcce26e1/pyzmq-26.3.0-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:f52eba83272a26b444f4b8fc79f2e2c83f91d706d693836c9f7ccb16e6713c31", size = 1521092 }, + { url = "https://files.pythonhosted.org/packages/aa/b5/261749d5b9a9fd9a32eb4eebddce0e46e720d14f4565b55d62bc004bcae9/pyzmq-26.3.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:952085a09ff32115794629ba47f8940896d7842afdef1283332109d38222479d", size = 1420582 }, + { url = "https://files.pythonhosted.org/packages/b8/d5/65e00583641b1060b21d350716eb9539a626a665a87921710a7e3ebde592/pyzmq-26.3.0-cp39-cp39-win32.whl", hash = "sha256:0240289e33e3fbae44a5db73e54e955399179332a6b1d47c764a4983ec1524c3", size = 584172 }, + { url = "https://files.pythonhosted.org/packages/71/23/c51f63a78bf5a039be26eccda1d2040b83553189daf82378c71a33f60caa/pyzmq-26.3.0-cp39-cp39-win_amd64.whl", hash = "sha256:b2db7c82f08b8ce44c0b9d1153ce63907491972a7581e8b6adea71817f119df8", size = 647715 }, + { url = "https://files.pythonhosted.org/packages/27/67/aae0809e3806f8bbcf679dbf1874f7e0efb5d957cfbb66e907c4f45d79b9/pyzmq-26.3.0-cp39-cp39-win_arm64.whl", hash = "sha256:2d3459b6311463c96abcb97808ee0a1abb0d932833edb6aa81c30d622fd4a12d", size = 561557 }, + { url = "https://files.pythonhosted.org/packages/7e/ec/2e02dde6b1a436b02a6c0e3cb64c779bf6e76cc41c12131f29d9b10a088f/pyzmq-26.3.0-pp310-pypy310_pp73-macosx_10_15_x86_64.whl", hash = "sha256:ad03f4252d9041b0635c37528dfa3f44b39f46024ae28c8567f7423676ee409b", size = 835672 }, + { url = "https://files.pythonhosted.org/packages/22/ee/30c2c3f162912cff31af2b9d87295533d16f867e7621bd6f9ed62d9cc807/pyzmq-26.3.0-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0f3dfb68cf7bf4cfdf34283a75848e077c5defa4907506327282afe92780084d", size = 570837 }, + { url = "https://files.pythonhosted.org/packages/51/a5/5aead624f5f1033dab9bdaf3e2bc692a8042fcb59355c919a2c042061780/pyzmq-26.3.0-pp310-pypy310_pp73-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:356ec0e39c5a9cda872b65aca1fd8a5d296ffdadf8e2442b70ff32e73ef597b1", size = 799508 }, + { url = "https://files.pythonhosted.org/packages/ca/8a/dcc0a24cfed80cc004abcba710077147ec9178a12865914e73a60a70cb62/pyzmq-26.3.0-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:749d671b0eec8e738bbf0b361168369d8c682b94fcd458c20741dc4d69ef5278", size = 758001 }, + { url = "https://files.pythonhosted.org/packages/1a/74/f18e63540340f5c740396eb6408d154a84e9f0e9e1ae931b192bf2aa7425/pyzmq-26.3.0-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:f950f17ae608e0786298340163cac25a4c5543ef25362dd5ddb6dcb10b547be9", size = 556425 }, + { url = "https://files.pythonhosted.org/packages/f4/c6/e36b2a2ff6534cb1d1f6b3fb37901ac54675caf7b2e1239613aa40d1d217/pyzmq-26.3.0-pp311-pypy311_pp73-macosx_10_15_x86_64.whl", hash = "sha256:b4fc9903a73c25be9d5fe45c87faababcf3879445efa16140146b08fccfac017", size = 835670 }, + { url = "https://files.pythonhosted.org/packages/1d/b9/8059c5af94b245068e7f7379c08c7e409ec854139d6021aecf2c111d8547/pyzmq-26.3.0-pp311-pypy311_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c15b69af22030960ac63567e98ad8221cddf5d720d9cf03d85021dfd452324ef", size = 570838 }, + { url = "https://files.pythonhosted.org/packages/80/a4/f0a4266ff2d94a87f7c32895b1716f9ac0edc0471d518462beeb0a9a94b5/pyzmq-26.3.0-pp311-pypy311_pp73-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2cf9ab0dff4dbaa2e893eb608373c97eb908e53b7d9793ad00ccbd082c0ee12f", size = 799507 }, + { url = "https://files.pythonhosted.org/packages/78/14/3d7d459f496fab8e487b23423ccba57abf7153a4fde0c3e000500fa02ff8/pyzmq-26.3.0-pp311-pypy311_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3ec332675f6a138db57aad93ae6387953763f85419bdbd18e914cb279ee1c451", size = 758002 }, + { url = "https://files.pythonhosted.org/packages/22/65/cc1f0e1db1290770285430e36d51767e620487523e6a04094be637e55698/pyzmq-26.3.0-pp311-pypy311_pp73-win_amd64.whl", hash = "sha256:eb96568a22fe070590942cd4780950e2172e00fb033a8b76e47692583b1bd97c", size = 556425 }, + { url = "https://files.pythonhosted.org/packages/31/dc/d35ccb541761f9e55d07a3e42f126b28fed86bb9e0e7682cabef0641f552/pyzmq-26.3.0-pp39-pypy39_pp73-macosx_10_15_x86_64.whl", hash = "sha256:21c6ddb98557a77cfe3366af0c5600fb222a1b2de5f90d9cd052b324e0c295e8", size = 835669 }, + { url = "https://files.pythonhosted.org/packages/c8/45/78c3b0f048c7da7bab68884304e7535e453daf19ac09ab12639e52aadd27/pyzmq-26.3.0-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1fc81d5d60c9d40e692de14b8d884d43cf67562402b931681f0ccb3ce6b19875", size = 570834 }, + { url = "https://files.pythonhosted.org/packages/95/07/b23e5158ef143f06f07d29f1e76f5378b929c77b10f117ba2369fb5298a5/pyzmq-26.3.0-pp39-pypy39_pp73-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:52b064fafef772d0f5dbf52d4c39f092be7bc62d9a602fe6e82082e001326de3", size = 799504 }, + { url = "https://files.pythonhosted.org/packages/a0/47/a7d1b2b1f1cade45833a49c0ba7bc9455ad8c796ef56652c6b43522750eb/pyzmq-26.3.0-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b72206eb041f780451c61e1e89dbc3705f3d66aaaa14ee320d4f55864b13358a", size = 757996 }, + { url = "https://files.pythonhosted.org/packages/0d/0f/ac17e43312dd2d3a127962378320480371433907db1335df11b0b63ac314/pyzmq-26.3.0-pp39-pypy39_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:8ab78dc21c7b1e13053086bcf0b4246440b43b5409904b73bfd1156654ece8a1", size = 746636 }, + { url = "https://files.pythonhosted.org/packages/3a/7c/2acf02fd523163d4d5a9d528ecd4a5764de05a4dc9162f33de7385d3109c/pyzmq-26.3.0-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:0b42403ad7d1194dca9574cd3c56691c345f4601fa2d0a33434f35142baec7ac", size = 556417 }, +] + +[[package]] +name = "referencing" +version = "0.36.2" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "attrs" }, + { name = "rpds-py" }, + { name = "typing-extensions", marker = "python_full_version < '3.13'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/2f/db/98b5c277be99dd18bfd91dd04e1b759cad18d1a338188c936e92f921c7e2/referencing-0.36.2.tar.gz", hash = "sha256:df2e89862cd09deabbdba16944cc3f10feb6b3e6f18e902f7cc25609a34775aa", size = 74744 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/c1/b1/3baf80dc6d2b7bc27a95a67752d0208e410351e3feb4eb78de5f77454d8d/referencing-0.36.2-py3-none-any.whl", hash = "sha256:e8699adbbf8b5c7de96d8ffa0eb5c158b3beafce084968e2ea8bb08c6794dcd0", size = 26775 }, +] + +[[package]] +name = "requests" +version = "2.32.3" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "certifi" }, + { name = "charset-normalizer" }, + { name = "idna" }, + { name = "urllib3" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/63/70/2bf7780ad2d390a8d301ad0b550f1581eadbd9a20f896afe06353c2a2913/requests-2.32.3.tar.gz", hash = "sha256:55365417734eb18255590a9ff9eb97e9e1da868d4ccd6402399eaf68af20a760", size = 131218 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/f9/9b/335f9764261e915ed497fcdeb11df5dfd6f7bf257d4a6a2a686d80da4d54/requests-2.32.3-py3-none-any.whl", hash = "sha256:70761cfe03c773ceb22aa2f671b4757976145175cdfca038c02654d061d6dcc6", size = 64928 }, +] + +[[package]] +name = "rpds-py" +version = "0.24.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/0b/b3/52b213298a0ba7097c7ea96bee95e1947aa84cc816d48cebb539770cdf41/rpds_py-0.24.0.tar.gz", hash = "sha256:772cc1b2cd963e7e17e6cc55fe0371fb9c704d63e44cacec7b9b7f523b78919e", size = 26863 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/6a/21/cbc43b220c9deb536b07fbd598c97d463bbb7afb788851891252fc920742/rpds_py-0.24.0-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:006f4342fe729a368c6df36578d7a348c7c716be1da0a1a0f86e3021f8e98724", size = 377531 }, + { url = "https://files.pythonhosted.org/packages/42/15/cc4b09ef160483e49c3aab3b56f3d375eadf19c87c48718fb0147e86a446/rpds_py-0.24.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:2d53747da70a4e4b17f559569d5f9506420966083a31c5fbd84e764461c4444b", size = 362273 }, + { url = "https://files.pythonhosted.org/packages/8c/a2/67718a188a88dbd5138d959bed6efe1cc7413a4caa8283bd46477ed0d1ad/rpds_py-0.24.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e8acd55bd5b071156bae57b555f5d33697998752673b9de554dd82f5b5352727", size = 388111 }, + { url = "https://files.pythonhosted.org/packages/e5/e6/cbf1d3163405ad5f4a1a6d23f80245f2204d0c743b18525f34982dec7f4d/rpds_py-0.24.0-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:7e80d375134ddb04231a53800503752093dbb65dad8dabacce2c84cccc78e964", size = 394447 }, + { url = "https://files.pythonhosted.org/packages/21/bb/4fe220ccc8a549b38b9e9cec66212dc3385a82a5ee9e37b54411cce4c898/rpds_py-0.24.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:60748789e028d2a46fc1c70750454f83c6bdd0d05db50f5ae83e2db500b34da5", size = 448028 }, + { url = "https://files.pythonhosted.org/packages/a5/41/d2d6e0fd774818c4cadb94185d30cf3768de1c2a9e0143fc8bc6ce59389e/rpds_py-0.24.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:6e1daf5bf6c2be39654beae83ee6b9a12347cb5aced9a29eecf12a2d25fff664", size = 447410 }, + { url = "https://files.pythonhosted.org/packages/a7/a7/6d04d438f53d8bb2356bb000bea9cf5c96a9315e405b577117e344cc7404/rpds_py-0.24.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1b221c2457d92a1fb3c97bee9095c874144d196f47c038462ae6e4a14436f7bc", size = 389531 }, + { url = "https://files.pythonhosted.org/packages/23/be/72e6df39bd7ca5a66799762bf54d8e702483fdad246585af96723109d486/rpds_py-0.24.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:66420986c9afff67ef0c5d1e4cdc2d0e5262f53ad11e4f90e5e22448df485bf0", size = 420099 }, + { url = "https://files.pythonhosted.org/packages/8c/c9/ca100cd4688ee0aa266197a5cb9f685231676dd7d573041ca53787b23f4e/rpds_py-0.24.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:43dba99f00f1d37b2a0265a259592d05fcc8e7c19d140fe51c6e6f16faabeb1f", size = 564950 }, + { url = "https://files.pythonhosted.org/packages/05/98/908cd95686d33b3ac8ac2e582d7ae38e2c3aa2c0377bf1f5663bafd1ffb2/rpds_py-0.24.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:a88c0d17d039333a41d9bf4616bd062f0bd7aa0edeb6cafe00a2fc2a804e944f", size = 591778 }, + { url = "https://files.pythonhosted.org/packages/7b/ac/e143726f1dd3215efcb974b50b03bd08a8a1556b404a0a7872af6d197e57/rpds_py-0.24.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:cc31e13ce212e14a539d430428cd365e74f8b2d534f8bc22dd4c9c55b277b875", size = 560421 }, + { url = "https://files.pythonhosted.org/packages/60/28/add1c1d2fcd5aa354f7225d036d4492261759a22d449cff14841ef36a514/rpds_py-0.24.0-cp310-cp310-win32.whl", hash = "sha256:fc2c1e1b00f88317d9de6b2c2b39b012ebbfe35fe5e7bef980fd2a91f6100a07", size = 222089 }, + { url = "https://files.pythonhosted.org/packages/b0/ac/81f8066c6de44c507caca488ba336ae30d35d57f61fe10578824d1a70196/rpds_py-0.24.0-cp310-cp310-win_amd64.whl", hash = "sha256:c0145295ca415668420ad142ee42189f78d27af806fcf1f32a18e51d47dd2052", size = 234622 }, + { url = "https://files.pythonhosted.org/packages/80/e6/c1458bbfb257448fdb2528071f1f4e19e26798ed5ef6d47d7aab0cb69661/rpds_py-0.24.0-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:2d3ee4615df36ab8eb16c2507b11e764dcc11fd350bbf4da16d09cda11fcedef", size = 377679 }, + { url = "https://files.pythonhosted.org/packages/dd/26/ea4181ef78f58b2c167548c6a833d7dc22408e5b3b181bda9dda440bb92d/rpds_py-0.24.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:e13ae74a8a3a0c2f22f450f773e35f893484fcfacb00bb4344a7e0f4f48e1f97", size = 362571 }, + { url = "https://files.pythonhosted.org/packages/56/fa/1ec54dd492c64c280a2249a047fc3369e2789dc474eac20445ebfc72934b/rpds_py-0.24.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:cf86f72d705fc2ef776bb7dd9e5fbba79d7e1f3e258bf9377f8204ad0fc1c51e", size = 388012 }, + { url = "https://files.pythonhosted.org/packages/3a/be/bad8b0e0f7e58ef4973bb75e91c472a7d51da1977ed43b09989264bf065c/rpds_py-0.24.0-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:c43583ea8517ed2e780a345dd9960896afc1327e8cf3ac8239c167530397440d", size = 394730 }, + { url = "https://files.pythonhosted.org/packages/35/56/ab417fc90c21826df048fc16e55316ac40876e4b790104ececcbce813d8f/rpds_py-0.24.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:4cd031e63bc5f05bdcda120646a0d32f6d729486d0067f09d79c8db5368f4586", size = 448264 }, + { url = "https://files.pythonhosted.org/packages/b6/75/4c63862d5c05408589196c8440a35a14ea4ae337fa70ded1f03638373f06/rpds_py-0.24.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:34d90ad8c045df9a4259c47d2e16a3f21fdb396665c94520dbfe8766e62187a4", size = 446813 }, + { url = "https://files.pythonhosted.org/packages/e7/0c/91cf17dffa9a38835869797a9f041056091ebba6a53963d3641207e3d467/rpds_py-0.24.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e838bf2bb0b91ee67bf2b889a1a841e5ecac06dd7a2b1ef4e6151e2ce155c7ae", size = 389438 }, + { url = "https://files.pythonhosted.org/packages/1b/b0/60e6c72727c978276e02851819f3986bc40668f115be72c1bc4d922c950f/rpds_py-0.24.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:04ecf5c1ff4d589987b4d9882872f80ba13da7d42427234fce8f22efb43133bc", size = 420416 }, + { url = "https://files.pythonhosted.org/packages/a1/d7/f46f85b9f863fb59fd3c534b5c874c48bee86b19e93423b9da8784605415/rpds_py-0.24.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:630d3d8ea77eabd6cbcd2ea712e1c5cecb5b558d39547ac988351195db433f6c", size = 565236 }, + { url = "https://files.pythonhosted.org/packages/2a/d1/1467620ded6dd70afc45ec822cdf8dfe7139537780d1f3905de143deb6fd/rpds_py-0.24.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:ebcb786b9ff30b994d5969213a8430cbb984cdd7ea9fd6df06663194bd3c450c", size = 592016 }, + { url = "https://files.pythonhosted.org/packages/5d/13/fb1ded2e6adfaa0c0833106c42feb290973f665300f4facd5bf5d7891d9c/rpds_py-0.24.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:174e46569968ddbbeb8a806d9922f17cd2b524aa753b468f35b97ff9c19cb718", size = 560123 }, + { url = "https://files.pythonhosted.org/packages/1e/df/09fc1857ac7cc2eb16465a7199c314cbce7edde53c8ef21d615410d7335b/rpds_py-0.24.0-cp311-cp311-win32.whl", hash = "sha256:5ef877fa3bbfb40b388a5ae1cb00636a624690dcb9a29a65267054c9ea86d88a", size = 222256 }, + { url = "https://files.pythonhosted.org/packages/ff/25/939b40bc4d54bf910e5ee60fb5af99262c92458f4948239e8c06b0b750e7/rpds_py-0.24.0-cp311-cp311-win_amd64.whl", hash = "sha256:e274f62cbd274359eff63e5c7e7274c913e8e09620f6a57aae66744b3df046d6", size = 234718 }, + { url = "https://files.pythonhosted.org/packages/1a/e0/1c55f4a3be5f1ca1a4fd1f3ff1504a1478c1ed48d84de24574c4fa87e921/rpds_py-0.24.0-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:d8551e733626afec514b5d15befabea0dd70a343a9f23322860c4f16a9430205", size = 366945 }, + { url = "https://files.pythonhosted.org/packages/39/1b/a3501574fbf29118164314dbc800d568b8c1c7b3258b505360e8abb3902c/rpds_py-0.24.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:0e374c0ce0ca82e5b67cd61fb964077d40ec177dd2c4eda67dba130de09085c7", size = 351935 }, + { url = "https://files.pythonhosted.org/packages/dc/47/77d3d71c55f6a374edde29f1aca0b2e547325ed00a9da820cabbc9497d2b/rpds_py-0.24.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d69d003296df4840bd445a5d15fa5b6ff6ac40496f956a221c4d1f6f7b4bc4d9", size = 390817 }, + { url = "https://files.pythonhosted.org/packages/4e/ec/1e336ee27484379e19c7f9cc170f4217c608aee406d3ae3a2e45336bff36/rpds_py-0.24.0-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:8212ff58ac6dfde49946bea57474a386cca3f7706fc72c25b772b9ca4af6b79e", size = 401983 }, + { url = "https://files.pythonhosted.org/packages/07/f8/39b65cbc272c635eaea6d393c2ad1ccc81c39eca2db6723a0ca4b2108fce/rpds_py-0.24.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:528927e63a70b4d5f3f5ccc1fa988a35456eb5d15f804d276709c33fc2f19bda", size = 451719 }, + { url = "https://files.pythonhosted.org/packages/32/05/05c2b27dd9c30432f31738afed0300659cb9415db0ff7429b05dfb09bbde/rpds_py-0.24.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a824d2c7a703ba6daaca848f9c3d5cb93af0505be505de70e7e66829affd676e", size = 442546 }, + { url = "https://files.pythonhosted.org/packages/7d/e0/19383c8b5d509bd741532a47821c3e96acf4543d0832beba41b4434bcc49/rpds_py-0.24.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:44d51febb7a114293ffd56c6cf4736cb31cd68c0fddd6aa303ed09ea5a48e029", size = 393695 }, + { url = "https://files.pythonhosted.org/packages/9d/15/39f14e96d94981d0275715ae8ea564772237f3fa89bc3c21e24de934f2c7/rpds_py-0.24.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:3fab5f4a2c64a8fb64fc13b3d139848817a64d467dd6ed60dcdd6b479e7febc9", size = 427218 }, + { url = "https://files.pythonhosted.org/packages/22/b9/12da7124905a680f690da7a9de6f11de770b5e359f5649972f7181c8bf51/rpds_py-0.24.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:9be4f99bee42ac107870c61dfdb294d912bf81c3c6d45538aad7aecab468b6b7", size = 568062 }, + { url = "https://files.pythonhosted.org/packages/88/17/75229017a2143d915f6f803721a6d721eca24f2659c5718a538afa276b4f/rpds_py-0.24.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:564c96b6076a98215af52f55efa90d8419cc2ef45d99e314fddefe816bc24f91", size = 596262 }, + { url = "https://files.pythonhosted.org/packages/aa/64/8e8a1d8bd1b6b638d6acb6d41ab2cec7f2067a5b8b4c9175703875159a7c/rpds_py-0.24.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:75a810b7664c17f24bf2ffd7f92416c00ec84b49bb68e6a0d93e542406336b56", size = 564306 }, + { url = "https://files.pythonhosted.org/packages/68/1c/a7eac8d8ed8cb234a9b1064647824c387753343c3fab6ed7c83481ed0be7/rpds_py-0.24.0-cp312-cp312-win32.whl", hash = "sha256:f6016bd950be4dcd047b7475fdf55fb1e1f59fc7403f387be0e8123e4a576d30", size = 224281 }, + { url = "https://files.pythonhosted.org/packages/bb/46/b8b5424d1d21f2f2f3f2d468660085318d4f74a8df8289e3dd6ad224d488/rpds_py-0.24.0-cp312-cp312-win_amd64.whl", hash = "sha256:998c01b8e71cf051c28f5d6f1187abbdf5cf45fc0efce5da6c06447cba997034", size = 239719 }, + { url = "https://files.pythonhosted.org/packages/9d/c3/3607abc770395bc6d5a00cb66385a5479fb8cd7416ddef90393b17ef4340/rpds_py-0.24.0-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:3d2d8e4508e15fc05b31285c4b00ddf2e0eb94259c2dc896771966a163122a0c", size = 367072 }, + { url = "https://files.pythonhosted.org/packages/d8/35/8c7ee0fe465793e3af3298dc5a9f3013bd63e7a69df04ccfded8293a4982/rpds_py-0.24.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:0f00c16e089282ad68a3820fd0c831c35d3194b7cdc31d6e469511d9bffc535c", size = 351919 }, + { url = "https://files.pythonhosted.org/packages/91/d3/7e1b972501eb5466b9aca46a9c31bcbbdc3ea5a076e9ab33f4438c1d069d/rpds_py-0.24.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:951cc481c0c395c4a08639a469d53b7d4afa252529a085418b82a6b43c45c240", size = 390360 }, + { url = "https://files.pythonhosted.org/packages/a2/a8/ccabb50d3c91c26ad01f9b09a6a3b03e4502ce51a33867c38446df9f896b/rpds_py-0.24.0-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:c9ca89938dff18828a328af41ffdf3902405a19f4131c88e22e776a8e228c5a8", size = 400704 }, + { url = "https://files.pythonhosted.org/packages/53/ae/5fa5bf0f3bc6ce21b5ea88fc0ecd3a439e7cb09dd5f9ffb3dbe1b6894fc5/rpds_py-0.24.0-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ed0ef550042a8dbcd657dfb284a8ee00f0ba269d3f2286b0493b15a5694f9fe8", size = 450839 }, + { url = "https://files.pythonhosted.org/packages/e3/ac/c4e18b36d9938247e2b54f6a03746f3183ca20e1edd7d3654796867f5100/rpds_py-0.24.0-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2b2356688e5d958c4d5cb964af865bea84db29971d3e563fb78e46e20fe1848b", size = 441494 }, + { url = "https://files.pythonhosted.org/packages/bf/08/b543969c12a8f44db6c0f08ced009abf8f519191ca6985509e7c44102e3c/rpds_py-0.24.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:78884d155fd15d9f64f5d6124b486f3d3f7fd7cd71a78e9670a0f6f6ca06fb2d", size = 393185 }, + { url = "https://files.pythonhosted.org/packages/da/7e/f6eb6a7042ce708f9dfc781832a86063cea8a125bbe451d663697b51944f/rpds_py-0.24.0-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:6a4a535013aeeef13c5532f802708cecae8d66c282babb5cd916379b72110cf7", size = 426168 }, + { url = "https://files.pythonhosted.org/packages/38/b0/6cd2bb0509ac0b51af4bb138e145b7c4c902bb4b724d6fd143689d6e0383/rpds_py-0.24.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:84e0566f15cf4d769dade9b366b7b87c959be472c92dffb70462dd0844d7cbad", size = 567622 }, + { url = "https://files.pythonhosted.org/packages/64/b0/c401f4f077547d98e8b4c2ec6526a80e7cb04f519d416430ec1421ee9e0b/rpds_py-0.24.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:823e74ab6fbaa028ec89615ff6acb409e90ff45580c45920d4dfdddb069f2120", size = 595435 }, + { url = "https://files.pythonhosted.org/packages/9f/ec/7993b6e803294c87b61c85bd63e11142ccfb2373cf88a61ec602abcbf9d6/rpds_py-0.24.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:c61a2cb0085c8783906b2f8b1f16a7e65777823c7f4d0a6aaffe26dc0d358dd9", size = 563762 }, + { url = "https://files.pythonhosted.org/packages/1f/29/4508003204cb2f461dc2b83dd85f8aa2b915bc98fe6046b9d50d4aa05401/rpds_py-0.24.0-cp313-cp313-win32.whl", hash = "sha256:60d9b630c8025b9458a9d114e3af579a2c54bd32df601c4581bd054e85258143", size = 223510 }, + { url = "https://files.pythonhosted.org/packages/f9/12/09e048d1814195e01f354155fb772fb0854bd3450b5f5a82224b3a319f0e/rpds_py-0.24.0-cp313-cp313-win_amd64.whl", hash = "sha256:6eea559077d29486c68218178ea946263b87f1c41ae7f996b1f30a983c476a5a", size = 239075 }, + { url = "https://files.pythonhosted.org/packages/d2/03/5027cde39bb2408d61e4dd0cf81f815949bb629932a6c8df1701d0257fc4/rpds_py-0.24.0-cp313-cp313t-macosx_10_12_x86_64.whl", hash = "sha256:d09dc82af2d3c17e7dd17120b202a79b578d79f2b5424bda209d9966efeed114", size = 362974 }, + { url = "https://files.pythonhosted.org/packages/bf/10/24d374a2131b1ffafb783e436e770e42dfdb74b69a2cd25eba8c8b29d861/rpds_py-0.24.0-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:5fc13b44de6419d1e7a7e592a4885b323fbc2f46e1f22151e3a8ed3b8b920405", size = 348730 }, + { url = "https://files.pythonhosted.org/packages/7a/d1/1ef88d0516d46cd8df12e5916966dbf716d5ec79b265eda56ba1b173398c/rpds_py-0.24.0-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c347a20d79cedc0a7bd51c4d4b7dbc613ca4e65a756b5c3e57ec84bd43505b47", size = 387627 }, + { url = "https://files.pythonhosted.org/packages/4e/35/07339051b8b901ecefd449ebf8e5522e92bcb95e1078818cbfd9db8e573c/rpds_py-0.24.0-cp313-cp313t-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:20f2712bd1cc26a3cc16c5a1bfee9ed1abc33d4cdf1aabd297fe0eb724df4272", size = 394094 }, + { url = "https://files.pythonhosted.org/packages/dc/62/ee89ece19e0ba322b08734e95441952062391065c157bbd4f8802316b4f1/rpds_py-0.24.0-cp313-cp313t-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:aad911555286884be1e427ef0dc0ba3929e6821cbeca2194b13dc415a462c7fd", size = 449639 }, + { url = "https://files.pythonhosted.org/packages/15/24/b30e9f9e71baa0b9dada3a4ab43d567c6b04a36d1cb531045f7a8a0a7439/rpds_py-0.24.0-cp313-cp313t-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:0aeb3329c1721c43c58cae274d7d2ca85c1690d89485d9c63a006cb79a85771a", size = 438584 }, + { url = "https://files.pythonhosted.org/packages/28/d9/49f7b8f3b4147db13961e19d5e30077cd0854ccc08487026d2cb2142aa4a/rpds_py-0.24.0-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2a0f156e9509cee987283abd2296ec816225145a13ed0391df8f71bf1d789e2d", size = 391047 }, + { url = "https://files.pythonhosted.org/packages/49/b0/e66918d0972c33a259ba3cd7b7ff10ed8bd91dbcfcbec6367b21f026db75/rpds_py-0.24.0-cp313-cp313t-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:aa6800adc8204ce898c8a424303969b7aa6a5e4ad2789c13f8648739830323b7", size = 418085 }, + { url = "https://files.pythonhosted.org/packages/e1/6b/99ed7ea0a94c7ae5520a21be77a82306aac9e4e715d4435076ead07d05c6/rpds_py-0.24.0-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:a18fc371e900a21d7392517c6f60fe859e802547309e94313cd8181ad9db004d", size = 564498 }, + { url = "https://files.pythonhosted.org/packages/28/26/1cacfee6b800e6fb5f91acecc2e52f17dbf8b0796a7c984b4568b6d70e38/rpds_py-0.24.0-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:9168764133fd919f8dcca2ead66de0105f4ef5659cbb4fa044f7014bed9a1797", size = 590202 }, + { url = "https://files.pythonhosted.org/packages/a9/9e/57bd2f9fba04a37cef673f9a66b11ca8c43ccdd50d386c455cd4380fe461/rpds_py-0.24.0-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:5f6e3cec44ba05ee5cbdebe92d052f69b63ae792e7d05f1020ac5e964394080c", size = 561771 }, + { url = "https://files.pythonhosted.org/packages/9f/cf/b719120f375ab970d1c297dbf8de1e3c9edd26fe92c0ed7178dd94b45992/rpds_py-0.24.0-cp313-cp313t-win32.whl", hash = "sha256:8ebc7e65ca4b111d928b669713865f021b7773350eeac4a31d3e70144297baba", size = 221195 }, + { url = "https://files.pythonhosted.org/packages/2d/e5/22865285789f3412ad0c3d7ec4dc0a3e86483b794be8a5d9ed5a19390900/rpds_py-0.24.0-cp313-cp313t-win_amd64.whl", hash = "sha256:675269d407a257b8c00a6b58205b72eec8231656506c56fd429d924ca00bb350", size = 237354 }, + { url = "https://files.pythonhosted.org/packages/22/ef/a194eaef0d0f2cd3f4c893c5b809a7458aaa7c0a64e60a45a72a04835ed4/rpds_py-0.24.0-cp39-cp39-macosx_10_12_x86_64.whl", hash = "sha256:a36b452abbf29f68527cf52e181fced56685731c86b52e852053e38d8b60bc8d", size = 378126 }, + { url = "https://files.pythonhosted.org/packages/c3/8d/9a07f69933204c098760c884f03835ab8fb66e28d2d5f3dd6741720cf29c/rpds_py-0.24.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:8b3b397eefecec8e8e39fa65c630ef70a24b09141a6f9fc17b3c3a50bed6b50e", size = 362887 }, + { url = "https://files.pythonhosted.org/packages/29/74/315f42060f2e3cedd77d382a98484a68ef727bd3b5fd7b91825b859a3e85/rpds_py-0.24.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:cdabcd3beb2a6dca7027007473d8ef1c3b053347c76f685f5f060a00327b8b65", size = 388661 }, + { url = "https://files.pythonhosted.org/packages/29/22/7ee7bb2b25ecdfcf1265d5a51472814fe60b580f9e1e2746eed9c476310a/rpds_py-0.24.0-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:5db385bacd0c43f24be92b60c857cf760b7f10d8234f4bd4be67b5b20a7c0b6b", size = 394993 }, + { url = "https://files.pythonhosted.org/packages/46/7b/5f40e278d81cd23eea6b88bbac62bacc27ed19412051a1fc4229e8f9367a/rpds_py-0.24.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8097b3422d020ff1c44effc40ae58e67d93e60d540a65649d2cdaf9466030791", size = 448706 }, + { url = "https://files.pythonhosted.org/packages/5a/7a/06aada7ecdb0d02fbc041daee998ae841882fcc8ed3c0f84e72d6832fef1/rpds_py-0.24.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:493fe54318bed7d124ce272fc36adbf59d46729659b2c792e87c3b95649cdee9", size = 447369 }, + { url = "https://files.pythonhosted.org/packages/c6/f3/428a9367077268f852db9b3b68b6eda6ee4594ab7dc2d603a2c370619cc0/rpds_py-0.24.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8aa362811ccdc1f8dadcc916c6d47e554169ab79559319ae9fae7d7752d0d60c", size = 390012 }, + { url = "https://files.pythonhosted.org/packages/55/66/24b61f14cd54e525583404afe6e3c221b309d1abd4b0b597a566dd8ee42d/rpds_py-0.24.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:d8f9a6e7fd5434817526815f09ea27f2746c4a51ee11bb3439065f5fc754db58", size = 421576 }, + { url = "https://files.pythonhosted.org/packages/22/56/18b81a4f0550e0d4be700cdcf1415ebf250fd21f9a5a775843dd3588dbf6/rpds_py-0.24.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:8205ee14463248d3349131bb8099efe15cd3ce83b8ef3ace63c7e976998e7124", size = 565562 }, + { url = "https://files.pythonhosted.org/packages/42/80/82a935d78f74974f82d38e83fb02430f8e8cc09ad35e06d9a5d2e9b907a7/rpds_py-0.24.0-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:921ae54f9ecba3b6325df425cf72c074cd469dea843fb5743a26ca7fb2ccb149", size = 592924 }, + { url = "https://files.pythonhosted.org/packages/0d/49/b717e7b93c2ca881d2dac8b23b3a87a4c30f7c762bfd3df0b3953e655f13/rpds_py-0.24.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:32bab0a56eac685828e00cc2f5d1200c548f8bc11f2e44abf311d6b548ce2e45", size = 560847 }, + { url = "https://files.pythonhosted.org/packages/1e/26/ba630a291238e7f42d25bc5569d152623f18c21e9183e506585b23325c48/rpds_py-0.24.0-cp39-cp39-win32.whl", hash = "sha256:f5c0ed12926dec1dfe7d645333ea59cf93f4d07750986a586f511c0bc61fe103", size = 222570 }, + { url = "https://files.pythonhosted.org/packages/2d/84/01126e25e21f2ed6e63ec4030f78793dfee1a21aff1842136353c9caaed9/rpds_py-0.24.0-cp39-cp39-win_amd64.whl", hash = "sha256:afc6e35f344490faa8276b5f2f7cbf71f88bc2cda4328e00553bd451728c571f", size = 234931 }, + { url = "https://files.pythonhosted.org/packages/99/48/11dae46d0c7f7e156ca0971a83f89c510af0316cd5d42c771b7cef945f0c/rpds_py-0.24.0-pp310-pypy310_pp73-macosx_10_12_x86_64.whl", hash = "sha256:619ca56a5468f933d940e1bf431c6f4e13bef8e688698b067ae68eb4f9b30e3a", size = 378224 }, + { url = "https://files.pythonhosted.org/packages/33/18/e8398d255369e35d312942f3bb8ecaff013c44968904891be2ab63b3aa94/rpds_py-0.24.0-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:4b28e5122829181de1898c2c97f81c0b3246d49f585f22743a1246420bb8d399", size = 363252 }, + { url = "https://files.pythonhosted.org/packages/17/39/dd73ba691f4df3e6834bf982de214086ac3359ab3ac035adfb30041570e3/rpds_py-0.24.0-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e8e5ab32cf9eb3647450bc74eb201b27c185d3857276162c101c0f8c6374e098", size = 388871 }, + { url = "https://files.pythonhosted.org/packages/2f/2e/da0530b25cabd0feca2a759b899d2df325069a94281eeea8ac44c6cfeff7/rpds_py-0.24.0-pp310-pypy310_pp73-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:208b3a70a98cf3710e97cabdc308a51cd4f28aa6e7bb11de3d56cd8b74bab98d", size = 394766 }, + { url = "https://files.pythonhosted.org/packages/4c/ee/dd1c5040a431beb40fad4a5d7868acf343444b0bc43e627c71df2506538b/rpds_py-0.24.0-pp310-pypy310_pp73-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:bbc4362e06f950c62cad3d4abf1191021b2ffaf0b31ac230fbf0526453eee75e", size = 448712 }, + { url = "https://files.pythonhosted.org/packages/f5/ec/6b93ffbb686be948e4d91ec76f4e6757f8551034b2a8176dd848103a1e34/rpds_py-0.24.0-pp310-pypy310_pp73-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:ebea2821cdb5f9fef44933617be76185b80150632736f3d76e54829ab4a3b4d1", size = 447150 }, + { url = "https://files.pythonhosted.org/packages/55/d5/a1c23760adad85b432df074ced6f910dd28f222b8c60aeace5aeb9a6654e/rpds_py-0.24.0-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b9a4df06c35465ef4d81799999bba810c68d29972bf1c31db61bfdb81dd9d5bb", size = 390662 }, + { url = "https://files.pythonhosted.org/packages/a5/f3/419cb1f9bfbd3a48c256528c156e00f3349e3edce5ad50cbc141e71f66a5/rpds_py-0.24.0-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:d3aa13bdf38630da298f2e0d77aca967b200b8cc1473ea05248f6c5e9c9bdb44", size = 421351 }, + { url = "https://files.pythonhosted.org/packages/98/8e/62d1a55078e5ede0b3b09f35e751fa35924a34a0d44d7c760743383cd54a/rpds_py-0.24.0-pp310-pypy310_pp73-musllinux_1_2_aarch64.whl", hash = "sha256:041f00419e1da7a03c46042453598479f45be3d787eb837af382bfc169c0db33", size = 566074 }, + { url = "https://files.pythonhosted.org/packages/fc/69/b7d1003166d78685da032b3c4ff1599fa536a3cfe6e5ce2da87c9c431906/rpds_py-0.24.0-pp310-pypy310_pp73-musllinux_1_2_i686.whl", hash = "sha256:d8754d872a5dfc3c5bf9c0e059e8107451364a30d9fd50f1f1a85c4fb9481164", size = 592398 }, + { url = "https://files.pythonhosted.org/packages/ea/a8/1c98bc99338c37faadd28dd667d336df7409d77b4da999506a0b6b1c0aa2/rpds_py-0.24.0-pp310-pypy310_pp73-musllinux_1_2_x86_64.whl", hash = "sha256:896c41007931217a343eff197c34513c154267636c8056fb409eafd494c3dcdc", size = 561114 }, + { url = "https://files.pythonhosted.org/packages/2b/41/65c91443685a4c7b5f1dd271beadc4a3e063d57c3269221548dd9416e15c/rpds_py-0.24.0-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:92558d37d872e808944c3c96d0423b8604879a3d1c86fdad508d7ed91ea547d5", size = 235548 }, + { url = "https://files.pythonhosted.org/packages/65/53/40bcc246a8354530d51a26d2b5b9afd1deacfb0d79e67295cc74df362f52/rpds_py-0.24.0-pp311-pypy311_pp73-macosx_10_12_x86_64.whl", hash = "sha256:f9e0057a509e096e47c87f753136c9b10d7a91842d8042c2ee6866899a717c0d", size = 378386 }, + { url = "https://files.pythonhosted.org/packages/80/b0/5ea97dd2f53e3618560aa1f9674e896e63dff95a9b796879a201bc4c1f00/rpds_py-0.24.0-pp311-pypy311_pp73-macosx_11_0_arm64.whl", hash = "sha256:d6e109a454412ab82979c5b1b3aee0604eca4bbf9a02693bb9df027af2bfa91a", size = 363440 }, + { url = "https://files.pythonhosted.org/packages/57/9d/259b6eada6f747cdd60c9a5eb3efab15f6704c182547149926c38e5bd0d5/rpds_py-0.24.0-pp311-pypy311_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:fc1c892b1ec1f8cbd5da8de287577b455e388d9c328ad592eabbdcb6fc93bee5", size = 388816 }, + { url = "https://files.pythonhosted.org/packages/94/c1/faafc7183712f89f4b7620c3c15979ada13df137d35ef3011ae83e93b005/rpds_py-0.24.0-pp311-pypy311_pp73-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:9c39438c55983d48f4bb3487734d040e22dad200dab22c41e331cee145e7a50d", size = 395058 }, + { url = "https://files.pythonhosted.org/packages/6c/96/d7fa9d2a7b7604a61da201cc0306a355006254942093779d7121c64700ce/rpds_py-0.24.0-pp311-pypy311_pp73-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9d7e8ce990ae17dda686f7e82fd41a055c668e13ddcf058e7fb5e9da20b57793", size = 448692 }, + { url = "https://files.pythonhosted.org/packages/96/37/a3146c6eebc65d6d8c96cc5ffdcdb6af2987412c789004213227fbe52467/rpds_py-0.24.0-pp311-pypy311_pp73-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9ea7f4174d2e4194289cb0c4e172d83e79a6404297ff95f2875cf9ac9bced8ba", size = 446462 }, + { url = "https://files.pythonhosted.org/packages/1f/13/6481dfd9ac7de43acdaaa416e3a7da40bc4bb8f5c6ca85e794100aa54596/rpds_py-0.24.0-pp311-pypy311_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bb2954155bb8f63bb19d56d80e5e5320b61d71084617ed89efedb861a684baea", size = 390460 }, + { url = "https://files.pythonhosted.org/packages/61/e1/37e36bce65e109543cc4ff8d23206908649023549604fa2e7fbeba5342f7/rpds_py-0.24.0-pp311-pypy311_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:04f2b712a2206e13800a8136b07aaedc23af3facab84918e7aa89e4be0260032", size = 421609 }, + { url = "https://files.pythonhosted.org/packages/20/dd/1f1a923d6cd798b8582176aca8a0784676f1a0449fb6f07fce6ac1cdbfb6/rpds_py-0.24.0-pp311-pypy311_pp73-musllinux_1_2_aarch64.whl", hash = "sha256:eda5c1e2a715a4cbbca2d6d304988460942551e4e5e3b7457b50943cd741626d", size = 565818 }, + { url = "https://files.pythonhosted.org/packages/56/ec/d8da6df6a1eb3a418944a17b1cb38dd430b9e5a2e972eafd2b06f10c7c46/rpds_py-0.24.0-pp311-pypy311_pp73-musllinux_1_2_i686.whl", hash = "sha256:9abc80fe8c1f87218db116016de575a7998ab1629078c90840e8d11ab423ee25", size = 592627 }, + { url = "https://files.pythonhosted.org/packages/b3/14/c492b9c7d5dd133e13f211ddea6bb9870f99e4f73932f11aa00bc09a9be9/rpds_py-0.24.0-pp311-pypy311_pp73-musllinux_1_2_x86_64.whl", hash = "sha256:6a727fd083009bc83eb83d6950f0c32b3c94c8b80a9b667c87f4bd1274ca30ba", size = 560885 }, + { url = "https://files.pythonhosted.org/packages/ef/e2/16cbbd7aaa4deaaeef5c90fee8b485c8b3312094cdad31e8006f5a3e5e08/rpds_py-0.24.0-pp39-pypy39_pp73-macosx_10_12_x86_64.whl", hash = "sha256:e0f3ef95795efcd3b2ec3fe0a5bcfb5dadf5e3996ea2117427e524d4fbf309c6", size = 378245 }, + { url = "https://files.pythonhosted.org/packages/d4/8c/5024dd105bf0a515576b7df8aeeba6556ffdbe2d636dee172c1a30497dd1/rpds_py-0.24.0-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:2c13777ecdbbba2077670285dd1fe50828c8742f6a4119dbef6f83ea13ad10fb", size = 363461 }, + { url = "https://files.pythonhosted.org/packages/a4/6f/3a4efcfa2f4391b69f5d0ed3e6be5d2c5468c24fd2d15b712d2dbefc1749/rpds_py-0.24.0-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:79e8d804c2ccd618417e96720ad5cd076a86fa3f8cb310ea386a3e6229bae7d1", size = 388839 }, + { url = "https://files.pythonhosted.org/packages/6c/d2/b8e5f0a0e97d295a0ebceb5265ef2e44c3d55e0d0f938d64a5ecfffa715e/rpds_py-0.24.0-pp39-pypy39_pp73-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:fd822f019ccccd75c832deb7aa040bb02d70a92eb15a2f16c7987b7ad4ee8d83", size = 394860 }, + { url = "https://files.pythonhosted.org/packages/90/e9/9f1f297bdbc5b871826ad790b6641fc40532d97917916e6bd9f87fdd128d/rpds_py-0.24.0-pp39-pypy39_pp73-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:0047638c3aa0dbcd0ab99ed1e549bbf0e142c9ecc173b6492868432d8989a046", size = 449314 }, + { url = "https://files.pythonhosted.org/packages/06/ad/62ddbbaead31a1a22f0332958d0ea7c7aeed1b2536c6a51dd66dfae321a2/rpds_py-0.24.0-pp39-pypy39_pp73-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a5b66d1b201cc71bc3081bc2f1fc36b0c1f268b773e03bbc39066651b9e18391", size = 446376 }, + { url = "https://files.pythonhosted.org/packages/82/a7/05b660d2f3789506e98be69aaf2ccde94e0fc49cd26cd78d7069bc5ba1b8/rpds_py-0.24.0-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dbcbb6db5582ea33ce46a5d20a5793134b5365110d84df4e30b9d37c6fd40ad3", size = 390560 }, + { url = "https://files.pythonhosted.org/packages/66/1b/79fa0abffb802ff817821a148ce752eaaab87ba3a6a5e6b9f244c00c73d0/rpds_py-0.24.0-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:63981feca3f110ed132fd217bf7768ee8ed738a55549883628ee3da75bb9cb78", size = 421225 }, + { url = "https://files.pythonhosted.org/packages/6e/9b/368893ad2f7b2ece42cad87c7ec71309b5d93188db28b307eadb48cd28e5/rpds_py-0.24.0-pp39-pypy39_pp73-musllinux_1_2_aarch64.whl", hash = "sha256:3a55fc10fdcbf1a4bd3c018eea422c52cf08700cf99c28b5cb10fe97ab77a0d3", size = 566071 }, + { url = "https://files.pythonhosted.org/packages/41/75/1cd0a654d300449411e6fd0821f83c1cfc7223da2e8109f586b4d9b89054/rpds_py-0.24.0-pp39-pypy39_pp73-musllinux_1_2_i686.whl", hash = "sha256:c30ff468163a48535ee7e9bf21bd14c7a81147c0e58a36c1078289a8ca7af0bd", size = 592334 }, + { url = "https://files.pythonhosted.org/packages/31/33/5905e2a2e7612218e25307a9255fc8671b977449d40d62fe317775fe4939/rpds_py-0.24.0-pp39-pypy39_pp73-musllinux_1_2_x86_64.whl", hash = "sha256:369d9c6d4c714e36d4a03957b4783217a3ccd1e222cdd67d464a3a479fc17796", size = 561111 }, + { url = "https://files.pythonhosted.org/packages/64/bd/f4cc34ac2261a7cb8a48bc90ce1e36dc05f1ec5ac3b4537def20be5df555/rpds_py-0.24.0-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:24795c099453e3721fda5d8ddd45f5dfcc8e5a547ce7b8e9da06fecc3832e26f", size = 235168 }, +] + +[[package]] +name = "six" +version = "1.17.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/94/e7/b2c673351809dca68a0e064b6af791aa332cf192da575fd474ed7d6f16a2/six-1.17.0.tar.gz", hash = "sha256:ff70335d468e7eb6ec65b95b99d3a2836546063f63acc5171de367e834932a81", size = 34031 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/b7/ce/149a00dd41f10bc29e5921b496af8b574d8413afcd5e30dfa0ed46c2cc5e/six-1.17.0-py2.py3-none-any.whl", hash = "sha256:4721f391ed90541fddacab5acf947aa0d3dc7d27b2e1e8eda2be8970586c3274", size = 11050 }, +] + +[[package]] +name = "tomli" +version = "2.2.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/18/87/302344fed471e44a87289cf4967697d07e532f2421fdaf868a303cbae4ff/tomli-2.2.1.tar.gz", hash = "sha256:cd45e1dc79c835ce60f7404ec8119f2eb06d38b1deba146f07ced3bbc44505ff", size = 17175 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/43/ca/75707e6efa2b37c77dadb324ae7d9571cb424e61ea73fad7c56c2d14527f/tomli-2.2.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:678e4fa69e4575eb77d103de3df8a895e1591b48e740211bd1067378c69e8249", size = 131077 }, + { url = "https://files.pythonhosted.org/packages/c7/16/51ae563a8615d472fdbffc43a3f3d46588c264ac4f024f63f01283becfbb/tomli-2.2.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:023aa114dd824ade0100497eb2318602af309e5a55595f76b626d6d9f3b7b0a6", size = 123429 }, + { url = "https://files.pythonhosted.org/packages/f1/dd/4f6cd1e7b160041db83c694abc78e100473c15d54620083dbd5aae7b990e/tomli-2.2.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ece47d672db52ac607a3d9599a9d48dcb2f2f735c6c2d1f34130085bb12b112a", size = 226067 }, + { url = "https://files.pythonhosted.org/packages/a9/6b/c54ede5dc70d648cc6361eaf429304b02f2871a345bbdd51e993d6cdf550/tomli-2.2.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6972ca9c9cc9f0acaa56a8ca1ff51e7af152a9f87fb64623e31d5c83700080ee", size = 236030 }, + { url = "https://files.pythonhosted.org/packages/1f/47/999514fa49cfaf7a92c805a86c3c43f4215621855d151b61c602abb38091/tomli-2.2.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c954d2250168d28797dd4e3ac5cf812a406cd5a92674ee4c8f123c889786aa8e", size = 240898 }, + { url = "https://files.pythonhosted.org/packages/73/41/0a01279a7ae09ee1573b423318e7934674ce06eb33f50936655071d81a24/tomli-2.2.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:8dd28b3e155b80f4d54beb40a441d366adcfe740969820caf156c019fb5c7ec4", size = 229894 }, + { url = "https://files.pythonhosted.org/packages/55/18/5d8bc5b0a0362311ce4d18830a5d28943667599a60d20118074ea1b01bb7/tomli-2.2.1-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:e59e304978767a54663af13c07b3d1af22ddee3bb2fb0618ca1593e4f593a106", size = 245319 }, + { url = "https://files.pythonhosted.org/packages/92/a3/7ade0576d17f3cdf5ff44d61390d4b3febb8a9fc2b480c75c47ea048c646/tomli-2.2.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:33580bccab0338d00994d7f16f4c4ec25b776af3ffaac1ed74e0b3fc95e885a8", size = 238273 }, + { url = "https://files.pythonhosted.org/packages/72/6f/fa64ef058ac1446a1e51110c375339b3ec6be245af9d14c87c4a6412dd32/tomli-2.2.1-cp311-cp311-win32.whl", hash = "sha256:465af0e0875402f1d226519c9904f37254b3045fc5084697cefb9bdde1ff99ff", size = 98310 }, + { url = "https://files.pythonhosted.org/packages/6a/1c/4a2dcde4a51b81be3530565e92eda625d94dafb46dbeb15069df4caffc34/tomli-2.2.1-cp311-cp311-win_amd64.whl", hash = "sha256:2d0f2fdd22b02c6d81637a3c95f8cd77f995846af7414c5c4b8d0545afa1bc4b", size = 108309 }, + { url = "https://files.pythonhosted.org/packages/52/e1/f8af4c2fcde17500422858155aeb0d7e93477a0d59a98e56cbfe75070fd0/tomli-2.2.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:4a8f6e44de52d5e6c657c9fe83b562f5f4256d8ebbfe4ff922c495620a7f6cea", size = 132762 }, + { url = "https://files.pythonhosted.org/packages/03/b8/152c68bb84fc00396b83e7bbddd5ec0bd3dd409db4195e2a9b3e398ad2e3/tomli-2.2.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:8d57ca8095a641b8237d5b079147646153d22552f1c637fd3ba7f4b0b29167a8", size = 123453 }, + { url = "https://files.pythonhosted.org/packages/c8/d6/fc9267af9166f79ac528ff7e8c55c8181ded34eb4b0e93daa767b8841573/tomli-2.2.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4e340144ad7ae1533cb897d406382b4b6fede8890a03738ff1683af800d54192", size = 233486 }, + { url = "https://files.pythonhosted.org/packages/5c/51/51c3f2884d7bab89af25f678447ea7d297b53b5a3b5730a7cb2ef6069f07/tomli-2.2.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:db2b95f9de79181805df90bedc5a5ab4c165e6ec3fe99f970d0e302f384ad222", size = 242349 }, + { url = "https://files.pythonhosted.org/packages/ab/df/bfa89627d13a5cc22402e441e8a931ef2108403db390ff3345c05253935e/tomli-2.2.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:40741994320b232529c802f8bc86da4e1aa9f413db394617b9a256ae0f9a7f77", size = 252159 }, + { url = "https://files.pythonhosted.org/packages/9e/6e/fa2b916dced65763a5168c6ccb91066f7639bdc88b48adda990db10c8c0b/tomli-2.2.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:400e720fe168c0f8521520190686ef8ef033fb19fc493da09779e592861b78c6", size = 237243 }, + { url = "https://files.pythonhosted.org/packages/b4/04/885d3b1f650e1153cbb93a6a9782c58a972b94ea4483ae4ac5cedd5e4a09/tomli-2.2.1-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:02abe224de6ae62c19f090f68da4e27b10af2b93213d36cf44e6e1c5abd19fdd", size = 259645 }, + { url = "https://files.pythonhosted.org/packages/9c/de/6b432d66e986e501586da298e28ebeefd3edc2c780f3ad73d22566034239/tomli-2.2.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:b82ebccc8c8a36f2094e969560a1b836758481f3dc360ce9a3277c65f374285e", size = 244584 }, + { url = "https://files.pythonhosted.org/packages/1c/9a/47c0449b98e6e7d1be6cbac02f93dd79003234ddc4aaab6ba07a9a7482e2/tomli-2.2.1-cp312-cp312-win32.whl", hash = "sha256:889f80ef92701b9dbb224e49ec87c645ce5df3fa2cc548664eb8a25e03127a98", size = 98875 }, + { url = "https://files.pythonhosted.org/packages/ef/60/9b9638f081c6f1261e2688bd487625cd1e660d0a85bd469e91d8db969734/tomli-2.2.1-cp312-cp312-win_amd64.whl", hash = "sha256:7fc04e92e1d624a4a63c76474610238576942d6b8950a2d7f908a340494e67e4", size = 109418 }, + { url = "https://files.pythonhosted.org/packages/04/90/2ee5f2e0362cb8a0b6499dc44f4d7d48f8fff06d28ba46e6f1eaa61a1388/tomli-2.2.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:f4039b9cbc3048b2416cc57ab3bda989a6fcf9b36cf8937f01a6e731b64f80d7", size = 132708 }, + { url = "https://files.pythonhosted.org/packages/c0/ec/46b4108816de6b385141f082ba99e315501ccd0a2ea23db4a100dd3990ea/tomli-2.2.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:286f0ca2ffeeb5b9bd4fcc8d6c330534323ec51b2f52da063b11c502da16f30c", size = 123582 }, + { url = "https://files.pythonhosted.org/packages/a0/bd/b470466d0137b37b68d24556c38a0cc819e8febe392d5b199dcd7f578365/tomli-2.2.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a92ef1a44547e894e2a17d24e7557a5e85a9e1d0048b0b5e7541f76c5032cb13", size = 232543 }, + { url = "https://files.pythonhosted.org/packages/d9/e5/82e80ff3b751373f7cead2815bcbe2d51c895b3c990686741a8e56ec42ab/tomli-2.2.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9316dc65bed1684c9a98ee68759ceaed29d229e985297003e494aa825ebb0281", size = 241691 }, + { url = "https://files.pythonhosted.org/packages/05/7e/2a110bc2713557d6a1bfb06af23dd01e7dde52b6ee7dadc589868f9abfac/tomli-2.2.1-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e85e99945e688e32d5a35c1ff38ed0b3f41f43fad8df0bdf79f72b2ba7bc5272", size = 251170 }, + { url = "https://files.pythonhosted.org/packages/64/7b/22d713946efe00e0adbcdfd6d1aa119ae03fd0b60ebed51ebb3fa9f5a2e5/tomli-2.2.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:ac065718db92ca818f8d6141b5f66369833d4a80a9d74435a268c52bdfa73140", size = 236530 }, + { url = "https://files.pythonhosted.org/packages/38/31/3a76f67da4b0cf37b742ca76beaf819dca0ebef26d78fc794a576e08accf/tomli-2.2.1-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:d920f33822747519673ee656a4b6ac33e382eca9d331c87770faa3eef562aeb2", size = 258666 }, + { url = "https://files.pythonhosted.org/packages/07/10/5af1293da642aded87e8a988753945d0cf7e00a9452d3911dd3bb354c9e2/tomli-2.2.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:a198f10c4d1b1375d7687bc25294306e551bf1abfa4eace6650070a5c1ae2744", size = 243954 }, + { url = "https://files.pythonhosted.org/packages/5b/b9/1ed31d167be802da0fc95020d04cd27b7d7065cc6fbefdd2f9186f60d7bd/tomli-2.2.1-cp313-cp313-win32.whl", hash = "sha256:d3f5614314d758649ab2ab3a62d4f2004c825922f9e370b29416484086b264ec", size = 98724 }, + { url = "https://files.pythonhosted.org/packages/c7/32/b0963458706accd9afcfeb867c0f9175a741bf7b19cd424230714d722198/tomli-2.2.1-cp313-cp313-win_amd64.whl", hash = "sha256:a38aa0308e754b0e3c67e344754dff64999ff9b513e691d0e786265c93583c69", size = 109383 }, + { url = "https://files.pythonhosted.org/packages/6e/c2/61d3e0f47e2b74ef40a68b9e6ad5984f6241a942f7cd3bbfbdbd03861ea9/tomli-2.2.1-py3-none-any.whl", hash = "sha256:cb55c73c5f4408779d0cf3eef9f762b9c9f147a77de7b258bef0a5628adc85cc", size = 14257 }, +] + +[[package]] +name = "typing-extensions" +version = "4.13.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/0e/3e/b00a62db91a83fff600de219b6ea9908e6918664899a2d85db222f4fbf19/typing_extensions-4.13.0.tar.gz", hash = "sha256:0a4ac55a5820789d87e297727d229866c9650f6521b64206413c4fbada24d95b", size = 106520 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/e0/86/39b65d676ec5732de17b7e3c476e45bb80ec64eb50737a8dce1a4178aba1/typing_extensions-4.13.0-py3-none-any.whl", hash = "sha256:c8dd92cc0d6425a97c18fbb9d1954e5ff92c1ca881a309c45f06ebc0b79058e5", size = 45683 }, +] + +[[package]] +name = "tzdata" +version = "2025.2" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/95/32/1a225d6164441be760d75c2c42e2780dc0873fe382da3e98a2e1e48361e5/tzdata-2025.2.tar.gz", hash = "sha256:b60a638fcc0daffadf82fe0f57e53d06bdec2f36c4df66280ae79bce6bd6f2b9", size = 196380 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/5c/23/c7abc0ca0a1526a0774eca151daeb8de62ec457e77262b66b359c3c7679e/tzdata-2025.2-py2.py3-none-any.whl", hash = "sha256:1a403fada01ff9221ca8044d701868fa132215d84beb92242d9acd2147f667a8", size = 347839 }, +] + +[[package]] +name = "urllib3" +version = "2.3.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/aa/63/e53da845320b757bf29ef6a9062f5c669fe997973f966045cb019c3f4b66/urllib3-2.3.0.tar.gz", hash = "sha256:f8c5449b3cf0861679ce7e0503c7b44b5ec981bec0d1d3795a07f1ba96f0204d", size = 307268 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/c8/19/4ec628951a74043532ca2cf5d97b7b14863931476d117c471e8e2b1eb39f/urllib3-2.3.0-py3-none-any.whl", hash = "sha256:1cee9ad369867bfdbbb48b7dd50374c0967a0bb7710050facf0dd6911440e3df", size = 128369 }, +] + +[[package]] +name = "zmq" +version = "0.0.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "pyzmq" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/6e/78/833b2808793c1619835edb1a4e17a023d5d625f4f97ff25ffff986d1f472/zmq-0.0.0.tar.gz", hash = "sha256:6b1a1de53338646e8c8405803cffb659e8eb7bb02fff4c9be62a7acfac8370c9", size = 966 }