Skip to content

Commit 49dda05

Browse files
committed
chore: Add Typehinting to tokens module
Signed-off-by: Roger Barker <[email protected]> additional changes to use "Any" and to update additional tokens module files Signed-off-by: Roger Barker <[email protected]> More updates Signed-off-by: Roger Barker <[email protected]> Through token_mint_transactions Signed-off-by: Roger Barker <[email protected]> finished tokens module Signed-off-by: Roger Barker <[email protected]> Finished transaction model Signed-off-by: Roger Barker <[email protected]> chore: Typing README (#151) * chore: starter mypy loose config Signed-off-by: exploreriii <[email protected]> * chore: rename of main README Signed-off-by: exploreriii <[email protected]> * chore: What are Types? Signed-off-by: exploreriii <[email protected]> * chore: What are Type hints?-rest Signed-off-by: exploreriii <[email protected]> * chore: fixing some small types and urls Signed-off-by: exploreriii <[email protected]> * chore: basic contents for typing Signed-off-by: exploreriii <[email protected]> * chore: markdown references for type hinting Signed-off-by: exploreriii <[email protected]> * revert: README core naming Signed-off-by: exploreriii <[email protected]> --------- Signed-off-by: exploreriii <[email protected]> fix: example scripts and README update (#154) * fixed example scripts and readme Signed-off-by: nadinedelia <[email protected]> * added commas Signed-off-by: nadinedelia <[email protected]> --------- Signed-off-by: nadinedelia <[email protected]> feat: add `TransactionRecordQuery` (#144) * feat: add transaction_id field to TransactionReceipt Signed-off-by: dosi <[email protected]> * refactor: store transaction_id in TransactionReceipt Signed-off-by: dosi <[email protected]> * feat: add _from_proto() to TokenNftTransfer Signed-off-by: dosi <[email protected]> * test: add unit test for TokenNftTransfer _from_proto() Signed-off-by: dosi <[email protected]> * test: add unit tests for TransactionRecord Signed-off-by: dosi <[email protected]> * feat: implement TransactionRecord class Signed-off-by: dosi <[email protected]> * sqash s transaction record Signed-off-by: dosi <[email protected]> * feat: implement TransactionRecordQuery Signed-off-by: dosi <[email protected]> * test: implement integration tests for TransactionRecordQuery Signed-off-by: dosi <[email protected]> * test: add unit tests Signed-off-by: dosi <[email protected]> * docs: add query record example Signed-off-by: dosi <[email protected]> * chore: add TransactionRecord and TransactionRecordQuery to __init__.py Signed-off-by: dosi <[email protected]> * docs: add transaction record query to README Signed-off-by: dosi <[email protected]> * test: reduce test_transaction_record_query_execute() lines in TransactionRecordQuery unit tests Signed-off-by: dosi <[email protected]> * feat: add __repr__ method Signed-off-by: Ivan Ivanov <[email protected]> --------- Signed-off-by: dosi <[email protected]> Signed-off-by: Ivan Ivanov <[email protected]> Co-authored-by: Ivan Ivanov <[email protected]> feat: add `AccountInfoQuery` (#142) * feat: add AccountInfo class Signed-off-by: dosi <[email protected]> * test: add unit tests for AccountInfo Signed-off-by: dosi <[email protected]> * feat: add TokenRelationship Signed-off-by: dosi <[email protected]> * test: add unit tests for TokenRelationship Signed-off-by: dosi <[email protected]> * feat: implement AccountInfoQuery Signed-off-by: dosi <[email protected]> * test: add AccountInfoQuery unit tests Signed-off-by: dosi <[email protected]> * test: add AccountInfoQuery integration tests Signed-off-by: dosi <[email protected]> * fix: remove incorrect token freeze validation that blocks creating frozen tokens Signed-off-by: dosi <[email protected]> * docs: add account info query example Signed-off-by: dosi <[email protected]> * docs: update examples README Signed-off-by: dosi <[email protected]> * chore: add AccountInfoQuery to __init__.py Signed-off-by: dosi <[email protected]> * refactor: use list comprehension to reduce cyclomatic complexity Signed-off-by: dosi <[email protected]> * test: fix unit test for AccountInfo Signed-off-by: dosi <[email protected]> * test: reduce test_account_info_query_execute() lines in AccountInfoQuery unit tests Signed-off-by: dosi <[email protected]> * chore: add type hinting Signed-off-by: Ivan Ivanov <[email protected]> --------- Signed-off-by: dosi <[email protected]> Signed-off-by: Ivan Ivanov <[email protected]> Co-authored-by: Ivan Ivanov <[email protected]> edited changelog, release 0.1.3 (#157) Signed-off-by: nadinedelia <[email protected]> chore: Type hinting crypto and utils (#164) * chore: type clarifying in private key Signed-off-by: exploreriii <[email protected]> * chore: type clarifying in public key Signed-off-by: exploreriii <[email protected]> * fix: import paths in unused crypto utils Signed-off-by: exploreriii <[email protected]> --------- Signed-off-by: exploreriii <[email protected]> fix: Hedera to Hiero solo (#168) * fix: hedera to hiero solo page Signed-off-by: exploreriii <[email protected]> * fix: hiero solo action Signed-off-by: exploreriii <[email protected]> --------- Signed-off-by: exploreriii <[email protected]> chore: Type improvements to account, address_book and consensus (#160) * chore: type fixes account Signed-off-by: exploreriii <[email protected]> * chore: type fixes address_book Signed-off-by: exploreriii <[email protected]> * chore: type fixes consensus Signed-off-by: exploreriii <[email protected]> * fix: remove duplicate eq Signed-off-by: exploreriii <[email protected]> --------- Signed-off-by: exploreriii <[email protected]> Feedback integrated and updating things from mypy Signed-off-by: Roger Barker <[email protected]> metadata field is being silly. Signed-off-by: Roger Barker <[email protected]> Remove `return True` from __post_init__ in tokenId Signed-off-by: Roger Barker <[email protected]> Fix the parameter for self.__init__ in token_update_nfts_transaction.py Signed-off-by: Roger Barker <[email protected]> Update return type for build_query_payment_transaction Signed-off-by: Roger Barker <[email protected]> Updated per mypy findings Signed-off-by: Roger Barker <[email protected]> Add node_account_id to transaction.py Signed-off-by: Roger Barker <[email protected]> Remove optional on Duration in transaction.py init Signed-off-by: Roger Barker <[email protected]> Update comment in transaction.py Signed-off-by: Roger Barker <[email protected]> Updated per PR review feedback Signed-off-by: Roger Barker <[email protected]> Update transaction_receipt.py to include proper signatures Signed-off-by: Roger Barker <[email protected]> Update type-hinting in transaction_response.py Signed-off-by: Roger Barker <[email protected]> Cleanup mypy errors in client module Signed-off-by: Roger Barker <[email protected]> fix mypy errors in consensus module Signed-off-by: Roger Barker <[email protected]> Update query module with mypy fixes Signed-off-by: Roger Barker <[email protected]> Fix mypy errors Signed-off-by: Roger Barker <[email protected]> Fix token create transaction Signed-off-by: Roger Barker <[email protected]> minor cleanup in transaction.py Signed-off-by: Roger Barker <[email protected]> Update token_create_transaction to use the base type transaction class Signed-off-by: Roger Barker <[email protected]> Playing around more with tokencreatetransaction Signed-off-by: Roger Barker <[email protected]> updated tests to use full paths, commented out items in __init__.py to remove circular dependencies in many places Signed-off-by: Roger Barker <[email protected]> Add env to token_pause_transaction_e2e_test.py Signed-off-by: Roger Barker <[email protected]>
1 parent 8640023 commit 49dda05

32 files changed

+266
-237
lines changed

examples/query_topic_message.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,9 @@
33
from datetime import datetime, timezone
44
from dotenv import load_dotenv
55

6-
from hiero_sdk_python import Network, Client, TopicMessageQuery
6+
from hiero_sdk_python.client.network import Network
7+
from hiero_sdk_python.client.client import Client
8+
from hiero_sdk_python.query.topic_message_query import TopicMessageQuery
79

810
load_dotenv()
911

src/hiero_sdk_python/__init__.py

Lines changed: 133 additions & 140 deletions
Original file line numberDiff line numberDiff line change
@@ -1,83 +1,83 @@
11
# Client and Network
2-
from .client.client import Client
3-
from .client.network import Network
2+
# from .client.client import Client
3+
# from .client.network import Network
44

55
# Account
6-
from .account.account_id import AccountId
7-
from .account.account_create_transaction import AccountCreateTransaction
8-
from .account.account_info import AccountInfo
6+
# from .account.account_id import AccountId
7+
# from .account.account_create_transaction import AccountCreateTransaction
8+
# from .account.account_info import AccountInfo
99

1010
# Crypto
11-
from .crypto.private_key import PrivateKey
12-
from .crypto.public_key import PublicKey
11+
# from .crypto.private_key import PrivateKey
12+
# from .crypto.public_key import PublicKey
1313

1414
# Tokens
15-
from .tokens.token_create_transaction import TokenCreateTransaction
16-
from .tokens.token_associate_transaction import TokenAssociateTransaction
17-
from .tokens.token_dissociate_transaction import TokenDissociateTransaction
18-
from .tokens.token_delete_transaction import TokenDeleteTransaction
19-
from .tokens.token_info import TokenInfo
20-
from .tokens.token_mint_transaction import TokenMintTransaction
21-
from .tokens.token_freeze_transaction import TokenFreezeTransaction
22-
from .tokens.token_unfreeze_transaction import TokenUnfreezeTransaction
23-
from .tokens.token_wipe_transaction import TokenWipeTransaction
24-
from .tokens.token_reject_transaction import TokenRejectTransaction
25-
from .tokens.token_update_nfts_transaction import TokenUpdateNftsTransaction
26-
from .tokens.token_burn_transaction import TokenBurnTransaction
27-
from .tokens.token_grant_kyc_transaction import TokenGrantKycTransaction
28-
from .tokens.token_revoke_kyc_transaction import TokenRevokeKycTransaction
29-
from .tokens.token_update_transaction import TokenUpdateTransaction
30-
from .tokens.token_id import TokenId
31-
from .tokens.token_type import TokenType
32-
from .tokens.supply_type import SupplyType
33-
from .tokens.nft_id import NftId
34-
from .tokens.token_nft_transfer import TokenNftTransfer
35-
from .tokens.token_nft_info import TokenNftInfo
36-
from .tokens.token_relationship import TokenRelationship
15+
# from .tokens.token_create_transaction import TokenCreateTransaction
16+
# from .tokens.token_associate_transaction import TokenAssociateTransaction
17+
# from .tokens.token_dissociate_transaction import TokenDissociateTransaction
18+
# from .tokens.token_delete_transaction import TokenDeleteTransaction
19+
# from .tokens.token_info import TokenInfo
20+
# from .tokens.token_mint_transaction import TokenMintTransaction
21+
# from .tokens.token_freeze_transaction import TokenFreezeTransaction
22+
# from .tokens.token_unfreeze_transaction import TokenUnfreezeTransaction
23+
# from .tokens.token_wipe_transaction import TokenWipeTransaction
24+
# from .tokens.token_reject_transaction import TokenRejectTransaction
25+
# from .tokens.token_update_nfts_transaction import TokenUpdateNftsTransaction
26+
# from .tokens.token_burn_transaction import TokenBurnTransaction
27+
# from .tokens.token_grant_kyc_transaction import TokenGrantKycTransaction
28+
# from .tokens.token_revoke_kyc_transaction import TokenRevokeKycTransaction
29+
# from .tokens.token_update_transaction import TokenUpdateTransaction
30+
# from .tokens.token_id import TokenId
31+
# from .tokens.token_type import TokenType
32+
# from .tokens.supply_type import SupplyType
33+
# from .tokens.nft_id import NftId
34+
# from .tokens.token_nft_transfer import TokenNftTransfer
35+
# from .tokens.token_nft_info import TokenNftInfo
36+
# from .tokens.token_relationship import TokenRelationship
3737

3838
# Transaction
39-
from .transaction.transfer_transaction import TransferTransaction
40-
from .transaction.transaction_id import TransactionId
41-
from .transaction.transaction_receipt import TransactionReceipt
42-
from .transaction.transaction_response import TransactionResponse
43-
from .transaction.transaction_record import TransactionRecord
39+
# from .transaction.transfer_transaction import TransferTransaction
40+
# from .transaction.transaction_id import TransactionId
41+
# from .transaction.transaction_receipt import TransactionReceipt
42+
# from .transaction.transaction_response import TransactionResponse
43+
# from .transaction.transaction_record import TransactionRecord
4444

4545
# Response / Codes
46-
from .response_code import ResponseCode
46+
# from .response_code import ResponseCode
4747

4848
# HBAR
49-
from .hbar import Hbar
49+
# from .hbar import Hbar
5050

5151
# Timestamp
52-
from .timestamp import Timestamp
52+
# from .timestamp import Timestamp
5353

5454
# Duration
55-
from .Duration import Duration
55+
# from .Duration import Duration
5656

5757
# Consensus
58-
from .consensus.topic_create_transaction import TopicCreateTransaction
59-
from .consensus.topic_message_submit_transaction import TopicMessageSubmitTransaction
60-
from .consensus.topic_update_transaction import TopicUpdateTransaction
61-
from .consensus.topic_delete_transaction import TopicDeleteTransaction
62-
from .consensus.topic_id import TopicId
58+
# from .consensus.topic_create_transaction import TopicCreateTransaction
59+
# from .consensus.topic_message_submit_transaction import TopicMessageSubmitTransaction
60+
# from .consensus.topic_update_transaction import TopicUpdateTransaction
61+
# from .consensus.topic_delete_transaction import TopicDeleteTransaction
62+
# from .consensus.topic_id import TopicId
6363

6464
# Queries
65-
from .query.topic_info_query import TopicInfoQuery
66-
from .query.topic_message_query import TopicMessageQuery
67-
from .query.transaction_get_receipt_query import TransactionGetReceiptQuery
68-
from .query.transaction_record_query import TransactionRecordQuery
69-
from .query.account_balance_query import CryptoGetAccountBalanceQuery
70-
from .query.token_nft_info_query import TokenNftInfoQuery
71-
from .query.token_info_query import TokenInfoQuery
72-
from .query.account_info_query import AccountInfoQuery
65+
# from .query.topic_info_query import TopicInfoQuery
66+
# from .query.topic_message_query import TopicMessageQuery
67+
# from .query.transaction_get_receipt_query import TransactionGetReceiptQuery
68+
# from .query.transaction_record_query import TransactionRecordQuery
69+
# from .query.account_balance_query import CryptoGetAccountBalanceQuery
70+
# from .query.token_nft_info_query import TokenNftInfoQuery
71+
# from .query.token_info_query import TokenInfoQuery
72+
# from .query.account_info_query import AccountInfoQuery
7373

7474
# Address book
75-
from .address_book.endpoint import Endpoint
76-
from .address_book.node_address import NodeAddress
75+
# from .address_book.endpoint import Endpoint
76+
# from .address_book.node_address import NodeAddress
7777

7878
# Logger
79-
from .logger.logger import Logger
80-
from .logger.log_level import LogLevel
79+
# from .logger.logger import Logger
80+
# from .logger.log_level import LogLevel
8181

8282
# File
8383
from .file.file_create_transaction import FileCreateTransaction
@@ -86,88 +86,81 @@
8686
from .file.file_contents_query import FileContentsQuery
8787
from .file.file_delete_transaction import FileDeleteTransaction
8888

89-
__all__ = [
90-
# Client
91-
"Client",
92-
"Network",
93-
94-
# Account
95-
"AccountId",
96-
"AccountCreateTransaction",
97-
"AccountInfo",
98-
99-
# Crypto
100-
"PrivateKey",
101-
"PublicKey",
102-
103-
# Tokens
104-
"TokenCreateTransaction",
105-
"TokenAssociateTransaction",
106-
"TokenDissociateTransaction",
107-
"TokenDeleteTransaction",
108-
"TokenMintTransaction",
109-
"TokenFreezeTransaction",
110-
"TokenUnfreezeTransaction",
111-
"TokenWipeTransaction",
112-
"TokenId",
113-
"NftId",
114-
"TokenInfo",
115-
"TokenNftTransfer",
116-
"TokenNftInfo",
117-
"TokenRejectTransaction",
118-
"TokenUpdateNftsTransaction",
119-
"TokenBurnTransaction",
120-
"TokenGrantKycTransaction",
121-
"TokenRelationship",
122-
"TokenUpdateTransaction",
123-
"TokenType",
124-
"SupplyType",
125-
126-
# Transaction
127-
"TransferTransaction",
128-
"TransactionId",
129-
"TransactionReceipt",
130-
"TransactionResponse",
131-
"TransactionRecord",
132-
133-
# Response
134-
"ResponseCode",
135-
136-
# Consensus
137-
"TopicCreateTransaction",
138-
"TopicMessageSubmitTransaction",
139-
"TopicUpdateTransaction",
140-
"TopicDeleteTransaction",
141-
"TopicId",
142-
143-
# Queries
144-
"TopicInfoQuery",
145-
"TopicMessageQuery",
146-
"TransactionGetReceiptQuery",
147-
"TransactionRecordQuery",
148-
"CryptoGetAccountBalanceQuery",
149-
"TokenNftInfoQuery",
150-
"TokenInfoQuery",
151-
"AccountInfoQuery",
152-
153-
# Address book
154-
"Endpoint",
155-
"NodeAddress",
156-
157-
# Logger
158-
"Logger",
159-
"LogLevel",
160-
161-
# HBAR
162-
"Hbar",
163-
"ResponseCode",
164-
"Timestamp",
165-
"Duration",
166-
167-
# File
168-
"FileCreateTransaction",
169-
"FileInfoQuery",
170-
"FileInfo",
171-
"FileContentsQuery",
172-
"FileDeleteTransaction",
173-
]
89+
# __all__ = [
90+
# # Client
91+
# "Client",
92+
# "Network",
93+
94+
# # Account
95+
# "AccountId",
96+
# "AccountCreateTransaction",
97+
# "AccountInfo",
98+
99+
# # Crypto
100+
# "PrivateKey",
101+
# "PublicKey",
102+
103+
# # Tokens
104+
# "TokenCreateTransaction",
105+
# "TokenAssociateTransaction",
106+
# "TokenDissociateTransaction",
107+
# "TokenDeleteTransaction",
108+
# "TokenMintTransaction",
109+
# "TokenFreezeTransaction",
110+
# "TokenUnfreezeTransaction",
111+
# "TokenWipeTransaction",
112+
# "TokenId",
113+
# "NftId",
114+
# "TokenInfo",
115+
# "TokenNftTransfer",
116+
# "TokenNftInfo",
117+
# "TokenRejectTransaction",
118+
# "TokenUpdateNftsTransaction",
119+
# "TokenBurnTransaction",
120+
# "TokenGrantKycTransaction",
121+
# "TokenRelationship",
122+
# "TokenUpdateTransaction",
123+
# "TokenType",
124+
# "SupplyType",
125+
126+
# # Transaction
127+
# "TransferTransaction",
128+
# "TransactionId",
129+
# "TransactionReceipt",
130+
# "TransactionResponse",
131+
# "TransactionRecord",
132+
133+
# # Response
134+
# "ResponseCode",
135+
136+
# # Consensus
137+
# "TopicCreateTransaction",
138+
# "TopicMessageSubmitTransaction",
139+
# "TopicUpdateTransaction",
140+
# "TopicDeleteTransaction",
141+
# "TopicId",
142+
143+
# # Queries
144+
# "TopicInfoQuery",
145+
# "TopicMessageQuery",
146+
# "TransactionGetReceiptQuery",
147+
# "TransactionRecordQuery",
148+
# "CryptoGetAccountBalanceQuery",
149+
# "TokenNftInfoQuery",
150+
# "TokenInfoQuery",
151+
# "AccountInfoQuery",
152+
153+
# # Address book
154+
# "Endpoint",
155+
# "NodeAddress",
156+
157+
# # Logger
158+
# "Logger",
159+
# "LogLevel",
160+
161+
# # HBAR
162+
# "Hbar",
163+
# "ResponseCode",
164+
# "Timestamp",
165+
# "Duration"
166+
# ]

src/hiero_sdk_python/client/network.py

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
import requests
66

7+
from typing import Dict, List, Tuple
78
from hiero_sdk_python.account.account_id import AccountId
89
from hiero_sdk_python.address_book.node_address import NodeAddress
910
from hiero_sdk_python.node import _Node
@@ -29,7 +30,7 @@ class Network:
2930
'solo': 'http://localhost:8080'
3031
}
3132

32-
DEFAULT_NODES: Dict[str,List[_Node]] = {
33+
DEFAULT_NODES: Dict[str,List[Tuple[str,AccountId]]] = {
3334
'mainnet': [
3435
("35.237.200.180:50211", AccountId(0, 0, 3)),
3536
("35.186.191.247:50211", AccountId(0, 0, 4)),
@@ -87,9 +88,9 @@ def __init__(
8788
if nodes is not None:
8889
self.nodes: List[_Node] = nodes
8990
elif self.network in ('solo', 'localhost', 'local'):
90-
self.nodes: List[_Node] = self._fetch_nodes_from_default_nodes()
91+
self.nodes = self._fetch_nodes_from_default_nodes()
9192
else:
92-
self.nodes: List[_Node] = self._fetch_nodes_from_mirror_node()
93+
self.nodes = self._fetch_nodes_from_mirror_node()
9394
if not self.nodes and self.network in self.DEFAULT_NODES:
9495
self.nodes = self._fetch_nodes_from_default_nodes()
9596
elif not self.nodes:

src/hiero_sdk_python/consensus/topic_create_transaction.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,7 @@ def set_auto_renew_account(self, account_id: AccountId) -> "TopicCreateTransacti
100100
self.auto_renew_account = account_id
101101
return self
102102

103-
def build_transaction_body(self):
103+
def build_transaction_body(self) -> transaction_body_pb2.TransactionBody:
104104
"""
105105
Builds and returns the protobuf transaction body for topic creation.
106106

src/hiero_sdk_python/consensus/topic_message.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,9 @@
11
from datetime import datetime
22
from typing import Optional, List, Union, Dict
33

4-
from hiero_sdk_python import Timestamp
4+
from hiero_sdk_python.timestamp import Timestamp
55
from hiero_sdk_python.hapi.mirror import consensus_service_pb2 as mirror_proto
66

7-
87
class TopicMessageChunk:
98
"""
109
Represents a single chunk within a chunked topic message.

src/hiero_sdk_python/query/query.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,9 @@
55
import time
66
from typing import Any, List, Optional, Union
77

8-
from typing import Any, List, Optional
8+
from typing import Any, List, Optional, Union
99

10-
from hiero_sdk_python.exceptions import PrecheckError
10+
from hiero_sdk_python.exceptions import PrecheckError, ReceiptStatusError
1111
from hiero_sdk_python.executable import _Method
1212
from hiero_sdk_python.channels import _Channel
1313
from hiero_sdk_python.hapi.services import query_header_pb2, query_pb2

src/hiero_sdk_python/query/topic_message_query.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
from hiero_sdk_python.consensus.topic_id import TopicId
99
from hiero_sdk_python.consensus.topic_message import TopicMessage
1010
from hiero_sdk_python.utils.subscription_handle import SubscriptionHandle
11-
from hiero_sdk_python import Client
11+
from hiero_sdk_python.client.client import Client
1212

1313

1414
class TopicMessageQuery:

src/hiero_sdk_python/query/transaction_get_receipt_query.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -194,7 +194,7 @@ def _map_status_error(self, response: Any) -> Union[PrecheckError,ReceiptStatusE
194194

195195
status = response.transactionGetReceipt.receipt.status
196196

197-
return ReceiptStatusError(status, self.transaction_id, TransactionReceipt._from_proto(response.transactionGetReceipt.receipt))
197+
return ReceiptStatusError(status, self.transaction_id, TransactionReceipt._from_proto(response.transactionGetReceipt.receipt, self.transaction_id))
198198

199199
def execute(self, client: Client) -> TransactionReceipt:
200200
"""

0 commit comments

Comments
 (0)