jamlib 3.0.0b13.dev0__tar.gz → 3.0.0b13.dev1__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.
- {jamlib-3.0.0b13.dev0/src/jamlib.egg-info → jamlib-3.0.0b13.dev1}/PKG-INFO +1 -1
- {jamlib-3.0.0b13.dev0 → jamlib-3.0.0b13.dev1}/pyproject.toml +1 -1
- {jamlib-3.0.0b13.dev0 → jamlib-3.0.0b13.dev1}/src/jam/__init__.py +1 -1
- jamlib-3.0.0b13.dev1/src/jam/ext/starlette/__init__.py +16 -0
- {jamlib-3.0.0b13.dev0 → jamlib-3.0.0b13.dev1}/src/jam/ext/starlette/backends.py +47 -2
- jamlib-3.0.0b13.dev1/src/jam/ext/starlette/objects.py +53 -0
- {jamlib-3.0.0b13.dev0 → jamlib-3.0.0b13.dev1/src/jamlib.egg-info}/PKG-INFO +1 -1
- {jamlib-3.0.0b13.dev0 → jamlib-3.0.0b13.dev1}/src/jamlib.egg-info/SOURCES.txt +1 -0
- jamlib-3.0.0b13.dev0/src/jam/ext/starlette/__init__.py +0 -6
- {jamlib-3.0.0b13.dev0 → jamlib-3.0.0b13.dev1}/LICENSE.md +0 -0
- {jamlib-3.0.0b13.dev0 → jamlib-3.0.0b13.dev1}/README.md +0 -0
- {jamlib-3.0.0b13.dev0 → jamlib-3.0.0b13.dev1}/setup.cfg +0 -0
- {jamlib-3.0.0b13.dev0 → jamlib-3.0.0b13.dev1}/src/jam/__base__.py +0 -0
- {jamlib-3.0.0b13.dev0 → jamlib-3.0.0b13.dev1}/src/jam/__base_encoder__.py +0 -0
- {jamlib-3.0.0b13.dev0 → jamlib-3.0.0b13.dev1}/src/jam/__deprecated__.py +0 -0
- {jamlib-3.0.0b13.dev0 → jamlib-3.0.0b13.dev1}/src/jam/aio/__base__.py +0 -0
- {jamlib-3.0.0b13.dev0 → jamlib-3.0.0b13.dev1}/src/jam/aio/__init__.py +0 -0
- {jamlib-3.0.0b13.dev0 → jamlib-3.0.0b13.dev1}/src/jam/aio/instance.py +0 -0
- {jamlib-3.0.0b13.dev0 → jamlib-3.0.0b13.dev1}/src/jam/aio/jwt/__init__.py +0 -0
- {jamlib-3.0.0b13.dev0 → jamlib-3.0.0b13.dev1}/src/jam/aio/oauth2/__base__.py +0 -0
- {jamlib-3.0.0b13.dev0 → jamlib-3.0.0b13.dev1}/src/jam/aio/oauth2/__init__.py +0 -0
- {jamlib-3.0.0b13.dev0 → jamlib-3.0.0b13.dev1}/src/jam/aio/oauth2/builtin/__init__.py +0 -0
- {jamlib-3.0.0b13.dev0 → jamlib-3.0.0b13.dev1}/src/jam/aio/oauth2/builtin/github.py +0 -0
- {jamlib-3.0.0b13.dev0 → jamlib-3.0.0b13.dev1}/src/jam/aio/oauth2/builtin/gitlab.py +0 -0
- {jamlib-3.0.0b13.dev0 → jamlib-3.0.0b13.dev1}/src/jam/aio/oauth2/builtin/google.py +0 -0
- {jamlib-3.0.0b13.dev0 → jamlib-3.0.0b13.dev1}/src/jam/aio/oauth2/builtin/yandex.py +0 -0
- {jamlib-3.0.0b13.dev0 → jamlib-3.0.0b13.dev1}/src/jam/aio/oauth2/client.py +0 -0
- {jamlib-3.0.0b13.dev0 → jamlib-3.0.0b13.dev1}/src/jam/aio/sessions/__base__.py +0 -0
- {jamlib-3.0.0b13.dev0 → jamlib-3.0.0b13.dev1}/src/jam/aio/sessions/__init__.py +0 -0
- {jamlib-3.0.0b13.dev0 → jamlib-3.0.0b13.dev1}/src/jam/aio/sessions/json.py +0 -0
- {jamlib-3.0.0b13.dev0 → jamlib-3.0.0b13.dev1}/src/jam/aio/sessions/redis.py +0 -0
- {jamlib-3.0.0b13.dev0 → jamlib-3.0.0b13.dev1}/src/jam/encoders.py +0 -0
- {jamlib-3.0.0b13.dev0 → jamlib-3.0.0b13.dev1}/src/jam/exceptions/__init__.py +0 -0
- {jamlib-3.0.0b13.dev0 → jamlib-3.0.0b13.dev1}/src/jam/exceptions/base.py +0 -0
- {jamlib-3.0.0b13.dev0 → jamlib-3.0.0b13.dev1}/src/jam/exceptions/jwt.py +0 -0
- {jamlib-3.0.0b13.dev0 → jamlib-3.0.0b13.dev1}/src/jam/exceptions/oauth2.py +0 -0
- {jamlib-3.0.0b13.dev0 → jamlib-3.0.0b13.dev1}/src/jam/exceptions/paseto.py +0 -0
- {jamlib-3.0.0b13.dev0 → jamlib-3.0.0b13.dev1}/src/jam/exceptions/plugins.py +0 -0
- {jamlib-3.0.0b13.dev0 → jamlib-3.0.0b13.dev1}/src/jam/exceptions/sessions.py +0 -0
- {jamlib-3.0.0b13.dev0 → jamlib-3.0.0b13.dev1}/src/jam/ext/__init__.py +0 -0
- {jamlib-3.0.0b13.dev0 → jamlib-3.0.0b13.dev1}/src/jam/ext/fastapi/__init__.py +0 -0
- {jamlib-3.0.0b13.dev0 → jamlib-3.0.0b13.dev1}/src/jam/ext/flask/__init__.py +0 -0
- {jamlib-3.0.0b13.dev0 → jamlib-3.0.0b13.dev1}/src/jam/ext/flask/extensions.py +0 -0
- {jamlib-3.0.0b13.dev0 → jamlib-3.0.0b13.dev1}/src/jam/ext/litestar/__init__.py +0 -0
- {jamlib-3.0.0b13.dev0 → jamlib-3.0.0b13.dev1}/src/jam/ext/litestar/middleware.py +0 -0
- {jamlib-3.0.0b13.dev0 → jamlib-3.0.0b13.dev1}/src/jam/ext/litestar/objects.py +0 -0
- {jamlib-3.0.0b13.dev0 → jamlib-3.0.0b13.dev1}/src/jam/ext/litestar/plugins.py +0 -0
- {jamlib-3.0.0b13.dev0 → jamlib-3.0.0b13.dev1}/src/jam/instance.py +0 -0
- {jamlib-3.0.0b13.dev0 → jamlib-3.0.0b13.dev1}/src/jam/jwt/__algorithms__.py +0 -0
- {jamlib-3.0.0b13.dev0 → jamlib-3.0.0b13.dev1}/src/jam/jwt/__base__.py +0 -0
- {jamlib-3.0.0b13.dev0 → jamlib-3.0.0b13.dev1}/src/jam/jwt/__init__.py +0 -0
- {jamlib-3.0.0b13.dev0 → jamlib-3.0.0b13.dev1}/src/jam/jwt/__types__.py +0 -0
- {jamlib-3.0.0b13.dev0 → jamlib-3.0.0b13.dev1}/src/jam/jwt/lists/__abc_list_repo__.py +0 -0
- {jamlib-3.0.0b13.dev0 → jamlib-3.0.0b13.dev1}/src/jam/jwt/lists/__init__.py +0 -0
- {jamlib-3.0.0b13.dev0 → jamlib-3.0.0b13.dev1}/src/jam/jwt/lists/json.py +0 -0
- {jamlib-3.0.0b13.dev0 → jamlib-3.0.0b13.dev1}/src/jam/jwt/lists/redis.py +0 -0
- {jamlib-3.0.0b13.dev0 → jamlib-3.0.0b13.dev1}/src/jam/jwt/module.py +0 -0
- {jamlib-3.0.0b13.dev0 → jamlib-3.0.0b13.dev1}/src/jam/jwt/utils.py +0 -0
- {jamlib-3.0.0b13.dev0 → jamlib-3.0.0b13.dev1}/src/jam/logger.py +0 -0
- {jamlib-3.0.0b13.dev0 → jamlib-3.0.0b13.dev1}/src/jam/oauth2/__base__.py +0 -0
- {jamlib-3.0.0b13.dev0 → jamlib-3.0.0b13.dev1}/src/jam/oauth2/__init__.py +0 -0
- {jamlib-3.0.0b13.dev0 → jamlib-3.0.0b13.dev1}/src/jam/oauth2/builtin/__init__.py +0 -0
- {jamlib-3.0.0b13.dev0 → jamlib-3.0.0b13.dev1}/src/jam/oauth2/builtin/github.py +0 -0
- {jamlib-3.0.0b13.dev0 → jamlib-3.0.0b13.dev1}/src/jam/oauth2/builtin/gitlab.py +0 -0
- {jamlib-3.0.0b13.dev0 → jamlib-3.0.0b13.dev1}/src/jam/oauth2/builtin/google.py +0 -0
- {jamlib-3.0.0b13.dev0 → jamlib-3.0.0b13.dev1}/src/jam/oauth2/builtin/yandex.py +0 -0
- {jamlib-3.0.0b13.dev0 → jamlib-3.0.0b13.dev1}/src/jam/oauth2/client.py +0 -0
- {jamlib-3.0.0b13.dev0 → jamlib-3.0.0b13.dev1}/src/jam/otp/__base__.py +0 -0
- {jamlib-3.0.0b13.dev0 → jamlib-3.0.0b13.dev1}/src/jam/otp/__init__.py +0 -0
- {jamlib-3.0.0b13.dev0 → jamlib-3.0.0b13.dev1}/src/jam/otp/hotp.py +0 -0
- {jamlib-3.0.0b13.dev0 → jamlib-3.0.0b13.dev1}/src/jam/otp/totp.py +0 -0
- {jamlib-3.0.0b13.dev0 → jamlib-3.0.0b13.dev1}/src/jam/paseto/__base__.py +0 -0
- {jamlib-3.0.0b13.dev0 → jamlib-3.0.0b13.dev1}/src/jam/paseto/__init__.py +0 -0
- {jamlib-3.0.0b13.dev0 → jamlib-3.0.0b13.dev1}/src/jam/paseto/utils.py +0 -0
- {jamlib-3.0.0b13.dev0 → jamlib-3.0.0b13.dev1}/src/jam/paseto/v1.py +0 -0
- {jamlib-3.0.0b13.dev0 → jamlib-3.0.0b13.dev1}/src/jam/paseto/v2.py +0 -0
- {jamlib-3.0.0b13.dev0 → jamlib-3.0.0b13.dev1}/src/jam/paseto/v3.py +0 -0
- {jamlib-3.0.0b13.dev0 → jamlib-3.0.0b13.dev1}/src/jam/paseto/v4.py +0 -0
- {jamlib-3.0.0b13.dev0 → jamlib-3.0.0b13.dev1}/src/jam/py.typed +0 -0
- {jamlib-3.0.0b13.dev0 → jamlib-3.0.0b13.dev1}/src/jam/sessions/__base__.py +0 -0
- {jamlib-3.0.0b13.dev0 → jamlib-3.0.0b13.dev1}/src/jam/sessions/__init__.py +0 -0
- {jamlib-3.0.0b13.dev0 → jamlib-3.0.0b13.dev1}/src/jam/sessions/json.py +0 -0
- {jamlib-3.0.0b13.dev0 → jamlib-3.0.0b13.dev1}/src/jam/sessions/redis.py +0 -0
- {jamlib-3.0.0b13.dev0 → jamlib-3.0.0b13.dev1}/src/jam/tests/__init__.py +0 -0
- {jamlib-3.0.0b13.dev0 → jamlib-3.0.0b13.dev1}/src/jam/tests/clients.py +0 -0
- {jamlib-3.0.0b13.dev0 → jamlib-3.0.0b13.dev1}/src/jam/tests/fakers.py +0 -0
- {jamlib-3.0.0b13.dev0 → jamlib-3.0.0b13.dev1}/src/jam/utils/__init__.py +0 -0
- {jamlib-3.0.0b13.dev0 → jamlib-3.0.0b13.dev1}/src/jam/utils/aes.py +0 -0
- {jamlib-3.0.0b13.dev0 → jamlib-3.0.0b13.dev1}/src/jam/utils/await_maybe.py +0 -0
- {jamlib-3.0.0b13.dev0 → jamlib-3.0.0b13.dev1}/src/jam/utils/basic_auth.py +0 -0
- {jamlib-3.0.0b13.dev0 → jamlib-3.0.0b13.dev1}/src/jam/utils/config_maker.py +0 -0
- {jamlib-3.0.0b13.dev0 → jamlib-3.0.0b13.dev1}/src/jam/utils/ed.py +0 -0
- {jamlib-3.0.0b13.dev0 → jamlib-3.0.0b13.dev1}/src/jam/utils/otp_keys.py +0 -0
- {jamlib-3.0.0b13.dev0 → jamlib-3.0.0b13.dev1}/src/jam/utils/rsa.py +0 -0
- {jamlib-3.0.0b13.dev0 → jamlib-3.0.0b13.dev1}/src/jam/utils/salt_hash.py +0 -0
- {jamlib-3.0.0b13.dev0 → jamlib-3.0.0b13.dev1}/src/jam/utils/symmetric.py +0 -0
- {jamlib-3.0.0b13.dev0 → jamlib-3.0.0b13.dev1}/src/jam/utils/xchacha20poly1305.py +0 -0
- {jamlib-3.0.0b13.dev0 → jamlib-3.0.0b13.dev1}/src/jam/utils/xor.py +0 -0
- {jamlib-3.0.0b13.dev0 → jamlib-3.0.0b13.dev1}/src/jamlib.egg-info/dependency_links.txt +0 -0
- {jamlib-3.0.0b13.dev0 → jamlib-3.0.0b13.dev1}/src/jamlib.egg-info/requires.txt +0 -0
- {jamlib-3.0.0b13.dev0 → jamlib-3.0.0b13.dev1}/src/jamlib.egg-info/top_level.txt +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: jamlib
|
|
3
|
-
Version: 3.0.0b13.
|
|
3
|
+
Version: 3.0.0b13.dev1
|
|
4
4
|
Summary: Simple and universal library for authorization.
|
|
5
5
|
Author-email: Makridenko Adrian <adrianmakridenko@duck.com>, Ksenia Travnikova <kseniatravnikova@duck.com>
|
|
6
6
|
License: Apache-2.0
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
# -*- coding: utf-8 -*-
|
|
2
|
+
|
|
3
|
+
"""Starlette integration.
|
|
4
|
+
|
|
5
|
+
Starlette docs: https://starlette.dev
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
from .objects import BaseUser, SimpleUser
|
|
9
|
+
from .backends import JWTBackend
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
__all__ = [
|
|
13
|
+
"BaseUser",
|
|
14
|
+
"SimpleUser",
|
|
15
|
+
"JWTBackend",
|
|
16
|
+
]
|
|
@@ -3,9 +3,17 @@
|
|
|
3
3
|
from collections.abc import Callable
|
|
4
4
|
from typing import Any
|
|
5
5
|
|
|
6
|
-
from starlette.authentication import
|
|
6
|
+
from starlette.authentication import (
|
|
7
|
+
AuthCredentials,
|
|
8
|
+
AuthenticationBackend,
|
|
9
|
+
UnauthenticatedUser,
|
|
10
|
+
)
|
|
11
|
+
from starlette.authentication import BaseUser as StarletteBaseUser
|
|
12
|
+
from starlette.requests import HTTPConnection
|
|
7
13
|
|
|
8
14
|
from jam.exceptions import JamStarlettePluginConfigError
|
|
15
|
+
from jam.ext.starlette.objects import BaseUser, SimpleUser
|
|
16
|
+
from jam.jwt import JWT
|
|
9
17
|
from jam.utils.config_maker import GENERIC_POINTER, __config_maker__
|
|
10
18
|
|
|
11
19
|
|
|
@@ -21,7 +29,7 @@ class BaseBackend(AuthenticationBackend):
|
|
|
21
29
|
pointer: str = GENERIC_POINTER,
|
|
22
30
|
cookie_name: str | None = None,
|
|
23
31
|
header_name: str | None = None,
|
|
24
|
-
user: type[BaseUser]
|
|
32
|
+
user: type[BaseUser] = SimpleUser,
|
|
25
33
|
**kwargs,
|
|
26
34
|
) -> None:
|
|
27
35
|
if not cookie_name and not header_name:
|
|
@@ -37,6 +45,25 @@ class BaseBackend(AuthenticationBackend):
|
|
|
37
45
|
self._user = user
|
|
38
46
|
self._config_setup(config, pointer, kwargs)
|
|
39
47
|
|
|
48
|
+
def _get_auth_token(self, connection: HTTPConnection) -> str | None:
|
|
49
|
+
if self._cookie_name:
|
|
50
|
+
token = connection.cookies.get(self._cookie_name, None)
|
|
51
|
+
elif self._header_name:
|
|
52
|
+
token_bear = connection.headers.get(self._header_name, None)
|
|
53
|
+
if token_bear:
|
|
54
|
+
token = token_bear.split("Bearer ")[1] # noqa: E701
|
|
55
|
+
else:
|
|
56
|
+
token = None # noqa: E701
|
|
57
|
+
else:
|
|
58
|
+
raise JamStarlettePluginConfigError(
|
|
59
|
+
message="cookie_name or header_name must be provided.",
|
|
60
|
+
details={
|
|
61
|
+
"cookie_name": self._cookie_name,
|
|
62
|
+
"header_name": self._header_name,
|
|
63
|
+
},
|
|
64
|
+
)
|
|
65
|
+
return token
|
|
66
|
+
|
|
40
67
|
def _config_setup(
|
|
41
68
|
self,
|
|
42
69
|
config: dict[str, Any] | str | None,
|
|
@@ -63,3 +90,21 @@ class BaseBackend(AuthenticationBackend):
|
|
|
63
90
|
"error": str(e),
|
|
64
91
|
},
|
|
65
92
|
)
|
|
93
|
+
|
|
94
|
+
|
|
95
|
+
class JWTBackend(BaseBackend):
|
|
96
|
+
"""JWT Backend for litestar."""
|
|
97
|
+
|
|
98
|
+
MODULE = JWT
|
|
99
|
+
_CONFIG_KEY = "jwt"
|
|
100
|
+
|
|
101
|
+
async def authenticate( # noqa
|
|
102
|
+
self, conn: HTTPConnection
|
|
103
|
+
) -> tuple[AuthCredentials, StarletteBaseUser] | None:
|
|
104
|
+
token = self._get_auth_token(conn)
|
|
105
|
+
if token:
|
|
106
|
+
data = self._auth.decode(token)
|
|
107
|
+
user = self._user.from_payload(data)
|
|
108
|
+
return AuthCredentials(["authenticated"]), user
|
|
109
|
+
|
|
110
|
+
return AuthCredentials(None), UnauthenticatedUser()
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
# -*- coding: utf-8 -*-
|
|
2
|
+
|
|
3
|
+
from abc import ABC, abstractmethod
|
|
4
|
+
from dataclasses import dataclass
|
|
5
|
+
from typing import Any, TypeVar
|
|
6
|
+
|
|
7
|
+
from starlette.authentication import BaseUser as StarletteBaseUser
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
User = TypeVar("User", bound="BaseUser")
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
class BaseUser(ABC, StarletteBaseUser):
|
|
14
|
+
"""BaseUser with builder from payload."""
|
|
15
|
+
|
|
16
|
+
@classmethod
|
|
17
|
+
@abstractmethod
|
|
18
|
+
def from_payload(cls, payload: dict[str, Any]) -> User:
|
|
19
|
+
"""Create instance by payload.
|
|
20
|
+
|
|
21
|
+
Args:
|
|
22
|
+
payload (dict[str, Any]): Payload from auth
|
|
23
|
+
|
|
24
|
+
Example:
|
|
25
|
+
```python
|
|
26
|
+
|
|
27
|
+
class MyUser(JamBaseUser):
|
|
28
|
+
id: int
|
|
29
|
+
username: str
|
|
30
|
+
|
|
31
|
+
@classmethod
|
|
32
|
+
def from_payload(cls, payload):
|
|
33
|
+
return cls(
|
|
34
|
+
id=payload["id"],
|
|
35
|
+
username=payload["username"]
|
|
36
|
+
)
|
|
37
|
+
|
|
38
|
+
payload = jwt.decode(token)
|
|
39
|
+
user = MyUser.from_payload(payload)
|
|
40
|
+
```
|
|
41
|
+
"""
|
|
42
|
+
raise NotImplementedError
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
@dataclass(slots=True)
|
|
46
|
+
class SimpleUser(BaseUser):
|
|
47
|
+
"""Simple user with payload only."""
|
|
48
|
+
|
|
49
|
+
payload: dict[str, Any]
|
|
50
|
+
|
|
51
|
+
@classmethod
|
|
52
|
+
def from_payload(cls, payload: dict[str, Any]): # noqa
|
|
53
|
+
return cls(payload=payload)
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: jamlib
|
|
3
|
-
Version: 3.0.0b13.
|
|
3
|
+
Version: 3.0.0b13.dev1
|
|
4
4
|
Summary: Simple and universal library for authorization.
|
|
5
5
|
Author-email: Makridenko Adrian <adrianmakridenko@duck.com>, Ksenia Travnikova <kseniatravnikova@duck.com>
|
|
6
6
|
License: Apache-2.0
|
|
@@ -42,6 +42,7 @@ src/jam/ext/litestar/objects.py
|
|
|
42
42
|
src/jam/ext/litestar/plugins.py
|
|
43
43
|
src/jam/ext/starlette/__init__.py
|
|
44
44
|
src/jam/ext/starlette/backends.py
|
|
45
|
+
src/jam/ext/starlette/objects.py
|
|
45
46
|
src/jam/jwt/__algorithms__.py
|
|
46
47
|
src/jam/jwt/__base__.py
|
|
47
48
|
src/jam/jwt/__init__.py
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|