anshitsu 0.0.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.
anshitsu/__init__.py ADDED
File without changes
@@ -0,0 +1 @@
1
+ version: str = "v1.5.0"
anshitsu/cli.py ADDED
@@ -0,0 +1,14 @@
1
+ import fire
2
+
3
+ from anshitsu.process import process
4
+
5
+
6
+ def main():
7
+ """
8
+ main [summary]
9
+ """
10
+ fire.Fire(process)
11
+
12
+
13
+ if __name__ == "__main__":
14
+ main()
anshitsu/process.py ADDED
@@ -0,0 +1,139 @@
1
+ import datetime
2
+ import glob
3
+ import os
4
+ import os.path
5
+ import re
6
+ from typing import Optional
7
+
8
+ import fire
9
+ import fire.core
10
+ from PIL import Image, UnidentifiedImageError
11
+
12
+ from anshitsu.retouch import Retouch
13
+ from anshitsu.__version__ import version as __version__
14
+
15
+
16
+ def process(
17
+ path: Optional[str] = None,
18
+ colorautoadjust: bool = False,
19
+ colorstretch: bool = False,
20
+ grayscale: bool = False,
21
+ invert: bool = False,
22
+ tosaka: Optional[float] = None,
23
+ outputrgb: bool = False,
24
+ noise: Optional[float] = None,
25
+ overwrite: bool = False,
26
+ version: bool = False,
27
+ ) -> str:
28
+ """
29
+ Process Runnner for Command Line Interface
30
+
31
+ This utility converts the colors of images such as photos.
32
+
33
+ If you specify a directory path, it will convert
34
+ the image files in the specified directory.
35
+ If you specify a file path, it will convert the specified file.
36
+ If you specify an option, the specified conversion will be performed.
37
+
38
+ Tosaka mode is a mode that expresses the preference of
39
+ Tosaka-senpai, a character in "Kyūkyoku Chōjin R",
40
+ for "photos taken with Tri-X that look like they were
41
+ burned onto No. 4 or No. 5 photographic paper".
42
+ Only use floating-point numbers when using this mode;
43
+ numbers around 2.4 will make it look right.
44
+
45
+ Args:
46
+ path (Optional[str], optional): Directory or File Path. Defaults to None.
47
+ overwrite (bool, optional): Overwrite original files. Defaults to False.
48
+ colorautoadjust (bool, optional): Use colorautoadjust algorithm. Defaults to False.
49
+ colorstretch (bool, optional): Use colorstretch algorithm. Defaults to False.
50
+ grayscale (bool, optional): Convert to grayscale. Defaults to False.
51
+ invert (bool, optional): Invert color. Defaults to False.
52
+ tosaka (Optional[float], optional): Use Tosaka mode. Defaults to None.
53
+ outputrgb (bool, optional): Outputs a monochrome image in RGB. Defaults to False.
54
+ noise (Optional[float], optional): Add Gaussian noise. Defaults to None.
55
+ version (bool, optional): Show version. Defaults to False.
56
+
57
+ Raises:
58
+ fire.core.FireError: Error that occurs when the specified string is not a path.
59
+
60
+ Returns:
61
+ str: Message.
62
+ """
63
+ if version:
64
+ return "Anshitsu version {}".format(__version__)
65
+ if path is None:
66
+ raise fire.core.FireError("No path specified!")
67
+ types = ("*.jpg", "*.JPG", "*.jpeg", "*.JPEG", "*.png", "*.PNG")
68
+ files_glob = []
69
+ return_path = ""
70
+ now_s = datetime.datetime.now()
71
+ output_dir = "anshitsu_out"
72
+ original_dir = "anshitsu_orig"
73
+ if os.path.isdir(path):
74
+ for type in types:
75
+ files_glob.extend(glob.glob(os.path.join(path, '**', type), recursive=True))
76
+ files_glob = [file for file in files_glob if not file.__contains__(output_dir)]
77
+ return_path = path
78
+
79
+ if len(files_glob) == 0:
80
+ raise fire.core.FireError(
81
+ "There are no JPEG or PNG files in this directory."
82
+ )
83
+ elif os.path.isfile(path):
84
+ files_glob.extend(glob.glob(path))
85
+ return_path = os.path.abspath(os.path.join(path, os.pardir))
86
+ else:
87
+ raise fire.core.FireError("A non-path string was passed.")
88
+ if overwrite is True:
89
+ os.makedirs(os.path.join(return_path, original_dir))
90
+ for i, file in enumerate(files_glob):
91
+ try:
92
+ image = Image.open(file)
93
+ except UnidentifiedImageError as e:
94
+ raise fire.core.FireError(e)
95
+ exif = image.getexif()
96
+ original_filename: str = os.path.split(file)[1]
97
+ extension = original_filename.split(".")[-1]
98
+ timestamp = now_s.strftime("%Y-%m-%d_%H-%M-%S")
99
+ if overwrite is True:
100
+ backup_filename = original_filename
101
+ image.save(os.path.join(
102
+ return_path,
103
+ original_dir,
104
+ backup_filename
105
+ ))
106
+ filename = os.path.join(return_path, re.sub(r"\.[^.]+$", "", original_filename) + ".png")
107
+ remove_file_list = [".jpg", ".JPG", ".jpeg", ".JPEG", ".PNG"]
108
+ for remove_file in remove_file_list:
109
+ remove_file_name = re.sub(r"\.[^.]+$", "", original_filename) + remove_file
110
+ remove_file_path = os.path.join(return_path, remove_file_name)
111
+ if os.path.isfile(remove_file_path):
112
+ os.remove(remove_file_path)
113
+ else:
114
+ filename = os.path.join(
115
+ return_path,
116
+ output_dir,
117
+ re.sub(r"\.[^.]+$", "_", original_filename)
118
+ + "_{0}_converted_at_{1}.png".format(extension, timestamp))
119
+ retouch = Retouch(
120
+ image=image,
121
+ colorautoadjust=colorautoadjust,
122
+ colorstretch=colorstretch,
123
+ grayscale=grayscale,
124
+ invert=invert,
125
+ tosaka=tosaka,
126
+ outputrgb=outputrgb,
127
+ noise=noise,
128
+ )
129
+ saved_image = retouch.process()
130
+ os.makedirs(os.path.join(return_path, output_dir), exist_ok=True)
131
+ saved_image.save(
132
+ filename,
133
+ quality=100, # Specify 100 as the highest image quality
134
+ subsampling=0,
135
+ exif=exif,
136
+ )
137
+ print("{0}/{1} done!".format((i + 1), str(len(files_glob))))
138
+
139
+ return "The process was completed successfully."
anshitsu/retouch.py ADDED
@@ -0,0 +1,236 @@
1
+ from collections import namedtuple
2
+ from typing import Optional, Tuple
3
+
4
+ import colorcorrect.algorithm as cca
5
+ import numpy as np
6
+ from colorcorrect.util import from_pil, to_pil
7
+ from PIL import Image, ImageChops, ImageEnhance, ImageOps
8
+
9
+
10
+ class Retouch:
11
+ """
12
+ Perform retouching.
13
+
14
+ Passing an image and options to the constructor will convert the specified image.
15
+ """
16
+
17
+ RGB_RED_VALUE: int = 255
18
+ RGB_GREEN_VALUE: int = 255
19
+ RGB_BLUE_VALUE: int = 255
20
+ RGB_WHITE_COLOR: Tuple[int, int, int] = (
21
+ RGB_RED_VALUE,
22
+ RGB_GREEN_VALUE,
23
+ RGB_BLUE_VALUE,
24
+ )
25
+
26
+ def __init__(
27
+ self,
28
+ image: Image,
29
+ colorautoadjust: bool = False,
30
+ colorstretch: bool = False,
31
+ grayscale: bool = False,
32
+ invert: bool = False,
33
+ tosaka: Optional[float] = None,
34
+ outputrgb: bool = False,
35
+ noise: Optional[float] = None,
36
+ ) -> None:
37
+ """
38
+ __init__ constructor.
39
+
40
+ Args:
41
+ image (Image): Image file.
42
+ colorautoadjust (bool, optional): Use colorautoadjust algorithm. Defaults to False.
43
+ colorstretch (bool, optional): Use colorstretch algorithm. Defaults to False.
44
+ grayscale (bool, optional): Convert to grayscale. Defaults to False.
45
+ invert (bool, optional): Invert color. Defaults to False.
46
+ tosaka (Optional[float], optional): Use Tosaka mode. Defaults to None.
47
+ outputrgb (bool, optional): Outputs a monochrome image in RGB. Defaults to False.
48
+ noise (Optional[float], optional): Add Gaussian noise. Defaults to None.
49
+ """
50
+ self.image = image
51
+ self.colorautoadjust = colorautoadjust
52
+ self.colorstretch = colorstretch
53
+ self.grayscale = grayscale
54
+ self.invert = invert
55
+ self.tosaka = tosaka
56
+ self.output_rgb = outputrgb
57
+ self.noise = noise
58
+
59
+ def process(self) -> Image:
60
+ self.image = self.__rgba_convert()
61
+
62
+ if self.invert:
63
+ self.image = self.__invert()
64
+
65
+ if self.colorautoadjust:
66
+ self.image = self.__colorautoadjust()
67
+
68
+ if self.colorstretch:
69
+ self.image = self.__colorstretch()
70
+
71
+ if self.grayscale:
72
+ self.image = self.__grayscale()
73
+
74
+ if self.noise is not None:
75
+ self.image = self.__noise()
76
+
77
+ if self.tosaka is not None:
78
+ self.image = self.__tosaka()
79
+
80
+ if self.output_rgb:
81
+ self.image = self.__output_rgb()
82
+
83
+ return self.image
84
+
85
+ def __colorautoadjust(self) -> Image:
86
+ """
87
+ __colorautoadjust
88
+
89
+ Use colorautoadjust algorithm.
90
+
91
+ Returns:
92
+ Image: processed image.
93
+ """
94
+ if self.image.mode == "L":
95
+ return self.image
96
+ return to_pil(cca.automatic_color_equalization(from_pil(self.image)))
97
+
98
+ def __colorstretch(self) -> Image:
99
+ """
100
+ __colorstretch
101
+
102
+ Use colorstretch algorithm.
103
+
104
+ Returns:
105
+ Image: processed image.
106
+ """
107
+ if self.image.mode == "L":
108
+ return self.image
109
+ return to_pil(cca.stretch(cca.grey_world(from_pil(self.image))))
110
+
111
+ def __noise(self) -> Image:
112
+ """
113
+ __noise
114
+
115
+ Add Gaussian noise.
116
+ To add noise, you need to specify floating-point numbers;
117
+ a value of about 10.0 will be just right.
118
+
119
+ Returns:
120
+ Image: processed image.
121
+ """
122
+ table = [x * 2 for x in range(256)] * len(self.image.getbands())
123
+ if self.image.mode == "RGB":
124
+ noise_image = Image.effect_noise(
125
+ (self.image.width, self.image.height), self.noise
126
+ ).convert("RGB")
127
+ self.image = ImageChops.multiply(self.image, noise_image).point(table)
128
+ if self.image.mode == "L":
129
+ noise_image = Image.effect_noise(
130
+ (self.image.width, self.image.height), self.noise
131
+ )
132
+ self.image = ImageChops.multiply(self.image, noise_image).point(table)
133
+ return self.image
134
+
135
+ def __grayscale(self) -> Image:
136
+ """
137
+ __grayscale
138
+
139
+ Converts to grayscale based on the luminance in the CIE XYZ color space.
140
+
141
+ Returns:
142
+ Image: processed image.
143
+ """
144
+ if self.image.mode == "L":
145
+ return self.image
146
+
147
+ rgb = np.array(self.image, dtype="float32")
148
+
149
+ GAMMA = 2.2
150
+ ColorMatrix = namedtuple("ColorMatrix", ("red", "green", "blue"))
151
+
152
+ # Coefficients for luminance in CIE XYZ color space
153
+ CIE_XYZ = ColorMatrix(0.2126, 0.7152, 0.0722)
154
+
155
+ # Inverse Gamma Correction
156
+ rgbL = pow(rgb / 255.0, GAMMA)
157
+
158
+ # Extract RGB values
159
+ r, g, b = rgbL[:, :, 0], rgbL[:, :, 1], rgbL[:, :, 2]
160
+
161
+ # Convert to grayscale
162
+ grayL = CIE_XYZ.red * r + CIE_XYZ.green * g + CIE_XYZ.blue * b
163
+
164
+ # gamma correction
165
+ gray = pow(grayL, 1.0 / GAMMA) * 255
166
+
167
+ self.image = Image.fromarray(gray.astype("uint8"))
168
+
169
+ return self.image
170
+
171
+ def __invert(self) -> Image:
172
+ """
173
+ __invert
174
+
175
+ Invert color.
176
+
177
+ Returns:
178
+ Image: processed image.
179
+ """
180
+ return ImageOps.invert(self.image)
181
+
182
+ def __tosaka(self) -> Image:
183
+ """
184
+ __tosaka
185
+
186
+ Use Tosaka mode.
187
+
188
+ Tosaka mode is a mode that expresses the preference of
189
+ Tosaka-senpai, a character in "Kyūkyoku Chōjin R",
190
+ for "photos taken with Tri-X that look like they were
191
+ burned onto No. 4 or No. 5 photographic paper".
192
+ Only use floating-point numbers when using this mode;
193
+ numbers around 2.4 will make it look right.
194
+
195
+ Returns:
196
+ Image: processed image.
197
+ """
198
+ if self.image.mode != "L":
199
+ self.image = self.__grayscale()
200
+ imageC = ImageEnhance.Contrast(self.image)
201
+ self.image = imageC.enhance(self.tosaka)
202
+ return self.image
203
+
204
+ def __rgba_convert(self) -> Image:
205
+ """
206
+ __rgba_convert
207
+
208
+ Converts image data that contains transparency to image data that does not contain transparency.
209
+
210
+ Returns:
211
+ Image: processed image.
212
+ """
213
+ if self.image.mode == "RGBA":
214
+ self.image.load()
215
+ background = Image.new("RGB", self.image.size, self.RGB_WHITE_COLOR)
216
+ background.paste(self.image, mask=self.image.split()[3])
217
+ self.image = background
218
+ if self.image.mode == "LA":
219
+ self.image.load()
220
+ background = Image.new("L", self.image.size, 255)
221
+ background.paste(self.image, mask=self.image.split()[1])
222
+ self.image = background
223
+ return self.image
224
+
225
+ def __output_rgb(self) -> Image:
226
+ """
227
+ __output_rgb
228
+
229
+ Outputs a monochrome image in RGB.
230
+
231
+ Returns:
232
+ Image: processed image.
233
+ """
234
+ if self.image.mode == "L":
235
+ self.image = self.image.convert("RGB")
236
+ return self.image
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2021 Iosif Takakura
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,183 @@
1
+ Metadata-Version: 2.1
2
+ Name: anshitsu
3
+ Version: 0.0.0
4
+ Summary: A tiny digital photographic utility.
5
+ Home-page: https://github.com/huideyeren
6
+ License: MIT
7
+ Author: Iosif Takakura
8
+ Author-email: iosif@huideyeren.info
9
+ Requires-Python: >=3.10,<3.13
10
+ Classifier: License :: OSI Approved :: MIT License
11
+ Classifier: Programming Language :: Python :: 3
12
+ Classifier: Programming Language :: Python :: 3.10
13
+ Classifier: Programming Language :: Python :: 3.11
14
+ Requires-Dist: Pillow (>=10.1.0,<11.0.0)
15
+ Requires-Dist: colorcorrect (>=0.9.1,<0.10.0)
16
+ Requires-Dist: fire (>=0.5.0,<0.6.0)
17
+ Requires-Dist: numpy (>=1.26.0,<2.0.0)
18
+ Project-URL: Documentation, https://github.com/huideyeren/anshitsu
19
+ Project-URL: Repository, https://github.com/huideyeren/anshitsu
20
+ Description-Content-Type: text/markdown
21
+
22
+ # Anshitsu
23
+
24
+ [![Testing](https://github.com/huideyeren/anshitsu/actions/workflows/testing.yml/badge.svg)](https://github.com/huideyeren/anshitsu/actions/workflows/testing.yml)
25
+
26
+ [![codecov](https://codecov.io/gh/huideyeren/anshitsu/branch/main/graph/badge.svg?token=ZYRX8NBTLQ)](https://codecov.io/gh/huideyeren/anshitsu)
27
+
28
+ A tiny digital photographic utility.
29
+
30
+ "Anshitsu" means a darkroom in Japanese.
31
+
32
+ ## Install
33
+
34
+ Run this command in an environment where Python 3.10 or higher is installed.
35
+
36
+ We have tested it on Windows, Mac, and Ubuntu on GitHub Actions, but we have not tested it on Macs with Apple Silicon, so please use it at your own risk on Macs with Apple Silicon.
37
+
38
+ ``` shell
39
+ pip install anshitsu
40
+ ```
41
+
42
+ ## Usage
43
+
44
+ It is as described in the following help.
45
+
46
+ ``` shell
47
+ INFO: Showing help with the command 'anshitsu -- --help'.
48
+
49
+ NAME
50
+ anshitsu - Process Runnner for Command Line Interface
51
+
52
+ SYNOPSIS
53
+ anshitsu PATH <flags>
54
+
55
+ DESCRIPTION
56
+ This utility converts the colors of images such as photos.
57
+
58
+ If you specify a directory path, it will convert
59
+ the image files in the specified directory.
60
+ If you specify a file path, it will convert the specified file.
61
+ If you specify an option, the specified conversion will be performed.
62
+
63
+ Tosaka mode is a mode that expresses the preference of
64
+ Tosaka-senpai, a character in "Kyūkyoku Chōjin R",
65
+ for "photos taken with Tri-X that look like they were
66
+ burned onto No. 4 or No. 5 photographic paper".
67
+ Only use floating-point numbers when using this mode;
68
+ numbers around 2.4 will make it look right.
69
+
70
+ POSITIONAL ARGUMENTS
71
+ PATH
72
+ Type: str
73
+ Directory or File Path
74
+
75
+ FLAGS
76
+ --colorautoadjust=COLORAUTOADJUST
77
+ Type: bool
78
+ Default: False
79
+ Use colorautoadjust algorithm. Defaults to False.
80
+ --colorstretch=COLORSTRETCH
81
+ Type: bool
82
+ Default: False
83
+ Use colorstretch algorithm. Defaults to False.
84
+ --grayscale=GRAYSCALE
85
+ Type: bool
86
+ Default: False
87
+ Convert to grayscale. Defaults to False.
88
+ --invert=INVERT
89
+ Type: bool
90
+ Default: False
91
+ Invert color. Defaults to False.
92
+ --tosaka=TOSAKA
93
+ Type: Optional[Optional]
94
+ Default: None
95
+ Use Tosaka mode. Defaults to None.
96
+ --outputrgb=OUTPUTRGB
97
+ Type: bool
98
+ Default: False
99
+ Outputs a monochrome image in RGB. Defaults to False.
100
+ --noise=NOISE
101
+ Type: Optional[Optional]
102
+ Default: None
103
+ Add Gaussian noise. Defaults to None.
104
+
105
+ NOTES
106
+ You can also use flags syntax for POSITIONAL ARGUMENTS
107
+ ```
108
+
109
+ If a directory is specified in the path, an `out` directory will be created in the specified directory, and the converted JPEG and PNG images will be stored in PNG format.
110
+
111
+ If you specify a JPEG or PNG image file as the path, an `out` directory will be created in the directory where the image is stored, and the converted image will be stored in PNG format.
112
+
113
+ **Note:** If you specify a file in any other format in the path, be aware there is no error handling. The program will terminate abnormally.
114
+
115
+ ## Algorithms
116
+
117
+ The following algorithms are available in this tool.
118
+
119
+ ### RGBA to RGB Convert
120
+
121
+ Converts an image that contains Alpha, such as RGBA, to image data that does not contain Alpha.
122
+ Transparent areas will be filled with white.
123
+
124
+ This algorithm is performed on any image file.
125
+
126
+ ### invert
127
+
128
+ Inverts the colors of an image using Pillow's built-in algorithm.
129
+
130
+ In the case of negative film, color conversion that takes into account the film base color is not performed, but we plan to follow up with a feature to be developed in the future.
131
+
132
+ ### colorautoajust
133
+
134
+ We will use the "automatic color equalization" algorithm described in the following paper to apply color correction.
135
+
136
+ This process is more time consuming than the algorithm used in "colorstretch", but it can reproduce more natural colors.
137
+
138
+ (References)
139
+
140
+ A. Rizzi, C. Gatta and D. Marini, "A new algorithm for unsupervised global and local color correction.", Pattern Recognition Letters, vol. 24, no. 11, 2003.
141
+
142
+ ### colorstretch
143
+
144
+ The "gray world" and "stretch" algorithms described in the following paper are combined to apply color correction.
145
+
146
+ This process is faster than the algorithm used in "colorautoajust".
147
+
148
+ (References)
149
+
150
+ D. Nikitenko, M. Wirth and K. Trudel, "Applicability Of White-Balancing Algorithms to Restoring Faded Colour Slides: An Empirical Evaluation.", Journal of Multimedia, vol. 3, no. 5, 2008.
151
+
152
+ ### grayscale
153
+
154
+ Convert a color image to grayscale using the algorithm described in the following article.
155
+
156
+ [Python でグレースケール(grayscale)化](https://qiita.com/yoya/items/dba7c40b31f832e9bc2a#pilpillow-%E3%81%A7%E3%82%B0%E3%83%AC%E3%83%BC%E3%82%B9%E3%82%B1%E3%83%BC%E3%83%AB%E5%8C%96-numpy-%E3%81%A7%E4%BD%8E%E8%BC%9D%E5%BA%A6%E5%AF%BE%E5%BF%9C)
157
+
158
+ Note: This article is written in Japanese.
159
+
160
+ ### Tosaka mode
161
+
162
+ Tosaka mode is a mode that expresses the preference of Tosaka-senpai, a character in "Kyūkyoku Chōjin R", for "photos taken with Tri-X that look like they were burned onto No. 4 or No. 5 photographic paper".
163
+
164
+ Only use floating-point numbers when using this mode; numbers around 2.4 will make it look right.
165
+
166
+ When this mode is specified, color images will also be converted to grayscale.
167
+
168
+ ### outputrgb
169
+
170
+ Outputs a monochrome image in RGB.
171
+
172
+ ### noise
173
+
174
+ Add Gaussian noise.
175
+
176
+ To add noise, you need to specify a floating-point number; a value of about 10.0 will be just right.
177
+
178
+ ## Special Thanks
179
+
180
+ We are using the following libraries.
181
+
182
+ [shunsukeaihara/colorcorrect](https://github.com/shunsukeaihara/colorcorrect)
183
+
@@ -0,0 +1,10 @@
1
+ anshitsu/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
2
+ anshitsu/__version__.py,sha256=jO-0XZe2LK4sxY9Jy21OX9LMsd02dSx3yjI9we0PSY4,24
3
+ anshitsu/cli.py,sha256=yY16URQm-ndXBW0QpcivkeLr7J3kNOJIXy4QKY9_PcM,162
4
+ anshitsu/process.py,sha256=QeMRoqz9LF40Rc9lr1P-hdti8oUec2cQrWdwRkA-nIk,5413
5
+ anshitsu/retouch.py,sha256=gbMYITD4RmBoIHClFtIcJF9kGpWLCE4EwducVVIU6GA,6982
6
+ anshitsu-0.0.0.dist-info/LICENSE,sha256=Hfj88p2Eh9As-ZvaGoE02XkqFlmKks71SnjV-dUpE1k,1071
7
+ anshitsu-0.0.0.dist-info/METADATA,sha256=AVheXk7yTzB5WyfSL2DxuRonLHRQbTdz6bEkxnvrXrg,6389
8
+ anshitsu-0.0.0.dist-info/WHEEL,sha256=d2fvjOD7sXsVzChCqf0Ty0JbHKBaLYwDbGQDwQTnJ50,88
9
+ anshitsu-0.0.0.dist-info/entry_points.txt,sha256=vMtbdj3zt7D9SEzY-icd22vCq9WGIm3wIYBbrB5RuSs,46
10
+ anshitsu-0.0.0.dist-info/RECORD,,
@@ -0,0 +1,4 @@
1
+ Wheel-Version: 1.0
2
+ Generator: poetry-core 1.7.0
3
+ Root-Is-Purelib: true
4
+ Tag: py3-none-any
@@ -0,0 +1,3 @@
1
+ [console_scripts]
2
+ anshitsu=anshitsu.cli:main
3
+