batch-renderer 1.0.0__tar.gz

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.
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 Jérémie Lumbroso
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,26 @@
1
+ # MANIFEST.in — controls what goes into the source distribution (sdist)
2
+ # The wheel is already clean via [tool.setuptools.packages.find] where = ["src"]
3
+
4
+ # Include core files
5
+ include README.md
6
+ include LICENSE
7
+ include pyproject.toml
8
+
9
+ # Exclude internal methodology and development artifacts
10
+ # These should never appear on PyPI
11
+ recursive-exclude docs *
12
+ exclude CLAUDE.md
13
+ recursive-exclude .claude *
14
+ recursive-exclude tests/fixtures *
15
+ recursive-exclude _prompts *
16
+ recursive-exclude _output *
17
+ recursive-exclude logs *
18
+ exclude temp
19
+ recursive-exclude temp *
20
+
21
+ # Exclude development config files
22
+ exclude Pipfile
23
+ exclude Pipfile.lock
24
+ exclude setup.py
25
+ exclude .env
26
+ exclude .env.*
@@ -0,0 +1,318 @@
1
+ Metadata-Version: 2.4
2
+ Name: batch-renderer
3
+ Version: 1.0.0
4
+ Summary: CLI tool for batch rendering AI image prompts from markdown files
5
+ Author: Jérémie Lumbroso
6
+ Author-email: Jérémie Lumbroso <lumbroso@seas.upenn.edu>
7
+ License: MIT
8
+ Project-URL: Homepage, https://github.com/jlumbroso/batch-renderer
9
+ Project-URL: Repository, https://github.com/jlumbroso/batch-renderer
10
+ Project-URL: Bug Tracker, https://github.com/jlumbroso/batch-renderer/issues
11
+ Keywords: ai,image-generation,batch,cli,poe,prompts,markdown
12
+ Classifier: Development Status :: 3 - Alpha
13
+ Classifier: Environment :: Console
14
+ Classifier: Intended Audience :: Developers
15
+ Classifier: Intended Audience :: End Users/Desktop
16
+ Classifier: License :: OSI Approved :: MIT License
17
+ Classifier: Operating System :: OS Independent
18
+ Classifier: Programming Language :: Python :: 3
19
+ Classifier: Programming Language :: Python :: 3.11
20
+ Classifier: Programming Language :: Python :: 3.12
21
+ Classifier: Topic :: Multimedia :: Graphics
22
+ Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
23
+ Classifier: Topic :: Utilities
24
+ Requires-Python: >=3.11
25
+ Description-Content-Type: text/markdown
26
+ License-File: LICENSE
27
+ Requires-Dist: openai>=1.0.0
28
+ Requires-Dist: rich>=13.0.0
29
+ Requires-Dist: python-dotenv>=1.0.0
30
+ Requires-Dist: click>=8.0.0
31
+ Requires-Dist: requests>=2.31.0
32
+ Requires-Dist: structlog>=24.0.0
33
+ Provides-Extra: dev
34
+ Requires-Dist: pytest>=8.0.0; extra == "dev"
35
+ Requires-Dist: pytest-cov>=4.0.0; extra == "dev"
36
+ Dynamic: author
37
+ Dynamic: license-file
38
+ Dynamic: requires-python
39
+
40
+ # Batch Renderer
41
+
42
+ A CLI tool for batch rendering AI image prompts from markdown files using the Poe API.
43
+
44
+ ## Features
45
+
46
+ - 📝 **Extract prompts from markdown** files using configurable patterns
47
+ - 🎨 **Batch render images** using multiple AI models (GPT-Image-1, Nano-Banana, etc.)
48
+ - 📦 **Nested output structure** organized by sections
49
+ - 🎯 **Per-prompt metadata** to override model, quality, aspect ratio, etc.
50
+ - 🔄 **Automatic retries** on errors
51
+ - 📊 **Rich CLI interface** with progress bars and colored output
52
+ - ✅ **Dry-run mode** to preview extraction before rendering
53
+ - ⚙️ **Flexible configuration** via CLI, environment variables, or inline metadata
54
+
55
+ ## Installation
56
+
57
+ ```bash
58
+ # Clone the repository
59
+ cd batch-renderer
60
+
61
+ # Install dependencies
62
+ pipenv install
63
+
64
+ # Install the package in editable mode
65
+ pipenv install -e .
66
+ ```
67
+
68
+ ## Quick Start
69
+
70
+ 1. **Set up your Poe API key**:
71
+ ```bash
72
+ echo "POE_API_KEY=your_api_key_here" >> .env
73
+ ```
74
+
75
+ 2. **Create a markdown file with prompts** (see [Format](#markdown-format) below)
76
+
77
+ 3. **Dry run to preview**:
78
+ ```bash
79
+ pipenv run batch-renderer docs/SAMPLE-CONCEPTS.md --dry-run
80
+ ```
81
+
82
+ 4. **Render images**:
83
+ ```bash
84
+ pipenv run batch-renderer docs/SAMPLE-CONCEPTS.md
85
+ ```
86
+
87
+ ## Markdown Format
88
+
89
+ ### Basic Format
90
+
91
+ ```markdown
92
+ ## 1. Section Title
93
+
94
+ ### Concept 1.1: Image Title
95
+ A detailed description of the image you want to generate...
96
+
97
+ ### Concept 1.2: Another Image
98
+ Another prompt description...
99
+ ```
100
+
101
+ ### With Metadata
102
+
103
+ Add metadata as bullet points after the heading to override settings:
104
+
105
+ ```markdown
106
+ ### Concept 1.1: Custom Image
107
+ - model: GPT-Image-1
108
+ - aspect: 16:9
109
+ - quality: high
110
+ - retries: 5
111
+
112
+ A detailed prompt for the image...
113
+ ```
114
+
115
+ ### Standard Metadata Keys
116
+
117
+ - `model` - Override the model for this prompt (e.g., `GPT-Image-1`, `Nano-Banana`)
118
+ - `format` - Override output format (e.g., `png`, `jpg`)
119
+ - `skip` - Set to `true` to skip this prompt
120
+ - `retries` - Number of retry attempts (default: 3)
121
+
122
+ ### Custom Metadata Keys
123
+
124
+ Any other keys are passed directly to the API via `extra_body`:
125
+
126
+ - `aspect` - Aspect ratio (`1:1`, `3:2`, `2:3`, `16:9`, `auto`)
127
+ - `quality` - Image quality (`low`, `medium`, `high`)
128
+ - `thinking_level` - For thinking models (`low`, `medium`, `high`)
129
+ - `thinking_budget` - Thinking budget (`extended`)
130
+ - `web_search` - Enable web search (`true` / `false`)
131
+
132
+ ## CLI Usage
133
+
134
+ ```bash
135
+ batch-renderer [OPTIONS] INPUT_FILE
136
+ ```
137
+
138
+ ### Options
139
+
140
+ | Option | Description | Default |
141
+ |--------|-------------|---------|
142
+ | `--model`, `-m` | Model to use | `Nano-Banana` (or `POE_DEFAULT_MODEL` env) |
143
+ | `--output`, `-o` | Output directory | `out` |
144
+ | `--pattern`, `-p` | Extraction pattern (`concept`, `numbered`, `simple`) | `concept` |
145
+ | `--format`, `-f` | Output image format | `png` |
146
+ | `--flatten` | Flatten output (no subdirectories) | `false` |
147
+ | `--dry-run` | Extract and display without rendering | `false` |
148
+ | `--no-confirm` | Skip confirmation prompt | `false` |
149
+ | `--cache-images` | Cache images in `logs/image_cache` | `false` |
150
+ | `--validation-mode` | Metadata validation (`strict`, `lenient`, `hybrid`) | `hybrid` |
151
+ | `--api-key` | Poe API key (or `POE_API_KEY` env) | - |
152
+
153
+ ### Examples
154
+
155
+ **Basic usage**:
156
+ ```bash
157
+ batch-renderer prompts.md
158
+ ```
159
+
160
+ **Use a specific model**:
161
+ ```bash
162
+ batch-renderer prompts.md --model GPT-Image-1
163
+ ```
164
+
165
+ **Flat output structure**:
166
+ ```bash
167
+ batch-renderer prompts.md --flatten
168
+ ```
169
+
170
+ **Dry run to preview**:
171
+ ```bash
172
+ batch-renderer prompts.md --dry-run
173
+ ```
174
+
175
+ **Batch render without confirmation**:
176
+ ```bash
177
+ batch-renderer prompts.md --no-confirm
178
+ ```
179
+
180
+ **Strict metadata validation**:
181
+ ```bash
182
+ batch-renderer prompts.md --validation-mode strict
183
+ ```
184
+
185
+ ## Output Structure
186
+
187
+ ### Nested (default)
188
+
189
+ ```
190
+ out/
191
+ 1-artificial-lovers/
192
+ concept-1-1-blade-runner-noir-romance.png
193
+ concept-1-2-holographic-love.png
194
+ 2-fantastic-eight/
195
+ concept-2-1-renaissance-group-portrait.png
196
+ ```
197
+
198
+ ### Flattened (with `--flatten`)
199
+
200
+ ```
201
+ out/
202
+ concept-1-1-blade-runner-noir-romance.png
203
+ concept-1-2-holographic-love.png
204
+ concept-2-1-renaissance-group-portrait.png
205
+ ```
206
+
207
+ ## Configuration Precedence
208
+
209
+ Settings are applied in this order (later overrides earlier):
210
+
211
+ 1. **Hard-coded defaults** (`Nano-Banana`, `png`, etc.)
212
+ 2. **Environment variables** (`POE_DEFAULT_MODEL`, `POE_API_KEY`)
213
+ 3. **Inline metadata** (in markdown file)
214
+ 4. **CLI arguments** (`--model`, `--format`, etc.)
215
+
216
+ ## Validation Modes
217
+
218
+ ### `hybrid` (default)
219
+ - **Standard keys** (model, format, skip, retries): Warns on malformed values
220
+ - **Custom keys**: Pass through without validation
221
+
222
+ ### `strict`
223
+ - **Standard keys**: Fails on malformed values
224
+ - **Custom keys**: Pass through without validation
225
+
226
+ ### `lenient`
227
+ - **All keys**: Warns only, never fails
228
+
229
+ ## Error Handling
230
+
231
+ - **Automatic retries**: Failed requests are retried 3 times by default (configurable per-prompt)
232
+ - **Text responses**: If model returns text instead of image, saves to `.txt` file with warning
233
+ - **Partial failures**: Continues rendering remaining prompts if one fails
234
+ - **Summary report**: Shows successful, text responses, and failed renders
235
+
236
+ ## Pattern Types
237
+
238
+ ### `concept` (default)
239
+ Extracts `### Concept X.Y: Title` style prompts with section headers.
240
+
241
+ ### `numbered`
242
+ Extracts `### X.Y Title` style prompts (no "Concept" keyword).
243
+
244
+ ### `simple`
245
+ Extracts all level-3 headings as prompts.
246
+
247
+ ## Environment Variables
248
+
249
+ Create a `.env` file in the project root:
250
+
251
+ ```env
252
+ # Required
253
+ POE_API_KEY=your_api_key_here
254
+
255
+ # Optional
256
+ POE_DEFAULT_MODEL=Nano-Banana
257
+ ```
258
+
259
+ ## Development
260
+
261
+ ### Project Structure
262
+
263
+ ```
264
+ batch-renderer/
265
+ ├── src/batch_renderer/
266
+ │ ├── __init__.py
267
+ │ ├── __main__.py
268
+ │ ├── cli.py # CLI interface
269
+ │ ├── config.py # Configuration management
270
+ │ ├── patterns.py # Prompt extraction patterns
271
+ │ └── renderer.py # Image rendering
272
+ ├── docs/
273
+ │ ├── adr/ # Architecture Decision Records
274
+ │ └── SAMPLE-CONCEPTS.md
275
+ ├── setup.py
276
+ ├── Pipfile
277
+ └── README.md
278
+ ```
279
+
280
+ ### Running Tests
281
+
282
+ ```bash
283
+ # Dry run with test file
284
+ pipenv run batch-renderer test_prompts.md --dry-run
285
+
286
+ # Dry run with full sample
287
+ pipenv run batch-renderer docs/SAMPLE-CONCEPTS.md --dry-run
288
+ ```
289
+
290
+ ## Architecture Decisions
291
+
292
+ See [docs/adr/](docs/adr/) for detailed design decisions:
293
+ - [ADR-0001: Core Architecture](docs/adr/0001-core-architecture.md)
294
+ - [ADR-0002: Prompt Metadata Format](docs/adr/0002-prompt-metadata-format.md)
295
+
296
+ ## Troubleshooting
297
+
298
+ ### "POE_API_KEY not found"
299
+ Make sure you've created a `.env` file with your API key, or pass it via `--api-key`.
300
+
301
+ ### "No prompts found in file"
302
+ Check that your markdown file uses the correct pattern format. Use `--dry-run` to debug extraction.
303
+
304
+ ### Model returns text instead of image
305
+ This can happen if:
306
+ - The model doesn't support image generation
307
+ - The model name is incorrect
308
+ - The prompt is ambiguous
309
+
310
+ The tool will save the text response to a `.txt` file for inspection.
311
+
312
+ ## License
313
+
314
+ MIT
315
+
316
+ ## Author
317
+
318
+ Jérémie Lumbroso with Claude Sonnet 4.5
@@ -0,0 +1,279 @@
1
+ # Batch Renderer
2
+
3
+ A CLI tool for batch rendering AI image prompts from markdown files using the Poe API.
4
+
5
+ ## Features
6
+
7
+ - 📝 **Extract prompts from markdown** files using configurable patterns
8
+ - 🎨 **Batch render images** using multiple AI models (GPT-Image-1, Nano-Banana, etc.)
9
+ - 📦 **Nested output structure** organized by sections
10
+ - 🎯 **Per-prompt metadata** to override model, quality, aspect ratio, etc.
11
+ - 🔄 **Automatic retries** on errors
12
+ - 📊 **Rich CLI interface** with progress bars and colored output
13
+ - ✅ **Dry-run mode** to preview extraction before rendering
14
+ - ⚙️ **Flexible configuration** via CLI, environment variables, or inline metadata
15
+
16
+ ## Installation
17
+
18
+ ```bash
19
+ # Clone the repository
20
+ cd batch-renderer
21
+
22
+ # Install dependencies
23
+ pipenv install
24
+
25
+ # Install the package in editable mode
26
+ pipenv install -e .
27
+ ```
28
+
29
+ ## Quick Start
30
+
31
+ 1. **Set up your Poe API key**:
32
+ ```bash
33
+ echo "POE_API_KEY=your_api_key_here" >> .env
34
+ ```
35
+
36
+ 2. **Create a markdown file with prompts** (see [Format](#markdown-format) below)
37
+
38
+ 3. **Dry run to preview**:
39
+ ```bash
40
+ pipenv run batch-renderer docs/SAMPLE-CONCEPTS.md --dry-run
41
+ ```
42
+
43
+ 4. **Render images**:
44
+ ```bash
45
+ pipenv run batch-renderer docs/SAMPLE-CONCEPTS.md
46
+ ```
47
+
48
+ ## Markdown Format
49
+
50
+ ### Basic Format
51
+
52
+ ```markdown
53
+ ## 1. Section Title
54
+
55
+ ### Concept 1.1: Image Title
56
+ A detailed description of the image you want to generate...
57
+
58
+ ### Concept 1.2: Another Image
59
+ Another prompt description...
60
+ ```
61
+
62
+ ### With Metadata
63
+
64
+ Add metadata as bullet points after the heading to override settings:
65
+
66
+ ```markdown
67
+ ### Concept 1.1: Custom Image
68
+ - model: GPT-Image-1
69
+ - aspect: 16:9
70
+ - quality: high
71
+ - retries: 5
72
+
73
+ A detailed prompt for the image...
74
+ ```
75
+
76
+ ### Standard Metadata Keys
77
+
78
+ - `model` - Override the model for this prompt (e.g., `GPT-Image-1`, `Nano-Banana`)
79
+ - `format` - Override output format (e.g., `png`, `jpg`)
80
+ - `skip` - Set to `true` to skip this prompt
81
+ - `retries` - Number of retry attempts (default: 3)
82
+
83
+ ### Custom Metadata Keys
84
+
85
+ Any other keys are passed directly to the API via `extra_body`:
86
+
87
+ - `aspect` - Aspect ratio (`1:1`, `3:2`, `2:3`, `16:9`, `auto`)
88
+ - `quality` - Image quality (`low`, `medium`, `high`)
89
+ - `thinking_level` - For thinking models (`low`, `medium`, `high`)
90
+ - `thinking_budget` - Thinking budget (`extended`)
91
+ - `web_search` - Enable web search (`true` / `false`)
92
+
93
+ ## CLI Usage
94
+
95
+ ```bash
96
+ batch-renderer [OPTIONS] INPUT_FILE
97
+ ```
98
+
99
+ ### Options
100
+
101
+ | Option | Description | Default |
102
+ |--------|-------------|---------|
103
+ | `--model`, `-m` | Model to use | `Nano-Banana` (or `POE_DEFAULT_MODEL` env) |
104
+ | `--output`, `-o` | Output directory | `out` |
105
+ | `--pattern`, `-p` | Extraction pattern (`concept`, `numbered`, `simple`) | `concept` |
106
+ | `--format`, `-f` | Output image format | `png` |
107
+ | `--flatten` | Flatten output (no subdirectories) | `false` |
108
+ | `--dry-run` | Extract and display without rendering | `false` |
109
+ | `--no-confirm` | Skip confirmation prompt | `false` |
110
+ | `--cache-images` | Cache images in `logs/image_cache` | `false` |
111
+ | `--validation-mode` | Metadata validation (`strict`, `lenient`, `hybrid`) | `hybrid` |
112
+ | `--api-key` | Poe API key (or `POE_API_KEY` env) | - |
113
+
114
+ ### Examples
115
+
116
+ **Basic usage**:
117
+ ```bash
118
+ batch-renderer prompts.md
119
+ ```
120
+
121
+ **Use a specific model**:
122
+ ```bash
123
+ batch-renderer prompts.md --model GPT-Image-1
124
+ ```
125
+
126
+ **Flat output structure**:
127
+ ```bash
128
+ batch-renderer prompts.md --flatten
129
+ ```
130
+
131
+ **Dry run to preview**:
132
+ ```bash
133
+ batch-renderer prompts.md --dry-run
134
+ ```
135
+
136
+ **Batch render without confirmation**:
137
+ ```bash
138
+ batch-renderer prompts.md --no-confirm
139
+ ```
140
+
141
+ **Strict metadata validation**:
142
+ ```bash
143
+ batch-renderer prompts.md --validation-mode strict
144
+ ```
145
+
146
+ ## Output Structure
147
+
148
+ ### Nested (default)
149
+
150
+ ```
151
+ out/
152
+ 1-artificial-lovers/
153
+ concept-1-1-blade-runner-noir-romance.png
154
+ concept-1-2-holographic-love.png
155
+ 2-fantastic-eight/
156
+ concept-2-1-renaissance-group-portrait.png
157
+ ```
158
+
159
+ ### Flattened (with `--flatten`)
160
+
161
+ ```
162
+ out/
163
+ concept-1-1-blade-runner-noir-romance.png
164
+ concept-1-2-holographic-love.png
165
+ concept-2-1-renaissance-group-portrait.png
166
+ ```
167
+
168
+ ## Configuration Precedence
169
+
170
+ Settings are applied in this order (later overrides earlier):
171
+
172
+ 1. **Hard-coded defaults** (`Nano-Banana`, `png`, etc.)
173
+ 2. **Environment variables** (`POE_DEFAULT_MODEL`, `POE_API_KEY`)
174
+ 3. **Inline metadata** (in markdown file)
175
+ 4. **CLI arguments** (`--model`, `--format`, etc.)
176
+
177
+ ## Validation Modes
178
+
179
+ ### `hybrid` (default)
180
+ - **Standard keys** (model, format, skip, retries): Warns on malformed values
181
+ - **Custom keys**: Pass through without validation
182
+
183
+ ### `strict`
184
+ - **Standard keys**: Fails on malformed values
185
+ - **Custom keys**: Pass through without validation
186
+
187
+ ### `lenient`
188
+ - **All keys**: Warns only, never fails
189
+
190
+ ## Error Handling
191
+
192
+ - **Automatic retries**: Failed requests are retried 3 times by default (configurable per-prompt)
193
+ - **Text responses**: If model returns text instead of image, saves to `.txt` file with warning
194
+ - **Partial failures**: Continues rendering remaining prompts if one fails
195
+ - **Summary report**: Shows successful, text responses, and failed renders
196
+
197
+ ## Pattern Types
198
+
199
+ ### `concept` (default)
200
+ Extracts `### Concept X.Y: Title` style prompts with section headers.
201
+
202
+ ### `numbered`
203
+ Extracts `### X.Y Title` style prompts (no "Concept" keyword).
204
+
205
+ ### `simple`
206
+ Extracts all level-3 headings as prompts.
207
+
208
+ ## Environment Variables
209
+
210
+ Create a `.env` file in the project root:
211
+
212
+ ```env
213
+ # Required
214
+ POE_API_KEY=your_api_key_here
215
+
216
+ # Optional
217
+ POE_DEFAULT_MODEL=Nano-Banana
218
+ ```
219
+
220
+ ## Development
221
+
222
+ ### Project Structure
223
+
224
+ ```
225
+ batch-renderer/
226
+ ├── src/batch_renderer/
227
+ │ ├── __init__.py
228
+ │ ├── __main__.py
229
+ │ ├── cli.py # CLI interface
230
+ │ ├── config.py # Configuration management
231
+ │ ├── patterns.py # Prompt extraction patterns
232
+ │ └── renderer.py # Image rendering
233
+ ├── docs/
234
+ │ ├── adr/ # Architecture Decision Records
235
+ │ └── SAMPLE-CONCEPTS.md
236
+ ├── setup.py
237
+ ├── Pipfile
238
+ └── README.md
239
+ ```
240
+
241
+ ### Running Tests
242
+
243
+ ```bash
244
+ # Dry run with test file
245
+ pipenv run batch-renderer test_prompts.md --dry-run
246
+
247
+ # Dry run with full sample
248
+ pipenv run batch-renderer docs/SAMPLE-CONCEPTS.md --dry-run
249
+ ```
250
+
251
+ ## Architecture Decisions
252
+
253
+ See [docs/adr/](docs/adr/) for detailed design decisions:
254
+ - [ADR-0001: Core Architecture](docs/adr/0001-core-architecture.md)
255
+ - [ADR-0002: Prompt Metadata Format](docs/adr/0002-prompt-metadata-format.md)
256
+
257
+ ## Troubleshooting
258
+
259
+ ### "POE_API_KEY not found"
260
+ Make sure you've created a `.env` file with your API key, or pass it via `--api-key`.
261
+
262
+ ### "No prompts found in file"
263
+ Check that your markdown file uses the correct pattern format. Use `--dry-run` to debug extraction.
264
+
265
+ ### Model returns text instead of image
266
+ This can happen if:
267
+ - The model doesn't support image generation
268
+ - The model name is incorrect
269
+ - The prompt is ambiguous
270
+
271
+ The tool will save the text response to a `.txt` file for inspection.
272
+
273
+ ## License
274
+
275
+ MIT
276
+
277
+ ## Author
278
+
279
+ Jérémie Lumbroso with Claude Sonnet 4.5