falyx 0.1.22__py3-none-any.whl → 0.1.24__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.
falyx/selection_action.py CHANGED
@@ -10,6 +10,7 @@ from falyx.action import BaseAction
10
10
  from falyx.context import ExecutionContext
11
11
  from falyx.execution_registry import ExecutionRegistry as er
12
12
  from falyx.hook_manager import HookType
13
+ from falyx.logger import logger
13
14
  from falyx.selection import (
14
15
  SelectionOption,
15
16
  prompt_for_index,
@@ -18,17 +19,25 @@ from falyx.selection import (
18
19
  render_selection_indexed_table,
19
20
  )
20
21
  from falyx.themes.colors import OneColors
21
- from falyx.utils import CaseInsensitiveDict, logger
22
+ from falyx.utils import CaseInsensitiveDict
22
23
 
23
24
 
24
25
  class SelectionAction(BaseAction):
26
+ """
27
+ A selection action that prompts the user to select an option from a list or
28
+ dictionary. The selected option is then returned as the result of the action.
29
+
30
+ If return_key is True, the key of the selected option is returned instead of
31
+ the value.
32
+ """
33
+
25
34
  def __init__(
26
35
  self,
27
36
  name: str,
28
37
  selections: list[str] | set[str] | tuple[str, ...] | dict[str, SelectionOption],
29
38
  *,
30
39
  title: str = "Select an option",
31
- columns: int = 2,
40
+ columns: int = 5,
32
41
  prompt_message: str = "Select > ",
33
42
  default_selection: str = "",
34
43
  inject_last_result: bool = False,
@@ -45,7 +54,8 @@ class SelectionAction(BaseAction):
45
54
  inject_into=inject_into,
46
55
  never_prompt=never_prompt,
47
56
  )
48
- self.selections: list[str] | CaseInsensitiveDict = selections
57
+ # Setter normalizes to correct type, mypy can't infer that
58
+ self.selections: list[str] | CaseInsensitiveDict = selections # type: ignore[assignment]
49
59
  self.return_key = return_key
50
60
  self.title = title
51
61
  self.columns = columns
@@ -71,7 +81,8 @@ class SelectionAction(BaseAction):
71
81
  self._selections = cid
72
82
  else:
73
83
  raise TypeError(
74
- f"'selections' must be a list[str] or dict[str, SelectionOption], got {type(value).__name__}"
84
+ "'selections' must be a list[str] or dict[str, SelectionOption], "
85
+ f"got {type(value).__name__}"
75
86
  )
76
87
 
77
88
  async def _run(self, *args, **kwargs) -> Any:
@@ -108,7 +119,8 @@ class SelectionAction(BaseAction):
108
119
 
109
120
  if self.never_prompt and not effective_default:
110
121
  raise ValueError(
111
- f"[{self.name}] 'never_prompt' is True but no valid default_selection was provided."
122
+ f"[{self.name}] 'never_prompt' is True but no valid default_selection "
123
+ "was provided."
112
124
  )
113
125
 
114
126
  context.start_timer()
@@ -152,7 +164,8 @@ class SelectionAction(BaseAction):
152
164
  result = key if self.return_key else self.selections[key].value
153
165
  else:
154
166
  raise TypeError(
155
- f"'selections' must be a list[str] or dict[str, tuple[str, Any]], got {type(self.selections).__name__}"
167
+ "'selections' must be a list[str] or dict[str, tuple[str, Any]], "
168
+ f"got {type(self.selections).__name__}"
156
169
  )
157
170
  context.result = result
158
171
  await self.hooks.trigger(HookType.ON_SUCCESS, context)
@@ -186,7 +199,7 @@ class SelectionAction(BaseAction):
186
199
  if len(self.selections) > 10:
187
200
  sub.add(f"[dim]... ({len(self.selections) - 10} more)[/]")
188
201
  else:
189
- tree.add("[bold red]Invalid selections type[/]")
202
+ tree.add(f"[{OneColors.DARK_RED_b}]Invalid selections type[/]")
190
203
  return
191
204
 
192
205
  tree.add(f"[dim]Default:[/] '{self.default_selection or self.last_result}'")
@@ -205,5 +218,6 @@ class SelectionAction(BaseAction):
205
218
  return (
206
219
  f"SelectionAction(name={self.name!r}, type={selection_type}, "
207
220
  f"default_selection={self.default_selection!r}, "
208
- f"return_key={self.return_key}, prompt={'off' if self.never_prompt else 'on'})"
221
+ f"return_key={self.return_key}, "
222
+ f"prompt={'off' if self.never_prompt else 'on'})"
209
223
  )
falyx/signal_action.py CHANGED
@@ -1,3 +1,5 @@
1
+ # Falyx CLI Framework — (c) 2025 rtj.dev LLC — MIT Licensed
2
+ """signal_action.py"""
1
3
  from falyx.action import Action
2
4
  from falyx.signals import FlowSignal
3
5
 
falyx/signals.py CHANGED
@@ -1,4 +1,7 @@
1
1
  # Falyx CLI Framework — (c) 2025 rtj.dev LLC — MIT Licensed
2
+ """signals.py"""
3
+
4
+
2
5
  class FlowSignal(BaseException):
3
6
  """Base class for all flow control signals in Falyx.
4
7
 
falyx/tagged_table.py CHANGED
@@ -1,4 +1,5 @@
1
1
  # Falyx CLI Framework — (c) 2025 rtj.dev LLC — MIT Licensed
2
+ """tagged_table.py"""
2
3
  from collections import defaultdict
3
4
 
4
5
  from rich import box
@@ -10,7 +11,7 @@ from falyx.falyx import Falyx
10
11
 
11
12
  def build_tagged_table(flx: Falyx) -> Table:
12
13
  """Custom table builder that groups commands by tags."""
13
- table = Table(title=flx.title, show_header=False, box=box.SIMPLE)
14
+ table = Table(title=flx.title, show_header=False, box=box.SIMPLE) # type: ignore[arg-type]
14
15
 
15
16
  # Group commands by first tag
16
17
  grouped: dict[str, list[Command]] = defaultdict(list)
falyx/utils.py CHANGED
@@ -1,5 +1,7 @@
1
1
  # Falyx CLI Framework — (c) 2025 rtj.dev LLC — MIT Licensed
2
2
  """utils.py"""
3
+ from __future__ import annotations
4
+
3
5
  import functools
4
6
  import inspect
5
7
  import logging
@@ -10,23 +12,12 @@ from itertools import islice
10
12
  from typing import Any, Awaitable, Callable, TypeVar
11
13
 
12
14
  import pythonjsonlogger.json
13
- from prompt_toolkit import PromptSession
14
- from prompt_toolkit.formatted_text import (
15
- AnyFormattedText,
16
- FormattedText,
17
- merge_formatted_text,
18
- )
19
15
  from rich.logging import RichHandler
20
16
 
21
- from falyx.themes.colors import OneColors
22
- from falyx.validators import yes_no_validator
23
-
24
- logger = logging.getLogger("falyx")
25
-
26
17
  T = TypeVar("T")
27
18
 
28
19
 
29
- async def _noop(*args, **kwargs):
20
+ async def _noop(*_, **__):
30
21
  pass
31
22
 
32
23
 
@@ -70,22 +61,6 @@ def chunks(iterator, size):
70
61
  yield chunk
71
62
 
72
63
 
73
- async def confirm_async(
74
- message: AnyFormattedText = "Are you sure?",
75
- prefix: AnyFormattedText = FormattedText([(OneColors.CYAN, "❓ ")]),
76
- suffix: AnyFormattedText = FormattedText([(OneColors.LIGHT_YELLOW_b, " [Y/n] > ")]),
77
- session: PromptSession | None = None,
78
- ) -> bool:
79
- """Prompt the user with a yes/no async confirmation and return True for 'Y'."""
80
- session = session or PromptSession()
81
- merged_message: AnyFormattedText = merge_formatted_text([prefix, message, suffix])
82
- answer = await session.prompt_async(
83
- merged_message,
84
- validator=yes_no_validator(),
85
- )
86
- return True if answer.upper() == "Y" else False
87
-
88
-
89
64
  class CaseInsensitiveDict(dict):
90
65
  """A case-insensitive dictionary that treats all keys as uppercase."""
91
66
 
@@ -114,12 +89,6 @@ class CaseInsensitiveDict(dict):
114
89
  items.update({self._normalize_key(k): v for k, v in kwargs.items()})
115
90
  super().update(items)
116
91
 
117
- def __iter__(self):
118
- return super().__iter__()
119
-
120
- def keys(self):
121
- return super().keys()
122
-
123
92
 
124
93
  def running_in_container() -> bool:
125
94
  try:
@@ -143,11 +112,13 @@ def setup_logging(
143
112
  console_log_level: int = logging.WARNING,
144
113
  ):
145
114
  """
146
- Configure logging for Falyx with support for both CLI-friendly and structured JSON output.
115
+ Configure logging for Falyx with support for both CLI-friendly and structured
116
+ JSON output.
147
117
 
148
- This function sets up separate logging handlers for console and file output, with optional
149
- support for JSON formatting. It also auto-detects whether the application is running inside
150
- a container to default to machine-readable logs when appropriate.
118
+ This function sets up separate logging handlers for console and file output,
119
+ with optional support for JSON formatting. It also auto-detects whether the
120
+ application is running inside a container to default to machine-readable logs
121
+ when appropriate.
151
122
 
152
123
  Args:
153
124
  mode (str | None):
@@ -170,7 +141,8 @@ def setup_logging(
170
141
  - Clears existing root handlers before setup.
171
142
  - Configures console logging using either Rich (for CLI) or JSON formatting.
172
143
  - Configures file logging in plain text or JSON based on `json_log_to_file`.
173
- - Automatically sets logging levels for noisy third-party modules (`urllib3`, `asyncio`).
144
+ - Automatically sets logging levels for noisy third-party modules
145
+ (`urllib3`, `asyncio`, `markdown_it`).
174
146
  - Propagates logs from the "falyx" logger to ensure centralized output.
175
147
 
176
148
  Raises:
falyx/validators.py CHANGED
@@ -1,4 +1,5 @@
1
1
  # Falyx CLI Framework — (c) 2025 rtj.dev LLC — MIT Licensed
2
+ """validators.py"""
2
3
  from typing import KeysView, Sequence
3
4
 
4
5
  from prompt_toolkit.validation import Validator
@@ -7,10 +8,10 @@ from prompt_toolkit.validation import Validator
7
8
  def int_range_validator(minimum: int, maximum: int) -> Validator:
8
9
  """Validator for integer ranges."""
9
10
 
10
- def validate(input: str) -> bool:
11
+ def validate(text: str) -> bool:
11
12
  try:
12
- value = int(input)
13
- if not (minimum <= value <= maximum):
13
+ value = int(text)
14
+ if not minimum <= value <= maximum:
14
15
  return False
15
16
  return True
16
17
  except ValueError:
@@ -25,8 +26,8 @@ def int_range_validator(minimum: int, maximum: int) -> Validator:
25
26
  def key_validator(keys: Sequence[str] | KeysView[str]) -> Validator:
26
27
  """Validator for key inputs."""
27
28
 
28
- def validate(input: str) -> bool:
29
- if input.upper() not in [key.upper() for key in keys]:
29
+ def validate(text: str) -> bool:
30
+ if text.upper() not in [key.upper() for key in keys]:
30
31
  return False
31
32
  return True
32
33
 
@@ -38,8 +39,8 @@ def key_validator(keys: Sequence[str] | KeysView[str]) -> Validator:
38
39
  def yes_no_validator() -> Validator:
39
40
  """Validator for yes/no inputs."""
40
41
 
41
- def validate(input: str) -> bool:
42
- if input.upper() not in ["Y", "N"]:
42
+ def validate(text: str) -> bool:
43
+ if text.upper() not in ["Y", "N"]:
43
44
  return False
44
45
  return True
45
46
 
falyx/version.py CHANGED
@@ -1 +1 @@
1
- __version__ = "0.1.22"
1
+ __version__ = "0.1.24"
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: falyx
3
- Version: 0.1.22
3
+ Version: 0.1.24
4
4
  Summary: Reliable and introspectable async CLI action framework.
5
5
  License: MIT
6
6
  Author: Roland Thomas Jr
@@ -0,0 +1,42 @@
1
+ falyx/.pytyped,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
2
+ falyx/__init__.py,sha256=dYRamQJlT1Zoy5Uu1uG4NCV05Xk98nN1LAQrSR1CT2A,643
3
+ falyx/__main__.py,sha256=g_LwJieofK3DJzCYtpkAMEeOXhzSLQenb7pRVUqcf-Y,2152
4
+ falyx/action.py,sha256=9iOsqi-7tiNdBcGFrAQHGBCsTKZoBYXkClZE0DM9qhQ,32495
5
+ falyx/action_factory.py,sha256=RKKb9C49xYNnMBgNvaDYTspVF3jmpBtNibrxlzLGiQQ,4228
6
+ falyx/bottom_bar.py,sha256=GdyM-IY-E08c2GSaeAGVv1h1suOQuohFTRwbqtawbW0,7390
7
+ falyx/command.py,sha256=PCnGDbx8E-168FcuUvz87YqR94FvYCQX8dj6tVXnMtw,12231
8
+ falyx/config.py,sha256=nbAEea1-3zNhycrQ9aKuMqqa_EaQGBK0HcCAGsj_rZ0,7204
9
+ falyx/config_schema.py,sha256=j5GQuHVlaU-VLxLF9t8idZRjqOP9MIKp1hyd9NhpAGU,3124
10
+ falyx/context.py,sha256=FNF-IS7RMDxel2l3kskEqQImZ0mLO6zvGw_xC9cIzgI,10338
11
+ falyx/debug.py,sha256=oWWTLOF8elrx_RGZ1G4pbzfFr46FjB0woFXpVU2wmjU,1567
12
+ falyx/exceptions.py,sha256=Qxp6UScZWEyno-6Lgksrv3s9iwjbr2U-d6hun-_xpc0,798
13
+ falyx/execution_registry.py,sha256=io2hX9VkWJBRch-G7thla1eH_PgyVjjWf9qU5foOOEA,4719
14
+ falyx/falyx.py,sha256=KuIAaZj4RgiFdiAzOMswZ8n6lUKN00L5k4zWoJA1PBk,40545
15
+ falyx/hook_manager.py,sha256=GuGxVVz9FXrU39Tk220QcsLsMXeut7ZDkGW3hU9GcwQ,2952
16
+ falyx/hooks.py,sha256=KOmUGP6xWU-eTW8QOl-qEflNRxZRf_OHA0N7gph13UM,2947
17
+ falyx/http_action.py,sha256=sGADtRhSRuNu4UiEo1oeTHeC2rgAlALZm08-X4Pne34,5806
18
+ falyx/init.py,sha256=abcSlPmxVeByLIHdUkNjqtO_tEkO3ApC6f9WbxsSEWg,3393
19
+ falyx/io_action.py,sha256=5TIWeRUIffvkbdMbureLMiNk6mcy-tCaMMBRCeFFfgM,9718
20
+ falyx/logger.py,sha256=1Mfb_vJFJ1tQwziuyU2p-cSMi2Js8N2byniFEnI6vOQ,132
21
+ falyx/menu_action.py,sha256=jLYUR6-6F5NIDb9kP0Ysovmy3mtfO8xTXRRZMRaTtY0,8183
22
+ falyx/options_manager.py,sha256=dFAnQw543tQ6Xupvh1PwBrhiSWlSACHw8K-sHP_lUh4,2842
23
+ falyx/parsers.py,sha256=hxrBouQEqdgk6aWzNa7UwTg7u55vJffSEUUTiiQoI0U,5602
24
+ falyx/prompt_utils.py,sha256=6qt65HESo79-rZhIWpgndrYG6yJwk8tMSJCKXar0dP0,1549
25
+ falyx/protocols.py,sha256=Sk2a1rz5Tk7iDUVTeitItNX-Kg3kwXOSwIjojEOE1mI,299
26
+ falyx/retry.py,sha256=UUzY6FlKobr84Afw7yJO9rj3AIQepDk2fcWs6_1gi6Q,3788
27
+ falyx/retry_utils.py,sha256=1xPSr-1ZJsUXnXFyGNZZJ9h9eE4ExHjJMkyjHIm5cd8,687
28
+ falyx/select_file_action.py,sha256=698t0Mc5_6dPXjxuKBC_O7u35o08nLqkgpQH82dZafc,8678
29
+ falyx/selection.py,sha256=r__wrXaLz4oJobeqniKvHrEhe9vYVsZo1SoB3Cn6qRM,10738
30
+ falyx/selection_action.py,sha256=PdY-3ewMhgC8F3DKS6TCWcAoOD3va9Hp8bPkdZSMWBE,8811
31
+ falyx/signal_action.py,sha256=DSwVkL81PLWAHRHZbpiYlPH1ew97KL6TPs3XlU--RJY,916
32
+ falyx/signals.py,sha256=4PTuVRB_P_aWfnU8pANqhMxGTLq7TJDEyk9jCp0Bx2c,713
33
+ falyx/tagged_table.py,sha256=4SV-SdXFrAhy1JNToeBCvyxT-iWVf6cWY7XETTys4n8,1067
34
+ falyx/themes/colors.py,sha256=4aaeAHJetmeNInI0Zytg4E3YqKfPFelpf04vtjSvsS8,19776
35
+ falyx/utils.py,sha256=uss-FV8p164pmhoqYtQt8gNp5z8fGbuMAk4dRJ6RopI,6717
36
+ falyx/validators.py,sha256=t5iyzVpY8tdC4rfhr4isEfWpD5gNTzjeX_Hbi_Uq6sA,1328
37
+ falyx/version.py,sha256=Jq7e1LcKcQSNVg4EOJ-acPyPgs8Os5cYEZWXrQsI7Pg,23
38
+ falyx-0.1.24.dist-info/LICENSE,sha256=B0yqgaHuSdhN7T3OBmgQSiDTy8HqT5Oe_dLypRe4Ra4,1073
39
+ falyx-0.1.24.dist-info/METADATA,sha256=b7Ca1bcIlHrVsb3YLlSUQCgzoh0Jvd7qfUeD6ms5mWo,5484
40
+ falyx-0.1.24.dist-info/WHEEL,sha256=fGIA9gx4Qxk2KDKeNJCbOEwSrmLtjWCwzBz351GyrPQ,88
41
+ falyx-0.1.24.dist-info/entry_points.txt,sha256=j8owOSl2j1Ss8DtGMnKfgehKaolqnIPhVFHaUBLUnMs,45
42
+ falyx-0.1.24.dist-info/RECORD,,
@@ -1,40 +0,0 @@
1
- falyx/.pytyped,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
2
- falyx/__init__.py,sha256=dYRamQJlT1Zoy5Uu1uG4NCV05Xk98nN1LAQrSR1CT2A,643
3
- falyx/__main__.py,sha256=559pd3P1iScvC-V__gfXUbEQTxeV7PXlRcQI9kpMQcg,2286
4
- falyx/action.py,sha256=J-SG5zltYbqtdvTwBBUeEj4jp44DOKBR6G5rvmdkkTs,32147
5
- falyx/action_factory.py,sha256=SMucCBuigKk3rlKXCEN69Sew4dVaBUxQqxyUUAHMZeo,3629
6
- falyx/bottom_bar.py,sha256=NTen52Nfz32eWSBmJtEUuJO33u5sGQj-33IeudPVsqQ,7403
7
- falyx/command.py,sha256=8J3xeHw3fYiqf05EUbXd--aEIJso5bzxb5JECGuISQk,12199
8
- falyx/config.py,sha256=MnZeyti2TpeuOKrvXVaslIxYPHFyE4liREJsmUKlySg,5455
9
- falyx/context.py,sha256=Dm7HV-eigU-aTv5ERah6Ow9fIRdrOsB1G6ETPIu42Gw,10070
10
- falyx/debug.py,sha256=-jbTti29UC5zP9qQlWs3TbkOQR2f3zKSuNluh-r56wY,1551
11
- falyx/exceptions.py,sha256=YVbhPp2BNvZoO_xqeGSRKHVQ2rdLOLf1HCjH4JTj9w8,776
12
- falyx/execution_registry.py,sha256=IZvZr2hElzsYcMX3bAXg7sc7V2zi4RURn0OR7de2iCo,2864
13
- falyx/falyx.py,sha256=Yj7dYpEiqnswVRWSJyqS45wlRTUKvABIQR8Bh2axA9I,40453
14
- falyx/hook_manager.py,sha256=E9Vk4bdoUTeXPQ_BQEvY2Jt-jUAusc40LI8JDy3NLUw,2381
15
- falyx/hooks.py,sha256=9zXk62DsJLJrmwTdyeNy5s-rVRvl8feuYRrfMmz6cVQ,2802
16
- falyx/http_action.py,sha256=JfopEleXJ0goVHi0VCn983c22GrmJhobnPIP7sTRqzU,5796
17
- falyx/init.py,sha256=jP4ZNw7ycDMKw4n1HDifxWSa0NYHaGLq7_LiFt85NpA,1832
18
- falyx/io_action.py,sha256=mBRX8rqQ11gkcUnJluZ87XT4QBA1oFkof6PaCtuK5o8,8997
19
- falyx/menu_action.py,sha256=kagtnn3djDxUm_Cyynp0lj-sZ9D_FZn4IEBYnFYqB74,7986
20
- falyx/options_manager.py,sha256=yYpn-moYN-bRYgMLccmi_de4mUzhTT7cv_bR2FFWZ8c,2798
21
- falyx/parsers.py,sha256=r2FZTN26PqrnEQG4hVPorzzTPQZihsb4ca23fQY4Lgo,5574
22
- falyx/prompt_utils.py,sha256=JOg3p8Juv6ZdY1srfy_HlMNYfE-ajggDWLqNsjZq87I,560
23
- falyx/protocols.py,sha256=yNtQEugq9poN-SbOJf5LL_j6HBWdglbTNghpyopLpTs,216
24
- falyx/retry.py,sha256=GncBUiDDfDHUvLsWsWQw2Nq2XYL0TR0Fne3iXPzvQ48,3551
25
- falyx/retry_utils.py,sha256=SN5apcsg71IG2-KylysqdJd-PkPBLoCVwsgrSTF9wrQ,666
26
- falyx/select_file_action.py,sha256=5Pt9ThIfwqd8ZJLEVDapevV6SF_AQEQFkk-i9Y1to_Q,7315
27
- falyx/selection.py,sha256=aeJZPDwb5LR9e9iTjCYx4D5bh1mWyn3uBPA-M1AXdAw,10553
28
- falyx/selection_action.py,sha256=MAKZeDwfCEE3hOoL1hpiMVlFUEDYV6X0oNCVGEcT_ZU,8324
29
- falyx/signal_action.py,sha256=wfhW9miSUj9MUoc1WOyk4tU9CtYKAXusHxQdBPYLoyQ,829
30
- falyx/signals.py,sha256=tlUbz3x6z3rYlUggan_Ntoy4bU5RbOd8UfR4cNcV6kQ,694
31
- falyx/tagged_table.py,sha256=sn2kosRRpcpeMB8vKk47c9yjpffSz_9FXH_e6kw15mA,1019
32
- falyx/themes/colors.py,sha256=4aaeAHJetmeNInI0Zytg4E3YqKfPFelpf04vtjSvsS8,19776
33
- falyx/utils.py,sha256=b1GQ3ooz4Io3zPE7MsoDm7j42AioTG-ZcWH-N2TRpbI,7710
34
- falyx/validators.py,sha256=NMxqCk8Fr8HQGVDYpg8B_JRk5SKR41E_G9gj1YfQnxg,1316
35
- falyx/version.py,sha256=zmP2TRnzKPjZJ1eiBcT-cRInsji6FW-OVD3FafQFCc4,23
36
- falyx-0.1.22.dist-info/LICENSE,sha256=B0yqgaHuSdhN7T3OBmgQSiDTy8HqT5Oe_dLypRe4Ra4,1073
37
- falyx-0.1.22.dist-info/METADATA,sha256=jXADXacZ3y4WPCwGkMSg5aGsseu-G98twHd2YIK5Hzg,5484
38
- falyx-0.1.22.dist-info/WHEEL,sha256=fGIA9gx4Qxk2KDKeNJCbOEwSrmLtjWCwzBz351GyrPQ,88
39
- falyx-0.1.22.dist-info/entry_points.txt,sha256=j8owOSl2j1Ss8DtGMnKfgehKaolqnIPhVFHaUBLUnMs,45
40
- falyx-0.1.22.dist-info/RECORD,,
File without changes