minecraft-datapack-language 15.4.7__py3-none-any.whl → 15.4.9__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -6,16 +6,6 @@ from dataclasses import dataclass
6
6
  from typing import Optional, List, Any
7
7
  import os
8
8
 
9
- # Import color utilities
10
- try:
11
- from .cli_colors import color
12
- except ImportError:
13
- # Fallback if colors aren't available
14
- class DummyColor:
15
- def __getattr__(self, name):
16
- return lambda text: text
17
- color = DummyColor()
18
-
19
9
 
20
10
  @dataclass
21
11
  class MDLError(BaseException):
@@ -31,40 +21,78 @@ class MDLError(BaseException):
31
21
 
32
22
  def __str__(self) -> str:
33
23
  """Format error message with location information."""
34
- parts = []
35
-
36
- if self.file_path:
37
- # Show relative path if possible
38
- try:
39
- rel_path = os.path.relpath(self.file_path)
40
- parts.append(f"{color.file_path('File:')} {color.file_path(rel_path)}")
41
- except ValueError:
42
- parts.append(f"{color.file_path('File:')} {color.file_path(self.file_path)}")
43
-
44
- if self.line is not None:
45
- parts.append(f"{color.line_number('Line:')} {color.line_number(str(self.line))}")
46
- if self.column is not None:
47
- parts.append(f"{color.column_number('Column:')} {color.column_number(str(self.column))}")
48
-
49
- if self.line_content:
50
- parts.append(f"{color.context('Code:')} {color.context(self.line_content.strip())}")
51
- if self.column is not None:
52
- # Add a caret to show the exact position
53
- indent = " " * (self.column - 1)
54
- parts.append(f" {indent}{color.error('^')}")
55
-
56
- parts.append(f"{color.error_type('Error:')} {color.error(self.message)}")
57
-
58
- if self.suggestion:
59
- parts.append(f"{color.suggestion('Suggestion:')} {color.suggestion(self.suggestion)}")
60
-
61
- # Add context if we have file and line information
62
- if self.file_path and self.line is not None:
63
- context = format_error_context(self.file_path, self.line, self.column, self.context_lines)
64
- if context:
65
- parts.append(f"\n{color.context('Context:')}\n{context}")
66
-
67
- return "\n".join(parts)
24
+ try:
25
+ from .cli_colors import color
26
+ parts = []
27
+
28
+ if self.file_path:
29
+ # Show relative path if possible
30
+ try:
31
+ rel_path = os.path.relpath(self.file_path)
32
+ parts.append(f"{color.file_path('File:')} {color.file_path(rel_path)}")
33
+ except ValueError:
34
+ parts.append(f"{color.file_path('File:')} {color.file_path(self.file_path)}")
35
+
36
+ if self.line is not None:
37
+ parts.append(f"{color.line_number('Line:')} {color.line_number(str(self.line))}")
38
+ if self.column is not None:
39
+ parts.append(f"{color.column_number('Column:')} {color.column_number(str(self.column))}")
40
+
41
+ if self.line_content:
42
+ parts.append(f"{color.context('Code:')} {color.context(self.line_content.strip())}")
43
+ if self.column is not None:
44
+ # Add a caret to show the exact position
45
+ indent = " " * (self.column - 1)
46
+ parts.append(f" {indent}{color.error('^')}")
47
+
48
+ parts.append(f"{color.error_type('Error:')} {color.error(self.message)}")
49
+
50
+ if self.suggestion:
51
+ parts.append(f"{color.suggestion('Suggestion:')} {color.suggestion(self.suggestion)}")
52
+
53
+ # Add context if we have file and line information
54
+ if self.file_path and self.line is not None:
55
+ context = format_error_context(self.file_path, self.line, self.column, self.context_lines)
56
+ if context:
57
+ parts.append(f"\n{color.context('Context:')}\n{context}")
58
+
59
+ return "\n".join(parts)
60
+ except ImportError:
61
+ # Fallback if colors aren't available
62
+ parts = []
63
+
64
+ if self.file_path:
65
+ # Show relative path if possible
66
+ try:
67
+ rel_path = os.path.relpath(self.file_path)
68
+ parts.append(f"File: {rel_path}")
69
+ except ValueError:
70
+ parts.append(f"File: {self.file_path}")
71
+
72
+ if self.line is not None:
73
+ parts.append(f"Line: {self.line}")
74
+ if self.column is not None:
75
+ parts.append(f"Column: {self.column}")
76
+
77
+ if self.line_content:
78
+ parts.append(f"Code: {self.line_content.strip()}")
79
+ if self.column is not None:
80
+ # Add a caret to show the exact position
81
+ indent = " " * (self.column - 1)
82
+ parts.append(f" {indent}^")
83
+
84
+ parts.append(f"Error: {self.message}")
85
+
86
+ if self.suggestion:
87
+ parts.append(f"Suggestion: {self.suggestion}")
88
+
89
+ # Add context if we have file and line information
90
+ if self.file_path and self.line is not None:
91
+ context = format_error_context(self.file_path, self.line, self.column, self.context_lines)
92
+ if context:
93
+ parts.append(f"\nContext:\n{context}")
94
+
95
+ return "\n".join(parts)
68
96
 
69
97
  def to_dict(self) -> dict:
70
98
  """Convert error to dictionary for JSON output."""
@@ -85,7 +113,11 @@ class MDLSyntaxError(MDLError):
85
113
  error_type: str = "syntax_error"
86
114
 
87
115
  def __str__(self) -> str:
88
- return f"{color.error_type('Syntax Error:')} {super().__str__()}"
116
+ try:
117
+ from .cli_colors import color
118
+ return f"{color.error_type('Syntax Error:')} {super().__str__()}"
119
+ except ImportError:
120
+ return f"Syntax Error: {super().__str__()}"
89
121
 
90
122
 
91
123
  @dataclass
@@ -94,7 +126,11 @@ class MDLLexerError(MDLError):
94
126
  error_type: str = "lexer_error"
95
127
 
96
128
  def __str__(self) -> str:
97
- return f"{color.error_type('Lexer Error:')} {super().__str__()}"
129
+ try:
130
+ from .cli_colors import color
131
+ return f"{color.error_type('Lexer Error:')} {super().__str__()}"
132
+ except ImportError:
133
+ return f"Lexer Error: {super().__str__()}"
98
134
 
99
135
 
100
136
  @dataclass
@@ -103,43 +139,76 @@ class MDLParserError(MDLError):
103
139
  error_type: str = "parser_error"
104
140
 
105
141
  def __str__(self) -> str:
106
- return f"{color.error_type('Parser Error:')} {super().__str__()}"
142
+ try:
143
+ from .cli_colors import color
144
+ return f"{color.error_type('Parser Error:')} {super().__str__()}"
145
+ except ImportError:
146
+ return f"Parser Error: {super().__str__()}"
107
147
 
108
148
 
109
149
  @dataclass
110
150
  class MDLValidationError(MDLError):
111
- """Validation error during semantic analysis."""
151
+ """Error during validation."""
112
152
  error_type: str = "validation_error"
113
153
 
114
154
  def __str__(self) -> str:
115
- return f"{color.error_type('Validation Error:')} {super().__str__()}"
155
+ try:
156
+ from .cli_colors import color
157
+ return f"{color.error_type('Validation Error:')} {super().__str__()}"
158
+ except ImportError:
159
+ return f"Validation Error: {super().__str__()}"
116
160
 
117
161
 
118
162
  @dataclass
119
- class MDLConfigurationError(MDLError):
120
- """Configuration or setup error."""
121
- error_type: str = "configuration_error"
163
+ class MDLBuildError(MDLError):
164
+ """Error during build process."""
165
+ error_type: str = "build_error"
166
+
167
+ def __str__(self) -> str:
168
+ try:
169
+ from .cli_colors import color
170
+ return f"{color.error_type('Build Error:')} {super().__str__()}"
171
+ except ImportError:
172
+ return f"Build Error: {super().__str__()}"
173
+
174
+
175
+ @dataclass
176
+ class MDLCompilationError(MDLError):
177
+ """Error during compilation."""
178
+ error_type: str = "compilation_error"
122
179
 
123
180
  def __str__(self) -> str:
124
- return f"{color.error_type('Configuration Error:')} {super().__str__()}"
181
+ try:
182
+ from .cli_colors import color
183
+ return f"{color.error_type('Compilation Error:')} {super().__str__()}"
184
+ except ImportError:
185
+ return f"Compilation Error: {super().__str__()}"
125
186
 
126
187
 
127
188
  @dataclass
128
189
  class MDLFileError(MDLError):
129
- """File I/O or access error."""
190
+ """Error related to file operations."""
130
191
  error_type: str = "file_error"
131
192
 
132
193
  def __str__(self) -> str:
133
- return f"{color.error_type('File Error:')} {super().__str__()}"
194
+ try:
195
+ from .cli_colors import color
196
+ return f"{color.error_type('File Error:')} {super().__str__()}"
197
+ except ImportError:
198
+ return f"File Error: {super().__str__()}"
134
199
 
135
200
 
136
201
  @dataclass
137
- class MDLWarning(MDLError):
138
- """Warning message (non-fatal)."""
139
- error_type: str = "warning"
202
+ class MDLConfigurationError(MDLError):
203
+ """Error related to configuration."""
204
+ error_type: str = "configuration_error"
140
205
 
141
206
  def __str__(self) -> str:
142
- return f"{color.warning('Warning:')} {super().__str__()}"
207
+ try:
208
+ from .cli_colors import color
209
+ return f"{color.error_type('Configuration Error:')} {super().__str__()}"
210
+ except ImportError:
211
+ return f"Configuration Error: {super().__str__()}"
143
212
 
144
213
 
145
214
  class MDLErrorCollector:
@@ -149,16 +218,12 @@ class MDLErrorCollector:
149
218
  self.errors: List[MDLError] = []
150
219
  self.warnings: List[MDLError] = []
151
220
 
152
- def add_error(self, error: MDLError):
153
- """Add an error to the collector."""
154
- if isinstance(error, MDLWarning):
155
- self.warnings.append(error)
156
- else:
157
- self.errors.append(error)
221
+ def add_error(self, error: MDLError) -> None:
222
+ """Add an error to the collection."""
223
+ self.errors.append(error)
158
224
 
159
- def add_warning(self, message: str, **kwargs):
160
- """Add a warning message."""
161
- warning = create_error(MDLWarning, message, **kwargs)
225
+ def add_warning(self, warning: MDLError) -> None:
226
+ """Add a warning to the collection."""
162
227
  self.warnings.append(warning)
163
228
 
164
229
  def has_errors(self) -> bool:
@@ -169,104 +234,127 @@ class MDLErrorCollector:
169
234
  """Check if there are any warnings."""
170
235
  return len(self.warnings) > 0
171
236
 
172
- def get_error_count(self) -> int:
173
- """Get the total number of errors."""
174
- return len(self.errors)
175
-
176
- def get_warning_count(self) -> int:
177
- """Get the total number of warnings."""
178
- return len(self.warnings)
179
-
180
- def clear(self):
181
- """Clear all errors and warnings."""
182
- self.errors.clear()
183
- self.warnings.clear()
237
+ def get_all_issues(self) -> List[MDLError]:
238
+ """Get all errors and warnings."""
239
+ return self.errors + self.warnings
184
240
 
185
- def print_errors(self, verbose: bool = True, ignore_warnings: bool = False):
186
- """Print all collected errors and warnings."""
187
- if not ignore_warnings and self.warnings:
188
- print(f"\n{color.warning(f'⚠️ {len(self.warnings)} Warning(s):')}")
189
- for warning in self.warnings:
190
- print(f"\n{warning}")
191
-
192
- if self.errors:
193
- print(f"\n{color.error(f'❌ {len(self.errors)} Error(s):')}")
194
- for error in self.errors:
195
- print(f"\n{error}")
196
-
241
+ def print_errors(self, verbose: bool = False, ignore_warnings: bool = False) -> None:
242
+ """Print all errors and warnings."""
197
243
  if not self.errors and not self.warnings:
198
- print(f"\n{color.success('✅ No errors or warnings found!')}")
244
+ return
245
+
246
+ try:
247
+ from .cli_colors import color
248
+ if self.errors:
249
+ print(f"\n{color.error_type('ERROR:')} Found {color.error(str(len(self.errors)))} error(s):")
250
+ for i, error in enumerate(self.errors, 1):
251
+ print(f"\n{color.highlight(str(i))}. {error}")
252
+
253
+ if self.warnings and not ignore_warnings:
254
+ print(f"\n{color.warning('WARNING:')} Found {color.warning(str(len(self.warnings)))} warning(s):")
255
+ for i, warning in enumerate(self.warnings, 1):
256
+ print(f"\n{color.highlight(str(i))}. {warning}")
257
+ except ImportError:
258
+ # Fallback if colors aren't available
259
+ if self.errors:
260
+ print(f"\nERROR: Found {len(self.errors)} error(s):")
261
+ for i, error in enumerate(self.errors, 1):
262
+ print(f"\n{i}. {error}")
263
+
264
+ if self.warnings and not ignore_warnings:
265
+ print(f"\nWARNING: Found {len(self.warnings)} warning(s):")
266
+ for i, warning in enumerate(self.warnings, 1):
267
+ print(f"\n{i}. {warning}")
199
268
 
200
- def raise_if_errors(self):
269
+ def raise_if_errors(self) -> None:
201
270
  """Raise an exception if there are any errors."""
202
271
  if self.has_errors():
203
- error_summary = f"Compilation failed with {len(self.errors)} error(s)"
204
- if self.warnings:
205
- error_summary += f" and {len(self.warnings)} warning(s)"
206
-
207
- # Create a summary error
208
- summary_error = create_error(
209
- MDLConfigurationError,
210
- error_summary,
211
- suggestion="Fix the errors above and try again."
272
+ error_messages = [str(error) for error in self.errors]
273
+ raise MDLBuildError(
274
+ message=f"Build failed with {len(self.errors)} error(s):\n" + "\n".join(error_messages),
275
+ error_type="build_error"
212
276
  )
213
-
214
- # Add all errors as context
215
- for error in self.errors:
216
- summary_error.message += f"\n- {error.message}"
217
-
218
- raise summary_error
277
+
278
+ def get_summary(self) -> str:
279
+ """Get a summary of errors and warnings."""
280
+ summary_parts = []
281
+
282
+ if self.errors:
283
+ summary_parts.append(f"{len(self.errors)} error(s)")
284
+
285
+ if self.warnings:
286
+ summary_parts.append(f"{len(self.warnings)} warning(s)")
287
+
288
+ if not summary_parts:
289
+ return "No issues found"
290
+
291
+ return ", ".join(summary_parts)
219
292
 
220
293
 
221
- def create_error(error_class: type, message: str, file_path: Optional[str] = None,
294
+ def create_error(error_type: str, message: str, file_path: Optional[str] = None,
222
295
  line: Optional[int] = None, column: Optional[int] = None,
223
- line_content: Optional[str] = None, suggestion: Optional[str] = None,
224
- context_lines: int = 2) -> MDLError:
225
- """Create an MDL error with the given information."""
296
+ line_content: Optional[str] = None, suggestion: Optional[str] = None) -> MDLError:
297
+ """Factory function to create appropriate error type."""
298
+ error_classes = {
299
+ "syntax": MDLSyntaxError,
300
+ "lexer": MDLLexerError,
301
+ "parser": MDLParserError,
302
+ "validation": MDLValidationError,
303
+ "build": MDLBuildError,
304
+ "compilation": MDLCompilationError,
305
+ "file": MDLFileError,
306
+ "configuration": MDLConfigurationError
307
+ }
308
+
309
+ error_class = error_classes.get(error_type, MDLError)
226
310
  return error_class(
227
311
  message=message,
228
312
  file_path=file_path,
229
313
  line=line,
230
314
  column=column,
231
315
  line_content=line_content,
232
- suggestion=suggestion,
233
- context_lines=context_lines
316
+ error_type=error_type,
317
+ suggestion=suggestion
234
318
  )
235
319
 
236
320
 
237
- def format_error_context(file_path: str, line: int, column: Optional[int], context_lines: int) -> str:
321
+ def get_line_content(file_path: str, line_number: int) -> Optional[str]:
322
+ """Get the content of a specific line from a file."""
323
+ try:
324
+ with open(file_path, 'r', encoding='utf-8') as f:
325
+ lines = f.readlines()
326
+ if 1 <= line_number <= len(lines):
327
+ return lines[line_number - 1]
328
+ except (FileNotFoundError, UnicodeDecodeError):
329
+ pass
330
+ return None
331
+
332
+
333
+ def format_error_context(file_path: str, line: int, column: int,
334
+ context_lines: int = 2) -> str:
238
335
  """Format error context with surrounding lines."""
239
336
  try:
240
337
  with open(file_path, 'r', encoding='utf-8') as f:
241
338
  lines = f.readlines()
242
339
 
243
- if not lines:
244
- return ""
245
-
246
- # Calculate line range to show
247
- start_line = max(0, line - context_lines - 1)
340
+ start_line = max(1, line - context_lines)
248
341
  end_line = min(len(lines), line + context_lines)
249
342
 
250
- context_parts = []
251
- for i in range(start_line, end_line):
252
- line_num = i + 1
253
- line_content = lines[i].rstrip('\n\r')
343
+ context = []
344
+ for i in range(start_line, end_line + 1):
345
+ prefix = ">>> " if i == line else " "
346
+ line_num = f"{i:4d}"
347
+ content = lines[i - 1].rstrip('\n')
348
+ context.append(f"{prefix}{line_num}: {content}")
254
349
 
255
- if line_num == line:
256
- # Highlight the error line
257
- prefix = f"{color.line_number(f'{line_num:3d}:')} "
258
- content = color.error(line_content)
259
- context_parts.append(f"{prefix}{content}")
260
- else:
261
- # Show context lines
262
- prefix = f"{color.context(f'{line_num:3d}:')} "
263
- content = color.context(line_content)
264
- context_parts.append(f"{prefix}{content}")
265
-
266
- return "\n".join(context_parts)
350
+ if i == line and column is not None:
351
+ # Add caret to show exact position
352
+ indent = " " * (column - 1)
353
+ context.append(f" {indent}^")
267
354
 
268
- except Exception:
269
- return "Unable to load file context"
355
+ return "\n".join(context)
356
+ except (FileNotFoundError, UnicodeDecodeError):
357
+ return f"Unable to read file: {file_path}"
270
358
 
271
359
 
272
360
  def create_syntax_error(message: str, file_path: Optional[str] = None,
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: minecraft-datapack-language
3
- Version: 15.4.7
3
+ Version: 15.4.9
4
4
  Summary: Compile JavaScript-style MDL language or Python API into a Minecraft datapack (1.21+ ready). Features variables, control flow, error handling, and VS Code extension.
5
5
  Project-URL: Homepage, https://www.mcmdl.com
6
6
  Project-URL: Documentation, https://www.mcmdl.com/docs
@@ -1,25 +1,25 @@
1
1
  minecraft_datapack_language/__init__.py,sha256=i-qCchbe5b2Fshgc6yCU9mddOLs2UBt9SAcLqfUIrT0,606
2
- minecraft_datapack_language/_version.py,sha256=SIXKzGXg_ZDjpdiyLe3C99MU-0N6v8GJBEqcqIzfHEs,706
2
+ minecraft_datapack_language/_version.py,sha256=kBS_aJPr-qhhnmfVNaDqUObyMzWJEMpsVQ-KXHKYm_8,706
3
3
  minecraft_datapack_language/ast_nodes.py,sha256=pgjI2Nlap3ixFPgWqGSkqncG9zB91h5BKgRjtcJqMew,2118
4
4
  minecraft_datapack_language/cli.py,sha256=p5A_tEEXugN2NhQFbbgfwi4FxbWYD91RWeKR_A3Vuec,6263
5
5
  minecraft_datapack_language/cli_build.py,sha256=HvrQdINx8EmF4OW6IZCx_S6Rs4NZQ-eB1PSlcDMnCmA,47939
6
6
  minecraft_datapack_language/cli_check.py,sha256=bPq9gHsxQ1CIiftkrAtRCifWkVAyjp5c8Oay2NNQ1qs,6277
7
7
  minecraft_datapack_language/cli_colors.py,sha256=Ims0KbdYpsiwoqv96Y_g89uOB5l1qdETm_P51rkljfk,7884
8
- minecraft_datapack_language/cli_help.py,sha256=z7PTqkrRYOFhfqe7CLdaF68kEAO5R1iP0j45b_36bEw,13196
9
- minecraft_datapack_language/cli_new.py,sha256=3K6gHCYwmOTXysicSWJNsjU1YXyz2xa5IGjoOtj1CKc,6489
8
+ minecraft_datapack_language/cli_help.py,sha256=jUTHUQBONAZKVTdQK9tNPXq4c_6xpsafNOvHDjkEldg,12243
9
+ minecraft_datapack_language/cli_new.py,sha256=_pj5EeXESAG00C80_os9jONIXAMcsu2eoR8xVJWDw6g,9347
10
10
  minecraft_datapack_language/cli_utils.py,sha256=nl22j96vpCW0XRMpD_zjwamnMU4e4LXEjACsnwiFGzs,9931
11
11
  minecraft_datapack_language/dir_map.py,sha256=HmxFkuvWGkzHF8o_GFb4BpuMCRc6QMw8UbmcAI8JVdY,1788
12
12
  minecraft_datapack_language/expression_processor.py,sha256=GN6cuRNvgI8TrV6YnEHrA9P0X-ACTT7rCBh4WlOPjSI,20140
13
13
  minecraft_datapack_language/linter.py,sha256=7UqbygC5JPCGg-BSOq65NB2xEJBu_OUOYIIgmHItO2M,16567
14
- minecraft_datapack_language/mdl_errors.py,sha256=O0lIem8C6GtOeYnbV0E0-ZGNVx9G7aD5X5LuzsvFCfs,11907
14
+ minecraft_datapack_language/mdl_errors.py,sha256=mz6uyPkeBpbMHj4PiAyVecEVJ9_hdSfR45QAjG6oYf0,15690
15
15
  minecraft_datapack_language/mdl_lexer_js.py,sha256=VvbhKm727khdSAABxa03hoIIA7H3hWi3RLp9BSXbhY0,28277
16
16
  minecraft_datapack_language/mdl_linter.py,sha256=z85xoAglENurCh30bR7kEHZ_JeMxcYaLDcGNRAl-RAI,17253
17
17
  minecraft_datapack_language/mdl_parser_js.py,sha256=SQzc67pKls3NVnQaT0xIILGqpZYAmcZn78TQ0KIM4TE,40216
18
18
  minecraft_datapack_language/pack.py,sha256=nYiXQ3jgJlDfc4m-65f7C2LFhDRioaUU_XVy6Na4SJI,34625
19
19
  minecraft_datapack_language/utils.py,sha256=Aq0HAGlXqj9BUTEjaEilpvzEW0EtZYYMMwOqG9db6dE,684
20
- minecraft_datapack_language-15.4.7.dist-info/licenses/LICENSE,sha256=OXLcl0T2SZ8Pmy2_dmlvKuetivmyPd5m1q-Gyd-zaYY,35149
21
- minecraft_datapack_language-15.4.7.dist-info/METADATA,sha256=Y1SE5p89bmmGEXZK674BS73GdhoYCCm9YAYtT0yYPdc,35229
22
- minecraft_datapack_language-15.4.7.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
23
- minecraft_datapack_language-15.4.7.dist-info/entry_points.txt,sha256=c6vjBeCiyQflvPHBRyBk2nJCSfYt3Oc7Sc9V87ySi_U,108
24
- minecraft_datapack_language-15.4.7.dist-info/top_level.txt,sha256=ADtFI476tbKLLxEAA-aJQAfg53MA3k_DOb0KTFiggfw,28
25
- minecraft_datapack_language-15.4.7.dist-info/RECORD,,
20
+ minecraft_datapack_language-15.4.9.dist-info/licenses/LICENSE,sha256=OXLcl0T2SZ8Pmy2_dmlvKuetivmyPd5m1q-Gyd-zaYY,35149
21
+ minecraft_datapack_language-15.4.9.dist-info/METADATA,sha256=OToHEbhvuer4uXbIRTJGD8DZzuiZ-aUqZAOINC5qcsM,35229
22
+ minecraft_datapack_language-15.4.9.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
23
+ minecraft_datapack_language-15.4.9.dist-info/entry_points.txt,sha256=c6vjBeCiyQflvPHBRyBk2nJCSfYt3Oc7Sc9V87ySi_U,108
24
+ minecraft_datapack_language-15.4.9.dist-info/top_level.txt,sha256=ADtFI476tbKLLxEAA-aJQAfg53MA3k_DOb0KTFiggfw,28
25
+ minecraft_datapack_language-15.4.9.dist-info/RECORD,,