boost-skill-cli 1.0.56__tar.gz → 1.0.58__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.
- {boost_skill_cli-1.0.56 → boost_skill_cli-1.0.58}/PKG-INFO +1 -1
- {boost_skill_cli-1.0.56 → boost_skill_cli-1.0.58}/boost_cli/_version.py +2 -2
- {boost_skill_cli-1.0.56 → boost_skill_cli-1.0.58}/boost_cli/core/store.py +34 -4
- {boost_skill_cli-1.0.56 → boost_skill_cli-1.0.58}/boost_skill_cli.egg-info/PKG-INFO +1 -1
- {boost_skill_cli-1.0.56 → boost_skill_cli-1.0.58}/tests/unit/test_store.py +66 -0
- {boost_skill_cli-1.0.56 → boost_skill_cli-1.0.58}/.gitignore +0 -0
- {boost_skill_cli-1.0.56 → boost_skill_cli-1.0.58}/CLAUDE.md +0 -0
- {boost_skill_cli-1.0.56 → boost_skill_cli-1.0.58}/CONTRIBUTING.md +0 -0
- {boost_skill_cli-1.0.56 → boost_skill_cli-1.0.58}/LICENSE +0 -0
- {boost_skill_cli-1.0.56 → boost_skill_cli-1.0.58}/MANIFEST.in +0 -0
- {boost_skill_cli-1.0.56 → boost_skill_cli-1.0.58}/Makefile +0 -0
- {boost_skill_cli-1.0.56 → boost_skill_cli-1.0.58}/README.md +0 -0
- {boost_skill_cli-1.0.56 → boost_skill_cli-1.0.58}/SECURITY.md +0 -0
- {boost_skill_cli-1.0.56 → boost_skill_cli-1.0.58}/boost +0 -0
- {boost_skill_cli-1.0.56 → boost_skill_cli-1.0.58}/boost_cli/__init__.py +0 -0
- {boost_skill_cli-1.0.56 → boost_skill_cli-1.0.58}/boost_cli/__main__.py +0 -0
- {boost_skill_cli-1.0.56 → boost_skill_cli-1.0.58}/boost_cli/cli.py +0 -0
- {boost_skill_cli-1.0.56 → boost_skill_cli-1.0.58}/boost_cli/cliparse.py +0 -0
- {boost_skill_cli-1.0.56 → boost_skill_cli-1.0.58}/boost_cli/commands/__init__.py +0 -0
- {boost_skill_cli-1.0.56 → boost_skill_cli-1.0.58}/boost_cli/commands/bmad.py +0 -0
- {boost_skill_cli-1.0.56 → boost_skill_cli-1.0.58}/boost_cli/commands/configuration.py +0 -0
- {boost_skill_cli-1.0.56 → boost_skill_cli-1.0.58}/boost_cli/commands/discovery.py +0 -0
- {boost_skill_cli-1.0.56 → boost_skill_cli-1.0.58}/boost_cli/commands/hooks.py +0 -0
- {boost_skill_cli-1.0.56 → boost_skill_cli-1.0.58}/boost_cli/commands/info.py +0 -0
- {boost_skill_cli-1.0.56 → boost_skill_cli-1.0.58}/boost_cli/commands/intelligence.py +0 -0
- {boost_skill_cli-1.0.56 → boost_skill_cli-1.0.58}/boost_cli/commands/pkg.py +0 -0
- {boost_skill_cli-1.0.56 → boost_skill_cli-1.0.58}/boost_cli/commands/quality.py +0 -0
- {boost_skill_cli-1.0.56 → boost_skill_cli-1.0.58}/boost_cli/commands/taps.py +0 -0
- {boost_skill_cli-1.0.56 → boost_skill_cli-1.0.58}/boost_cli/commands/team.py +0 -0
- {boost_skill_cli-1.0.56 → boost_skill_cli-1.0.58}/boost_cli/core/__init__.py +0 -0
- {boost_skill_cli-1.0.56 → boost_skill_cli-1.0.58}/boost_cli/core/agents.py +0 -0
- {boost_skill_cli-1.0.56 → boost_skill_cli-1.0.58}/boost_cli/core/ai.py +0 -0
- {boost_skill_cli-1.0.56 → boost_skill_cli-1.0.58}/boost_cli/core/catalog.py +0 -0
- {boost_skill_cli-1.0.56 → boost_skill_cli-1.0.58}/boost_cli/core/claude_settings.py +0 -0
- {boost_skill_cli-1.0.56 → boost_skill_cli-1.0.58}/boost_cli/core/config.py +0 -0
- {boost_skill_cli-1.0.56 → boost_skill_cli-1.0.58}/boost_cli/core/dense.py +0 -0
- {boost_skill_cli-1.0.56 → boost_skill_cli-1.0.58}/boost_cli/core/embed.py +0 -0
- {boost_skill_cli-1.0.56 → boost_skill_cli-1.0.58}/boost_cli/core/frontmatter.py +0 -0
- {boost_skill_cli-1.0.56 → boost_skill_cli-1.0.58}/boost_cli/core/gitutil.py +0 -0
- {boost_skill_cli-1.0.56 → boost_skill_cli-1.0.58}/boost_cli/core/journal.py +0 -0
- {boost_skill_cli-1.0.56 → boost_skill_cli-1.0.58}/boost_cli/core/lockfile.py +0 -0
- {boost_skill_cli-1.0.56 → boost_skill_cli-1.0.58}/boost_cli/core/logs.py +0 -0
- {boost_skill_cli-1.0.56 → boost_skill_cli-1.0.58}/boost_cli/core/mcp.py +0 -0
- {boost_skill_cli-1.0.56 → boost_skill_cli-1.0.58}/boost_cli/core/output.py +0 -0
- {boost_skill_cli-1.0.56 → boost_skill_cli-1.0.58}/boost_cli/core/paths.py +0 -0
- {boost_skill_cli-1.0.56 → boost_skill_cli-1.0.58}/boost_cli/core/policy.py +0 -0
- {boost_skill_cli-1.0.56 → boost_skill_cli-1.0.58}/boost_cli/core/rag.py +0 -0
- {boost_skill_cli-1.0.56 → boost_skill_cli-1.0.58}/boost_cli/core/registry.py +0 -0
- {boost_skill_cli-1.0.56 → boost_skill_cli-1.0.58}/boost_cli/core/util.py +0 -0
- {boost_skill_cli-1.0.56 → boost_skill_cli-1.0.58}/boost_cli/data/registries.json +0 -0
- {boost_skill_cli-1.0.56 → boost_skill_cli-1.0.58}/boost_cli/errors.py +0 -0
- {boost_skill_cli-1.0.56 → boost_skill_cli-1.0.58}/boost_cli/spin.py +0 -0
- {boost_skill_cli-1.0.56 → boost_skill_cli-1.0.58}/boost_skill_cli.egg-info/SOURCES.txt +0 -0
- {boost_skill_cli-1.0.56 → boost_skill_cli-1.0.58}/boost_skill_cli.egg-info/dependency_links.txt +0 -0
- {boost_skill_cli-1.0.56 → boost_skill_cli-1.0.58}/boost_skill_cli.egg-info/entry_points.txt +0 -0
- {boost_skill_cli-1.0.56 → boost_skill_cli-1.0.58}/boost_skill_cli.egg-info/requires.txt +0 -0
- {boost_skill_cli-1.0.56 → boost_skill_cli-1.0.58}/boost_skill_cli.egg-info/top_level.txt +0 -0
- {boost_skill_cli-1.0.56 → boost_skill_cli-1.0.58}/docs/.claude/settings.local.json +0 -0
- {boost_skill_cli-1.0.56 → boost_skill_cli-1.0.58}/docs/DEBUGGING.md +0 -0
- {boost_skill_cli-1.0.56 → boost_skill_cli-1.0.58}/docs/demo.gif +0 -0
- {boost_skill_cli-1.0.56 → boost_skill_cli-1.0.58}/docs/demo.tape +0 -0
- {boost_skill_cli-1.0.56 → boost_skill_cli-1.0.58}/docs/design-roadmap.html +0 -0
- {boost_skill_cli-1.0.56 → boost_skill_cli-1.0.58}/docs/index.html +0 -0
- {boost_skill_cli-1.0.56 → boost_skill_cli-1.0.58}/docs/mcp-hub.html +0 -0
- {boost_skill_cli-1.0.56 → boost_skill_cli-1.0.58}/docs/rag-architecture.md +0 -0
- {boost_skill_cli-1.0.56 → boost_skill_cli-1.0.58}/docs/roadmap.html +0 -0
- {boost_skill_cli-1.0.56 → boost_skill_cli-1.0.58}/index.html +0 -0
- {boost_skill_cli-1.0.56 → boost_skill_cli-1.0.58}/pyproject.toml +0 -0
- {boost_skill_cli-1.0.56 → boost_skill_cli-1.0.58}/scripts/build_registries.py +0 -0
- {boost_skill_cli-1.0.56 → boost_skill_cli-1.0.58}/scripts/mutation_gate.py +0 -0
- {boost_skill_cli-1.0.56 → boost_skill_cli-1.0.58}/setup.cfg +0 -0
- {boost_skill_cli-1.0.56 → boost_skill_cli-1.0.58}/style/README.md +0 -0
- {boost_skill_cli-1.0.56 → boost_skill_cli-1.0.58}/style/boost.css +0 -0
- {boost_skill_cli-1.0.56 → boost_skill_cli-1.0.58}/style/boost.js +0 -0
- {boost_skill_cli-1.0.56 → boost_skill_cli-1.0.58}/style/demo.html +0 -0
- {boost_skill_cli-1.0.56 → boost_skill_cli-1.0.58}/tests/conftest.py +0 -0
- {boost_skill_cli-1.0.56 → boost_skill_cli-1.0.58}/tests/functional/test_cli_bmad.py +0 -0
- {boost_skill_cli-1.0.56 → boost_skill_cli-1.0.58}/tests/functional/test_cli_configuration.py +0 -0
- {boost_skill_cli-1.0.56 → boost_skill_cli-1.0.58}/tests/functional/test_cli_discovery.py +0 -0
- {boost_skill_cli-1.0.56 → boost_skill_cli-1.0.58}/tests/functional/test_cli_hooks.py +0 -0
- {boost_skill_cli-1.0.56 → boost_skill_cli-1.0.58}/tests/functional/test_cli_info.py +0 -0
- {boost_skill_cli-1.0.56 → boost_skill_cli-1.0.58}/tests/functional/test_cli_intelligence.py +0 -0
- {boost_skill_cli-1.0.56 → boost_skill_cli-1.0.58}/tests/functional/test_cli_pkg.py +0 -0
- {boost_skill_cli-1.0.56 → boost_skill_cli-1.0.58}/tests/functional/test_cli_quality.py +0 -0
- {boost_skill_cli-1.0.56 → boost_skill_cli-1.0.58}/tests/functional/test_cli_taps.py +0 -0
- {boost_skill_cli-1.0.56 → boost_skill_cli-1.0.58}/tests/functional/test_cli_team.py +0 -0
- {boost_skill_cli-1.0.56 → boost_skill_cli-1.0.58}/tests/functional/test_everyday_loop.py +0 -0
- {boost_skill_cli-1.0.56 → boost_skill_cli-1.0.58}/tests/make_fixture.py +0 -0
- {boost_skill_cli-1.0.56 → boost_skill_cli-1.0.58}/tests/smoke.sh +0 -0
- {boost_skill_cli-1.0.56 → boost_skill_cli-1.0.58}/tests/unit/test_agents.py +0 -0
- {boost_skill_cli-1.0.56 → boost_skill_cli-1.0.58}/tests/unit/test_ai.py +0 -0
- {boost_skill_cli-1.0.56 → boost_skill_cli-1.0.58}/tests/unit/test_catalog.py +0 -0
- {boost_skill_cli-1.0.56 → boost_skill_cli-1.0.58}/tests/unit/test_claude_settings.py +0 -0
- {boost_skill_cli-1.0.56 → boost_skill_cli-1.0.58}/tests/unit/test_cliparse.py +0 -0
- {boost_skill_cli-1.0.56 → boost_skill_cli-1.0.58}/tests/unit/test_config.py +0 -0
- {boost_skill_cli-1.0.56 → boost_skill_cli-1.0.58}/tests/unit/test_dense.py +0 -0
- {boost_skill_cli-1.0.56 → boost_skill_cli-1.0.58}/tests/unit/test_dense_fallback.py +0 -0
- {boost_skill_cli-1.0.56 → boost_skill_cli-1.0.58}/tests/unit/test_embed.py +0 -0
- {boost_skill_cli-1.0.56 → boost_skill_cli-1.0.58}/tests/unit/test_errors_and_cli_table.py +0 -0
- {boost_skill_cli-1.0.56 → boost_skill_cli-1.0.58}/tests/unit/test_frontmatter.py +0 -0
- {boost_skill_cli-1.0.56 → boost_skill_cli-1.0.58}/tests/unit/test_gitutil.py +0 -0
- {boost_skill_cli-1.0.56 → boost_skill_cli-1.0.58}/tests/unit/test_journal.py +0 -0
- {boost_skill_cli-1.0.56 → boost_skill_cli-1.0.58}/tests/unit/test_lockfile.py +0 -0
- {boost_skill_cli-1.0.56 → boost_skill_cli-1.0.58}/tests/unit/test_logs.py +0 -0
- {boost_skill_cli-1.0.56 → boost_skill_cli-1.0.58}/tests/unit/test_mcp.py +0 -0
- {boost_skill_cli-1.0.56 → boost_skill_cli-1.0.58}/tests/unit/test_mutation_hardening.py +0 -0
- {boost_skill_cli-1.0.56 → boost_skill_cli-1.0.58}/tests/unit/test_output.py +0 -0
- {boost_skill_cli-1.0.56 → boost_skill_cli-1.0.58}/tests/unit/test_paths.py +0 -0
- {boost_skill_cli-1.0.56 → boost_skill_cli-1.0.58}/tests/unit/test_policy.py +0 -0
- {boost_skill_cli-1.0.56 → boost_skill_cli-1.0.58}/tests/unit/test_rag.py +0 -0
- {boost_skill_cli-1.0.56 → boost_skill_cli-1.0.58}/tests/unit/test_registry.py +0 -0
- {boost_skill_cli-1.0.56 → boost_skill_cli-1.0.58}/tests/unit/test_spin.py +0 -0
- {boost_skill_cli-1.0.56 → boost_skill_cli-1.0.58}/tests/unit/test_token_parity.py +0 -0
- {boost_skill_cli-1.0.56 → boost_skill_cli-1.0.58}/tests/unit/test_util.py +0 -0
- {boost_skill_cli-1.0.56 → boost_skill_cli-1.0.58}/tests/unit/test_version.py +0 -0
|
@@ -18,7 +18,7 @@ version_tuple: tuple[int | str, ...]
|
|
|
18
18
|
commit_id: str | None
|
|
19
19
|
__commit_id__: str | None
|
|
20
20
|
|
|
21
|
-
__version__ = version = '1.0.
|
|
22
|
-
__version_tuple__ = version_tuple = (1, 0,
|
|
21
|
+
__version__ = version = '1.0.58'
|
|
22
|
+
__version_tuple__ = version_tuple = (1, 0, 58)
|
|
23
23
|
|
|
24
24
|
__commit_id__ = commit_id = None
|
|
@@ -5,8 +5,10 @@ install(): copy skill dir from a tap clone -> store, symlink into every
|
|
|
5
5
|
"""
|
|
6
6
|
from __future__ import annotations
|
|
7
7
|
|
|
8
|
+
import os
|
|
8
9
|
import re
|
|
9
10
|
import shutil
|
|
11
|
+
import tempfile
|
|
10
12
|
from dataclasses import dataclass, field
|
|
11
13
|
from pathlib import Path
|
|
12
14
|
from typing import Dict, List, Optional
|
|
@@ -76,10 +78,38 @@ def unlink_agents(name: str) -> List[str]:
|
|
|
76
78
|
|
|
77
79
|
|
|
78
80
|
def _copy_skill(src: Path, dest: Path) -> None:
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
81
|
+
"""Copy a skill tree into ``dest`` atomically.
|
|
82
|
+
|
|
83
|
+
The old rmtree-then-copytree left a window where a crash destroyed the
|
|
84
|
+
previous good copy before the new one finished — on a reinstall/upgrade the
|
|
85
|
+
skill would vanish while the lock file still referenced it, so store and
|
|
86
|
+
lock disagreed. Instead stage the full copy in a temp dir on the same
|
|
87
|
+
filesystem, then swap it in with directory renames: the existing copy stays
|
|
88
|
+
untouched until the new one is complete, the failure window shrinks to two
|
|
89
|
+
fast renames, and a failed swap rolls back to the original.
|
|
90
|
+
"""
|
|
91
|
+
dest = Path(dest)
|
|
92
|
+
dest.parent.mkdir(parents=True, exist_ok=True)
|
|
93
|
+
staged = Path(tempfile.mkdtemp(dir=str(dest.parent),
|
|
94
|
+
prefix="." + dest.name + ".tmp"))
|
|
95
|
+
backup = None
|
|
96
|
+
try:
|
|
97
|
+
shutil.copytree(
|
|
98
|
+
src, staged, dirs_exist_ok=True,
|
|
99
|
+
ignore=shutil.ignore_patterns(".git", "__pycache__", ".DS_Store"))
|
|
100
|
+
if dest.exists():
|
|
101
|
+
backup = staged.with_name(staged.name + ".old")
|
|
102
|
+
os.replace(dest, backup) # move the old copy aside (atomic)
|
|
103
|
+
os.replace(staged, dest) # swap the new copy in (atomic)
|
|
104
|
+
except BaseException:
|
|
105
|
+
if backup is not None and not dest.exists():
|
|
106
|
+
os.replace(backup, dest) # swap-in failed: restore the original
|
|
107
|
+
shutil.rmtree(staged, ignore_errors=True)
|
|
108
|
+
if backup is not None and backup.exists():
|
|
109
|
+
shutil.rmtree(backup, ignore_errors=True)
|
|
110
|
+
raise
|
|
111
|
+
if backup is not None:
|
|
112
|
+
shutil.rmtree(backup, ignore_errors=True)
|
|
83
113
|
|
|
84
114
|
|
|
85
115
|
def install(entry: dict, force: bool = False,
|
|
@@ -423,3 +423,69 @@ class TestSyncApply:
|
|
|
423
423
|
|
|
424
424
|
def test_nothing_to_do_no_actions(self, brainstorming):
|
|
425
425
|
assert store.sync_apply(store.sync_plan()) == []
|
|
426
|
+
|
|
427
|
+
|
|
428
|
+
class TestCopySkillAtomic:
|
|
429
|
+
def _mkskill(self, root, name, body="v1"):
|
|
430
|
+
d = root / name
|
|
431
|
+
d.mkdir(parents=True)
|
|
432
|
+
(d / "SKILL.md").write_text(body)
|
|
433
|
+
return d
|
|
434
|
+
|
|
435
|
+
def _leftovers(self, parent, keep):
|
|
436
|
+
return sorted(p.name for p in parent.iterdir() if p.name != keep)
|
|
437
|
+
|
|
438
|
+
def test_fresh_copy(self, tmp_path):
|
|
439
|
+
src = self._mkskill(tmp_path / "src", "sk")
|
|
440
|
+
(src / ".git").mkdir()
|
|
441
|
+
(src / ".git" / "cfg").write_text("junk")
|
|
442
|
+
dest = tmp_path / "store" / "sk"
|
|
443
|
+
store._copy_skill(src, dest)
|
|
444
|
+
assert (dest / "SKILL.md").read_text() == "v1"
|
|
445
|
+
assert not (dest / ".git").exists() # ignore patterns honoured
|
|
446
|
+
assert self._leftovers(dest.parent, "sk") == [] # no temp/backup dirs
|
|
447
|
+
|
|
448
|
+
def test_reinstall_replaces_and_cleans_up(self, tmp_path):
|
|
449
|
+
src1 = self._mkskill(tmp_path / "s1", "sk", body="old")
|
|
450
|
+
dest = tmp_path / "store" / "sk"
|
|
451
|
+
store._copy_skill(src1, dest)
|
|
452
|
+
src2 = self._mkskill(tmp_path / "s2", "sk", body="new")
|
|
453
|
+
store._copy_skill(src2, dest)
|
|
454
|
+
assert (dest / "SKILL.md").read_text() == "new"
|
|
455
|
+
assert self._leftovers(dest.parent, "sk") == []
|
|
456
|
+
|
|
457
|
+
def test_swap_in_failure_rolls_back_to_original(self, tmp_path, monkeypatch):
|
|
458
|
+
src1 = self._mkskill(tmp_path / "s1", "sk", body="original")
|
|
459
|
+
dest = tmp_path / "store" / "sk"
|
|
460
|
+
store._copy_skill(src1, dest) # dest now holds the good copy
|
|
461
|
+
src2 = self._mkskill(tmp_path / "s2", "sk", body="broken")
|
|
462
|
+
|
|
463
|
+
real = store.os.replace
|
|
464
|
+
calls = {"n": 0}
|
|
465
|
+
|
|
466
|
+
def flaky(a, b):
|
|
467
|
+
calls["n"] += 1
|
|
468
|
+
if calls["n"] == 2: # the swap-IN of the new copy
|
|
469
|
+
raise OSError("swap failed")
|
|
470
|
+
return real(a, b)
|
|
471
|
+
|
|
472
|
+
monkeypatch.setattr(store.os, "replace", flaky)
|
|
473
|
+
with pytest.raises(OSError, match="swap failed"):
|
|
474
|
+
store._copy_skill(src2, dest)
|
|
475
|
+
# original survives intact, nothing half-swapped, no debris
|
|
476
|
+
assert (dest / "SKILL.md").read_text() == "original"
|
|
477
|
+
assert self._leftovers(dest.parent, "sk") == []
|
|
478
|
+
|
|
479
|
+
def test_copytree_failure_preserves_existing(self, tmp_path, monkeypatch):
|
|
480
|
+
src1 = self._mkskill(tmp_path / "s1", "sk", body="original")
|
|
481
|
+
dest = tmp_path / "store" / "sk"
|
|
482
|
+
store._copy_skill(src1, dest)
|
|
483
|
+
|
|
484
|
+
def boom(*a, **k):
|
|
485
|
+
raise OSError("copy failed")
|
|
486
|
+
|
|
487
|
+
monkeypatch.setattr(store.shutil, "copytree", boom)
|
|
488
|
+
with pytest.raises(OSError, match="copy failed"):
|
|
489
|
+
store._copy_skill(tmp_path / "s1" / "sk", dest)
|
|
490
|
+
assert (dest / "SKILL.md").read_text() == "original"
|
|
491
|
+
assert self._leftovers(dest.parent, "sk") == []
|
|
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
|
{boost_skill_cli-1.0.56 → boost_skill_cli-1.0.58}/boost_skill_cli.egg-info/dependency_links.txt
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
|
{boost_skill_cli-1.0.56 → boost_skill_cli-1.0.58}/tests/functional/test_cli_configuration.py
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
|