Hugo Farajallah commited on
Commit
898ed95
·
1 Parent(s): 0e90d9f

feat(HF space): adds auto phonemization of the word.

Browse files
Files changed (5) hide show
  1. common.py +8 -2
  2. grapheme_to_phoneme.py +152 -0
  3. hf_space.py +81 -13
  4. pyproject.toml +1 -0
  5. uv.lock +234 -0
common.py CHANGED
@@ -1,3 +1,5 @@
 
 
1
  import numpy as np
2
  import torch
3
  import torchaudio
@@ -6,6 +8,9 @@ import wavlm_phoneme_fr_it
6
 
7
  SAMPLING_RATE = 16_000
8
 
 
 
 
9
 
10
  def get_model():
11
  checkpoint = "hugofara/wavlm-base-plus-phonemizer-fr-it"
@@ -44,7 +49,7 @@ def preprocess_audio(audio_data, target_sample_rate=SAMPLING_RATE):
44
  return audio
45
 
46
 
47
- def prepare_model_inputs(audio, processor, sampling_rate=SAMPLING_RATE):
48
  """Prepare inputs for the model"""
49
  inputs = processor(
50
  audio,
@@ -54,7 +59,8 @@ def prepare_model_inputs(audio, processor, sampling_rate=SAMPLING_RATE):
54
  )
55
 
56
  # Add language tensor (assuming French/Italian model)
57
- inputs["language"] = torch.tensor([[0]])
 
58
 
59
  return inputs
60
 
 
1
+ import enum
2
+
3
  import numpy as np
4
  import torch
5
  import torchaudio
 
8
 
9
  SAMPLING_RATE = 16_000
10
 
11
+ class Languages(enum.Enum):
12
+ FR = 0
13
+ IT = 1
14
 
15
  def get_model():
16
  checkpoint = "hugofara/wavlm-base-plus-phonemizer-fr-it"
 
49
  return audio
50
 
51
 
52
+ def prepare_model_inputs(audio, processor, sampling_rate=SAMPLING_RATE, language=Languages.FR):
53
  """Prepare inputs for the model"""
54
  inputs = processor(
55
  audio,
 
59
  )
60
 
61
  # Add language tensor (assuming French/Italian model)
62
+ language_code = 0. if language is Languages.FR else 1.
63
+ inputs["language"] = torch.tensor([[language_code]], dtype=torch.float32)
64
 
65
  return inputs
66
 
grapheme_to_phoneme.py ADDED
@@ -0,0 +1,152 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """
2
+ Customized phonemization wrapper.
3
+ Original wrapper by Lingjuan Zhu (@lingjzhu):
4
+ https://github.com/lingjzhu/text2phonemesequence
5
+
6
+ """
7
+ import csv
8
+ import json
9
+ import os
10
+ import re
11
+ import subprocess
12
+ import warnings
13
+
14
+ import segments
15
+ import torch
16
+ import transformers
17
+
18
+
19
+ class Grapheme2Phoneme:
20
+ def __init__(
21
+ self,
22
+ words_to_exclude=None,
23
+ tokenizer="google/byt5-small",
24
+ language="fr",
25
+ cuda=True,
26
+ folder_language="lang_dict",
27
+ ):
28
+ """
29
+ Load the rules to convert from a language to the corresponding phonemes.
30
+
31
+ :param list words_to_exclude: List of words to exclude from phonemization.
32
+ :param str tokenizer: Pre-trained tokenizer model name.
33
+ :param str language: Language code for phonemization. Two letters only (e.g.: "fr")
34
+ :param bool cuda: Flag to use CUDA for GPU acceleration.
35
+ :param str folder_language: Folder path to save language dictionaries.
36
+ """
37
+ self.tokenizer = transformers.AutoTokenizer.from_pretrained(tokenizer)
38
+ self.model = transformers.T5ForConditionalGeneration.from_pretrained(
39
+ "charsiu/g2p_multilingual_byT5_small_100"
40
+ )
41
+ device = "cpu"
42
+ if cuda:
43
+ if torch.cuda.is_available():
44
+ device = "cuda:0"
45
+ else:
46
+ warnings.warn("CUDA is not available but was requested")
47
+ self.device = torch.device(device)
48
+ self.model = self.model.to(self.device)
49
+ if words_to_exclude is None:
50
+ words_to_exclude = ["[UNK]"]
51
+ self.exclude_token = words_to_exclude
52
+ self.segment_tool = segments.Tokenizer()
53
+ self.language = {
54
+ "fr": "fra",
55
+ "it": "ita"
56
+ }[language]
57
+ self.phone_dict = {}
58
+ # Download language dictionary if not exists
59
+ os.makedirs(folder_language, exist_ok=True)
60
+ language_path = os.path.join(folder_language, self.language + ".tsv")
61
+ if not os.path.exists(language_path):
62
+ subprocess.run(
63
+ [
64
+ "wget",
65
+ "-O",
66
+ language_path,
67
+ f"https://raw.githubusercontent.com/lingjzhu/CharsiuG2P/main/dicts/{self.language}.tsv"
68
+ ],
69
+ check=True
70
+ )
71
+ # Setting phonemes length
72
+ config_path = "configs/phoneme_lengths.json"
73
+ if os.path.exists(config_path):
74
+ with open(config_path, "r", encoding="utf-8") as file:
75
+ self.phoneme_lengths = json.load(file)
76
+ else:
77
+ warnings.warn("Loading dummy values for phonemes lengths!")
78
+ self.phoneme_lengths = {
79
+ "fra.tsv": 50,
80
+ "ita.tsv": 50
81
+ }
82
+ if os.path.exists(language_path):
83
+ with open(language_path, "r", encoding="utf-8") as file:
84
+ tsv_file = csv.reader(file, delimiter="\t")
85
+ # printing data line by line
86
+ for word_phonemes in tsv_file:
87
+ assert len(word_phonemes) == 2
88
+ self.phone_dict[word_phonemes[0]] = [word_phonemes[1].split(",")[0]]
89
+
90
+ def phonemize(self, words):
91
+ """
92
+ Convert text to phonemes using the T5 model.
93
+
94
+ :param list[str] words: Input text to be converted.
95
+ :return list[str]: Phonemized words.
96
+ """
97
+ phonemes_list = [""] * len(words)
98
+ new_words = []
99
+ for i, word in enumerate(words):
100
+ # First normalize the spacing around special tokens
101
+ word = re.sub(r"(?<!\s)\[PAD](?!\s)", r"<pad>", word)
102
+ word = re.sub(r"(?<!\s)\[UNK](?!\s)", r"<unk>", word)
103
+ # Then collapse multiple spaces
104
+ word = re.sub(r" +", " ", word).strip()
105
+ if word in self.phone_dict:
106
+ phonemes_list[i] = self.phone_dict[word][0]
107
+ elif word in self.exclude_token:
108
+ phonemes_list[i] = word
109
+ else:
110
+ new_words.append((i, word))
111
+
112
+ # Then batch the unknown words
113
+ if new_words:
114
+ out = self.tokenizer(
115
+ [f"<{self.language}>: {word[1]}" for word in new_words],
116
+ padding=True,
117
+ add_special_tokens=False,
118
+ return_tensors="pt",
119
+ )
120
+ predictions = self.model.generate(
121
+ input_ids=out["input_ids"].to(self.device),
122
+ attention_mask=out["attention_mask"].to(self.device),
123
+ num_beams=1,
124
+ max_length=self.phoneme_lengths[self.language + ".tsv"],
125
+ )
126
+ phonemes = self.tokenizer.batch_decode(
127
+ predictions, skip_special_tokens=True
128
+ )
129
+ for i, phonemized in enumerate(phonemes):
130
+ phonemes_list[new_words[i][0]] = phonemized
131
+
132
+ for i, phoneme in enumerate(phonemes_list):
133
+ # skip excluded tokens of segmentation
134
+ if phoneme not in self.exclude_token:
135
+ try:
136
+ phonemes_list[i] = self.segment_tool(phoneme, ipa=True)
137
+ except IndexError:
138
+ # Some phonemes may not be recognized
139
+ phonemes_list[i] = self.segment_tool(phoneme)
140
+
141
+ # fill gaps with padding token
142
+ return phonemes_list
143
+
144
+
145
+ if __name__ == "__main__":
146
+ phonemizer = Grapheme2Phoneme(language="it", cuda=False)
147
+ print(phonemizer.phonemize([
148
+ "cuore, prezzemolo", "margherita, girotondo",
149
+ "mepola, rofe", "presemma, costro",
150
+ "lada, vufebu", "nurto, frimace",
151
+ "banzione, ceglirate", "banzione, alcelisto"
152
+ ]))
hf_space.py CHANGED
@@ -1,22 +1,43 @@
1
  import gradio as gr
2
 
3
  import common
 
4
 
5
  model, processor = common.get_model()
6
 
 
 
 
7
 
8
- def process_audio(audio_data, target_word):
 
 
 
 
 
 
 
 
 
 
 
9
  """Process recorded audio and return ASR output with target word comparison"""
10
  if audio_data is None:
11
- return "Please record some audio first."
 
 
 
 
 
12
 
13
  # Preprocess audio
14
  audio = common.preprocess_audio(audio_data)
15
  if audio is None:
16
- return "Failed to process audio."
17
 
18
- # Prepare model inputs
19
- inputs = common.prepare_model_inputs(audio, processor)
 
20
 
21
  # Run inference
22
  outputs, predicted_ids = common.run_inference(model, inputs)
@@ -24,8 +45,24 @@ def process_audio(audio_data, target_word):
24
  # Decode transcription
25
  transcription = common.decode_transcription(processor, predicted_ids)
26
 
27
- # Compare with target word
28
- return common.compare_with_target(transcription, target_word)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
29
 
30
 
31
  def create_interface():
@@ -37,10 +74,24 @@ def create_interface():
37
 
38
  with gr.Row():
39
  with gr.Column():
 
 
 
 
 
 
 
40
  target_word_input = gr.Textbox(
41
  label="Target Word (optional)",
42
  placeholder="Enter a word you expect to say...",
43
- info="Leave empty to just get the transcription"
 
 
 
 
 
 
 
44
  )
45
 
46
  audio_input = gr.Audio(
@@ -53,21 +104,38 @@ def create_interface():
53
 
54
  with gr.Column():
55
  output_text = gr.Markdown(
56
- label="Results",
57
  value="Results will appear here after processing..."
58
  )
59
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
60
  process_btn.click(
61
  fn=process_audio,
62
- inputs=[audio_input, target_word_input],
63
- outputs=output_text
64
  )
65
 
66
  # Auto-process when audio is recorded
67
  audio_input.change(
68
  fn=process_audio,
69
- inputs=[audio_input, target_word_input],
70
- outputs=output_text
71
  )
72
 
73
  return demo
 
1
  import gradio as gr
2
 
3
  import common
4
+ from grapheme_to_phoneme import Grapheme2Phoneme
5
 
6
  model, processor = common.get_model()
7
 
8
+ # Initialize phonemizers for both languages
9
+ phonemizer_fr = Grapheme2Phoneme(language="fr", cuda=False)
10
+ phonemizer_it = Grapheme2Phoneme(language="it", cuda=False)
11
 
12
+
13
+ def phonemize_text(text, language):
14
+ """Convert text to phonemes using the appropriate phonemizer"""
15
+ if not text or not text.strip():
16
+ return ""
17
+
18
+ phonemizer = phonemizer_fr if language == "French" else phonemizer_it
19
+ phonemes = phonemizer.phonemize([text.strip()])
20
+ return " ".join([word.replace(" ", "") for word in phonemes]) if phonemes and phonemes[0] else ""
21
+
22
+
23
+ def process_audio(audio_data, target_word, language):
24
  """Process recorded audio and return ASR output with target word comparison"""
25
  if audio_data is None:
26
+ return "Please record some audio first.", ""
27
+
28
+ # Convert target word to phonemes if provided
29
+ phonemized_target = ""
30
+ if target_word and target_word.strip():
31
+ phonemized_target = phonemize_text(target_word, language)
32
 
33
  # Preprocess audio
34
  audio = common.preprocess_audio(audio_data)
35
  if audio is None:
36
+ return "Failed to process audio.", ""
37
 
38
+ # Prepare model inputs with correct language
39
+ lang_enum = common.Languages.FR if language == "French" else common.Languages.IT
40
+ inputs = common.prepare_model_inputs(audio, processor, language=lang_enum)
41
 
42
  # Run inference
43
  outputs, predicted_ids = common.run_inference(model, inputs)
 
45
  # Decode transcription
46
  transcription = common.decode_transcription(processor, predicted_ids)
47
 
48
+ # Create detailed result
49
+ result = f"**Language:** {language}\n\n"
50
+ result += f"**Transcription:** {transcription}\n\n"
51
+
52
+ if target_word and target_word.strip():
53
+ result += f"**Target Word:** {target_word}\n"
54
+ result += f"**Target Phonemes:** {phonemized_target}\n\n"
55
+
56
+ # Compare phonemized versions
57
+ transcription_clean = transcription.lower().replace("[pad]", "").strip()
58
+ phonemized_target_clean = phonemized_target.lower().strip()
59
+
60
+ if phonemized_target_clean in transcription_clean:
61
+ result += f"✅ **Phoneme Match!** The phonemized target appears in the transcription."
62
+ else:
63
+ result += f"❌ **No phoneme match.** The phonemized target was not found in the transcription."
64
+
65
+ return result, phonemized_target
66
 
67
 
68
  def create_interface():
 
74
 
75
  with gr.Row():
76
  with gr.Column():
77
+ language_radio = gr.Radio(
78
+ choices=["French", "Italian"],
79
+ value="French",
80
+ label="Model Language",
81
+ info="Select the language for ASR recognition"
82
+ )
83
+
84
  target_word_input = gr.Textbox(
85
  label="Target Word (optional)",
86
  placeholder="Enter a word you expect to say...",
87
+ info="Will be converted to phonemes for comparison"
88
+ )
89
+
90
+ phonemes_display = gr.Textbox(
91
+ label="Target Phonemes",
92
+ interactive=False,
93
+ placeholder="Phonemes will appear here...",
94
+ info="Automatic phoneme conversion of your target word"
95
  )
96
 
97
  audio_input = gr.Audio(
 
104
 
105
  with gr.Column():
106
  output_text = gr.Markdown(
 
107
  value="Results will appear here after processing..."
108
  )
109
 
110
+ # Update phonemes when target word or language changes
111
+ def update_phonemes(text, language):
112
+ if text and text.strip():
113
+ return phonemize_text(text, language)
114
+ return ""
115
+
116
+ target_word_input.change(
117
+ fn=update_phonemes,
118
+ inputs=[target_word_input, language_radio],
119
+ outputs=phonemes_display
120
+ )
121
+
122
+ language_radio.change(
123
+ fn=update_phonemes,
124
+ inputs=[target_word_input, language_radio],
125
+ outputs=phonemes_display
126
+ )
127
+
128
  process_btn.click(
129
  fn=process_audio,
130
+ inputs=[audio_input, target_word_input, language_radio],
131
+ outputs=[output_text, phonemes_display]
132
  )
133
 
134
  # Auto-process when audio is recorded
135
  audio_input.change(
136
  fn=process_audio,
137
+ inputs=[audio_input, target_word_input, language_radio],
138
+ outputs=[output_text, phonemes_display]
139
  )
140
 
141
  return demo
pyproject.toml CHANGED
@@ -9,6 +9,7 @@ dependencies = [
9
  "matplotlib>=3.10.6",
10
  "numpy>=2.3.3",
11
  "pyqt6>=6.9.1",
 
12
  "sounddevice>=0.5.2",
13
  "torch>=2.8.0",
14
  "torchaudio>=2.8.0",
 
9
  "matplotlib>=3.10.6",
10
  "numpy>=2.3.3",
11
  "pyqt6>=6.9.1",
12
+ "segments>=2.3.0",
13
  "sounddevice>=0.5.2",
14
  "torch>=2.8.0",
15
  "torchaudio>=2.8.0",
uv.lock CHANGED
@@ -38,6 +38,15 @@ wheels = [
38
  { url = "https://files.pythonhosted.org/packages/6f/12/e5e0282d673bb9746bacfb6e2dba8719989d3660cdb2ea79aee9a9651afb/anyio-4.10.0-py3-none-any.whl", hash = "sha256:60e474ac86736bbfd6f210f7a61218939c318f43f9972497381f1c5e930ed3d1", size = 107213, upload-time = "2025-08-04T08:54:24.882Z" },
39
  ]
40
 
 
 
 
 
 
 
 
 
 
41
  [[package]]
42
  name = "audioop-lts"
43
  version = "0.2.2"
@@ -94,6 +103,15 @@ wheels = [
94
  { url = "https://files.pythonhosted.org/packages/f6/22/91616fe707a5c5510de2cac9b046a30defe7007ba8a0c04f9c08f27df312/audioop_lts-0.2.2-cp314-cp314t-win_arm64.whl", hash = "sha256:b492c3b040153e68b9fdaff5913305aaaba5bb433d8a7f73d5cf6a64ed3cc1dd", size = 25206, upload-time = "2025-08-05T16:43:16.444Z" },
95
  ]
96
 
 
 
 
 
 
 
 
 
 
97
  [[package]]
98
  name = "brotli"
99
  version = "1.1.0"
@@ -327,6 +345,28 @@ wheels = [
327
  { url = "https://files.pythonhosted.org/packages/ae/8c/469afb6465b853afff216f9528ffda78a915ff880ed58813ba4faf4ba0b6/contourpy-1.3.3-cp314-cp314t-win_arm64.whl", hash = "sha256:b7448cb5a725bb1e35ce88771b86fba35ef418952474492cf7c764059933ff8b", size = 203831, upload-time = "2025-07-26T12:02:51.449Z" },
328
  ]
329
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
330
  [[package]]
331
  name = "cycler"
332
  version = "0.12.1"
@@ -564,6 +604,15 @@ wheels = [
564
  { url = "https://files.pythonhosted.org/packages/76/c6/c88e154df9c4e1a2a66ccf0005a88dfb2650c1dffb6f5ce603dfbd452ce3/idna-3.10-py3-none-any.whl", hash = "sha256:946d195a0d259cbba61165e88e65941f16e9b36ea6ddb97f00452bae8b1287d3", size = 70442, upload-time = "2024-09-15T18:07:37.964Z" },
565
  ]
566
 
 
 
 
 
 
 
 
 
 
567
  [[package]]
568
  name = "jinja2"
569
  version = "3.1.6"
@@ -576,6 +625,33 @@ wheels = [
576
  { url = "https://files.pythonhosted.org/packages/62/a1/3d680cbfd5f4b8f15abc1d571870c5fc3e594bb582bc3b64ea099db13e56/jinja2-3.1.6-py3-none-any.whl", hash = "sha256:85ece4451f492d0c13c5dd7c13a64681a86afae63a5f347908daf103ce6d2f67", size = 134899, upload-time = "2025-03-05T20:05:00.369Z" },
577
  ]
578
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
579
  [[package]]
580
  name = "kiwisolver"
581
  version = "1.4.9"
@@ -648,6 +724,15 @@ wheels = [
648
  { url = "https://files.pythonhosted.org/packages/80/be/3578e8afd18c88cdf9cb4cffde75a96d2be38c5a903f1ed0ceec061bd09e/kiwisolver-1.4.9-cp314-cp314t-win_arm64.whl", hash = "sha256:4a48a2ce79d65d363597ef7b567ce3d14d68783d2b2263d98db3d9477805ba32", size = 70260, upload-time = "2025-08-10T21:27:36.606Z" },
649
  ]
650
 
 
 
 
 
 
 
 
 
 
651
  [[package]]
652
  name = "markdown-it-py"
653
  version = "4.0.0"
@@ -1323,6 +1408,32 @@ wheels = [
1323
  { url = "https://files.pythonhosted.org/packages/fa/de/02b54f42487e3d3c6efb3f89428677074ca7bf43aae402517bc7cca949f3/PyYAML-6.0.2-cp313-cp313-win_amd64.whl", hash = "sha256:8388ee1976c416731879ac16da0aff3f63b286ffdd57cdeb95f3f2e085687563", size = 156446, upload-time = "2024-08-06T20:33:04.33Z" },
1324
  ]
1325
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1326
  [[package]]
1327
  name = "regex"
1328
  version = "2025.9.1"
@@ -1388,6 +1499,15 @@ wheels = [
1388
  { url = "https://files.pythonhosted.org/packages/1e/db/4254e3eabe8020b458f1a747140d32277ec7a271daf1d235b70dc0b4e6e3/requests-2.32.5-py3-none-any.whl", hash = "sha256:2462f94637a34fd532264295e186976db0f5d453d1cdd31473c85a6a161affb6", size = 64738, upload-time = "2025-08-18T20:46:00.542Z" },
1389
  ]
1390
 
 
 
 
 
 
 
 
 
 
1391
  [[package]]
1392
  name = "rich"
1393
  version = "14.1.0"
@@ -1401,6 +1521,87 @@ wheels = [
1401
  { url = "https://files.pythonhosted.org/packages/e3/30/3c4d035596d3cf444529e0b2953ad0466f6049528a879d27534700580395/rich-14.1.0-py3-none-any.whl", hash = "sha256:536f5f1785986d6dbdea3c75205c473f970777b4a0d6c6dd1b696aa05a3fa04f", size = 243368, upload-time = "2025-07-25T07:32:56.73Z" },
1402
  ]
1403
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1404
  [[package]]
1405
  name = "ruff"
1406
  version = "0.13.1"
@@ -1461,6 +1662,19 @@ wheels = [
1461
  { url = "https://files.pythonhosted.org/packages/2c/c3/c0be1135726618dc1e28d181b8c442403d8dbb9e273fd791de2d4384bcdd/safetensors-0.6.2-cp38-abi3-win_amd64.whl", hash = "sha256:c7b214870df923cbc1593c3faee16bec59ea462758699bd3fee399d00aac072c", size = 320192, upload-time = "2025-08-08T13:13:59.467Z" },
1462
  ]
1463
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1464
  [[package]]
1465
  name = "semantic-version"
1466
  version = "2.10.0"
@@ -1546,6 +1760,15 @@ wheels = [
1546
  { url = "https://files.pythonhosted.org/packages/a2/09/77d55d46fd61b4a135c444fc97158ef34a095e5681d0a6c10b75bf356191/sympy-1.14.0-py3-none-any.whl", hash = "sha256:e091cc3e99d2141a0ba2847328f5479b05d94a6635cb96148ccb3f34671bd8f5", size = 6299353, upload-time = "2025-04-27T18:04:59.103Z" },
1547
  ]
1548
 
 
 
 
 
 
 
 
 
 
1549
  [[package]]
1550
  name = "tokenizers"
1551
  version = "0.22.0"
@@ -1749,6 +1972,15 @@ wheels = [
1749
  { url = "https://files.pythonhosted.org/packages/5c/23/c7abc0ca0a1526a0774eca151daeb8de62ec457e77262b66b359c3c7679e/tzdata-2025.2-py2.py3-none-any.whl", hash = "sha256:1a403fada01ff9221ca8044d701868fa132215d84beb92242d9acd2147f667a8", size = 347839, upload-time = "2025-03-23T13:54:41.845Z" },
1750
  ]
1751
 
 
 
 
 
 
 
 
 
 
1752
  [[package]]
1753
  name = "urllib3"
1754
  version = "2.5.0"
@@ -1780,6 +2012,7 @@ dependencies = [
1780
  { name = "matplotlib" },
1781
  { name = "numpy" },
1782
  { name = "pyqt6" },
 
1783
  { name = "sounddevice" },
1784
  { name = "torch" },
1785
  { name = "torchaudio" },
@@ -1793,6 +2026,7 @@ requires-dist = [
1793
  { name = "matplotlib", specifier = ">=3.10.6" },
1794
  { name = "numpy", specifier = ">=2.3.3" },
1795
  { name = "pyqt6", specifier = ">=6.9.1" },
 
1796
  { name = "sounddevice", specifier = ">=0.5.2" },
1797
  { name = "torch", specifier = ">=2.8.0" },
1798
  { name = "torchaudio", specifier = ">=2.8.0" },
 
38
  { url = "https://files.pythonhosted.org/packages/6f/12/e5e0282d673bb9746bacfb6e2dba8719989d3660cdb2ea79aee9a9651afb/anyio-4.10.0-py3-none-any.whl", hash = "sha256:60e474ac86736bbfd6f210f7a61218939c318f43f9972497381f1c5e930ed3d1", size = 107213, upload-time = "2025-08-04T08:54:24.882Z" },
39
  ]
40
 
41
+ [[package]]
42
+ name = "attrs"
43
+ version = "25.3.0"
44
+ source = { registry = "https://pypi.org/simple" }
45
+ sdist = { url = "https://files.pythonhosted.org/packages/5a/b0/1367933a8532ee6ff8d63537de4f1177af4bff9f3e829baf7331f595bb24/attrs-25.3.0.tar.gz", hash = "sha256:75d7cefc7fb576747b2c81b4442d4d4a1ce0900973527c011d1030fd3bf4af1b", size = 812032, upload-time = "2025-03-13T11:10:22.779Z" }
46
+ wheels = [
47
+ { url = "https://files.pythonhosted.org/packages/77/06/bb80f5f86020c4551da315d78b3ab75e8228f89f0162f2c3a819e407941a/attrs-25.3.0-py3-none-any.whl", hash = "sha256:427318ce031701fea540783410126f03899a97ffc6f61596ad581ac2e40e3bc3", size = 63815, upload-time = "2025-03-13T11:10:21.14Z" },
48
+ ]
49
+
50
  [[package]]
51
  name = "audioop-lts"
52
  version = "0.2.2"
 
103
  { url = "https://files.pythonhosted.org/packages/f6/22/91616fe707a5c5510de2cac9b046a30defe7007ba8a0c04f9c08f27df312/audioop_lts-0.2.2-cp314-cp314t-win_arm64.whl", hash = "sha256:b492c3b040153e68b9fdaff5913305aaaba5bb433d8a7f73d5cf6a64ed3cc1dd", size = 25206, upload-time = "2025-08-05T16:43:16.444Z" },
104
  ]
105
 
106
+ [[package]]
107
+ name = "babel"
108
+ version = "2.17.0"
109
+ source = { registry = "https://pypi.org/simple" }
110
+ sdist = { url = "https://files.pythonhosted.org/packages/7d/6b/d52e42361e1aa00709585ecc30b3f9684b3ab62530771402248b1b1d6240/babel-2.17.0.tar.gz", hash = "sha256:0c54cffb19f690cdcc52a3b50bcbf71e07a808d1c80d549f2459b9d2cf0afb9d", size = 9951852, upload-time = "2025-02-01T15:17:41.026Z" }
111
+ wheels = [
112
+ { url = "https://files.pythonhosted.org/packages/b7/b8/3fe70c75fe32afc4bb507f75563d39bc5642255d1d94f1f23604725780bf/babel-2.17.0-py3-none-any.whl", hash = "sha256:4d0b53093fdfb4b21c92b5213dba5a1b23885afa8383709427046b21c366e5f2", size = 10182537, upload-time = "2025-02-01T15:17:37.39Z" },
113
+ ]
114
+
115
  [[package]]
116
  name = "brotli"
117
  version = "1.1.0"
 
345
  { url = "https://files.pythonhosted.org/packages/ae/8c/469afb6465b853afff216f9528ffda78a915ff880ed58813ba4faf4ba0b6/contourpy-1.3.3-cp314-cp314t-win_arm64.whl", hash = "sha256:b7448cb5a725bb1e35ce88771b86fba35ef418952474492cf7c764059933ff8b", size = 203831, upload-time = "2025-07-26T12:02:51.449Z" },
346
  ]
347
 
348
+ [[package]]
349
+ name = "csvw"
350
+ version = "3.6.0"
351
+ source = { registry = "https://pypi.org/simple" }
352
+ dependencies = [
353
+ { name = "attrs" },
354
+ { name = "babel" },
355
+ { name = "isodate" },
356
+ { name = "jsonschema" },
357
+ { name = "language-tags" },
358
+ { name = "python-dateutil" },
359
+ { name = "rdflib" },
360
+ { name = "requests" },
361
+ { name = "rfc3986" },
362
+ { name = "termcolor" },
363
+ { name = "uritemplate" },
364
+ ]
365
+ sdist = { url = "https://files.pythonhosted.org/packages/27/00/813bfc929257afc9a7b836a56b895625cea8abe8e010e1c5432d995a1e64/csvw-3.6.0.tar.gz", hash = "sha256:ae4ea6735f27bb6c20b4f5cac197f24b0130a631550c7fc0b09fd5f6a8720d4e", size = 74086, upload-time = "2025-09-18T13:56:29.914Z" }
366
+ wheels = [
367
+ { url = "https://files.pythonhosted.org/packages/76/27/0b30279559353b2f2604a0a00fd95f7defaff915a5971ae35914904f0ebf/csvw-3.6.0-py2.py3-none-any.whl", hash = "sha256:af17f59f4f0c02e650d394e5faf1ee75b0905c0fc15565d910a115b2bcc81895", size = 60161, upload-time = "2025-09-18T13:56:27.777Z" },
368
+ ]
369
+
370
  [[package]]
371
  name = "cycler"
372
  version = "0.12.1"
 
604
  { url = "https://files.pythonhosted.org/packages/76/c6/c88e154df9c4e1a2a66ccf0005a88dfb2650c1dffb6f5ce603dfbd452ce3/idna-3.10-py3-none-any.whl", hash = "sha256:946d195a0d259cbba61165e88e65941f16e9b36ea6ddb97f00452bae8b1287d3", size = 70442, upload-time = "2024-09-15T18:07:37.964Z" },
605
  ]
606
 
607
+ [[package]]
608
+ name = "isodate"
609
+ version = "0.7.2"
610
+ source = { registry = "https://pypi.org/simple" }
611
+ sdist = { url = "https://files.pythonhosted.org/packages/54/4d/e940025e2ce31a8ce1202635910747e5a87cc3a6a6bb2d00973375014749/isodate-0.7.2.tar.gz", hash = "sha256:4cd1aa0f43ca76f4a6c6c0292a85f40b35ec2e43e315b59f06e6d32171a953e6", size = 29705, upload-time = "2024-10-08T23:04:11.5Z" }
612
+ wheels = [
613
+ { url = "https://files.pythonhosted.org/packages/15/aa/0aca39a37d3c7eb941ba736ede56d689e7be91cab5d9ca846bde3999eba6/isodate-0.7.2-py3-none-any.whl", hash = "sha256:28009937d8031054830160fce6d409ed342816b543597cece116d966c6d99e15", size = 22320, upload-time = "2024-10-08T23:04:09.501Z" },
614
+ ]
615
+
616
  [[package]]
617
  name = "jinja2"
618
  version = "3.1.6"
 
625
  { url = "https://files.pythonhosted.org/packages/62/a1/3d680cbfd5f4b8f15abc1d571870c5fc3e594bb582bc3b64ea099db13e56/jinja2-3.1.6-py3-none-any.whl", hash = "sha256:85ece4451f492d0c13c5dd7c13a64681a86afae63a5f347908daf103ce6d2f67", size = 134899, upload-time = "2025-03-05T20:05:00.369Z" },
626
  ]
627
 
628
+ [[package]]
629
+ name = "jsonschema"
630
+ version = "4.25.1"
631
+ source = { registry = "https://pypi.org/simple" }
632
+ dependencies = [
633
+ { name = "attrs" },
634
+ { name = "jsonschema-specifications" },
635
+ { name = "referencing" },
636
+ { name = "rpds-py" },
637
+ ]
638
+ sdist = { url = "https://files.pythonhosted.org/packages/74/69/f7185de793a29082a9f3c7728268ffb31cb5095131a9c139a74078e27336/jsonschema-4.25.1.tar.gz", hash = "sha256:e4a9655ce0da0c0b67a085847e00a3a51449e1157f4f75e9fb5aa545e122eb85", size = 357342, upload-time = "2025-08-18T17:03:50.038Z" }
639
+ wheels = [
640
+ { url = "https://files.pythonhosted.org/packages/bf/9c/8c95d856233c1f82500c2450b8c68576b4cf1c871db3afac5c34ff84e6fd/jsonschema-4.25.1-py3-none-any.whl", hash = "sha256:3fba0169e345c7175110351d456342c364814cfcf3b964ba4587f22915230a63", size = 90040, upload-time = "2025-08-18T17:03:48.373Z" },
641
+ ]
642
+
643
+ [[package]]
644
+ name = "jsonschema-specifications"
645
+ version = "2025.9.1"
646
+ source = { registry = "https://pypi.org/simple" }
647
+ dependencies = [
648
+ { name = "referencing" },
649
+ ]
650
+ sdist = { url = "https://files.pythonhosted.org/packages/19/74/a633ee74eb36c44aa6d1095e7cc5569bebf04342ee146178e2d36600708b/jsonschema_specifications-2025.9.1.tar.gz", hash = "sha256:b540987f239e745613c7a9176f3edb72b832a4ac465cf02712288397832b5e8d", size = 32855, upload-time = "2025-09-08T01:34:59.186Z" }
651
+ wheels = [
652
+ { url = "https://files.pythonhosted.org/packages/41/45/1a4ed80516f02155c51f51e8cedb3c1902296743db0bbc66608a0db2814f/jsonschema_specifications-2025.9.1-py3-none-any.whl", hash = "sha256:98802fee3a11ee76ecaca44429fda8a41bff98b00a0f2838151b113f210cc6fe", size = 18437, upload-time = "2025-09-08T01:34:57.871Z" },
653
+ ]
654
+
655
  [[package]]
656
  name = "kiwisolver"
657
  version = "1.4.9"
 
724
  { url = "https://files.pythonhosted.org/packages/80/be/3578e8afd18c88cdf9cb4cffde75a96d2be38c5a903f1ed0ceec061bd09e/kiwisolver-1.4.9-cp314-cp314t-win_arm64.whl", hash = "sha256:4a48a2ce79d65d363597ef7b567ce3d14d68783d2b2263d98db3d9477805ba32", size = 70260, upload-time = "2025-08-10T21:27:36.606Z" },
725
  ]
726
 
727
+ [[package]]
728
+ name = "language-tags"
729
+ version = "1.2.0"
730
+ source = { registry = "https://pypi.org/simple" }
731
+ sdist = { url = "https://files.pythonhosted.org/packages/e0/7e/b6a0efe4fee11e9742c1baaedf7c574084238a70b03c1d8eb2761383848f/language_tags-1.2.0.tar.gz", hash = "sha256:e934acba3e3dc85f867703eca421847a9ab7b7679b11b5d5cfd096febbf8bde6", size = 207901, upload-time = "2023-01-11T18:38:07.893Z" }
732
+ wheels = [
733
+ { url = "https://files.pythonhosted.org/packages/b0/42/327554649ed2dd5ce59d3f5da176c7be20f9352c7c6c51597293660b7b08/language_tags-1.2.0-py3-none-any.whl", hash = "sha256:d815604622242fdfbbfd747b40c31213617fd03734a267f2e39ee4bd73c88722", size = 213449, upload-time = "2023-01-11T18:38:05.692Z" },
734
+ ]
735
+
736
  [[package]]
737
  name = "markdown-it-py"
738
  version = "4.0.0"
 
1408
  { url = "https://files.pythonhosted.org/packages/fa/de/02b54f42487e3d3c6efb3f89428677074ca7bf43aae402517bc7cca949f3/PyYAML-6.0.2-cp313-cp313-win_amd64.whl", hash = "sha256:8388ee1976c416731879ac16da0aff3f63b286ffdd57cdeb95f3f2e085687563", size = 156446, upload-time = "2024-08-06T20:33:04.33Z" },
1409
  ]
1410
 
1411
+ [[package]]
1412
+ name = "rdflib"
1413
+ version = "7.2.1"
1414
+ source = { registry = "https://pypi.org/simple" }
1415
+ dependencies = [
1416
+ { name = "pyparsing" },
1417
+ ]
1418
+ sdist = { url = "https://files.pythonhosted.org/packages/8d/99/d2fec85e5f6bdfe4367dea143119cb4469bf48710487939df0abf7e22003/rdflib-7.2.1.tar.gz", hash = "sha256:cf9b7fa25234e8925da8b1fb09700f8349b5f0f100e785fb4260e737308292ac", size = 4873802, upload-time = "2025-09-19T02:33:36.492Z" }
1419
+ wheels = [
1420
+ { url = "https://files.pythonhosted.org/packages/31/98/7fa830bb4b9da21905683a5352aa0a01a1f3082328ae976aad341e980c23/rdflib-7.2.1-py3-none-any.whl", hash = "sha256:1a175bc1386a167a42fbfaba003bfa05c164a2a3ca3cb9c0c97f9c9638ca6ac2", size = 565423, upload-time = "2025-09-19T02:33:30.889Z" },
1421
+ ]
1422
+
1423
+ [[package]]
1424
+ name = "referencing"
1425
+ version = "0.36.2"
1426
+ source = { registry = "https://pypi.org/simple" }
1427
+ dependencies = [
1428
+ { name = "attrs" },
1429
+ { name = "rpds-py" },
1430
+ { name = "typing-extensions", marker = "python_full_version < '3.13'" },
1431
+ ]
1432
+ sdist = { url = "https://files.pythonhosted.org/packages/2f/db/98b5c277be99dd18bfd91dd04e1b759cad18d1a338188c936e92f921c7e2/referencing-0.36.2.tar.gz", hash = "sha256:df2e89862cd09deabbdba16944cc3f10feb6b3e6f18e902f7cc25609a34775aa", size = 74744, upload-time = "2025-01-25T08:48:16.138Z" }
1433
+ wheels = [
1434
+ { url = "https://files.pythonhosted.org/packages/c1/b1/3baf80dc6d2b7bc27a95a67752d0208e410351e3feb4eb78de5f77454d8d/referencing-0.36.2-py3-none-any.whl", hash = "sha256:e8699adbbf8b5c7de96d8ffa0eb5c158b3beafce084968e2ea8bb08c6794dcd0", size = 26775, upload-time = "2025-01-25T08:48:14.241Z" },
1435
+ ]
1436
+
1437
  [[package]]
1438
  name = "regex"
1439
  version = "2025.9.1"
 
1499
  { url = "https://files.pythonhosted.org/packages/1e/db/4254e3eabe8020b458f1a747140d32277ec7a271daf1d235b70dc0b4e6e3/requests-2.32.5-py3-none-any.whl", hash = "sha256:2462f94637a34fd532264295e186976db0f5d453d1cdd31473c85a6a161affb6", size = 64738, upload-time = "2025-08-18T20:46:00.542Z" },
1500
  ]
1501
 
1502
+ [[package]]
1503
+ name = "rfc3986"
1504
+ version = "1.5.0"
1505
+ source = { registry = "https://pypi.org/simple" }
1506
+ sdist = { url = "https://files.pythonhosted.org/packages/79/30/5b1b6c28c105629cc12b33bdcbb0b11b5bb1880c6cfbd955f9e792921aa8/rfc3986-1.5.0.tar.gz", hash = "sha256:270aaf10d87d0d4e095063c65bf3ddbc6ee3d0b226328ce21e036f946e421835", size = 49378, upload-time = "2021-05-07T23:29:27.183Z" }
1507
+ wheels = [
1508
+ { url = "https://files.pythonhosted.org/packages/c4/e5/63ca2c4edf4e00657584608bee1001302bbf8c5f569340b78304f2f446cb/rfc3986-1.5.0-py2.py3-none-any.whl", hash = "sha256:a86d6e1f5b1dc238b218b012df0aa79409667bb209e58da56d0b94704e712a97", size = 31976, upload-time = "2021-05-07T23:29:25.611Z" },
1509
+ ]
1510
+
1511
  [[package]]
1512
  name = "rich"
1513
  version = "14.1.0"
 
1521
  { url = "https://files.pythonhosted.org/packages/e3/30/3c4d035596d3cf444529e0b2953ad0466f6049528a879d27534700580395/rich-14.1.0-py3-none-any.whl", hash = "sha256:536f5f1785986d6dbdea3c75205c473f970777b4a0d6c6dd1b696aa05a3fa04f", size = 243368, upload-time = "2025-07-25T07:32:56.73Z" },
1522
  ]
1523
 
1524
+ [[package]]
1525
+ name = "rpds-py"
1526
+ version = "0.27.1"
1527
+ source = { registry = "https://pypi.org/simple" }
1528
+ sdist = { url = "https://files.pythonhosted.org/packages/e9/dd/2c0cbe774744272b0ae725f44032c77bdcab6e8bcf544bffa3b6e70c8dba/rpds_py-0.27.1.tar.gz", hash = "sha256:26a1c73171d10b7acccbded82bf6a586ab8203601e565badc74bbbf8bc5a10f8", size = 27479, upload-time = "2025-08-27T12:16:36.024Z" }
1529
+ wheels = [
1530
+ { url = "https://files.pythonhosted.org/packages/bd/fe/38de28dee5df58b8198c743fe2bea0c785c6d40941b9950bac4cdb71a014/rpds_py-0.27.1-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:ae2775c1973e3c30316892737b91f9283f9908e3cc7625b9331271eaaed7dc90", size = 361887, upload-time = "2025-08-27T12:13:10.233Z" },
1531
+ { url = "https://files.pythonhosted.org/packages/7c/9a/4b6c7eedc7dd90986bf0fab6ea2a091ec11c01b15f8ba0a14d3f80450468/rpds_py-0.27.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:2643400120f55c8a96f7c9d858f7be0c88d383cd4653ae2cf0d0c88f668073e5", size = 345795, upload-time = "2025-08-27T12:13:11.65Z" },
1532
+ { url = "https://files.pythonhosted.org/packages/6f/0e/e650e1b81922847a09cca820237b0edee69416a01268b7754d506ade11ad/rpds_py-0.27.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:16323f674c089b0360674a4abd28d5042947d54ba620f72514d69be4ff64845e", size = 385121, upload-time = "2025-08-27T12:13:13.008Z" },
1533
+ { url = "https://files.pythonhosted.org/packages/1b/ea/b306067a712988e2bff00dcc7c8f31d26c29b6d5931b461aa4b60a013e33/rpds_py-0.27.1-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:9a1f4814b65eacac94a00fc9a526e3fdafd78e439469644032032d0d63de4881", size = 398976, upload-time = "2025-08-27T12:13:14.368Z" },
1534
+ { url = "https://files.pythonhosted.org/packages/2c/0a/26dc43c8840cb8fe239fe12dbc8d8de40f2365e838f3d395835dde72f0e5/rpds_py-0.27.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:7ba32c16b064267b22f1850a34051121d423b6f7338a12b9459550eb2096e7ec", size = 525953, upload-time = "2025-08-27T12:13:15.774Z" },
1535
+ { url = "https://files.pythonhosted.org/packages/22/14/c85e8127b573aaf3a0cbd7fbb8c9c99e735a4a02180c84da2a463b766e9e/rpds_py-0.27.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e5c20f33fd10485b80f65e800bbe5f6785af510b9f4056c5a3c612ebc83ba6cb", size = 407915, upload-time = "2025-08-27T12:13:17.379Z" },
1536
+ { url = "https://files.pythonhosted.org/packages/ed/7b/8f4fee9ba1fb5ec856eb22d725a4efa3deb47f769597c809e03578b0f9d9/rpds_py-0.27.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:466bfe65bd932da36ff279ddd92de56b042f2266d752719beb97b08526268ec5", size = 386883, upload-time = "2025-08-27T12:13:18.704Z" },
1537
+ { url = "https://files.pythonhosted.org/packages/86/47/28fa6d60f8b74fcdceba81b272f8d9836ac0340570f68f5df6b41838547b/rpds_py-0.27.1-cp312-cp312-manylinux_2_31_riscv64.whl", hash = "sha256:41e532bbdcb57c92ba3be62c42e9f096431b4cf478da9bc3bc6ce5c38ab7ba7a", size = 405699, upload-time = "2025-08-27T12:13:20.089Z" },
1538
+ { url = "https://files.pythonhosted.org/packages/d0/fd/c5987b5e054548df56953a21fe2ebed51fc1ec7c8f24fd41c067b68c4a0a/rpds_py-0.27.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:f149826d742b406579466283769a8ea448eed82a789af0ed17b0cd5770433444", size = 423713, upload-time = "2025-08-27T12:13:21.436Z" },
1539
+ { url = "https://files.pythonhosted.org/packages/ac/ba/3c4978b54a73ed19a7d74531be37a8bcc542d917c770e14d372b8daea186/rpds_py-0.27.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:80c60cfb5310677bd67cb1e85a1e8eb52e12529545441b43e6f14d90b878775a", size = 562324, upload-time = "2025-08-27T12:13:22.789Z" },
1540
+ { url = "https://files.pythonhosted.org/packages/b5/6c/6943a91768fec16db09a42b08644b960cff540c66aab89b74be6d4a144ba/rpds_py-0.27.1-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:7ee6521b9baf06085f62ba9c7a3e5becffbc32480d2f1b351559c001c38ce4c1", size = 593646, upload-time = "2025-08-27T12:13:24.122Z" },
1541
+ { url = "https://files.pythonhosted.org/packages/11/73/9d7a8f4be5f4396f011a6bb7a19fe26303a0dac9064462f5651ced2f572f/rpds_py-0.27.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:a512c8263249a9d68cac08b05dd59d2b3f2061d99b322813cbcc14c3c7421998", size = 558137, upload-time = "2025-08-27T12:13:25.557Z" },
1542
+ { url = "https://files.pythonhosted.org/packages/6e/96/6772cbfa0e2485bcceef8071de7821f81aeac8bb45fbfd5542a3e8108165/rpds_py-0.27.1-cp312-cp312-win32.whl", hash = "sha256:819064fa048ba01b6dadc5116f3ac48610435ac9a0058bbde98e569f9e785c39", size = 221343, upload-time = "2025-08-27T12:13:26.967Z" },
1543
+ { url = "https://files.pythonhosted.org/packages/67/b6/c82f0faa9af1c6a64669f73a17ee0eeef25aff30bb9a1c318509efe45d84/rpds_py-0.27.1-cp312-cp312-win_amd64.whl", hash = "sha256:d9199717881f13c32c4046a15f024971a3b78ad4ea029e8da6b86e5aa9cf4594", size = 232497, upload-time = "2025-08-27T12:13:28.326Z" },
1544
+ { url = "https://files.pythonhosted.org/packages/e1/96/2817b44bd2ed11aebacc9251da03689d56109b9aba5e311297b6902136e2/rpds_py-0.27.1-cp312-cp312-win_arm64.whl", hash = "sha256:33aa65b97826a0e885ef6e278fbd934e98cdcfed80b63946025f01e2f5b29502", size = 222790, upload-time = "2025-08-27T12:13:29.71Z" },
1545
+ { url = "https://files.pythonhosted.org/packages/cc/77/610aeee8d41e39080c7e14afa5387138e3c9fa9756ab893d09d99e7d8e98/rpds_py-0.27.1-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:e4b9fcfbc021633863a37e92571d6f91851fa656f0180246e84cbd8b3f6b329b", size = 361741, upload-time = "2025-08-27T12:13:31.039Z" },
1546
+ { url = "https://files.pythonhosted.org/packages/3a/fc/c43765f201c6a1c60be2043cbdb664013def52460a4c7adace89d6682bf4/rpds_py-0.27.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:1441811a96eadca93c517d08df75de45e5ffe68aa3089924f963c782c4b898cf", size = 345574, upload-time = "2025-08-27T12:13:32.902Z" },
1547
+ { url = "https://files.pythonhosted.org/packages/20/42/ee2b2ca114294cd9847d0ef9c26d2b0851b2e7e00bf14cc4c0b581df0fc3/rpds_py-0.27.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:55266dafa22e672f5a4f65019015f90336ed31c6383bd53f5e7826d21a0e0b83", size = 385051, upload-time = "2025-08-27T12:13:34.228Z" },
1548
+ { url = "https://files.pythonhosted.org/packages/fd/e8/1e430fe311e4799e02e2d1af7c765f024e95e17d651612425b226705f910/rpds_py-0.27.1-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:d78827d7ac08627ea2c8e02c9e5b41180ea5ea1f747e9db0915e3adf36b62dcf", size = 398395, upload-time = "2025-08-27T12:13:36.132Z" },
1549
+ { url = "https://files.pythonhosted.org/packages/82/95/9dc227d441ff2670651c27a739acb2535ccaf8b351a88d78c088965e5996/rpds_py-0.27.1-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ae92443798a40a92dc5f0b01d8a7c93adde0c4dc965310a29ae7c64d72b9fad2", size = 524334, upload-time = "2025-08-27T12:13:37.562Z" },
1550
+ { url = "https://files.pythonhosted.org/packages/87/01/a670c232f401d9ad461d9a332aa4080cd3cb1d1df18213dbd0d2a6a7ab51/rpds_py-0.27.1-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c46c9dd2403b66a2a3b9720ec4b74d4ab49d4fabf9f03dfdce2d42af913fe8d0", size = 407691, upload-time = "2025-08-27T12:13:38.94Z" },
1551
+ { url = "https://files.pythonhosted.org/packages/03/36/0a14aebbaa26fe7fab4780c76f2239e76cc95a0090bdb25e31d95c492fcd/rpds_py-0.27.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2efe4eb1d01b7f5f1939f4ef30ecea6c6b3521eec451fb93191bf84b2a522418", size = 386868, upload-time = "2025-08-27T12:13:40.192Z" },
1552
+ { url = "https://files.pythonhosted.org/packages/3b/03/8c897fb8b5347ff6c1cc31239b9611c5bf79d78c984430887a353e1409a1/rpds_py-0.27.1-cp313-cp313-manylinux_2_31_riscv64.whl", hash = "sha256:15d3b4d83582d10c601f481eca29c3f138d44c92187d197aff663a269197c02d", size = 405469, upload-time = "2025-08-27T12:13:41.496Z" },
1553
+ { url = "https://files.pythonhosted.org/packages/da/07/88c60edc2df74850d496d78a1fdcdc7b54360a7f610a4d50008309d41b94/rpds_py-0.27.1-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:4ed2e16abbc982a169d30d1a420274a709949e2cbdef119fe2ec9d870b42f274", size = 422125, upload-time = "2025-08-27T12:13:42.802Z" },
1554
+ { url = "https://files.pythonhosted.org/packages/6b/86/5f4c707603e41b05f191a749984f390dabcbc467cf833769b47bf14ba04f/rpds_py-0.27.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:a75f305c9b013289121ec0f1181931975df78738cdf650093e6b86d74aa7d8dd", size = 562341, upload-time = "2025-08-27T12:13:44.472Z" },
1555
+ { url = "https://files.pythonhosted.org/packages/b2/92/3c0cb2492094e3cd9baf9e49bbb7befeceb584ea0c1a8b5939dca4da12e5/rpds_py-0.27.1-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:67ce7620704745881a3d4b0ada80ab4d99df390838839921f99e63c474f82cf2", size = 592511, upload-time = "2025-08-27T12:13:45.898Z" },
1556
+ { url = "https://files.pythonhosted.org/packages/10/bb/82e64fbb0047c46a168faa28d0d45a7851cd0582f850b966811d30f67ad8/rpds_py-0.27.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:9d992ac10eb86d9b6f369647b6a3f412fc0075cfd5d799530e84d335e440a002", size = 557736, upload-time = "2025-08-27T12:13:47.408Z" },
1557
+ { url = "https://files.pythonhosted.org/packages/00/95/3c863973d409210da7fb41958172c6b7dbe7fc34e04d3cc1f10bb85e979f/rpds_py-0.27.1-cp313-cp313-win32.whl", hash = "sha256:4f75e4bd8ab8db624e02c8e2fc4063021b58becdbe6df793a8111d9343aec1e3", size = 221462, upload-time = "2025-08-27T12:13:48.742Z" },
1558
+ { url = "https://files.pythonhosted.org/packages/ce/2c/5867b14a81dc217b56d95a9f2a40fdbc56a1ab0181b80132beeecbd4b2d6/rpds_py-0.27.1-cp313-cp313-win_amd64.whl", hash = "sha256:f9025faafc62ed0b75a53e541895ca272815bec18abe2249ff6501c8f2e12b83", size = 232034, upload-time = "2025-08-27T12:13:50.11Z" },
1559
+ { url = "https://files.pythonhosted.org/packages/c7/78/3958f3f018c01923823f1e47f1cc338e398814b92d83cd278364446fac66/rpds_py-0.27.1-cp313-cp313-win_arm64.whl", hash = "sha256:ed10dc32829e7d222b7d3b93136d25a406ba9788f6a7ebf6809092da1f4d279d", size = 222392, upload-time = "2025-08-27T12:13:52.587Z" },
1560
+ { url = "https://files.pythonhosted.org/packages/01/76/1cdf1f91aed5c3a7bf2eba1f1c4e4d6f57832d73003919a20118870ea659/rpds_py-0.27.1-cp313-cp313t-macosx_10_12_x86_64.whl", hash = "sha256:92022bbbad0d4426e616815b16bc4127f83c9a74940e1ccf3cfe0b387aba0228", size = 358355, upload-time = "2025-08-27T12:13:54.012Z" },
1561
+ { url = "https://files.pythonhosted.org/packages/c3/6f/bf142541229374287604caf3bb2a4ae17f0a580798fd72d3b009b532db4e/rpds_py-0.27.1-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:47162fdab9407ec3f160805ac3e154df042e577dd53341745fc7fb3f625e6d92", size = 342138, upload-time = "2025-08-27T12:13:55.791Z" },
1562
+ { url = "https://files.pythonhosted.org/packages/1a/77/355b1c041d6be40886c44ff5e798b4e2769e497b790f0f7fd1e78d17e9a8/rpds_py-0.27.1-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:fb89bec23fddc489e5d78b550a7b773557c9ab58b7946154a10a6f7a214a48b2", size = 380247, upload-time = "2025-08-27T12:13:57.683Z" },
1563
+ { url = "https://files.pythonhosted.org/packages/d6/a4/d9cef5c3946ea271ce2243c51481971cd6e34f21925af2783dd17b26e815/rpds_py-0.27.1-cp313-cp313t-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:e48af21883ded2b3e9eb48cb7880ad8598b31ab752ff3be6457001d78f416723", size = 390699, upload-time = "2025-08-27T12:13:59.137Z" },
1564
+ { url = "https://files.pythonhosted.org/packages/3a/06/005106a7b8c6c1a7e91b73169e49870f4af5256119d34a361ae5240a0c1d/rpds_py-0.27.1-cp313-cp313t-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:6f5b7bd8e219ed50299e58551a410b64daafb5017d54bbe822e003856f06a802", size = 521852, upload-time = "2025-08-27T12:14:00.583Z" },
1565
+ { url = "https://files.pythonhosted.org/packages/e5/3e/50fb1dac0948e17a02eb05c24510a8fe12d5ce8561c6b7b7d1339ab7ab9c/rpds_py-0.27.1-cp313-cp313t-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:08f1e20bccf73b08d12d804d6e1c22ca5530e71659e6673bce31a6bb71c1e73f", size = 402582, upload-time = "2025-08-27T12:14:02.034Z" },
1566
+ { url = "https://files.pythonhosted.org/packages/cb/b0/f4e224090dc5b0ec15f31a02d746ab24101dd430847c4d99123798661bfc/rpds_py-0.27.1-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0dc5dceeaefcc96dc192e3a80bbe1d6c410c469e97bdd47494a7d930987f18b2", size = 384126, upload-time = "2025-08-27T12:14:03.437Z" },
1567
+ { url = "https://files.pythonhosted.org/packages/54/77/ac339d5f82b6afff1df8f0fe0d2145cc827992cb5f8eeb90fc9f31ef7a63/rpds_py-0.27.1-cp313-cp313t-manylinux_2_31_riscv64.whl", hash = "sha256:d76f9cc8665acdc0c9177043746775aa7babbf479b5520b78ae4002d889f5c21", size = 399486, upload-time = "2025-08-27T12:14:05.443Z" },
1568
+ { url = "https://files.pythonhosted.org/packages/d6/29/3e1c255eee6ac358c056a57d6d6869baa00a62fa32eea5ee0632039c50a3/rpds_py-0.27.1-cp313-cp313t-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:134fae0e36022edad8290a6661edf40c023562964efea0cc0ec7f5d392d2aaef", size = 414832, upload-time = "2025-08-27T12:14:06.902Z" },
1569
+ { url = "https://files.pythonhosted.org/packages/3f/db/6d498b844342deb3fa1d030598db93937a9964fcf5cb4da4feb5f17be34b/rpds_py-0.27.1-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:eb11a4f1b2b63337cfd3b4d110af778a59aae51c81d195768e353d8b52f88081", size = 557249, upload-time = "2025-08-27T12:14:08.37Z" },
1570
+ { url = "https://files.pythonhosted.org/packages/60/f3/690dd38e2310b6f68858a331399b4d6dbb9132c3e8ef8b4333b96caf403d/rpds_py-0.27.1-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:13e608ac9f50a0ed4faec0e90ece76ae33b34c0e8656e3dceb9a7db994c692cd", size = 587356, upload-time = "2025-08-27T12:14:10.034Z" },
1571
+ { url = "https://files.pythonhosted.org/packages/86/e3/84507781cccd0145f35b1dc32c72675200c5ce8d5b30f813e49424ef68fc/rpds_py-0.27.1-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:dd2135527aa40f061350c3f8f89da2644de26cd73e4de458e79606384f4f68e7", size = 555300, upload-time = "2025-08-27T12:14:11.783Z" },
1572
+ { url = "https://files.pythonhosted.org/packages/e5/ee/375469849e6b429b3516206b4580a79e9ef3eb12920ddbd4492b56eaacbe/rpds_py-0.27.1-cp313-cp313t-win32.whl", hash = "sha256:3020724ade63fe320a972e2ffd93b5623227e684315adce194941167fee02688", size = 216714, upload-time = "2025-08-27T12:14:13.629Z" },
1573
+ { url = "https://files.pythonhosted.org/packages/21/87/3fc94e47c9bd0742660e84706c311a860dcae4374cf4a03c477e23ce605a/rpds_py-0.27.1-cp313-cp313t-win_amd64.whl", hash = "sha256:8ee50c3e41739886606388ba3ab3ee2aae9f35fb23f833091833255a31740797", size = 228943, upload-time = "2025-08-27T12:14:14.937Z" },
1574
+ { url = "https://files.pythonhosted.org/packages/70/36/b6e6066520a07cf029d385de869729a895917b411e777ab1cde878100a1d/rpds_py-0.27.1-cp314-cp314-macosx_10_12_x86_64.whl", hash = "sha256:acb9aafccaae278f449d9c713b64a9e68662e7799dbd5859e2c6b3c67b56d334", size = 362472, upload-time = "2025-08-27T12:14:16.333Z" },
1575
+ { url = "https://files.pythonhosted.org/packages/af/07/b4646032e0dcec0df9c73a3bd52f63bc6c5f9cda992f06bd0e73fe3fbebd/rpds_py-0.27.1-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:b7fb801aa7f845ddf601c49630deeeccde7ce10065561d92729bfe81bd21fb33", size = 345676, upload-time = "2025-08-27T12:14:17.764Z" },
1576
+ { url = "https://files.pythonhosted.org/packages/b0/16/2f1003ee5d0af4bcb13c0cf894957984c32a6751ed7206db2aee7379a55e/rpds_py-0.27.1-cp314-cp314-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:fe0dd05afb46597b9a2e11c351e5e4283c741237e7f617ffb3252780cca9336a", size = 385313, upload-time = "2025-08-27T12:14:19.829Z" },
1577
+ { url = "https://files.pythonhosted.org/packages/05/cd/7eb6dd7b232e7f2654d03fa07f1414d7dfc980e82ba71e40a7c46fd95484/rpds_py-0.27.1-cp314-cp314-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:b6dfb0e058adb12d8b1d1b25f686e94ffa65d9995a5157afe99743bf7369d62b", size = 399080, upload-time = "2025-08-27T12:14:21.531Z" },
1578
+ { url = "https://files.pythonhosted.org/packages/20/51/5829afd5000ec1cb60f304711f02572d619040aa3ec033d8226817d1e571/rpds_py-0.27.1-cp314-cp314-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ed090ccd235f6fa8bb5861684567f0a83e04f52dfc2e5c05f2e4b1309fcf85e7", size = 523868, upload-time = "2025-08-27T12:14:23.485Z" },
1579
+ { url = "https://files.pythonhosted.org/packages/05/2c/30eebca20d5db95720ab4d2faec1b5e4c1025c473f703738c371241476a2/rpds_py-0.27.1-cp314-cp314-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:bf876e79763eecf3e7356f157540d6a093cef395b65514f17a356f62af6cc136", size = 408750, upload-time = "2025-08-27T12:14:24.924Z" },
1580
+ { url = "https://files.pythonhosted.org/packages/90/1a/cdb5083f043597c4d4276eae4e4c70c55ab5accec078da8611f24575a367/rpds_py-0.27.1-cp314-cp314-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:12ed005216a51b1d6e2b02a7bd31885fe317e45897de81d86dcce7d74618ffff", size = 387688, upload-time = "2025-08-27T12:14:27.537Z" },
1581
+ { url = "https://files.pythonhosted.org/packages/7c/92/cf786a15320e173f945d205ab31585cc43969743bb1a48b6888f7a2b0a2d/rpds_py-0.27.1-cp314-cp314-manylinux_2_31_riscv64.whl", hash = "sha256:ee4308f409a40e50593c7e3bb8cbe0b4d4c66d1674a316324f0c2f5383b486f9", size = 407225, upload-time = "2025-08-27T12:14:28.981Z" },
1582
+ { url = "https://files.pythonhosted.org/packages/33/5c/85ee16df5b65063ef26017bef33096557a4c83fbe56218ac7cd8c235f16d/rpds_py-0.27.1-cp314-cp314-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:0b08d152555acf1f455154d498ca855618c1378ec810646fcd7c76416ac6dc60", size = 423361, upload-time = "2025-08-27T12:14:30.469Z" },
1583
+ { url = "https://files.pythonhosted.org/packages/4b/8e/1c2741307fcabd1a334ecf008e92c4f47bb6f848712cf15c923becfe82bb/rpds_py-0.27.1-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:dce51c828941973a5684d458214d3a36fcd28da3e1875d659388f4f9f12cc33e", size = 562493, upload-time = "2025-08-27T12:14:31.987Z" },
1584
+ { url = "https://files.pythonhosted.org/packages/04/03/5159321baae9b2222442a70c1f988cbbd66b9be0675dd3936461269be360/rpds_py-0.27.1-cp314-cp314-musllinux_1_2_i686.whl", hash = "sha256:c1476d6f29eb81aa4151c9a31219b03f1f798dc43d8af1250a870735516a1212", size = 592623, upload-time = "2025-08-27T12:14:33.543Z" },
1585
+ { url = "https://files.pythonhosted.org/packages/ff/39/c09fd1ad28b85bc1d4554a8710233c9f4cefd03d7717a1b8fbfd171d1167/rpds_py-0.27.1-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:3ce0cac322b0d69b63c9cdb895ee1b65805ec9ffad37639f291dd79467bee675", size = 558800, upload-time = "2025-08-27T12:14:35.436Z" },
1586
+ { url = "https://files.pythonhosted.org/packages/c5/d6/99228e6bbcf4baa764b18258f519a9035131d91b538d4e0e294313462a98/rpds_py-0.27.1-cp314-cp314-win32.whl", hash = "sha256:dfbfac137d2a3d0725758cd141f878bf4329ba25e34979797c89474a89a8a3a3", size = 221943, upload-time = "2025-08-27T12:14:36.898Z" },
1587
+ { url = "https://files.pythonhosted.org/packages/be/07/c802bc6b8e95be83b79bdf23d1aa61d68324cb1006e245d6c58e959e314d/rpds_py-0.27.1-cp314-cp314-win_amd64.whl", hash = "sha256:a6e57b0abfe7cc513450fcf529eb486b6e4d3f8aee83e92eb5f1ef848218d456", size = 233739, upload-time = "2025-08-27T12:14:38.386Z" },
1588
+ { url = "https://files.pythonhosted.org/packages/c8/89/3e1b1c16d4c2d547c5717377a8df99aee8099ff050f87c45cb4d5fa70891/rpds_py-0.27.1-cp314-cp314-win_arm64.whl", hash = "sha256:faf8d146f3d476abfee026c4ae3bdd9ca14236ae4e4c310cbd1cf75ba33d24a3", size = 223120, upload-time = "2025-08-27T12:14:39.82Z" },
1589
+ { url = "https://files.pythonhosted.org/packages/62/7e/dc7931dc2fa4a6e46b2a4fa744a9fe5c548efd70e0ba74f40b39fa4a8c10/rpds_py-0.27.1-cp314-cp314t-macosx_10_12_x86_64.whl", hash = "sha256:ba81d2b56b6d4911ce735aad0a1d4495e808b8ee4dc58715998741a26874e7c2", size = 358944, upload-time = "2025-08-27T12:14:41.199Z" },
1590
+ { url = "https://files.pythonhosted.org/packages/e6/22/4af76ac4e9f336bfb1a5f240d18a33c6b2fcaadb7472ac7680576512b49a/rpds_py-0.27.1-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:84f7d509870098de0e864cad0102711c1e24e9b1a50ee713b65928adb22269e4", size = 342283, upload-time = "2025-08-27T12:14:42.699Z" },
1591
+ { url = "https://files.pythonhosted.org/packages/1c/15/2a7c619b3c2272ea9feb9ade67a45c40b3eeb500d503ad4c28c395dc51b4/rpds_py-0.27.1-cp314-cp314t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a9e960fc78fecd1100539f14132425e1d5fe44ecb9239f8f27f079962021523e", size = 380320, upload-time = "2025-08-27T12:14:44.157Z" },
1592
+ { url = "https://files.pythonhosted.org/packages/a2/7d/4c6d243ba4a3057e994bb5bedd01b5c963c12fe38dde707a52acdb3849e7/rpds_py-0.27.1-cp314-cp314t-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:62f85b665cedab1a503747617393573995dac4600ff51869d69ad2f39eb5e817", size = 391760, upload-time = "2025-08-27T12:14:45.845Z" },
1593
+ { url = "https://files.pythonhosted.org/packages/b4/71/b19401a909b83bcd67f90221330bc1ef11bc486fe4e04c24388d28a618ae/rpds_py-0.27.1-cp314-cp314t-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:fed467af29776f6556250c9ed85ea5a4dd121ab56a5f8b206e3e7a4c551e48ec", size = 522476, upload-time = "2025-08-27T12:14:47.364Z" },
1594
+ { url = "https://files.pythonhosted.org/packages/e4/44/1a3b9715c0455d2e2f0f6df5ee6d6f5afdc423d0773a8a682ed2b43c566c/rpds_py-0.27.1-cp314-cp314t-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f2729615f9d430af0ae6b36cf042cb55c0936408d543fb691e1a9e36648fd35a", size = 403418, upload-time = "2025-08-27T12:14:49.991Z" },
1595
+ { url = "https://files.pythonhosted.org/packages/1c/4b/fb6c4f14984eb56673bc868a66536f53417ddb13ed44b391998100a06a96/rpds_py-0.27.1-cp314-cp314t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1b207d881a9aef7ba753d69c123a35d96ca7cb808056998f6b9e8747321f03b8", size = 384771, upload-time = "2025-08-27T12:14:52.159Z" },
1596
+ { url = "https://files.pythonhosted.org/packages/c0/56/d5265d2d28b7420d7b4d4d85cad8ef891760f5135102e60d5c970b976e41/rpds_py-0.27.1-cp314-cp314t-manylinux_2_31_riscv64.whl", hash = "sha256:639fd5efec029f99b79ae47e5d7e00ad8a773da899b6309f6786ecaf22948c48", size = 400022, upload-time = "2025-08-27T12:14:53.859Z" },
1597
+ { url = "https://files.pythonhosted.org/packages/8f/e9/9f5fc70164a569bdd6ed9046486c3568d6926e3a49bdefeeccfb18655875/rpds_py-0.27.1-cp314-cp314t-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:fecc80cb2a90e28af8a9b366edacf33d7a91cbfe4c2c4544ea1246e949cfebeb", size = 416787, upload-time = "2025-08-27T12:14:55.673Z" },
1598
+ { url = "https://files.pythonhosted.org/packages/d4/64/56dd03430ba491db943a81dcdef115a985aac5f44f565cd39a00c766d45c/rpds_py-0.27.1-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:42a89282d711711d0a62d6f57d81aa43a1368686c45bc1c46b7f079d55692734", size = 557538, upload-time = "2025-08-27T12:14:57.245Z" },
1599
+ { url = "https://files.pythonhosted.org/packages/3f/36/92cc885a3129993b1d963a2a42ecf64e6a8e129d2c7cc980dbeba84e55fb/rpds_py-0.27.1-cp314-cp314t-musllinux_1_2_i686.whl", hash = "sha256:cf9931f14223de59551ab9d38ed18d92f14f055a5f78c1d8ad6493f735021bbb", size = 588512, upload-time = "2025-08-27T12:14:58.728Z" },
1600
+ { url = "https://files.pythonhosted.org/packages/dd/10/6b283707780a81919f71625351182b4f98932ac89a09023cb61865136244/rpds_py-0.27.1-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:f39f58a27cc6e59f432b568ed8429c7e1641324fbe38131de852cd77b2d534b0", size = 555813, upload-time = "2025-08-27T12:15:00.334Z" },
1601
+ { url = "https://files.pythonhosted.org/packages/04/2e/30b5ea18c01379da6272a92825dd7e53dc9d15c88a19e97932d35d430ef7/rpds_py-0.27.1-cp314-cp314t-win32.whl", hash = "sha256:d5fa0ee122dc09e23607a28e6d7b150da16c662e66409bbe85230e4c85bb528a", size = 217385, upload-time = "2025-08-27T12:15:01.937Z" },
1602
+ { url = "https://files.pythonhosted.org/packages/32/7d/97119da51cb1dd3f2f3c0805f155a3aa4a95fa44fe7d78ae15e69edf4f34/rpds_py-0.27.1-cp314-cp314t-win_amd64.whl", hash = "sha256:6567d2bb951e21232c2f660c24cf3470bb96de56cdcb3f071a83feeaff8a2772", size = 230097, upload-time = "2025-08-27T12:15:03.961Z" },
1603
+ ]
1604
+
1605
  [[package]]
1606
  name = "ruff"
1607
  version = "0.13.1"
 
1662
  { url = "https://files.pythonhosted.org/packages/2c/c3/c0be1135726618dc1e28d181b8c442403d8dbb9e273fd791de2d4384bcdd/safetensors-0.6.2-cp38-abi3-win_amd64.whl", hash = "sha256:c7b214870df923cbc1593c3faee16bec59ea462758699bd3fee399d00aac072c", size = 320192, upload-time = "2025-08-08T13:13:59.467Z" },
1663
  ]
1664
 
1665
+ [[package]]
1666
+ name = "segments"
1667
+ version = "2.3.0"
1668
+ source = { registry = "https://pypi.org/simple" }
1669
+ dependencies = [
1670
+ { name = "csvw" },
1671
+ { name = "regex" },
1672
+ ]
1673
+ sdist = { url = "https://files.pythonhosted.org/packages/9b/4c/25e499df952528004ff3f7f8e1e63d20773ed30141ed17c285adb5446f55/segments-2.3.0.tar.gz", hash = "sha256:381143f66f59eaf45398f5bb57f899d6501be011048ec5f92754c9b24b181615", size = 18193, upload-time = "2025-02-20T07:55:42.273Z" }
1674
+ wheels = [
1675
+ { url = "https://files.pythonhosted.org/packages/11/18/cb614939ccd46d336013cab705f1e11540ec9c68b08ecbb854ab893fc480/segments-2.3.0-py2.py3-none-any.whl", hash = "sha256:30a5656787071430cd22422e04713b2a9beabe1a97d2ebf37f716a56f90577a3", size = 15705, upload-time = "2025-02-20T07:55:39.755Z" },
1676
+ ]
1677
+
1678
  [[package]]
1679
  name = "semantic-version"
1680
  version = "2.10.0"
 
1760
  { url = "https://files.pythonhosted.org/packages/a2/09/77d55d46fd61b4a135c444fc97158ef34a095e5681d0a6c10b75bf356191/sympy-1.14.0-py3-none-any.whl", hash = "sha256:e091cc3e99d2141a0ba2847328f5479b05d94a6635cb96148ccb3f34671bd8f5", size = 6299353, upload-time = "2025-04-27T18:04:59.103Z" },
1761
  ]
1762
 
1763
+ [[package]]
1764
+ name = "termcolor"
1765
+ version = "3.1.0"
1766
+ source = { registry = "https://pypi.org/simple" }
1767
+ sdist = { url = "https://files.pythonhosted.org/packages/ca/6c/3d75c196ac07ac8749600b60b03f4f6094d54e132c4d94ebac6ee0e0add0/termcolor-3.1.0.tar.gz", hash = "sha256:6a6dd7fbee581909eeec6a756cff1d7f7c376063b14e4a298dc4980309e55970", size = 14324, upload-time = "2025-04-30T11:37:53.791Z" }
1768
+ wheels = [
1769
+ { url = "https://files.pythonhosted.org/packages/4f/bd/de8d508070629b6d84a30d01d57e4a65c69aa7f5abe7560b8fad3b50ea59/termcolor-3.1.0-py3-none-any.whl", hash = "sha256:591dd26b5c2ce03b9e43f391264626557873ce1d379019786f99b0c2bee140aa", size = 7684, upload-time = "2025-04-30T11:37:52.382Z" },
1770
+ ]
1771
+
1772
  [[package]]
1773
  name = "tokenizers"
1774
  version = "0.22.0"
 
1972
  { url = "https://files.pythonhosted.org/packages/5c/23/c7abc0ca0a1526a0774eca151daeb8de62ec457e77262b66b359c3c7679e/tzdata-2025.2-py2.py3-none-any.whl", hash = "sha256:1a403fada01ff9221ca8044d701868fa132215d84beb92242d9acd2147f667a8", size = 347839, upload-time = "2025-03-23T13:54:41.845Z" },
1973
  ]
1974
 
1975
+ [[package]]
1976
+ name = "uritemplate"
1977
+ version = "4.2.0"
1978
+ source = { registry = "https://pypi.org/simple" }
1979
+ sdist = { url = "https://files.pythonhosted.org/packages/98/60/f174043244c5306c9988380d2cb10009f91563fc4b31293d27e17201af56/uritemplate-4.2.0.tar.gz", hash = "sha256:480c2ed180878955863323eea31b0ede668795de182617fef9c6ca09e6ec9d0e", size = 33267, upload-time = "2025-06-02T15:12:06.318Z" }
1980
+ wheels = [
1981
+ { url = "https://files.pythonhosted.org/packages/a9/99/3ae339466c9183ea5b8ae87b34c0b897eda475d2aec2307cae60e5cd4f29/uritemplate-4.2.0-py3-none-any.whl", hash = "sha256:962201ba1c4edcab02e60f9a0d3821e82dfc5d2d6662a21abd533879bdb8a686", size = 11488, upload-time = "2025-06-02T15:12:03.405Z" },
1982
+ ]
1983
+
1984
  [[package]]
1985
  name = "urllib3"
1986
  version = "2.5.0"
 
2012
  { name = "matplotlib" },
2013
  { name = "numpy" },
2014
  { name = "pyqt6" },
2015
+ { name = "segments" },
2016
  { name = "sounddevice" },
2017
  { name = "torch" },
2018
  { name = "torchaudio" },
 
2026
  { name = "matplotlib", specifier = ">=3.10.6" },
2027
  { name = "numpy", specifier = ">=2.3.3" },
2028
  { name = "pyqt6", specifier = ">=6.9.1" },
2029
+ { name = "segments", specifier = ">=2.3.0" },
2030
  { name = "sounddevice", specifier = ">=0.5.2" },
2031
  { name = "torch", specifier = ">=2.8.0" },
2032
  { name = "torchaudio", specifier = ">=2.8.0" },