pou2md 0.1.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.
pou2md-0.1.0/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Cristiano
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.
pou2md-0.1.0/PKG-INFO ADDED
@@ -0,0 +1,444 @@
1
+ Metadata-Version: 2.4
2
+ Name: pou2md
3
+ Version: 0.1.0
4
+ Summary: Convert TwinCAT 3 .TcPOU files into Markdown documentation with Mermaid diagrams
5
+ Author-email: crissoll <info@crissoll.com>
6
+ License: MIT
7
+ Project-URL: Homepage, https://github.com/crissoll/pou2md
8
+ Project-URL: Repository, https://github.com/crissoll/pou2md
9
+ Project-URL: Issues, https://github.com/crissoll/pou2md/issues
10
+ Keywords: twincat,twincat3,beckhoff,plc,iec61131-3,mermaid,markdown,cfc,fbd,ladder-diagram
11
+ Classifier: Development Status :: 4 - Beta
12
+ Classifier: Intended Audience :: Developers
13
+ Classifier: Intended Audience :: Manufacturing
14
+ Classifier: License :: OSI Approved :: MIT License
15
+ Classifier: Operating System :: OS Independent
16
+ Classifier: Programming Language :: Python :: 3
17
+ Classifier: Programming Language :: Python :: 3.10
18
+ Classifier: Programming Language :: Python :: 3.11
19
+ Classifier: Programming Language :: Python :: 3.12
20
+ Classifier: Programming Language :: Python :: 3.13
21
+ Classifier: Topic :: Software Development :: Documentation
22
+ Classifier: Topic :: Software Development :: Code Generators
23
+ Requires-Python: >=3.10
24
+ Description-Content-Type: text/markdown
25
+ License-File: LICENSE
26
+ Requires-Dist: tomli>=2.0; python_version < "3.11"
27
+ Provides-Extra: dev
28
+ Requires-Dist: pytest>=7.0; extra == "dev"
29
+ Requires-Dist: ruff; extra == "dev"
30
+ Requires-Dist: build; extra == "dev"
31
+ Requires-Dist: twine; extra == "dev"
32
+ Dynamic: license-file
33
+
34
+ # POU to Markdown Converter
35
+
36
+ [![CI](https://github.com/crissoll/pou2md/actions/workflows/ci.yml/badge.svg)](https://github.com/crissoll/pou2md/actions/workflows/ci.yml)
37
+ [![Python Versions](https://img.shields.io/badge/python-3.10%20%7C%203.11%20%7C%203.12%20%7C%203.13-blue)](https://www.python.org/)
38
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
39
+
40
+ A modular Python tool that converts Beckhoff TwinCAT 3 `.TcPOU` files into Mermaid diagrams embedded in Markdown (`.md`) documents.
41
+
42
+ ## Features
43
+
44
+ - **Class Diagrams (`classDiagram`)**: Automatically extracts IEC 61131-3 declarations (`PROGRAM`, `FUNCTION_BLOCK`, `FUNCTION`) with variable sections (`VAR_INPUT`, `VAR_OUTPUT`, `VAR_IN_OUT`, `VAR`), types, and initial values.
45
+ - **Continuous Function Chart (CFC)**: Reconstructs the signal flow graph (`flowchart LR`) from `<CFC>` XML structures, resolving pins, operators, function blocks, program calls, and wiring.
46
+ - **Function Block Diagram (FBD)**: Recursively parses `<NWL>` trees, resolving nested calls, pass-through assignments, and negated inputs.
47
+ - **Ladder Diagram (LD)**: Automatically detects LD view mode, formatting contacts (`┤├`), coils (`( )`), and jump labels (`▶ Label`).
48
+ - **Structured Text (ST)**: Embeds the original IEC 61131-3 source code in an `iecst` code block alongside the declaration class diagram.
49
+ - **Minimal Runtime Dependencies**: Uses only the Python standard library on Python 3.11+; Python 3.10 installs `tomli` for TOML configuration support.
50
+
51
+ ## Architecture
52
+
53
+ ```
54
+ pou2md/
55
+ ├── __init__.py
56
+ ├── __main__.py # CLI entry point
57
+ ├── converter.py # Main conversion orchestrator
58
+ ├── model/
59
+ │ ├── declaration.py # PouDeclaration, VarGroup, Variable dataclasses
60
+ │ └── flow_graph.py # FlowNode, FlowEdge, NetworkDiagram, FlowGraph dataclasses
61
+ ├── parser/
62
+ │ ├── declaration.py # IEC 61131-3 CDATA declaration parser
63
+ │ ├── nwl_parser.py # Network List parser (FBD & LD)
64
+ │ ├── cfc_parser.py # Continuous Function Chart parser
65
+ │ └── st_parser.py # Structured Text parser
66
+ ├── renderer/
67
+ │ ├── class_diagram.py # Mermaid classDiagram generator
68
+ │ └── flowchart.py # Mermaid flowchart LR generator
69
+ └── writer/
70
+ └── markdown.py # Markdown document generator
71
+ ```
72
+
73
+ ## Installation & CLI Setup
74
+
75
+ Install the package using `pip` (editable mode is recommended during development):
76
+
77
+ ```bash
78
+ # Editable install (recommended)
79
+ pip install -e .
80
+
81
+ # Or standard install
82
+ pip install .
83
+ ```
84
+
85
+ Once installed, the CLI tool can be executed from any terminal or directory using `pou2md` (or via Python's `-m` switch):
86
+
87
+ ```bash
88
+ # Global CLI command
89
+ pou2md [input] [options]
90
+
91
+ # Standard Python module syntax
92
+ python -m pou2md [input] [options]
93
+ ```
94
+
95
+ ---
96
+
97
+ ## CLI Reference
98
+
99
+ ### Command Syntax
100
+
101
+ ```bash
102
+ pou2md [input] [-o OUTPUT] [-r] [-u] [--single-folder] [--copy-folder-structure] [--exclude PATTERN] [--dry-run] [--clean] [--stdout] [-w] [--curve {step,stepAfter,linear,basis,none}] [--no-bifurcate] [--repeat-inputs]
103
+ ```
104
+
105
+ ### Options & Arguments
106
+
107
+ | Argument / Flag | Value Type / Choices | Default | Description |
108
+ | :--- | :--- | :--- | :--- |
109
+ | `input` *(positional)* | `Path` (file or folder) | `.` *(Current dir)* | Path to a single `.TcPOU` file or a directory containing `.TcPOU` files. |
110
+ | `-o`, `--output` | `Path` (folder or `.md` file) | `None` | Destination directory (e.g. `docs/`) or specific file path (e.g. `docs/system.md`). Required for directory input unless `--stdout` is set. |
111
+ | `-r`, `--recursive` | `Flag` | `False` | Recursively scan subdirectories for `.TcPOU` files. |
112
+ | `-u`, `--unified` | `Flag` | `False` | Merges all converted POUs into a single Markdown document separated by horizontal dividers (`---`). |
113
+ | `--single-folder` | `Flag` | Automatic | Also generate individual Markdown files. This is enabled by default unless `--unified` is used alone. |
114
+ | `--copy-folder-structure` | `Flag` | `False` | Generate individual Markdown files under matching source subdirectories instead of flattened names. Also enables individual output. |
115
+ | `--exclude PATTERN` | `Pattern` | None | Exclude matching filenames or relative paths; repeat the option for multiple patterns. |
116
+ | `--stdout` | `Flag` | `False` | Prints generated Markdown directly to `stdout` instead of writing to disk. |
117
+ | `--curve` | `step` \| `stepAfter` \| `linear` \| `basis` \| `none` | `step` | Mermaid flowchart wire routing style. `step` generates orthogonal right-angle wires entering blocks horizontally (`>`). |
118
+ | `--no-bifurcate` | `Flag` | *(Bifurcation enabled)* | Disables bifurcation junction nodes (`(( ))`), drawing independent wires from the source pin to each destination pin. |
119
+ | `--repeat-inputs` | `Flag` | `False` | In CFC diagrams, duplicates input variable blocks next to each connected pin to eliminate long cross-sheet wires. |
120
+ | `-w`, `--watch` | `Flag` | `False` | Continuously watches the input file or directory and regenerates Markdown after changes. Press `Ctrl+C` to stop. |
121
+ | `--poll-interval` | Seconds | `1.0` | Watcher polling interval. |
122
+ | `--debounce-delay` | Seconds | `0.25` | Delay after a detected change before conversion. |
123
+ | `--retry-count` | Integer | `3` | Conversion attempts for transient save or network errors. |
124
+ | `--retry-delay` | Seconds | `0.5` | Delay between conversion attempts. |
125
+ | `-v`, `--verbose` | `Flag` | `False` | Enable diagnostic logging. |
126
+ | `--quiet` | `Flag` | `False` | Suppress normal status messages while preserving errors. |
127
+ | `--log-format` | `text` \| `json` | `text` | Select human-readable or machine-readable logs. |
128
+ | `--dry-run` | `Flag` | `False` | Show planned outputs without writing Markdown or a manifest. |
129
+ | `--clean` | `Flag` | `False` | Remove stale outputs previously recorded in the output manifest. Requires `-o`. |
130
+ | `--config FILE` | TOML file | None | Load default arguments from a project configuration file. Command-line values override config values. |
131
+ | `--version` | `Flag` | - | Print the installed package version. |
132
+ | `-h`, `--help` | `Flag` | - | Display CLI help message and exit. |
133
+
134
+ ---
135
+
136
+ ## Output Resolution Rules
137
+
138
+ The destination path depends on the input type and flags provided:
139
+
140
+ | Input Type | Flags | Destination Behavior |
141
+ | :--- | :--- | :--- |
142
+ | **Single `.TcPOU` file** | *No `-o` or `--stdout`* | Prints generated Markdown directly to `stdout`. |
143
+ | **Single `.TcPOU` file** | `-o path/to/dir/` | Creates `path/to/dir/<POU_NAME>.md`. |
144
+ | **Single `.TcPOU` file** | `-o path/to/custom.md` | Writes directly to `path/to/custom.md`. |
145
+ | **Directory** | `-o path/to/dir/` | Generates individual `<POU_NAME>.md` files inside `path/to/dir/`. |
146
+ | **Directory** | `-r -o path/to/dir/` | Recursively scans subfolders; outputs flattened names: `parent--subfolder--<POU_NAME>.md`. |
147
+ | **Directory** | `-u -o path/to/dir/` | Combines all POUs into `path/to/dir/unified.md`. |
148
+ | **Directory** | `-u -o path/to/custom.md`| Combines all POUs into the exact specified file `path/to/custom.md`. |
149
+ | **Directory** | `-u --single-folder -o path/to/dir/` | Writes both individual files and `unified.md`. |
150
+ | **Directory** | `-r --copy-folder-structure -o path/to/dir/` | Writes individual files under matching subdirectories. |
151
+ | **Directory** | `-u --copy-folder-structure -o path/to/dir/` | Writes both nested individual files and `unified.md`. |
152
+ | **Any Input** | `--stdout` | Emits Markdown to terminal `stdout` without creating any files on disk. |
153
+
154
+ When both individual and unified output are requested with `-o path/to/file.md`,
155
+ the unified document uses that exact path and individual files are written to
156
+ its parent directory.
157
+
158
+ ## Continuous Watching (`-w`)
159
+
160
+ Use `-w` to perform an initial conversion and then keep the process running while
161
+ watching for added, modified, or removed `.TcPOU` files. The watcher polls the
162
+ input path, debounces editor save operations, and releases its lock file when
163
+ stopped with `Ctrl+C`.
164
+
165
+ ```bash
166
+ # Watch a directory and update individual generated files
167
+ pou2md MyPlcProject/ -r -w -o docs/generated/
168
+
169
+ # Watch a directory and rebuild one unified document
170
+ pou2md MyPlcProject/ -r -u -w -o docs/complete_system_manual.md
171
+
172
+ # Watch one file and print each generated document to stdout
173
+ pou2md POUs/FB_Motor.TcPOU -w
174
+ ```
175
+
176
+ For directory input, specify `-o/--output` or `--stdout`, just as with a
177
+ one-time conversion. When a source file is removed, its generated individual
178
+ Markdown file is removed as well; unified output files are rebuilt instead.
179
+
180
+ Output mode combinations are:
181
+
182
+ | Flags | Output |
183
+ | :--- | :--- |
184
+ | *(none)* | Individual files in one output folder |
185
+ | `--unified` | Unified file only |
186
+ | `--single-folder` | Individual files in one output folder |
187
+ | `--unified --single-folder` | Both individual files and unified file |
188
+ | `--copy-folder-structure` | Individual files in matching subfolders |
189
+ | `--unified --copy-folder-structure` | Both nested individual files and unified file |
190
+
191
+ The default polling interval is one second, followed by a 250 ms save debounce.
192
+ This is normally suitable for mapped drives and SMB shares, but network latency
193
+ can make detection slower and a temporarily unavailable share is skipped until
194
+ the next poll. The watcher uses an atomic lock-file claim, so two processes
195
+ started for the same target cannot both watch it; the second process exits with
196
+ an error. Different output targets intentionally use separate locks.
197
+
198
+ Parsing errors are reported to `stderr` and do not terminate the watcher. This
199
+ allows editors to save an incomplete XML document temporarily: the watcher
200
+ waits and retries that file after the next change. The same behavior applies to
201
+ an incomplete file present when the watcher starts.
202
+
203
+ Generated Markdown is written through a temporary sibling file and atomically
204
+ replaced into place, preventing readers from seeing partially written output.
205
+ Use `--exclude` to ignore backup or generated sources, for example:
206
+
207
+ ```bash
208
+ pou2md MyPlcProject/ -r -w -o docs/ --exclude "Backup/*" --exclude "*_old.TcPOU"
209
+ ```
210
+
211
+ Use `--verbose` for diagnostic status logging or `--quiet` to suppress normal
212
+ status messages while retaining errors. Watcher timing can be tuned with
213
+ `--poll-interval`, `--debounce-delay`, `--retry-count`, and `--retry-delay`.
214
+
215
+ ## Dry runs, cleanup, and manifests
216
+
217
+ Use `--dry-run` to inspect the output plan without creating files:
218
+
219
+ ```bash
220
+ pou2md MyPlcProject/ -r --copy-folder-structure --dry-run -o docs/
221
+ ```
222
+
223
+ When writing to an output directory, the converter maintains
224
+ `.pou2md-manifest.json` containing the generated Markdown paths. `--clean`
225
+ removes only stale paths recorded in that manifest; it never scans for or
226
+ deletes untracked files:
227
+
228
+ ```bash
229
+ pou2md MyPlcProject/ -r --clean -o docs/
230
+ ```
231
+
232
+ Use JSON logs for automation:
233
+
234
+ ```bash
235
+ pou2md MyPlcProject/ -r -w -o docs/ --log-format json
236
+ ```
237
+
238
+ ## Project configuration
239
+
240
+ Arguments can be saved in a committed `pou2md.toml` file:
241
+
242
+ ```toml
243
+ input = "POUs"
244
+ output = "docs"
245
+ recursive = true
246
+ unified = true
247
+ copy_folder_structure = true
248
+ exclude = ["Backup/*"]
249
+ ```
250
+
251
+ Run it with:
252
+
253
+ ```bash
254
+ pou2md --config pou2md.toml
255
+ ```
256
+
257
+ Built-in defaults are overridden by the TOML file, and explicit command-line
258
+ arguments override the TOML values.
259
+
260
+ Use `pou2md --version` when reporting issues so the exact installed converter
261
+ version is known. Invalid XML errors include the source filename and XML
262
+ location, while the watcher preserves the last valid output.
263
+
264
+ ---
265
+
266
+ ## Practical CLI Recipes
267
+
268
+ ### 1. Quick Inspection & Terminal Piping
269
+ Inspect generated Markdown or pipe directly into tools like `bat`, `glow`, or clipboard utilities:
270
+
271
+ ```bash
272
+ # Print POU markdown directly to stdout
273
+ pou2md POUs/FB_Motor.TcPOU --stdout
274
+
275
+ # Pipe output to a markdown viewer (bat, glow, etc.)
276
+ pou2md POUs/FB_Motor.TcPOU --stdout | bat -l md
277
+
278
+ # Copy markdown directly to clipboard (Windows PowerShell)
279
+ pou2md POUs/FB_Motor.TcPOU --stdout | Set-Clipboard
280
+ ```
281
+
282
+ ### 2. Single File Conversion
283
+ Convert an individual POU into a specific output directory or custom filename:
284
+
285
+ ```bash
286
+ # Save to an output directory (produces output/FB_Motor.md)
287
+ pou2md POUs/FB_Motor.TcPOU -o output/
288
+
289
+ # Save to a specific custom filename
290
+ pou2md POUs/FB_Motor.TcPOU -o docs/motor_controller.md
291
+ ```
292
+
293
+ ### 3. Batch Directory Conversion
294
+ Convert all `.TcPOU` files located directly inside a folder:
295
+
296
+ ```bash
297
+ pou2md POUs/ -o docs/pous/
298
+ ```
299
+
300
+ ### 4. Recursive Project Conversion (`-r`)
301
+ Recursively scan complete TwinCAT PLC project structures. The converter flattens nested folder hierarchies into distinct, clash-free filenames:
302
+
303
+ ```bash
304
+ pou2md MyPlcProject/ -r -o docs/generated/
305
+ ```
306
+
307
+ *Example name mapping:*
308
+ - `MyPlcProject/Motion/Axes/FB_Axis.TcPOU` &rarr; `docs/generated/Motion--Axes--FB_Axis.md`
309
+ - `MyPlcProject/Diagnostics/FB_Logger.TcPOU` &rarr; `docs/generated/Diagnostics--FB_Logger.md`
310
+
311
+ ### 5. Unified Single-Document Generation (`-u`)
312
+ Merge your entire PLC library or project into a single Markdown document. Perfect for single-page project wikis, Obsidian vaults, or MkDocs:
313
+
314
+ ```bash
315
+ # Save as default unified.md in target directory
316
+ pou2md MyPlcProject/ -r -u -o docs/
317
+
318
+ # Save with a custom documentation filename
319
+ pou2md MyPlcProject/ -r -u -o docs/complete_system_manual.md
320
+
321
+ # Stream the entire unified manual to stdout for downstream processing
322
+ pou2md MyPlcProject/ -r -u --stdout > complete_system_manual.md
323
+ ```
324
+
325
+ ---
326
+
327
+ ## Diagram Layout & Styling Customization
328
+
329
+ `pou2md` provides dedicated flags to fine-tune the look and layout of Mermaid flowcharts to match industrial PLC schematics:
330
+
331
+ ### Wire Routing (`--curve`)
332
+ Select how signal connection lines are interpolated:
333
+
334
+ ```bash
335
+ # Default: Orthogonal right angles entering nodes horizontally (industrial CAD style)
336
+ pou2md POUs/FB_Controller.TcPOU -o docs/ --curve step
337
+
338
+ # Smooth cubic splines (fluid curves)
339
+ pou2md POUs/FB_Controller.TcPOU -o docs/ --curve basis
340
+
341
+ # Direct point-to-point straight lines
342
+ pou2md POUs/FB_Controller.TcPOU -o docs/ --curve linear
343
+
344
+ # Standard Mermaid default curve interpolation
345
+ pou2md POUs/FB_Controller.TcPOU -o docs/ --curve none
346
+ ```
347
+
348
+ ### Output Bifurcation Junctions (`--no-bifurcate`)
349
+ When an output pin connects to multiple downstream blocks:
350
+ - **Default (Bifurcation enabled)**: Splits wires using a clean junction dot (`(( ))`), preventing duplicate pin labels and visual clutter.
351
+ - **`--no-bifurcate`**: Draws separate, independent wires directly from the output pin to every target node.
352
+
353
+ ```bash
354
+ # Disable bifurcation junctions
355
+ pou2md POUs/FB_Controller.TcPOU -o docs/ --no-bifurcate
356
+ ```
357
+
358
+ ### CFC Input Variable Duplication (`--repeat-inputs`)
359
+ In large Continuous Function Charts (CFC), multiple blocks often share common inputs (e.g. `bEnable` or `stConfig`):
360
+ - **Default (`False`)**: Creates a single node for each input variable and connects it across the diagram.
361
+ - **`--repeat-inputs`**: Creates an input variable block next to each block pin it feeds, eliminating long feedback loops and wires crossing through the middle of the sheet.
362
+
363
+ ```bash
364
+ pou2md POUs/CFC_PlantControl.TcPOU -o docs/ --repeat-inputs
365
+ ```
366
+
367
+ ---
368
+
369
+ ## CI / CD & Automation Integration
370
+
371
+ ### GitHub Actions Workflow Example
372
+ Automatically generate up-to-date Markdown diagrams whenever PLC files are pushed:
373
+
374
+ ```yaml
375
+ name: Generate PLC Documentation
376
+ on: [push, pull_request]
377
+
378
+ jobs:
379
+ docs:
380
+ runs-on: ubuntu-latest
381
+ steps:
382
+ - uses: actions/checkout@v4
383
+ - uses: actions/setup-python@v5
384
+ with:
385
+ python-version: "3.12"
386
+ - name: Install converter
387
+ run: pip install .
388
+ - name: Build documentation
389
+ run: pou2md src/ -r -u -o docs/plc_architecture.md
390
+ - name: Upload documentation artifact
391
+ uses: actions/upload-artifact@v4
392
+ with:
393
+ name: plc-docs
394
+ path: docs/plc_architecture.md
395
+ ```
396
+
397
+ ### Shell Automation Scripts
398
+
399
+ **PowerShell (Windows):**
400
+ ```powershell
401
+ # Convert all POU subdirectories into separate documentation folders
402
+ Get-ChildItem -Directory "src/PLC/*" | ForEach-Object {
403
+ pou2md $_.FullName -r -o "docs/$($_.Name)"
404
+ }
405
+ ```
406
+
407
+ **Bash (Linux / macOS):**
408
+ ```bash
409
+ # Compile documentation for each PLC subsystem
410
+ for dir in src/PLC/*/; do
411
+ name=$(basename "$dir")
412
+ pou2md "$dir" -r -u -o "docs/${name}.md"
413
+ done
414
+ ```
415
+
416
+ ---
417
+
418
+ ## Exit Codes
419
+
420
+ For CI/CD scripts and automated tools, the CLI returns standard status codes:
421
+ - `0`: Execution completed successfully.
422
+ - `1`: Error encountered (e.g. input path does not exist, or directory input without `-o` / `--stdout`).
423
+
424
+ ## Running Tests
425
+
426
+ Run the test suite using Python's standard `unittest` module:
427
+ ```bash
428
+ python -m unittest tests/test_converter.py -v
429
+ ```
430
+
431
+ ## Disclaimer & AI Disclosure
432
+
433
+ > [!WARNING]
434
+ > **Industrial Automation & Safety Notice**
435
+ >
436
+ > This tool was developed with the assistance of Artificial Intelligence (AI).
437
+ >
438
+ > * **Visualization Only**: Generated diagrams and Markdown files are intended for documentation and visualization purposes. Never rely solely on this tool for safety audits, formal verification, or machine commissioning.
439
+ > * **No Warranty / As-Is**: This software is provided "as is", without warranty of any kind, express or implied.
440
+ > * **Limitation of Liability**: The author assumes no responsibility or liability for any errors, omissions, machine downtime, equipment damage, or personal injury resulting from the use of this tool. Use entirely at your own risk.
441
+
442
+ ## License
443
+
444
+ This project is licensed under the [MIT License](LICENSE).