alterdb 0.2.2__tar.gz → 0.2.3__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.
- {alterdb-0.2.2 → alterdb-0.2.3}/CHANGELOG.md +59 -0
- {alterdb-0.2.2 → alterdb-0.2.3}/PKG-INFO +1 -1
- {alterdb-0.2.2 → alterdb-0.2.3}/pyproject.toml +1 -1
- {alterdb-0.2.2 → alterdb-0.2.3}/src/alter/generators/_surgical.py +37 -6
- {alterdb-0.2.2 → alterdb-0.2.3}/src/alter/mcp_server.py +16 -2
- {alterdb-0.2.2 → alterdb-0.2.3}/.env.example +0 -0
- {alterdb-0.2.2 → alterdb-0.2.3}/.gitignore +0 -0
- {alterdb-0.2.2 → alterdb-0.2.3}/.python-version +0 -0
- {alterdb-0.2.2 → alterdb-0.2.3}/LICENSE +0 -0
- {alterdb-0.2.2 → alterdb-0.2.3}/README.md +0 -0
- {alterdb-0.2.2 → alterdb-0.2.3}/docker-compose.yml +0 -0
- {alterdb-0.2.2 → alterdb-0.2.3}/docs/Canvas.png +0 -0
- {alterdb-0.2.2 → alterdb-0.2.3}/examples/saas-starter/alembic/alembic.ini +0 -0
- {alterdb-0.2.2 → alterdb-0.2.3}/examples/saas-starter/alembic/env.py +0 -0
- {alterdb-0.2.2 → alterdb-0.2.3}/examples/saas-starter/alembic/script.py.mako +0 -0
- {alterdb-0.2.2 → alterdb-0.2.3}/examples/saas-starter/app/__init__.py +0 -0
- {alterdb-0.2.2 → alterdb-0.2.3}/examples/saas-starter/app/database.py +0 -0
- {alterdb-0.2.2 → alterdb-0.2.3}/examples/saas-starter/app/enums.py +0 -0
- {alterdb-0.2.2 → alterdb-0.2.3}/examples/saas-starter/app/main.py +0 -0
- {alterdb-0.2.2 → alterdb-0.2.3}/examples/saas-starter/app/models/parents.py +0 -0
- {alterdb-0.2.2 → alterdb-0.2.3}/examples/saas-starter/app/models/starter.py +0 -0
- {alterdb-0.2.2 → alterdb-0.2.3}/examples/saas-starter/pyproject.toml +0 -0
- {alterdb-0.2.2 → alterdb-0.2.3}/examples/saas-starter/tests/__init__.py +0 -0
- {alterdb-0.2.2 → alterdb-0.2.3}/examples/saas-starter/tests/test_integration.py +0 -0
- {alterdb-0.2.2 → alterdb-0.2.3}/examples/saas-starter/tests/test_round_trip.py +0 -0
- {alterdb-0.2.2 → alterdb-0.2.3}/src/alter/__init__.py +0 -0
- {alterdb-0.2.2 → alterdb-0.2.3}/src/alter/canvas/__init__.py +0 -0
- {alterdb-0.2.2 → alterdb-0.2.3}/src/alter/canvas/server.py +0 -0
- {alterdb-0.2.2 → alterdb-0.2.3}/src/alter/canvas/static/canvas.js +0 -0
- {alterdb-0.2.2 → alterdb-0.2.3}/src/alter/canvas/static/index.html +0 -0
- {alterdb-0.2.2 → alterdb-0.2.3}/src/alter/canvas/static/style.css +0 -0
- {alterdb-0.2.2 → alterdb-0.2.3}/src/alter/cli.py +0 -0
- {alterdb-0.2.2 → alterdb-0.2.3}/src/alter/data/demo_schema.alter +0 -0
- {alterdb-0.2.2 → alterdb-0.2.3}/src/alter/diff.py +0 -0
- {alterdb-0.2.2 → alterdb-0.2.3}/src/alter/diff_format.py +0 -0
- {alterdb-0.2.2 → alterdb-0.2.3}/src/alter/errors.py +0 -0
- {alterdb-0.2.2 → alterdb-0.2.3}/src/alter/exporters/__init__.py +0 -0
- {alterdb-0.2.2 → alterdb-0.2.3}/src/alter/exporters/alter_file.py +0 -0
- {alterdb-0.2.2 → alterdb-0.2.3}/src/alter/exporters/mermaid.py +0 -0
- {alterdb-0.2.2 → alterdb-0.2.3}/src/alter/exporters/sql.py +0 -0
- {alterdb-0.2.2 → alterdb-0.2.3}/src/alter/generators/__init__.py +0 -0
- {alterdb-0.2.2 → alterdb-0.2.3}/src/alter/generators/base.py +0 -0
- {alterdb-0.2.2 → alterdb-0.2.3}/src/alter/generators/sqlalchemy.py +0 -0
- {alterdb-0.2.2 → alterdb-0.2.3}/src/alter/generators/sqlmodel.py +0 -0
- {alterdb-0.2.2 → alterdb-0.2.3}/src/alter/importers/__init__.py +0 -0
- {alterdb-0.2.2 → alterdb-0.2.3}/src/alter/importers/alter_file.py +0 -0
- {alterdb-0.2.2 → alterdb-0.2.3}/src/alter/importers/database.py +0 -0
- {alterdb-0.2.2 → alterdb-0.2.3}/src/alter/importers/sql.py +0 -0
- {alterdb-0.2.2 → alterdb-0.2.3}/src/alter/layout.py +0 -0
- {alterdb-0.2.2 → alterdb-0.2.3}/src/alter/merge_driver.py +0 -0
- {alterdb-0.2.2 → alterdb-0.2.3}/src/alter/parsers/__init__.py +0 -0
- {alterdb-0.2.2 → alterdb-0.2.3}/src/alter/parsers/base.py +0 -0
- {alterdb-0.2.2 → alterdb-0.2.3}/src/alter/parsers/sqlalchemy.py +0 -0
- {alterdb-0.2.2 → alterdb-0.2.3}/src/alter/parsers/sqlmodel.py +0 -0
- {alterdb-0.2.2 → alterdb-0.2.3}/src/alter/schema.py +0 -0
- {alterdb-0.2.2 → alterdb-0.2.3}/src/alter/staging.py +0 -0
- {alterdb-0.2.2 → alterdb-0.2.3}/src/alter/templates/auth.alter +0 -0
- {alterdb-0.2.2 → alterdb-0.2.3}/src/alter/templates/cms.alter +0 -0
- {alterdb-0.2.2 → alterdb-0.2.3}/src/alter/templates/ecommerce.alter +0 -0
- {alterdb-0.2.2 → alterdb-0.2.3}/src/alter/templates/saas-base.alter +0 -0
- {alterdb-0.2.2 → alterdb-0.2.3}/src/alter/types.py +0 -0
- {alterdb-0.2.2 → alterdb-0.2.3}/src/alter/validate.py +0 -0
- {alterdb-0.2.2 → alterdb-0.2.3}/src/alterdb/__init__.py +0 -0
- {alterdb-0.2.2 → alterdb-0.2.3}/templates/auth.alter +0 -0
- {alterdb-0.2.2 → alterdb-0.2.3}/templates/cms.alter +0 -0
- {alterdb-0.2.2 → alterdb-0.2.3}/templates/ecommerce.alter +0 -0
- {alterdb-0.2.2 → alterdb-0.2.3}/templates/saas-base.alter +0 -0
- {alterdb-0.2.2 → alterdb-0.2.3}/tests/__init__.py +0 -0
- {alterdb-0.2.2 → alterdb-0.2.3}/tests/conftest.py +0 -0
- {alterdb-0.2.2 → alterdb-0.2.3}/tests/fixtures/__init__.py +0 -0
- {alterdb-0.2.2 → alterdb-0.2.3}/tests/fixtures/sqlalchemy_models.py +0 -0
- {alterdb-0.2.2 → alterdb-0.2.3}/tests/test_alembic_wrapper.py +0 -0
- {alterdb-0.2.2 → alterdb-0.2.3}/tests/test_bug10_sa_column_type.py +0 -0
- {alterdb-0.2.2 → alterdb-0.2.3}/tests/test_bug17_apply_preserve.py +0 -0
- {alterdb-0.2.2 → alterdb-0.2.3}/tests/test_bug6_list_any_json.py +0 -0
- {alterdb-0.2.2 → alterdb-0.2.3}/tests/test_bug7_table_args.py +0 -0
- {alterdb-0.2.2 → alterdb-0.2.3}/tests/test_bug7_unreferenced_enums.py +0 -0
- {alterdb-0.2.2 → alterdb-0.2.3}/tests/test_bug8_surgical_preserve.py +0 -0
- {alterdb-0.2.2 → alterdb-0.2.3}/tests/test_bug_table_args_tuple.py +0 -0
- {alterdb-0.2.2 → alterdb-0.2.3}/tests/test_bugs_v013.py +0 -0
- {alterdb-0.2.2 → alterdb-0.2.3}/tests/test_canvas_actions.py +0 -0
- {alterdb-0.2.2 → alterdb-0.2.3}/tests/test_canvas_cors.py +0 -0
- {alterdb-0.2.2 → alterdb-0.2.3}/tests/test_cli.py +0 -0
- {alterdb-0.2.2 → alterdb-0.2.3}/tests/test_diff.py +0 -0
- {alterdb-0.2.2 → alterdb-0.2.3}/tests/test_e2e.py +0 -0
- {alterdb-0.2.2 → alterdb-0.2.3}/tests/test_enum_routing.py +0 -0
- {alterdb-0.2.2 → alterdb-0.2.3}/tests/test_exporters.py +0 -0
- {alterdb-0.2.2 → alterdb-0.2.3}/tests/test_generator_sqlalchemy.py +0 -0
- {alterdb-0.2.2 → alterdb-0.2.3}/tests/test_generator_sqlmodel.py +0 -0
- {alterdb-0.2.2 → alterdb-0.2.3}/tests/test_importer_database.py +0 -0
- {alterdb-0.2.2 → alterdb-0.2.3}/tests/test_importers.py +0 -0
- {alterdb-0.2.2 → alterdb-0.2.3}/tests/test_layout.py +0 -0
- {alterdb-0.2.2 → alterdb-0.2.3}/tests/test_mcp_server.py +0 -0
- {alterdb-0.2.2 → alterdb-0.2.3}/tests/test_merge_driver.py +0 -0
- {alterdb-0.2.2 → alterdb-0.2.3}/tests/test_migration_sql.py +0 -0
- {alterdb-0.2.2 → alterdb-0.2.3}/tests/test_parser_sqlalchemy.py +0 -0
- {alterdb-0.2.2 → alterdb-0.2.3}/tests/test_parser_sqlmodel.py +0 -0
- {alterdb-0.2.2 → alterdb-0.2.3}/tests/test_round_trip.py +0 -0
- {alterdb-0.2.2 → alterdb-0.2.3}/tests/test_schema.py +0 -0
- {alterdb-0.2.2 → alterdb-0.2.3}/tests/test_smoke.py +0 -0
- {alterdb-0.2.2 → alterdb-0.2.3}/tests/test_staging.py +0 -0
- {alterdb-0.2.2 → alterdb-0.2.3}/tests/test_surgical.py +0 -0
- {alterdb-0.2.2 → alterdb-0.2.3}/tests/test_sync_from_code.py +0 -0
- {alterdb-0.2.2 → alterdb-0.2.3}/tests/test_types.py +0 -0
- {alterdb-0.2.2 → alterdb-0.2.3}/tests/test_validate.py +0 -0
- {alterdb-0.2.2 → alterdb-0.2.3}/uv.lock +0 -0
|
@@ -2,6 +2,65 @@
|
|
|
2
2
|
|
|
3
3
|
All notable changes to Alter are documented here.
|
|
4
4
|
|
|
5
|
+
## [0.2.3] — 2026-03-15
|
|
6
|
+
|
|
7
|
+
### Bug Fixes
|
|
8
|
+
|
|
9
|
+
#### `alter mcp` crashes with a cryptic `ModuleNotFoundError` when `mcp < 1.2.0` (Bug A)
|
|
10
|
+
|
|
11
|
+
`alter mcp` calls `init_mcp()` which imports `FastMCP` from `mcp.server.fastmcp`. That
|
|
12
|
+
submodule was introduced in `mcp 1.2.0`; older installations raise a bare
|
|
13
|
+
`ModuleNotFoundError: No module named 'mcp.server.fastmcp'` with no indication of how
|
|
14
|
+
to fix it.
|
|
15
|
+
|
|
16
|
+
`init_mcp()` now wraps the import in a `try/except ImportError` and raises an
|
|
17
|
+
`AlterError` with an actionable message:
|
|
18
|
+
|
|
19
|
+
```
|
|
20
|
+
'alter mcp' requires mcp>=1.2.0, but mcp==1.1.3 is installed.
|
|
21
|
+
Upgrade with: pip install 'mcp>=1.2.0'
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
The error surfaces cleanly in the CLI (no "MCP server error:" prefix) because the CLI
|
|
25
|
+
already handles `AlterError` separately from generic exceptions.
|
|
26
|
+
|
|
27
|
+
A second guard wraps the cosmetic `_mcp_server.version` assignment in
|
|
28
|
+
`try/except AttributeError` so that future changes to `mcp` internals do not break
|
|
29
|
+
`alter mcp` startup.
|
|
30
|
+
|
|
31
|
+
#### `alter apply` spuriously rewrites `datetime.now(timezone.utc)` defaults on Python 3.11+ (Bug B)
|
|
32
|
+
|
|
33
|
+
When a model file contained a column with `default_factory=lambda: datetime.now(timezone.utc)`,
|
|
34
|
+
running `alter apply` on Python 3.11+ would rewrite the line even though nothing had
|
|
35
|
+
changed in the schema.
|
|
36
|
+
|
|
37
|
+
Root cause: `_parse_field_kwargs` normalises kwargs via `ast.unparse`, and the Python
|
|
38
|
+
`ast` module changed how it serialises zero-argument lambdas between versions —
|
|
39
|
+
Python ≤ 3.10 produces `"lambda :"` (with a space after `lambda`), while Python 3.11+
|
|
40
|
+
produces `"lambda:"` (no space). Because `ast.unparse` is applied to both the
|
|
41
|
+
existing code and the freshly generated schema line, the comparison reached different
|
|
42
|
+
sides of the `_DEFAULT_FACTORY_EQUIV` lookup depending on the Python version in use,
|
|
43
|
+
causing the surgical patcher to believe a change was needed when there was none.
|
|
44
|
+
|
|
45
|
+
Two-part fix in `generators/_surgical.py`:
|
|
46
|
+
|
|
47
|
+
1. **`_norm_lambda_ws()` helper** — strips extraneous whitespace between `lambda` and
|
|
48
|
+
`:` for zero-argument lambdas (`re.sub(r"^lambda\s*:", "lambda:", s)`), making
|
|
49
|
+
lambda strings compare equal across Python versions.
|
|
50
|
+
|
|
51
|
+
2. **Normalization applied consistently** — `_normalize_kw_for_eq` now calls
|
|
52
|
+
`_norm_lambda_ws` on `default_factory` values after the `_DEFAULT_FACTORY_EQUIV`
|
|
53
|
+
lookup, so both the existing-file side and the schema side are normalised before
|
|
54
|
+
comparison. The rebuild path in `_rebuild_field_line` applies the same
|
|
55
|
+
normalization when checking whether the existing value is canonically equivalent.
|
|
56
|
+
|
|
57
|
+
The `_DEFAULT_FACTORY_EQUIV` dict value for `utcnow` was also corrected from
|
|
58
|
+
`"lambda : datetime.now(timezone.utc)"` (with spurious space, matching old Python 3.10
|
|
59
|
+
`ast.unparse` output) to `"lambda: datetime.now(timezone.utc)"` (canonical form) — the
|
|
60
|
+
`_norm_lambda_ws` normalization then makes both forms match on all Python versions.
|
|
61
|
+
|
|
62
|
+
---
|
|
63
|
+
|
|
5
64
|
## [0.2.2] — 2026-03-15
|
|
6
65
|
|
|
7
66
|
### Bug Fixes
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: alterdb
|
|
3
|
-
Version: 0.2.
|
|
3
|
+
Version: 0.2.3
|
|
4
4
|
Summary: Visual schema design for SQLModel and SQLAlchemy. Edit your database as a diagram, write it back as code.
|
|
5
5
|
Project-URL: Homepage, https://github.com/chimi-labs/alter
|
|
6
6
|
Project-URL: Repository, https://github.com/chimi-labs/alter
|
|
@@ -280,9 +280,15 @@ _DEFAULT_FACTORY_EQUIV: dict[str, str] = {
|
|
|
280
280
|
# modern lambda form. Treat both as semantically identical so existing
|
|
281
281
|
# hand-written code is never touched unless the field actually changes.
|
|
282
282
|
#
|
|
283
|
-
# NOTE:
|
|
284
|
-
#
|
|
285
|
-
|
|
283
|
+
# NOTE: ast.unparse() output for zero-argument lambdas varies by version:
|
|
284
|
+
# Python <=3.10 produces "lambda :" (with space before colon);
|
|
285
|
+
# Python 3.11+ produces "lambda:" (no space).
|
|
286
|
+
# _parse_field_kwargs uses ast.unparse on BOTH the existing and generated
|
|
287
|
+
# sides, so the raw strings here may differ by a single space depending on
|
|
288
|
+
# the interpreter. _normalize_kw_for_eq() normalises this via
|
|
289
|
+
# _norm_lambda_ws() after the dict lookup, so the value stored here only
|
|
290
|
+
# needs to be recognisable — the no-space form (3.11 canonical) is used.
|
|
291
|
+
"datetime.utcnow": "lambda: datetime.now(timezone.utc)",
|
|
286
292
|
# uuid4 (from `from uuid import uuid4`) and uuid.uuid4 (from `import uuid`)
|
|
287
293
|
# are semantically identical. Treat them as equal so existing hand-written
|
|
288
294
|
# code using the direct-import form is never touched.
|
|
@@ -290,6 +296,22 @@ _DEFAULT_FACTORY_EQUIV: dict[str, str] = {
|
|
|
290
296
|
}
|
|
291
297
|
|
|
292
298
|
|
|
299
|
+
def _norm_lambda_ws(s: str) -> str:
|
|
300
|
+
"""Normalise zero-argument lambda whitespace for cross-version compat.
|
|
301
|
+
|
|
302
|
+
``ast.unparse()`` output for ``lambda: …`` differs between Python versions:
|
|
303
|
+
* Python <=3.10: ``"lambda : expr"`` (space before colon)
|
|
304
|
+
* Python 3.11+: ``"lambda: expr"`` (no space)
|
|
305
|
+
|
|
306
|
+
Both sides of an equality comparison go through ``ast.unparse`` (via
|
|
307
|
+
``_parse_field_kwargs``), so we must normalise before comparing to avoid
|
|
308
|
+
spurious rewrites depending on which Python is running.
|
|
309
|
+
"""
|
|
310
|
+
if s.startswith("lambda"):
|
|
311
|
+
return re.sub(r"^lambda\s*:", "lambda:", s)
|
|
312
|
+
return s
|
|
313
|
+
|
|
314
|
+
|
|
293
315
|
def _normalize_kw_for_eq(kw: dict[str, str]) -> dict[str, str]:
|
|
294
316
|
"""Normalise mutable-default equivalents to a single canonical form.
|
|
295
317
|
|
|
@@ -301,6 +323,10 @@ def _normalize_kw_for_eq(kw: dict[str, str]) -> dict[str, str]:
|
|
|
301
323
|
``datetime.utcnow`` → ``lambda: datetime.now(timezone.utc)``) so that
|
|
302
324
|
fields using the deprecated form are not spuriously rewritten just because
|
|
303
325
|
the generator produces the modern form.
|
|
326
|
+
|
|
327
|
+
Finally normalises zero-argument lambda whitespace via ``_norm_lambda_ws``
|
|
328
|
+
so that ``"lambda :"`` (Python <=3.10 ast.unparse) and ``"lambda:"``
|
|
329
|
+
(Python 3.11+) compare as equal.
|
|
304
330
|
"""
|
|
305
331
|
result = dict(kw)
|
|
306
332
|
for (old_key, old_val), (new_key, new_val) in _MUTABLE_DEFAULT_EQUIV.items():
|
|
@@ -309,7 +335,8 @@ def _normalize_kw_for_eq(kw: dict[str, str]) -> dict[str, str]:
|
|
|
309
335
|
result[new_key] = new_val
|
|
310
336
|
if "default_factory" in result:
|
|
311
337
|
val = result["default_factory"]
|
|
312
|
-
|
|
338
|
+
val = _DEFAULT_FACTORY_EQUIV.get(val, val)
|
|
339
|
+
result["default_factory"] = _norm_lambda_ws(val)
|
|
313
340
|
return result
|
|
314
341
|
|
|
315
342
|
|
|
@@ -458,10 +485,14 @@ def _rebuild_field_line(
|
|
|
458
485
|
val = new_kw[key]
|
|
459
486
|
if key.startswith("__pos_"):
|
|
460
487
|
merged.append(val) # positional
|
|
461
|
-
elif key == "default_factory" and
|
|
488
|
+
elif key == "default_factory" and (
|
|
489
|
+
(_canon := _DEFAULT_FACTORY_EQUIV.get(existing_val)) is not None
|
|
490
|
+
and _norm_lambda_ws(_canon) == _norm_lambda_ws(val)
|
|
491
|
+
):
|
|
462
492
|
# The existing value is a known equivalent of what the generator
|
|
463
493
|
# produces (e.g. datetime.utcnow ↔ lambda: datetime.now(timezone.utc),
|
|
464
|
-
# uuid4 ↔ uuid.uuid4).
|
|
494
|
+
# uuid4 ↔ uuid.uuid4). Normalise lambda whitespace on both sides
|
|
495
|
+
# for Python 3.10/3.11 ast.unparse compat.
|
|
465
496
|
# Preserve the user's original form so we don't introduce noisy diffs.
|
|
466
497
|
merged.append(f"default_factory={existing_val}")
|
|
467
498
|
elif existing_val == val and key in existing_raw:
|
|
@@ -128,10 +128,24 @@ def init_mcp(alter_file_path: Path) -> None:
|
|
|
128
128
|
global _staging, _path
|
|
129
129
|
_path = alter_file_path
|
|
130
130
|
_staging = StagingManager(alter_file_path)
|
|
131
|
-
|
|
131
|
+
try:
|
|
132
|
+
from mcp.server.fastmcp import FastMCP # noqa: PLC0415
|
|
133
|
+
except ImportError:
|
|
134
|
+
import importlib.metadata as _meta # noqa: PLC0415
|
|
135
|
+
try:
|
|
136
|
+
_ver = _meta.version("mcp")
|
|
137
|
+
except _meta.PackageNotFoundError:
|
|
138
|
+
_ver = "unknown"
|
|
139
|
+
raise AlterError(
|
|
140
|
+
f"'alter mcp' requires mcp>=1.2.0, but mcp=={_ver} is installed. "
|
|
141
|
+
f"Upgrade with: pip install 'mcp>=1.2.0'"
|
|
142
|
+
) from None
|
|
132
143
|
from alter import __version__ # noqa: PLC0415
|
|
133
144
|
real_mcp = FastMCP("Alter")
|
|
134
|
-
|
|
145
|
+
try:
|
|
146
|
+
real_mcp._mcp_server.version = __version__
|
|
147
|
+
except AttributeError:
|
|
148
|
+
pass # mcp internals changed — version label is cosmetic, not critical
|
|
135
149
|
mcp._init_real(real_mcp)
|
|
136
150
|
|
|
137
151
|
|
|
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
|