label-studio-sdk 2.0.1__py3-none-any.whl → 2.0.2__py3-none-any.whl
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.
Potentially problematic release.
This version of label-studio-sdk might be problematic. Click here for more details.
- label_studio_sdk/__init__.py +4 -0
- label_studio_sdk/actions/client.py +13 -13
- label_studio_sdk/actions/types/actions_list_response_item.py +3 -3
- label_studio_sdk/actions/types/actions_list_response_item_dialog.py +2 -2
- label_studio_sdk/annotations/client.py +441 -441
- label_studio_sdk/comments/client.py +176 -176
- label_studio_sdk/export_storage/azure/client.py +274 -274
- label_studio_sdk/export_storage/gcs/client.py +263 -263
- label_studio_sdk/export_storage/local/client.py +206 -206
- label_studio_sdk/export_storage/redis/client.py +287 -287
- label_studio_sdk/export_storage/s3/client.py +347 -347
- label_studio_sdk/export_storage/s3s/client.py +678 -678
- label_studio_sdk/import_storage/azure/client.py +357 -357
- label_studio_sdk/import_storage/gcs/client.py +357 -357
- label_studio_sdk/import_storage/local/client.py +206 -206
- label_studio_sdk/import_storage/redis/client.py +309 -309
- label_studio_sdk/import_storage/s3/client.py +452 -452
- label_studio_sdk/import_storage/s3s/client.py +735 -735
- label_studio_sdk/jwt_settings/client.py +10 -10
- label_studio_sdk/ml/client.py +118 -118
- label_studio_sdk/ml/types/ml_list_model_versions_response.py +1 -1
- label_studio_sdk/model_providers/client.py +181 -181
- label_studio_sdk/organizations/members/client.py +8 -8
- label_studio_sdk/predictions/client.py +60 -60
- label_studio_sdk/projects/__init__.py +30 -1
- label_studio_sdk/projects/assignments/__init__.py +33 -0
- label_studio_sdk/projects/assignments/client.py +764 -0
- label_studio_sdk/projects/assignments/types/__init__.py +35 -0
- label_studio_sdk/projects/assignments/types/assignments_assign_request_type.py +5 -0
- label_studio_sdk/projects/assignments/types/assignments_bulk_assign_request_filters.py +33 -0
- label_studio_sdk/projects/assignments/types/assignments_bulk_assign_request_filters_conjunction.py +5 -0
- label_studio_sdk/projects/assignments/types/assignments_bulk_assign_request_filters_items_item.py +44 -0
- label_studio_sdk/projects/assignments/types/assignments_bulk_assign_request_filters_items_item_filter.py +31 -0
- label_studio_sdk/projects/assignments/types/assignments_bulk_assign_request_filters_items_item_operator.py +23 -0
- label_studio_sdk/projects/assignments/types/assignments_bulk_assign_request_filters_items_item_value.py +7 -0
- label_studio_sdk/projects/assignments/types/assignments_bulk_assign_request_selected_items.py +9 -0
- label_studio_sdk/projects/assignments/types/assignments_bulk_assign_request_selected_items_excluded.py +29 -0
- label_studio_sdk/projects/assignments/types/assignments_bulk_assign_request_selected_items_included.py +29 -0
- label_studio_sdk/projects/assignments/types/assignments_bulk_assign_request_type.py +5 -0
- label_studio_sdk/projects/assignments/types/assignments_bulk_assign_response.py +22 -0
- label_studio_sdk/projects/assignments/types/assignments_update_request_type.py +5 -0
- label_studio_sdk/projects/client.py +441 -425
- label_studio_sdk/projects/exports/client.py +55 -55
- label_studio_sdk/projects/exports/types/exports_convert_response.py +1 -1
- label_studio_sdk/projects/stats/types/stats_iaa_response.py +5 -5
- label_studio_sdk/projects/types/projects_import_tasks_response.py +12 -12
- label_studio_sdk/prompts/client.py +211 -211
- label_studio_sdk/prompts/runs/client.py +33 -33
- label_studio_sdk/prompts/versions/client.py +72 -72
- label_studio_sdk/tasks/client.py +174 -174
- label_studio_sdk/types/__init__.py +4 -0
- label_studio_sdk/types/all_roles_project_list.py +94 -94
- label_studio_sdk/types/annotation.py +35 -35
- label_studio_sdk/types/annotation_request.py +27 -27
- label_studio_sdk/types/azure_blob_export_storage.py +29 -29
- label_studio_sdk/types/azure_blob_import_storage.py +33 -33
- label_studio_sdk/types/batch_failed_predictions.py +1 -1
- label_studio_sdk/types/billing_checks.py +14 -14
- label_studio_sdk/types/billing_flags.py +16 -16
- label_studio_sdk/types/blueprint_list.py +7 -8
- label_studio_sdk/types/child_filter.py +11 -10
- label_studio_sdk/types/comment.py +15 -15
- label_studio_sdk/types/comment_request.py +7 -8
- label_studio_sdk/types/comment_serializer_with_expanded_user.py +17 -18
- label_studio_sdk/types/converted_format.py +1 -1
- label_studio_sdk/types/converted_format_request.py +1 -1
- label_studio_sdk/types/export.py +8 -8
- label_studio_sdk/types/file_upload.py +3 -2
- label_studio_sdk/types/filter.py +10 -9
- label_studio_sdk/types/filter_group.py +4 -3
- label_studio_sdk/types/gcs_export_storage.py +23 -23
- label_studio_sdk/types/gcs_import_storage.py +27 -27
- label_studio_sdk/types/import_api_request.py +26 -26
- label_studio_sdk/types/inference_run_cost_estimate.py +10 -10
- label_studio_sdk/types/local_files_export_storage.py +23 -23
- label_studio_sdk/types/local_files_import_storage.py +26 -26
- label_studio_sdk/types/lse_annotation_filter_options.py +10 -10
- label_studio_sdk/types/lse_annotation_filter_options_request.py +10 -10
- label_studio_sdk/types/lse_export_create.py +12 -12
- label_studio_sdk/types/lse_fields.py +14 -14
- label_studio_sdk/types/lse_organization.py +17 -17
- label_studio_sdk/types/lse_organization_member_list.py +1 -1
- label_studio_sdk/types/lse_project_create.py +72 -72
- label_studio_sdk/types/lse_project_update.py +89 -89
- label_studio_sdk/types/lse_s3export_storage.py +46 -46
- label_studio_sdk/types/lse_s3export_storage_request.py +43 -43
- label_studio_sdk/types/lse_s3import_storage.py +53 -53
- label_studio_sdk/types/lse_s3import_storage_request.py +49 -49
- label_studio_sdk/types/lse_task.py +49 -49
- label_studio_sdk/types/lse_task_drafts_item.py +1 -1
- label_studio_sdk/types/lse_task_filter_options.py +14 -14
- label_studio_sdk/types/lse_task_filter_options_request.py +14 -14
- label_studio_sdk/types/lse_task_predictions_item.py +5 -5
- label_studio_sdk/types/lse_task_serializer_for_annotators.py +12 -12
- label_studio_sdk/types/lse_task_serializer_for_annotators_drafts_item.py +1 -1
- label_studio_sdk/types/lse_task_serializer_for_annotators_predictions_item.py +5 -5
- label_studio_sdk/types/lse_task_serializer_for_reviewers.py +49 -49
- label_studio_sdk/types/lse_task_serializer_for_reviewers_drafts_item.py +1 -1
- label_studio_sdk/types/lse_task_serializer_for_reviewers_predictions_item.py +5 -5
- label_studio_sdk/types/lse_user.py +13 -13
- label_studio_sdk/types/lse_user_api.py +11 -11
- label_studio_sdk/types/lse_user_organization_member_list.py +13 -13
- label_studio_sdk/types/lseapi_token_create.py +1 -1
- label_studio_sdk/types/lseapi_token_list.py +1 -1
- label_studio_sdk/types/lsejwt_settings.py +5 -5
- label_studio_sdk/types/ml_backend.py +27 -28
- label_studio_sdk/types/model_interface.py +12 -12
- label_studio_sdk/types/model_interface_request.py +7 -8
- label_studio_sdk/types/model_interface_serializer_get.py +13 -13
- label_studio_sdk/types/model_provider_connection.py +34 -34
- label_studio_sdk/types/model_provider_connection_request.py +15 -14
- label_studio_sdk/types/model_run.py +12 -12
- label_studio_sdk/types/organization_billing.py +1 -1
- label_studio_sdk/types/organization_id.py +2 -2
- label_studio_sdk/types/organization_invite.py +1 -1
- label_studio_sdk/types/organization_member.py +8 -9
- label_studio_sdk/types/organization_membership.py +2 -1
- label_studio_sdk/types/pause.py +23 -23
- label_studio_sdk/types/prediction.py +21 -21
- label_studio_sdk/types/prediction_request.py +16 -16
- label_studio_sdk/types/project.py +72 -72
- label_studio_sdk/types/project_import.py +21 -21
- label_studio_sdk/types/redis_export_storage.py +34 -34
- label_studio_sdk/types/redis_import_storage.py +37 -37
- label_studio_sdk/types/refined_prompt_response.py +11 -11
- label_studio_sdk/types/review_settings.py +29 -30
- label_studio_sdk/types/review_settings_request.py +29 -30
- label_studio_sdk/types/s3export_storage.py +45 -45
- label_studio_sdk/types/s3import_storage.py +44 -44
- label_studio_sdk/types/selected_items_request.py +1 -1
- label_studio_sdk/types/serialization_options.py +10 -10
- label_studio_sdk/types/serialization_options_request.py +10 -10
- label_studio_sdk/types/task_assignment.py +43 -0
- label_studio_sdk/types/third_party_model_version.py +11 -11
- label_studio_sdk/types/third_party_model_version_request.py +6 -7
- label_studio_sdk/types/type_enum.py +5 -0
- label_studio_sdk/types/user_simple.py +3 -3
- label_studio_sdk/types/user_simple_request.py +1 -1
- label_studio_sdk/types/version_response.py +19 -20
- label_studio_sdk/types/view.py +8 -8
- label_studio_sdk/types/webhook.py +16 -16
- label_studio_sdk/types/webhook_serializer_for_update.py +16 -16
- label_studio_sdk/types/workspace.py +10 -11
- label_studio_sdk/users/client.py +160 -160
- label_studio_sdk/views/client.py +164 -164
- label_studio_sdk/webhooks/client.py +183 -183
- label_studio_sdk/webhooks/types/webhooks_info_response.py +32 -32
- label_studio_sdk/webhooks/types/webhooks_info_response_annotation_created.py +1 -1
- label_studio_sdk/webhooks/types/webhooks_info_response_annotation_updated.py +1 -1
- label_studio_sdk/webhooks/types/webhooks_info_response_annotations_created.py +1 -1
- label_studio_sdk/webhooks/types/webhooks_info_response_annotations_deleted.py +1 -1
- label_studio_sdk/webhooks/types/webhooks_info_response_label_link_created.py +1 -1
- label_studio_sdk/webhooks/types/webhooks_info_response_label_link_deleted.py +1 -1
- label_studio_sdk/webhooks/types/webhooks_info_response_label_link_updated.py +1 -1
- label_studio_sdk/webhooks/types/webhooks_info_response_project_created.py +1 -1
- label_studio_sdk/webhooks/types/webhooks_info_response_project_deleted.py +1 -1
- label_studio_sdk/webhooks/types/webhooks_info_response_project_updated.py +1 -1
- label_studio_sdk/webhooks/types/webhooks_info_response_review_created.py +1 -1
- label_studio_sdk/webhooks/types/webhooks_info_response_review_updated.py +1 -1
- label_studio_sdk/webhooks/types/webhooks_info_response_reviews_deleted.py +1 -1
- label_studio_sdk/webhooks/types/webhooks_info_response_tasks_created.py +1 -1
- label_studio_sdk/webhooks/types/webhooks_info_response_tasks_deleted.py +1 -1
- label_studio_sdk/workspaces/client.py +40 -40
- {label_studio_sdk-2.0.1.dist-info → label_studio_sdk-2.0.2.dist-info}/METADATA +1 -1
- {label_studio_sdk-2.0.1.dist-info → label_studio_sdk-2.0.2.dist-info}/RECORD +167 -149
- {label_studio_sdk-2.0.1.dist-info → label_studio_sdk-2.0.2.dist-info}/LICENSE +0 -0
- {label_studio_sdk-2.0.1.dist-info → label_studio_sdk-2.0.2.dist-info}/WHEEL +0 -0
label_studio_sdk/__init__.py
CHANGED
|
@@ -161,11 +161,13 @@ from .types import (
|
|
|
161
161
|
StateEnum,
|
|
162
162
|
Status7BfEnum,
|
|
163
163
|
StatusC5AEnum,
|
|
164
|
+
TaskAssignment,
|
|
164
165
|
ThirdPartyModelVersion,
|
|
165
166
|
ThirdPartyModelVersionRequest,
|
|
166
167
|
TokenRefreshResponse,
|
|
167
168
|
TokenRotateResponse,
|
|
168
169
|
TrialRoleEnum,
|
|
170
|
+
TypeEnum,
|
|
169
171
|
UserSimple,
|
|
170
172
|
UserSimpleRequest,
|
|
171
173
|
VersionResponse,
|
|
@@ -479,12 +481,14 @@ __all__ = [
|
|
|
479
481
|
"StateEnum",
|
|
480
482
|
"Status7BfEnum",
|
|
481
483
|
"StatusC5AEnum",
|
|
484
|
+
"TaskAssignment",
|
|
482
485
|
"TasksListRequestFields",
|
|
483
486
|
"ThirdPartyModelVersion",
|
|
484
487
|
"ThirdPartyModelVersionRequest",
|
|
485
488
|
"TokenRefreshResponse",
|
|
486
489
|
"TokenRotateResponse",
|
|
487
490
|
"TrialRoleEnum",
|
|
491
|
+
"TypeEnum",
|
|
488
492
|
"UnauthorizedError",
|
|
489
493
|
"UserSimple",
|
|
490
494
|
"UserSimpleRequest",
|
|
@@ -9,8 +9,8 @@ from json.decoder import JSONDecodeError
|
|
|
9
9
|
from ..core.api_error import ApiError
|
|
10
10
|
from .types.actions_create_request_id import ActionsCreateRequestId
|
|
11
11
|
from .types.actions_create_request_filters import ActionsCreateRequestFilters
|
|
12
|
-
from .types.actions_create_request_selected_items import ActionsCreateRequestSelectedItems
|
|
13
12
|
from .types.actions_create_request_ordering_item import ActionsCreateRequestOrderingItem
|
|
13
|
+
from .types.actions_create_request_selected_items import ActionsCreateRequestSelectedItems
|
|
14
14
|
from ..core.serialization import convert_and_respect_annotation_metadata
|
|
15
15
|
from ..core.client_wrapper import AsyncClientWrapper
|
|
16
16
|
|
|
@@ -81,8 +81,8 @@ class ActionsClient:
|
|
|
81
81
|
project: int,
|
|
82
82
|
view: typing.Optional[int] = None,
|
|
83
83
|
filters: typing.Optional[ActionsCreateRequestFilters] = OMIT,
|
|
84
|
-
selected_items: typing.Optional[ActionsCreateRequestSelectedItems] = OMIT,
|
|
85
84
|
ordering: typing.Optional[typing.Sequence[ActionsCreateRequestOrderingItem]] = OMIT,
|
|
85
|
+
selected_items: typing.Optional[ActionsCreateRequestSelectedItems] = OMIT,
|
|
86
86
|
request_options: typing.Optional[RequestOptions] = None,
|
|
87
87
|
) -> None:
|
|
88
88
|
"""
|
|
@@ -102,12 +102,12 @@ class ActionsClient:
|
|
|
102
102
|
filters : typing.Optional[ActionsCreateRequestFilters]
|
|
103
103
|
Filters to apply on tasks. You can use [the helper class `Filters` from this page](https://labelstud.io/sdk/data_manager.html) to create Data Manager Filters.<br>Example: `{"conjunction": "or", "items": [{"filter": "filter:tasks:completed_at", "operator": "greater", "type": "Datetime", "value": "2021-01-01T00:00:00.000Z"}]}`
|
|
104
104
|
|
|
105
|
-
selected_items : typing.Optional[ActionsCreateRequestSelectedItems]
|
|
106
|
-
Task selection by IDs. If filters are applied, the selection will be applied to the filtered tasks.If "all" is `false`, `"included"` must be used. If "all" is `true`, `"excluded"` must be used.<br>Examples: `{"all": false, "included": [1, 2, 3]}` or `{"all": true, "excluded": [4, 5]}`
|
|
107
|
-
|
|
108
105
|
ordering : typing.Optional[typing.Sequence[ActionsCreateRequestOrderingItem]]
|
|
109
106
|
List of fields to order by. Fields are similar to filters but without the `filter:` prefix. To reverse the order, add a minus sign before the field name, e.g. `-tasks:created_at`.
|
|
110
107
|
|
|
108
|
+
selected_items : typing.Optional[ActionsCreateRequestSelectedItems]
|
|
109
|
+
Task selection by IDs. If filters are applied, the selection will be applied to the filtered tasks.If "all" is `false`, `"included"` must be used. If "all" is `true`, `"excluded"` must be used.<br>Examples: `{"all": false, "included": [1, 2, 3]}` or `{"all": true, "excluded": [4, 5]}`
|
|
110
|
+
|
|
111
111
|
request_options : typing.Optional[RequestOptions]
|
|
112
112
|
Request-specific configuration.
|
|
113
113
|
|
|
@@ -141,11 +141,11 @@ class ActionsClient:
|
|
|
141
141
|
)
|
|
142
142
|
],
|
|
143
143
|
),
|
|
144
|
+
ordering=["tasks:total_annotations"],
|
|
144
145
|
selected_items=ActionsCreateRequestSelectedItemsExcluded(
|
|
145
146
|
all_=True,
|
|
146
147
|
excluded=[124, 125, 126],
|
|
147
148
|
),
|
|
148
|
-
ordering=["tasks:total_annotations"],
|
|
149
149
|
)
|
|
150
150
|
"""
|
|
151
151
|
_response = self._client_wrapper.httpx_client.request(
|
|
@@ -160,10 +160,10 @@ class ActionsClient:
|
|
|
160
160
|
"filters": convert_and_respect_annotation_metadata(
|
|
161
161
|
object_=filters, annotation=ActionsCreateRequestFilters, direction="write"
|
|
162
162
|
),
|
|
163
|
+
"ordering": ordering,
|
|
163
164
|
"selectedItems": convert_and_respect_annotation_metadata(
|
|
164
165
|
object_=selected_items, annotation=ActionsCreateRequestSelectedItems, direction="write"
|
|
165
166
|
),
|
|
166
|
-
"ordering": ordering,
|
|
167
167
|
},
|
|
168
168
|
headers={
|
|
169
169
|
"content-type": "application/json",
|
|
@@ -251,8 +251,8 @@ class AsyncActionsClient:
|
|
|
251
251
|
project: int,
|
|
252
252
|
view: typing.Optional[int] = None,
|
|
253
253
|
filters: typing.Optional[ActionsCreateRequestFilters] = OMIT,
|
|
254
|
-
selected_items: typing.Optional[ActionsCreateRequestSelectedItems] = OMIT,
|
|
255
254
|
ordering: typing.Optional[typing.Sequence[ActionsCreateRequestOrderingItem]] = OMIT,
|
|
255
|
+
selected_items: typing.Optional[ActionsCreateRequestSelectedItems] = OMIT,
|
|
256
256
|
request_options: typing.Optional[RequestOptions] = None,
|
|
257
257
|
) -> None:
|
|
258
258
|
"""
|
|
@@ -272,12 +272,12 @@ class AsyncActionsClient:
|
|
|
272
272
|
filters : typing.Optional[ActionsCreateRequestFilters]
|
|
273
273
|
Filters to apply on tasks. You can use [the helper class `Filters` from this page](https://labelstud.io/sdk/data_manager.html) to create Data Manager Filters.<br>Example: `{"conjunction": "or", "items": [{"filter": "filter:tasks:completed_at", "operator": "greater", "type": "Datetime", "value": "2021-01-01T00:00:00.000Z"}]}`
|
|
274
274
|
|
|
275
|
-
selected_items : typing.Optional[ActionsCreateRequestSelectedItems]
|
|
276
|
-
Task selection by IDs. If filters are applied, the selection will be applied to the filtered tasks.If "all" is `false`, `"included"` must be used. If "all" is `true`, `"excluded"` must be used.<br>Examples: `{"all": false, "included": [1, 2, 3]}` or `{"all": true, "excluded": [4, 5]}`
|
|
277
|
-
|
|
278
275
|
ordering : typing.Optional[typing.Sequence[ActionsCreateRequestOrderingItem]]
|
|
279
276
|
List of fields to order by. Fields are similar to filters but without the `filter:` prefix. To reverse the order, add a minus sign before the field name, e.g. `-tasks:created_at`.
|
|
280
277
|
|
|
278
|
+
selected_items : typing.Optional[ActionsCreateRequestSelectedItems]
|
|
279
|
+
Task selection by IDs. If filters are applied, the selection will be applied to the filtered tasks.If "all" is `false`, `"included"` must be used. If "all" is `true`, `"excluded"` must be used.<br>Examples: `{"all": false, "included": [1, 2, 3]}` or `{"all": true, "excluded": [4, 5]}`
|
|
280
|
+
|
|
281
281
|
request_options : typing.Optional[RequestOptions]
|
|
282
282
|
Request-specific configuration.
|
|
283
283
|
|
|
@@ -316,11 +316,11 @@ class AsyncActionsClient:
|
|
|
316
316
|
)
|
|
317
317
|
],
|
|
318
318
|
),
|
|
319
|
+
ordering=["tasks:total_annotations"],
|
|
319
320
|
selected_items=ActionsCreateRequestSelectedItemsExcluded(
|
|
320
321
|
all_=True,
|
|
321
322
|
excluded=[124, 125, 126],
|
|
322
323
|
),
|
|
323
|
-
ordering=["tasks:total_annotations"],
|
|
324
324
|
)
|
|
325
325
|
|
|
326
326
|
|
|
@@ -338,10 +338,10 @@ class AsyncActionsClient:
|
|
|
338
338
|
"filters": convert_and_respect_annotation_metadata(
|
|
339
339
|
object_=filters, annotation=ActionsCreateRequestFilters, direction="write"
|
|
340
340
|
),
|
|
341
|
+
"ordering": ordering,
|
|
341
342
|
"selectedItems": convert_and_respect_annotation_metadata(
|
|
342
343
|
object_=selected_items, annotation=ActionsCreateRequestSelectedItems, direction="write"
|
|
343
344
|
),
|
|
344
|
-
"ordering": ordering,
|
|
345
345
|
},
|
|
346
346
|
headers={
|
|
347
347
|
"content-type": "application/json",
|
|
@@ -8,12 +8,12 @@ import pydantic
|
|
|
8
8
|
|
|
9
9
|
|
|
10
10
|
class ActionsListResponseItem(UncheckedBaseModel):
|
|
11
|
+
dialog: typing.Optional[ActionsListResponseItemDialog] = None
|
|
12
|
+
experimental: typing.Optional[bool] = None
|
|
11
13
|
id: typing.Optional[str] = None
|
|
12
|
-
title: typing.Optional[str] = None
|
|
13
14
|
order: typing.Optional[int] = None
|
|
14
15
|
permission: typing.Optional[str] = None
|
|
15
|
-
|
|
16
|
-
dialog: typing.Optional[ActionsListResponseItemDialog] = None
|
|
16
|
+
title: typing.Optional[str] = None
|
|
17
17
|
|
|
18
18
|
if IS_PYDANTIC_V2:
|
|
19
19
|
model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2
|
|
@@ -7,10 +7,10 @@ import pydantic
|
|
|
7
7
|
|
|
8
8
|
|
|
9
9
|
class ActionsListResponseItemDialog(UncheckedBaseModel):
|
|
10
|
-
|
|
10
|
+
form: typing.Optional[typing.List[typing.Dict[str, typing.Optional[typing.Any]]]] = None
|
|
11
11
|
text: typing.Optional[str] = None
|
|
12
|
+
title: typing.Optional[str] = None
|
|
12
13
|
type: typing.Optional[str] = None
|
|
13
|
-
form: typing.Optional[typing.List[typing.Dict[str, typing.Optional[typing.Any]]]] = None
|
|
14
14
|
|
|
15
15
|
if IS_PYDANTIC_V2:
|
|
16
16
|
model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2
|