orionis 0.27.0__py3-none-any.whl → 0.30.0__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.
orionis/framework.py CHANGED
@@ -5,7 +5,7 @@
5
5
  NAME = "orionis"
6
6
 
7
7
  # Current version of the framework
8
- VERSION = "0.27.0"
8
+ VERSION = "0.30.0"
9
9
 
10
10
  # Full name of the author or maintainer of the project
11
11
  AUTHOR = "Raul Mauricio Uñate Castro"
orionis/luminate/app.py CHANGED
@@ -1,6 +1,36 @@
1
1
  from orionis.luminate.container.container import Container
2
2
 
3
- class OrionisApp:
3
+ class App:
4
4
 
5
- def __init__(self, config):
6
- self.container = Container()
5
+ def __init__(self):
6
+ # Inicializa el contenedor de dependencias
7
+ self.container = Container()
8
+
9
+ def start(self):
10
+ pass
11
+
12
+ def finish(self):
13
+ pass
14
+
15
+ def in_context(self):
16
+ """Método placeholder para gestionar el contexto de la aplicación"""
17
+ pass
18
+
19
+ def register_service_providers(self):
20
+ """
21
+ Registra los proveedores de servicios en el contenedor.
22
+ Carga y registra los servicios de forma perezosa.
23
+ """
24
+ # Importación perezosa de los servicios
25
+ from orionis.luminate.cache.app.config import CacheConfig
26
+ from orionis.luminate.bootstrap.config.register import Register
27
+ from orionis.luminate.bootstrap.config.bootstrapper import Bootstrapper
28
+
29
+ # Registro de servicios esenciales en el contenedor
30
+ self.container.singleton(CacheConfig) # Configuración del cache
31
+ self.container.singleton(Register) # Registro de la configuración de la app
32
+ self.container.singleton(Bootstrapper) # Inicialización del sistema
33
+
34
+ def load_config(self):
35
+ """Método placeholder para cargar la configuración de la aplicación"""
36
+ pass
@@ -65,7 +65,7 @@ class Bootstrapper(IBootstrapper):
65
65
  # Define the command directories to search
66
66
  command_dirs = [
67
67
  base_path / "app" / "console" / "commands",
68
- pathlib.Path(__file__).resolve().parent.parent / "console" / "commands"
68
+ pathlib.Path(__file__).resolve().parent.parent.parent / "console" / "commands"
69
69
  ]
70
70
 
71
71
  # Iterate over each command directory
@@ -84,10 +84,12 @@ class Bootstrapper(IBootstrapper):
84
84
 
85
85
  # Convert file path to a Python module import path
86
86
  module_path = ".".join(file_path.relative_to(base_path).with_suffix("").parts)
87
+ if 'site-packages.' in module_path:
88
+ module_path = module_path.split('site-packages.')[1]
87
89
 
88
90
  try:
89
91
  # Dynamically import the module
90
- module = importlib.import_module(module_path)
92
+ module = importlib.import_module(module_path.strip())
91
93
 
92
94
  # Find classes that inherit from `BaseCommand`
93
95
  for name, obj in inspect.getmembers(module, inspect.isclass):
@@ -4,6 +4,7 @@ import getpass
4
4
  import datetime
5
5
  from orionis.luminate.console.output.styles import ANSIColors
6
6
  from orionis.luminate.contracts.console.output.console_interface import IConsole
7
+ from orionis.luminate.tools.exception_to_dict import ExceptionsToDict
7
8
 
8
9
  class Console(IConsole):
9
10
  """
@@ -424,3 +425,39 @@ class Console(IConsole):
424
425
  answer = input("Please select a valid number: ").strip()
425
426
 
426
427
  return choices[int(answer) - 1]
428
+
429
+ @staticmethod
430
+ def exception(e) -> None:
431
+ """
432
+ Prints an exception message with detailed information.
433
+
434
+ Parameters
435
+ ----------
436
+ exception : Exception
437
+ The exception to print.
438
+
439
+ Notes
440
+ -----
441
+ This method prints the exception type, message, and a detailed stack trace.
442
+ """
443
+
444
+ errors = ExceptionsToDict.parse(e)
445
+ error_type = errors.get("error_type")
446
+ error_message = errors.get("error_message")
447
+ stack_trace = errors.get("stack_trace")
448
+
449
+ # Format the output with a more eye-catching appearance
450
+ message = f"{ANSIColors.BG_ERROR.value}{ANSIColors.TEXT_WHITE.value} [{error_type}] {ANSIColors.TEXT_RESET.value}: {ANSIColors.TEXT_WARNING.value}{error_message}{ANSIColors.TEXT_RESET.value}"
451
+ print("-" * len(f" [{error_type}] : {error_message}")) # separator line
452
+ print(message)
453
+
454
+ for frame in stack_trace:
455
+ filename = frame["filename"]
456
+ lineno = frame["lineno"]
457
+ name = frame["name"]
458
+ line = frame["line"]
459
+
460
+ # Print the stack trace with enhanced styling
461
+ print(f"{ANSIColors.CYAN.value}{ANSIColors.DIM.value} {ANSIColors.MAGENTA.value}{ANSIColors.TEXT_BOLD.value}{filename}:{ANSIColors.TEXT_BOLD.value}{lineno}{ANSIColors.TEXT_RESET.value} / {ANSIColors.DIM.value}{ANSIColors.ITALIC.value}{ANSIColors.TEXT_WARNING.value}{name}{ANSIColors.TEXT_RESET.value} / {ANSIColors.CYAN.value}{line}{ANSIColors.TEXT_RESET.value}")
462
+
463
+ print("-" * len(f" [{error_type}] : {error_message}"))
@@ -93,3 +93,7 @@ class ANSIColors(Enum):
93
93
  TEXT_BOLD = "\033[1m" # Bold text
94
94
  TEXT_STYLE_UNDERLINE = '\033[4m' # Underline text
95
95
  TEXT_RESET = "\033[0m" # Reset styles
96
+ CYAN = "\033[36m"
97
+ DIM = "\033[2m"
98
+ MAGENTA = "\033[35m"
99
+ ITALIC = "\033[3m"
@@ -302,4 +302,20 @@ class IConsole(ABC):
302
302
  one by entering the corresponding number. If an invalid input is provided,
303
303
  the user will be repeatedly prompted until a valid choice is made.
304
304
  """
305
+ pass
306
+
307
+ @abstractmethod
308
+ def exception(e) -> None:
309
+ """
310
+ Prints an exception message with detailed information.
311
+
312
+ Parameters
313
+ ----------
314
+ exception : Exception
315
+ The exception to print.
316
+
317
+ Notes
318
+ -----
319
+ This method prints the exception type, message, and a detailed stack trace.
320
+ """
305
321
  pass
@@ -0,0 +1,35 @@
1
+ from abc import ABC, abstractmethod
2
+
3
+ class IExceptionsToDict(ABC):
4
+ """
5
+ A utility class to parse an exception and convert it into a structured dictionary.
6
+
7
+ Methods
8
+ -------
9
+ parse(exception: Exception) -> dict
10
+ Converts an exception into a dictionary containing the error type, message,
11
+ and stack trace information.
12
+ """
13
+
14
+ @abstractmethod
15
+ def parse(exception):
16
+ """
17
+ Parse the provided exception and serialize it into a dictionary format.
18
+
19
+ Parameters
20
+ ----------
21
+ exception : Exception
22
+ The exception object to be serialized.
23
+
24
+ Returns
25
+ -------
26
+ dict
27
+ A dictionary containing the exception details such as error type, message,
28
+ and the stack trace.
29
+
30
+ Notes
31
+ -----
32
+ - Uses `traceback.TracebackException.from_exception()` to extract detailed traceback information.
33
+ - The stack trace includes filenames, line numbers, function names, and the exact line of code.
34
+ """
35
+ pass
@@ -0,0 +1,111 @@
1
+ import traceback
2
+ from orionis.luminate.app import App
3
+
4
+ class OrionisContext:
5
+ """
6
+ Context manager for the Orionis application that handles startup and cleanup.
7
+
8
+ This class manages the lifecycle of an Orionis application instance.
9
+ It starts the application when entering the context and ensures that the
10
+ application is properly finished when exiting, capturing any exceptions that occur.
11
+
12
+ Attributes
13
+ ----------
14
+ is_started : bool
15
+ Flag indicating whether the application has been successfully started.
16
+ app : App
17
+ Instance of the Orionis application.
18
+ error_info : tuple or None
19
+ Tuple containing the exception instance and its formatted traceback if an error occurs;
20
+ otherwise, None.
21
+ """
22
+
23
+ def __init__(self):
24
+ """
25
+ Initialize the OrionisContext.
26
+
27
+ Sets up the application instance and initializes state variables.
28
+ """
29
+ self.is_started = False
30
+ self.app = App()
31
+ self.error_info = None
32
+
33
+ def __enter__(self):
34
+ """
35
+ Enter the runtime context and start the application.
36
+
37
+ Attempts to start the Orionis application. If successful, sets the active flag
38
+ and returns the context instance. If an exception is raised during startup,
39
+ captures the exception and its traceback before re-raising it.
40
+
41
+ Returns
42
+ -------
43
+ OrionisContext
44
+ The current context instance with the application started.
45
+
46
+ Raises
47
+ ------
48
+ Exception
49
+ Re-raises any exception that occurs during the application startup.
50
+ """
51
+ try:
52
+ self.app.start()
53
+ self.is_started = True
54
+ return self
55
+ except Exception as e:
56
+ self.error_info = (e, traceback.format_exc())
57
+ raise
58
+
59
+ def __exit__(self, exc_type, exc_val, exc_tb):
60
+ """
61
+ Exit the runtime context and finish the application.
62
+
63
+ Calls the application's finish method to perform cleanup regardless of whether
64
+ an exception occurred. If an exception occurred, captures its information and
65
+ returns False to indicate that the exception should not be suppressed.
66
+
67
+ Parameters
68
+ ----------
69
+ exc_type : type
70
+ The type of the exception raised (if any).
71
+ exc_val : Exception
72
+ The exception instance raised (if any).
73
+ exc_tb : traceback
74
+ The traceback associated with the exception (if any).
75
+
76
+ Returns
77
+ -------
78
+ bool
79
+ Always returns False so that any exception is propagated.
80
+ """
81
+ try:
82
+ self.app.finish()
83
+ finally:
84
+ self.is_started = False
85
+
86
+ if exc_type:
87
+ self.error_info = (exc_val, traceback.format_exc())
88
+ return False
89
+
90
+ def is_active(self):
91
+ """
92
+ Check if the application is currently active.
93
+
94
+ Returns
95
+ -------
96
+ bool
97
+ True if the application has been started and is active, False otherwise.
98
+ """
99
+ return self.is_started
100
+
101
+ def get_error(self):
102
+ """
103
+ Retrieve the stored error information.
104
+
105
+ Returns
106
+ -------
107
+ tuple or None
108
+ A tuple containing the exception and its formatted traceback if an error occurred;
109
+ otherwise, None.
110
+ """
111
+ return self.error_info
@@ -0,0 +1,52 @@
1
+ from orionis.luminate.contracts.tools.exception_to_dict_interface import IExceptionsToDict
2
+ import traceback
3
+
4
+ class ExceptionsToDict(IExceptionsToDict):
5
+ """
6
+ A utility class to parse an exception and convert it into a structured dictionary.
7
+
8
+ Methods
9
+ -------
10
+ parse(exception: Exception) -> dict
11
+ Converts an exception into a dictionary containing the error type, message,
12
+ and stack trace information.
13
+ """
14
+
15
+ @staticmethod
16
+ def parse(exception):
17
+ """
18
+ Parse the provided exception and serialize it into a dictionary format.
19
+
20
+ Parameters
21
+ ----------
22
+ exception : Exception
23
+ The exception object to be serialized.
24
+
25
+ Returns
26
+ -------
27
+ dict
28
+ A dictionary containing the exception details such as error type, message,
29
+ and the stack trace.
30
+
31
+ Notes
32
+ -----
33
+ - Uses `traceback.TracebackException.from_exception()` to extract detailed traceback information.
34
+ - The stack trace includes filenames, line numbers, function names, and the exact line of code.
35
+ """
36
+ # Extract the detailed traceback information from the exception
37
+ tb = traceback.TracebackException.from_exception(exception)
38
+
39
+ # Construct and return the dictionary containing all necessary exception details
40
+ return {
41
+ "error_type": tb.exc_type_str, # Using `exc_type_str` to avoid deprecation warnings
42
+ "error_message": str(tb), # A string representation of the entire traceback message
43
+ "stack_trace": [
44
+ {
45
+ "filename": frame.filename, # The source file of the frame
46
+ "lineno": frame.lineno, # The line number where the exception occurred
47
+ "name": frame.name, # The function name
48
+ "line": frame.line # The line of code in the frame
49
+ }
50
+ for frame in tb.stack # Iterating over each frame in the traceback stack
51
+ ]
52
+ }
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.2
2
2
  Name: orionis
3
- Version: 0.27.0
3
+ Version: 0.30.0
4
4
  Summary: Orionis Framework – Elegant, Fast, and Powerful.
5
5
  Home-page: https://github.com/orionis-framework/framework
6
6
  Author: Raul Mauricio Uñate Castro
@@ -1,11 +1,12 @@
1
1
  orionis/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
2
2
  orionis/cli_manager.py,sha256=9wNVJxB0HyqUbNesUvkwlsqTyUbZwK6R46iVLE5WVBQ,1715
3
- orionis/framework.py,sha256=YAVaj0HKJgo1NVBMFlLifezZIIm_9SwPXeiVeTOL2Cg,1386
3
+ orionis/framework.py,sha256=xtmJazlCIPVp_r-jU-eWaI19VnVIrsyHVtGbaEm1o2o,1386
4
4
  orionis/luminate/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
5
- orionis/luminate/app.py,sha256=fh5p0w5VBb0zJ6qKNHOCs2vxIix6AborENZFW_GCvrw,152
5
+ orionis/luminate/app.py,sha256=4exLRx5qKyHz9aeb0DCZMcbUe0gDGuKP5lt2AfkrB10,1290
6
+ orionis/luminate/orionis.py,sha256=VM6YgIBZBu6WU7Tv5i22wbuIhWVJsDrtDxokBP169o8,3512
6
7
  orionis/luminate/bootstrap/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
7
8
  orionis/luminate/bootstrap/cli_exception.py,sha256=wDKfEW295c7-bavr7YUHK2CLYcTSZgjT9ZRSBne6GOE,1356
8
- orionis/luminate/bootstrap/commands/bootstrapper.py,sha256=0TtExkxyokfMSooR5-RieOQKiIt8dY_iodT_WA_Ncpc,3874
9
+ orionis/luminate/bootstrap/commands/bootstrapper.py,sha256=TuXuQUzeaiDL8sJyZNdqnFl2h2MfxcnSU045IeIKVQE,4016
9
10
  orionis/luminate/bootstrap/commands/register.py,sha256=YonMvfe1TQBVPLxqM7o7_mYaXPKoXvZNRSsW365uVtM,3734
10
11
  orionis/luminate/bootstrap/config/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
11
12
  orionis/luminate/bootstrap/config/bootstrapper.py,sha256=PtmZJIH8sHVOdGIogLlqTuPD0XZvR2DgOnPZDgSng9o,2971
@@ -47,10 +48,10 @@ orionis/luminate/console/commands/version.py,sha256=oM5Vr_2Xc7Eaq6VHbcMaTeteY0cD
47
48
  orionis/luminate/console/exceptions/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
48
49
  orionis/luminate/console/exceptions/cli_exception.py,sha256=QM7tRdPBoo7WdmAb3Zasj8d3429zskftUGYHAvhcnSU,4631
49
50
  orionis/luminate/console/output/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
50
- orionis/luminate/console/output/console.py,sha256=KTQKMpVVOdCsGUxrKRSQzlqmz42wwWV-8b14q_mfrYI,14481
51
+ orionis/luminate/console/output/console.py,sha256=61rMbYQHmQxzt2cZdX9Sz6y9TidqDiDfrPFXghky8Rg,16178
51
52
  orionis/luminate/console/output/executor.py,sha256=J4lmWMRCXW2b5L8PbX31q1fGnnjYZOO93O4rtPyA_0A,3379
52
53
  orionis/luminate/console/output/progress_bar.py,sha256=YT8Gl-_Zfc3E6foU-Dw7aAndZm4m-xY36G3MpPi3Aj4,3106
53
- orionis/luminate/console/output/styles.py,sha256=fF_B1kw95lkiLUzq4cjYPppF-sLsx9_qmyhKqoeZrJ0,3604
54
+ orionis/luminate/console/output/styles.py,sha256=2e1_FJdNpKaVqmdlCx-udzTleH_6uEFE9_TjH7T1ZUk,3696
54
55
  orionis/luminate/console/scripts/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
55
56
  orionis/luminate/console/scripts/management.py,sha256=J5gLXtvX8I1zdNk6sa23njR18D5s4LJXZK7ElK0sFzI,2868
56
57
  orionis/luminate/console/tasks/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
@@ -78,7 +79,7 @@ orionis/luminate/contracts/console/parser_interface.py,sha256=vMmTK0wMfTjt7H-tRf
78
79
  orionis/luminate/contracts/console/runner_interface.py,sha256=vWLtMhl0m1T6rfCUHZbxGQJl9ZWTXlp3HjcTfCAztGk,1644
79
80
  orionis/luminate/contracts/console/task_manager_interface.py,sha256=sOmeifoncpWCG2WYh4q3QZ7M7w7P9Onb3Jxw9X2lpXE,1197
80
81
  orionis/luminate/contracts/console/base/base_command_interface.py,sha256=Lz0ktEjeXcqU5803BVIDT8H3fhbvfkd3Ngsa561lrZY,12241
81
- orionis/luminate/contracts/console/output/console_interface.py,sha256=NL6GsbJy286y0wcWhAhqavC6G2EW_WZJYQdH9wMO8Vc,8517
82
+ orionis/luminate/contracts/console/output/console_interface.py,sha256=bkYTT5oIK3NP-p7XONgi1z_SO50ZvJu31Nv7cjs4t7s,8902
82
83
  orionis/luminate/contracts/console/output/executor_interface.py,sha256=MGMTTPSwF8dgCjHD3A4CKtYDaCcD-KU28dorC61Q04k,1411
83
84
  orionis/luminate/contracts/console/output/progress_bar_interface.py,sha256=sOkQzQsliFemqZHMyzs4fWhNJfXDTk5KH3aExReetSE,1760
84
85
  orionis/luminate/contracts/console/scripts/management_interface.py,sha256=4Zc8da5iz3kHZju61A0krArKVZ5K39B0Imk1GmgTMks,1586
@@ -104,6 +105,7 @@ orionis/luminate/contracts/publisher/pypi_publisher_interface.py,sha256=u0mEMbli
104
105
  orionis/luminate/contracts/test/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
105
106
  orionis/luminate/contracts/test/unit_test_interface.py,sha256=F6jKKZcpQ94acqpbUjPwSOZGJB7McD5hHH1lStqL9Go,1486
106
107
  orionis/luminate/contracts/tools/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
108
+ orionis/luminate/contracts/tools/exception_to_dict_interface.py,sha256=rCuhx2tmUgT4flpsyw4tLnjMbrVTURbADUQxC16cCgA,1079
107
109
  orionis/luminate/contracts/tools/reflection_interface.py,sha256=k9y7So3Z-_QFBBaCl-4t50ZRixt1pcxPtpwlo1NrSGk,8140
108
110
  orionis/luminate/contracts/tools/std_interface.py,sha256=VtOlmz7c1llBRVzKnEBA4aJE5m0Y0w7pFJ_1TgG1-G0,1408
109
111
  orionis/luminate/facades/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
@@ -137,15 +139,16 @@ orionis/luminate/test/exception.py,sha256=VJaZ7VMZfdKW1ov_GwKp2HAz_NYobujJxDt5Ra
137
139
  orionis/luminate/test/unit_test.py,sha256=3zemWa150SfxcXhs1n1TjYvbfLgwqJjhwFPnUlLLtgg,3738
138
140
  orionis/luminate/tools/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
139
141
  orionis/luminate/tools/dot_dict.py,sha256=FVHfBuAGTTVMjNG01Fix645fRNKKUMmNx61pYkxPL5c,1253
142
+ orionis/luminate/tools/exception_to_dict.py,sha256=ylnLmn5W7EW8b_gZrB6MwwNHqdbVqhdLdKtR1gNakKo,2113
140
143
  orionis/luminate/tools/reflection.py,sha256=3G4nZIE73LDtGJLlq9U_P9O2FnTi5-wr9s00CVAmjFw,11959
141
144
  orionis/luminate/tools/std.py,sha256=wquV7xgT1tvSRpbrq5h_GQwCof9cXjen-vuWPubAKbs,1398
142
145
  tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
143
146
  tests/tools/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
144
147
  tests/tools/class_example.py,sha256=dIPD997Y15n6WmKhWoOFSwEldRm9MdOHTZZ49eF1p3c,1056
145
148
  tests/tools/test_reflection.py,sha256=dNN5p_xAosyEf0ddAElmmmTfhcTtBd4zBNl7qzgnsc0,5242
146
- orionis-0.27.0.dist-info/LICENCE,sha256=-_4cF2EBKuYVS_SQpy1uapq0oJPUU1vl_RUWSy2jJTo,1111
147
- orionis-0.27.0.dist-info/METADATA,sha256=DwS_1R60RwWhZk4NtiMg9I7rfxNxrAyuk7XhL-Dm0Qo,2978
148
- orionis-0.27.0.dist-info/WHEEL,sha256=In9FTNxeP60KnTkGw7wk6mJPYd_dQSjEZmXdBdMCI-8,91
149
- orionis-0.27.0.dist-info/entry_points.txt,sha256=eef1_CVewfokKjrGBynXa06KabSJYo7LlDKKIKvs1cM,53
150
- orionis-0.27.0.dist-info/top_level.txt,sha256=2bdoHgyGZhOtLAXS6Om8OCTmL24dUMC_L1quMe_ETbk,14
151
- orionis-0.27.0.dist-info/RECORD,,
149
+ orionis-0.30.0.dist-info/LICENCE,sha256=-_4cF2EBKuYVS_SQpy1uapq0oJPUU1vl_RUWSy2jJTo,1111
150
+ orionis-0.30.0.dist-info/METADATA,sha256=PsyKM0V1nld_HPgnrK97KGWIBmxLNxuizjJaMfTeFWc,2978
151
+ orionis-0.30.0.dist-info/WHEEL,sha256=In9FTNxeP60KnTkGw7wk6mJPYd_dQSjEZmXdBdMCI-8,91
152
+ orionis-0.30.0.dist-info/entry_points.txt,sha256=eef1_CVewfokKjrGBynXa06KabSJYo7LlDKKIKvs1cM,53
153
+ orionis-0.30.0.dist-info/top_level.txt,sha256=2bdoHgyGZhOtLAXS6Om8OCTmL24dUMC_L1quMe_ETbk,14
154
+ orionis-0.30.0.dist-info/RECORD,,