auto-editor 28.0.2__py3-none-any.whl → 28.1.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.
- auto_editor/__init__.py +1 -1
- auto_editor/__main__.py +4 -3
- auto_editor/analyze.py +13 -13
- auto_editor/cmds/desc.py +2 -2
- auto_editor/cmds/levels.py +3 -3
- auto_editor/cmds/subdump.py +4 -4
- auto_editor/cmds/test.py +31 -27
- auto_editor/edit.py +35 -23
- auto_editor/exports/kdenlive.py +322 -0
- auto_editor/ffwrapper.py +8 -8
- auto_editor/help.py +1 -0
- auto_editor/lang/stdenv.py +0 -5
- auto_editor/make_layers.py +3 -3
- auto_editor/render/audio.py +42 -42
- auto_editor/render/subtitle.py +5 -5
- auto_editor/render/video.py +28 -33
- auto_editor/utils/container.py +2 -3
- auto_editor/utils/log.py +3 -1
- {auto_editor-28.0.2.dist-info → auto_editor-28.1.0.dist-info}/METADATA +2 -2
- {auto_editor-28.0.2.dist-info → auto_editor-28.1.0.dist-info}/RECORD +24 -23
- {auto_editor-28.0.2.dist-info → auto_editor-28.1.0.dist-info}/WHEEL +0 -0
- {auto_editor-28.0.2.dist-info → auto_editor-28.1.0.dist-info}/entry_points.txt +0 -0
- {auto_editor-28.0.2.dist-info → auto_editor-28.1.0.dist-info}/licenses/LICENSE +0 -0
- {auto_editor-28.0.2.dist-info → auto_editor-28.1.0.dist-info}/top_level.txt +0 -0
auto_editor/render/subtitle.py
CHANGED
@@ -6,7 +6,7 @@ import re
|
|
6
6
|
from dataclasses import dataclass
|
7
7
|
from typing import TYPE_CHECKING
|
8
8
|
|
9
|
-
import
|
9
|
+
import av
|
10
10
|
|
11
11
|
from auto_editor.utils.func import to_timecode
|
12
12
|
|
@@ -17,7 +17,7 @@ if TYPE_CHECKING:
|
|
17
17
|
from auto_editor.utils.chunks import Chunks
|
18
18
|
from auto_editor.utils.log import Log
|
19
19
|
|
20
|
-
Input =
|
20
|
+
Input = av.container.InputContainer
|
21
21
|
|
22
22
|
|
23
23
|
@dataclass(slots=True)
|
@@ -143,7 +143,7 @@ def make_srt(input_: Input, stream: int) -> str:
|
|
143
143
|
end = to_timecode(start_num + packet.duration * input_stream.time_base, "srt")
|
144
144
|
|
145
145
|
for sub in packet.decode():
|
146
|
-
assert isinstance(sub,
|
146
|
+
assert isinstance(sub, av.subtitles.subtitle.AssSubtitle)
|
147
147
|
|
148
148
|
output_bytes.write(f"{s}\n{start} --> {end}\n")
|
149
149
|
output_bytes.write(sub.dialogue.decode("utf-8", errors="ignore") + "\n\n")
|
@@ -155,7 +155,7 @@ def make_srt(input_: Input, stream: int) -> str:
|
|
155
155
|
|
156
156
|
def _ensure(input_: Input, format: str, stream: int) -> str:
|
157
157
|
output_bytes = io.BytesIO()
|
158
|
-
output =
|
158
|
+
output = av.open(output_bytes, "w", format=format)
|
159
159
|
|
160
160
|
in_stream = input_.streams.subtitles[stream]
|
161
161
|
out_stream = output.add_stream_from_template(in_stream)
|
@@ -175,7 +175,7 @@ def make_new_subtitles(tl: v3, log: Log) -> list[str]:
|
|
175
175
|
if tl.v1 is None:
|
176
176
|
return []
|
177
177
|
|
178
|
-
input_ =
|
178
|
+
input_ = av.open(tl.v1.source.path)
|
179
179
|
new_paths = []
|
180
180
|
|
181
181
|
for s, sub in enumerate(tl.v1.source.subtitles):
|
auto_editor/render/video.py
CHANGED
@@ -3,7 +3,7 @@ from __future__ import annotations
|
|
3
3
|
from dataclasses import dataclass
|
4
4
|
from typing import TYPE_CHECKING
|
5
5
|
|
6
|
-
import
|
6
|
+
import av
|
7
7
|
import numpy as np
|
8
8
|
|
9
9
|
from auto_editor.timeline import Clip, TlImage, TlRect
|
@@ -24,12 +24,12 @@ class VideoFrame:
|
|
24
24
|
src: FileInfo
|
25
25
|
|
26
26
|
|
27
|
-
def make_solid(width: int, height: int, pix_fmt: str, bg: str) ->
|
27
|
+
def make_solid(width: int, height: int, pix_fmt: str, bg: str) -> av.VideoFrame:
|
28
28
|
hex_color = bg.lstrip("#").upper()
|
29
29
|
rgb_color = tuple(int(hex_color[i : i + 2], 16) for i in (0, 2, 4))
|
30
30
|
|
31
31
|
rgb_array = np.full((height, width, 3), rgb_color, dtype=np.uint8)
|
32
|
-
rgb_frame =
|
32
|
+
rgb_frame = av.VideoFrame.from_ndarray(rgb_array, format="rgb24")
|
33
33
|
return rgb_frame.reformat(format=pix_fmt)
|
34
34
|
|
35
35
|
|
@@ -38,11 +38,11 @@ def make_image_cache(tl: v3) -> dict[tuple[FileInfo, int], np.ndarray]:
|
|
38
38
|
for clip in tl.v:
|
39
39
|
for obj in clip:
|
40
40
|
if isinstance(obj, TlImage) and (obj.src, obj.width) not in img_cache:
|
41
|
-
with
|
41
|
+
with av.open(obj.src.path) as cn:
|
42
42
|
my_stream = cn.streams.video[0]
|
43
43
|
for frame in cn.decode(my_stream):
|
44
44
|
if obj.width != 0:
|
45
|
-
graph =
|
45
|
+
graph = av.filter.Graph()
|
46
46
|
graph.link_nodes(
|
47
47
|
graph.add_buffer(template=my_stream),
|
48
48
|
graph.add("scale", f"{obj.width}:-1"),
|
@@ -57,12 +57,12 @@ def make_image_cache(tl: v3) -> dict[tuple[FileInfo, int], np.ndarray]:
|
|
57
57
|
|
58
58
|
|
59
59
|
def render_av(
|
60
|
-
output:
|
61
|
-
) -> Iterator[tuple[int,
|
62
|
-
from_ndarray =
|
60
|
+
output: av.container.OutputContainer, tl: v3, args: Args, log: Log
|
61
|
+
) -> Iterator[tuple[int, av.VideoFrame]]:
|
62
|
+
from_ndarray = av.VideoFrame.from_ndarray
|
63
63
|
|
64
|
-
cns: dict[FileInfo,
|
65
|
-
decoders: dict[FileInfo, Iterator[
|
64
|
+
cns: dict[FileInfo, av.container.InputContainer] = {}
|
65
|
+
decoders: dict[FileInfo, Iterator[av.VideoFrame]] = {}
|
66
66
|
seek_cost: dict[FileInfo, int] = {}
|
67
67
|
tous: dict[FileInfo, int] = {}
|
68
68
|
|
@@ -76,7 +76,7 @@ def render_av(
|
|
76
76
|
first_src = src
|
77
77
|
|
78
78
|
if src not in cns:
|
79
|
-
cns[src] =
|
79
|
+
cns[src] = av.open(f"{src.path}")
|
80
80
|
|
81
81
|
for src, cn in cns.items():
|
82
82
|
if len(cn.streams.video) > 0:
|
@@ -101,26 +101,21 @@ def render_av(
|
|
101
101
|
log.debug(f"Tous: {tous}")
|
102
102
|
log.debug(f"Clips: {tl.v}")
|
103
103
|
|
104
|
-
|
105
|
-
|
106
|
-
need_valid_fmt = True
|
107
|
-
if codec.video_formats is not None:
|
108
|
-
for video_format in codec.video_formats:
|
109
|
-
if pix_fmt == video_format.name:
|
110
|
-
need_valid_fmt = False
|
111
|
-
break
|
104
|
+
output_stream = output.add_stream(args.video_codec, rate=target_fps)
|
105
|
+
output_stream.options = {"x265-params": "log-level=error"}
|
112
106
|
|
107
|
+
need_valid_fmt = not (
|
108
|
+
output_stream.codec.video_formats
|
109
|
+
and any(pix_fmt == vfmt.name for vfmt in output_stream.codec.video_formats)
|
110
|
+
)
|
113
111
|
if need_valid_fmt:
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
del codec
|
122
|
-
output_stream = output.add_stream(args.video_codec, rate=target_fps)
|
123
|
-
output_stream.options = {"x265-params": "log-level=error"} # type: ignore
|
112
|
+
match output_stream.codec.canonical_name:
|
113
|
+
case "gif":
|
114
|
+
pix_fmt = "rgb8"
|
115
|
+
case "prores":
|
116
|
+
pix_fmt = "yuv422p10le"
|
117
|
+
case _:
|
118
|
+
pix_fmt = "yuv420p"
|
124
119
|
|
125
120
|
cc = output_stream.codec_context
|
126
121
|
if args.vprofile is not None:
|
@@ -133,7 +128,7 @@ def render_av(
|
|
133
128
|
cc.profile = args.vprofile.title()
|
134
129
|
|
135
130
|
yield output_stream # type: ignore
|
136
|
-
if not isinstance(output_stream,
|
131
|
+
if not isinstance(output_stream, av.VideoStream):
|
137
132
|
log.error(f"Not a known video codec: {args.video_codec}")
|
138
133
|
if src.videos and src.videos[0].lang is not None:
|
139
134
|
output_stream.metadata["language"] = src.videos[0].lang
|
@@ -144,7 +139,7 @@ def render_av(
|
|
144
139
|
else:
|
145
140
|
target_width = max(round(tl.res[0] * args.scale), 2)
|
146
141
|
target_height = max(round(tl.res[1] * args.scale), 2)
|
147
|
-
scale_graph =
|
142
|
+
scale_graph = av.filter.Graph()
|
148
143
|
scale_graph.link_nodes(
|
149
144
|
scale_graph.add(
|
150
145
|
"buffer", video_size="1x1", time_base="1/1", pix_fmt=pix_fmt
|
@@ -246,7 +241,7 @@ def render_av(
|
|
246
241
|
|
247
242
|
if (frame.width, frame.height) != tl.res:
|
248
243
|
width, height = tl.res
|
249
|
-
graph =
|
244
|
+
graph = av.filter.Graph()
|
250
245
|
graph.link_nodes(
|
251
246
|
graph.add_buffer(template=my_stream),
|
252
247
|
graph.add(
|
@@ -258,7 +253,7 @@ def render_av(
|
|
258
253
|
).vpush(frame)
|
259
254
|
frame = graph.vpull()
|
260
255
|
elif isinstance(obj, TlRect):
|
261
|
-
graph =
|
256
|
+
graph = av.filter.Graph()
|
262
257
|
x, y = obj.x, obj.y
|
263
258
|
graph.link_nodes(
|
264
259
|
graph.add_buffer(template=my_stream),
|
auto_editor/utils/container.py
CHANGED
@@ -3,8 +3,7 @@ from __future__ import annotations
|
|
3
3
|
from dataclasses import dataclass
|
4
4
|
from typing import TypedDict
|
5
5
|
|
6
|
-
import
|
7
|
-
from bv.codec import Codec
|
6
|
+
from av import Codec, open
|
8
7
|
|
9
8
|
from auto_editor.utils.log import Log
|
10
9
|
|
@@ -64,7 +63,7 @@ def codec_type(x: str) -> str:
|
|
64
63
|
|
65
64
|
def container_constructor(ext: str, log: Log) -> Container:
|
66
65
|
try:
|
67
|
-
container =
|
66
|
+
container = open(f".{ext}", "w")
|
68
67
|
except ValueError:
|
69
68
|
log.error(f"Could not find a suitable format for extension: {ext}")
|
70
69
|
|
auto_editor/utils/log.py
CHANGED
@@ -100,8 +100,10 @@ class Log:
|
|
100
100
|
sys.stderr.write(f"\033[1m\033[33m{message}\033[0m\n")
|
101
101
|
|
102
102
|
def error(self, message: str | Exception) -> NoReturn:
|
103
|
-
if self.is_debug
|
103
|
+
if self.is_debug:
|
104
104
|
self.cleanup()
|
105
|
+
if isinstance(message, str):
|
106
|
+
raise Exception(message)
|
105
107
|
raise message
|
106
108
|
|
107
109
|
self.conwrite("")
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.4
|
2
2
|
Name: auto-editor
|
3
|
-
Version: 28.0
|
3
|
+
Version: 28.1.0
|
4
4
|
Summary: Auto-Editor: Effort free video editing!
|
5
5
|
Author-email: WyattBlue <wyattblue@auto-editor.com>
|
6
6
|
License-Expression: Unlicense
|
@@ -12,7 +12,7 @@ Requires-Python: <3.14,>=3.10
|
|
12
12
|
Description-Content-Type: text/markdown
|
13
13
|
License-File: LICENSE
|
14
14
|
Requires-Dist: numpy<3.0,>=2
|
15
|
-
Requires-Dist:
|
15
|
+
Requires-Dist: av<16,>=15.0
|
16
16
|
Dynamic: license-file
|
17
17
|
|
18
18
|
<p align="center"><img src="https://auto-editor.com/img/auto-editor-banner.webp" title="Auto-Editor" width="700"></p>
|
@@ -1,27 +1,28 @@
|
|
1
|
-
auto_editor/__init__.py,sha256=
|
2
|
-
auto_editor/__main__.py,sha256=
|
3
|
-
auto_editor/analyze.py,sha256=
|
4
|
-
auto_editor/edit.py,sha256=
|
5
|
-
auto_editor/ffwrapper.py,sha256=
|
6
|
-
auto_editor/help.py,sha256=
|
1
|
+
auto_editor/__init__.py,sha256=22AwAEXAu8nCjcGi5JKpN5CwGqL0avyRi9p7xsPeXQk,23
|
2
|
+
auto_editor/__main__.py,sha256=46l-4asehWV-GJIDDULm2Sh9RKD6KjVBariy6ijgFSI,15552
|
3
|
+
auto_editor/analyze.py,sha256=b3x7efPza_PJ5E6zzSsgqFGYIRRulcpL1AEcrGVcFAg,12300
|
4
|
+
auto_editor/edit.py,sha256=pU5uhyKJSsOoSVeZDWBUjWi2_UPEBXXEpHUsCD8CmwA,19690
|
5
|
+
auto_editor/ffwrapper.py,sha256=YNGvHnkX0PTHsBx19kc-O3ZAiZX8WoqqZvIfjJ3tovQ,5474
|
6
|
+
auto_editor/help.py,sha256=YAw0b_-b6_RXXuDSl6OHevCMrhDocxWbcvoIlj5Qq-E,7959
|
7
7
|
auto_editor/json.py,sha256=g6ZsrSOXtjQj-8Otea3TIY2G-HZ6g-IXUblwukgTO1g,9332
|
8
|
-
auto_editor/make_layers.py,sha256=
|
8
|
+
auto_editor/make_layers.py,sha256=JAel8N1wr3NSmd0LRhEQsMDHQILqcMXjGDZ_qTrs5No,10076
|
9
9
|
auto_editor/preview.py,sha256=pBCw21wTORG0-Zs4Zf2anCecTNlnfiCq50tINeOcFmg,2815
|
10
10
|
auto_editor/timeline.py,sha256=84k-sSK3c2kTZ28atPoIaWgSecZvO-fOGfsXFlmifP4,8165
|
11
11
|
auto_editor/vanparse.py,sha256=Ug5A2QaRqGiw4l55Z_h9T2QU1x0WqRibR7yY5rQ0WTk,10002
|
12
12
|
auto_editor/cmds/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
13
13
|
auto_editor/cmds/cache.py,sha256=rK06dX3Z1pDAK0t5rqR7S2cMEpnT_Tv17t3Q5qPQKLI,1959
|
14
|
-
auto_editor/cmds/desc.py,sha256=
|
14
|
+
auto_editor/cmds/desc.py,sha256=VKs6ibRMbC4I4ro5Qh2B-3xsfnYSwunkyEvgHidBTqk,805
|
15
15
|
auto_editor/cmds/info.py,sha256=NwzZu6l6IIdK0ajZdn8WX_iiJwlsMrGIZ2vffDRu3gc,6535
|
16
|
-
auto_editor/cmds/levels.py,sha256=
|
16
|
+
auto_editor/cmds/levels.py,sha256=sHaaDqCCU8fwV311kL_otVCBanrD37m8KvsIs5BQ1HY,5853
|
17
17
|
auto_editor/cmds/palet.py,sha256=t2O_xM82PXUjnSgcHxyt9OG24gwQS4ksR2sKiQ1SvUA,743
|
18
18
|
auto_editor/cmds/repl.py,sha256=HSUTDaVykPb5Bd-v_jz_8R7HvFmKOcT_ZVmP-d0AbUY,3247
|
19
|
-
auto_editor/cmds/subdump.py,sha256=
|
20
|
-
auto_editor/cmds/test.py,sha256=
|
19
|
+
auto_editor/cmds/subdump.py,sha256=QPMX-Tb5ZIU857-u6UXSMf2pkoJON-OQ1zuZjhOFQgk,2393
|
20
|
+
auto_editor/cmds/test.py,sha256=sFAbMKC_kTEIvFCjK7sm9cb2HL-ZyE0dNGCJpz-le9M,29946
|
21
21
|
auto_editor/exports/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
22
22
|
auto_editor/exports/fcp11.py,sha256=uOonQPBoSQSfUpdi58vqDgpZdmN6Jevm2YNPo9m9nI0,6195
|
23
23
|
auto_editor/exports/fcp7.py,sha256=shZtn5i66hqGVrpR1PP1hiwKiZirr1cRUxATzbW-BOo,12069
|
24
24
|
auto_editor/exports/json.py,sha256=Q176-MtctEyPVenxbjuhMx_j8oVx-_G4Zwa-PJ3f7oQ,1579
|
25
|
+
auto_editor/exports/kdenlive.py,sha256=ZgMivXb2pBEF9zvU0Mnfm_a7CGupcb02jCt9EwDjwoQ,11798
|
25
26
|
auto_editor/exports/shotcut.py,sha256=miIOvzM73tUJcHFCe7fUu66YZxEvlDSkV1PHxv8ED8k,4699
|
26
27
|
auto_editor/imports/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
27
28
|
auto_editor/imports/fcp7.py,sha256=Vep1syViRZOrtZBlF6Ek_eRy0rLINpTso5nrh3uY3zk,8563
|
@@ -30,27 +31,27 @@ auto_editor/lang/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,
|
|
30
31
|
auto_editor/lang/libintrospection.py,sha256=6H1rGp0wqaCud5IPaoEmzULGnYt6ec7_0h32ATcw2oY,261
|
31
32
|
auto_editor/lang/libmath.py,sha256=z33A161Oe6vYYK7R6pgYjdZZe63dQkN38Qf36TL3prg,847
|
32
33
|
auto_editor/lang/palet.py,sha256=bsuEWNEefTb0-69Dc4lq4aotqu7aarH1okETK8ab-Gw,22794
|
33
|
-
auto_editor/lang/stdenv.py,sha256=
|
34
|
+
auto_editor/lang/stdenv.py,sha256=Ier6zmn8eFd6cpMdgHnnShjmxXXPWH1ItGyqZQvSkjc,43475
|
34
35
|
auto_editor/lib/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
35
36
|
auto_editor/lib/contracts.py,sha256=bADXnFXyq_-Tku59saxwDOlvexfS3wMAMdrKNL-Ql2w,7494
|
36
37
|
auto_editor/lib/data_structs.py,sha256=2SxsOXKiY0H95wRIFOrQBjv1ykJUQar0Vr5dK9zZOiQ,6971
|
37
38
|
auto_editor/lib/err.py,sha256=UlszQJdzMZwkbT8x3sY4GkCV_5x9yrd6uVVUzvA8iiI,35
|
38
39
|
auto_editor/render/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
39
|
-
auto_editor/render/audio.py,sha256=
|
40
|
-
auto_editor/render/subtitle.py,sha256=
|
41
|
-
auto_editor/render/video.py,sha256=
|
40
|
+
auto_editor/render/audio.py,sha256=O4aUBfyLg4-6QmyXoOjwnKmw3n5ZMHvFJKGzu07BpgM,17629
|
41
|
+
auto_editor/render/subtitle.py,sha256=6zPRbW2ksoBMDMm449vslLqs8v7htDEe5MRFEjXCGog,6129
|
42
|
+
auto_editor/render/video.py,sha256=hrj2b6xJ7cu7JeALF_XaOOxGtJfYYvXAEIgylEXrh9k,11964
|
42
43
|
auto_editor/utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
43
44
|
auto_editor/utils/bar.py,sha256=Ky9JRf37JTgLyvNuIXDfucaUE8H1vBbCqKLjttmsmmo,4156
|
44
45
|
auto_editor/utils/chunks.py,sha256=J-eGKtEz68gFtRrj1kOSgH4Tj_Yz6prNQ7Xr-d9NQJw,52
|
45
46
|
auto_editor/utils/cmdkw.py,sha256=aUGBvBel2Ko1o6Rwmr4rEL-BMc5hEnzYLbyZ1GeJdcY,5729
|
46
|
-
auto_editor/utils/container.py,sha256=
|
47
|
+
auto_editor/utils/container.py,sha256=tdvTsY5kcz46DAQ7jvKoXk_UPzhsz430kSKEHL7RUTQ,2615
|
47
48
|
auto_editor/utils/func.py,sha256=ODyjXnzSDatEu08w398K8_xBKYdXMY3IPHiJpGRZDyQ,3250
|
48
|
-
auto_editor/utils/log.py,sha256=
|
49
|
+
auto_editor/utils/log.py,sha256=hTBpBpadu6uD161Uhi0X5Ks7aA1azbtjXVNmN_sz1ko,3748
|
49
50
|
auto_editor/utils/types.py,sha256=j2hd4zMQ9EftDy41Ji2_PFru_7HEZObd9yKA0BJxFaY,7616
|
50
|
-
auto_editor-28.0.
|
51
|
+
auto_editor-28.1.0.dist-info/licenses/LICENSE,sha256=yiq99pWITHfqS0pbZMp7cy2dnbreTuvBwudsU-njvIM,1210
|
51
52
|
docs/build.py,sha256=g1uc1H9T_naGaermUiVMMwUpbT0IWElRhjgT0fvCh8w,1914
|
52
|
-
auto_editor-28.0.
|
53
|
-
auto_editor-28.0.
|
54
|
-
auto_editor-28.0.
|
55
|
-
auto_editor-28.0.
|
56
|
-
auto_editor-28.0.
|
53
|
+
auto_editor-28.1.0.dist-info/METADATA,sha256=KEs0ikYYnmLrSLLhJXU4tgU9_LZGcCqWl82DjgGfmJI,6165
|
54
|
+
auto_editor-28.1.0.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
55
|
+
auto_editor-28.1.0.dist-info/entry_points.txt,sha256=UAsTc7qJQbnAzHd7KWg-ALo_X9Hj2yDs3M9I2DV3eyI,212
|
56
|
+
auto_editor-28.1.0.dist-info/top_level.txt,sha256=jBV5zlbWRbKOa-xaWPvTD45QL7lGExx2BDzv-Ji4dTw,17
|
57
|
+
auto_editor-28.1.0.dist-info/RECORD,,
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|