webbee 0.3.30__tar.gz → 0.3.32__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.
- {webbee-0.3.30 → webbee-0.3.32}/CHANGELOG.md +14 -0
- {webbee-0.3.30 → webbee-0.3.32}/PKG-INFO +1 -1
- {webbee-0.3.30 → webbee-0.3.32}/pyproject.toml +1 -1
- webbee-0.3.32/src/webbee/__init__.py +1 -0
- {webbee-0.3.30 → webbee-0.3.32}/src/webbee/repl.py +22 -0
- webbee-0.3.32/src/webbee/urlopen.py +37 -0
- webbee-0.3.32/tests/test_urlopen.py +50 -0
- webbee-0.3.30/src/webbee/__init__.py +0 -1
- webbee-0.3.30/src/webbee/urlopen.py +0 -16
- webbee-0.3.30/tests/test_urlopen.py +0 -18
- {webbee-0.3.30 → webbee-0.3.32}/.github/workflows/publish.yml +0 -0
- {webbee-0.3.30 → webbee-0.3.32}/.gitignore +0 -0
- {webbee-0.3.30 → webbee-0.3.32}/LICENSE +0 -0
- {webbee-0.3.30 → webbee-0.3.32}/README.md +0 -0
- {webbee-0.3.30 → webbee-0.3.32}/docs/superpowers/plans/2026-07-21-interactive-home-dashboard.md +0 -0
- {webbee-0.3.30 → webbee-0.3.32}/install.sh +0 -0
- {webbee-0.3.30 → webbee-0.3.32}/src/webbee/account.py +0 -0
- {webbee-0.3.30 → webbee-0.3.32}/src/webbee/active_sessions.py +0 -0
- {webbee-0.3.30 → webbee-0.3.32}/src/webbee/banner_art.py +0 -0
- {webbee-0.3.30 → webbee-0.3.32}/src/webbee/boot.py +0 -0
- {webbee-0.3.30 → webbee-0.3.32}/src/webbee/checkpoints.py +0 -0
- {webbee-0.3.30 → webbee-0.3.32}/src/webbee/cli.py +0 -0
- {webbee-0.3.30 → webbee-0.3.32}/src/webbee/clipboard.py +0 -0
- {webbee-0.3.30 → webbee-0.3.32}/src/webbee/coding_context.py +0 -0
- {webbee-0.3.30 → webbee-0.3.32}/src/webbee/commands.py +0 -0
- {webbee-0.3.30 → webbee-0.3.32}/src/webbee/config.py +0 -0
- {webbee-0.3.30 → webbee-0.3.32}/src/webbee/consent.py +0 -0
- {webbee-0.3.30 → webbee-0.3.32}/src/webbee/details.py +0 -0
- {webbee-0.3.30 → webbee-0.3.32}/src/webbee/events.py +0 -0
- {webbee-0.3.30 → webbee-0.3.32}/src/webbee/frames.py +0 -0
- {webbee-0.3.30 → webbee-0.3.32}/src/webbee/home.py +0 -0
- {webbee-0.3.30 → webbee-0.3.32}/src/webbee/home_view.py +0 -0
- {webbee-0.3.30 → webbee-0.3.32}/src/webbee/http.py +0 -0
- {webbee-0.3.30 → webbee-0.3.32}/src/webbee/instance_lock.py +0 -0
- {webbee-0.3.30 → webbee-0.3.32}/src/webbee/intel/__init__.py +0 -0
- {webbee-0.3.30 → webbee-0.3.32}/src/webbee/intel/chunker.py +0 -0
- {webbee-0.3.30 → webbee-0.3.32}/src/webbee/intel/embed.py +0 -0
- {webbee-0.3.30 → webbee-0.3.32}/src/webbee/intel/graph.py +0 -0
- {webbee-0.3.30 → webbee-0.3.32}/src/webbee/intel/indexer.py +0 -0
- {webbee-0.3.30 → webbee-0.3.32}/src/webbee/intel/models.py +0 -0
- {webbee-0.3.30 → webbee-0.3.32}/src/webbee/intel/query.py +0 -0
- {webbee-0.3.30 → webbee-0.3.32}/src/webbee/intel/service.py +0 -0
- {webbee-0.3.30 → webbee-0.3.32}/src/webbee/intel/store.py +0 -0
- {webbee-0.3.30 → webbee-0.3.32}/src/webbee/intel/vectors.py +0 -0
- {webbee-0.3.30 → webbee-0.3.32}/src/webbee/intel/watch.py +0 -0
- {webbee-0.3.30 → webbee-0.3.32}/src/webbee/mode_store.py +0 -0
- {webbee-0.3.30 → webbee-0.3.32}/src/webbee/newtab_mode.py +0 -0
- {webbee-0.3.30 → webbee-0.3.32}/src/webbee/output_pane.py +0 -0
- {webbee-0.3.30 → webbee-0.3.32}/src/webbee/queue_panel.py +0 -0
- {webbee-0.3.30 → webbee-0.3.32}/src/webbee/reflow.py +0 -0
- {webbee-0.3.30 → webbee-0.3.32}/src/webbee/remote.py +0 -0
- {webbee-0.3.30 → webbee-0.3.32}/src/webbee/render.py +0 -0
- {webbee-0.3.30 → webbee-0.3.32}/src/webbee/repo.py +0 -0
- {webbee-0.3.30 → webbee-0.3.32}/src/webbee/selection.py +0 -0
- {webbee-0.3.30 → webbee-0.3.32}/src/webbee/session.py +0 -0
- {webbee-0.3.30 → webbee-0.3.32}/src/webbee/sessions.py +0 -0
- {webbee-0.3.30 → webbee-0.3.32}/src/webbee/sizing.py +0 -0
- {webbee-0.3.30 → webbee-0.3.32}/src/webbee/slots.py +0 -0
- {webbee-0.3.30 → webbee-0.3.32}/src/webbee/steer.py +0 -0
- {webbee-0.3.30 → webbee-0.3.32}/src/webbee/stream.py +0 -0
- {webbee-0.3.30 → webbee-0.3.32}/src/webbee/tabs.py +0 -0
- {webbee-0.3.30 → webbee-0.3.32}/src/webbee/thread.py +0 -0
- {webbee-0.3.30 → webbee-0.3.32}/src/webbee/todo_panel.py +0 -0
- {webbee-0.3.30 → webbee-0.3.32}/src/webbee/tokens.py +0 -0
- {webbee-0.3.30 → webbee-0.3.32}/src/webbee/tools.py +0 -0
- {webbee-0.3.30 → webbee-0.3.32}/src/webbee/tui.py +0 -0
- {webbee-0.3.30 → webbee-0.3.32}/src/webbee/update.py +0 -0
- {webbee-0.3.30 → webbee-0.3.32}/src/webbee/wallet.py +0 -0
- {webbee-0.3.30 → webbee-0.3.32}/src/webbee/worktrees.py +0 -0
- {webbee-0.3.30 → webbee-0.3.32}/tests/__init__.py +0 -0
- {webbee-0.3.30 → webbee-0.3.32}/tests/conftest.py +0 -0
- {webbee-0.3.30 → webbee-0.3.32}/tests/test_account.py +0 -0
- {webbee-0.3.30 → webbee-0.3.32}/tests/test_active_sessions.py +0 -0
- {webbee-0.3.30 → webbee-0.3.32}/tests/test_checkpoints.py +0 -0
- {webbee-0.3.30 → webbee-0.3.32}/tests/test_cli.py +0 -0
- {webbee-0.3.30 → webbee-0.3.32}/tests/test_clipboard.py +0 -0
- {webbee-0.3.30 → webbee-0.3.32}/tests/test_commands.py +0 -0
- {webbee-0.3.30 → webbee-0.3.32}/tests/test_config.py +0 -0
- {webbee-0.3.30 → webbee-0.3.32}/tests/test_cpc_contract_stable.py +0 -0
- {webbee-0.3.30 → webbee-0.3.32}/tests/test_details.py +0 -0
- {webbee-0.3.30 → webbee-0.3.32}/tests/test_events.py +0 -0
- {webbee-0.3.30 → webbee-0.3.32}/tests/test_freeze_fix.py +0 -0
- {webbee-0.3.30 → webbee-0.3.32}/tests/test_home.py +0 -0
- {webbee-0.3.30 → webbee-0.3.32}/tests/test_home_view.py +0 -0
- {webbee-0.3.30 → webbee-0.3.32}/tests/test_instance_lock.py +0 -0
- {webbee-0.3.30 → webbee-0.3.32}/tests/test_intel_chunker.py +0 -0
- {webbee-0.3.30 → webbee-0.3.32}/tests/test_intel_embed.py +0 -0
- {webbee-0.3.30 → webbee-0.3.32}/tests/test_intel_graph.py +0 -0
- {webbee-0.3.30 → webbee-0.3.32}/tests/test_intel_indexer.py +0 -0
- {webbee-0.3.30 → webbee-0.3.32}/tests/test_intel_no_numpy.py +0 -0
- {webbee-0.3.30 → webbee-0.3.32}/tests/test_intel_query.py +0 -0
- {webbee-0.3.30 → webbee-0.3.32}/tests/test_intel_service.py +0 -0
- {webbee-0.3.30 → webbee-0.3.32}/tests/test_intel_store.py +0 -0
- {webbee-0.3.30 → webbee-0.3.32}/tests/test_intel_vectors.py +0 -0
- {webbee-0.3.30 → webbee-0.3.32}/tests/test_intel_watch.py +0 -0
- {webbee-0.3.30 → webbee-0.3.32}/tests/test_marathon.py +0 -0
- {webbee-0.3.30 → webbee-0.3.32}/tests/test_mode_store.py +0 -0
- {webbee-0.3.30 → webbee-0.3.32}/tests/test_newtab_mode.py +0 -0
- {webbee-0.3.30 → webbee-0.3.32}/tests/test_packaging.py +0 -0
- {webbee-0.3.30 → webbee-0.3.32}/tests/test_reflow.py +0 -0
- {webbee-0.3.30 → webbee-0.3.32}/tests/test_render.py +0 -0
- {webbee-0.3.30 → webbee-0.3.32}/tests/test_repl.py +0 -0
- {webbee-0.3.30 → webbee-0.3.32}/tests/test_repo.py +0 -0
- {webbee-0.3.30 → webbee-0.3.32}/tests/test_session.py +0 -0
- {webbee-0.3.30 → webbee-0.3.32}/tests/test_sessions.py +0 -0
- {webbee-0.3.30 → webbee-0.3.32}/tests/test_sizing.py +0 -0
- {webbee-0.3.30 → webbee-0.3.32}/tests/test_slots.py +0 -0
- {webbee-0.3.30 → webbee-0.3.32}/tests/test_steer.py +0 -0
- {webbee-0.3.30 → webbee-0.3.32}/tests/test_stream.py +0 -0
- {webbee-0.3.30 → webbee-0.3.32}/tests/test_tabs.py +0 -0
- {webbee-0.3.30 → webbee-0.3.32}/tests/test_thread.py +0 -0
- {webbee-0.3.30 → webbee-0.3.32}/tests/test_todo_panel.py +0 -0
- {webbee-0.3.30 → webbee-0.3.32}/tests/test_tokens.py +0 -0
- {webbee-0.3.30 → webbee-0.3.32}/tests/test_tools.py +0 -0
- {webbee-0.3.30 → webbee-0.3.32}/tests/test_tui.py +0 -0
- {webbee-0.3.30 → webbee-0.3.32}/tests/test_tui_hardening.py +0 -0
- {webbee-0.3.30 → webbee-0.3.32}/tests/test_update.py +0 -0
- {webbee-0.3.30 → webbee-0.3.32}/tests/test_version.py +0 -0
- {webbee-0.3.30 → webbee-0.3.32}/tests/test_wallet.py +0 -0
- {webbee-0.3.30 → webbee-0.3.32}/tests/test_worktrees.py +0 -0
|
@@ -1,5 +1,19 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 0.3.32
|
|
4
|
+
|
|
5
|
+
- Fixed the screen getting scrambled by stray output from background helper
|
|
6
|
+
programs (a git credential helper on macOS, a browser on Linux, and the
|
|
7
|
+
like). Their output is now fully redirected to a log for the whole session,
|
|
8
|
+
so nothing but Webbee Code can draw on your terminal.
|
|
9
|
+
|
|
10
|
+
## 0.3.31
|
|
11
|
+
|
|
12
|
+
- Fixed a Linux bug where "Top up credits" / "Read our security" could dump a
|
|
13
|
+
browser's startup logs into the terminal and scramble the screen. The
|
|
14
|
+
browser now launches fully detached and silent; on a headless/SSH session
|
|
15
|
+
we simply show the link to copy.
|
|
16
|
+
|
|
3
17
|
## 0.3.30
|
|
4
18
|
|
|
5
19
|
- Removed the stray "◆ Home" title from the top of the Home screen — Home now
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
__version__ = "0.3.32"
|
|
@@ -1221,6 +1221,20 @@ async def run_repl(cfg, mode: str = "default", *, once: bool = False, sink=None,
|
|
|
1221
1221
|
# renderer. Restored the instant the dock exits (the transcript dump
|
|
1222
1222
|
# below writes to the REAL stdout).
|
|
1223
1223
|
_errlog = boot._open_dock_stderr_log()
|
|
1224
|
+
# OS-LEVEL redirect of fd 2, not just Python's sys.stderr object:
|
|
1225
|
+
# SUBPROCESSES inherit the real fd 2, so a `contextlib.redirect_stderr`
|
|
1226
|
+
# alone (Python-level) does NOT stop a child's stderr from hitting the
|
|
1227
|
+
# terminal and scrambling the diff-based renderer — a Linux browser's
|
|
1228
|
+
# MESA/GCM logs, a macOS `Python … MallocStackLogging` git-helper, etc.
|
|
1229
|
+
# dup2 sends ALL of it (children + C libs + fd-2 writes) to the same
|
|
1230
|
+
# log; the contextlib redirect below additionally covers Python-level
|
|
1231
|
+
# sys.stderr writers. Fail-soft: on any failure leave fd 2 untouched.
|
|
1232
|
+
_saved_stderr_fd = None
|
|
1233
|
+
try:
|
|
1234
|
+
_saved_stderr_fd = os.dup(2)
|
|
1235
|
+
os.dup2(_errlog.fileno(), 2)
|
|
1236
|
+
except (OSError, ValueError, AttributeError):
|
|
1237
|
+
_saved_stderr_fd = None
|
|
1224
1238
|
try:
|
|
1225
1239
|
with contextlib.redirect_stderr(_errlog):
|
|
1226
1240
|
from webbee import tui
|
|
@@ -1363,6 +1377,14 @@ async def run_repl(cfg, mode: str = "default", *, once: bool = False, sink=None,
|
|
|
1363
1377
|
except Exception:
|
|
1364
1378
|
ok = False
|
|
1365
1379
|
finally:
|
|
1380
|
+
# Restore the real fd 2 BEFORE the transcript dump / any later
|
|
1381
|
+
# console output, then close the log.
|
|
1382
|
+
if _saved_stderr_fd is not None:
|
|
1383
|
+
try:
|
|
1384
|
+
os.dup2(_saved_stderr_fd, 2)
|
|
1385
|
+
os.close(_saved_stderr_fd)
|
|
1386
|
+
except OSError:
|
|
1387
|
+
pass
|
|
1366
1388
|
try:
|
|
1367
1389
|
_errlog.close()
|
|
1368
1390
|
except Exception:
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
"""Best-effort URL opener (W5 Home: Top-up credits, Read security docs).
|
|
2
|
+
|
|
3
|
+
The browser is launched FULLY DETACHED and SILENCED — its own session, with
|
|
4
|
+
stdin/stdout/stderr all routed to /dev/null — so a chatty browser can NEVER
|
|
5
|
+
spew into and corrupt the full-screen terminal. (A real Ubuntu user clicked
|
|
6
|
+
"Top up credits" and Chrome's `MESA-LOADER` / GCM / lens-overlay JS logs
|
|
7
|
+
poured straight into the TUI, scrambling it — that inherited-fd path is what
|
|
8
|
+
this guards against.) On a pure SSH / headless Linux session there is no
|
|
9
|
+
browser to open, so we don't even try — the caller ALWAYS shows the URL as
|
|
10
|
+
copyable text, which is the reliable path there. Returns the URL unchanged so
|
|
11
|
+
the caller can display it; never raises, never blocks."""
|
|
12
|
+
from __future__ import annotations
|
|
13
|
+
|
|
14
|
+
import os
|
|
15
|
+
import subprocess
|
|
16
|
+
import sys
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
def open_url(url: str) -> str:
|
|
20
|
+
try:
|
|
21
|
+
if sys.platform == "darwin":
|
|
22
|
+
argv = ["open", url]
|
|
23
|
+
elif os.name == "nt":
|
|
24
|
+
argv = ["cmd", "/c", "start", "", url]
|
|
25
|
+
else:
|
|
26
|
+
# Linux / BSD: only attempt a launch when a graphical session is
|
|
27
|
+
# actually present. No DISPLAY/WAYLAND == SSH/headless == nothing
|
|
28
|
+
# to open (and nothing that could pollute the terminal).
|
|
29
|
+
if not (os.environ.get("DISPLAY") or os.environ.get("WAYLAND_DISPLAY")):
|
|
30
|
+
return url
|
|
31
|
+
argv = ["xdg-open", url]
|
|
32
|
+
devnull = subprocess.DEVNULL
|
|
33
|
+
subprocess.Popen(argv, stdin=devnull, stdout=devnull, stderr=devnull,
|
|
34
|
+
start_new_session=True)
|
|
35
|
+
except Exception:
|
|
36
|
+
pass
|
|
37
|
+
return url
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import os
|
|
2
|
+
import subprocess
|
|
3
|
+
import sys
|
|
4
|
+
|
|
5
|
+
import webbee.urlopen as urlopen
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
def test_open_url_launches_detached_and_silenced(monkeypatch):
|
|
9
|
+
# Force the darwin path so a launch is always attempted regardless of the
|
|
10
|
+
# test host, then assert the child's std streams are ALL silenced (so a
|
|
11
|
+
# chatty browser can't corrupt the TUI) and it's detached.
|
|
12
|
+
monkeypatch.setattr(sys, "platform", "darwin")
|
|
13
|
+
calls = {}
|
|
14
|
+
|
|
15
|
+
def fake_popen(argv, **kw):
|
|
16
|
+
calls["argv"] = argv
|
|
17
|
+
calls["kw"] = kw
|
|
18
|
+
return object()
|
|
19
|
+
|
|
20
|
+
monkeypatch.setattr(subprocess, "Popen", fake_popen)
|
|
21
|
+
out = urlopen.open_url("https://panel.imperal.io/ext/billing")
|
|
22
|
+
assert out == "https://panel.imperal.io/ext/billing"
|
|
23
|
+
assert "https://panel.imperal.io/ext/billing" in calls["argv"]
|
|
24
|
+
assert calls["kw"]["stdin"] == subprocess.DEVNULL
|
|
25
|
+
assert calls["kw"]["stdout"] == subprocess.DEVNULL
|
|
26
|
+
assert calls["kw"]["stderr"] == subprocess.DEVNULL
|
|
27
|
+
assert calls["kw"].get("start_new_session") is True
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
def test_open_url_skips_launch_on_headless_linux(monkeypatch):
|
|
31
|
+
# No DISPLAY/WAYLAND on Linux == SSH/headless: don't spawn anything, just
|
|
32
|
+
# return the URL for the caller to show as copyable text.
|
|
33
|
+
monkeypatch.setattr(sys, "platform", "linux")
|
|
34
|
+
monkeypatch.setattr(os, "name", "posix")
|
|
35
|
+
monkeypatch.delenv("DISPLAY", raising=False)
|
|
36
|
+
monkeypatch.delenv("WAYLAND_DISPLAY", raising=False)
|
|
37
|
+
called = []
|
|
38
|
+
monkeypatch.setattr(subprocess, "Popen", lambda *a, **k: called.append(1))
|
|
39
|
+
assert urlopen.open_url("https://x") == "https://x"
|
|
40
|
+
assert called == []
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
def test_open_url_never_raises(monkeypatch):
|
|
44
|
+
monkeypatch.setattr(sys, "platform", "darwin")
|
|
45
|
+
|
|
46
|
+
def boom(*a, **k):
|
|
47
|
+
raise RuntimeError("no opener")
|
|
48
|
+
|
|
49
|
+
monkeypatch.setattr(subprocess, "Popen", boom)
|
|
50
|
+
assert urlopen.open_url("https://x") == "https://x"
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
__version__ = "0.3.30"
|
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
"""Best-effort URL opener (W5 Home: Top-up credits, Read security docs).
|
|
2
|
-
There is no existing opener in the client -- this is the minimal one. On a
|
|
3
|
-
LOCAL machine `webbrowser.open` launches the default browser; over SSH (the
|
|
4
|
-
common Webbee Code case) it no-ops or fails, so the caller ALSO surfaces the
|
|
5
|
-
URL as copyable text. Returns the URL unchanged so the caller can show it;
|
|
6
|
-
never raises."""
|
|
7
|
-
from __future__ import annotations
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
def open_url(url: str) -> str:
|
|
11
|
-
try:
|
|
12
|
-
import webbrowser
|
|
13
|
-
webbrowser.open(url, new=2)
|
|
14
|
-
except Exception:
|
|
15
|
-
pass
|
|
16
|
-
return url
|
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
import webbee.urlopen as urlopen
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
def test_open_url_returns_url_and_calls_webbrowser(monkeypatch):
|
|
5
|
-
calls = []
|
|
6
|
-
import webbrowser
|
|
7
|
-
monkeypatch.setattr(webbrowser, "open", lambda u, new=2: calls.append(u))
|
|
8
|
-
out = urlopen.open_url("https://panel.imperal.io/billing")
|
|
9
|
-
assert out == "https://panel.imperal.io/billing"
|
|
10
|
-
assert calls == ["https://panel.imperal.io/billing"]
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
def test_open_url_never_raises(monkeypatch):
|
|
14
|
-
import webbrowser
|
|
15
|
-
def boom(*a, **k):
|
|
16
|
-
raise RuntimeError("no display")
|
|
17
|
-
monkeypatch.setattr(webbrowser, "open", boom)
|
|
18
|
-
assert urlopen.open_url("https://x") == "https://x"
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{webbee-0.3.30 → webbee-0.3.32}/docs/superpowers/plans/2026-07-21-interactive-home-dashboard.md
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
|
|
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
|
|
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
|