witbitz-code 1.3.5__tar.gz → 1.3.6__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.
- {witbitz_code-1.3.5/src/witbitz_code.egg-info → witbitz_code-1.3.6}/PKG-INFO +2 -1
- {witbitz_code-1.3.5 → witbitz_code-1.3.6}/pyproject.toml +2 -2
- {witbitz_code-1.3.5 → witbitz_code-1.3.6}/src/witbitz_code/__init__.py +1 -1
- {witbitz_code-1.3.5 → witbitz_code-1.3.6}/src/witbitz_code/cli.py +1 -1
- {witbitz_code-1.3.5 → witbitz_code-1.3.6}/src/witbitz_code/opencode_plugins/witbitz-media-server.mjs +19 -10
- {witbitz_code-1.3.5 → witbitz_code-1.3.6}/src/witbitz_code/wizard.py +7 -3
- {witbitz_code-1.3.5 → witbitz_code-1.3.6/src/witbitz_code.egg-info}/PKG-INFO +2 -1
- {witbitz_code-1.3.5 → witbitz_code-1.3.6}/src/witbitz_code.egg-info/requires.txt +1 -0
- {witbitz_code-1.3.5 → witbitz_code-1.3.6}/tests/test_toolsetup.py +58 -0
- {witbitz_code-1.3.5 → witbitz_code-1.3.6}/LICENSE +0 -0
- {witbitz_code-1.3.5 → witbitz_code-1.3.6}/README.md +0 -0
- {witbitz_code-1.3.5 → witbitz_code-1.3.6}/setup.cfg +0 -0
- {witbitz_code-1.3.5 → witbitz_code-1.3.6}/src/witbitz_code/__main__.py +0 -0
- {witbitz_code-1.3.5 → witbitz_code-1.3.6}/src/witbitz_code/_js.py +0 -0
- {witbitz_code-1.3.5 → witbitz_code-1.3.6}/src/witbitz_code/account.py +0 -0
- {witbitz_code-1.3.5 → witbitz_code-1.3.6}/src/witbitz_code/asks.py +0 -0
- {witbitz_code-1.3.5 → witbitz_code-1.3.6}/src/witbitz_code/attachments.py +0 -0
- {witbitz_code-1.3.5 → witbitz_code-1.3.6}/src/witbitz_code/auto.py +0 -0
- {witbitz_code-1.3.5 → witbitz_code-1.3.6}/src/witbitz_code/auto_runner.py +0 -0
- {witbitz_code-1.3.5 → witbitz_code-1.3.6}/src/witbitz_code/codekeys.py +0 -0
- {witbitz_code-1.3.5 → witbitz_code-1.3.6}/src/witbitz_code/codetools.py +0 -0
- {witbitz_code-1.3.5 → witbitz_code-1.3.6}/src/witbitz_code/compress.py +0 -0
- {witbitz_code-1.3.5 → witbitz_code-1.3.6}/src/witbitz_code/computers.py +0 -0
- {witbitz_code-1.3.5 → witbitz_code-1.3.6}/src/witbitz_code/confidential.py +0 -0
- {witbitz_code-1.3.5 → witbitz_code-1.3.6}/src/witbitz_code/confidential_models.json +0 -0
- {witbitz_code-1.3.5 → witbitz_code-1.3.6}/src/witbitz_code/connector.py +0 -0
- {witbitz_code-1.3.5 → witbitz_code-1.3.6}/src/witbitz_code/devicelink.py +0 -0
- {witbitz_code-1.3.5 → witbitz_code-1.3.6}/src/witbitz_code/folders.py +0 -0
- {witbitz_code-1.3.5 → witbitz_code-1.3.6}/src/witbitz_code/gateway.py +0 -0
- {witbitz_code-1.3.5 → witbitz_code-1.3.6}/src/witbitz_code/keys.py +0 -0
- {witbitz_code-1.3.5 → witbitz_code-1.3.6}/src/witbitz_code/link.py +0 -0
- {witbitz_code-1.3.5 → witbitz_code-1.3.6}/src/witbitz_code/models.py +0 -0
- {witbitz_code-1.3.5 → witbitz_code-1.3.6}/src/witbitz_code/net.py +0 -0
- {witbitz_code-1.3.5 → witbitz_code-1.3.6}/src/witbitz_code/offered_models.json +0 -0
- {witbitz_code-1.3.5 → witbitz_code-1.3.6}/src/witbitz_code/opencode_plugins/notes-init.md +0 -0
- {witbitz_code-1.3.5 → witbitz_code-1.3.6}/src/witbitz_code/opencode_plugins/witbitz-notes.js +0 -0
- {witbitz_code-1.3.5 → witbitz_code-1.3.6}/src/witbitz_code/opencode_plugins/witbitz-progress.js +0 -0
- {witbitz_code-1.3.5 → witbitz_code-1.3.6}/src/witbitz_code/outputs.py +0 -0
- {witbitz_code-1.3.5 → witbitz_code-1.3.6}/src/witbitz_code/pair.py +0 -0
- {witbitz_code-1.3.5 → witbitz_code-1.3.6}/src/witbitz_code/pairings.py +0 -0
- {witbitz_code-1.3.5 → witbitz_code-1.3.6}/src/witbitz_code/payers.py +0 -0
- {witbitz_code-1.3.5 → witbitz_code-1.3.6}/src/witbitz_code/plugins.py +0 -0
- {witbitz_code-1.3.5 → witbitz_code-1.3.6}/src/witbitz_code/policy.py +0 -0
- {witbitz_code-1.3.5 → witbitz_code-1.3.6}/src/witbitz_code/ports.py +0 -0
- {witbitz_code-1.3.5 → witbitz_code-1.3.6}/src/witbitz_code/qr.py +0 -0
- {witbitz_code-1.3.5 → witbitz_code-1.3.6}/src/witbitz_code/receipt.py +0 -0
- {witbitz_code-1.3.5 → witbitz_code-1.3.6}/src/witbitz_code/relay.py +0 -0
- {witbitz_code-1.3.5 → witbitz_code-1.3.6}/src/witbitz_code/seen.py +0 -0
- {witbitz_code-1.3.5 → witbitz_code-1.3.6}/src/witbitz_code/tinfoil_read.py +0 -0
- {witbitz_code-1.3.5 → witbitz_code-1.3.6}/src/witbitz_code/tools_catalog.json +0 -0
- {witbitz_code-1.3.5 → witbitz_code-1.3.6}/src/witbitz_code/tools_probe.py +0 -0
- {witbitz_code-1.3.5 → witbitz_code-1.3.6}/src/witbitz_code/toolsetup.py +0 -0
- {witbitz_code-1.3.5 → witbitz_code-1.3.6}/src/witbitz_code/uninstall.py +0 -0
- {witbitz_code-1.3.5 → witbitz_code-1.3.6}/src/witbitz_code/winagent.py +0 -0
- {witbitz_code-1.3.5 → witbitz_code-1.3.6}/src/witbitz_code/winconsole.py +0 -0
- {witbitz_code-1.3.5 → witbitz_code-1.3.6}/src/witbitz_code.egg-info/SOURCES.txt +0 -0
- {witbitz_code-1.3.5 → witbitz_code-1.3.6}/src/witbitz_code.egg-info/dependency_links.txt +0 -0
- {witbitz_code-1.3.5 → witbitz_code-1.3.6}/src/witbitz_code.egg-info/entry_points.txt +0 -0
- {witbitz_code-1.3.5 → witbitz_code-1.3.6}/src/witbitz_code.egg-info/top_level.txt +0 -0
- {witbitz_code-1.3.5 → witbitz_code-1.3.6}/tests/test_asks.py +0 -0
- {witbitz_code-1.3.5 → witbitz_code-1.3.6}/tests/test_attachments.py +0 -0
- {witbitz_code-1.3.5 → witbitz_code-1.3.6}/tests/test_auto.py +0 -0
- {witbitz_code-1.3.5 → witbitz_code-1.3.6}/tests/test_cli.py +0 -0
- {witbitz_code-1.3.5 → witbitz_code-1.3.6}/tests/test_codekeys.py +0 -0
- {witbitz_code-1.3.5 → witbitz_code-1.3.6}/tests/test_codetools.py +0 -0
- {witbitz_code-1.3.5 → witbitz_code-1.3.6}/tests/test_confidential.py +0 -0
- {witbitz_code-1.3.5 → witbitz_code-1.3.6}/tests/test_connector_e2e.py +0 -0
- {witbitz_code-1.3.5 → witbitz_code-1.3.6}/tests/test_devicelink.py +0 -0
- {witbitz_code-1.3.5 → witbitz_code-1.3.6}/tests/test_files_and_compress.py +0 -0
- {witbitz_code-1.3.5 → witbitz_code-1.3.6}/tests/test_folders.py +0 -0
- {witbitz_code-1.3.5 → witbitz_code-1.3.6}/tests/test_outputs.py +0 -0
- {witbitz_code-1.3.5 → witbitz_code-1.3.6}/tests/test_pair_flows.py +0 -0
- {witbitz_code-1.3.5 → witbitz_code-1.3.6}/tests/test_plugins.py +0 -0
- {witbitz_code-1.3.5 → witbitz_code-1.3.6}/tests/test_policy.py +0 -0
- {witbitz_code-1.3.5 → witbitz_code-1.3.6}/tests/test_ports.py +0 -0
- {witbitz_code-1.3.5 → witbitz_code-1.3.6}/tests/test_registry.py +0 -0
- {witbitz_code-1.3.5 → witbitz_code-1.3.6}/tests/test_relay_codec.py +0 -0
- {witbitz_code-1.3.5 → witbitz_code-1.3.6}/tests/test_setup.py +0 -0
- {witbitz_code-1.3.5 → witbitz_code-1.3.6}/tests/test_tools_probe.py +0 -0
- {witbitz_code-1.3.5 → witbitz_code-1.3.6}/tests/test_uninstall.py +0 -0
- {witbitz_code-1.3.5 → witbitz_code-1.3.6}/tests/test_winagent.py +0 -0
- {witbitz_code-1.3.5 → witbitz_code-1.3.6}/tests/test_winconsole.py +0 -0
- {witbitz_code-1.3.5 → witbitz_code-1.3.6}/tests/test_windows_files.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: witbitz-code
|
|
3
|
-
Version: 1.3.
|
|
3
|
+
Version: 1.3.6
|
|
4
4
|
Summary: Reach OpenCode on this computer from the Witbitz Spaces Code section, through an end-to-end sealed relay.
|
|
5
5
|
Author: Witbitz
|
|
6
6
|
License-Expression: MIT
|
|
@@ -21,6 +21,7 @@ Requires-Dist: segno>=1.5
|
|
|
21
21
|
Requires-Dist: tinfoil<0.15,>=0.14
|
|
22
22
|
Provides-Extra: test
|
|
23
23
|
Requires-Dist: pytest>=8; extra == "test"
|
|
24
|
+
Requires-Dist: pyflakes>=3; extra == "test"
|
|
24
25
|
Dynamic: license-file
|
|
25
26
|
|
|
26
27
|
# witbitz-code
|
|
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "witbitz-code"
|
|
7
|
-
version = "1.3.
|
|
7
|
+
version = "1.3.6"
|
|
8
8
|
description = "Reach OpenCode on this computer from the Witbitz Spaces Code section, through an end-to-end sealed relay."
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
requires-python = ">=3.10"
|
|
@@ -29,7 +29,7 @@ dependencies = [
|
|
|
29
29
|
]
|
|
30
30
|
|
|
31
31
|
[project.optional-dependencies]
|
|
32
|
-
test = ["pytest>=8"]
|
|
32
|
+
test = ["pytest>=8", "pyflakes>=3"]
|
|
33
33
|
|
|
34
34
|
[project.urls]
|
|
35
35
|
Documentation = "https://witbitz.chat/docs/opencode.md"
|
|
@@ -26,7 +26,7 @@ import httpx
|
|
|
26
26
|
from . import __version__
|
|
27
27
|
from . import pair as pair_cmd
|
|
28
28
|
from . import pairings as pp
|
|
29
|
-
from . import codekeys, codetools, confidential, keys, models, plugins, policy, uninstall as uninstall_mod, winagent, winconsole, wizard
|
|
29
|
+
from . import codekeys, codetools, confidential, keys, models, plugins, policy, ports, toolsetup, uninstall as uninstall_mod, winagent, winconsole, wizard
|
|
30
30
|
from ._js import to_number, truthy
|
|
31
31
|
from .connector import pairings_for_port, start_connector
|
|
32
32
|
from .payers import SessionPayers
|
{witbitz_code-1.3.5 → witbitz_code-1.3.6}/src/witbitz_code/opencode_plugins/witbitz-media-server.mjs
RENAMED
|
@@ -719,26 +719,35 @@ export function parseSearchAnswer (data) { // == agent/tinfoilWebSearch.mjs pars
|
|
|
719
719
|
}
|
|
720
720
|
return { text, citations }
|
|
721
721
|
}
|
|
722
|
-
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
|
|
726
|
-
if (!apiKey) fail('web_search needs a Tinfoil key: TINFOIL_API_KEY is not set for this OpenCode (on a laptop it comes from ~/.opencode-server.env; a cloud computer gets it from its Sentinel)')
|
|
727
|
-
const url = env.WITBITZ_SEARCH_URL || `https://${SEARCH_HOST}${SEARCH_PATH}`
|
|
728
|
-
const body = {
|
|
722
|
+
/** The one Tinfoil web-search request, for a laptop (sent with the key) and for a cloud computer's Sentinel (which builds it
|
|
723
|
+
* from the query alone, so the key it holds cannot be spent on any other call — infra/cloud-computer/sentinel). */
|
|
724
|
+
export function searchRequest (query, { piiCheck = true } = {}) {
|
|
725
|
+
return {
|
|
729
726
|
model: SEARCH_MODEL,
|
|
730
727
|
messages: [
|
|
731
728
|
{ role: 'system', content: 'You are a web research assistant. Search the web and report what you find, briefly and factually, with dates. State plainly when sources disagree or when something has not happened yet. Do not speculate beyond what the sources say.' },
|
|
732
|
-
{ role: 'user', content:
|
|
729
|
+
{ role: 'user', content: query },
|
|
733
730
|
],
|
|
734
731
|
max_tokens: SEARCH_MAX_TOKENS,
|
|
735
732
|
reasoning_effort: SEARCH_REASONING_EFFORT,
|
|
736
733
|
web_search_options: {},
|
|
737
|
-
...(
|
|
734
|
+
...(piiCheck === false ? {} : { pii_check_options: {} }), // a query carrying personal data is refused before it leaves the enclave for the index
|
|
738
735
|
}
|
|
736
|
+
}
|
|
737
|
+
|
|
738
|
+
async function webSearch (a, { fetchImpl = fetch, env = process.env } = {}) {
|
|
739
|
+
const q = String((a && a.query) || '').replace(/\s+/g, ' ').trim().slice(0, 2000)
|
|
740
|
+
if (!q) fail('query is required')
|
|
741
|
+
const piiCheck = !(a && a.pii_check === false)
|
|
742
|
+
// A cloud computer holds no key: the query goes to its Credential Sentinel, which builds this same request with the key.
|
|
743
|
+
const viaSentinel = env.WITBITZ_SEARCH_SENTINEL
|
|
744
|
+
const apiKey = env.TINFOIL_API_KEY
|
|
745
|
+
if (!viaSentinel && !apiKey) fail('web_search needs a Tinfoil key: TINFOIL_API_KEY is not set for this OpenCode (on a laptop it comes from ~/.opencode-server.env; a cloud computer gets it from its Sentinel)')
|
|
746
|
+
const url = viaSentinel || env.WITBITZ_SEARCH_URL || `https://${SEARCH_HOST}${SEARCH_PATH}`
|
|
747
|
+
const body = viaSentinel ? { query: q, pii_check: piiCheck } : searchRequest(q, { piiCheck })
|
|
739
748
|
let data
|
|
740
749
|
try {
|
|
741
|
-
const res = await fetchImpl(url, { method: 'POST', headers: { 'content-type': 'application/json', authorization: `Bearer ${apiKey}` }, body: JSON.stringify(body), signal: AbortSignal.timeout(SEARCH_TIMEOUT_MS) })
|
|
750
|
+
const res = await fetchImpl(url, { method: 'POST', headers: { 'content-type': 'application/json', ...(viaSentinel ? {} : { authorization: `Bearer ${apiKey}` }) }, body: JSON.stringify(body), signal: AbortSignal.timeout(SEARCH_TIMEOUT_MS) })
|
|
742
751
|
if (!res.ok) fail(`the search endpoint answered ${res.status}`)
|
|
743
752
|
data = await res.json()
|
|
744
753
|
} catch (e) { fail(`could not search the web (${String((e && e.message) || e).slice(0, 160)})`) }
|
|
@@ -241,7 +241,7 @@ def _describe(step: dict) -> str:
|
|
|
241
241
|
|
|
242
242
|
|
|
243
243
|
async def _tools_step(d: Deps) -> str:
|
|
244
|
-
"""→ 'here' | 'installed' | 'partly' | 'skipped' | 'unavailable'."""
|
|
244
|
+
"""→ 'here' | 'installed' | 'partly' | 'skipped' | 'unavailable' | 'failed' (an install that breaks never ends setup)."""
|
|
245
245
|
try:
|
|
246
246
|
report = d.probe_tools()
|
|
247
247
|
except Exception: # noqa: BLE001 — a probe that fails never stops setup
|
|
@@ -262,8 +262,12 @@ async def _tools_step(d: Deps) -> str:
|
|
|
262
262
|
if not _yes(d.ask(" Install them now? [Y/n] ")):
|
|
263
263
|
d.say(" Skipped — run witbitz-code setup again to install them, or use the card in Code.")
|
|
264
264
|
return "skipped"
|
|
265
|
-
|
|
266
|
-
|
|
265
|
+
try:
|
|
266
|
+
d.run_tools(plan)
|
|
267
|
+
d.refresh_path()
|
|
268
|
+
except Exception as e: # noqa: BLE001 — the tools are a convenience: setup goes on to serve
|
|
269
|
+
d.say(f" Could not install them ({str(e)[:160]}) — setup goes on; \"Install with the agent\" in Code can try.")
|
|
270
|
+
return "failed"
|
|
267
271
|
try:
|
|
268
272
|
after = {t["id"] for t in toolsetup.missing_tools(d.probe_tools())}
|
|
269
273
|
except Exception: # noqa: BLE001
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: witbitz-code
|
|
3
|
-
Version: 1.3.
|
|
3
|
+
Version: 1.3.6
|
|
4
4
|
Summary: Reach OpenCode on this computer from the Witbitz Spaces Code section, through an end-to-end sealed relay.
|
|
5
5
|
Author: Witbitz
|
|
6
6
|
License-Expression: MIT
|
|
@@ -21,6 +21,7 @@ Requires-Dist: segno>=1.5
|
|
|
21
21
|
Requires-Dist: tinfoil<0.15,>=0.14
|
|
22
22
|
Provides-Extra: test
|
|
23
23
|
Requires-Dist: pytest>=8; extra == "test"
|
|
24
|
+
Requires-Dist: pyflakes>=3; extra == "test"
|
|
24
25
|
Dynamic: license-file
|
|
25
26
|
|
|
26
27
|
# witbitz-code
|
|
@@ -145,3 +145,61 @@ def test_no_package_manager_says_so_without_asking():
|
|
|
145
145
|
t = Tools(["jq"], {"os": "darwin", "pm": ""})
|
|
146
146
|
r, said = step(t, [])
|
|
147
147
|
assert r == "unavailable" and t.plans == [] and any("no package manager found" in s for s in said)
|
|
148
|
+
|
|
149
|
+
|
|
150
|
+
def test_an_install_that_breaks_never_ends_setup():
|
|
151
|
+
# 1.3.5 on Windows: cli.py never imported toolsetup, so the first "y" died "FATAL — name 'toolsetup' is not defined"
|
|
152
|
+
t = Tools(["jq"], {"os": "win32", "pm": "winget"})
|
|
153
|
+
|
|
154
|
+
def broken(plan: list) -> dict:
|
|
155
|
+
raise NameError("name 'toolsetup' is not defined")
|
|
156
|
+
|
|
157
|
+
t.run = broken # type: ignore[method-assign]
|
|
158
|
+
r, said = step(t, [""])
|
|
159
|
+
assert r == "failed"
|
|
160
|
+
assert any("Could not install them (name 'toolsetup' is not defined) — setup goes on" in s for s in said)
|
|
161
|
+
|
|
162
|
+
|
|
163
|
+
def test_setup_hands_the_wizard_the_real_installer_and_path_refresh(monkeypatch):
|
|
164
|
+
# the wizard's own tests fake run_tools/refresh_path, so only this one runs the lambdas cli.py builds
|
|
165
|
+
from witbitz_code import cli
|
|
166
|
+
|
|
167
|
+
seen: dict = {}
|
|
168
|
+
|
|
169
|
+
async def capture(d):
|
|
170
|
+
seen["d"] = d
|
|
171
|
+
return {"served": 0}
|
|
172
|
+
|
|
173
|
+
monkeypatch.setattr(wizard, "run_setup", capture)
|
|
174
|
+
asyncio.run(cli.setup([]))
|
|
175
|
+
seen["d"].refresh_path()
|
|
176
|
+
assert seen["d"].run_tools([]) == {"done": [], "failed": [], "auto": [], "none": []}
|
|
177
|
+
|
|
178
|
+
|
|
179
|
+
def test_no_module_uses_a_name_it_never_defined():
|
|
180
|
+
# pyflakes: the two missing imports that reached a release (ports in 1.3.3's serve, toolsetup in 1.3.5's setup)
|
|
181
|
+
from pathlib import Path
|
|
182
|
+
|
|
183
|
+
import pyflakes.api
|
|
184
|
+
import pyflakes.messages
|
|
185
|
+
|
|
186
|
+
import witbitz_code
|
|
187
|
+
|
|
188
|
+
class Undefined:
|
|
189
|
+
def __init__(self) -> None:
|
|
190
|
+
self.found: list[str] = []
|
|
191
|
+
|
|
192
|
+
def unexpectedError(self, filename, msg): # noqa: N802 — pyflakes' reporter interface
|
|
193
|
+
self.found.append(f"{filename}: {msg}")
|
|
194
|
+
|
|
195
|
+
def syntaxError(self, filename, msg, lineno, offset, text): # noqa: N802
|
|
196
|
+
self.found.append(f"{filename}:{lineno}: {msg}")
|
|
197
|
+
|
|
198
|
+
def flake(self, message):
|
|
199
|
+
if isinstance(message, pyflakes.messages.UndefinedName):
|
|
200
|
+
self.found.append(str(message))
|
|
201
|
+
|
|
202
|
+
rep = Undefined()
|
|
203
|
+
for f in sorted(Path(witbitz_code.__file__).parent.glob("*.py")):
|
|
204
|
+
pyflakes.api.check(f.read_text(encoding="utf-8"), str(f), rep)
|
|
205
|
+
assert rep.found == []
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{witbitz_code-1.3.5 → witbitz_code-1.3.6}/src/witbitz_code/opencode_plugins/witbitz-notes.js
RENAMED
|
File without changes
|
{witbitz_code-1.3.5 → witbitz_code-1.3.6}/src/witbitz_code/opencode_plugins/witbitz-progress.js
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|