saycode-claude-swap 0.27.0b2__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.
- saycode_claude_swap-0.27.0b2/.github/FUNDING.yml +1 -0
- saycode_claude_swap-0.27.0b2/.github/ISSUE_TEMPLATE/bug_report.yml +47 -0
- saycode_claude_swap-0.27.0b2/.github/ISSUE_TEMPLATE/config.yml +5 -0
- saycode_claude_swap-0.27.0b2/.github/ISSUE_TEMPLATE/feature_request.yml +16 -0
- saycode_claude_swap-0.27.0b2/.github/workflows/ci.yml +82 -0
- saycode_claude_swap-0.27.0b2/.github/workflows/publish.yml +67 -0
- saycode_claude_swap-0.27.0b2/.gitignore +17 -0
- saycode_claude_swap-0.27.0b2/.python-version +1 -0
- saycode_claude_swap-0.27.0b2/.vscode/launch.json +60 -0
- saycode_claude_swap-0.27.0b2/LICENSE +21 -0
- saycode_claude_swap-0.27.0b2/PKG-INFO +434 -0
- saycode_claude_swap-0.27.0b2/README.md +403 -0
- saycode_claude_swap-0.27.0b2/assets/tui-watch.png +0 -0
- saycode_claude_swap-0.27.0b2/pyproject.toml +72 -0
- saycode_claude_swap-0.27.0b2/specs/integration-provenance.md +137 -0
- saycode_claude_swap-0.27.0b2/specs/token-runtime-contract.md +554 -0
- saycode_claude_swap-0.27.0b2/src/claude_swap/__init__.py +9 -0
- saycode_claude_swap-0.27.0b2/src/claude_swap/__main__.py +6 -0
- saycode_claude_swap-0.27.0b2/src/claude_swap/appearance.py +218 -0
- saycode_claude_swap-0.27.0b2/src/claude_swap/autoswitch.py +2376 -0
- saycode_claude_swap-0.27.0b2/src/claude_swap/cache.py +44 -0
- saycode_claude_swap-0.27.0b2/src/claude_swap/claude_locks.py +187 -0
- saycode_claude_swap-0.27.0b2/src/claude_swap/cli.py +1537 -0
- saycode_claude_swap-0.27.0b2/src/claude_swap/credentials.py +1849 -0
- saycode_claude_swap-0.27.0b2/src/claude_swap/exceptions.py +96 -0
- saycode_claude_swap-0.27.0b2/src/claude_swap/fsutil.py +101 -0
- saycode_claude_swap-0.27.0b2/src/claude_swap/json_output.py +363 -0
- saycode_claude_swap-0.27.0b2/src/claude_swap/launch_agent.py +289 -0
- saycode_claude_swap-0.27.0b2/src/claude_swap/locking.py +83 -0
- saycode_claude_swap-0.27.0b2/src/claude_swap/logging_config.py +64 -0
- saycode_claude_swap-0.27.0b2/src/claude_swap/macos_keychain.py +226 -0
- saycode_claude_swap-0.27.0b2/src/claude_swap/mappings.py +142 -0
- saycode_claude_swap-0.27.0b2/src/claude_swap/menubar.py +1057 -0
- saycode_claude_swap-0.27.0b2/src/claude_swap/migrations.py +537 -0
- saycode_claude_swap-0.27.0b2/src/claude_swap/models.py +231 -0
- saycode_claude_swap-0.27.0b2/src/claude_swap/oauth.py +812 -0
- saycode_claude_swap-0.27.0b2/src/claude_swap/org_probe.py +110 -0
- saycode_claude_swap-0.27.0b2/src/claude_swap/pace.py +161 -0
- saycode_claude_swap-0.27.0b2/src/claude_swap/paths.py +221 -0
- saycode_claude_swap-0.27.0b2/src/claude_swap/poll_policy.py +270 -0
- saycode_claude_swap-0.27.0b2/src/claude_swap/printer.py +232 -0
- saycode_claude_swap-0.27.0b2/src/claude_swap/process_detection.py +350 -0
- saycode_claude_swap-0.27.0b2/src/claude_swap/rotation_owner.py +352 -0
- saycode_claude_swap-0.27.0b2/src/claude_swap/session.py +1500 -0
- saycode_claude_swap-0.27.0b2/src/claude_swap/settings.py +488 -0
- saycode_claude_swap-0.27.0b2/src/claude_swap/snapshot_source.py +100 -0
- saycode_claude_swap-0.27.0b2/src/claude_swap/switcher.py +7530 -0
- saycode_claude_swap-0.27.0b2/src/claude_swap/token_probe.py +145 -0
- saycode_claude_swap-0.27.0b2/src/claude_swap/token_runtime.py +652 -0
- saycode_claude_swap-0.27.0b2/src/claude_swap/transfer.py +852 -0
- saycode_claude_swap-0.27.0b2/src/claude_swap/tui/__init__.py +43 -0
- saycode_claude_swap-0.27.0b2/src/claude_swap/tui/app.py +434 -0
- saycode_claude_swap-0.27.0b2/src/claude_swap/tui/autoview.py +331 -0
- saycode_claude_swap-0.27.0b2/src/claude_swap/tui/cswap.tcss +205 -0
- saycode_claude_swap-0.27.0b2/src/claude_swap/tui/dashboard.py +432 -0
- saycode_claude_swap-0.27.0b2/src/claude_swap/tui/data.py +194 -0
- saycode_claude_swap-0.27.0b2/src/claude_swap/tui/modals.py +159 -0
- saycode_claude_swap-0.27.0b2/src/claude_swap/tui/theme.py +141 -0
- saycode_claude_swap-0.27.0b2/src/claude_swap/tui/widgets.py +403 -0
- saycode_claude_swap-0.27.0b2/src/claude_swap/update_check.py +184 -0
- saycode_claude_swap-0.27.0b2/src/claude_swap/usage_store.py +1325 -0
- saycode_claude_swap-0.27.0b2/tests/__init__.py +1 -0
- saycode_claude_swap-0.27.0b2/tests/conftest.py +880 -0
- saycode_claude_swap-0.27.0b2/tests/fixtures/sample_config.json +10 -0
- saycode_claude_swap-0.27.0b2/tests/pack_token_runtime.py +162 -0
- saycode_claude_swap-0.27.0b2/tests/rotation_contention_worker.py +204 -0
- saycode_claude_swap-0.27.0b2/tests/test_add_account_identity.py +720 -0
- saycode_claude_swap-0.27.0b2/tests/test_api_key_accounts.py +1108 -0
- saycode_claude_swap-0.27.0b2/tests/test_appearance.py +331 -0
- saycode_claude_swap-0.27.0b2/tests/test_autoswitch.py +6896 -0
- saycode_claude_swap-0.27.0b2/tests/test_cache.py +72 -0
- saycode_claude_swap-0.27.0b2/tests/test_claude_locks.py +199 -0
- saycode_claude_swap-0.27.0b2/tests/test_cli.py +1816 -0
- saycode_claude_swap-0.27.0b2/tests/test_colour_cache_isolation.py +196 -0
- saycode_claude_swap-0.27.0b2/tests/test_config_cli.py +270 -0
- saycode_claude_swap-0.27.0b2/tests/test_credentials.py +273 -0
- saycode_claude_swap-0.27.0b2/tests/test_fsutil.py +286 -0
- saycode_claude_swap-0.27.0b2/tests/test_json_output.py +803 -0
- saycode_claude_swap-0.27.0b2/tests/test_launch_agent.py +396 -0
- saycode_claude_swap-0.27.0b2/tests/test_locking.py +162 -0
- saycode_claude_swap-0.27.0b2/tests/test_logging_config.py +59 -0
- saycode_claude_swap-0.27.0b2/tests/test_macos_keychain.py +212 -0
- saycode_claude_swap-0.27.0b2/tests/test_macos_keychain_contract.py +1202 -0
- saycode_claude_swap-0.27.0b2/tests/test_mappings.py +185 -0
- saycode_claude_swap-0.27.0b2/tests/test_menubar.py +619 -0
- saycode_claude_swap-0.27.0b2/tests/test_migrations.py +596 -0
- saycode_claude_swap-0.27.0b2/tests/test_move_accounts.py +578 -0
- saycode_claude_swap-0.27.0b2/tests/test_oauth.py +1534 -0
- saycode_claude_swap-0.27.0b2/tests/test_org_probe.py +167 -0
- saycode_claude_swap-0.27.0b2/tests/test_pace.py +169 -0
- saycode_claude_swap-0.27.0b2/tests/test_paths.py +316 -0
- saycode_claude_swap-0.27.0b2/tests/test_poll_policy.py +315 -0
- saycode_claude_swap-0.27.0b2/tests/test_printer.py +308 -0
- saycode_claude_swap-0.27.0b2/tests/test_process_detection.py +650 -0
- saycode_claude_swap-0.27.0b2/tests/test_real_store_guard.py +912 -0
- saycode_claude_swap-0.27.0b2/tests/test_rotation_contention.py +98 -0
- saycode_claude_swap-0.27.0b2/tests/test_rotation_owner.py +598 -0
- saycode_claude_swap-0.27.0b2/tests/test_session.py +2863 -0
- saycode_claude_swap-0.27.0b2/tests/test_settings.py +357 -0
- saycode_claude_swap-0.27.0b2/tests/test_swap_accounts.py +542 -0
- saycode_claude_swap-0.27.0b2/tests/test_switcher.py +12498 -0
- saycode_claude_swap-0.27.0b2/tests/test_theme.py +67 -0
- saycode_claude_swap-0.27.0b2/tests/test_token_probe.py +137 -0
- saycode_claude_swap-0.27.0b2/tests/test_token_runtime.py +390 -0
- saycode_claude_swap-0.27.0b2/tests/test_transfer.py +2470 -0
- saycode_claude_swap-0.27.0b2/tests/test_tui.py +1712 -0
- saycode_claude_swap-0.27.0b2/tests/test_update_check.py +351 -0
- saycode_claude_swap-0.27.0b2/tests/test_usage_store.py +1847 -0
- saycode_claude_swap-0.27.0b2/uv.lock +361 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
github: realiti4
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
name: Bug report
|
|
2
|
+
description: Something in cswap isn't working right
|
|
3
|
+
labels: [bug]
|
|
4
|
+
body:
|
|
5
|
+
- type: textarea
|
|
6
|
+
id: what-happened
|
|
7
|
+
attributes:
|
|
8
|
+
label: What happened?
|
|
9
|
+
description: What did you do, what did you see, and what did you expect instead?
|
|
10
|
+
placeholder: Ran `cswap switch 2`, got ... — expected ...
|
|
11
|
+
validations:
|
|
12
|
+
required: true
|
|
13
|
+
- type: input
|
|
14
|
+
id: version
|
|
15
|
+
attributes:
|
|
16
|
+
label: cswap version and install method
|
|
17
|
+
description: Output of `cswap --version`, and whether you installed with uv, pipx, or from source.
|
|
18
|
+
placeholder: cswap 0.20.0, installed with uv
|
|
19
|
+
validations:
|
|
20
|
+
required: true
|
|
21
|
+
- type: dropdown
|
|
22
|
+
id: os
|
|
23
|
+
attributes:
|
|
24
|
+
label: Operating system
|
|
25
|
+
description: Credentials are stored differently per platform, so this matters a lot.
|
|
26
|
+
options:
|
|
27
|
+
- macOS
|
|
28
|
+
- Linux
|
|
29
|
+
- Windows
|
|
30
|
+
- WSL
|
|
31
|
+
validations:
|
|
32
|
+
required: true
|
|
33
|
+
- type: dropdown
|
|
34
|
+
id: claude-code
|
|
35
|
+
attributes:
|
|
36
|
+
label: How do you run Claude Code?
|
|
37
|
+
multiple: true
|
|
38
|
+
options:
|
|
39
|
+
- CLI (terminal)
|
|
40
|
+
- VS Code extension
|
|
41
|
+
- Desktop app
|
|
42
|
+
- type: textarea
|
|
43
|
+
id: logs
|
|
44
|
+
attributes:
|
|
45
|
+
label: Command output or logs
|
|
46
|
+
description: Paste the failing command's output — `cswap list` for account-state issues, `cswap auto` log lines for auto-switch issues. Formatted automatically, no backticks needed. Please redact emails/account identifiers, and never paste access/refresh tokens, API keys, setup tokens, or credential-file/Keychain contents.
|
|
47
|
+
render: shell
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
name: Feature request
|
|
2
|
+
description: Suggest an improvement or new capability
|
|
3
|
+
labels: [enhancement]
|
|
4
|
+
body:
|
|
5
|
+
- type: textarea
|
|
6
|
+
id: problem
|
|
7
|
+
attributes:
|
|
8
|
+
label: What problem would this solve?
|
|
9
|
+
description: Describe the situation where you miss this feature — the workflow matters more than the mechanism.
|
|
10
|
+
validations:
|
|
11
|
+
required: true
|
|
12
|
+
- type: textarea
|
|
13
|
+
id: solution
|
|
14
|
+
attributes:
|
|
15
|
+
label: What would you like to happen?
|
|
16
|
+
description: A rough sketch is fine — commands, flags, behavior.
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
name: CI
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches: [main]
|
|
6
|
+
pull_request:
|
|
7
|
+
branches: [main]
|
|
8
|
+
|
|
9
|
+
jobs:
|
|
10
|
+
test:
|
|
11
|
+
runs-on: ubuntu-latest
|
|
12
|
+
|
|
13
|
+
steps:
|
|
14
|
+
- uses: actions/checkout@v4
|
|
15
|
+
|
|
16
|
+
# uv (not pip) so the PEP 735 dev dependency-group — pytest,
|
|
17
|
+
# pytest-asyncio — installs from the committed lockfile, same as local
|
|
18
|
+
# development.
|
|
19
|
+
- name: Install uv
|
|
20
|
+
uses: astral-sh/setup-uv@v6
|
|
21
|
+
with:
|
|
22
|
+
python-version: '3.12'
|
|
23
|
+
|
|
24
|
+
- name: Install dependencies
|
|
25
|
+
run: uv sync --locked
|
|
26
|
+
|
|
27
|
+
- name: Run tests
|
|
28
|
+
run: uv run pytest
|
|
29
|
+
|
|
30
|
+
test-windows:
|
|
31
|
+
runs-on: windows-latest
|
|
32
|
+
|
|
33
|
+
steps:
|
|
34
|
+
- uses: actions/checkout@v4
|
|
35
|
+
|
|
36
|
+
- name: Install uv
|
|
37
|
+
uses: astral-sh/setup-uv@v6
|
|
38
|
+
with:
|
|
39
|
+
python-version: '3.12'
|
|
40
|
+
|
|
41
|
+
- name: Install dependencies
|
|
42
|
+
run: uv sync --locked
|
|
43
|
+
|
|
44
|
+
- name: Run tests
|
|
45
|
+
# Includes the TUI tests: the Textual TUI (unlike the old curses one)
|
|
46
|
+
# runs on stock Windows, and this job is the proof.
|
|
47
|
+
run: uv run pytest
|
|
48
|
+
|
|
49
|
+
# The id stays `macos-keychain` although the job now runs everything: it is
|
|
50
|
+
# the name branch protection matches on, and renaming it silently drops the
|
|
51
|
+
# required check.
|
|
52
|
+
macos-keychain:
|
|
53
|
+
runs-on: macos-latest
|
|
54
|
+
|
|
55
|
+
steps:
|
|
56
|
+
- uses: actions/checkout@v4
|
|
57
|
+
|
|
58
|
+
- name: Install uv
|
|
59
|
+
uses: astral-sh/setup-uv@v6
|
|
60
|
+
with:
|
|
61
|
+
python-version: '3.12'
|
|
62
|
+
|
|
63
|
+
- name: Install dependencies
|
|
64
|
+
run: uv sync --locked
|
|
65
|
+
|
|
66
|
+
- name: Run the whole suite (not only the Keychain files)
|
|
67
|
+
# THE NARROW SELECTION WAS A BLIND SPOT, not a saving. Three cases
|
|
68
|
+
# failed on macOS -- one asserting the Linux XDG layout, two because a
|
|
69
|
+
# usable Keychain takes the write and leaves no `.enc` to chmod --
|
|
70
|
+
# while every job stayed green, because this job never ran them. A merge that
|
|
71
|
+
# restores a two-file selection here re-opens that hole invisibly:
|
|
72
|
+
# those cases pass now, they would simply stop running.
|
|
73
|
+
#
|
|
74
|
+
# faulthandler dumps every thread's stack past the budget, the only
|
|
75
|
+
# clue when a `security` call blocks on an invisible SecurityAgent
|
|
76
|
+
# dialog. While pyproject sets no faulthandler keys this `-o` is the
|
|
77
|
+
# only thing setting the budget and the dump does not abort; PR 287
|
|
78
|
+
# adds them repo-wide at the same 600, after which this is a no-op
|
|
79
|
+
# and the dump aborts the worker. `timeout-minutes` is the backstop
|
|
80
|
+
# that holds under either ordering.
|
|
81
|
+
timeout-minutes: 15
|
|
82
|
+
run: uv run pytest -o faulthandler_timeout=600
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
name: Publish to PyPI
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
release:
|
|
5
|
+
types: [published]
|
|
6
|
+
workflow_dispatch:
|
|
7
|
+
inputs:
|
|
8
|
+
version:
|
|
9
|
+
description: "Package version to publish (must match pyproject.toml)"
|
|
10
|
+
required: true
|
|
11
|
+
type: string
|
|
12
|
+
|
|
13
|
+
jobs:
|
|
14
|
+
publish:
|
|
15
|
+
runs-on: ubuntu-latest
|
|
16
|
+
environment: pypi
|
|
17
|
+
permissions:
|
|
18
|
+
id-token: write
|
|
19
|
+
|
|
20
|
+
steps:
|
|
21
|
+
- uses: actions/checkout@v4
|
|
22
|
+
|
|
23
|
+
- name: Resolve release version
|
|
24
|
+
id: version
|
|
25
|
+
env:
|
|
26
|
+
RELEASE_TAG: ${{ github.event.release.tag_name }}
|
|
27
|
+
DISPATCH_VERSION: ${{ inputs.version }}
|
|
28
|
+
run: |
|
|
29
|
+
set -eu
|
|
30
|
+
if [ -n "${RELEASE_TAG}" ]; then
|
|
31
|
+
version="${RELEASE_TAG#v}"
|
|
32
|
+
else
|
|
33
|
+
version="${DISPATCH_VERSION}"
|
|
34
|
+
fi
|
|
35
|
+
test -n "${version}"
|
|
36
|
+
echo "value=${version}" >> "${GITHUB_OUTPUT}"
|
|
37
|
+
|
|
38
|
+
- name: Verify package version
|
|
39
|
+
env:
|
|
40
|
+
EXPECTED_VERSION: ${{ steps.version.outputs.value }}
|
|
41
|
+
run: |
|
|
42
|
+
set -eu
|
|
43
|
+
actual="$(python - <<'PY'
|
|
44
|
+
import pathlib, re
|
|
45
|
+
|
|
46
|
+
text = pathlib.Path("pyproject.toml").read_text()
|
|
47
|
+
match = re.search(r'^version\s*=\s*[\"\']([^\"\']+)[\"\']$', text, re.MULTILINE)
|
|
48
|
+
if match is None:
|
|
49
|
+
raise SystemExit("pyproject.toml version is missing")
|
|
50
|
+
print(match.group(1))
|
|
51
|
+
PY
|
|
52
|
+
)"
|
|
53
|
+
test "${actual}" = "${EXPECTED_VERSION}"
|
|
54
|
+
|
|
55
|
+
- name: Set up Python
|
|
56
|
+
uses: actions/setup-python@v5
|
|
57
|
+
with:
|
|
58
|
+
python-version: '3.12'
|
|
59
|
+
|
|
60
|
+
- name: Install build dependencies
|
|
61
|
+
run: pip install build
|
|
62
|
+
|
|
63
|
+
- name: Build package
|
|
64
|
+
run: python -m build
|
|
65
|
+
|
|
66
|
+
- name: Publish to PyPI
|
|
67
|
+
uses: pypa/gh-action-pypi-publish@release/v1
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
# Python-generated files
|
|
2
|
+
__pycache__/
|
|
3
|
+
*.py[oc]
|
|
4
|
+
build/
|
|
5
|
+
dist/
|
|
6
|
+
wheels/
|
|
7
|
+
*.egg-info
|
|
8
|
+
|
|
9
|
+
# Virtual environments
|
|
10
|
+
.venv
|
|
11
|
+
|
|
12
|
+
# superpowers session planning artifacts (not part of the project)
|
|
13
|
+
docs/superpowers/
|
|
14
|
+
|
|
15
|
+
# Worktree-local dependency/tool caches are not distributable sources
|
|
16
|
+
.uv-cache/
|
|
17
|
+
.ruff_cache/
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
3.14
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": "0.2.0",
|
|
3
|
+
"configurations": [
|
|
4
|
+
{
|
|
5
|
+
"name": "cswap --list",
|
|
6
|
+
"type": "debugpy",
|
|
7
|
+
"request": "launch",
|
|
8
|
+
"module": "claude_swap.cli",
|
|
9
|
+
"args": ["--list"],
|
|
10
|
+
"cwd": "${workspaceFolder}",
|
|
11
|
+
"env": {
|
|
12
|
+
"PYTHONPATH": "${workspaceFolder}/src"
|
|
13
|
+
},
|
|
14
|
+
"console": "integratedTerminal"
|
|
15
|
+
},
|
|
16
|
+
{
|
|
17
|
+
"name": "cswap --switch",
|
|
18
|
+
"type": "debugpy",
|
|
19
|
+
"request": "launch",
|
|
20
|
+
"module": "claude_swap.cli",
|
|
21
|
+
"args": ["--switch"],
|
|
22
|
+
"cwd": "${workspaceFolder}",
|
|
23
|
+
"env": {
|
|
24
|
+
"PYTHONPATH": "${workspaceFolder}/src"
|
|
25
|
+
},
|
|
26
|
+
"console": "integratedTerminal"
|
|
27
|
+
},
|
|
28
|
+
{
|
|
29
|
+
"name": "cswap --purge",
|
|
30
|
+
"type": "debugpy",
|
|
31
|
+
"request": "launch",
|
|
32
|
+
"module": "claude_swap.cli",
|
|
33
|
+
"args": ["--purge"],
|
|
34
|
+
"cwd": "${workspaceFolder}",
|
|
35
|
+
"env": {
|
|
36
|
+
"PYTHONPATH": "${workspaceFolder}/src"
|
|
37
|
+
},
|
|
38
|
+
"console": "integratedTerminal"
|
|
39
|
+
},
|
|
40
|
+
{
|
|
41
|
+
"name": "cswap (custom args)",
|
|
42
|
+
"type": "debugpy",
|
|
43
|
+
"request": "launch",
|
|
44
|
+
"module": "claude_swap.cli",
|
|
45
|
+
"args": ["${input:cliArgs}"],
|
|
46
|
+
"cwd": "${workspaceFolder}",
|
|
47
|
+
"env": {
|
|
48
|
+
"PYTHONPATH": "${workspaceFolder}/src"
|
|
49
|
+
},
|
|
50
|
+
"console": "integratedTerminal"
|
|
51
|
+
}
|
|
52
|
+
],
|
|
53
|
+
"inputs": [
|
|
54
|
+
{
|
|
55
|
+
"id": "cliArgs",
|
|
56
|
+
"type": "promptString",
|
|
57
|
+
"description": "CLI arguments (e.g., --list, --status, --switch)"
|
|
58
|
+
}
|
|
59
|
+
]
|
|
60
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Onur Cetinkol
|
|
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.
|