streamlit-mini-toolkit 0.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.
- mini_toolkit/__init__.py +3 -0
- mini_toolkit/__main__.py +3 -0
- mini_toolkit/app.py +111 -0
- mini_toolkit/cli.py +40 -0
- mini_toolkit/core/__init__.py +1 -0
- mini_toolkit/core/net.py +56 -0
- mini_toolkit/core/pdf.py +12 -0
- mini_toolkit/core/registry.py +75 -0
- mini_toolkit/core/ui.py +90 -0
- mini_toolkit/streamlit_config.toml +16 -0
- mini_toolkit/style/style.css +171 -0
- mini_toolkit/tools/__init__.py +1 -0
- mini_toolkit/tools/background_remover.py +65 -0
- mini_toolkit/tools/change_tracker.py +90 -0
- mini_toolkit/tools/chat_alert.py +42 -0
- mini_toolkit/tools/color_picker.py +40 -0
- mini_toolkit/tools/document_converter.py +121 -0
- mini_toolkit/tools/file_compressor.py +78 -0
- mini_toolkit/tools/github_trending.py +53 -0
- mini_toolkit/tools/hash_generator.py +43 -0
- mini_toolkit/tools/image_converter.py +63 -0
- mini_toolkit/tools/image_downloader.py +67 -0
- mini_toolkit/tools/image_enhancer.py +54 -0
- mini_toolkit/tools/image_watermarker.py +63 -0
- mini_toolkit/tools/ocr.py +93 -0
- mini_toolkit/tools/page_speed.py +45 -0
- mini_toolkit/tools/password_checker.py +53 -0
- mini_toolkit/tools/pdf_tools.py +83 -0
- mini_toolkit/tools/qr_code.py +83 -0
- mini_toolkit/tools/resume_builder.py +385 -0
- mini_toolkit/tools/seo_health.py +64 -0
- mini_toolkit/tools/signature.py +72 -0
- mini_toolkit/tools/ssl_checker.py +68 -0
- mini_toolkit/tools/text_to_speech.py +34 -0
- mini_toolkit/tools/text_utilities.py +36 -0
- mini_toolkit/tools/url_shortener.py +29 -0
- mini_toolkit/tools/website_status.py +39 -0
- streamlit_mini_toolkit-0.1.0.dist-info/METADATA +151 -0
- streamlit_mini_toolkit-0.1.0.dist-info/RECORD +42 -0
- streamlit_mini_toolkit-0.1.0.dist-info/WHEEL +4 -0
- streamlit_mini_toolkit-0.1.0.dist-info/entry_points.txt +2 -0
- streamlit_mini_toolkit-0.1.0.dist-info/licenses/LICENSE +21 -0
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
from typing import Optional
|
|
2
|
+
|
|
3
|
+
import requests
|
|
4
|
+
import streamlit as st
|
|
5
|
+
|
|
6
|
+
from core.net import normalize_url
|
|
7
|
+
|
|
8
|
+
API = "https://tinyurl.com/api-create.php"
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
def shorten_url(long_url: str) -> Optional[str]:
|
|
12
|
+
try:
|
|
13
|
+
response = requests.get(API, params={"url": long_url}, timeout=8)
|
|
14
|
+
except requests.RequestException:
|
|
15
|
+
return None
|
|
16
|
+
text = response.text.strip()
|
|
17
|
+
return text if response.ok and text.startswith("http") else None
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
def render() -> None:
|
|
21
|
+
long_url = st.text_input("Long URL", placeholder="https://example.com/a/very/long/path?with=parameters")
|
|
22
|
+
if st.button("Shorten", type="primary", disabled=not long_url.strip()):
|
|
23
|
+
with st.spinner("Shortening…"):
|
|
24
|
+
short = shorten_url(normalize_url(long_url))
|
|
25
|
+
if short:
|
|
26
|
+
st.success("Done — copy your link below.")
|
|
27
|
+
st.code(short, language=None)
|
|
28
|
+
else:
|
|
29
|
+
st.error("TinyURL couldn't shorten that link. Check the URL and try again.")
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import time
|
|
2
|
+
from concurrent.futures import ThreadPoolExecutor
|
|
3
|
+
|
|
4
|
+
import streamlit as st
|
|
5
|
+
|
|
6
|
+
from core.net import fetch, normalize_url
|
|
7
|
+
|
|
8
|
+
MAX_URLS = 25
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
def check(url: str) -> dict:
|
|
12
|
+
url = normalize_url(url)
|
|
13
|
+
started = time.perf_counter()
|
|
14
|
+
try:
|
|
15
|
+
response = fetch(url, timeout=10)
|
|
16
|
+
except Exception as exc:
|
|
17
|
+
return {"URL": url, "Status": "🔴 Down", "Code": None, "Time (ms)": None, "Detail": str(exc)[:120]}
|
|
18
|
+
elapsed = round((time.perf_counter() - started) * 1000)
|
|
19
|
+
ok = response.status_code < 400
|
|
20
|
+
return {
|
|
21
|
+
"URL": url,
|
|
22
|
+
"Status": "🟢 Up" if ok else "🟠 Error",
|
|
23
|
+
"Code": response.status_code,
|
|
24
|
+
"Time (ms)": elapsed,
|
|
25
|
+
"Detail": response.reason,
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
def render() -> None:
|
|
30
|
+
raw = st.text_area("URLs (one per line)", height=140, placeholder="example.com\nhttps://github.com")
|
|
31
|
+
urls = list(dict.fromkeys(u.strip() for u in raw.splitlines() if u.strip()))[:MAX_URLS]
|
|
32
|
+
if st.button("Check status", type="primary", disabled=not urls):
|
|
33
|
+
with st.spinner(f"Checking {len(urls)} URL{'s' if len(urls) != 1 else ''}…"):
|
|
34
|
+
with ThreadPoolExecutor(max_workers=8) as pool:
|
|
35
|
+
results = list(pool.map(check, urls))
|
|
36
|
+
up = sum(r["Status"].endswith("Up") for r in results)
|
|
37
|
+
st.metric("Online", f"{up} / {len(results)}")
|
|
38
|
+
st.dataframe(results, width="stretch", hide_index=True)
|
|
39
|
+
st.caption(f"Checks up to {MAX_URLS} URLs at a time.")
|
|
@@ -0,0 +1,151 @@
|
|
|
1
|
+
Metadata-Version: 2.5
|
|
2
|
+
Name: streamlit-mini-toolkit
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: 25 everyday utilities (image, document, text and web tools) in one Streamlit app.
|
|
5
|
+
Project-URL: Homepage, https://github.com/sarif-mia/mini-toolkit
|
|
6
|
+
Project-URL: Source, https://github.com/sarif-mia/mini-toolkit
|
|
7
|
+
Project-URL: Tracker, https://github.com/sarif-mia/mini-toolkit/issues
|
|
8
|
+
Author: Sarif Mia
|
|
9
|
+
License-Expression: MIT
|
|
10
|
+
License-File: LICENSE
|
|
11
|
+
Keywords: image,pdf,qr-code,seo,streamlit,toolkit,utilities
|
|
12
|
+
Classifier: Operating System :: OS Independent
|
|
13
|
+
Classifier: Programming Language :: Python :: 3
|
|
14
|
+
Classifier: Topic :: Utilities
|
|
15
|
+
Requires-Python: >=3.9
|
|
16
|
+
Requires-Dist: beautifulsoup4>=4.12
|
|
17
|
+
Requires-Dist: fpdf2>=2.7.8
|
|
18
|
+
Requires-Dist: gtts>=2.5
|
|
19
|
+
Requires-Dist: pillow>=10.1
|
|
20
|
+
Requires-Dist: pypdf>=4.0
|
|
21
|
+
Requires-Dist: python-docx>=1.1
|
|
22
|
+
Requires-Dist: qrcode>=7.4
|
|
23
|
+
Requires-Dist: requests>=2.31
|
|
24
|
+
Requires-Dist: streamlit-image-coordinates>=0.1.9
|
|
25
|
+
Requires-Dist: streamlit>=1.50
|
|
26
|
+
Provides-Extra: all
|
|
27
|
+
Requires-Dist: docx2pdf>=0.1.8; (sys_platform != 'linux') and extra == 'all'
|
|
28
|
+
Requires-Dist: opencv-python-headless>=4.8; extra == 'all'
|
|
29
|
+
Requires-Dist: pdf2docx>=0.5.8; extra == 'all'
|
|
30
|
+
Requires-Dist: pytesseract>=0.3.10; extra == 'all'
|
|
31
|
+
Requires-Dist: pywin32; (sys_platform == 'win32') and extra == 'all'
|
|
32
|
+
Requires-Dist: rembg[cpu]>=2.0.50; extra == 'all'
|
|
33
|
+
Provides-Extra: bg
|
|
34
|
+
Requires-Dist: rembg[cpu]>=2.0.50; extra == 'bg'
|
|
35
|
+
Provides-Extra: docs
|
|
36
|
+
Requires-Dist: docx2pdf>=0.1.8; (sys_platform != 'linux') and extra == 'docs'
|
|
37
|
+
Requires-Dist: pdf2docx>=0.5.8; extra == 'docs'
|
|
38
|
+
Requires-Dist: pywin32; (sys_platform == 'win32') and extra == 'docs'
|
|
39
|
+
Provides-Extra: ocr
|
|
40
|
+
Requires-Dist: opencv-python-headless>=4.8; extra == 'ocr'
|
|
41
|
+
Requires-Dist: pytesseract>=0.3.10; extra == 'ocr'
|
|
42
|
+
Description-Content-Type: text/markdown
|
|
43
|
+
|
|
44
|
+
# 🧰 Mini Toolkit
|
|
45
|
+
|
|
46
|
+
A collection of 25 everyday utilities — image editing, document conversion, text tools and website checks — in one fast, clean Streamlit app. No sign-up, no clutter.
|
|
47
|
+
|
|
48
|
+
## Tools
|
|
49
|
+
|
|
50
|
+
| Category | Tools |
|
|
51
|
+
| --- | --- |
|
|
52
|
+
| **Image** | Background Remover · Image Converter · Image Enhancer · Image Watermarker · Image Color Picker · QR Code Generator · OCR Text Extractor |
|
|
53
|
+
| **Documents** | Document Converter (DOCX ↔ PDF ↔ TXT) · PDF Merge & Split · File Compressor · Resume Builder · Email Signature |
|
|
54
|
+
| **Text & Security** | Text Utilities · Text to Speech · Hash Generator · Password Checker & Generator |
|
|
55
|
+
| **Web & Developer** | Website Status · Page Speed Checker · SSL Certificate Checker · SEO Health Check · Website Image Downloader · URL Shortener · Website Change Tracker · GitHub Trending · Chat Alert Bot (Slack / Teams / Discord) |
|
|
56
|
+
|
|
57
|
+
Every tool has its own shareable URL, e.g. `/?tool=qr-code`.
|
|
58
|
+
|
|
59
|
+
## Install from PyPI
|
|
60
|
+
|
|
61
|
+
```sh
|
|
62
|
+
pip install streamlit-mini-toolkit # core tools
|
|
63
|
+
pip install "streamlit-mini-toolkit[all]" # + background remover, OCR, DOCX/PDF conversion
|
|
64
|
+
mini-toolkit # opens the app at http://localhost:8501
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
Pick extras individually if you prefer: `[bg]` (Background Remover), `[ocr]` (OCR Text Extractor), `[docs]` (DOCX ↔ PDF). Streamlit flags pass through, e.g. `mini-toolkit --server.port 8080`.
|
|
68
|
+
|
|
69
|
+
## Quick start (from source)
|
|
70
|
+
|
|
71
|
+
Requires Python 3.9+.
|
|
72
|
+
|
|
73
|
+
```sh
|
|
74
|
+
git clone https://github.com/sarif-mia/mini-toolkit.git
|
|
75
|
+
cd mini-toolkit
|
|
76
|
+
python -m venv .venv && source .venv/bin/activate # Windows: .venv\Scripts\activate
|
|
77
|
+
pip install -r requirements.txt
|
|
78
|
+
streamlit run app.py
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
The app opens at <http://localhost:8501>.
|
|
82
|
+
|
|
83
|
+
### System dependencies (optional)
|
|
84
|
+
|
|
85
|
+
A few tools call external programs. Everything else works without them.
|
|
86
|
+
|
|
87
|
+
| Feature | Needs |
|
|
88
|
+
| --- | --- |
|
|
89
|
+
| OCR Text Extractor | [Tesseract](https://tesseract-ocr.github.io/tessdoc/Installation.html) |
|
|
90
|
+
| DOCX → PDF | [LibreOffice](https://www.libreoffice.org/) (or Microsoft Word on Windows/macOS) |
|
|
91
|
+
|
|
92
|
+
On Debian/Ubuntu: `sudo xargs apt-get install -y < packages.txt`
|
|
93
|
+
|
|
94
|
+
## Deployment
|
|
95
|
+
|
|
96
|
+
### Streamlit Community Cloud (recommended, free)
|
|
97
|
+
|
|
98
|
+
1. Go to [share.streamlit.io](https://share.streamlit.io) and sign in with GitHub.
|
|
99
|
+
2. **Create app** → pick this repository, branch `master`, main file `app.py`.
|
|
100
|
+
3. Deploy. `requirements.txt` and `packages.txt` are picked up automatically.
|
|
101
|
+
|
|
102
|
+
### Docker (Render, Railway, Fly.io, Hugging Face Spaces, …)
|
|
103
|
+
|
|
104
|
+
```sh
|
|
105
|
+
docker build -t mini-toolkit .
|
|
106
|
+
docker run -p 8501:8501 mini-toolkit
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
> **Why not Vercel?** Vercel runs short-lived serverless functions, while Streamlit needs a long-running server with a persistent WebSocket connection. Use one of the options above instead.
|
|
110
|
+
|
|
111
|
+
### Optional secrets
|
|
112
|
+
|
|
113
|
+
The Website Change Tracker can email change summaries. Add these to `.streamlit/secrets.toml` locally, or to your host's secrets settings:
|
|
114
|
+
|
|
115
|
+
```toml
|
|
116
|
+
smtp_server = "smtp.gmail.com"
|
|
117
|
+
smtp_port = 587
|
|
118
|
+
smtp_user = "you@example.com"
|
|
119
|
+
smtp_pass = "app-password"
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
## Project structure
|
|
123
|
+
|
|
124
|
+
```
|
|
125
|
+
app.py Entry point: page config, routing, home page
|
|
126
|
+
core/
|
|
127
|
+
registry.py List of tools and categories (add new tools here)
|
|
128
|
+
ui.py Shared UI helpers (headers, uploads, ZIP export, footer)
|
|
129
|
+
net.py Safe HTTP fetching for the web tools
|
|
130
|
+
tools/ One module per tool, each exposing render()
|
|
131
|
+
style/style.css Custom styling
|
|
132
|
+
.streamlit/ Theme and server config
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
### Adding a tool
|
|
136
|
+
|
|
137
|
+
1. Create `tools/my_tool.py` with a `render()` function.
|
|
138
|
+
2. Register it in `core/registry.py`:
|
|
139
|
+
```python
|
|
140
|
+
Tool("my-tool", "My Tool", "🧪", "One-line description.", TEXT, "my_tool"),
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
Tools are imported lazily, so a missing optional dependency only affects that one tool.
|
|
144
|
+
|
|
145
|
+
## License
|
|
146
|
+
|
|
147
|
+
Distributed under the MIT License. See [`LICENSE`](LICENSE).
|
|
148
|
+
|
|
149
|
+
---
|
|
150
|
+
|
|
151
|
+
Built by [Sarif](https://sarifmiia.netlify.app/) · [GitHub](https://github.com/sarif-mia) · [LinkedIn](https://www.linkedin.com/in/sarif-mia/)
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
mini_toolkit/__init__.py,sha256=jdSYdcJbRTNJmTKlfNjKsG1SZ8jqsjfACwDKLveBdjk,87
|
|
2
|
+
mini_toolkit/__main__.py,sha256=bYt9eEaoRQWdejEHFD8REx9jxVEdZptECFsV7F49Ink,30
|
|
3
|
+
mini_toolkit/cli.py,sha256=mkLiQ1MY2nQz_w0jm-nOxKbKBK67hG_z0SuGh-9HTxI,1253
|
|
4
|
+
mini_toolkit/app.py,sha256=SmNRjQCn5tBJbXre0Hk3X_XYGVtmKuz0jCanrUblg08,4066
|
|
5
|
+
mini_toolkit/core/__init__.py,sha256=KeMW6i_R-Uhs1P1gtson3kI4OlC6rEnDJ3RpOhqJvLQ,55
|
|
6
|
+
mini_toolkit/core/net.py,sha256=_Yv9uVqcHVS24ziQrdXqdtOR6fE9LNB8D_Kngu69jT8,2079
|
|
7
|
+
mini_toolkit/core/pdf.py,sha256=jD_94CLbs1RqKHiXVJy8SddAC28MGpVVAbfHsTnboEs,491
|
|
8
|
+
mini_toolkit/core/registry.py,sha256=TPtzYtjhFN735STVnS7KbWMzNWCkHj7e8hL8hsC4KC0,4364
|
|
9
|
+
mini_toolkit/core/ui.py,sha256=ZTOFUlNvVpiEKf8T15E1_YtrqwnsnDnix_YQ8OmZkIg,2917
|
|
10
|
+
mini_toolkit/streamlit_config.toml,sha256=Id7klNaTibgWijXvNi7U8Zvqmt1-eb7vRMoVZz-VCNc,253
|
|
11
|
+
mini_toolkit/style/style.css,sha256=kZOOFW-hrVxKBE5cKiBO1eeMrrM12X3sCWdTgOYxXlo,5158
|
|
12
|
+
mini_toolkit/tools/__init__.py,sha256=4qFWYnLos7YC39ghfp2EcoQtxgtaRe8pWXpn3wpmjHU,85
|
|
13
|
+
mini_toolkit/tools/background_remover.py,sha256=S5J5uGOPCkmVPP1yCbNHpVOABOj3dKWP3JU3KBgfG18,2316
|
|
14
|
+
mini_toolkit/tools/change_tracker.py,sha256=81Oeef0up4lgd7SeW0MNJ4M2ILwFkdh123AVIZd3f7s,3530
|
|
15
|
+
mini_toolkit/tools/chat_alert.py,sha256=2KXW94DnjWWUXAD82uINNUzHK5yar-Kjaxx7W3Fi_Vg,1778
|
|
16
|
+
mini_toolkit/tools/color_picker.py,sha256=0_ti0osWwwOY1slXDMX9qrnPpOgOF0asySvsPPNn3WU,1435
|
|
17
|
+
mini_toolkit/tools/document_converter.py,sha256=kmAGAO2XqTdta80hkwhJTbtMPk2qQaCNXY7M_oZLDaU,4003
|
|
18
|
+
mini_toolkit/tools/file_compressor.py,sha256=4O0c-X4DUTKXizHX2fr1fAq690BQppovzEml93RntTM,2939
|
|
19
|
+
mini_toolkit/tools/github_trending.py,sha256=QfA8nxup1lLOnM6SG8Z4uhYY0oLa6N2gNNECcVSWOsA,2101
|
|
20
|
+
mini_toolkit/tools/hash_generator.py,sha256=SHE31moSoR5Vvv7aEjFTyGQyMuf6QS_oNckw-DaNCcI,1361
|
|
21
|
+
mini_toolkit/tools/image_converter.py,sha256=5OWaFKog-Iv7mIugKcwIcunA5kIwyiEIFYsMqwQKIM8,2344
|
|
22
|
+
mini_toolkit/tools/image_downloader.py,sha256=AQ6lKLNzdMYhbzjidShgCABwBvi4EobDc83hLeMkXGs,2362
|
|
23
|
+
mini_toolkit/tools/image_enhancer.py,sha256=QnqJAqacAQNgxKwHxJSbhAOHjDh6ehbC2uLEDeodGVg,2027
|
|
24
|
+
mini_toolkit/tools/image_watermarker.py,sha256=7jkSDuNmrPLmI2Mjt-DK38YHejjaoYAcQv6Ntj0WaPI,2483
|
|
25
|
+
mini_toolkit/tools/ocr.py,sha256=4oX0zNNvQPQpXD0L-cvBdqyYByDXS91IqaEd6LVE5BE,3310
|
|
26
|
+
mini_toolkit/tools/page_speed.py,sha256=APakz_ycPr8bOqdf0d-JvT6_8V1rVTX3EFMBEY7ARuw,1717
|
|
27
|
+
mini_toolkit/tools/password_checker.py,sha256=WBX5DP0F2FTij6i_NDrctMoLqeYjQIXlu0v0PkXgA5U,2200
|
|
28
|
+
mini_toolkit/tools/pdf_tools.py,sha256=AZdzDp0y8ztXMZ_rRo6ezUg77awrvxx8XAFR_n2zFM0,2786
|
|
29
|
+
mini_toolkit/tools/qr_code.py,sha256=cmVvofZOPdvcFkFrV0LPhYw9xW7JqNpaelmoR_TZMVY,3221
|
|
30
|
+
mini_toolkit/tools/resume_builder.py,sha256=TRLL399eLqbDz1X6MqP8YgKavYsizROh4qVL6DxtkKs,17597
|
|
31
|
+
mini_toolkit/tools/seo_health.py,sha256=8fwLPGqWDAEIsL72iDEJzDrZ9_ZnZRQ29SFWWFIU6_0,3269
|
|
32
|
+
mini_toolkit/tools/signature.py,sha256=pRJ13QJdOFovrpRDAQhcrlr4vVkaZVBCM4NcTLlo_FA,3996
|
|
33
|
+
mini_toolkit/tools/ssl_checker.py,sha256=bbCDGQ-WFwXIsA9FOZIqLFXu9ro2cXQ18ADQUsfS5oo,2551
|
|
34
|
+
mini_toolkit/tools/text_to_speech.py,sha256=r45zSSsiBpmocnPoveuvHedEKPcAq3iADEFIYTYnr1c,1187
|
|
35
|
+
mini_toolkit/tools/text_utilities.py,sha256=VYpNVyKA5GPl8VVxc9sGsR8wVrR_90Ai_pKyx8CqP9I,1400
|
|
36
|
+
mini_toolkit/tools/url_shortener.py,sha256=0Osk8H-pnVaOuVb2O3M7uyld8FLJDNIKkNcyoA_lAv0,970
|
|
37
|
+
mini_toolkit/tools/website_status.py,sha256=JvTs0nLdKHamLEBhaLOLJJJPNFnK8nPMMmokdodLGJ0,1450
|
|
38
|
+
streamlit_mini_toolkit-0.1.0.dist-info/METADATA,sha256=Z7dSbd2QTis5nnGLknif1VYuUA4vRoWTfkI_1jj5w00,5815
|
|
39
|
+
streamlit_mini_toolkit-0.1.0.dist-info/WHEEL,sha256=2iZrJkDIkeDh0k9SikKMqFuRP-ua6mb4Ir1AsER4BEw,87
|
|
40
|
+
streamlit_mini_toolkit-0.1.0.dist-info/entry_points.txt,sha256=_-pAJ0nnBJ8iWjUxMiqeg_9s6ZJgPlvVFTQhcSXy-Hw,55
|
|
41
|
+
streamlit_mini_toolkit-0.1.0.dist-info/licenses/LICENSE,sha256=ahCDv8oyJulKJT1dR0tAwVdV8igmw_DvQNd6JW1qfPg,1066
|
|
42
|
+
streamlit_mini_toolkit-0.1.0.dist-info/RECORD,,
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 Sarif Mia
|
|
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.
|