sfapi-client 0.0.3__tar.gz → 0.0.5__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.
- {sfapi_client-0.0.3 → sfapi_client-0.0.5}/PKG-INFO +1 -1
- {sfapi_client-0.0.3 → sfapi_client-0.0.5}/scripts/run.py +3 -1
- {sfapi_client-0.0.3 → sfapi_client-0.0.5}/src/sfapi_client/_async/compute.py +2 -2
- {sfapi_client-0.0.3 → sfapi_client-0.0.5}/src/sfapi_client/_async/projects.py +5 -0
- {sfapi_client-0.0.3 → sfapi_client-0.0.5}/src/sfapi_client/_async/users.py +23 -2
- {sfapi_client-0.0.3 → sfapi_client-0.0.5}/src/sfapi_client/_models/__init__.py +7 -0
- {sfapi_client-0.0.3 → sfapi_client-0.0.5}/src/sfapi_client/_monitor.py +4 -2
- {sfapi_client-0.0.3 → sfapi_client-0.0.5}/src/sfapi_client/_sync/compute.py +2 -2
- {sfapi_client-0.0.3 → sfapi_client-0.0.5}/src/sfapi_client/_sync/projects.py +5 -0
- {sfapi_client-0.0.3 → sfapi_client-0.0.5}/src/sfapi_client/_sync/users.py +23 -2
- sfapi_client-0.0.5/src/sfapi_client/projects.py +2 -0
- {sfapi_client-0.0.3 → sfapi_client-0.0.5}/tests/test_projects.py +18 -0
- {sfapi_client-0.0.3 → sfapi_client-0.0.5}/tests/test_projects_async.py +20 -0
- sfapi_client-0.0.3/src/sfapi_client/projects.py +0 -2
- {sfapi_client-0.0.3 → sfapi_client-0.0.5}/.github/workflows/mkdocs.yml +0 -0
- {sfapi_client-0.0.3 → sfapi_client-0.0.5}/.github/workflows/pypi.yml +0 -0
- {sfapi_client-0.0.3 → sfapi_client-0.0.5}/.github/workflows/pytest.yml +0 -0
- {sfapi_client-0.0.3 → sfapi_client-0.0.5}/.gitignore +0 -0
- {sfapi_client-0.0.3 → sfapi_client-0.0.5}/LEGAL +0 -0
- {sfapi_client-0.0.3 → sfapi_client-0.0.5}/LICENSE +0 -0
- {sfapi_client-0.0.3 → sfapi_client-0.0.5}/README.md +0 -0
- {sfapi_client-0.0.3 → sfapi_client-0.0.5}/docs/community/contributing.md +0 -0
- {sfapi_client-0.0.3 → sfapi_client-0.0.5}/docs/examples/check_current_and_past_jobs.ipynb +0 -0
- {sfapi_client-0.0.3 → sfapi_client-0.0.5}/docs/examples/getting_bearer_token.ipynb +0 -0
- {sfapi_client-0.0.3 → sfapi_client-0.0.5}/docs/examples/run_job_and_check_status.ipynb +0 -0
- {sfapi_client-0.0.3 → sfapi_client-0.0.5}/docs/gen_examples.py +0 -0
- {sfapi_client-0.0.3 → sfapi_client-0.0.5}/docs/gen_sync.py +0 -0
- {sfapi_client-0.0.3 → sfapi_client-0.0.5}/docs/index.md +0 -0
- {sfapi_client-0.0.3 → sfapi_client-0.0.5}/docs/javascript/apiselector.js +0 -0
- {sfapi_client-0.0.3 → sfapi_client-0.0.5}/docs/quickstart/index.md +0 -0
- {sfapi_client-0.0.3 → sfapi_client-0.0.5}/docs/reference/SUMMARY.txt +0 -0
- {sfapi_client-0.0.3 → sfapi_client-0.0.5}/docs/reference/async/client/index.md +0 -0
- {sfapi_client-0.0.3 → sfapi_client-0.0.5}/docs/reference/async/compute/index.md +0 -0
- {sfapi_client-0.0.3 → sfapi_client-0.0.5}/docs/reference/async/exceptions/index.md +0 -0
- {sfapi_client-0.0.3 → sfapi_client-0.0.5}/docs/reference/async/groups/index.md +0 -0
- {sfapi_client-0.0.3 → sfapi_client-0.0.5}/docs/reference/async/jobs/index.md +0 -0
- {sfapi_client-0.0.3 → sfapi_client-0.0.5}/docs/reference/async/paths/index.md +0 -0
- {sfapi_client-0.0.3 → sfapi_client-0.0.5}/docs/reference/async/projects/index.md +0 -0
- {sfapi_client-0.0.3 → sfapi_client-0.0.5}/docs/reference/async/resources/index.md +0 -0
- {sfapi_client-0.0.3 → sfapi_client-0.0.5}/docs/reference/async/users/index.md +0 -0
- {sfapi_client-0.0.3 → sfapi_client-0.0.5}/mkdocs.yml +0 -0
- {sfapi_client-0.0.3 → sfapi_client-0.0.5}/pyproject.toml +0 -0
- {sfapi_client-0.0.3 → sfapi_client-0.0.5}/pytest.ini +0 -0
- {sfapi_client-0.0.3 → sfapi_client-0.0.5}/requirements-dev.txt +0 -0
- {sfapi_client-0.0.3 → sfapi_client-0.0.5}/src/sfapi_client/__init__.py +0 -0
- {sfapi_client-0.0.3 → sfapi_client-0.0.5}/src/sfapi_client/_async/__init__.py +0 -0
- {sfapi_client-0.0.3 → sfapi_client-0.0.5}/src/sfapi_client/_async/client.py +0 -0
- {sfapi_client-0.0.3 → sfapi_client-0.0.5}/src/sfapi_client/_async/groups.py +0 -0
- {sfapi_client-0.0.3 → sfapi_client-0.0.5}/src/sfapi_client/_async/jobs.py +0 -0
- {sfapi_client-0.0.3 → sfapi_client-0.0.5}/src/sfapi_client/_async/paths.py +0 -0
- {sfapi_client-0.0.3 → sfapi_client-0.0.5}/src/sfapi_client/_compute.py +0 -0
- {sfapi_client-0.0.3 → sfapi_client-0.0.5}/src/sfapi_client/_jobs.py +0 -0
- {sfapi_client-0.0.3 → sfapi_client-0.0.5}/src/sfapi_client/_models/job_status_response_sacct.py +0 -0
- {sfapi_client-0.0.3 → sfapi_client-0.0.5}/src/sfapi_client/_models/job_status_response_squeue.py +0 -0
- {sfapi_client-0.0.3 → sfapi_client-0.0.5}/src/sfapi_client/_models/resources.py +0 -0
- {sfapi_client-0.0.3 → sfapi_client-0.0.5}/src/sfapi_client/_sync/__init__.py +0 -0
- {sfapi_client-0.0.3 → sfapi_client-0.0.5}/src/sfapi_client/_sync/_models.py +0 -0
- {sfapi_client-0.0.3 → sfapi_client-0.0.5}/src/sfapi_client/_sync/client.py +0 -0
- {sfapi_client-0.0.3 → sfapi_client-0.0.5}/src/sfapi_client/_sync/groups.py +0 -0
- {sfapi_client-0.0.3 → sfapi_client-0.0.5}/src/sfapi_client/_sync/jobs.py +0 -0
- {sfapi_client-0.0.3 → sfapi_client-0.0.5}/src/sfapi_client/_sync/paths.py +0 -0
- {sfapi_client-0.0.3 → sfapi_client-0.0.5}/src/sfapi_client/_utils.py +0 -0
- {sfapi_client-0.0.3 → sfapi_client-0.0.5}/src/sfapi_client/client.py +0 -0
- {sfapi_client-0.0.3 → sfapi_client-0.0.5}/src/sfapi_client/compute.py +0 -0
- {sfapi_client-0.0.3 → sfapi_client-0.0.5}/src/sfapi_client/exceptions.py +0 -0
- {sfapi_client-0.0.3 → sfapi_client-0.0.5}/src/sfapi_client/groups.py +0 -0
- {sfapi_client-0.0.3 → sfapi_client-0.0.5}/src/sfapi_client/jobs.py +0 -0
- {sfapi_client-0.0.3 → sfapi_client-0.0.5}/src/sfapi_client/paths.py +0 -0
- {sfapi_client-0.0.3 → sfapi_client-0.0.5}/src/sfapi_client/resources.py +0 -0
- {sfapi_client-0.0.3 → sfapi_client-0.0.5}/src/sfapi_client/users.py +0 -0
- {sfapi_client-0.0.3 → sfapi_client-0.0.5}/tests/conftest.py +0 -0
- {sfapi_client-0.0.3 → sfapi_client-0.0.5}/tests/test_api.py +0 -0
- {sfapi_client-0.0.3 → sfapi_client-0.0.5}/tests/test_api_async.py +0 -0
- {sfapi_client-0.0.3 → sfapi_client-0.0.5}/tests/test_client.py +0 -0
- {sfapi_client-0.0.3 → sfapi_client-0.0.5}/tests/test_client_async.py +0 -0
- {sfapi_client-0.0.3 → sfapi_client-0.0.5}/tests/test_compute.py +0 -0
- {sfapi_client-0.0.3 → sfapi_client-0.0.5}/tests/test_compute_async.py +0 -0
- {sfapi_client-0.0.3 → sfapi_client-0.0.5}/tests/test_groups.py +0 -0
- {sfapi_client-0.0.3 → sfapi_client-0.0.5}/tests/test_groups_async.py +0 -0
- {sfapi_client-0.0.3 → sfapi_client-0.0.5}/tests/test_jobs.py +0 -0
- {sfapi_client-0.0.3 → sfapi_client-0.0.5}/tests/test_jobs_async.py +0 -0
- {sfapi_client-0.0.3 → sfapi_client-0.0.5}/tests/test_paths.py +0 -0
- {sfapi_client-0.0.3 → sfapi_client-0.0.5}/tests/test_paths_async.py +0 -0
- {sfapi_client-0.0.3 → sfapi_client-0.0.5}/tests/test_resources.py +0 -0
- {sfapi_client-0.0.3 → sfapi_client-0.0.5}/tests/test_resources_async.py +0 -0
- {sfapi_client-0.0.3 → sfapi_client-0.0.5}/tests/test_users.py +0 -0
- {sfapi_client-0.0.3 → sfapi_client-0.0.5}/tests/test_users_async.py +0 -0
|
@@ -31,6 +31,7 @@ def run_unasync():
|
|
|
31
31
|
"AsyncGroupMember": "GroupMember",
|
|
32
32
|
"AsyncRemotePath": "RemotePath",
|
|
33
33
|
"AsyncProject": "Project",
|
|
34
|
+
"AsyncRole": "Role",
|
|
34
35
|
"AsyncUser": "User",
|
|
35
36
|
"AsyncJob": "Job",
|
|
36
37
|
"AsyncJobSacct": "JobSacct",
|
|
@@ -151,7 +152,8 @@ def resources_codegen(
|
|
|
151
152
|
),
|
|
152
153
|
):
|
|
153
154
|
|
|
154
|
-
import requests
|
|
155
|
+
import requests
|
|
156
|
+
import datetime
|
|
155
157
|
api_url = "https://api.nersc.gov/api/v1.2/status"
|
|
156
158
|
response = requests.get(api_url)
|
|
157
159
|
status = response.json()
|
|
@@ -121,7 +121,7 @@ class AsyncCompute(ComputeBase):
|
|
|
121
121
|
|
|
122
122
|
@check_auth
|
|
123
123
|
async def job(
|
|
124
|
-
self, jobid: int, command: Optional[JobCommand] = JobCommand.sacct
|
|
124
|
+
self, jobid: Union[int, str], command: Optional[JobCommand] = JobCommand.sacct
|
|
125
125
|
) -> Union["AsyncJobSacct", "AsyncJobSqueue"]:
|
|
126
126
|
# Get different job depending on query
|
|
127
127
|
Job = AsyncJobSacct if (command == JobCommand.sacct) else AsyncJobSqueue
|
|
@@ -134,7 +134,7 @@ class AsyncCompute(ComputeBase):
|
|
|
134
134
|
@check_auth
|
|
135
135
|
async def jobs(
|
|
136
136
|
self,
|
|
137
|
-
jobids: Optional[int] = None,
|
|
137
|
+
jobids: Optional[List[Union[int, str]]] = None,
|
|
138
138
|
user: Optional[str] = None,
|
|
139
139
|
partition: Optional[str] = None,
|
|
140
140
|
command: Optional[JobCommand] = JobCommand.squeue,
|
|
@@ -3,10 +3,15 @@ from pydantic import ValidationError, Field
|
|
|
3
3
|
|
|
4
4
|
from .._models import (
|
|
5
5
|
ProjectStats as ProjectBase,
|
|
6
|
+
RoleStats as RoleBase
|
|
6
7
|
)
|
|
7
8
|
from ..exceptions import SfApiError
|
|
8
9
|
|
|
9
10
|
|
|
11
|
+
class AsyncRole(RoleBase):
|
|
12
|
+
client: Optional["AsyncClient"]
|
|
13
|
+
|
|
14
|
+
|
|
10
15
|
class AsyncProject(ProjectBase):
|
|
11
16
|
client: Optional["AsyncClient"]
|
|
12
17
|
name: str = Field(alias="repo_name")
|
|
@@ -5,7 +5,7 @@ from .._models import (
|
|
|
5
5
|
UserInfo as UserBase,
|
|
6
6
|
GroupList as GroupsResponse,
|
|
7
7
|
)
|
|
8
|
-
from .projects import AsyncProject
|
|
8
|
+
from .projects import AsyncProject, AsyncRole
|
|
9
9
|
from ..exceptions import SfApiError
|
|
10
10
|
|
|
11
11
|
|
|
@@ -69,7 +69,7 @@ class AsyncUser(UserBase):
|
|
|
69
69
|
if self.name != (await self.client._user()).name:
|
|
70
70
|
raise SfApiError(f"Can only fetch projects for authenticated user.")
|
|
71
71
|
|
|
72
|
-
r = await self.client.get("account/
|
|
72
|
+
r = await self.client.get("account/projects")
|
|
73
73
|
|
|
74
74
|
json_response = r.json()
|
|
75
75
|
|
|
@@ -82,3 +82,24 @@ class AsyncUser(UserBase):
|
|
|
82
82
|
projects = map(_set_client, projects)
|
|
83
83
|
|
|
84
84
|
return list(projects)
|
|
85
|
+
|
|
86
|
+
async def roles(self) -> List[AsyncRole]:
|
|
87
|
+
"""
|
|
88
|
+
The roles the user is associate with.
|
|
89
|
+
"""
|
|
90
|
+
if self.name != (await self.client._user()).name:
|
|
91
|
+
raise SfApiError(f"Can only fetch roles for authenticated user.")
|
|
92
|
+
|
|
93
|
+
r = await self.client.get("account/roles")
|
|
94
|
+
|
|
95
|
+
json_response = r.json()
|
|
96
|
+
|
|
97
|
+
roles = [AsyncRole.parse_obj(p) for p in json_response]
|
|
98
|
+
|
|
99
|
+
def _set_client(p):
|
|
100
|
+
p.client = self.client
|
|
101
|
+
return p
|
|
102
|
+
|
|
103
|
+
roles = map(_set_client, roles)
|
|
104
|
+
|
|
105
|
+
return list(roles)
|
|
@@ -91,6 +91,13 @@ class PublicHost(str, Enum):
|
|
|
91
91
|
perlmutter = "perlmutter"
|
|
92
92
|
|
|
93
93
|
|
|
94
|
+
class RoleStats(BaseModel):
|
|
95
|
+
id: int = Field(..., title="Id")
|
|
96
|
+
description: str = Field(..., title="Description")
|
|
97
|
+
repo_name: str = Field(..., title="Repo Name")
|
|
98
|
+
iris_role: Optional[str] = Field(None, title="Iris Role")
|
|
99
|
+
|
|
100
|
+
|
|
94
101
|
class StatusValue(str, Enum):
|
|
95
102
|
active = "active"
|
|
96
103
|
unavailable = "unavailable"
|
|
@@ -62,8 +62,9 @@ class AsyncJobMonitor:
|
|
|
62
62
|
return job_type
|
|
63
63
|
|
|
64
64
|
async def fetch_jobs(
|
|
65
|
-
self, job_type: Union[AsyncJobSacct, AsyncJobSqueue], jobids: List[int]
|
|
65
|
+
self, job_type: Union[AsyncJobSacct, AsyncJobSqueue], jobids: List[Union[int, str]]
|
|
66
66
|
) -> List[Union[AsyncJobSacct, AsyncJobSqueue]]:
|
|
67
|
+
jobids = list(map(str, jobids))
|
|
67
68
|
jobids_for_type = self._jobids.setdefault(job_type, set())
|
|
68
69
|
jobids_for_type.update(jobids)
|
|
69
70
|
|
|
@@ -132,8 +133,9 @@ class SyncJobMonitor:
|
|
|
132
133
|
self._request_lock = Lock()
|
|
133
134
|
|
|
134
135
|
def fetch_jobs(
|
|
135
|
-
self, job_type: Union["JobSacct", "JobSqueue"], jobids: List[int]
|
|
136
|
+
self, job_type: Union["JobSacct", "JobSqueue"], jobids: List[Union[int, str]]
|
|
136
137
|
) -> List[Union[JobSqueue, JobSacct]]:
|
|
138
|
+
jobids = list(map(str, jobids))
|
|
137
139
|
# First update the jobids and create a request context
|
|
138
140
|
request = None
|
|
139
141
|
with self._requests_lock:
|
|
@@ -121,7 +121,7 @@ class Compute(ComputeBase):
|
|
|
121
121
|
|
|
122
122
|
@check_auth
|
|
123
123
|
def job(
|
|
124
|
-
self, jobid: int, command: Optional[JobCommand] = JobCommand.sacct
|
|
124
|
+
self, jobid: Union[int, str], command: Optional[JobCommand] = JobCommand.sacct
|
|
125
125
|
) -> Union["JobSacct", "JobSqueue"]:
|
|
126
126
|
# Get different job depending on query
|
|
127
127
|
Job = JobSacct if (command == JobCommand.sacct) else JobSqueue
|
|
@@ -134,7 +134,7 @@ class Compute(ComputeBase):
|
|
|
134
134
|
@check_auth
|
|
135
135
|
def jobs(
|
|
136
136
|
self,
|
|
137
|
-
jobids: Optional[int] = None,
|
|
137
|
+
jobids: Optional[List[Union[int, str]]] = None,
|
|
138
138
|
user: Optional[str] = None,
|
|
139
139
|
partition: Optional[str] = None,
|
|
140
140
|
command: Optional[JobCommand] = JobCommand.squeue,
|
|
@@ -3,10 +3,15 @@ from pydantic import ValidationError, Field
|
|
|
3
3
|
|
|
4
4
|
from .._models import (
|
|
5
5
|
ProjectStats as ProjectBase,
|
|
6
|
+
RoleStats as RoleBase
|
|
6
7
|
)
|
|
7
8
|
from ..exceptions import SfApiError
|
|
8
9
|
|
|
9
10
|
|
|
11
|
+
class Role(RoleBase):
|
|
12
|
+
client: Optional["Client"]
|
|
13
|
+
|
|
14
|
+
|
|
10
15
|
class Project(ProjectBase):
|
|
11
16
|
client: Optional["Client"]
|
|
12
17
|
name: str = Field(alias="repo_name")
|
|
@@ -5,7 +5,7 @@ from .._models import (
|
|
|
5
5
|
UserInfo as UserBase,
|
|
6
6
|
GroupList as GroupsResponse,
|
|
7
7
|
)
|
|
8
|
-
from .projects import Project
|
|
8
|
+
from .projects import Project, Role
|
|
9
9
|
from ..exceptions import SfApiError
|
|
10
10
|
|
|
11
11
|
|
|
@@ -69,7 +69,7 @@ class User(UserBase):
|
|
|
69
69
|
if self.name != (self.client._user()).name:
|
|
70
70
|
raise SfApiError(f"Can only fetch projects for authenticated user.")
|
|
71
71
|
|
|
72
|
-
r = self.client.get("account/
|
|
72
|
+
r = self.client.get("account/projects")
|
|
73
73
|
|
|
74
74
|
json_response = r.json()
|
|
75
75
|
|
|
@@ -82,3 +82,24 @@ class User(UserBase):
|
|
|
82
82
|
projects = map(_set_client, projects)
|
|
83
83
|
|
|
84
84
|
return list(projects)
|
|
85
|
+
|
|
86
|
+
def roles(self) -> List[Role]:
|
|
87
|
+
"""
|
|
88
|
+
The roles the user is associate with.
|
|
89
|
+
"""
|
|
90
|
+
if self.name != (self.client._user()).name:
|
|
91
|
+
raise SfApiError(f"Can only fetch roles for authenticated user.")
|
|
92
|
+
|
|
93
|
+
r = self.client.get("account/roles")
|
|
94
|
+
|
|
95
|
+
json_response = r.json()
|
|
96
|
+
|
|
97
|
+
roles = [Role.parse_obj(p) for p in json_response]
|
|
98
|
+
|
|
99
|
+
def _set_client(p):
|
|
100
|
+
p.client = self.client
|
|
101
|
+
return p
|
|
102
|
+
|
|
103
|
+
roles = map(_set_client, roles)
|
|
104
|
+
|
|
105
|
+
return list(roles)
|
|
@@ -24,3 +24,21 @@ async def test_create_group(
|
|
|
24
24
|
group = project.create_group(test_group_create)
|
|
25
25
|
|
|
26
26
|
assert group.name == test_create_group
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
def test_projects(
|
|
30
|
+
client_id, client_secret
|
|
31
|
+
):
|
|
32
|
+
with Client(client_id, client_secret) as client:
|
|
33
|
+
user = client.user()
|
|
34
|
+
projects = user.projects()
|
|
35
|
+
assert projects
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
def test_roles(
|
|
39
|
+
client_id, client_secret
|
|
40
|
+
):
|
|
41
|
+
with Client(client_id, client_secret) as client:
|
|
42
|
+
user = client.user()
|
|
43
|
+
roles = user.roles()
|
|
44
|
+
assert roles
|
|
@@ -26,3 +26,23 @@ async def test_create_group(
|
|
|
26
26
|
group = await project.create_group(test_group_create)
|
|
27
27
|
|
|
28
28
|
assert group.name == test_create_group
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
@pytest.mark.asyncio
|
|
32
|
+
async def test_projects(
|
|
33
|
+
client_id, client_secret
|
|
34
|
+
):
|
|
35
|
+
async with AsyncClient(client_id, client_secret) as client:
|
|
36
|
+
user = await client.user()
|
|
37
|
+
projects = await user.projects()
|
|
38
|
+
assert projects
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
@pytest.mark.asyncio
|
|
42
|
+
async def test_roles(
|
|
43
|
+
client_id, client_secret
|
|
44
|
+
):
|
|
45
|
+
async with AsyncClient(client_id, client_secret) as client:
|
|
46
|
+
user = await client.user()
|
|
47
|
+
roles = await user.roles()
|
|
48
|
+
assert roles
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{sfapi_client-0.0.3 → sfapi_client-0.0.5}/src/sfapi_client/_models/job_status_response_sacct.py
RENAMED
|
File without changes
|
{sfapi_client-0.0.3 → sfapi_client-0.0.5}/src/sfapi_client/_models/job_status_response_squeue.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
|