gitcode-api 1.2.13__tar.gz → 1.2.14__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.
- {gitcode_api-1.2.13 → gitcode_api-1.2.14}/PKG-INFO +22 -2
- {gitcode_api-1.2.13 → gitcode_api-1.2.14}/README.md +21 -1
- {gitcode_api-1.2.13 → gitcode_api-1.2.14}/gitcode_api/__init__.py +2 -0
- {gitcode_api-1.2.13 → gitcode_api-1.2.14}/gitcode_api/_models.py +28 -55
- {gitcode_api-1.2.13 → gitcode_api-1.2.14}/gitcode_api/llm/openai.py +1 -0
- gitcode_api-1.2.14/gitcode_api/resources/_shared.py +435 -0
- {gitcode_api-1.2.13 → gitcode_api-1.2.14}/gitcode_api/resources/collaboration.py +225 -1
- gitcode_api-1.2.14/gitcode_api/utils.py +37 -0
- gitcode_api-1.2.14/gitcode_api/version.txt +1 -0
- {gitcode_api-1.2.13 → gitcode_api-1.2.14}/gitcode_api.egg-info/PKG-INFO +22 -2
- {gitcode_api-1.2.13 → gitcode_api-1.2.14}/gitcode_api.egg-info/SOURCES.txt +4 -1
- {gitcode_api-1.2.13 → gitcode_api-1.2.14}/pyproject.toml +1 -1
- gitcode_api-1.2.14/tests/test_collaboration_templates.py +282 -0
- gitcode_api-1.2.14/tests/test_utils.py +26 -0
- gitcode_api-1.2.13/gitcode_api/resources/_shared.py +0 -129
- gitcode_api-1.2.13/gitcode_api/version.txt +0 -1
- {gitcode_api-1.2.13 → gitcode_api-1.2.14}/LICENSE +0 -0
- {gitcode_api-1.2.13 → gitcode_api-1.2.14}/gitcode_api/__main__.py +0 -0
- {gitcode_api-1.2.13 → gitcode_api-1.2.14}/gitcode_api/_base_client.py +0 -0
- {gitcode_api-1.2.13 → gitcode_api-1.2.14}/gitcode_api/_base_resource.py +0 -0
- {gitcode_api-1.2.13 → gitcode_api-1.2.14}/gitcode_api/_cli_banner.py +0 -0
- {gitcode_api-1.2.13 → gitcode_api-1.2.14}/gitcode_api/_client.py +0 -0
- {gitcode_api-1.2.13 → gitcode_api-1.2.14}/gitcode_api/_exceptions.py +0 -0
- {gitcode_api-1.2.13 → gitcode_api-1.2.14}/gitcode_api/cli.py +0 -0
- {gitcode_api-1.2.13 → gitcode_api-1.2.14}/gitcode_api/llm/__init__.py +0 -0
- {gitcode_api-1.2.13 → gitcode_api-1.2.14}/gitcode_api/llm/_tool.py +0 -0
- {gitcode_api-1.2.13 → gitcode_api-1.2.14}/gitcode_api/llm/jiuwen.py +0 -0
- {gitcode_api-1.2.13 → gitcode_api-1.2.14}/gitcode_api/llm/mcp.py +0 -0
- {gitcode_api-1.2.13 → gitcode_api-1.2.14}/gitcode_api/py.typed +0 -0
- {gitcode_api-1.2.13 → gitcode_api-1.2.14}/gitcode_api/resources/__init__.py +0 -0
- {gitcode_api-1.2.13 → gitcode_api-1.2.14}/gitcode_api/resources/account.py +0 -0
- {gitcode_api-1.2.13 → gitcode_api-1.2.14}/gitcode_api/resources/misc.py +0 -0
- {gitcode_api-1.2.13 → gitcode_api-1.2.14}/gitcode_api/resources/repositories.py +0 -0
- {gitcode_api-1.2.13 → gitcode_api-1.2.14}/gitcode_api/run_mcp.py +0 -0
- {gitcode_api-1.2.13 → gitcode_api-1.2.14}/gitcode_api.egg-info/dependency_links.txt +0 -0
- {gitcode_api-1.2.13 → gitcode_api-1.2.14}/gitcode_api.egg-info/entry_points.txt +0 -0
- {gitcode_api-1.2.13 → gitcode_api-1.2.14}/gitcode_api.egg-info/requires.txt +0 -0
- {gitcode_api-1.2.13 → gitcode_api-1.2.14}/gitcode_api.egg-info/top_level.txt +0 -0
- {gitcode_api-1.2.13 → gitcode_api-1.2.14}/setup.cfg +0 -0
- {gitcode_api-1.2.13 → gitcode_api-1.2.14}/tests/test_base_client.py +0 -0
- {gitcode_api-1.2.13 → gitcode_api-1.2.14}/tests/test_build_manifest.py +0 -0
- {gitcode_api-1.2.13 → gitcode_api-1.2.14}/tests/test_cli.py +0 -0
- {gitcode_api-1.2.13 → gitcode_api-1.2.14}/tests/test_client.py +0 -0
- {gitcode_api-1.2.13 → gitcode_api-1.2.14}/tests/test_llm_tools.py +0 -0
- {gitcode_api-1.2.13 → gitcode_api-1.2.14}/tests/test_models.py +0 -0
- {gitcode_api-1.2.13 → gitcode_api-1.2.14}/tests/test_resources_account.py +0 -0
- {gitcode_api-1.2.13 → gitcode_api-1.2.14}/tests/test_resources_collaboration.py +0 -0
- {gitcode_api-1.2.13 → gitcode_api-1.2.14}/tests/test_resources_misc.py +0 -0
- {gitcode_api-1.2.13 → gitcode_api-1.2.14}/tests/test_resources_repositories.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: gitcode-api
|
|
3
|
-
Version: 1.2.
|
|
3
|
+
Version: 1.2.14
|
|
4
4
|
Summary: Easy to use Python SDK for the GitCode REST API. Providing builtin CLI tool, and optional LLM integration (MCP, OpenAI tool, and openJiuwen tool) for agents. Community-maintained.
|
|
5
5
|
Author-email: Hugo Huang <hugo@hugohuang.com>
|
|
6
6
|
License-Expression: MIT
|
|
@@ -37,7 +37,7 @@ Dynamic: license-file
|
|
|
37
37
|
|
|
38
38
|
# GitCode-API
|
|
39
39
|
|
|
40
|
-
[](https://pypi.org/project/gitcode-api) [](https://pepy.tech/projects/gitcode-api) [](https://www.codefactor.io/repository/github/trenza1ore/gitcode-api)
|
|
41
41
|
[](https://cursor.com/en/install-mcp?name=GitCode%20API&config=eyJjb21tYW5kIjoidXZ4IiwiYXJncyI6WyItLWZyb20iLCJnaXRjb2RlLWFwaVttY3BdIiwiZ2l0Y29kZS1hcGkiLCJzZXJ2ZSJdLCJlbnYiOnsiR0lUQ09ERV9BQ0NFU1NfVE9LRU4iOiIke2lucHV0OmdpdGNvZGVfYWNjZXNzX3Rva2VufSJ9LCJpbnB1dHMiOlt7ImlkIjoiZ2l0Y29kZV9hY2Nlc3NfdG9rZW4iLCJ0eXBlIjoicHJvbXB0U3RyaW5nIiwiZGVzY3JpcHRpb24iOiJFbnRlciBHSVRDT0RFX0FDQ0VTU19UT0tFTiIsInBhc3N3b3JkIjp0cnVlfV19) [](https://vscode.dev/redirect/mcp/install?name=GitCode%20API&config=%7B%22command%22%3A%22uvx%22%2C%22args%22%3A%5B%22--from%22%2C%22gitcode-api%5Bmcp%5D%22%2C%22gitcode-api%22%2C%22serve%22%5D%2C%22env%22%3A%7B%22GITCODE_ACCESS_TOKEN%22%3A%22%24%7Binput%3Agitcode_access_token%7D%22%7D%2C%22inputs%22%3A%5B%7B%22id%22%3A%22gitcode_access_token%22%2C%22type%22%3A%22promptString%22%2C%22description%22%3A%22Enter%20GITCODE_ACCESS_TOKEN%22%2C%22password%22%3Atrue%7D%5D%7D)
|
|
42
42
|
[](https://github.com/Trenza1ore/GitCode-API) [](https://gitcode.com/SushiNinja/GitCode-API)
|
|
43
43
|
|
|
@@ -49,6 +49,7 @@ Dynamic: license-file
|
|
|
49
49
|
|
|
50
50
|
- Community project for developers who want a practical GitCode Python library.
|
|
51
51
|
- Sync and async clients with a consistent API surface.
|
|
52
|
+
- Convenient methods not offered by REST API directly: such as fetching Issue and PR templates.
|
|
52
53
|
- Resource groups such as `client.repos`, `client.pulls`, and `client.users`.
|
|
53
54
|
- Repository defaults via `owner=` and `repo=` on the client.
|
|
54
55
|
- Sphinx docs plus a mirrored GitCode REST API reference in `docs/`.
|
|
@@ -153,6 +154,21 @@ async def main() -> None:
|
|
|
153
154
|
asyncio.run(main())
|
|
154
155
|
```
|
|
155
156
|
|
|
157
|
+
### Convert typed return objects to dicts with `as_dict`
|
|
158
|
+
|
|
159
|
+
Response values are typed `APIObject` subclasses. For serialization or code that expects built-in `dict`, import `as_dict` from the package root: pass a single model to get a `dict`, or pass a list (for example from `client.pulls.list(...)`) to get `list[dict]`. This mirrors the idea of `dataclasses.asdict` but uses each model’s `to_dict()` method. Use `deep_copy=True` when you need detached deep copies.
|
|
160
|
+
|
|
161
|
+
```python
|
|
162
|
+
from gitcode_api import GitCode, as_dict
|
|
163
|
+
|
|
164
|
+
client = GitCode(owner="SushiNinja")
|
|
165
|
+
pulls = client.pulls.list_templates(repo="GitCode-API")
|
|
166
|
+
payload = as_dict(pulls) # list[dict]
|
|
167
|
+
|
|
168
|
+
repo = client.repos.get(repo="GitCode-API")
|
|
169
|
+
meta = as_dict(repo) # dict
|
|
170
|
+
```
|
|
171
|
+
|
|
156
172
|
### Context managers
|
|
157
173
|
|
|
158
174
|
`GitCode` and `AsyncGitCode` (and the lower-level `SyncAPIClient` / `AsyncAPIClient`) support `with` / `async with`. Leaving the block calls `close()` / `await close()` on the underlying client automatically, including a custom `http_client=` you passed in. `close()` also clears the LRU cache used by each resource group's `method_signature(...)` helper (see the [Available Resources](#available-resources) section).
|
|
@@ -354,6 +370,8 @@ Runnable examples live in `examples/`:
|
|
|
354
370
|
|
|
355
371
|
- `get_current_user.py`
|
|
356
372
|
- `get_repository_overview.py`
|
|
373
|
+
- `get_issue_templates.py`
|
|
374
|
+
- `get_pull_request_templates.py`
|
|
357
375
|
- `list_pull_requests.py`
|
|
358
376
|
- `async_list_branches.py`
|
|
359
377
|
|
|
@@ -362,6 +380,8 @@ Example scripts load shared configuration from `examples/.env` using `python-dot
|
|
|
362
380
|
```bash
|
|
363
381
|
uv run python examples/get_current_user.py
|
|
364
382
|
uv run python examples/get_repository_overview.py
|
|
383
|
+
uv run python examples/get_issue_templates.py
|
|
384
|
+
uv run python examples/get_pull_request_templates.py
|
|
365
385
|
uv run python examples/list_pull_requests.py
|
|
366
386
|
uv run python examples/async_list_branches.py
|
|
367
387
|
```
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# GitCode-API
|
|
2
2
|
|
|
3
|
-
[](https://pypi.org/project/gitcode-api) [](https://pepy.tech/projects/gitcode-api) [](https://www.codefactor.io/repository/github/trenza1ore/gitcode-api)
|
|
4
4
|
[](https://cursor.com/en/install-mcp?name=GitCode%20API&config=eyJjb21tYW5kIjoidXZ4IiwiYXJncyI6WyItLWZyb20iLCJnaXRjb2RlLWFwaVttY3BdIiwiZ2l0Y29kZS1hcGkiLCJzZXJ2ZSJdLCJlbnYiOnsiR0lUQ09ERV9BQ0NFU1NfVE9LRU4iOiIke2lucHV0OmdpdGNvZGVfYWNjZXNzX3Rva2VufSJ9LCJpbnB1dHMiOlt7ImlkIjoiZ2l0Y29kZV9hY2Nlc3NfdG9rZW4iLCJ0eXBlIjoicHJvbXB0U3RyaW5nIiwiZGVzY3JpcHRpb24iOiJFbnRlciBHSVRDT0RFX0FDQ0VTU19UT0tFTiIsInBhc3N3b3JkIjp0cnVlfV19) [](https://vscode.dev/redirect/mcp/install?name=GitCode%20API&config=%7B%22command%22%3A%22uvx%22%2C%22args%22%3A%5B%22--from%22%2C%22gitcode-api%5Bmcp%5D%22%2C%22gitcode-api%22%2C%22serve%22%5D%2C%22env%22%3A%7B%22GITCODE_ACCESS_TOKEN%22%3A%22%24%7Binput%3Agitcode_access_token%7D%22%7D%2C%22inputs%22%3A%5B%7B%22id%22%3A%22gitcode_access_token%22%2C%22type%22%3A%22promptString%22%2C%22description%22%3A%22Enter%20GITCODE_ACCESS_TOKEN%22%2C%22password%22%3Atrue%7D%5D%7D)
|
|
5
5
|
[](https://github.com/Trenza1ore/GitCode-API) [](https://gitcode.com/SushiNinja/GitCode-API)
|
|
6
6
|
|
|
@@ -12,6 +12,7 @@
|
|
|
12
12
|
|
|
13
13
|
- Community project for developers who want a practical GitCode Python library.
|
|
14
14
|
- Sync and async clients with a consistent API surface.
|
|
15
|
+
- Convenient methods not offered by REST API directly: such as fetching Issue and PR templates.
|
|
15
16
|
- Resource groups such as `client.repos`, `client.pulls`, and `client.users`.
|
|
16
17
|
- Repository defaults via `owner=` and `repo=` on the client.
|
|
17
18
|
- Sphinx docs plus a mirrored GitCode REST API reference in `docs/`.
|
|
@@ -116,6 +117,21 @@ async def main() -> None:
|
|
|
116
117
|
asyncio.run(main())
|
|
117
118
|
```
|
|
118
119
|
|
|
120
|
+
### Convert typed return objects to dicts with `as_dict`
|
|
121
|
+
|
|
122
|
+
Response values are typed `APIObject` subclasses. For serialization or code that expects built-in `dict`, import `as_dict` from the package root: pass a single model to get a `dict`, or pass a list (for example from `client.pulls.list(...)`) to get `list[dict]`. This mirrors the idea of `dataclasses.asdict` but uses each model’s `to_dict()` method. Use `deep_copy=True` when you need detached deep copies.
|
|
123
|
+
|
|
124
|
+
```python
|
|
125
|
+
from gitcode_api import GitCode, as_dict
|
|
126
|
+
|
|
127
|
+
client = GitCode(owner="SushiNinja")
|
|
128
|
+
pulls = client.pulls.list_templates(repo="GitCode-API")
|
|
129
|
+
payload = as_dict(pulls) # list[dict]
|
|
130
|
+
|
|
131
|
+
repo = client.repos.get(repo="GitCode-API")
|
|
132
|
+
meta = as_dict(repo) # dict
|
|
133
|
+
```
|
|
134
|
+
|
|
119
135
|
### Context managers
|
|
120
136
|
|
|
121
137
|
`GitCode` and `AsyncGitCode` (and the lower-level `SyncAPIClient` / `AsyncAPIClient`) support `with` / `async with`. Leaving the block calls `close()` / `await close()` on the underlying client automatically, including a custom `http_client=` you passed in. `close()` also clears the LRU cache used by each resource group's `method_signature(...)` helper (see the [Available Resources](#available-resources) section).
|
|
@@ -317,6 +333,8 @@ Runnable examples live in `examples/`:
|
|
|
317
333
|
|
|
318
334
|
- `get_current_user.py`
|
|
319
335
|
- `get_repository_overview.py`
|
|
336
|
+
- `get_issue_templates.py`
|
|
337
|
+
- `get_pull_request_templates.py`
|
|
320
338
|
- `list_pull_requests.py`
|
|
321
339
|
- `async_list_branches.py`
|
|
322
340
|
|
|
@@ -325,6 +343,8 @@ Example scripts load shared configuration from `examples/.env` using `python-dot
|
|
|
325
343
|
```bash
|
|
326
344
|
uv run python examples/get_current_user.py
|
|
327
345
|
uv run python examples/get_repository_overview.py
|
|
346
|
+
uv run python examples/get_issue_templates.py
|
|
347
|
+
uv run python examples/get_pull_request_templates.py
|
|
328
348
|
uv run python examples/list_pull_requests.py
|
|
329
349
|
uv run python examples/async_list_branches.py
|
|
330
350
|
```
|
|
@@ -9,6 +9,7 @@ from ._exceptions import (
|
|
|
9
9
|
GitCodeError,
|
|
10
10
|
GitCodeHTTPStatusError,
|
|
11
11
|
)
|
|
12
|
+
from .utils import as_dict
|
|
12
13
|
|
|
13
14
|
__version__ = (Path(__file__).parent / "version.txt").read_text().strip()
|
|
14
15
|
|
|
@@ -20,4 +21,5 @@ __all__ = [
|
|
|
20
21
|
"GitCodeConfigurationError",
|
|
21
22
|
"GitCodeError",
|
|
22
23
|
"GitCodeHTTPStatusError",
|
|
24
|
+
"as_dict",
|
|
23
25
|
]
|
|
@@ -9,7 +9,6 @@ from typing import (
|
|
|
9
9
|
Mapping,
|
|
10
10
|
MutableMapping,
|
|
11
11
|
Optional,
|
|
12
|
-
TypedDict,
|
|
13
12
|
TypeVar,
|
|
14
13
|
Union,
|
|
15
14
|
get_args,
|
|
@@ -136,60 +135,6 @@ def as_model_list(data: List[Mapping[str, Any]], model_type: type[ModelT]) -> Li
|
|
|
136
135
|
return [as_model(item, model_type) for item in data]
|
|
137
136
|
|
|
138
137
|
|
|
139
|
-
class RepositoryCreateParams(TypedDict, total=False):
|
|
140
|
-
"""Typed fields accepted by repository creation endpoints."""
|
|
141
|
-
|
|
142
|
-
name: str
|
|
143
|
-
description: str
|
|
144
|
-
has_issues: bool
|
|
145
|
-
has_wiki: bool
|
|
146
|
-
auto_init: bool
|
|
147
|
-
gitignore_template: str
|
|
148
|
-
license_template: str
|
|
149
|
-
path: str
|
|
150
|
-
private: bool
|
|
151
|
-
public: int
|
|
152
|
-
default_branch: str
|
|
153
|
-
homepage: str
|
|
154
|
-
can_comment: bool
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
class IssueCreateParams(TypedDict, total=False):
|
|
158
|
-
"""Typed fields accepted by issue creation endpoints."""
|
|
159
|
-
|
|
160
|
-
title: str
|
|
161
|
-
body: str
|
|
162
|
-
assignee: str
|
|
163
|
-
labels: List[str]
|
|
164
|
-
milestone: Union[int, str]
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
class PullRequestCreateParams(TypedDict, total=False):
|
|
168
|
-
"""Typed fields accepted by pull request creation endpoints."""
|
|
169
|
-
|
|
170
|
-
title: str
|
|
171
|
-
body: str
|
|
172
|
-
head: str
|
|
173
|
-
base: str
|
|
174
|
-
assignees: List[str]
|
|
175
|
-
testers: List[str]
|
|
176
|
-
labels: List[str]
|
|
177
|
-
draft: bool
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
class WebhookCreateParams(TypedDict, total=False):
|
|
181
|
-
"""Typed fields accepted by webhook creation endpoints."""
|
|
182
|
-
|
|
183
|
-
url: str
|
|
184
|
-
encryption_type: int
|
|
185
|
-
password: str
|
|
186
|
-
push_events: bool
|
|
187
|
-
tag_push_events: bool
|
|
188
|
-
issues_events: bool
|
|
189
|
-
note_events: bool
|
|
190
|
-
merge_requests_events: bool
|
|
191
|
-
|
|
192
|
-
|
|
193
138
|
@dataclass(init=False)
|
|
194
139
|
class UserRef(APIObject):
|
|
195
140
|
"""Compact user payload embedded in other responses.
|
|
@@ -513,6 +458,8 @@ class Repository(APIObject):
|
|
|
513
458
|
:vartype relation: Optional[str]
|
|
514
459
|
:ivar members: Members returned in the repository payload.
|
|
515
460
|
:vartype members: Optional[List[str]]
|
|
461
|
+
:ivar parent: Upstream source repository information
|
|
462
|
+
:vartype parent: Optional[Dict[str, Any]]
|
|
516
463
|
:ivar permission: Permission summary for this object.
|
|
517
464
|
:vartype permission: Optional[RepositoryPermission]
|
|
518
465
|
:ivar enterprise: Enterprise associated with the repository.
|
|
@@ -566,6 +513,7 @@ class Repository(APIObject):
|
|
|
566
513
|
status: Optional[str] = None
|
|
567
514
|
relation: Optional[str] = None
|
|
568
515
|
members: Optional[List[str]] = None
|
|
516
|
+
parent: Optional[Dict[str, Any]] = None
|
|
569
517
|
permission: Optional[RepositoryPermission] = None
|
|
570
518
|
enterprise: Optional[Union[EnterpriseRef, str]] = None
|
|
571
519
|
issue_template_source: Optional[str] = None
|
|
@@ -760,6 +708,31 @@ class ContentObject(APIObject):
|
|
|
760
708
|
_links: Optional[ContentLinks] = None
|
|
761
709
|
|
|
762
710
|
|
|
711
|
+
@dataclass(init=False)
|
|
712
|
+
class RepositoryGitCodeTemplate(APIObject):
|
|
713
|
+
"""Metadata for a ``.gitcode`` issue or pull request template file.
|
|
714
|
+
|
|
715
|
+
Returned by :meth:`~gitcode_api.resources.collaboration.IssuesResource.list_templates`
|
|
716
|
+
and :meth:`~gitcode_api.resources.collaboration.PullsResource.list_templates`. Use
|
|
717
|
+
:meth:`~gitcode_api.resources.collaboration.IssuesResource.get_template` or
|
|
718
|
+
:meth:`~gitcode_api.resources.collaboration.PullsResource.get_template` to load the body.
|
|
719
|
+
|
|
720
|
+
:ivar path: Repository-relative path (under ``.gitcode/``).
|
|
721
|
+
:vartype path: Optional[str]
|
|
722
|
+
:ivar sha: Object SHA for the file.
|
|
723
|
+
:vartype sha: Optional[str]
|
|
724
|
+
:ivar template_owner: Owner path of the repository the template was resolved from.
|
|
725
|
+
:vartype template_owner: Optional[str]
|
|
726
|
+
:ivar template_repo: Repository name the template was resolved from.
|
|
727
|
+
:vartype template_repo: Optional[str]
|
|
728
|
+
"""
|
|
729
|
+
|
|
730
|
+
path: Optional[str] = None
|
|
731
|
+
sha: Optional[str] = None
|
|
732
|
+
template_owner: Optional[str] = None
|
|
733
|
+
template_repo: Optional[str] = None
|
|
734
|
+
|
|
735
|
+
|
|
763
736
|
@dataclass(init=False)
|
|
764
737
|
class CommitIdentity(APIObject):
|
|
765
738
|
"""Commit author/committer identity.
|
|
@@ -75,6 +75,7 @@ class GitCodeOpenAITool(GitCodeLLMTool):
|
|
|
75
75
|
return self.tool
|
|
76
76
|
|
|
77
77
|
async def __async_call__(self, *args, **kwargs) -> str:
|
|
78
|
+
"""Invoke the configured async tool callable."""
|
|
78
79
|
result = await super().__async_call__(*args, **kwargs)
|
|
79
80
|
return json.dumps(result, ensure_ascii=False, indent=self.indent)
|
|
80
81
|
|