From 51de3be60b8d1623c80bdd6b91b31ccb67739f54 Mon Sep 17 00:00:00 2001 From: Chris Campbell Date: Fri, 18 Nov 2022 14:06:05 -0800 Subject: [PATCH] feat: native-staking; pytest; squash Signed-off-by: Chris Campbell --- .clang-format | 26 + .vscode/settings.json | 17 +- LICENSE | 201 ---- Makefile | 47 +- README.md | 27 - proto/BasicTypes.proto | 43 - proto/CryptoCreate.proto | 5 - proto/TokenAssociate.proto | 10 - proto/TokenBurn.proto | 14 - proto/TokenMint.proto | 14 - proto/TransactionBody.proto | 23 - proto/Transfer.proto | 32 - proto/Wrappers.proto | 5 - proto/basic_types.proto | 594 +++++++++++ proto/basic_types_pb2.py | 86 ++ proto/basic_types_pb2.pyi | 862 +++++++++++++++ proto/crypto_create.proto | 160 +++ proto/crypto_create_pb2.py | 36 + proto/crypto_create_pb2.pyi | 181 ++++ proto/crypto_transfer.proto | 55 + proto/crypto_transfer_pb2.py | 29 + proto/crypto_transfer_pb2.pyi | 64 ++ proto/crypto_update.proto | 157 +++ proto/crypto_update_pb2.py | 44 + proto/crypto_update_pb2.pyi | 187 ++++ proto/duration.proto | 34 + proto/duration_pb2.py | 26 + proto/duration_pb2.pyi | 37 + proto/timestamp.proto | 52 + proto/timestamp_pb2.py | 28 + proto/timestamp_pb2.pyi | 68 ++ proto/token_associate.proto | 55 + proto/token_associate_pb2.py | 29 + proto/token_associate_pb2.pyi | 64 ++ proto/token_burn.proto | 67 ++ proto/token_burn_pb2.py | 29 + proto/token_burn_pb2.pyi | 77 ++ proto/token_dissociate.proto | 56 + proto/token_dissociate_pb2.py | 29 + proto/token_dissociate_pb2.pyi | 65 ++ proto/token_mint.proto | 65 ++ proto/token_mint_pb2.py | 29 + proto/token_mint_pb2.pyi | 74 ++ proto/transaction_body.proto | 117 +++ proto/transaction_body_pb2.py | 39 + proto/transaction_body_pb2.pyi | 136 +++ proto/wrappers.proto | 108 ++ proto/wrappers_pb2.py | 40 + proto/wrappers_pb2.pyi | 212 ++++ src/debug.c | 13 +- src/get_app_configuration.c | 21 +- src/get_public_key.c | 154 +-- src/get_public_key.h | 13 +- src/handlers.h | 11 +- src/hedera.c | 90 +- src/hedera.h | 18 +- src/hedera_format.c | 30 +- src/hedera_format.h | 4 +- src/io.c | 25 +- src/io.h | 2 +- src/main.c | 73 +- src/printf.c | 1466 +++++++++++++------------- src/printf.h | 78 +- src/sign_transaction.c | 1737 +++++++++++++++++-------------- src/sign_transaction.h | 164 ++- src/ui.c | 167 ++- src/ui.h | 52 +- src/utils.c | 22 +- src/utils.h | 6 +- tests/.pdm.toml | 2 + tests/.vscode/settings.json | 4 + tests/__init__.py | 0 tests/apps/__init__.py | 0 tests/apps/hedera.py | 91 ++ tests/apps/hedera_builder.py | 319 ++++++ tests/conftest.py | 99 ++ tests/elfs/hedera_nanos.elf | Bin 0 -> 363372 bytes tests/elfs/hedera_nanosplus.elf | Bin 0 -> 481108 bytes tests/elfs/hedera_nanox.elf | Bin 0 -> 626812 bytes tests/nanopb_pb2.py | 1 + tests/pdm.lock | 1274 +++++++++++++++++++++++ tests/proto | 1 + tests/pyproject.toml | 26 + tests/requirements.txt | 4 + tests/test_hedera.py | 476 +++++++++ tests/utils.py | 57 + 86 files changed, 8551 insertions(+), 2404 deletions(-) create mode 100644 .clang-format delete mode 100644 LICENSE delete mode 100644 README.md delete mode 100644 proto/BasicTypes.proto delete mode 100644 proto/CryptoCreate.proto delete mode 100644 proto/TokenAssociate.proto delete mode 100644 proto/TokenBurn.proto delete mode 100644 proto/TokenMint.proto delete mode 100644 proto/TransactionBody.proto delete mode 100644 proto/Transfer.proto delete mode 100644 proto/Wrappers.proto create mode 100644 proto/basic_types.proto create mode 100644 proto/basic_types_pb2.py create mode 100644 proto/basic_types_pb2.pyi create mode 100644 proto/crypto_create.proto create mode 100644 proto/crypto_create_pb2.py create mode 100644 proto/crypto_create_pb2.pyi create mode 100644 proto/crypto_transfer.proto create mode 100644 proto/crypto_transfer_pb2.py create mode 100644 proto/crypto_transfer_pb2.pyi create mode 100644 proto/crypto_update.proto create mode 100644 proto/crypto_update_pb2.py create mode 100644 proto/crypto_update_pb2.pyi create mode 100644 proto/duration.proto create mode 100644 proto/duration_pb2.py create mode 100644 proto/duration_pb2.pyi create mode 100644 proto/timestamp.proto create mode 100644 proto/timestamp_pb2.py create mode 100644 proto/timestamp_pb2.pyi create mode 100644 proto/token_associate.proto create mode 100644 proto/token_associate_pb2.py create mode 100644 proto/token_associate_pb2.pyi create mode 100644 proto/token_burn.proto create mode 100644 proto/token_burn_pb2.py create mode 100644 proto/token_burn_pb2.pyi create mode 100644 proto/token_dissociate.proto create mode 100644 proto/token_dissociate_pb2.py create mode 100644 proto/token_dissociate_pb2.pyi create mode 100644 proto/token_mint.proto create mode 100644 proto/token_mint_pb2.py create mode 100644 proto/token_mint_pb2.pyi create mode 100644 proto/transaction_body.proto create mode 100644 proto/transaction_body_pb2.py create mode 100644 proto/transaction_body_pb2.pyi create mode 100644 proto/wrappers.proto create mode 100644 proto/wrappers_pb2.py create mode 100644 proto/wrappers_pb2.pyi create mode 100644 tests/.pdm.toml create mode 100644 tests/.vscode/settings.json create mode 100644 tests/__init__.py create mode 100644 tests/apps/__init__.py create mode 100644 tests/apps/hedera.py create mode 100644 tests/apps/hedera_builder.py create mode 100644 tests/conftest.py create mode 100755 tests/elfs/hedera_nanos.elf create mode 100755 tests/elfs/hedera_nanosplus.elf create mode 100755 tests/elfs/hedera_nanox.elf create mode 120000 tests/nanopb_pb2.py create mode 100644 tests/pdm.lock create mode 120000 tests/proto create mode 100644 tests/pyproject.toml create mode 100644 tests/requirements.txt create mode 100644 tests/test_hedera.py create mode 100644 tests/utils.py diff --git a/.clang-format b/.clang-format new file mode 100644 index 00000000..daa53e37 --- /dev/null +++ b/.clang-format @@ -0,0 +1,26 @@ +--- +Language: Cpp +BasedOnStyle: Google +AlignOperands: true +BreakStringLiterals: true +ColumnLimit: 80 +ConstructorInitializerIndentWidth: 4 +ContinuationIndentWidth: 4 +FixNamespaceComments: true +IndentCaseLabels: true +IndentWidth: 4 +MaxEmptyLinesToKeep: 1 +PointerAlignment: Left +ReflowComments: true +SortIncludes: true +SpaceBeforeParens: ControlStatements +SpaceInEmptyParentheses: false +SpacesBeforeTrailingComments: 1 +SpacesInContainerLiterals: true +SpacesInCStyleCastParentheses: false +SpacesInParentheses: false +SpacesInSquareBrackets: true +UseTab: Never +--- +Language: Proto +BasedOnStyle: LLVM \ No newline at end of file diff --git a/.vscode/settings.json b/.vscode/settings.json index bf920b8a..e61f9d5d 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -1,12 +1,19 @@ { "python.linting.pylintEnabled": false, - "python.linting.pylamaEnabled": true, + "python.linting.pylamaEnabled": false, "python.linting.enabled": true, "files.associations": { - "*.h": "c", - ".clang-tidy": "yaml", - "string_view": "c", - "regex": "c" + "*.h": "c", + ".clang-tidy": "yaml", + "string_view": "c", + "regex": "c", + "system_error": "c", + "array": "c", + "functional": "c", + "tuple": "c", + "type_traits": "c", + "utility": "c" }, "C_Cpp.dimInactiveRegions": false, + "python.linting.mypyEnabled": true, } diff --git a/LICENSE b/LICENSE deleted file mode 100644 index ae3ac373..00000000 --- a/LICENSE +++ /dev/null @@ -1,201 +0,0 @@ - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - nanopb notice, with the fields enclosed by brackets "{}" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright 2019 Hedera Hashgraph LLC - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. diff --git a/Makefile b/Makefile index 390fe555..22e7c050 100755 --- a/Makefile +++ b/Makefile @@ -62,7 +62,7 @@ DFEFINES += PB_FIELD_32BIT=1 # vendor/printf DEFINES += PRINTF_DISABLE_SUPPORT_FLOAT PRINTF_DISABLE_SUPPORT_EXPONENTIAL PRINTF_DISABLE_SUPPORT_PTRDIFF_T -DEFINES += PRINTF_NTOA_BUFFER_SIZE=9U PRINTF_FTOA_BUFFER_SIZE=0 +DEFINES += PRINTF_FTOA_BUFFER_SIZE=0 # endif # U2F @@ -160,39 +160,24 @@ DEFINES += PB_NO_ERRMSG=1 SOURCE_FILES += $(NANOPB_CORE) CFLAGS += "-I$(NANOPB_DIR)" -# Build rule for proto files -SOURCE_FILES += proto/BasicTypes.pb.c -SOURCE_FILES += proto/Wrappers.pb.c -SOURCE_FILES += proto/CryptoCreate.pb.c -SOURCE_FILES += proto/Transfer.pb.c -SOURCE_FILES += proto/TransactionBody.pb.c -SOURCE_FILES += proto/TokenAssociate.pb.c -SOURCE_FILES += proto/TokenMint.pb.c -SOURCE_FILES += proto/TokenBurn.pb.c +PB_FILES = $(wildcard proto/*.proto) +C_PB_FILES = $(patsubst %.proto,%.pb.c,$(PB_FILES)) +PYTHON_PB_FILES = $(patsubst %.proto,%_pb2.py,$(PB_FILES)) -proto/BasicTypes.pb.c: proto/BasicTypes.proto - $(PROTOC) $(PROTOC_OPTS) --nanopb_out=. proto/BasicTypes.proto +# Build rule for C proto files +SOURCE_FILES += $(C_PB_FILES) +$(C_PB_FILES): %.pb.c: $(PB_FILES) + $(PROTOC) $(PROTOC_OPTS) --nanopb_out=. $*.proto -proto/Wrappers.pb.c: proto/Wrappers.proto - $(PROTOC) $(PROTOC_OPTS) --nanopb_out=. proto/Wrappers.proto +# Build rule for Python proto files +$(PYTHON_PB_FILES): %_pb2.py: $(PB_FILES) + $(PROTOC) $(PROTOC_OPTS) --python_out=. --mypy_out=. $*.proto -proto/CryptoCreate.pb.c: proto/BasicTypes.proto - $(PROTOC) $(PROTOC_OPTS) --nanopb_out=. proto/CryptoCreate.proto - -proto/Transfer.pb.c: proto/BasicTypes.proto - $(PROTOC) $(PROTOC_OPTS) --nanopb_out=. proto/Transfer.proto - -proto/TransactionBody.pb.c: proto/BasicTypes.proto - $(PROTOC) $(PROTOC_OPTS) --nanopb_out=. proto/TransactionBody.proto - -proto/TokenAssociate.pb.c: proto/BasicTypes.proto - $(PROTOC) $(PROTOC_OPTS) --nanopb_out=. proto/TokenAssociate.proto - -proto/TokenMint.pb.c: proto/BasicTypes.proto - $(PROTOC) $(PROTOC_OPTS) --nanopb_out=. proto/TokenMint.proto - -proto/TokenBurn.pb.c: proto/BasicTypes.proto - $(PROTOC) $(PROTOC_OPTS) --nanopb_out=. proto/TokenBurn.proto +.PHONY: python_pb clean_python_pb +c_pb: $(C_PB_FILES) +python_pb: $(PYTHON_PB_FILES) +clean_python_pb: + rm -f $(PYTHON_PB_FILES) # target to also clean generated proto c files .SILENT : cleanall diff --git a/README.md b/README.md deleted file mode 100644 index 647ef3c9..00000000 --- a/README.md +++ /dev/null @@ -1,27 +0,0 @@ -# Hedera Ledger App - -Hedera™ Hashgraph BOLOS application for Ledger Nano S and Nano X. - -## Development - -### Prerequisite - -- Docker - -### Compile - -``` -docker run -v $PWD:/app --platform linux/amd64 -it \ - ghcr.io/ledgerhq/ledger-app-builder/ledger-app-builder:latest \ - make -``` - -### Check - -``` -docker run -v $PWD:/app --platform linux/amd64 -it \ - ghcr.io/ledgerhq/ledger-app-builder/ledger-app-builder:latest \ - scan-build --use-cc=clang -analyze-headers -enable-checker security \ - -enable-checker unix -enable-checker valist -o scan-build \ - --status-bugs make default -``` diff --git a/proto/BasicTypes.proto b/proto/BasicTypes.proto deleted file mode 100644 index a691136d..00000000 --- a/proto/BasicTypes.proto +++ /dev/null @@ -1,43 +0,0 @@ -syntax = "proto3"; - -import "nanopb.proto"; - -message HederaKey { - oneof key { - bytes ed25519 = 2 [(nanopb).max_size = 32]; - } -} - -message HederaShardID { - uint64 shardNum = 1; -} - -message HederaRealmID { - uint64 shardNum = 1; - uint64 realmNum = 2; -} - -message HederaAccountID { - uint64 shardNum = 1; - uint64 realmNum = 2; - uint64 accountNum = 3; -} - -message HederaTokenID { - uint64 shardNum = 1; - uint64 realmNum = 2; - uint64 tokenNum = 3; -} - -message HederaTimestamp { - uint64 seconds = 1; - uint32 nanos = 2; -} - -message HederaDuration { - uint64 seconds = 1; -} - -message HederaTransactionID { - HederaAccountID accountID = 2; -} diff --git a/proto/CryptoCreate.proto b/proto/CryptoCreate.proto deleted file mode 100644 index da04ce64..00000000 --- a/proto/CryptoCreate.proto +++ /dev/null @@ -1,5 +0,0 @@ -syntax = "proto3"; - -message HederaCryptoCreateTransactionBody { - uint64 initialBalance = 2; -} diff --git a/proto/TokenAssociate.proto b/proto/TokenAssociate.proto deleted file mode 100644 index 4bfad268..00000000 --- a/proto/TokenAssociate.proto +++ /dev/null @@ -1,10 +0,0 @@ -syntax = "proto3"; - -import "nanopb.proto"; -import "proto/BasicTypes.proto"; - -message HederaTokenAssociateTransactionBody { - HederaAccountID account = 1; - - repeated HederaTokenID tokens = 2 [(nanopb).max_count = 1]; -} diff --git a/proto/TokenBurn.proto b/proto/TokenBurn.proto deleted file mode 100644 index 10f42aaf..00000000 --- a/proto/TokenBurn.proto +++ /dev/null @@ -1,14 +0,0 @@ -syntax = "proto3"; - -import "proto/Wrappers.proto"; -import "proto/BasicTypes.proto"; - -message HederaTokenBurnTransactionBody { - HederaTokenID token = 1; - - uint64 amount = 2; - - // TODO(nft): repeated int64 serialNumbers = 3; - - UInt32Value expected_decimals = 4; -} diff --git a/proto/TokenMint.proto b/proto/TokenMint.proto deleted file mode 100644 index 2638adee..00000000 --- a/proto/TokenMint.proto +++ /dev/null @@ -1,14 +0,0 @@ -syntax = "proto3"; - -import "proto/Wrappers.proto"; -import "proto/BasicTypes.proto"; - -message HederaTokenMintTransactionBody { - HederaTokenID token = 1; - - uint64 amount = 2; - - // TODO(nft): repeated bytes metadata = 3; - - UInt32Value expected_decimals = 4; -} diff --git a/proto/TransactionBody.proto b/proto/TransactionBody.proto deleted file mode 100644 index 3fa24cf2..00000000 --- a/proto/TransactionBody.proto +++ /dev/null @@ -1,23 +0,0 @@ -syntax = "proto3"; - -import "nanopb.proto"; -import "proto/BasicTypes.proto"; -import "proto/CryptoCreate.proto"; -import "proto/Transfer.proto"; -import "proto/TokenAssociate.proto"; -import "proto/TokenMint.proto"; -import "proto/TokenBurn.proto"; - -message HederaTransactionBody { - HederaTransactionID transactionID = 1; - uint64 transactionFee = 3; - string memo = 6 [(nanopb).max_size = 100]; - - oneof data { - HederaCryptoCreateTransactionBody cryptoCreateAccount = 11; - HederaCryptoTransferTransactionBody cryptoTransfer = 14; - HederaTokenAssociateTransactionBody tokenAssociate = 40; - HederaTokenMintTransactionBody tokenMint = 37; - HederaTokenBurnTransactionBody tokenBurn = 38; - } -} diff --git a/proto/Transfer.proto b/proto/Transfer.proto deleted file mode 100644 index 783ae912..00000000 --- a/proto/Transfer.proto +++ /dev/null @@ -1,32 +0,0 @@ -syntax = "proto3"; - -import "nanopb.proto"; -import "proto/Wrappers.proto"; -import "proto/BasicTypes.proto"; - -message HederaAccountAmount { - HederaAccountID accountID = 1; - sint64 amount = 2; -} - -message HederaTransferList { - repeated HederaAccountAmount accountAmounts = 1 [(nanopb).max_count = 2]; -} - -message HederaTokenTransferList { - HederaTokenID token = 1; - - repeated HederaAccountAmount transfers = 2 [(nanopb).max_count = 2]; - - /** - * If present, the number of decimals this fungible token type is expected to have. The transfer - * will fail with UNEXPECTED_TOKEN_DECIMALS if the actual decimals differ. - */ - UInt32Value expected_decimals = 4; -} - -message HederaCryptoTransferTransactionBody { - HederaTransferList transfers = 1; - - repeated HederaTokenTransferList tokenTransfers = 2 [(nanopb).max_count = 1]; -} diff --git a/proto/Wrappers.proto b/proto/Wrappers.proto deleted file mode 100644 index 0fe25353..00000000 --- a/proto/Wrappers.proto +++ /dev/null @@ -1,5 +0,0 @@ -syntax = "proto3"; - -message UInt32Value { - uint32 value = 1; -} diff --git a/proto/basic_types.proto b/proto/basic_types.proto new file mode 100644 index 00000000..6aec15af --- /dev/null +++ b/proto/basic_types.proto @@ -0,0 +1,594 @@ +syntax = "proto3"; + +package Hedera; + +/*- + * ‌ + * Hedera Network Services Protobuf + * ​ + * Copyright (C) 2018 - 2022 Hedera Hashgraph, LLC + * ​ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ‍ + */ +import "nanopb.proto"; +import "proto/timestamp.proto"; +import "proto/wrappers.proto"; + +/** + * Each shard has a nonnegative shard number. Each realm within a given shard + * has a nonnegative realm number (that number might be reused in other + * shards). And each account, file, and smart contract instance within a given + * realm has a nonnegative number (which might be reused in other realms). + * Every account, file, and smart contract instance is within exactly one + * realm. So a FileID is a triplet of numbers, like 0.1.2 for entity number 2 + * within realm 1 within shard 0. Each realm maintains a single counter for + * assigning numbers, so if there is a file with ID 0.1.2, then there won't be + * an account or smart contract instance with ID 0.1.2. + * + * Everything is partitioned into realms so that each Solidity smart contract + * can access everything in just a single realm, locking all those entities + * while it's running, but other smart contracts could potentially run in + * other realms in parallel. So realms allow Solidity to be parallelized + * somewhat, even though the language itself assumes everything is serial. + */ +message ShardID { + /** + * the shard number (nonnegative) + */ + int64 shardNum = 1; +} + +/** + * The ID for a realm. Within a given shard, every realm has a unique ID. Each + * account, file, and contract instance belongs to exactly one realm. + */ +message RealmID { + /** + * The shard number (nonnegative) + */ + int64 shardNum = 1; + + /** + * The realm number (nonnegative) + */ + int64 realmNum = 2; +} + +/** + * The ID for an a cryptocurrency account + */ +message AccountID { + /** + * The shard number (nonnegative) + */ + int64 shardNum = 1; + + /** + * The realm number (nonnegative) + */ + int64 realmNum = 2; + + /** + * The account number unique within its realm which can be either a + * non-negative integer or an alias public key. For any AccountID fields in + * the query response, transaction record or transaction receipt only + * accountNum will be populated. + */ + oneof account { + /** + * A non-negative account number unique within its realm + */ + int64 accountNum = 3; + + /** + * The public key bytes to be used as the account's alias. The public key + * bytes are the result of serializing a protobuf Key message for any + * primitive key type. Currently only primitive key bytes are supported as + * an alias (ThresholdKey, KeyList, ContractID, and delegatable_contract_id + * are not supported) + * + * At most one account can ever have a given alias and it is used for + * account creation if it was automatically created using a crypto + * transfer. It will be null if an account is created normally. It is + * immutable once it is set for an account. + * + * If a transaction auto-creates the account, any further transfers to that + * alias will simply be deposited in that account, without creating + * anything, and with no creation fee being charged. + */ + bytes alias = 4 [ (nanopb).max_size = 32 ]; + } +} + +/** + * The ID for a file + */ +message FileID { + /** + * The shard number (nonnegative) + */ + int64 shardNum = 1; + + /** + * The realm number (nonnegative) + */ + int64 realmNum = 2; + + /** + * A nonnegative File number unique within its realm + */ + int64 fileNum = 3; +} + +/** + * The ID for a smart contract instance + */ +message ContractID { + /** + * The shard number (nonnegative) + */ + int64 shardNum = 1; + + /** + * The realm number (nonnegative) + */ + int64 realmNum = 2; + + oneof contract { + /** + * A nonnegative number unique within a given shard and realm + */ + int64 contractNum = 3; + + /** + * The 20-byte EVM address of the contract to call. + * + * Every contract has an EVM address determined by its + * shard.realm.num id. This address is as follows:
  1. The + * first 4 bytes are the big-endian representation of the shard.
  2. + *
  3. The next 8 bytes are the big-endian representation of the + * realm.
  4. The final 8 bytes are the big-endian representation of + * the number.
  5. + *
+ * + * Contracts created via CREATE2 have an additional, primary address + * that is derived from the EIP-1014 + * specification, and does not have a simple relation to a + * shard.realm.num id. + * + * (Please do note that CREATE2 contracts can also be referenced by the + * three-part EVM address described above.) + */ + bytes evm_address = 4 [ (nanopb).max_size = 20 ]; + } +} + +/** + * The ID for a transaction. This is used for retrieving receipts and records + * for a transaction, for appending to a file right after creating it, for + * instantiating a smart contract with bytecode in a file just created, and + * internally by the network for detecting when duplicate transactions are + * submitted. A user might get a transaction processed faster by submitting it + * to N nodes, each with a different node account, but all with the same + * TransactionID. Then, the transaction will take effect when the first of all + * those nodes submits the transaction and it reaches consensus. The other + * transactions will not take effect. So this could make the transaction take + * effect faster, if any given node might be slow. However, the full + * transaction fee is charged for each transaction, so the total fee is N times + * as much if the transaction is sent to N nodes. + * + * Applicable to Scheduled Transactions: + * - The ID of a Scheduled Transaction has transactionValidStart and + * accountIDs inherited from the ScheduleCreate transaction that created it. + * That is to say that they are equal + * - The scheduled property is true for Scheduled Transactions + * - transactionValidStart, accountID and scheduled properties should be + * omitted + */ +message TransactionID { + /** + * The transaction is invalid if consensusTimestamp < + * transactionID.transactionStartValid + */ + Timestamp transactionValidStart = 1; + + /** + * The Account ID that paid for this transaction + */ + AccountID accountID = 2; + + /** + * Whether the Transaction is of type Scheduled or no + */ + bool scheduled = 3; + + /** + * The identifier for an internal transaction that was spawned as part + * of handling a user transaction. (These internal transactions share the + * transactionValidStart and accountID of the user transaction, so a + * nonce is necessary to give them a unique TransactionID.) + * + * An example is when a "parent" ContractCreate or ContractCall transaction + * calls one or more HTS precompiled contracts; each of the "child" + * transactions spawned for a precompile has a id with a different nonce. + */ + int32 nonce = 4; +} + +/** + * An account, and the amount that it sends or receives during a cryptocurrency + * or token transfer. + */ +message AccountAmount { + /** + * The Account ID that sends/receives cryptocurrency or tokens + */ + AccountID accountID = 1; + + /** + * The amount of tinybars (for Crypto transfers) or in the lowest + * denomination (for Token transfers) that the account sends(negative) or + * receives(positive) + */ + sint64 amount = 2; + + /** + * If true then the transfer is expected to be an approved allowance and the + * accountID is expected to be the owner. The default is false (omitted). + */ + bool is_approval = 3; +} + +/** + * A list of accounts and amounts to transfer out of each account (negative) or + * into it (positive). + */ +message TransferList { + /** + * Multiple list of AccountAmount pairs, each of which has an account and + * an amount to transfer into it (positive) or out of it (negative) + * Limited to 2 for a transfer between two accounts + */ + repeated AccountAmount accountAmounts = 1 [ (nanopb).max_count = 2 ]; +} + +/** + * A sender account, a receiver account, and the serial number of an NFT of a + * Token with NON_FUNGIBLE_UNIQUE type. When minting NFTs the sender will be + * the default AccountID instance (0.0.0) and when burning NFTs, the receiver + * will be the default AccountID instance. + */ +message NftTransfer { + /** + * The accountID of the sender + */ + AccountID senderAccountID = 1; + + /** + * The accountID of the receiver + */ + AccountID receiverAccountID = 2; + + /** + * The serial number of the NFT + */ + int64 serialNumber = 3; + + /** + * If true then the transfer is expected to be an approved allowance and the + * senderAccountID is expected to be the owner. The default is false + * (omitted). + */ + bool is_approval = 4; +} + +/** + * A list of token IDs and amounts representing the transferred out (negative) + * or into (positive) amounts, represented in the lowest denomination of the + * token + */ +message TokenTransferList { + /** + * The ID of the token + */ + TokenID token = 1; + + /** + * Applicable to tokens of type FUNGIBLE_COMMON. Multiple list of + * AccountAmounts, each of which has an account and amount + * Limited to 2 for 1 allowed transfer (reciprocal subtraction of balance + + * actual transfer) + */ + repeated AccountAmount transfers = 2 [ (nanopb).max_count = 2 ]; + + /** + * Applicable to tokens of type NON_FUNGIBLE_UNIQUE. Multiple list of + * NftTransfers, each of which has a sender and receiver account, including + * the serial number of the NFT + * Limited to 1 here + */ + repeated NftTransfer nftTransfers = 3 [ (nanopb).max_count = 1 ]; + + /** + * If present, the number of decimals this fungible token type is expected to + * have. The transfer will fail with UNEXPECTED_TOKEN_DECIMALS if the actual + * decimals differ. + */ + UInt32Value expected_decimals = 4; +} + +/** + * A rational number, used to set the amount of a value transfer to collect as + * a custom fee + */ +message Fraction { + /** + * The rational's numerator + */ + int64 numerator = 1; + + /** + * The rational's denominator; a zero value will result in + * FRACTION_DIVIDES_BY_ZERO + */ + int64 denominator = 2; +} + +/** + * Unique identifier for a token + */ +message TokenID { + /** + * A nonnegative shard number + */ + int64 shardNum = 1; + + /** + * A nonnegative realm number + */ + int64 realmNum = 2; + + /** + * A nonnegative token number + */ + int64 tokenNum = 3; +} + +/** + * A Key can be a public key from either the Ed25519 or ECDSA(secp256k1) + * signature schemes, where in the ECDSA(secp256k1) case we require the 33-byte + * compressed form of the public key. We call these public keys primitive + * keys. + * + * If an account has primitive key associated to it, then the corresponding + * private key must sign any transaction to transfer cryptocurrency out of it. + * + * A Key can also be the ID of a smart contract instance, which is then + * authorized to perform any precompiled contract action that requires this key + * to sign. + * + * Note that when a Key is a smart contract ID, it doesn't mean the + * contract with that ID will actually create a cryptographic signature. It + * only means that when the contract calls a precompiled contract, the + * resulting "child transaction" will be authorized to perform any action + * controlled by the Key. + * + * A Key can be a "threshold key", which means a list of M keys, any N of which + * must sign in order for the threshold signature to be considered valid. The + * keys within a threshold signature may themselves be threshold signatures, to + * allow complex signature requirements. + * + * A Key can be a "key list" where all keys in the list must sign unless + * specified otherwise in the documentation for a specific transaction type + * (e.g. FileDeleteTransactionBody). Their use is dependent on context. For + * example, a Hedera file is created with a list of keys, where all of them + * must sign a transaction to create or modify the file, but only one of them + * is needed to sign a transaction to delete the file. So it's a single list + * that sometimes acts as a 1-of-M threshold key, and sometimes acts as an + * M-of-M threshold key. A key list is always an M-of-M, unless specified + * otherwise in documentation. A key list can have nested key lists or + * threshold keys. Nested key lists are always M-of-M. A key list can have + * repeated primitive public keys, but all repeated keys are only required to + * sign once. + * + * A Key can contain a ThresholdKey or KeyList, which in turn contain a Key, so + * this mutual recursion would allow nesting arbitrarily deep. A ThresholdKey + * which contains a list of primitive keys has 3 levels: ThresholdKey -> + * KeyList + * -> Key. A KeyList which contains several primitive keys has 2 levels: + * KeyList + * -> Key. A Key with 2 levels of nested ThresholdKeys has 7 levels: Key -> + * ThresholdKey -> KeyList -> Key -> ThresholdKey -> KeyList -> Key. + * + * Each Key should not have more than 46 levels, which implies 15 levels of + * nested ThresholdKeys. + */ +message Key { + oneof key { + /** + * smart contract instance that is authorized as if it had signed with a + * key + */ + ContractID contractID = 1; + + /** + * Ed25519 public key bytes + */ + bytes ed25519 = 2 [ (nanopb).max_size = 32 ]; + + /** + * (NOT SUPPORTED) RSA-3072 public key bytes + */ + bytes RSA_3072 = 3 [ (nanopb).max_size = 32 ]; + + /** + * (NOT SUPPORTED) ECDSA with the p-384 curve public key bytes + */ + bytes ECDSA_384 = 4 [ (nanopb).max_size = 32 ]; + + /** + * a threshold N followed by a list of M keys, any N of which are required + * to form a valid signature + * Leaving this in causes a circular dependecy + */ + // ThresholdKey thresholdKey = 5; + + /** + * A list of Keys of the Key type. + * Leaving this in causes a circular dependency + */ + // KeyList keyList = 6; + + /** + * Compressed ECDSA(secp256k1) public key bytes + */ + bytes ECDSA_secp256k1 = 7 [ (nanopb).max_size = 32 ]; + + /** + * A smart contract that, if the recipient of the active message frame, + * should be treated as having signed. (Note this does not mean the code + * being executed in the frame will belong to the given contract, since + * it could be running another contract's code via delegatecall. + * So setting this key is a more permissive version of setting the + * contractID key, which also requires the code in the active message frame + * belong to the the contract with the given id.) + */ + ContractID delegatable_contract_id = 8; + } +} + +/** + * A set of public keys that are used together to form a threshold signature. + * If the threshold is N and there are M keys, then this is an N of M threshold + * signature. If an account is associated with ThresholdKeys, then a + * transaction to move cryptocurrency out of it must be signed by a list of M + * signatures, where at most M-N of them are blank, and the other at least N of + * them are valid signatures corresponding to at least N of the public keys + * listed here. + */ +message ThresholdKey { + /** + * A valid signature set must have at least this many signatures + */ + uint32 threshold = 1; + + /** + * List of all the keys that can sign + */ + KeyList keys = 2; +} + +/** + * A list of keys that requires all keys (M-of-M) to sign unless otherwise + * specified in documentation. A KeyList may contain repeated keys, but all + * repeated keys are only required to sign once. + */ +message KeyList { + /** + * list of keys + * Limited to 1 here (because we don't have malloc!) + */ + repeated Key keys = 1 [ (nanopb).max_count = 1 ]; +} + +/** + * A number of transferable units of a certain token. + * + * The transferable unit of a token is its smallest denomination, as given by + * the token's decimals property---each minted token contains + * 10decimals transferable units. For example, we could + * think of the cent as the transferable unit of the US dollar + * (decimals=2); and the tinybar as the transferable unit of hbar + * (decimals=8). + * + * Transferable units are not directly comparable across different tokens. + */ +message TokenBalance { + /** + * A unique token id + */ + TokenID tokenId = 1; + + /** + * Number of transferable units of the identified token. For token of type + * FUNGIBLE_COMMON - balance in the smallest denomination. For token of type + * NON_FUNGIBLE_UNIQUE - the number of NFTs held by the account + */ + uint64 balance = 2; + + /** + * Tokens divide into 10decimals pieces + */ + uint32 decimals = 3; +} + +/** + * A sequence of token balances + * Limited to 1 here + */ +message TokenBalances { + repeated TokenBalance tokenBalances = 1 [ (nanopb).max_count = 1 ]; +} + +/* A token - account association */ +message TokenAssociation { + TokenID token_id = 1; // The token involved in the association + AccountID account_id = 2; // The account involved in the association +} + +/** + * Staking metadata for an account or a contract returned in CryptoGetInfo or + * ContractGetInfo queries + */ +message StakingInfo { + /** + * If true, this account or contract declined to receive a staking reward. + */ + bool decline_reward = 1; + + /** + * The staking period during which either the staking settings for this + * account or contract changed (such as starting staking or changing + * staked_node_id) or the most recent reward was earned, whichever is later. + * If this account or contract is not currently staked to a node, then this + * field is not set. + */ + Timestamp stake_period_start = 2; + + /** + * The amount in tinybars that will be received in the next reward situation. + */ + int64 pending_reward = 3; + + /** + * The total of balance of all accounts staked to this account or contract. + */ + int64 staked_to_me = 4; + + /** + * ID of the account or node to which this account or contract is staking. + */ + oneof staked_id { + /** + * The account to which this account or contract is staking. + */ + AccountID staked_account_id = 5; + + /** + * The ID of the node this account or contract is staked to. + */ + int64 staked_node_id = 6; + } +} \ No newline at end of file diff --git a/proto/basic_types_pb2.py b/proto/basic_types_pb2.py new file mode 100644 index 00000000..1861ee2f --- /dev/null +++ b/proto/basic_types_pb2.py @@ -0,0 +1,86 @@ +# -*- coding: utf-8 -*- +# Generated by the protocol buffer compiler. DO NOT EDIT! +# source: proto/basic_types.proto +"""Generated protocol buffer code.""" +from google.protobuf.internal import builder as _builder +from google.protobuf import descriptor as _descriptor +from google.protobuf import descriptor_pool as _descriptor_pool +from google.protobuf import symbol_database as _symbol_database +# @@protoc_insertion_point(imports) + +_sym_db = _symbol_database.Default() + + +import nanopb_pb2 as nanopb__pb2 +from proto import timestamp_pb2 as proto_dot_timestamp__pb2 +from proto import wrappers_pb2 as proto_dot_wrappers__pb2 + + +DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x17proto/basic_types.proto\x12\x06Hedera\x1a\x0cnanopb.proto\x1a\x15proto/timestamp.proto\x1a\x14proto/wrappers.proto\"\x1b\n\x07ShardID\x12\x10\n\x08shardNum\x18\x01 \x01(\x03\"-\n\x07RealmID\x12\x10\n\x08shardNum\x18\x01 \x01(\x03\x12\x10\n\x08realmNum\x18\x02 \x01(\x03\"h\n\tAccountID\x12\x10\n\x08shardNum\x18\x01 \x01(\x03\x12\x10\n\x08realmNum\x18\x02 \x01(\x03\x12\x14\n\naccountNum\x18\x03 \x01(\x03H\x00\x12\x16\n\x05\x61lias\x18\x04 \x01(\x0c\x42\x05\x92?\x02\x08 H\x00\x42\t\n\x07\x61\x63\x63ount\"=\n\x06\x46ileID\x12\x10\n\x08shardNum\x18\x01 \x01(\x03\x12\x10\n\x08realmNum\x18\x02 \x01(\x03\x12\x0f\n\x07\x66ileNum\x18\x03 \x01(\x03\"q\n\nContractID\x12\x10\n\x08shardNum\x18\x01 \x01(\x03\x12\x10\n\x08realmNum\x18\x02 \x01(\x03\x12\x15\n\x0b\x63ontractNum\x18\x03 \x01(\x03H\x00\x12\x1c\n\x0b\x65vm_address\x18\x04 \x01(\x0c\x42\x05\x92?\x02\x08\x14H\x00\x42\n\n\x08\x63ontract\"\x89\x01\n\rTransactionID\x12\x30\n\x15transactionValidStart\x18\x01 \x01(\x0b\x32\x11.Hedera.Timestamp\x12$\n\taccountID\x18\x02 \x01(\x0b\x32\x11.Hedera.AccountID\x12\x11\n\tscheduled\x18\x03 \x01(\x08\x12\r\n\x05nonce\x18\x04 \x01(\x05\"Z\n\rAccountAmount\x12$\n\taccountID\x18\x01 \x01(\x0b\x32\x11.Hedera.AccountID\x12\x0e\n\x06\x61mount\x18\x02 \x01(\x12\x12\x13\n\x0bis_approval\x18\x03 \x01(\x08\"D\n\x0cTransferList\x12\x34\n\x0e\x61\x63\x63ountAmounts\x18\x01 \x03(\x0b\x32\x15.Hedera.AccountAmountB\x05\x92?\x02\x10\x02\"\x92\x01\n\x0bNftTransfer\x12*\n\x0fsenderAccountID\x18\x01 \x01(\x0b\x32\x11.Hedera.AccountID\x12,\n\x11receiverAccountID\x18\x02 \x01(\x0b\x32\x11.Hedera.AccountID\x12\x14\n\x0cserialNumber\x18\x03 \x01(\x03\x12\x13\n\x0bis_approval\x18\x04 \x01(\x08\"\xc6\x01\n\x11TokenTransferList\x12\x1e\n\x05token\x18\x01 \x01(\x0b\x32\x0f.Hedera.TokenID\x12/\n\ttransfers\x18\x02 \x03(\x0b\x32\x15.Hedera.AccountAmountB\x05\x92?\x02\x10\x02\x12\x30\n\x0cnftTransfers\x18\x03 \x03(\x0b\x32\x13.Hedera.NftTransferB\x05\x92?\x02\x10\x01\x12.\n\x11\x65xpected_decimals\x18\x04 \x01(\x0b\x32\x13.Hedera.UInt32Value\"2\n\x08\x46raction\x12\x11\n\tnumerator\x18\x01 \x01(\x03\x12\x13\n\x0b\x64\x65nominator\x18\x02 \x01(\x03\"?\n\x07TokenID\x12\x10\n\x08shardNum\x18\x01 \x01(\x03\x12\x10\n\x08realmNum\x18\x02 \x01(\x03\x12\x10\n\x08tokenNum\x18\x03 \x01(\x03\"\xe0\x01\n\x03Key\x12(\n\ncontractID\x18\x01 \x01(\x0b\x32\x12.Hedera.ContractIDH\x00\x12\x18\n\x07\x65\x64\x32\x35\x35\x31\x39\x18\x02 \x01(\x0c\x42\x05\x92?\x02\x08 H\x00\x12\x19\n\x08RSA_3072\x18\x03 \x01(\x0c\x42\x05\x92?\x02\x08 H\x00\x12\x1a\n\tECDSA_384\x18\x04 \x01(\x0c\x42\x05\x92?\x02\x08 H\x00\x12 \n\x0f\x45\x43\x44SA_secp256k1\x18\x07 \x01(\x0c\x42\x05\x92?\x02\x08 H\x00\x12\x35\n\x17\x64\x65legatable_contract_id\x18\x08 \x01(\x0b\x32\x12.Hedera.ContractIDH\x00\x42\x05\n\x03key\"@\n\x0cThresholdKey\x12\x11\n\tthreshold\x18\x01 \x01(\r\x12\x1d\n\x04keys\x18\x02 \x01(\x0b\x32\x0f.Hedera.KeyList\"+\n\x07KeyList\x12 \n\x04keys\x18\x01 \x03(\x0b\x32\x0b.Hedera.KeyB\x05\x92?\x02\x10\x01\"S\n\x0cTokenBalance\x12 \n\x07tokenId\x18\x01 \x01(\x0b\x32\x0f.Hedera.TokenID\x12\x0f\n\x07\x62\x61lance\x18\x02 \x01(\x04\x12\x10\n\x08\x64\x65\x63imals\x18\x03 \x01(\r\"C\n\rTokenBalances\x12\x32\n\rtokenBalances\x18\x01 \x03(\x0b\x32\x14.Hedera.TokenBalanceB\x05\x92?\x02\x10\x01\"\\\n\x10TokenAssociation\x12!\n\x08token_id\x18\x01 \x01(\x0b\x32\x0f.Hedera.TokenID\x12%\n\naccount_id\x18\x02 \x01(\x0b\x32\x11.Hedera.AccountID\"\xd9\x01\n\x0bStakingInfo\x12\x16\n\x0e\x64\x65\x63line_reward\x18\x01 \x01(\x08\x12-\n\x12stake_period_start\x18\x02 \x01(\x0b\x32\x11.Hedera.Timestamp\x12\x16\n\x0epending_reward\x18\x03 \x01(\x03\x12\x14\n\x0cstaked_to_me\x18\x04 \x01(\x03\x12.\n\x11staked_account_id\x18\x05 \x01(\x0b\x32\x11.Hedera.AccountIDH\x00\x12\x18\n\x0estaked_node_id\x18\x06 \x01(\x03H\x00\x42\x0b\n\tstaked_idb\x06proto3') + +_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, globals()) +_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'proto.basic_types_pb2', globals()) +if _descriptor._USE_C_DESCRIPTORS == False: + + DESCRIPTOR._options = None + _ACCOUNTID.fields_by_name['alias']._options = None + _ACCOUNTID.fields_by_name['alias']._serialized_options = b'\222?\002\010 ' + _CONTRACTID.fields_by_name['evm_address']._options = None + _CONTRACTID.fields_by_name['evm_address']._serialized_options = b'\222?\002\010\024' + _TRANSFERLIST.fields_by_name['accountAmounts']._options = None + _TRANSFERLIST.fields_by_name['accountAmounts']._serialized_options = b'\222?\002\020\002' + _TOKENTRANSFERLIST.fields_by_name['transfers']._options = None + _TOKENTRANSFERLIST.fields_by_name['transfers']._serialized_options = b'\222?\002\020\002' + _TOKENTRANSFERLIST.fields_by_name['nftTransfers']._options = None + _TOKENTRANSFERLIST.fields_by_name['nftTransfers']._serialized_options = b'\222?\002\020\001' + _KEY.fields_by_name['ed25519']._options = None + _KEY.fields_by_name['ed25519']._serialized_options = b'\222?\002\010 ' + _KEY.fields_by_name['RSA_3072']._options = None + _KEY.fields_by_name['RSA_3072']._serialized_options = b'\222?\002\010 ' + _KEY.fields_by_name['ECDSA_384']._options = None + _KEY.fields_by_name['ECDSA_384']._serialized_options = b'\222?\002\010 ' + _KEY.fields_by_name['ECDSA_secp256k1']._options = None + _KEY.fields_by_name['ECDSA_secp256k1']._serialized_options = b'\222?\002\010 ' + _KEYLIST.fields_by_name['keys']._options = None + _KEYLIST.fields_by_name['keys']._serialized_options = b'\222?\002\020\001' + _TOKENBALANCES.fields_by_name['tokenBalances']._options = None + _TOKENBALANCES.fields_by_name['tokenBalances']._serialized_options = b'\222?\002\020\001' + _SHARDID._serialized_start=94 + _SHARDID._serialized_end=121 + _REALMID._serialized_start=123 + _REALMID._serialized_end=168 + _ACCOUNTID._serialized_start=170 + _ACCOUNTID._serialized_end=274 + _FILEID._serialized_start=276 + _FILEID._serialized_end=337 + _CONTRACTID._serialized_start=339 + _CONTRACTID._serialized_end=452 + _TRANSACTIONID._serialized_start=455 + _TRANSACTIONID._serialized_end=592 + _ACCOUNTAMOUNT._serialized_start=594 + _ACCOUNTAMOUNT._serialized_end=684 + _TRANSFERLIST._serialized_start=686 + _TRANSFERLIST._serialized_end=754 + _NFTTRANSFER._serialized_start=757 + _NFTTRANSFER._serialized_end=903 + _TOKENTRANSFERLIST._serialized_start=906 + _TOKENTRANSFERLIST._serialized_end=1104 + _FRACTION._serialized_start=1106 + _FRACTION._serialized_end=1156 + _TOKENID._serialized_start=1158 + _TOKENID._serialized_end=1221 + _KEY._serialized_start=1224 + _KEY._serialized_end=1448 + _THRESHOLDKEY._serialized_start=1450 + _THRESHOLDKEY._serialized_end=1514 + _KEYLIST._serialized_start=1516 + _KEYLIST._serialized_end=1559 + _TOKENBALANCE._serialized_start=1561 + _TOKENBALANCE._serialized_end=1644 + _TOKENBALANCES._serialized_start=1646 + _TOKENBALANCES._serialized_end=1713 + _TOKENASSOCIATION._serialized_start=1715 + _TOKENASSOCIATION._serialized_end=1807 + _STAKINGINFO._serialized_start=1810 + _STAKINGINFO._serialized_end=2027 +# @@protoc_insertion_point(module_scope) diff --git a/proto/basic_types_pb2.pyi b/proto/basic_types_pb2.pyi new file mode 100644 index 00000000..9707db1c --- /dev/null +++ b/proto/basic_types_pb2.pyi @@ -0,0 +1,862 @@ +""" +@generated by mypy-protobuf. Do not edit manually! +isort:skip_file +""" +import builtins +import collections.abc +import google.protobuf.descriptor +import google.protobuf.internal.containers +import google.protobuf.message +import proto.timestamp_pb2 +import proto.wrappers_pb2 +import sys + +if sys.version_info >= (3, 8): + import typing as typing_extensions +else: + import typing_extensions + +DESCRIPTOR: google.protobuf.descriptor.FileDescriptor + +@typing_extensions.final +class ShardID(google.protobuf.message.Message): + """* + Each shard has a nonnegative shard number. Each realm within a given shard + has a nonnegative realm number (that number might be reused in other + shards). And each account, file, and smart contract instance within a given + realm has a nonnegative number (which might be reused in other realms). + Every account, file, and smart contract instance is within exactly one + realm. So a FileID is a triplet of numbers, like 0.1.2 for entity number 2 + within realm 1 within shard 0. Each realm maintains a single counter for + assigning numbers, so if there is a file with ID 0.1.2, then there won't be + an account or smart contract instance with ID 0.1.2. + + Everything is partitioned into realms so that each Solidity smart contract + can access everything in just a single realm, locking all those entities + while it's running, but other smart contracts could potentially run in + other realms in parallel. So realms allow Solidity to be parallelized + somewhat, even though the language itself assumes everything is serial. + """ + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + SHARDNUM_FIELD_NUMBER: builtins.int + shardNum: builtins.int + """* + the shard number (nonnegative) + """ + def __init__( + self, + *, + shardNum: builtins.int = ..., + ) -> None: ... + def ClearField(self, field_name: typing_extensions.Literal["shardNum", b"shardNum"]) -> None: ... + +global___ShardID = ShardID + +@typing_extensions.final +class RealmID(google.protobuf.message.Message): + """* + The ID for a realm. Within a given shard, every realm has a unique ID. Each + account, file, and contract instance belongs to exactly one realm. + """ + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + SHARDNUM_FIELD_NUMBER: builtins.int + REALMNUM_FIELD_NUMBER: builtins.int + shardNum: builtins.int + """* + The shard number (nonnegative) + """ + realmNum: builtins.int + """* + The realm number (nonnegative) + """ + def __init__( + self, + *, + shardNum: builtins.int = ..., + realmNum: builtins.int = ..., + ) -> None: ... + def ClearField(self, field_name: typing_extensions.Literal["realmNum", b"realmNum", "shardNum", b"shardNum"]) -> None: ... + +global___RealmID = RealmID + +@typing_extensions.final +class AccountID(google.protobuf.message.Message): + """* + The ID for an a cryptocurrency account + """ + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + SHARDNUM_FIELD_NUMBER: builtins.int + REALMNUM_FIELD_NUMBER: builtins.int + ACCOUNTNUM_FIELD_NUMBER: builtins.int + ALIAS_FIELD_NUMBER: builtins.int + shardNum: builtins.int + """* + The shard number (nonnegative) + """ + realmNum: builtins.int + """* + The realm number (nonnegative) + """ + accountNum: builtins.int + """* + A non-negative account number unique within its realm + """ + alias: builtins.bytes + """* + The public key bytes to be used as the account's alias. The public key + bytes are the result of serializing a protobuf Key message for any + primitive key type. Currently only primitive key bytes are supported as + an alias (ThresholdKey, KeyList, ContractID, and delegatable_contract_id + are not supported) + + At most one account can ever have a given alias and it is used for + account creation if it was automatically created using a crypto + transfer. It will be null if an account is created normally. It is + immutable once it is set for an account. + + If a transaction auto-creates the account, any further transfers to that + alias will simply be deposited in that account, without creating + anything, and with no creation fee being charged. + """ + def __init__( + self, + *, + shardNum: builtins.int = ..., + realmNum: builtins.int = ..., + accountNum: builtins.int = ..., + alias: builtins.bytes = ..., + ) -> None: ... + def HasField(self, field_name: typing_extensions.Literal["account", b"account", "accountNum", b"accountNum", "alias", b"alias"]) -> builtins.bool: ... + def ClearField(self, field_name: typing_extensions.Literal["account", b"account", "accountNum", b"accountNum", "alias", b"alias", "realmNum", b"realmNum", "shardNum", b"shardNum"]) -> None: ... + def WhichOneof(self, oneof_group: typing_extensions.Literal["account", b"account"]) -> typing_extensions.Literal["accountNum", "alias"] | None: ... + +global___AccountID = AccountID + +@typing_extensions.final +class FileID(google.protobuf.message.Message): + """* + The ID for a file + """ + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + SHARDNUM_FIELD_NUMBER: builtins.int + REALMNUM_FIELD_NUMBER: builtins.int + FILENUM_FIELD_NUMBER: builtins.int + shardNum: builtins.int + """* + The shard number (nonnegative) + """ + realmNum: builtins.int + """* + The realm number (nonnegative) + """ + fileNum: builtins.int + """* + A nonnegative File number unique within its realm + """ + def __init__( + self, + *, + shardNum: builtins.int = ..., + realmNum: builtins.int = ..., + fileNum: builtins.int = ..., + ) -> None: ... + def ClearField(self, field_name: typing_extensions.Literal["fileNum", b"fileNum", "realmNum", b"realmNum", "shardNum", b"shardNum"]) -> None: ... + +global___FileID = FileID + +@typing_extensions.final +class ContractID(google.protobuf.message.Message): + """* + The ID for a smart contract instance + """ + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + SHARDNUM_FIELD_NUMBER: builtins.int + REALMNUM_FIELD_NUMBER: builtins.int + CONTRACTNUM_FIELD_NUMBER: builtins.int + EVM_ADDRESS_FIELD_NUMBER: builtins.int + shardNum: builtins.int + """* + The shard number (nonnegative) + """ + realmNum: builtins.int + """* + The realm number (nonnegative) + """ + contractNum: builtins.int + """* + A nonnegative number unique within a given shard and realm + """ + evm_address: builtins.bytes + """* + The 20-byte EVM address of the contract to call. + + Every contract has an EVM address determined by its + shard.realm.num id. This address is as follows:
  1. The + first 4 bytes are the big-endian representation of the shard.
  2. +
  3. The next 8 bytes are the big-endian representation of the + realm.
  4. The final 8 bytes are the big-endian representation of + the number.
  5. +
+ + Contracts created via CREATE2 have an additional, primary address + that is derived from the EIP-1014 + specification, and does not have a simple relation to a + shard.realm.num id. + + (Please do note that CREATE2 contracts can also be referenced by the + three-part EVM address described above.) + """ + def __init__( + self, + *, + shardNum: builtins.int = ..., + realmNum: builtins.int = ..., + contractNum: builtins.int = ..., + evm_address: builtins.bytes = ..., + ) -> None: ... + def HasField(self, field_name: typing_extensions.Literal["contract", b"contract", "contractNum", b"contractNum", "evm_address", b"evm_address"]) -> builtins.bool: ... + def ClearField(self, field_name: typing_extensions.Literal["contract", b"contract", "contractNum", b"contractNum", "evm_address", b"evm_address", "realmNum", b"realmNum", "shardNum", b"shardNum"]) -> None: ... + def WhichOneof(self, oneof_group: typing_extensions.Literal["contract", b"contract"]) -> typing_extensions.Literal["contractNum", "evm_address"] | None: ... + +global___ContractID = ContractID + +@typing_extensions.final +class TransactionID(google.protobuf.message.Message): + """* + The ID for a transaction. This is used for retrieving receipts and records + for a transaction, for appending to a file right after creating it, for + instantiating a smart contract with bytecode in a file just created, and + internally by the network for detecting when duplicate transactions are + submitted. A user might get a transaction processed faster by submitting it + to N nodes, each with a different node account, but all with the same + TransactionID. Then, the transaction will take effect when the first of all + those nodes submits the transaction and it reaches consensus. The other + transactions will not take effect. So this could make the transaction take + effect faster, if any given node might be slow. However, the full + transaction fee is charged for each transaction, so the total fee is N times + as much if the transaction is sent to N nodes. + + Applicable to Scheduled Transactions: + - The ID of a Scheduled Transaction has transactionValidStart and + accountIDs inherited from the ScheduleCreate transaction that created it. + That is to say that they are equal + - The scheduled property is true for Scheduled Transactions + - transactionValidStart, accountID and scheduled properties should be + omitted + """ + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + TRANSACTIONVALIDSTART_FIELD_NUMBER: builtins.int + ACCOUNTID_FIELD_NUMBER: builtins.int + SCHEDULED_FIELD_NUMBER: builtins.int + NONCE_FIELD_NUMBER: builtins.int + @property + def transactionValidStart(self) -> proto.timestamp_pb2.Timestamp: + """* + The transaction is invalid if consensusTimestamp < + transactionID.transactionStartValid + """ + @property + def accountID(self) -> global___AccountID: + """* + The Account ID that paid for this transaction + """ + scheduled: builtins.bool + """* + Whether the Transaction is of type Scheduled or no + """ + nonce: builtins.int + """* + The identifier for an internal transaction that was spawned as part + of handling a user transaction. (These internal transactions share the + transactionValidStart and accountID of the user transaction, so a + nonce is necessary to give them a unique TransactionID.) + + An example is when a "parent" ContractCreate or ContractCall transaction + calls one or more HTS precompiled contracts; each of the "child" + transactions spawned for a precompile has a id with a different nonce. + """ + def __init__( + self, + *, + transactionValidStart: proto.timestamp_pb2.Timestamp | None = ..., + accountID: global___AccountID | None = ..., + scheduled: builtins.bool = ..., + nonce: builtins.int = ..., + ) -> None: ... + def HasField(self, field_name: typing_extensions.Literal["accountID", b"accountID", "transactionValidStart", b"transactionValidStart"]) -> builtins.bool: ... + def ClearField(self, field_name: typing_extensions.Literal["accountID", b"accountID", "nonce", b"nonce", "scheduled", b"scheduled", "transactionValidStart", b"transactionValidStart"]) -> None: ... + +global___TransactionID = TransactionID + +@typing_extensions.final +class AccountAmount(google.protobuf.message.Message): + """* + An account, and the amount that it sends or receives during a cryptocurrency + or token transfer. + """ + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + ACCOUNTID_FIELD_NUMBER: builtins.int + AMOUNT_FIELD_NUMBER: builtins.int + IS_APPROVAL_FIELD_NUMBER: builtins.int + @property + def accountID(self) -> global___AccountID: + """* + The Account ID that sends/receives cryptocurrency or tokens + """ + amount: builtins.int + """* + The amount of tinybars (for Crypto transfers) or in the lowest + denomination (for Token transfers) that the account sends(negative) or + receives(positive) + """ + is_approval: builtins.bool + """* + If true then the transfer is expected to be an approved allowance and the + accountID is expected to be the owner. The default is false (omitted). + """ + def __init__( + self, + *, + accountID: global___AccountID | None = ..., + amount: builtins.int = ..., + is_approval: builtins.bool = ..., + ) -> None: ... + def HasField(self, field_name: typing_extensions.Literal["accountID", b"accountID"]) -> builtins.bool: ... + def ClearField(self, field_name: typing_extensions.Literal["accountID", b"accountID", "amount", b"amount", "is_approval", b"is_approval"]) -> None: ... + +global___AccountAmount = AccountAmount + +@typing_extensions.final +class TransferList(google.protobuf.message.Message): + """* + A list of accounts and amounts to transfer out of each account (negative) or + into it (positive). + """ + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + ACCOUNTAMOUNTS_FIELD_NUMBER: builtins.int + @property + def accountAmounts(self) -> google.protobuf.internal.containers.RepeatedCompositeFieldContainer[global___AccountAmount]: + """* + Multiple list of AccountAmount pairs, each of which has an account and + an amount to transfer into it (positive) or out of it (negative) + Limited to 2 for a transfer between two accounts + """ + def __init__( + self, + *, + accountAmounts: collections.abc.Iterable[global___AccountAmount] | None = ..., + ) -> None: ... + def ClearField(self, field_name: typing_extensions.Literal["accountAmounts", b"accountAmounts"]) -> None: ... + +global___TransferList = TransferList + +@typing_extensions.final +class NftTransfer(google.protobuf.message.Message): + """* + A sender account, a receiver account, and the serial number of an NFT of a + Token with NON_FUNGIBLE_UNIQUE type. When minting NFTs the sender will be + the default AccountID instance (0.0.0) and when burning NFTs, the receiver + will be the default AccountID instance. + """ + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + SENDERACCOUNTID_FIELD_NUMBER: builtins.int + RECEIVERACCOUNTID_FIELD_NUMBER: builtins.int + SERIALNUMBER_FIELD_NUMBER: builtins.int + IS_APPROVAL_FIELD_NUMBER: builtins.int + @property + def senderAccountID(self) -> global___AccountID: + """* + The accountID of the sender + """ + @property + def receiverAccountID(self) -> global___AccountID: + """* + The accountID of the receiver + """ + serialNumber: builtins.int + """* + The serial number of the NFT + """ + is_approval: builtins.bool + """* + If true then the transfer is expected to be an approved allowance and the + senderAccountID is expected to be the owner. The default is false + (omitted). + """ + def __init__( + self, + *, + senderAccountID: global___AccountID | None = ..., + receiverAccountID: global___AccountID | None = ..., + serialNumber: builtins.int = ..., + is_approval: builtins.bool = ..., + ) -> None: ... + def HasField(self, field_name: typing_extensions.Literal["receiverAccountID", b"receiverAccountID", "senderAccountID", b"senderAccountID"]) -> builtins.bool: ... + def ClearField(self, field_name: typing_extensions.Literal["is_approval", b"is_approval", "receiverAccountID", b"receiverAccountID", "senderAccountID", b"senderAccountID", "serialNumber", b"serialNumber"]) -> None: ... + +global___NftTransfer = NftTransfer + +@typing_extensions.final +class TokenTransferList(google.protobuf.message.Message): + """* + A list of token IDs and amounts representing the transferred out (negative) + or into (positive) amounts, represented in the lowest denomination of the + token + """ + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + TOKEN_FIELD_NUMBER: builtins.int + TRANSFERS_FIELD_NUMBER: builtins.int + NFTTRANSFERS_FIELD_NUMBER: builtins.int + EXPECTED_DECIMALS_FIELD_NUMBER: builtins.int + @property + def token(self) -> global___TokenID: + """* + The ID of the token + """ + @property + def transfers(self) -> google.protobuf.internal.containers.RepeatedCompositeFieldContainer[global___AccountAmount]: + """* + Applicable to tokens of type FUNGIBLE_COMMON. Multiple list of + AccountAmounts, each of which has an account and amount + Limited to 2 for 1 allowed transfer (reciprocal subtraction of balance + + actual transfer) + """ + @property + def nftTransfers(self) -> google.protobuf.internal.containers.RepeatedCompositeFieldContainer[global___NftTransfer]: + """* + Applicable to tokens of type NON_FUNGIBLE_UNIQUE. Multiple list of + NftTransfers, each of which has a sender and receiver account, including + the serial number of the NFT + Limited to 1 here + """ + @property + def expected_decimals(self) -> proto.wrappers_pb2.UInt32Value: + """* + If present, the number of decimals this fungible token type is expected to + have. The transfer will fail with UNEXPECTED_TOKEN_DECIMALS if the actual + decimals differ. + """ + def __init__( + self, + *, + token: global___TokenID | None = ..., + transfers: collections.abc.Iterable[global___AccountAmount] | None = ..., + nftTransfers: collections.abc.Iterable[global___NftTransfer] | None = ..., + expected_decimals: proto.wrappers_pb2.UInt32Value | None = ..., + ) -> None: ... + def HasField(self, field_name: typing_extensions.Literal["expected_decimals", b"expected_decimals", "token", b"token"]) -> builtins.bool: ... + def ClearField(self, field_name: typing_extensions.Literal["expected_decimals", b"expected_decimals", "nftTransfers", b"nftTransfers", "token", b"token", "transfers", b"transfers"]) -> None: ... + +global___TokenTransferList = TokenTransferList + +@typing_extensions.final +class Fraction(google.protobuf.message.Message): + """* + A rational number, used to set the amount of a value transfer to collect as + a custom fee + """ + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + NUMERATOR_FIELD_NUMBER: builtins.int + DENOMINATOR_FIELD_NUMBER: builtins.int + numerator: builtins.int + """* + The rational's numerator + """ + denominator: builtins.int + """* + The rational's denominator; a zero value will result in + FRACTION_DIVIDES_BY_ZERO + """ + def __init__( + self, + *, + numerator: builtins.int = ..., + denominator: builtins.int = ..., + ) -> None: ... + def ClearField(self, field_name: typing_extensions.Literal["denominator", b"denominator", "numerator", b"numerator"]) -> None: ... + +global___Fraction = Fraction + +@typing_extensions.final +class TokenID(google.protobuf.message.Message): + """* + Unique identifier for a token + """ + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + SHARDNUM_FIELD_NUMBER: builtins.int + REALMNUM_FIELD_NUMBER: builtins.int + TOKENNUM_FIELD_NUMBER: builtins.int + shardNum: builtins.int + """* + A nonnegative shard number + """ + realmNum: builtins.int + """* + A nonnegative realm number + """ + tokenNum: builtins.int + """* + A nonnegative token number + """ + def __init__( + self, + *, + shardNum: builtins.int = ..., + realmNum: builtins.int = ..., + tokenNum: builtins.int = ..., + ) -> None: ... + def ClearField(self, field_name: typing_extensions.Literal["realmNum", b"realmNum", "shardNum", b"shardNum", "tokenNum", b"tokenNum"]) -> None: ... + +global___TokenID = TokenID + +@typing_extensions.final +class Key(google.protobuf.message.Message): + """* + A Key can be a public key from either the Ed25519 or ECDSA(secp256k1) + signature schemes, where in the ECDSA(secp256k1) case we require the 33-byte + compressed form of the public key. We call these public keys primitive + keys. + + If an account has primitive key associated to it, then the corresponding + private key must sign any transaction to transfer cryptocurrency out of it. + + A Key can also be the ID of a smart contract instance, which is then + authorized to perform any precompiled contract action that requires this key + to sign. + + Note that when a Key is a smart contract ID, it doesn't mean the + contract with that ID will actually create a cryptographic signature. It + only means that when the contract calls a precompiled contract, the + resulting "child transaction" will be authorized to perform any action + controlled by the Key. + + A Key can be a "threshold key", which means a list of M keys, any N of which + must sign in order for the threshold signature to be considered valid. The + keys within a threshold signature may themselves be threshold signatures, to + allow complex signature requirements. + + A Key can be a "key list" where all keys in the list must sign unless + specified otherwise in the documentation for a specific transaction type + (e.g. FileDeleteTransactionBody). Their use is dependent on context. For + example, a Hedera file is created with a list of keys, where all of them + must sign a transaction to create or modify the file, but only one of them + is needed to sign a transaction to delete the file. So it's a single list + that sometimes acts as a 1-of-M threshold key, and sometimes acts as an + M-of-M threshold key. A key list is always an M-of-M, unless specified + otherwise in documentation. A key list can have nested key lists or + threshold keys. Nested key lists are always M-of-M. A key list can have + repeated primitive public keys, but all repeated keys are only required to + sign once. + + A Key can contain a ThresholdKey or KeyList, which in turn contain a Key, so + this mutual recursion would allow nesting arbitrarily deep. A ThresholdKey + which contains a list of primitive keys has 3 levels: ThresholdKey -> + KeyList + -> Key. A KeyList which contains several primitive keys has 2 levels: + KeyList + -> Key. A Key with 2 levels of nested ThresholdKeys has 7 levels: Key -> + ThresholdKey -> KeyList -> Key -> ThresholdKey -> KeyList -> Key. + + Each Key should not have more than 46 levels, which implies 15 levels of + nested ThresholdKeys. + """ + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + CONTRACTID_FIELD_NUMBER: builtins.int + ED25519_FIELD_NUMBER: builtins.int + RSA_3072_FIELD_NUMBER: builtins.int + ECDSA_384_FIELD_NUMBER: builtins.int + ECDSA_SECP256K1_FIELD_NUMBER: builtins.int + DELEGATABLE_CONTRACT_ID_FIELD_NUMBER: builtins.int + @property + def contractID(self) -> global___ContractID: + """* + smart contract instance that is authorized as if it had signed with a + key + """ + ed25519: builtins.bytes + """* + Ed25519 public key bytes + """ + RSA_3072: builtins.bytes + """* + (NOT SUPPORTED) RSA-3072 public key bytes + """ + ECDSA_384: builtins.bytes + """* + (NOT SUPPORTED) ECDSA with the p-384 curve public key bytes + """ + ECDSA_secp256k1: builtins.bytes + """KeyList keyList = 6; + + * + Compressed ECDSA(secp256k1) public key bytes + """ + @property + def delegatable_contract_id(self) -> global___ContractID: + """* + A smart contract that, if the recipient of the active message frame, + should be treated as having signed. (Note this does not mean the code + being executed in the frame will belong to the given contract, since + it could be running another contract's code via delegatecall. + So setting this key is a more permissive version of setting the + contractID key, which also requires the code in the active message frame + belong to the the contract with the given id.) + """ + def __init__( + self, + *, + contractID: global___ContractID | None = ..., + ed25519: builtins.bytes = ..., + RSA_3072: builtins.bytes = ..., + ECDSA_384: builtins.bytes = ..., + ECDSA_secp256k1: builtins.bytes = ..., + delegatable_contract_id: global___ContractID | None = ..., + ) -> None: ... + def HasField(self, field_name: typing_extensions.Literal["ECDSA_384", b"ECDSA_384", "ECDSA_secp256k1", b"ECDSA_secp256k1", "RSA_3072", b"RSA_3072", "contractID", b"contractID", "delegatable_contract_id", b"delegatable_contract_id", "ed25519", b"ed25519", "key", b"key"]) -> builtins.bool: ... + def ClearField(self, field_name: typing_extensions.Literal["ECDSA_384", b"ECDSA_384", "ECDSA_secp256k1", b"ECDSA_secp256k1", "RSA_3072", b"RSA_3072", "contractID", b"contractID", "delegatable_contract_id", b"delegatable_contract_id", "ed25519", b"ed25519", "key", b"key"]) -> None: ... + def WhichOneof(self, oneof_group: typing_extensions.Literal["key", b"key"]) -> typing_extensions.Literal["contractID", "ed25519", "RSA_3072", "ECDSA_384", "ECDSA_secp256k1", "delegatable_contract_id"] | None: ... + +global___Key = Key + +@typing_extensions.final +class ThresholdKey(google.protobuf.message.Message): + """* + A set of public keys that are used together to form a threshold signature. + If the threshold is N and there are M keys, then this is an N of M threshold + signature. If an account is associated with ThresholdKeys, then a + transaction to move cryptocurrency out of it must be signed by a list of M + signatures, where at most M-N of them are blank, and the other at least N of + them are valid signatures corresponding to at least N of the public keys + listed here. + """ + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + THRESHOLD_FIELD_NUMBER: builtins.int + KEYS_FIELD_NUMBER: builtins.int + threshold: builtins.int + """* + A valid signature set must have at least this many signatures + """ + @property + def keys(self) -> global___KeyList: + """* + List of all the keys that can sign + """ + def __init__( + self, + *, + threshold: builtins.int = ..., + keys: global___KeyList | None = ..., + ) -> None: ... + def HasField(self, field_name: typing_extensions.Literal["keys", b"keys"]) -> builtins.bool: ... + def ClearField(self, field_name: typing_extensions.Literal["keys", b"keys", "threshold", b"threshold"]) -> None: ... + +global___ThresholdKey = ThresholdKey + +@typing_extensions.final +class KeyList(google.protobuf.message.Message): + """* + A list of keys that requires all keys (M-of-M) to sign unless otherwise + specified in documentation. A KeyList may contain repeated keys, but all + repeated keys are only required to sign once. + """ + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + KEYS_FIELD_NUMBER: builtins.int + @property + def keys(self) -> google.protobuf.internal.containers.RepeatedCompositeFieldContainer[global___Key]: + """* + list of keys + Limited to 1 here (because we don't have malloc!) + """ + def __init__( + self, + *, + keys: collections.abc.Iterable[global___Key] | None = ..., + ) -> None: ... + def ClearField(self, field_name: typing_extensions.Literal["keys", b"keys"]) -> None: ... + +global___KeyList = KeyList + +@typing_extensions.final +class TokenBalance(google.protobuf.message.Message): + """* + A number of transferable units of a certain token. + + The transferable unit of a token is its smallest denomination, as given by + the token's decimals property---each minted token contains + 10decimals transferable units. For example, we could + think of the cent as the transferable unit of the US dollar + (decimals=2); and the tinybar as the transferable unit of hbar + (decimals=8). + + Transferable units are not directly comparable across different tokens. + """ + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + TOKENID_FIELD_NUMBER: builtins.int + BALANCE_FIELD_NUMBER: builtins.int + DECIMALS_FIELD_NUMBER: builtins.int + @property + def tokenId(self) -> global___TokenID: + """* + A unique token id + """ + balance: builtins.int + """* + Number of transferable units of the identified token. For token of type + FUNGIBLE_COMMON - balance in the smallest denomination. For token of type + NON_FUNGIBLE_UNIQUE - the number of NFTs held by the account + """ + decimals: builtins.int + """* + Tokens divide into 10decimals pieces + """ + def __init__( + self, + *, + tokenId: global___TokenID | None = ..., + balance: builtins.int = ..., + decimals: builtins.int = ..., + ) -> None: ... + def HasField(self, field_name: typing_extensions.Literal["tokenId", b"tokenId"]) -> builtins.bool: ... + def ClearField(self, field_name: typing_extensions.Literal["balance", b"balance", "decimals", b"decimals", "tokenId", b"tokenId"]) -> None: ... + +global___TokenBalance = TokenBalance + +@typing_extensions.final +class TokenBalances(google.protobuf.message.Message): + """* + A sequence of token balances + Limited to 1 here + """ + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + TOKENBALANCES_FIELD_NUMBER: builtins.int + @property + def tokenBalances(self) -> google.protobuf.internal.containers.RepeatedCompositeFieldContainer[global___TokenBalance]: ... + def __init__( + self, + *, + tokenBalances: collections.abc.Iterable[global___TokenBalance] | None = ..., + ) -> None: ... + def ClearField(self, field_name: typing_extensions.Literal["tokenBalances", b"tokenBalances"]) -> None: ... + +global___TokenBalances = TokenBalances + +@typing_extensions.final +class TokenAssociation(google.protobuf.message.Message): + """A token - account association""" + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + TOKEN_ID_FIELD_NUMBER: builtins.int + ACCOUNT_ID_FIELD_NUMBER: builtins.int + @property + def token_id(self) -> global___TokenID: + """The token involved in the association""" + @property + def account_id(self) -> global___AccountID: + """The account involved in the association""" + def __init__( + self, + *, + token_id: global___TokenID | None = ..., + account_id: global___AccountID | None = ..., + ) -> None: ... + def HasField(self, field_name: typing_extensions.Literal["account_id", b"account_id", "token_id", b"token_id"]) -> builtins.bool: ... + def ClearField(self, field_name: typing_extensions.Literal["account_id", b"account_id", "token_id", b"token_id"]) -> None: ... + +global___TokenAssociation = TokenAssociation + +@typing_extensions.final +class StakingInfo(google.protobuf.message.Message): + """* + Staking metadata for an account or a contract returned in CryptoGetInfo or + ContractGetInfo queries + """ + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + DECLINE_REWARD_FIELD_NUMBER: builtins.int + STAKE_PERIOD_START_FIELD_NUMBER: builtins.int + PENDING_REWARD_FIELD_NUMBER: builtins.int + STAKED_TO_ME_FIELD_NUMBER: builtins.int + STAKED_ACCOUNT_ID_FIELD_NUMBER: builtins.int + STAKED_NODE_ID_FIELD_NUMBER: builtins.int + decline_reward: builtins.bool + """* + If true, this account or contract declined to receive a staking reward. + """ + @property + def stake_period_start(self) -> proto.timestamp_pb2.Timestamp: + """* + The staking period during which either the staking settings for this + account or contract changed (such as starting staking or changing + staked_node_id) or the most recent reward was earned, whichever is later. + If this account or contract is not currently staked to a node, then this + field is not set. + """ + pending_reward: builtins.int + """* + The amount in tinybars that will be received in the next reward situation. + """ + staked_to_me: builtins.int + """* + The total of balance of all accounts staked to this account or contract. + """ + @property + def staked_account_id(self) -> global___AccountID: + """* + The account to which this account or contract is staking. + """ + staked_node_id: builtins.int + """* + The ID of the node this account or contract is staked to. + """ + def __init__( + self, + *, + decline_reward: builtins.bool = ..., + stake_period_start: proto.timestamp_pb2.Timestamp | None = ..., + pending_reward: builtins.int = ..., + staked_to_me: builtins.int = ..., + staked_account_id: global___AccountID | None = ..., + staked_node_id: builtins.int = ..., + ) -> None: ... + def HasField(self, field_name: typing_extensions.Literal["stake_period_start", b"stake_period_start", "staked_account_id", b"staked_account_id", "staked_id", b"staked_id", "staked_node_id", b"staked_node_id"]) -> builtins.bool: ... + def ClearField(self, field_name: typing_extensions.Literal["decline_reward", b"decline_reward", "pending_reward", b"pending_reward", "stake_period_start", b"stake_period_start", "staked_account_id", b"staked_account_id", "staked_id", b"staked_id", "staked_node_id", b"staked_node_id", "staked_to_me", b"staked_to_me"]) -> None: ... + def WhichOneof(self, oneof_group: typing_extensions.Literal["staked_id", b"staked_id"]) -> typing_extensions.Literal["staked_account_id", "staked_node_id"] | None: ... + +global___StakingInfo = StakingInfo diff --git a/proto/crypto_create.proto b/proto/crypto_create.proto new file mode 100644 index 00000000..dbe42cec --- /dev/null +++ b/proto/crypto_create.proto @@ -0,0 +1,160 @@ +syntax = "proto3"; + +package Hedera; + +/*- + * ‌ + * Hedera Network Services Protobuf + * ​ + * Copyright (C) 2018 - 2021 Hedera Hashgraph, LLC + * ​ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ‍ + */ +import "nanopb.proto"; +import "proto/basic_types.proto"; +import "proto/duration.proto"; + +/* + * Create a new account. After the account is created, the AccountID for it is + * in the receipt. It can also be retrieved with a GetByKey query. Threshold + * values can be defined, and records are generated and stored for 25 hours for + * any transfer that exceeds the thresholds. This account is charged for each + * record generated, so the thresholds are useful for limiting record + * generation to happen only for large transactions. + * + * The Key field is the key used to sign transactions for this account. If the + * account has receiverSigRequired set to true, then all cryptocurrency + * transfers must be signed by this account's key, both for transfers in and + * out. If it is false, then only transfers out have to be signed by it. When + * the account is created, the payer account is charged enough hbars so that + * the new account will not expire for the next autoRenewPeriod seconds. When + * it reaches the expiration time, the new account will then be automatically + * charged to renew for another autoRenewPeriod seconds. If it does not have + * enough hbars to renew for that long, then the remaining hbars are used to + * extend its expiration as long as possible. If it is has a zero balance when + * it expires, then it is deleted. This transaction must be signed by the payer + * account. If receiverSigRequired is false, then the transaction does not have + * to be signed by the keys in the keys field. If it is true, then it must be + * signed by them, in addition to the keys of the payer account. + * + * An entity (account, file, or smart contract instance) must be created in a + * particular realm. If the realmID is left null, then a new realm will be + * created with the given admin key. If a new realm has a null adminKey, then + * anyone can create/modify/delete entities in that realm. But if an admin key + * is given, then any transaction to create/modify/delete an entity in that + * realm must be signed by that key, though anyone can still call functions on + * smart contract instances that exist in that realm. A realm ceases to exist + * when everything within it has expired and no longer exists. + * + * The current API ignores shardID, realmID, and newRealmAdminKey, and creates + * everything in shard 0 and realm 0, with a null key. Future versions of the + * API will support multiple realms and multiple shards. + */ +message CryptoCreateTransactionBody { + /** + * The key that must sign each transfer out of the account. If + * receiverSigRequired is true, then it must also sign any transfer into the + * account. + */ + Key key = 1; + + /** + * The initial number of tinybars to put into the account + */ + uint64 initialBalance = 2; + + /** + * [Deprecated] ID of the account to which this account is proxy staked. If + * proxyAccountID is null, or is an invalid account, or is an account that + * isn't a node, then this account is automatically proxy staked to a node + * chosen by the network, but without earning payments. If the proxyAccountID + * account refuses to accept proxy staking , or if it is not currently + * running a node, then it will behave as if proxyAccountID was null. + */ + AccountID proxyAccountID = 3 [ deprecated = true ]; + + /** + * [Deprecated]. The threshold amount (in tinybars) for which an account + * record is created for any send/withdraw transaction + */ + uint64 sendRecordThreshold = 6 [ deprecated = true ]; + + /** + * [Deprecated]. The threshold amount (in tinybars) for which an account + * record is created for any receive/deposit transaction + */ + uint64 receiveRecordThreshold = 7 [ deprecated = true ]; + + /** + * If true, this account's key must sign any transaction depositing into this + * account (in addition to all withdrawals) + */ + bool receiverSigRequired = 8; + + /** + * The account is charged to extend its expiration date every this many + * seconds. If it doesn't have enough balance, it extends as long as + * possible. If it is empty when it expires, then it is deleted. + */ + Duration autoRenewPeriod = 9; + + /** + * The shard in which this account is created + */ + ShardID shardID = 10; + + /** + * The realm in which this account is created (leave this null to create a + * new realm) + */ + RealmID realmID = 11; + + /** + * If realmID is null, then this the admin key for the new realm that will be + * created + */ + Key newRealmAdminKey = 12; + + /** + * The memo associated with the account (UTF-8 encoding max 100 bytes) + */ + string memo = 13 [ (nanopb).max_size = 100 ]; + + /** + * The maximum number of tokens that an Account can be implicitly associated + * with. Defaults to 0 and up to a maximum value of 1000. + */ + int32 max_automatic_token_associations = 14; + + /** + * ID of the account or node to which this account is staking. + */ + oneof staked_id { + /** + * ID of the account to which this account is staking. + */ + AccountID staked_account_id = 15; + + /** + * ID of the node this account is staked to. + */ + int64 staked_node_id = 16; + } + + /** + * If true, the account declines receiving a staking reward. The default + * value is false. + */ + bool decline_reward = 17; +} \ No newline at end of file diff --git a/proto/crypto_create_pb2.py b/proto/crypto_create_pb2.py new file mode 100644 index 00000000..6f2009d0 --- /dev/null +++ b/proto/crypto_create_pb2.py @@ -0,0 +1,36 @@ +# -*- coding: utf-8 -*- +# Generated by the protocol buffer compiler. DO NOT EDIT! +# source: proto/crypto_create.proto +"""Generated protocol buffer code.""" +from google.protobuf.internal import builder as _builder +from google.protobuf import descriptor as _descriptor +from google.protobuf import descriptor_pool as _descriptor_pool +from google.protobuf import symbol_database as _symbol_database +# @@protoc_insertion_point(imports) + +_sym_db = _symbol_database.Default() + + +import nanopb_pb2 as nanopb__pb2 +from proto import basic_types_pb2 as proto_dot_basic__types__pb2 +from proto import duration_pb2 as proto_dot_duration__pb2 + + +DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x19proto/crypto_create.proto\x12\x06Hedera\x1a\x0cnanopb.proto\x1a\x17proto/basic_types.proto\x1a\x14proto/duration.proto\"\xa4\x04\n\x1b\x43ryptoCreateTransactionBody\x12\x18\n\x03key\x18\x01 \x01(\x0b\x32\x0b.Hedera.Key\x12\x16\n\x0einitialBalance\x18\x02 \x01(\x04\x12-\n\x0eproxyAccountID\x18\x03 \x01(\x0b\x32\x11.Hedera.AccountIDB\x02\x18\x01\x12\x1f\n\x13sendRecordThreshold\x18\x06 \x01(\x04\x42\x02\x18\x01\x12\"\n\x16receiveRecordThreshold\x18\x07 \x01(\x04\x42\x02\x18\x01\x12\x1b\n\x13receiverSigRequired\x18\x08 \x01(\x08\x12)\n\x0f\x61utoRenewPeriod\x18\t \x01(\x0b\x32\x10.Hedera.Duration\x12 \n\x07shardID\x18\n \x01(\x0b\x32\x0f.Hedera.ShardID\x12 \n\x07realmID\x18\x0b \x01(\x0b\x32\x0f.Hedera.RealmID\x12%\n\x10newRealmAdminKey\x18\x0c \x01(\x0b\x32\x0b.Hedera.Key\x12\x13\n\x04memo\x18\r \x01(\tB\x05\x92?\x02\x08\x64\x12(\n max_automatic_token_associations\x18\x0e \x01(\x05\x12.\n\x11staked_account_id\x18\x0f \x01(\x0b\x32\x11.Hedera.AccountIDH\x00\x12\x18\n\x0estaked_node_id\x18\x10 \x01(\x03H\x00\x12\x16\n\x0e\x64\x65\x63line_reward\x18\x11 \x01(\x08\x42\x0b\n\tstaked_idb\x06proto3') + +_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, globals()) +_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'proto.crypto_create_pb2', globals()) +if _descriptor._USE_C_DESCRIPTORS == False: + + DESCRIPTOR._options = None + _CRYPTOCREATETRANSACTIONBODY.fields_by_name['proxyAccountID']._options = None + _CRYPTOCREATETRANSACTIONBODY.fields_by_name['proxyAccountID']._serialized_options = b'\030\001' + _CRYPTOCREATETRANSACTIONBODY.fields_by_name['sendRecordThreshold']._options = None + _CRYPTOCREATETRANSACTIONBODY.fields_by_name['sendRecordThreshold']._serialized_options = b'\030\001' + _CRYPTOCREATETRANSACTIONBODY.fields_by_name['receiveRecordThreshold']._options = None + _CRYPTOCREATETRANSACTIONBODY.fields_by_name['receiveRecordThreshold']._serialized_options = b'\030\001' + _CRYPTOCREATETRANSACTIONBODY.fields_by_name['memo']._options = None + _CRYPTOCREATETRANSACTIONBODY.fields_by_name['memo']._serialized_options = b'\222?\002\010d' + _CRYPTOCREATETRANSACTIONBODY._serialized_start=99 + _CRYPTOCREATETRANSACTIONBODY._serialized_end=647 +# @@protoc_insertion_point(module_scope) diff --git a/proto/crypto_create_pb2.pyi b/proto/crypto_create_pb2.pyi new file mode 100644 index 00000000..2d472669 --- /dev/null +++ b/proto/crypto_create_pb2.pyi @@ -0,0 +1,181 @@ +""" +@generated by mypy-protobuf. Do not edit manually! +isort:skip_file +""" +import builtins +import google.protobuf.descriptor +import google.protobuf.message +import proto.basic_types_pb2 +import proto.duration_pb2 +import sys + +if sys.version_info >= (3, 8): + import typing as typing_extensions +else: + import typing_extensions + +DESCRIPTOR: google.protobuf.descriptor.FileDescriptor + +@typing_extensions.final +class CryptoCreateTransactionBody(google.protobuf.message.Message): + """ + Create a new account. After the account is created, the AccountID for it is + in the receipt. It can also be retrieved with a GetByKey query. Threshold + values can be defined, and records are generated and stored for 25 hours for + any transfer that exceeds the thresholds. This account is charged for each + record generated, so the thresholds are useful for limiting record + generation to happen only for large transactions. + + The Key field is the key used to sign transactions for this account. If the + account has receiverSigRequired set to true, then all cryptocurrency + transfers must be signed by this account's key, both for transfers in and + out. If it is false, then only transfers out have to be signed by it. When + the account is created, the payer account is charged enough hbars so that + the new account will not expire for the next autoRenewPeriod seconds. When + it reaches the expiration time, the new account will then be automatically + charged to renew for another autoRenewPeriod seconds. If it does not have + enough hbars to renew for that long, then the remaining hbars are used to + extend its expiration as long as possible. If it is has a zero balance when + it expires, then it is deleted. This transaction must be signed by the payer + account. If receiverSigRequired is false, then the transaction does not have + to be signed by the keys in the keys field. If it is true, then it must be + signed by them, in addition to the keys of the payer account. + + An entity (account, file, or smart contract instance) must be created in a + particular realm. If the realmID is left null, then a new realm will be + created with the given admin key. If a new realm has a null adminKey, then + anyone can create/modify/delete entities in that realm. But if an admin key + is given, then any transaction to create/modify/delete an entity in that + realm must be signed by that key, though anyone can still call functions on + smart contract instances that exist in that realm. A realm ceases to exist + when everything within it has expired and no longer exists. + + The current API ignores shardID, realmID, and newRealmAdminKey, and creates + everything in shard 0 and realm 0, with a null key. Future versions of the + API will support multiple realms and multiple shards. + """ + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + KEY_FIELD_NUMBER: builtins.int + INITIALBALANCE_FIELD_NUMBER: builtins.int + PROXYACCOUNTID_FIELD_NUMBER: builtins.int + SENDRECORDTHRESHOLD_FIELD_NUMBER: builtins.int + RECEIVERECORDTHRESHOLD_FIELD_NUMBER: builtins.int + RECEIVERSIGREQUIRED_FIELD_NUMBER: builtins.int + AUTORENEWPERIOD_FIELD_NUMBER: builtins.int + SHARDID_FIELD_NUMBER: builtins.int + REALMID_FIELD_NUMBER: builtins.int + NEWREALMADMINKEY_FIELD_NUMBER: builtins.int + MEMO_FIELD_NUMBER: builtins.int + MAX_AUTOMATIC_TOKEN_ASSOCIATIONS_FIELD_NUMBER: builtins.int + STAKED_ACCOUNT_ID_FIELD_NUMBER: builtins.int + STAKED_NODE_ID_FIELD_NUMBER: builtins.int + DECLINE_REWARD_FIELD_NUMBER: builtins.int + @property + def key(self) -> proto.basic_types_pb2.Key: + """* + The key that must sign each transfer out of the account. If + receiverSigRequired is true, then it must also sign any transfer into the + account. + """ + initialBalance: builtins.int + """* + The initial number of tinybars to put into the account + """ + @property + def proxyAccountID(self) -> proto.basic_types_pb2.AccountID: + """* + [Deprecated] ID of the account to which this account is proxy staked. If + proxyAccountID is null, or is an invalid account, or is an account that + isn't a node, then this account is automatically proxy staked to a node + chosen by the network, but without earning payments. If the proxyAccountID + account refuses to accept proxy staking , or if it is not currently + running a node, then it will behave as if proxyAccountID was null. + """ + sendRecordThreshold: builtins.int + """* + [Deprecated]. The threshold amount (in tinybars) for which an account + record is created for any send/withdraw transaction + """ + receiveRecordThreshold: builtins.int + """* + [Deprecated]. The threshold amount (in tinybars) for which an account + record is created for any receive/deposit transaction + """ + receiverSigRequired: builtins.bool + """* + If true, this account's key must sign any transaction depositing into this + account (in addition to all withdrawals) + """ + @property + def autoRenewPeriod(self) -> proto.duration_pb2.Duration: + """* + The account is charged to extend its expiration date every this many + seconds. If it doesn't have enough balance, it extends as long as + possible. If it is empty when it expires, then it is deleted. + """ + @property + def shardID(self) -> proto.basic_types_pb2.ShardID: + """* + The shard in which this account is created + """ + @property + def realmID(self) -> proto.basic_types_pb2.RealmID: + """* + The realm in which this account is created (leave this null to create a + new realm) + """ + @property + def newRealmAdminKey(self) -> proto.basic_types_pb2.Key: + """* + If realmID is null, then this the admin key for the new realm that will be + created + """ + memo: builtins.str + """* + The memo associated with the account (UTF-8 encoding max 100 bytes) + """ + max_automatic_token_associations: builtins.int + """* + The maximum number of tokens that an Account can be implicitly associated + with. Defaults to 0 and up to a maximum value of 1000. + """ + @property + def staked_account_id(self) -> proto.basic_types_pb2.AccountID: + """* + ID of the account to which this account is staking. + """ + staked_node_id: builtins.int + """* + ID of the node this account is staked to. + """ + decline_reward: builtins.bool + """* + If true, the account declines receiving a staking reward. The default + value is false. + """ + def __init__( + self, + *, + key: proto.basic_types_pb2.Key | None = ..., + initialBalance: builtins.int = ..., + proxyAccountID: proto.basic_types_pb2.AccountID | None = ..., + sendRecordThreshold: builtins.int = ..., + receiveRecordThreshold: builtins.int = ..., + receiverSigRequired: builtins.bool = ..., + autoRenewPeriod: proto.duration_pb2.Duration | None = ..., + shardID: proto.basic_types_pb2.ShardID | None = ..., + realmID: proto.basic_types_pb2.RealmID | None = ..., + newRealmAdminKey: proto.basic_types_pb2.Key | None = ..., + memo: builtins.str = ..., + max_automatic_token_associations: builtins.int = ..., + staked_account_id: proto.basic_types_pb2.AccountID | None = ..., + staked_node_id: builtins.int = ..., + decline_reward: builtins.bool = ..., + ) -> None: ... + def HasField(self, field_name: typing_extensions.Literal["autoRenewPeriod", b"autoRenewPeriod", "key", b"key", "newRealmAdminKey", b"newRealmAdminKey", "proxyAccountID", b"proxyAccountID", "realmID", b"realmID", "shardID", b"shardID", "staked_account_id", b"staked_account_id", "staked_id", b"staked_id", "staked_node_id", b"staked_node_id"]) -> builtins.bool: ... + def ClearField(self, field_name: typing_extensions.Literal["autoRenewPeriod", b"autoRenewPeriod", "decline_reward", b"decline_reward", "initialBalance", b"initialBalance", "key", b"key", "max_automatic_token_associations", b"max_automatic_token_associations", "memo", b"memo", "newRealmAdminKey", b"newRealmAdminKey", "proxyAccountID", b"proxyAccountID", "realmID", b"realmID", "receiveRecordThreshold", b"receiveRecordThreshold", "receiverSigRequired", b"receiverSigRequired", "sendRecordThreshold", b"sendRecordThreshold", "shardID", b"shardID", "staked_account_id", b"staked_account_id", "staked_id", b"staked_id", "staked_node_id", b"staked_node_id"]) -> None: ... + def WhichOneof(self, oneof_group: typing_extensions.Literal["staked_id", b"staked_id"]) -> typing_extensions.Literal["staked_account_id", "staked_node_id"] | None: ... + +global___CryptoCreateTransactionBody = CryptoCreateTransactionBody diff --git a/proto/crypto_transfer.proto b/proto/crypto_transfer.proto new file mode 100644 index 00000000..9b59bf3d --- /dev/null +++ b/proto/crypto_transfer.proto @@ -0,0 +1,55 @@ +syntax = "proto3"; + +package Hedera; + +/*- + * ‌ + * Hedera Network Services Protobuf + * ​ + * Copyright (C) 2018 - 2021 Hedera Hashgraph, LLC + * ​ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ‍ + */ +import "nanopb.proto"; +import "proto/basic_types.proto"; + +/** + * Transfers cryptocurrency among two or more accounts by making the desired + * adjustments to their balances. Each transfer list can specify up to 10 + * adjustments. Each negative amount is withdrawn from the corresponding + * account (a sender), and each positive one is added to the corresponding + * account (a receiver). The amounts list must sum to zero. Each amount is a + * number of tinybars (there are 100,000,000 tinybars in one hbar). If any + * sender account fails to have sufficient hbars, then the entire transaction + * fails, and none of those transfers occur, though the transaction fee is + * still charged. This transaction must be signed by the keys for all the + * sending accounts, and for any receiving accounts that have + * receiverSigRequired == true. The signatures are in the same order as the + * accounts, skipping those accounts that don't need a signature. + */ +message CryptoTransferTransactionBody { + /** + * The desired hbar balance adjustments + */ + TransferList transfers = 1; + + /** + * The desired token unit balance adjustments; if any custom fees are + * assessed, the ledger will try to deduct them from the payer of this + * CryptoTransfer, resolving the transaction to + * INSUFFICIENT_PAYER_BALANCE_FOR_CUSTOM_FEE if this is not possible + * Limited to 1 here + */ + repeated TokenTransferList tokenTransfers = 2 [ (nanopb).max_count = 1 ]; +} \ No newline at end of file diff --git a/proto/crypto_transfer_pb2.py b/proto/crypto_transfer_pb2.py new file mode 100644 index 00000000..9c40c036 --- /dev/null +++ b/proto/crypto_transfer_pb2.py @@ -0,0 +1,29 @@ +# -*- coding: utf-8 -*- +# Generated by the protocol buffer compiler. DO NOT EDIT! +# source: proto/crypto_transfer.proto +"""Generated protocol buffer code.""" +from google.protobuf.internal import builder as _builder +from google.protobuf import descriptor as _descriptor +from google.protobuf import descriptor_pool as _descriptor_pool +from google.protobuf import symbol_database as _symbol_database +# @@protoc_insertion_point(imports) + +_sym_db = _symbol_database.Default() + + +import nanopb_pb2 as nanopb__pb2 +from proto import basic_types_pb2 as proto_dot_basic__types__pb2 + + +DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x1bproto/crypto_transfer.proto\x12\x06Hedera\x1a\x0cnanopb.proto\x1a\x17proto/basic_types.proto\"\x82\x01\n\x1d\x43ryptoTransferTransactionBody\x12\'\n\ttransfers\x18\x01 \x01(\x0b\x32\x14.Hedera.TransferList\x12\x38\n\x0etokenTransfers\x18\x02 \x03(\x0b\x32\x19.Hedera.TokenTransferListB\x05\x92?\x02\x10\x01\x62\x06proto3') + +_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, globals()) +_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'proto.crypto_transfer_pb2', globals()) +if _descriptor._USE_C_DESCRIPTORS == False: + + DESCRIPTOR._options = None + _CRYPTOTRANSFERTRANSACTIONBODY.fields_by_name['tokenTransfers']._options = None + _CRYPTOTRANSFERTRANSACTIONBODY.fields_by_name['tokenTransfers']._serialized_options = b'\222?\002\020\001' + _CRYPTOTRANSFERTRANSACTIONBODY._serialized_start=79 + _CRYPTOTRANSFERTRANSACTIONBODY._serialized_end=209 +# @@protoc_insertion_point(module_scope) diff --git a/proto/crypto_transfer_pb2.pyi b/proto/crypto_transfer_pb2.pyi new file mode 100644 index 00000000..831e8333 --- /dev/null +++ b/proto/crypto_transfer_pb2.pyi @@ -0,0 +1,64 @@ +""" +@generated by mypy-protobuf. Do not edit manually! +isort:skip_file +""" +import builtins +import collections.abc +import google.protobuf.descriptor +import google.protobuf.internal.containers +import google.protobuf.message +import proto.basic_types_pb2 +import sys + +if sys.version_info >= (3, 8): + import typing as typing_extensions +else: + import typing_extensions + +DESCRIPTOR: google.protobuf.descriptor.FileDescriptor + +@typing_extensions.final +class CryptoTransferTransactionBody(google.protobuf.message.Message): + """* + Transfers cryptocurrency among two or more accounts by making the desired + adjustments to their balances. Each transfer list can specify up to 10 + adjustments. Each negative amount is withdrawn from the corresponding + account (a sender), and each positive one is added to the corresponding + account (a receiver). The amounts list must sum to zero. Each amount is a + number of tinybars (there are 100,000,000 tinybars in one hbar). If any + sender account fails to have sufficient hbars, then the entire transaction + fails, and none of those transfers occur, though the transaction fee is + still charged. This transaction must be signed by the keys for all the + sending accounts, and for any receiving accounts that have + receiverSigRequired == true. The signatures are in the same order as the + accounts, skipping those accounts that don't need a signature. + """ + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + TRANSFERS_FIELD_NUMBER: builtins.int + TOKENTRANSFERS_FIELD_NUMBER: builtins.int + @property + def transfers(self) -> proto.basic_types_pb2.TransferList: + """* + The desired hbar balance adjustments + """ + @property + def tokenTransfers(self) -> google.protobuf.internal.containers.RepeatedCompositeFieldContainer[proto.basic_types_pb2.TokenTransferList]: + """* + The desired token unit balance adjustments; if any custom fees are + assessed, the ledger will try to deduct them from the payer of this + CryptoTransfer, resolving the transaction to + INSUFFICIENT_PAYER_BALANCE_FOR_CUSTOM_FEE if this is not possible + Limited to 1 here + """ + def __init__( + self, + *, + transfers: proto.basic_types_pb2.TransferList | None = ..., + tokenTransfers: collections.abc.Iterable[proto.basic_types_pb2.TokenTransferList] | None = ..., + ) -> None: ... + def HasField(self, field_name: typing_extensions.Literal["transfers", b"transfers"]) -> builtins.bool: ... + def ClearField(self, field_name: typing_extensions.Literal["tokenTransfers", b"tokenTransfers", "transfers", b"transfers"]) -> None: ... + +global___CryptoTransferTransactionBody = CryptoTransferTransactionBody diff --git a/proto/crypto_update.proto b/proto/crypto_update.proto new file mode 100644 index 00000000..a60c27bc --- /dev/null +++ b/proto/crypto_update.proto @@ -0,0 +1,157 @@ +syntax = "proto3"; + +package Hedera; + +/*- + * ‌ + * Hedera Network Services Protobuf + * ​ + * Copyright (C) 2018 - 2021 Hedera Hashgraph, LLC + * ​ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ‍ + */ +import "nanopb.proto"; +import "proto/basic_types.proto"; +import "proto/duration.proto"; +import "proto/timestamp.proto"; +import "proto/wrappers.proto"; + +/** + * Change properties for the given account. Any null field is ignored (left + * unchanged). This transaction must be signed by the existing key for this + * account. If the transaction is changing the key field, then the transaction + * must be signed by both the old key (from before the change) and the new key. + * The old key must sign for security. The new key must sign as a safeguard to + * avoid accidentally changing to an invalid key, and then having no way to + * recover. + */ +message CryptoUpdateTransactionBody { + /** + * The account ID which is being updated in this transaction + */ + AccountID accountIDToUpdate = 2; + + /** + * The new key + */ + Key key = 3; + + /** + * [Deprecated] ID of the account to which this account is proxy staked. If + * proxyAccountID is null, or is an invalid account, or is an account that + * isn't a node, then this account is automatically proxy staked to a node + * chosen by the network, but without earning payments. If the proxyAccountID + * account refuses to accept proxy staking , or if it is not currently running + * a node, then it will behave as if proxyAccountID was null. + */ + AccountID proxyAccountID = 4 [ deprecated = true ]; + + /** + * [Deprecated]. Payments earned from proxy staking are shared between the + * node and this account, with proxyFraction / 10000 going to this account + */ + int32 proxyFraction = 5 [ deprecated = true ]; + + oneof sendRecordThresholdField { + /** + * [Deprecated]. The new threshold amount (in tinybars) for which an account + * record is created for any send/withdraw transaction + */ + uint64 sendRecordThreshold = 6 [ deprecated = true ]; + + /** + * [Deprecated]. The new threshold amount (in tinybars) for which an account + * record is created for any send/withdraw transaction + */ + UInt64Value sendRecordThresholdWrapper = 11 [ deprecated = true ]; + } + + oneof receiveRecordThresholdField { + /** + * [Deprecated]. The new threshold amount (in tinybars) for which an account + * record is created for any receive/deposit transaction. + */ + uint64 receiveRecordThreshold = 7 [ deprecated = true ]; + + /** + * [Deprecated]. The new threshold amount (in tinybars) for which an account + * record is created for any receive/deposit transaction. + */ + UInt64Value receiveRecordThresholdWrapper = 12 [ deprecated = true ]; + } + + /** + * The duration in which it will automatically extend the expiration period. + * If it doesn't have enough balance, it extends as long as possible. If it is + * empty when it expires, then it is deleted. + */ + Duration autoRenewPeriod = 8; + + /** + * The new expiration time to extend to (ignored if equal to or before the + * current one) + */ + Timestamp expirationTime = 9; + + oneof receiverSigRequiredField { + /** + * [Deprecated] Do NOT use this field to set a false value because the + * server cannot distinguish from the default value. Use + * receiverSigRequiredWrapper field for this purpose. + */ + bool receiverSigRequired = 10 [ deprecated = true ]; + + /** + * If true, this account's key must sign any transaction depositing into + * this account (in addition to all withdrawals) + */ + BoolValue receiverSigRequiredWrapper = 13; + } + + /** + * If set, the new memo to be associated with the account (UTF-8 encoding max + * 100 bytes) + */ + StringValue memo = 14; + + /** + * The maximum number of tokens that an Account can be implicitly associated + * with. Up to a 1000 including implicit and explicit associations. + */ + Int32Value max_automatic_token_associations = 15; + + /** + * ID of the account or node to which this account is staking. + */ + oneof staked_id { + /** + * ID of the new account to which this account is staking. If set to the + * sentinel 0.0.0 AccountID, this field removes this account's + * staked account ID. + */ + AccountID staked_account_id = 16; + + /** + * ID of the new node this account is staked to. If set to the sentinel + * -1, this field removes this account's staked node ID. + */ + int64 staked_node_id = 17; + } + + /** + * If true, the account declines receiving a staking reward. The default value + * is false. + */ + BoolValue decline_reward = 18; +} \ No newline at end of file diff --git a/proto/crypto_update_pb2.py b/proto/crypto_update_pb2.py new file mode 100644 index 00000000..1936fb2f --- /dev/null +++ b/proto/crypto_update_pb2.py @@ -0,0 +1,44 @@ +# -*- coding: utf-8 -*- +# Generated by the protocol buffer compiler. DO NOT EDIT! +# source: proto/crypto_update.proto +"""Generated protocol buffer code.""" +from google.protobuf.internal import builder as _builder +from google.protobuf import descriptor as _descriptor +from google.protobuf import descriptor_pool as _descriptor_pool +from google.protobuf import symbol_database as _symbol_database +# @@protoc_insertion_point(imports) + +_sym_db = _symbol_database.Default() + + +import nanopb_pb2 as nanopb__pb2 +from proto import basic_types_pb2 as proto_dot_basic__types__pb2 +from proto import duration_pb2 as proto_dot_duration__pb2 +from proto import timestamp_pb2 as proto_dot_timestamp__pb2 +from proto import wrappers_pb2 as proto_dot_wrappers__pb2 + + +DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x19proto/crypto_update.proto\x12\x06Hedera\x1a\x0cnanopb.proto\x1a\x17proto/basic_types.proto\x1a\x14proto/duration.proto\x1a\x15proto/timestamp.proto\x1a\x14proto/wrappers.proto\"\xe5\x06\n\x1b\x43ryptoUpdateTransactionBody\x12,\n\x11\x61\x63\x63ountIDToUpdate\x18\x02 \x01(\x0b\x32\x11.Hedera.AccountID\x12\x18\n\x03key\x18\x03 \x01(\x0b\x32\x0b.Hedera.Key\x12-\n\x0eproxyAccountID\x18\x04 \x01(\x0b\x32\x11.Hedera.AccountIDB\x02\x18\x01\x12\x19\n\rproxyFraction\x18\x05 \x01(\x05\x42\x02\x18\x01\x12!\n\x13sendRecordThreshold\x18\x06 \x01(\x04\x42\x02\x18\x01H\x00\x12=\n\x1asendRecordThresholdWrapper\x18\x0b \x01(\x0b\x32\x13.Hedera.UInt64ValueB\x02\x18\x01H\x00\x12$\n\x16receiveRecordThreshold\x18\x07 \x01(\x04\x42\x02\x18\x01H\x01\x12@\n\x1dreceiveRecordThresholdWrapper\x18\x0c \x01(\x0b\x32\x13.Hedera.UInt64ValueB\x02\x18\x01H\x01\x12)\n\x0f\x61utoRenewPeriod\x18\x08 \x01(\x0b\x32\x10.Hedera.Duration\x12)\n\x0e\x65xpirationTime\x18\t \x01(\x0b\x32\x11.Hedera.Timestamp\x12!\n\x13receiverSigRequired\x18\n \x01(\x08\x42\x02\x18\x01H\x02\x12\x37\n\x1areceiverSigRequiredWrapper\x18\r \x01(\x0b\x32\x11.Hedera.BoolValueH\x02\x12!\n\x04memo\x18\x0e \x01(\x0b\x32\x13.Hedera.StringValue\x12<\n max_automatic_token_associations\x18\x0f \x01(\x0b\x32\x12.Hedera.Int32Value\x12.\n\x11staked_account_id\x18\x10 \x01(\x0b\x32\x11.Hedera.AccountIDH\x03\x12\x18\n\x0estaked_node_id\x18\x11 \x01(\x03H\x03\x12)\n\x0e\x64\x65\x63line_reward\x18\x12 \x01(\x0b\x32\x11.Hedera.BoolValueB\x1a\n\x18sendRecordThresholdFieldB\x1d\n\x1breceiveRecordThresholdFieldB\x1a\n\x18receiverSigRequiredFieldB\x0b\n\tstaked_idb\x06proto3') + +_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, globals()) +_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'proto.crypto_update_pb2', globals()) +if _descriptor._USE_C_DESCRIPTORS == False: + + DESCRIPTOR._options = None + _CRYPTOUPDATETRANSACTIONBODY.fields_by_name['proxyAccountID']._options = None + _CRYPTOUPDATETRANSACTIONBODY.fields_by_name['proxyAccountID']._serialized_options = b'\030\001' + _CRYPTOUPDATETRANSACTIONBODY.fields_by_name['proxyFraction']._options = None + _CRYPTOUPDATETRANSACTIONBODY.fields_by_name['proxyFraction']._serialized_options = b'\030\001' + _CRYPTOUPDATETRANSACTIONBODY.fields_by_name['sendRecordThreshold']._options = None + _CRYPTOUPDATETRANSACTIONBODY.fields_by_name['sendRecordThreshold']._serialized_options = b'\030\001' + _CRYPTOUPDATETRANSACTIONBODY.fields_by_name['sendRecordThresholdWrapper']._options = None + _CRYPTOUPDATETRANSACTIONBODY.fields_by_name['sendRecordThresholdWrapper']._serialized_options = b'\030\001' + _CRYPTOUPDATETRANSACTIONBODY.fields_by_name['receiveRecordThreshold']._options = None + _CRYPTOUPDATETRANSACTIONBODY.fields_by_name['receiveRecordThreshold']._serialized_options = b'\030\001' + _CRYPTOUPDATETRANSACTIONBODY.fields_by_name['receiveRecordThresholdWrapper']._options = None + _CRYPTOUPDATETRANSACTIONBODY.fields_by_name['receiveRecordThresholdWrapper']._serialized_options = b'\030\001' + _CRYPTOUPDATETRANSACTIONBODY.fields_by_name['receiverSigRequired']._options = None + _CRYPTOUPDATETRANSACTIONBODY.fields_by_name['receiverSigRequired']._serialized_options = b'\030\001' + _CRYPTOUPDATETRANSACTIONBODY._serialized_start=144 + _CRYPTOUPDATETRANSACTIONBODY._serialized_end=1013 +# @@protoc_insertion_point(module_scope) diff --git a/proto/crypto_update_pb2.pyi b/proto/crypto_update_pb2.pyi new file mode 100644 index 00000000..e1ca7bc6 --- /dev/null +++ b/proto/crypto_update_pb2.pyi @@ -0,0 +1,187 @@ +""" +@generated by mypy-protobuf. Do not edit manually! +isort:skip_file +""" +import builtins +import google.protobuf.descriptor +import google.protobuf.message +import proto.basic_types_pb2 +import proto.duration_pb2 +import proto.timestamp_pb2 +import proto.wrappers_pb2 +import sys +import typing + +if sys.version_info >= (3, 8): + import typing as typing_extensions +else: + import typing_extensions + +DESCRIPTOR: google.protobuf.descriptor.FileDescriptor + +@typing_extensions.final +class CryptoUpdateTransactionBody(google.protobuf.message.Message): + """* + Change properties for the given account. Any null field is ignored (left + unchanged). This transaction must be signed by the existing key for this + account. If the transaction is changing the key field, then the transaction + must be signed by both the old key (from before the change) and the new key. + The old key must sign for security. The new key must sign as a safeguard to + avoid accidentally changing to an invalid key, and then having no way to + recover. + """ + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + ACCOUNTIDTOUPDATE_FIELD_NUMBER: builtins.int + KEY_FIELD_NUMBER: builtins.int + PROXYACCOUNTID_FIELD_NUMBER: builtins.int + PROXYFRACTION_FIELD_NUMBER: builtins.int + SENDRECORDTHRESHOLD_FIELD_NUMBER: builtins.int + SENDRECORDTHRESHOLDWRAPPER_FIELD_NUMBER: builtins.int + RECEIVERECORDTHRESHOLD_FIELD_NUMBER: builtins.int + RECEIVERECORDTHRESHOLDWRAPPER_FIELD_NUMBER: builtins.int + AUTORENEWPERIOD_FIELD_NUMBER: builtins.int + EXPIRATIONTIME_FIELD_NUMBER: builtins.int + RECEIVERSIGREQUIRED_FIELD_NUMBER: builtins.int + RECEIVERSIGREQUIREDWRAPPER_FIELD_NUMBER: builtins.int + MEMO_FIELD_NUMBER: builtins.int + MAX_AUTOMATIC_TOKEN_ASSOCIATIONS_FIELD_NUMBER: builtins.int + STAKED_ACCOUNT_ID_FIELD_NUMBER: builtins.int + STAKED_NODE_ID_FIELD_NUMBER: builtins.int + DECLINE_REWARD_FIELD_NUMBER: builtins.int + @property + def accountIDToUpdate(self) -> proto.basic_types_pb2.AccountID: + """* + The account ID which is being updated in this transaction + """ + @property + def key(self) -> proto.basic_types_pb2.Key: + """* + The new key + """ + @property + def proxyAccountID(self) -> proto.basic_types_pb2.AccountID: + """* + [Deprecated] ID of the account to which this account is proxy staked. If + proxyAccountID is null, or is an invalid account, or is an account that + isn't a node, then this account is automatically proxy staked to a node + chosen by the network, but without earning payments. If the proxyAccountID + account refuses to accept proxy staking , or if it is not currently running + a node, then it will behave as if proxyAccountID was null. + """ + proxyFraction: builtins.int + """* + [Deprecated]. Payments earned from proxy staking are shared between the + node and this account, with proxyFraction / 10000 going to this account + """ + sendRecordThreshold: builtins.int + """* + [Deprecated]. The new threshold amount (in tinybars) for which an account + record is created for any send/withdraw transaction + """ + @property + def sendRecordThresholdWrapper(self) -> proto.wrappers_pb2.UInt64Value: + """* + [Deprecated]. The new threshold amount (in tinybars) for which an account + record is created for any send/withdraw transaction + """ + receiveRecordThreshold: builtins.int + """* + [Deprecated]. The new threshold amount (in tinybars) for which an account + record is created for any receive/deposit transaction. + """ + @property + def receiveRecordThresholdWrapper(self) -> proto.wrappers_pb2.UInt64Value: + """* + [Deprecated]. The new threshold amount (in tinybars) for which an account + record is created for any receive/deposit transaction. + """ + @property + def autoRenewPeriod(self) -> proto.duration_pb2.Duration: + """* + The duration in which it will automatically extend the expiration period. + If it doesn't have enough balance, it extends as long as possible. If it is + empty when it expires, then it is deleted. + """ + @property + def expirationTime(self) -> proto.timestamp_pb2.Timestamp: + """* + The new expiration time to extend to (ignored if equal to or before the + current one) + """ + receiverSigRequired: builtins.bool + """* + [Deprecated] Do NOT use this field to set a false value because the + server cannot distinguish from the default value. Use + receiverSigRequiredWrapper field for this purpose. + """ + @property + def receiverSigRequiredWrapper(self) -> proto.wrappers_pb2.BoolValue: + """* + If true, this account's key must sign any transaction depositing into + this account (in addition to all withdrawals) + """ + @property + def memo(self) -> proto.wrappers_pb2.StringValue: + """* + If set, the new memo to be associated with the account (UTF-8 encoding max + 100 bytes) + """ + @property + def max_automatic_token_associations(self) -> proto.wrappers_pb2.Int32Value: + """* + The maximum number of tokens that an Account can be implicitly associated + with. Up to a 1000 including implicit and explicit associations. + """ + @property + def staked_account_id(self) -> proto.basic_types_pb2.AccountID: + """* + ID of the new account to which this account is staking. If set to the + sentinel 0.0.0 AccountID, this field removes this account's + staked account ID. + """ + staked_node_id: builtins.int + """* + ID of the new node this account is staked to. If set to the sentinel + -1, this field removes this account's staked node ID. + """ + @property + def decline_reward(self) -> proto.wrappers_pb2.BoolValue: + """* + If true, the account declines receiving a staking reward. The default value + is false. + """ + def __init__( + self, + *, + accountIDToUpdate: proto.basic_types_pb2.AccountID | None = ..., + key: proto.basic_types_pb2.Key | None = ..., + proxyAccountID: proto.basic_types_pb2.AccountID | None = ..., + proxyFraction: builtins.int = ..., + sendRecordThreshold: builtins.int = ..., + sendRecordThresholdWrapper: proto.wrappers_pb2.UInt64Value | None = ..., + receiveRecordThreshold: builtins.int = ..., + receiveRecordThresholdWrapper: proto.wrappers_pb2.UInt64Value | None = ..., + autoRenewPeriod: proto.duration_pb2.Duration | None = ..., + expirationTime: proto.timestamp_pb2.Timestamp | None = ..., + receiverSigRequired: builtins.bool = ..., + receiverSigRequiredWrapper: proto.wrappers_pb2.BoolValue | None = ..., + memo: proto.wrappers_pb2.StringValue | None = ..., + max_automatic_token_associations: proto.wrappers_pb2.Int32Value | None = ..., + staked_account_id: proto.basic_types_pb2.AccountID | None = ..., + staked_node_id: builtins.int = ..., + decline_reward: proto.wrappers_pb2.BoolValue | None = ..., + ) -> None: ... + def HasField(self, field_name: typing_extensions.Literal["accountIDToUpdate", b"accountIDToUpdate", "autoRenewPeriod", b"autoRenewPeriod", "decline_reward", b"decline_reward", "expirationTime", b"expirationTime", "key", b"key", "max_automatic_token_associations", b"max_automatic_token_associations", "memo", b"memo", "proxyAccountID", b"proxyAccountID", "receiveRecordThreshold", b"receiveRecordThreshold", "receiveRecordThresholdField", b"receiveRecordThresholdField", "receiveRecordThresholdWrapper", b"receiveRecordThresholdWrapper", "receiverSigRequired", b"receiverSigRequired", "receiverSigRequiredField", b"receiverSigRequiredField", "receiverSigRequiredWrapper", b"receiverSigRequiredWrapper", "sendRecordThreshold", b"sendRecordThreshold", "sendRecordThresholdField", b"sendRecordThresholdField", "sendRecordThresholdWrapper", b"sendRecordThresholdWrapper", "staked_account_id", b"staked_account_id", "staked_id", b"staked_id", "staked_node_id", b"staked_node_id"]) -> builtins.bool: ... + def ClearField(self, field_name: typing_extensions.Literal["accountIDToUpdate", b"accountIDToUpdate", "autoRenewPeriod", b"autoRenewPeriod", "decline_reward", b"decline_reward", "expirationTime", b"expirationTime", "key", b"key", "max_automatic_token_associations", b"max_automatic_token_associations", "memo", b"memo", "proxyAccountID", b"proxyAccountID", "proxyFraction", b"proxyFraction", "receiveRecordThreshold", b"receiveRecordThreshold", "receiveRecordThresholdField", b"receiveRecordThresholdField", "receiveRecordThresholdWrapper", b"receiveRecordThresholdWrapper", "receiverSigRequired", b"receiverSigRequired", "receiverSigRequiredField", b"receiverSigRequiredField", "receiverSigRequiredWrapper", b"receiverSigRequiredWrapper", "sendRecordThreshold", b"sendRecordThreshold", "sendRecordThresholdField", b"sendRecordThresholdField", "sendRecordThresholdWrapper", b"sendRecordThresholdWrapper", "staked_account_id", b"staked_account_id", "staked_id", b"staked_id", "staked_node_id", b"staked_node_id"]) -> None: ... + @typing.overload + def WhichOneof(self, oneof_group: typing_extensions.Literal["receiveRecordThresholdField", b"receiveRecordThresholdField"]) -> typing_extensions.Literal["receiveRecordThreshold", "receiveRecordThresholdWrapper"] | None: ... + @typing.overload + def WhichOneof(self, oneof_group: typing_extensions.Literal["receiverSigRequiredField", b"receiverSigRequiredField"]) -> typing_extensions.Literal["receiverSigRequired", "receiverSigRequiredWrapper"] | None: ... + @typing.overload + def WhichOneof(self, oneof_group: typing_extensions.Literal["sendRecordThresholdField", b"sendRecordThresholdField"]) -> typing_extensions.Literal["sendRecordThreshold", "sendRecordThresholdWrapper"] | None: ... + @typing.overload + def WhichOneof(self, oneof_group: typing_extensions.Literal["staked_id", b"staked_id"]) -> typing_extensions.Literal["staked_account_id", "staked_node_id"] | None: ... + +global___CryptoUpdateTransactionBody = CryptoUpdateTransactionBody diff --git a/proto/duration.proto b/proto/duration.proto new file mode 100644 index 00000000..9d7514c7 --- /dev/null +++ b/proto/duration.proto @@ -0,0 +1,34 @@ + +syntax = "proto3"; + +package Hedera; +/*- + * ‌ + * Hedera Network Services Protobuf + * ​ + * Copyright (C) 2018 - 2021 Hedera Hashgraph, LLC + * ​ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ‍ + */ +import "nanopb.proto"; + +/** + * A length of time in seconds. + */ +message Duration { + /** + * The number of seconds + */ + int64 seconds = 1; +} \ No newline at end of file diff --git a/proto/duration_pb2.py b/proto/duration_pb2.py new file mode 100644 index 00000000..7dae9331 --- /dev/null +++ b/proto/duration_pb2.py @@ -0,0 +1,26 @@ +# -*- coding: utf-8 -*- +# Generated by the protocol buffer compiler. DO NOT EDIT! +# source: proto/duration.proto +"""Generated protocol buffer code.""" +from google.protobuf.internal import builder as _builder +from google.protobuf import descriptor as _descriptor +from google.protobuf import descriptor_pool as _descriptor_pool +from google.protobuf import symbol_database as _symbol_database +# @@protoc_insertion_point(imports) + +_sym_db = _symbol_database.Default() + + +import nanopb_pb2 as nanopb__pb2 + + +DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x14proto/duration.proto\x12\x06Hedera\x1a\x0cnanopb.proto\"\x1b\n\x08\x44uration\x12\x0f\n\x07seconds\x18\x01 \x01(\x03\x62\x06proto3') + +_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, globals()) +_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'proto.duration_pb2', globals()) +if _descriptor._USE_C_DESCRIPTORS == False: + + DESCRIPTOR._options = None + _DURATION._serialized_start=46 + _DURATION._serialized_end=73 +# @@protoc_insertion_point(module_scope) diff --git a/proto/duration_pb2.pyi b/proto/duration_pb2.pyi new file mode 100644 index 00000000..656be12d --- /dev/null +++ b/proto/duration_pb2.pyi @@ -0,0 +1,37 @@ +""" +@generated by mypy-protobuf. Do not edit manually! +isort:skip_file +""" +import builtins +import google.protobuf.descriptor +import google.protobuf.message +import sys + +if sys.version_info >= (3, 8): + import typing as typing_extensions +else: + import typing_extensions + +DESCRIPTOR: google.protobuf.descriptor.FileDescriptor + +@typing_extensions.final +class Duration(google.protobuf.message.Message): + """* + A length of time in seconds. + """ + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + SECONDS_FIELD_NUMBER: builtins.int + seconds: builtins.int + """* + The number of seconds + """ + def __init__( + self, + *, + seconds: builtins.int = ..., + ) -> None: ... + def ClearField(self, field_name: typing_extensions.Literal["seconds", b"seconds"]) -> None: ... + +global___Duration = Duration diff --git a/proto/timestamp.proto b/proto/timestamp.proto new file mode 100644 index 00000000..4c898e45 --- /dev/null +++ b/proto/timestamp.proto @@ -0,0 +1,52 @@ +syntax = "proto3"; + +package Hedera; + +/*- + * ‌ + * Hedera Network Services Protobuf + * ​ + * Copyright (C) 2018 - 2022 Hedera Hashgraph, LLC + * ​ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ‍ + */ +import "nanopb.proto"; + +/** + * An exact date and time. This is the same data structure as the protobuf + * Timestamp.proto (see the comments in + * https://github.com/google/protobuf + * /blob/master/src/google/protobuf/timestamp.proto) + */ +message Timestamp { + /** + * Number of complete seconds since the start of the epoch + */ + int64 seconds = 1; + + /** + * Number of nanoseconds since the start of the last second + */ + int32 nanos = 2; +} + +/** + * An exact date and time, with a resolution of one second (no nanoseconds). + */ +message TimestampSeconds { + /** + * Number of complete seconds since the start of the epoch + */ + int64 seconds = 1; +} diff --git a/proto/timestamp_pb2.py b/proto/timestamp_pb2.py new file mode 100644 index 00000000..ee8d3d1e --- /dev/null +++ b/proto/timestamp_pb2.py @@ -0,0 +1,28 @@ +# -*- coding: utf-8 -*- +# Generated by the protocol buffer compiler. DO NOT EDIT! +# source: proto/timestamp.proto +"""Generated protocol buffer code.""" +from google.protobuf.internal import builder as _builder +from google.protobuf import descriptor as _descriptor +from google.protobuf import descriptor_pool as _descriptor_pool +from google.protobuf import symbol_database as _symbol_database +# @@protoc_insertion_point(imports) + +_sym_db = _symbol_database.Default() + + +import nanopb_pb2 as nanopb__pb2 + + +DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x15proto/timestamp.proto\x12\x06Hedera\x1a\x0cnanopb.proto\"+\n\tTimestamp\x12\x0f\n\x07seconds\x18\x01 \x01(\x03\x12\r\n\x05nanos\x18\x02 \x01(\x05\"#\n\x10TimestampSeconds\x12\x0f\n\x07seconds\x18\x01 \x01(\x03\x62\x06proto3') + +_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, globals()) +_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'proto.timestamp_pb2', globals()) +if _descriptor._USE_C_DESCRIPTORS == False: + + DESCRIPTOR._options = None + _TIMESTAMP._serialized_start=47 + _TIMESTAMP._serialized_end=90 + _TIMESTAMPSECONDS._serialized_start=92 + _TIMESTAMPSECONDS._serialized_end=127 +# @@protoc_insertion_point(module_scope) diff --git a/proto/timestamp_pb2.pyi b/proto/timestamp_pb2.pyi new file mode 100644 index 00000000..883e7eb1 --- /dev/null +++ b/proto/timestamp_pb2.pyi @@ -0,0 +1,68 @@ +""" +@generated by mypy-protobuf. Do not edit manually! +isort:skip_file +""" +import builtins +import google.protobuf.descriptor +import google.protobuf.message +import sys + +if sys.version_info >= (3, 8): + import typing as typing_extensions +else: + import typing_extensions + +DESCRIPTOR: google.protobuf.descriptor.FileDescriptor + +@typing_extensions.final +class Timestamp(google.protobuf.message.Message): + """* + An exact date and time. This is the same data structure as the protobuf + Timestamp.proto (see the comments in + https://github.com/google/protobuf + /blob/master/src/google/protobuf/timestamp.proto) + """ + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + SECONDS_FIELD_NUMBER: builtins.int + NANOS_FIELD_NUMBER: builtins.int + seconds: builtins.int + """* + Number of complete seconds since the start of the epoch + """ + nanos: builtins.int + """* + Number of nanoseconds since the start of the last second + """ + def __init__( + self, + *, + seconds: builtins.int = ..., + nanos: builtins.int = ..., + ) -> None: ... + def ClearField(self, field_name: typing_extensions.Literal["nanos", b"nanos", "seconds", b"seconds"]) -> None: ... + +global___Timestamp = Timestamp + +@typing_extensions.final +class TimestampSeconds(google.protobuf.message.Message): + """* + An exact date and time, with a resolution of one second (no nanoseconds). + """ + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + SECONDS_FIELD_NUMBER: builtins.int + seconds: builtins.int + """* + Number of complete seconds since the start of the epoch + """ + def __init__( + self, + *, + seconds: builtins.int = ..., + ) -> None: ... + def ClearField(self, field_name: typing_extensions.Literal["seconds", b"seconds"]) -> None: ... + +global___TimestampSeconds = TimestampSeconds diff --git a/proto/token_associate.proto b/proto/token_associate.proto new file mode 100644 index 00000000..2a28fce5 --- /dev/null +++ b/proto/token_associate.proto @@ -0,0 +1,55 @@ +syntax = "proto3"; + +package Hedera; + +/*- + * ‌ + * Hedera Network Services Protobuf + * ​ + * Copyright (C) 2018 - 2021 Hedera Hashgraph, LLC + * ​ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ‍ + */ +import "nanopb.proto"; +import "proto/basic_types.proto"; + +/** + * Associates the provided account with the provided tokens. Must be signed by + * the provided Account's key. If the provided account is not found, the + * transaction will resolve to INVALID_ACCOUNT_ID. If the provided account has + * been deleted, the transaction will resolve to ACCOUNT_DELETED. If any of the + * provided tokens is not found, the transaction will resolve to + * INVALID_TOKEN_REF. If any of the provided tokens has been deleted, the + * transaction will resolve to TOKEN_WAS_DELETED. If an association between the + * provided account and any of the tokens already exists, the transaction will + * resolve to TOKEN_ALREADY_ASSOCIATED_TO_ACCOUNT. If the provided account's + * associations count exceed the constraint of maximum token associations per + * account, the transaction will resolve to TOKENS_PER_ACCOUNT_LIMIT_EXCEEDED. + * On success, associations between the provided account and tokens are made and + * the account is ready to interact with the tokens. + */ +message TokenAssociateTransactionBody { + /** + * The account to be associated with the provided tokens + */ + AccountID account = 1; + + /** + * The tokens to be associated with the provided account. In the case of + * NON_FUNGIBLE_UNIQUE Type, once an account is associated, it can hold any + * number of NFTs (serial numbers) of that token type + * Limited to 1 here (no access to malloc for dynamic decode!) + */ + repeated TokenID tokens = 2 [ (nanopb).max_count = 1 ]; +} \ No newline at end of file diff --git a/proto/token_associate_pb2.py b/proto/token_associate_pb2.py new file mode 100644 index 00000000..21ee64af --- /dev/null +++ b/proto/token_associate_pb2.py @@ -0,0 +1,29 @@ +# -*- coding: utf-8 -*- +# Generated by the protocol buffer compiler. DO NOT EDIT! +# source: proto/token_associate.proto +"""Generated protocol buffer code.""" +from google.protobuf.internal import builder as _builder +from google.protobuf import descriptor as _descriptor +from google.protobuf import descriptor_pool as _descriptor_pool +from google.protobuf import symbol_database as _symbol_database +# @@protoc_insertion_point(imports) + +_sym_db = _symbol_database.Default() + + +import nanopb_pb2 as nanopb__pb2 +from proto import basic_types_pb2 as proto_dot_basic__types__pb2 + + +DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x1bproto/token_associate.proto\x12\x06Hedera\x1a\x0cnanopb.proto\x1a\x17proto/basic_types.proto\"k\n\x1dTokenAssociateTransactionBody\x12\"\n\x07\x61\x63\x63ount\x18\x01 \x01(\x0b\x32\x11.Hedera.AccountID\x12&\n\x06tokens\x18\x02 \x03(\x0b\x32\x0f.Hedera.TokenIDB\x05\x92?\x02\x10\x01\x62\x06proto3') + +_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, globals()) +_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'proto.token_associate_pb2', globals()) +if _descriptor._USE_C_DESCRIPTORS == False: + + DESCRIPTOR._options = None + _TOKENASSOCIATETRANSACTIONBODY.fields_by_name['tokens']._options = None + _TOKENASSOCIATETRANSACTIONBODY.fields_by_name['tokens']._serialized_options = b'\222?\002\020\001' + _TOKENASSOCIATETRANSACTIONBODY._serialized_start=78 + _TOKENASSOCIATETRANSACTIONBODY._serialized_end=185 +# @@protoc_insertion_point(module_scope) diff --git a/proto/token_associate_pb2.pyi b/proto/token_associate_pb2.pyi new file mode 100644 index 00000000..bd01a227 --- /dev/null +++ b/proto/token_associate_pb2.pyi @@ -0,0 +1,64 @@ +""" +@generated by mypy-protobuf. Do not edit manually! +isort:skip_file +""" +import builtins +import collections.abc +import google.protobuf.descriptor +import google.protobuf.internal.containers +import google.protobuf.message +import proto.basic_types_pb2 +import sys + +if sys.version_info >= (3, 8): + import typing as typing_extensions +else: + import typing_extensions + +DESCRIPTOR: google.protobuf.descriptor.FileDescriptor + +@typing_extensions.final +class TokenAssociateTransactionBody(google.protobuf.message.Message): + """* + Associates the provided account with the provided tokens. Must be signed by + the provided Account's key. If the provided account is not found, the + transaction will resolve to INVALID_ACCOUNT_ID. If the provided account has + been deleted, the transaction will resolve to ACCOUNT_DELETED. If any of the + provided tokens is not found, the transaction will resolve to + INVALID_TOKEN_REF. If any of the provided tokens has been deleted, the + transaction will resolve to TOKEN_WAS_DELETED. If an association between the + provided account and any of the tokens already exists, the transaction will + resolve to TOKEN_ALREADY_ASSOCIATED_TO_ACCOUNT. If the provided account's + associations count exceed the constraint of maximum token associations per + account, the transaction will resolve to TOKENS_PER_ACCOUNT_LIMIT_EXCEEDED. + On success, associations between the provided account and tokens are made and + the account is ready to interact with the tokens. + """ + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + ACCOUNT_FIELD_NUMBER: builtins.int + TOKENS_FIELD_NUMBER: builtins.int + @property + def account(self) -> proto.basic_types_pb2.AccountID: + """* + The account to be associated with the provided tokens + """ + @property + def tokens(self) -> google.protobuf.internal.containers.RepeatedCompositeFieldContainer[proto.basic_types_pb2.TokenID]: + """* + The tokens to be associated with the provided account. In the case of + NON_FUNGIBLE_UNIQUE Type, once an account is associated, it can hold any + number of NFTs (serial numbers) of that token type + Limited to 1 here (no access to malloc for dynamic decode!) + """ + def __init__( + self, + *, + account: proto.basic_types_pb2.AccountID | None = ..., + tokens: collections.abc.Iterable[proto.basic_types_pb2.TokenID] | None = ..., + ) -> None: ... + def HasField(self, field_name: typing_extensions.Literal["account", b"account"]) -> builtins.bool: ... + def ClearField(self, field_name: typing_extensions.Literal["account", b"account", "tokens", b"tokens"]) -> None: ... + +global___TokenAssociateTransactionBody = TokenAssociateTransactionBody diff --git a/proto/token_burn.proto b/proto/token_burn.proto new file mode 100644 index 00000000..d89dda89 --- /dev/null +++ b/proto/token_burn.proto @@ -0,0 +1,67 @@ +syntax = "proto3"; + +package Hedera; + +/*- + * ‌ + * Hedera Network Services Protobuf + * ​ + * Copyright (C) 2018 - 2021 Hedera Hashgraph, LLC + * ​ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ‍ + */ +import "nanopb.proto"; +import "proto/basic_types.proto"; + +/** + * Burns tokens from the Token's treasury Account. If no Supply Key is defined, + * the transaction will resolve to TOKEN_HAS_NO_SUPPLY_KEY. The operation + * decreases the Total Supply of the Token. Total supply cannot go below zero. + * The amount provided must be in the lowest denomination possible. Example: + * Token A has 2 decimals. In order to burn 100 tokens, one must provide amount + * of 10000. In order to burn 100.55 tokens, one must provide amount of 10055. + * For non fungible tokens the transaction body accepts serialNumbers list of + * integers as a parameter. + * + * If neither the amount nor the serialNumbers get filled, a + * INVALID_TOKEN_BURN_AMOUNT response code will be returned. If both amount and + * serialNumbers get filled, a INVALID_TRANSACTION_BODY response code will be + * returned. + * If the serialNumbers' list count is greater than the batch size limit global + * dynamic property, a BATCH_SIZE_LIMIT_EXCEEDED response code will be returned. + * If the serialNumbers list contains a non-positive integer as a serial number, + * a INVALID_NFT_ID response code will be returned. + */ +message TokenBurnTransactionBody { + /** + * The token for which to burn tokens. If token does not exist, transaction + * results in INVALID_TOKEN_ID + */ + TokenID token = 1; + + /** + * Applicable to tokens of type FUNGIBLE_COMMON. The amount to burn from the + * Treasury Account. Amount must be a positive non-zero number, not bigger + * than the token balance of the treasury account (0; balance], represented in + * the lowest denomination. + */ + uint64 amount = 2; + + /** + * Applicable to tokens of type NON_FUNGIBLE_UNIQUE. The list of serial + * numbers to be burned. + * Limited to 1 here + */ + repeated int64 serialNumbers = 3 [ (nanopb).max_count = 1 ]; +} \ No newline at end of file diff --git a/proto/token_burn_pb2.py b/proto/token_burn_pb2.py new file mode 100644 index 00000000..05efdf3f --- /dev/null +++ b/proto/token_burn_pb2.py @@ -0,0 +1,29 @@ +# -*- coding: utf-8 -*- +# Generated by the protocol buffer compiler. DO NOT EDIT! +# source: proto/token_burn.proto +"""Generated protocol buffer code.""" +from google.protobuf.internal import builder as _builder +from google.protobuf import descriptor as _descriptor +from google.protobuf import descriptor_pool as _descriptor_pool +from google.protobuf import symbol_database as _symbol_database +# @@protoc_insertion_point(imports) + +_sym_db = _symbol_database.Default() + + +import nanopb_pb2 as nanopb__pb2 +from proto import basic_types_pb2 as proto_dot_basic__types__pb2 + + +DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x16proto/token_burn.proto\x12\x06Hedera\x1a\x0cnanopb.proto\x1a\x17proto/basic_types.proto\"h\n\x18TokenBurnTransactionBody\x12\x1e\n\x05token\x18\x01 \x01(\x0b\x32\x0f.Hedera.TokenID\x12\x0e\n\x06\x61mount\x18\x02 \x01(\x04\x12\x1c\n\rserialNumbers\x18\x03 \x03(\x03\x42\x05\x92?\x02\x10\x01\x62\x06proto3') + +_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, globals()) +_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'proto.token_burn_pb2', globals()) +if _descriptor._USE_C_DESCRIPTORS == False: + + DESCRIPTOR._options = None + _TOKENBURNTRANSACTIONBODY.fields_by_name['serialNumbers']._options = None + _TOKENBURNTRANSACTIONBODY.fields_by_name['serialNumbers']._serialized_options = b'\222?\002\020\001' + _TOKENBURNTRANSACTIONBODY._serialized_start=73 + _TOKENBURNTRANSACTIONBODY._serialized_end=177 +# @@protoc_insertion_point(module_scope) diff --git a/proto/token_burn_pb2.pyi b/proto/token_burn_pb2.pyi new file mode 100644 index 00000000..dc77477a --- /dev/null +++ b/proto/token_burn_pb2.pyi @@ -0,0 +1,77 @@ +""" +@generated by mypy-protobuf. Do not edit manually! +isort:skip_file +""" +import builtins +import collections.abc +import google.protobuf.descriptor +import google.protobuf.internal.containers +import google.protobuf.message +import proto.basic_types_pb2 +import sys + +if sys.version_info >= (3, 8): + import typing as typing_extensions +else: + import typing_extensions + +DESCRIPTOR: google.protobuf.descriptor.FileDescriptor + +@typing_extensions.final +class TokenBurnTransactionBody(google.protobuf.message.Message): + """* + Burns tokens from the Token's treasury Account. If no Supply Key is defined, + the transaction will resolve to TOKEN_HAS_NO_SUPPLY_KEY. The operation + decreases the Total Supply of the Token. Total supply cannot go below zero. + The amount provided must be in the lowest denomination possible. Example: + Token A has 2 decimals. In order to burn 100 tokens, one must provide amount + of 10000. In order to burn 100.55 tokens, one must provide amount of 10055. + For non fungible tokens the transaction body accepts serialNumbers list of + integers as a parameter. + + If neither the amount nor the serialNumbers get filled, a + INVALID_TOKEN_BURN_AMOUNT response code will be returned. If both amount and + serialNumbers get filled, a INVALID_TRANSACTION_BODY response code will be + returned. + If the serialNumbers' list count is greater than the batch size limit global + dynamic property, a BATCH_SIZE_LIMIT_EXCEEDED response code will be returned. + If the serialNumbers list contains a non-positive integer as a serial number, + a INVALID_NFT_ID response code will be returned. + """ + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + TOKEN_FIELD_NUMBER: builtins.int + AMOUNT_FIELD_NUMBER: builtins.int + SERIALNUMBERS_FIELD_NUMBER: builtins.int + @property + def token(self) -> proto.basic_types_pb2.TokenID: + """* + The token for which to burn tokens. If token does not exist, transaction + results in INVALID_TOKEN_ID + """ + amount: builtins.int + """* + Applicable to tokens of type FUNGIBLE_COMMON. The amount to burn from the + Treasury Account. Amount must be a positive non-zero number, not bigger + than the token balance of the treasury account (0; balance], represented in + the lowest denomination. + """ + @property + def serialNumbers(self) -> google.protobuf.internal.containers.RepeatedScalarFieldContainer[builtins.int]: + """* + Applicable to tokens of type NON_FUNGIBLE_UNIQUE. The list of serial + numbers to be burned. + Limited to 1 here + """ + def __init__( + self, + *, + token: proto.basic_types_pb2.TokenID | None = ..., + amount: builtins.int = ..., + serialNumbers: collections.abc.Iterable[builtins.int] | None = ..., + ) -> None: ... + def HasField(self, field_name: typing_extensions.Literal["token", b"token"]) -> builtins.bool: ... + def ClearField(self, field_name: typing_extensions.Literal["amount", b"amount", "serialNumbers", b"serialNumbers", "token", b"token"]) -> None: ... + +global___TokenBurnTransactionBody = TokenBurnTransactionBody diff --git a/proto/token_dissociate.proto b/proto/token_dissociate.proto new file mode 100644 index 00000000..4e75f3c7 --- /dev/null +++ b/proto/token_dissociate.proto @@ -0,0 +1,56 @@ +syntax = "proto3"; + +package Hedera; + +/*- + * ‌ + * Hedera Network Services Protobuf + * ​ + * Copyright (C) 2018 - 2021 Hedera Hashgraph, LLC + * ​ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ‍ + */ +import "nanopb.proto"; +import "proto/basic_types.proto"; + +/** + * Dissociates the provided account with the provided tokens. Must be signed by + * the provided Account's key. If the provided account is not found, the + * transaction will resolve to INVALID_ACCOUNT_ID. If the provided account has + * been deleted, the transaction will resolve to ACCOUNT_DELETED. If any of the + * provided tokens is not found, the transaction will resolve to + * INVALID_TOKEN_REF. If any of the provided tokens has been deleted, the + * transaction will resolve to TOKEN_WAS_DELETED. If an association between the + * provided account and any of the tokens does not exist, the transaction will + * resolve to TOKEN_NOT_ASSOCIATED_TO_ACCOUNT. If a token has not been deleted + * and has not expired, and the user has a nonzero balance, the transaction will + * resolve to TRANSACTION_REQUIRES_ZERO_TOKEN_BALANCES. If a fungible + * token has expired, the user can disassociate even if their token balance + * is not zero. If a non fungible token has expired, the user can + * not disassociate if their token balance is not zero. The transaction + * will resolve to TRANSACTION_REQUIRED_ZERO_TOKEN_BALANCES. On success, + * associations between the provided account and tokens are removed. + */ +message TokenDissociateTransactionBody { + /** + * The account to be dissociated with the provided tokens + */ + AccountID account = 1; + + /** + * The tokens to be dissociated with the provided account + * Limited to 1 here + */ + repeated TokenID tokens = 2 [ (nanopb).max_count = 1 ]; +} \ No newline at end of file diff --git a/proto/token_dissociate_pb2.py b/proto/token_dissociate_pb2.py new file mode 100644 index 00000000..b5809df2 --- /dev/null +++ b/proto/token_dissociate_pb2.py @@ -0,0 +1,29 @@ +# -*- coding: utf-8 -*- +# Generated by the protocol buffer compiler. DO NOT EDIT! +# source: proto/token_dissociate.proto +"""Generated protocol buffer code.""" +from google.protobuf.internal import builder as _builder +from google.protobuf import descriptor as _descriptor +from google.protobuf import descriptor_pool as _descriptor_pool +from google.protobuf import symbol_database as _symbol_database +# @@protoc_insertion_point(imports) + +_sym_db = _symbol_database.Default() + + +import nanopb_pb2 as nanopb__pb2 +from proto import basic_types_pb2 as proto_dot_basic__types__pb2 + + +DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x1cproto/token_dissociate.proto\x12\x06Hedera\x1a\x0cnanopb.proto\x1a\x17proto/basic_types.proto\"l\n\x1eTokenDissociateTransactionBody\x12\"\n\x07\x61\x63\x63ount\x18\x01 \x01(\x0b\x32\x11.Hedera.AccountID\x12&\n\x06tokens\x18\x02 \x03(\x0b\x32\x0f.Hedera.TokenIDB\x05\x92?\x02\x10\x01\x62\x06proto3') + +_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, globals()) +_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'proto.token_dissociate_pb2', globals()) +if _descriptor._USE_C_DESCRIPTORS == False: + + DESCRIPTOR._options = None + _TOKENDISSOCIATETRANSACTIONBODY.fields_by_name['tokens']._options = None + _TOKENDISSOCIATETRANSACTIONBODY.fields_by_name['tokens']._serialized_options = b'\222?\002\020\001' + _TOKENDISSOCIATETRANSACTIONBODY._serialized_start=79 + _TOKENDISSOCIATETRANSACTIONBODY._serialized_end=187 +# @@protoc_insertion_point(module_scope) diff --git a/proto/token_dissociate_pb2.pyi b/proto/token_dissociate_pb2.pyi new file mode 100644 index 00000000..e5a665e6 --- /dev/null +++ b/proto/token_dissociate_pb2.pyi @@ -0,0 +1,65 @@ +""" +@generated by mypy-protobuf. Do not edit manually! +isort:skip_file +""" +import builtins +import collections.abc +import google.protobuf.descriptor +import google.protobuf.internal.containers +import google.protobuf.message +import proto.basic_types_pb2 +import sys + +if sys.version_info >= (3, 8): + import typing as typing_extensions +else: + import typing_extensions + +DESCRIPTOR: google.protobuf.descriptor.FileDescriptor + +@typing_extensions.final +class TokenDissociateTransactionBody(google.protobuf.message.Message): + """* + Dissociates the provided account with the provided tokens. Must be signed by + the provided Account's key. If the provided account is not found, the + transaction will resolve to INVALID_ACCOUNT_ID. If the provided account has + been deleted, the transaction will resolve to ACCOUNT_DELETED. If any of the + provided tokens is not found, the transaction will resolve to + INVALID_TOKEN_REF. If any of the provided tokens has been deleted, the + transaction will resolve to TOKEN_WAS_DELETED. If an association between the + provided account and any of the tokens does not exist, the transaction will + resolve to TOKEN_NOT_ASSOCIATED_TO_ACCOUNT. If a token has not been deleted + and has not expired, and the user has a nonzero balance, the transaction will + resolve to TRANSACTION_REQUIRES_ZERO_TOKEN_BALANCES. If a fungible + token has expired, the user can disassociate even if their token balance + is not zero. If a non fungible token has expired, the user can + not disassociate if their token balance is not zero. The transaction + will resolve to TRANSACTION_REQUIRED_ZERO_TOKEN_BALANCES. On success, + associations between the provided account and tokens are removed. + """ + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + ACCOUNT_FIELD_NUMBER: builtins.int + TOKENS_FIELD_NUMBER: builtins.int + @property + def account(self) -> proto.basic_types_pb2.AccountID: + """* + The account to be dissociated with the provided tokens + """ + @property + def tokens(self) -> google.protobuf.internal.containers.RepeatedCompositeFieldContainer[proto.basic_types_pb2.TokenID]: + """* + The tokens to be dissociated with the provided account + Limited to 1 here + """ + def __init__( + self, + *, + account: proto.basic_types_pb2.AccountID | None = ..., + tokens: collections.abc.Iterable[proto.basic_types_pb2.TokenID] | None = ..., + ) -> None: ... + def HasField(self, field_name: typing_extensions.Literal["account", b"account"]) -> builtins.bool: ... + def ClearField(self, field_name: typing_extensions.Literal["account", b"account", "tokens", b"tokens"]) -> None: ... + +global___TokenDissociateTransactionBody = TokenDissociateTransactionBody diff --git a/proto/token_mint.proto b/proto/token_mint.proto new file mode 100644 index 00000000..1c81866a --- /dev/null +++ b/proto/token_mint.proto @@ -0,0 +1,65 @@ +syntax = "proto3"; + +package Hedera; + +/*- + * ‌ + * Hedera Network Services Protobuf + * ​ + * Copyright (C) 2018 - 2021 Hedera Hashgraph, LLC + * ​ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ‍ + */ +import "nanopb.proto"; +import "proto/basic_types.proto"; + +/** + * Mints tokens to the Token's treasury Account. If no Supply Key is defined, + * the transaction will resolve to TOKEN_HAS_NO_SUPPLY_KEY. The operation + * increases the Total Supply of the Token. The maximum total supply a token can + * have is 2^63-1. The amount provided must be in the lowest denomination + * possible. Example: Token A has 2 decimals. In order to mint 100 tokens, one + * must provide amount of 10000. In order to mint 100.55 tokens, one must + * provide amount of 10055. If both amount and metadata list get filled, a + * INVALID_TRANSACTION_BODY response code will be returned. If the metadata list + * contains metadata which is too large, a METADATA_TOO_LONG response code will + * be returned. + * If neither the amount nor the metadata list get filled, a + * INVALID_TOKEN_MINT_AMOUNT response code will be returned. If the metadata + * list count is greater than the batch size limit global dynamic property, a + * BATCH_SIZE_LIMIT_EXCEEDED response code will be returned. + */ +message TokenMintTransactionBody { + /** + * The token for which to mint tokens. If token does not exist, transaction + * results in INVALID_TOKEN_ID + */ + TokenID token = 1; + + /** + * Applicable to tokens of type FUNGIBLE_COMMON. The amount to mint to the + * Treasury Account. Amount must be a positive non-zero number represented in + * the lowest denomination of the token. The new supply must be lower than + * 2^63. + */ + uint64 amount = 2; + + /** + * Applicable to tokens of type NON_FUNGIBLE_UNIQUE. A list of metadata that + * are being created. Maximum allowed size of each metadata is 100 bytes + * Limited to 1 metadata chunk (no access to malloc) + */ + repeated bytes metadata = 3 + [ (nanopb).max_size = 100, (nanopb).max_count = 1 ]; +} \ No newline at end of file diff --git a/proto/token_mint_pb2.py b/proto/token_mint_pb2.py new file mode 100644 index 00000000..0ea6629c --- /dev/null +++ b/proto/token_mint_pb2.py @@ -0,0 +1,29 @@ +# -*- coding: utf-8 -*- +# Generated by the protocol buffer compiler. DO NOT EDIT! +# source: proto/token_mint.proto +"""Generated protocol buffer code.""" +from google.protobuf.internal import builder as _builder +from google.protobuf import descriptor as _descriptor +from google.protobuf import descriptor_pool as _descriptor_pool +from google.protobuf import symbol_database as _symbol_database +# @@protoc_insertion_point(imports) + +_sym_db = _symbol_database.Default() + + +import nanopb_pb2 as nanopb__pb2 +from proto import basic_types_pb2 as proto_dot_basic__types__pb2 + + +DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x16proto/token_mint.proto\x12\x06Hedera\x1a\x0cnanopb.proto\x1a\x17proto/basic_types.proto\"h\n\x18TokenMintTransactionBody\x12\x1e\n\x05token\x18\x01 \x01(\x0b\x32\x0f.Hedera.TokenID\x12\x0e\n\x06\x61mount\x18\x02 \x01(\x04\x12\x1c\n\x08metadata\x18\x03 \x03(\x0c\x42\n\x92?\x02\x08\x64\x92?\x02\x10\x01\x62\x06proto3') + +_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, globals()) +_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'proto.token_mint_pb2', globals()) +if _descriptor._USE_C_DESCRIPTORS == False: + + DESCRIPTOR._options = None + _TOKENMINTTRANSACTIONBODY.fields_by_name['metadata']._options = None + _TOKENMINTTRANSACTIONBODY.fields_by_name['metadata']._serialized_options = b'\222?\002\010d\222?\002\020\001' + _TOKENMINTTRANSACTIONBODY._serialized_start=73 + _TOKENMINTTRANSACTIONBODY._serialized_end=177 +# @@protoc_insertion_point(module_scope) diff --git a/proto/token_mint_pb2.pyi b/proto/token_mint_pb2.pyi new file mode 100644 index 00000000..2cece623 --- /dev/null +++ b/proto/token_mint_pb2.pyi @@ -0,0 +1,74 @@ +""" +@generated by mypy-protobuf. Do not edit manually! +isort:skip_file +""" +import builtins +import collections.abc +import google.protobuf.descriptor +import google.protobuf.internal.containers +import google.protobuf.message +import proto.basic_types_pb2 +import sys + +if sys.version_info >= (3, 8): + import typing as typing_extensions +else: + import typing_extensions + +DESCRIPTOR: google.protobuf.descriptor.FileDescriptor + +@typing_extensions.final +class TokenMintTransactionBody(google.protobuf.message.Message): + """* + Mints tokens to the Token's treasury Account. If no Supply Key is defined, + the transaction will resolve to TOKEN_HAS_NO_SUPPLY_KEY. The operation + increases the Total Supply of the Token. The maximum total supply a token can + have is 2^63-1. The amount provided must be in the lowest denomination + possible. Example: Token A has 2 decimals. In order to mint 100 tokens, one + must provide amount of 10000. In order to mint 100.55 tokens, one must + provide amount of 10055. If both amount and metadata list get filled, a + INVALID_TRANSACTION_BODY response code will be returned. If the metadata list + contains metadata which is too large, a METADATA_TOO_LONG response code will + be returned. + If neither the amount nor the metadata list get filled, a + INVALID_TOKEN_MINT_AMOUNT response code will be returned. If the metadata + list count is greater than the batch size limit global dynamic property, a + BATCH_SIZE_LIMIT_EXCEEDED response code will be returned. + """ + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + TOKEN_FIELD_NUMBER: builtins.int + AMOUNT_FIELD_NUMBER: builtins.int + METADATA_FIELD_NUMBER: builtins.int + @property + def token(self) -> proto.basic_types_pb2.TokenID: + """* + The token for which to mint tokens. If token does not exist, transaction + results in INVALID_TOKEN_ID + """ + amount: builtins.int + """* + Applicable to tokens of type FUNGIBLE_COMMON. The amount to mint to the + Treasury Account. Amount must be a positive non-zero number represented in + the lowest denomination of the token. The new supply must be lower than + 2^63. + """ + @property + def metadata(self) -> google.protobuf.internal.containers.RepeatedScalarFieldContainer[builtins.bytes]: + """* + Applicable to tokens of type NON_FUNGIBLE_UNIQUE. A list of metadata that + are being created. Maximum allowed size of each metadata is 100 bytes + Limited to 1 metadata chunk (no access to malloc) + """ + def __init__( + self, + *, + token: proto.basic_types_pb2.TokenID | None = ..., + amount: builtins.int = ..., + metadata: collections.abc.Iterable[builtins.bytes] | None = ..., + ) -> None: ... + def HasField(self, field_name: typing_extensions.Literal["token", b"token"]) -> builtins.bool: ... + def ClearField(self, field_name: typing_extensions.Literal["amount", b"amount", "metadata", b"metadata", "token", b"token"]) -> None: ... + +global___TokenMintTransactionBody = TokenMintTransactionBody diff --git a/proto/transaction_body.proto b/proto/transaction_body.proto new file mode 100644 index 00000000..73a5ca6b --- /dev/null +++ b/proto/transaction_body.proto @@ -0,0 +1,117 @@ +syntax = "proto3"; + +package Hedera; + +/*- + * ‌ + * Hedera Network Services Protobuf + * ​ + * Copyright (C) 2018 - 2021 Hedera Hashgraph, LLC + * ​ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ‍ + */ +import "nanopb.proto"; +import "proto/basic_types.proto"; +import "proto/crypto_create.proto"; +import "proto/crypto_transfer.proto"; +import "proto/crypto_update.proto"; +import "proto/duration.proto"; +import "proto/token_associate.proto"; +import "proto/token_burn.proto"; +import "proto/token_dissociate.proto"; +import "proto/token_mint.proto"; + +/** + * A single transaction. All transaction types are possible here. + */ +message TransactionBody { + /** + * The ID for this transaction, which includes the payer's account (the + * account paying the transaction fee). If two transactions have the same + * transactionID, they won't both have an effect + */ + TransactionID transactionID = 1; + + /** + * The account of the node that submits the client's transaction to the + * network + */ + AccountID nodeAccountID = 2; + + /** + * The maximum transaction fee the client is willing to pay + */ + uint64 transactionFee = 3; + + /** + * The transaction is invalid if consensusTimestamp > + * transactionID.transactionValidStart + transactionValidDuration + */ + Duration transactionValidDuration = 4; + + /** + * Should a record of this transaction be generated? (A receipt is always + * generated, but the record is optional) + */ + bool generateRecord = 5 [ deprecated = true ]; + + /** + * Any notes or descriptions that should be put into the record (max length + * 100) + */ + string memo = 6 [ (nanopb).max_size = 100 ]; + + /** + * The choices here are arranged by service in roughly lexicographical order. + * The field ordinals are non-sequential, and a result of the historical order + * of implementation. + * Limited to supported transactions here + */ + oneof data { + /** + * Create a new cryptocurrency account + */ + CryptoCreateTransactionBody cryptoCreateAccount = 11; + + /** + * Transfer amount between accounts + */ + CryptoTransferTransactionBody cryptoTransfer = 14; + + /** + * Modify information such as the expiration date for an account + */ + CryptoUpdateTransactionBody cryptoUpdateAccount = 15; + + /** + * Mints new tokens to a token's treasury account + */ + TokenMintTransactionBody tokenMint = 37; + + /** + * Burns tokens from a token's treasury account + */ + TokenBurnTransactionBody tokenBurn = 38; + + /** + * Associate tokens to an account + */ + TokenAssociateTransactionBody tokenAssociate = 40; + + /** + * Dissociate tokens from an account + */ + TokenDissociateTransactionBody tokenDissociate = 41; + } +} \ No newline at end of file diff --git a/proto/transaction_body_pb2.py b/proto/transaction_body_pb2.py new file mode 100644 index 00000000..e24c5440 --- /dev/null +++ b/proto/transaction_body_pb2.py @@ -0,0 +1,39 @@ +# -*- coding: utf-8 -*- +# Generated by the protocol buffer compiler. DO NOT EDIT! +# source: proto/transaction_body.proto +"""Generated protocol buffer code.""" +from google.protobuf.internal import builder as _builder +from google.protobuf import descriptor as _descriptor +from google.protobuf import descriptor_pool as _descriptor_pool +from google.protobuf import symbol_database as _symbol_database +# @@protoc_insertion_point(imports) + +_sym_db = _symbol_database.Default() + + +import nanopb_pb2 as nanopb__pb2 +from proto import basic_types_pb2 as proto_dot_basic__types__pb2 +from proto import crypto_create_pb2 as proto_dot_crypto__create__pb2 +from proto import crypto_transfer_pb2 as proto_dot_crypto__transfer__pb2 +from proto import crypto_update_pb2 as proto_dot_crypto__update__pb2 +from proto import duration_pb2 as proto_dot_duration__pb2 +from proto import token_associate_pb2 as proto_dot_token__associate__pb2 +from proto import token_burn_pb2 as proto_dot_token__burn__pb2 +from proto import token_dissociate_pb2 as proto_dot_token__dissociate__pb2 +from proto import token_mint_pb2 as proto_dot_token__mint__pb2 + + +DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x1cproto/transaction_body.proto\x12\x06Hedera\x1a\x0cnanopb.proto\x1a\x17proto/basic_types.proto\x1a\x19proto/crypto_create.proto\x1a\x1bproto/crypto_transfer.proto\x1a\x19proto/crypto_update.proto\x1a\x14proto/duration.proto\x1a\x1bproto/token_associate.proto\x1a\x16proto/token_burn.proto\x1a\x1cproto/token_dissociate.proto\x1a\x16proto/token_mint.proto\"\xa9\x05\n\x0fTransactionBody\x12,\n\rtransactionID\x18\x01 \x01(\x0b\x32\x15.Hedera.TransactionID\x12(\n\rnodeAccountID\x18\x02 \x01(\x0b\x32\x11.Hedera.AccountID\x12\x16\n\x0etransactionFee\x18\x03 \x01(\x04\x12\x32\n\x18transactionValidDuration\x18\x04 \x01(\x0b\x32\x10.Hedera.Duration\x12\x1a\n\x0egenerateRecord\x18\x05 \x01(\x08\x42\x02\x18\x01\x12\x13\n\x04memo\x18\x06 \x01(\tB\x05\x92?\x02\x08\x64\x12\x42\n\x13\x63ryptoCreateAccount\x18\x0b \x01(\x0b\x32#.Hedera.CryptoCreateTransactionBodyH\x00\x12?\n\x0e\x63ryptoTransfer\x18\x0e \x01(\x0b\x32%.Hedera.CryptoTransferTransactionBodyH\x00\x12\x42\n\x13\x63ryptoUpdateAccount\x18\x0f \x01(\x0b\x32#.Hedera.CryptoUpdateTransactionBodyH\x00\x12\x35\n\ttokenMint\x18% \x01(\x0b\x32 .Hedera.TokenMintTransactionBodyH\x00\x12\x35\n\ttokenBurn\x18& \x01(\x0b\x32 .Hedera.TokenBurnTransactionBodyH\x00\x12?\n\x0etokenAssociate\x18( \x01(\x0b\x32%.Hedera.TokenAssociateTransactionBodyH\x00\x12\x41\n\x0ftokenDissociate\x18) \x01(\x0b\x32&.Hedera.TokenDissociateTransactionBodyH\x00\x42\x06\n\x04\x64\x61tab\x06proto3') + +_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, globals()) +_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'proto.transaction_body_pb2', globals()) +if _descriptor._USE_C_DESCRIPTORS == False: + + DESCRIPTOR._options = None + _TRANSACTIONBODY.fields_by_name['generateRecord']._options = None + _TRANSACTIONBODY.fields_by_name['generateRecord']._serialized_options = b'\030\001' + _TRANSACTIONBODY.fields_by_name['memo']._options = None + _TRANSACTIONBODY.fields_by_name['memo']._serialized_options = b'\222?\002\010d' + _TRANSACTIONBODY._serialized_start=292 + _TRANSACTIONBODY._serialized_end=973 +# @@protoc_insertion_point(module_scope) diff --git a/proto/transaction_body_pb2.pyi b/proto/transaction_body_pb2.pyi new file mode 100644 index 00000000..e2374bdb --- /dev/null +++ b/proto/transaction_body_pb2.pyi @@ -0,0 +1,136 @@ +""" +@generated by mypy-protobuf. Do not edit manually! +isort:skip_file +""" +import builtins +import google.protobuf.descriptor +import google.protobuf.message +import proto.basic_types_pb2 +import proto.crypto_create_pb2 +import proto.crypto_transfer_pb2 +import proto.crypto_update_pb2 +import proto.duration_pb2 +import proto.token_associate_pb2 +import proto.token_burn_pb2 +import proto.token_dissociate_pb2 +import proto.token_mint_pb2 +import sys + +if sys.version_info >= (3, 8): + import typing as typing_extensions +else: + import typing_extensions + +DESCRIPTOR: google.protobuf.descriptor.FileDescriptor + +@typing_extensions.final +class TransactionBody(google.protobuf.message.Message): + """* + A single transaction. All transaction types are possible here. + """ + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + TRANSACTIONID_FIELD_NUMBER: builtins.int + NODEACCOUNTID_FIELD_NUMBER: builtins.int + TRANSACTIONFEE_FIELD_NUMBER: builtins.int + TRANSACTIONVALIDDURATION_FIELD_NUMBER: builtins.int + GENERATERECORD_FIELD_NUMBER: builtins.int + MEMO_FIELD_NUMBER: builtins.int + CRYPTOCREATEACCOUNT_FIELD_NUMBER: builtins.int + CRYPTOTRANSFER_FIELD_NUMBER: builtins.int + CRYPTOUPDATEACCOUNT_FIELD_NUMBER: builtins.int + TOKENMINT_FIELD_NUMBER: builtins.int + TOKENBURN_FIELD_NUMBER: builtins.int + TOKENASSOCIATE_FIELD_NUMBER: builtins.int + TOKENDISSOCIATE_FIELD_NUMBER: builtins.int + @property + def transactionID(self) -> proto.basic_types_pb2.TransactionID: + """* + The ID for this transaction, which includes the payer's account (the + account paying the transaction fee). If two transactions have the same + transactionID, they won't both have an effect + """ + @property + def nodeAccountID(self) -> proto.basic_types_pb2.AccountID: + """* + The account of the node that submits the client's transaction to the + network + """ + transactionFee: builtins.int + """* + The maximum transaction fee the client is willing to pay + """ + @property + def transactionValidDuration(self) -> proto.duration_pb2.Duration: + """* + The transaction is invalid if consensusTimestamp > + transactionID.transactionValidStart + transactionValidDuration + """ + generateRecord: builtins.bool + """* + Should a record of this transaction be generated? (A receipt is always + generated, but the record is optional) + """ + memo: builtins.str + """* + Any notes or descriptions that should be put into the record (max length + 100) + """ + @property + def cryptoCreateAccount(self) -> proto.crypto_create_pb2.CryptoCreateTransactionBody: + """* + Create a new cryptocurrency account + """ + @property + def cryptoTransfer(self) -> proto.crypto_transfer_pb2.CryptoTransferTransactionBody: + """* + Transfer amount between accounts + """ + @property + def cryptoUpdateAccount(self) -> proto.crypto_update_pb2.CryptoUpdateTransactionBody: + """* + Modify information such as the expiration date for an account + """ + @property + def tokenMint(self) -> proto.token_mint_pb2.TokenMintTransactionBody: + """* + Mints new tokens to a token's treasury account + """ + @property + def tokenBurn(self) -> proto.token_burn_pb2.TokenBurnTransactionBody: + """* + Burns tokens from a token's treasury account + """ + @property + def tokenAssociate(self) -> proto.token_associate_pb2.TokenAssociateTransactionBody: + """* + Associate tokens to an account + """ + @property + def tokenDissociate(self) -> proto.token_dissociate_pb2.TokenDissociateTransactionBody: + """* + Dissociate tokens from an account + """ + def __init__( + self, + *, + transactionID: proto.basic_types_pb2.TransactionID | None = ..., + nodeAccountID: proto.basic_types_pb2.AccountID | None = ..., + transactionFee: builtins.int = ..., + transactionValidDuration: proto.duration_pb2.Duration | None = ..., + generateRecord: builtins.bool = ..., + memo: builtins.str = ..., + cryptoCreateAccount: proto.crypto_create_pb2.CryptoCreateTransactionBody | None = ..., + cryptoTransfer: proto.crypto_transfer_pb2.CryptoTransferTransactionBody | None = ..., + cryptoUpdateAccount: proto.crypto_update_pb2.CryptoUpdateTransactionBody | None = ..., + tokenMint: proto.token_mint_pb2.TokenMintTransactionBody | None = ..., + tokenBurn: proto.token_burn_pb2.TokenBurnTransactionBody | None = ..., + tokenAssociate: proto.token_associate_pb2.TokenAssociateTransactionBody | None = ..., + tokenDissociate: proto.token_dissociate_pb2.TokenDissociateTransactionBody | None = ..., + ) -> None: ... + def HasField(self, field_name: typing_extensions.Literal["cryptoCreateAccount", b"cryptoCreateAccount", "cryptoTransfer", b"cryptoTransfer", "cryptoUpdateAccount", b"cryptoUpdateAccount", "data", b"data", "nodeAccountID", b"nodeAccountID", "tokenAssociate", b"tokenAssociate", "tokenBurn", b"tokenBurn", "tokenDissociate", b"tokenDissociate", "tokenMint", b"tokenMint", "transactionID", b"transactionID", "transactionValidDuration", b"transactionValidDuration"]) -> builtins.bool: ... + def ClearField(self, field_name: typing_extensions.Literal["cryptoCreateAccount", b"cryptoCreateAccount", "cryptoTransfer", b"cryptoTransfer", "cryptoUpdateAccount", b"cryptoUpdateAccount", "data", b"data", "generateRecord", b"generateRecord", "memo", b"memo", "nodeAccountID", b"nodeAccountID", "tokenAssociate", b"tokenAssociate", "tokenBurn", b"tokenBurn", "tokenDissociate", b"tokenDissociate", "tokenMint", b"tokenMint", "transactionFee", b"transactionFee", "transactionID", b"transactionID", "transactionValidDuration", b"transactionValidDuration"]) -> None: ... + def WhichOneof(self, oneof_group: typing_extensions.Literal["data", b"data"]) -> typing_extensions.Literal["cryptoCreateAccount", "cryptoTransfer", "cryptoUpdateAccount", "tokenMint", "tokenBurn", "tokenAssociate", "tokenDissociate"] | None: ... + +global___TransactionBody = TransactionBody diff --git a/proto/wrappers.proto b/proto/wrappers.proto new file mode 100644 index 00000000..d7f95475 --- /dev/null +++ b/proto/wrappers.proto @@ -0,0 +1,108 @@ + +syntax = "proto3"; + +package Hedera; +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// https://developers.google.com/protocol-buffers/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Wrappers for primitive (non-message) types. These types are useful +// for embedding primitives in the `google.protobuf.Any` type and for places +// where we need to distinguish between the absence of a primitive +// typed field and its default value. +// +// These wrappers have no meaningful use within repeated fields as they lack +// the ability to detect presence on individual elements. +// These wrappers have no meaningful use within a map or a oneof since +// individual entries of a map or fields of a oneof can already detect presence. +import "nanopb.proto"; + +// Wrapper message for `double`. +// +// The JSON representation for `DoubleValue` is JSON number. +message DoubleValue { + // The double value. + double value = 1; +} + +// Wrapper message for `float`. +// +// The JSON representation for `FloatValue` is JSON number. +message FloatValue { + // The float value. + float value = 1; +} + +// Wrapper message for `int64`. +// +// The JSON representation for `Int64Value` is JSON string. +message Int64Value { + // The int64 value. + int64 value = 1; +} + +// Wrapper message for `uint64`. +// +// The JSON representation for `UInt64Value` is JSON string. +message UInt64Value { + // The uint64 value. + uint64 value = 1; +} + +// Wrapper message for `int32`. +// +// The JSON representation for `Int32Value` is JSON number. +message Int32Value { + // The int32 value. + int32 value = 1; +} + +// Wrapper message for `uint32`. +// +// The JSON representation for `UInt32Value` is JSON number. +message UInt32Value { + // The uint32 value. + uint32 value = 1; +} + +// Wrapper message for `bool`. +// +// The JSON representation for `BoolValue` is JSON `true` and `false`. +message BoolValue { + // The bool value. + bool value = 1; +} + +// Wrapper message for `string`. +// +// The JSON representation for `StringValue` is JSON string. +message StringValue { + // The string value. + string value = 1; +} \ No newline at end of file diff --git a/proto/wrappers_pb2.py b/proto/wrappers_pb2.py new file mode 100644 index 00000000..7961d1ed --- /dev/null +++ b/proto/wrappers_pb2.py @@ -0,0 +1,40 @@ +# -*- coding: utf-8 -*- +# Generated by the protocol buffer compiler. DO NOT EDIT! +# source: proto/wrappers.proto +"""Generated protocol buffer code.""" +from google.protobuf.internal import builder as _builder +from google.protobuf import descriptor as _descriptor +from google.protobuf import descriptor_pool as _descriptor_pool +from google.protobuf import symbol_database as _symbol_database +# @@protoc_insertion_point(imports) + +_sym_db = _symbol_database.Default() + + +import nanopb_pb2 as nanopb__pb2 + + +DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x14proto/wrappers.proto\x12\x06Hedera\x1a\x0cnanopb.proto\"\x1c\n\x0b\x44oubleValue\x12\r\n\x05value\x18\x01 \x01(\x01\"\x1b\n\nFloatValue\x12\r\n\x05value\x18\x01 \x01(\x02\"\x1b\n\nInt64Value\x12\r\n\x05value\x18\x01 \x01(\x03\"\x1c\n\x0bUInt64Value\x12\r\n\x05value\x18\x01 \x01(\x04\"\x1b\n\nInt32Value\x12\r\n\x05value\x18\x01 \x01(\x05\"\x1c\n\x0bUInt32Value\x12\r\n\x05value\x18\x01 \x01(\r\"\x1a\n\tBoolValue\x12\r\n\x05value\x18\x01 \x01(\x08\"\x1c\n\x0bStringValue\x12\r\n\x05value\x18\x01 \x01(\tb\x06proto3') + +_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, globals()) +_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'proto.wrappers_pb2', globals()) +if _descriptor._USE_C_DESCRIPTORS == False: + + DESCRIPTOR._options = None + _DOUBLEVALUE._serialized_start=46 + _DOUBLEVALUE._serialized_end=74 + _FLOATVALUE._serialized_start=76 + _FLOATVALUE._serialized_end=103 + _INT64VALUE._serialized_start=105 + _INT64VALUE._serialized_end=132 + _UINT64VALUE._serialized_start=134 + _UINT64VALUE._serialized_end=162 + _INT32VALUE._serialized_start=164 + _INT32VALUE._serialized_end=191 + _UINT32VALUE._serialized_start=193 + _UINT32VALUE._serialized_end=221 + _BOOLVALUE._serialized_start=223 + _BOOLVALUE._serialized_end=249 + _STRINGVALUE._serialized_start=251 + _STRINGVALUE._serialized_end=279 +# @@protoc_insertion_point(module_scope) diff --git a/proto/wrappers_pb2.pyi b/proto/wrappers_pb2.pyi new file mode 100644 index 00000000..57f539f5 --- /dev/null +++ b/proto/wrappers_pb2.pyi @@ -0,0 +1,212 @@ +""" +@generated by mypy-protobuf. Do not edit manually! +isort:skip_file +Protocol Buffers - Google's data interchange format +Copyright 2008 Google Inc. All rights reserved. +https://developers.google.com/protocol-buffers/ + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + + * Redistributions of source code must retain the above copyright +notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above +copyright notice, this list of conditions and the following disclaimer +in the documentation and/or other materials provided with the +distribution. + * Neither the name of Google Inc. nor the names of its +contributors may be used to endorse or promote products derived from +this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +""" +import builtins +import google.protobuf.descriptor +import google.protobuf.message +import sys + +if sys.version_info >= (3, 8): + import typing as typing_extensions +else: + import typing_extensions + +DESCRIPTOR: google.protobuf.descriptor.FileDescriptor + +@typing_extensions.final +class DoubleValue(google.protobuf.message.Message): + """Wrapper message for `double`. + + The JSON representation for `DoubleValue` is JSON number. + """ + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + VALUE_FIELD_NUMBER: builtins.int + value: builtins.float + """The double value.""" + def __init__( + self, + *, + value: builtins.float = ..., + ) -> None: ... + def ClearField(self, field_name: typing_extensions.Literal["value", b"value"]) -> None: ... + +global___DoubleValue = DoubleValue + +@typing_extensions.final +class FloatValue(google.protobuf.message.Message): + """Wrapper message for `float`. + + The JSON representation for `FloatValue` is JSON number. + """ + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + VALUE_FIELD_NUMBER: builtins.int + value: builtins.float + """The float value.""" + def __init__( + self, + *, + value: builtins.float = ..., + ) -> None: ... + def ClearField(self, field_name: typing_extensions.Literal["value", b"value"]) -> None: ... + +global___FloatValue = FloatValue + +@typing_extensions.final +class Int64Value(google.protobuf.message.Message): + """Wrapper message for `int64`. + + The JSON representation for `Int64Value` is JSON string. + """ + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + VALUE_FIELD_NUMBER: builtins.int + value: builtins.int + """The int64 value.""" + def __init__( + self, + *, + value: builtins.int = ..., + ) -> None: ... + def ClearField(self, field_name: typing_extensions.Literal["value", b"value"]) -> None: ... + +global___Int64Value = Int64Value + +@typing_extensions.final +class UInt64Value(google.protobuf.message.Message): + """Wrapper message for `uint64`. + + The JSON representation for `UInt64Value` is JSON string. + """ + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + VALUE_FIELD_NUMBER: builtins.int + value: builtins.int + """The uint64 value.""" + def __init__( + self, + *, + value: builtins.int = ..., + ) -> None: ... + def ClearField(self, field_name: typing_extensions.Literal["value", b"value"]) -> None: ... + +global___UInt64Value = UInt64Value + +@typing_extensions.final +class Int32Value(google.protobuf.message.Message): + """Wrapper message for `int32`. + + The JSON representation for `Int32Value` is JSON number. + """ + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + VALUE_FIELD_NUMBER: builtins.int + value: builtins.int + """The int32 value.""" + def __init__( + self, + *, + value: builtins.int = ..., + ) -> None: ... + def ClearField(self, field_name: typing_extensions.Literal["value", b"value"]) -> None: ... + +global___Int32Value = Int32Value + +@typing_extensions.final +class UInt32Value(google.protobuf.message.Message): + """Wrapper message for `uint32`. + + The JSON representation for `UInt32Value` is JSON number. + """ + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + VALUE_FIELD_NUMBER: builtins.int + value: builtins.int + """The uint32 value.""" + def __init__( + self, + *, + value: builtins.int = ..., + ) -> None: ... + def ClearField(self, field_name: typing_extensions.Literal["value", b"value"]) -> None: ... + +global___UInt32Value = UInt32Value + +@typing_extensions.final +class BoolValue(google.protobuf.message.Message): + """Wrapper message for `bool`. + + The JSON representation for `BoolValue` is JSON `true` and `false`. + """ + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + VALUE_FIELD_NUMBER: builtins.int + value: builtins.bool + """The bool value.""" + def __init__( + self, + *, + value: builtins.bool = ..., + ) -> None: ... + def ClearField(self, field_name: typing_extensions.Literal["value", b"value"]) -> None: ... + +global___BoolValue = BoolValue + +@typing_extensions.final +class StringValue(google.protobuf.message.Message): + """Wrapper message for `string`. + + The JSON representation for `StringValue` is JSON string. + """ + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + VALUE_FIELD_NUMBER: builtins.int + value: builtins.str + """The string value.""" + def __init__( + self, + *, + value: builtins.str = ..., + ) -> None: ... + def ClearField(self, field_name: typing_extensions.Literal["value", b"value"]) -> None: ... + +global___StringValue = StringValue diff --git a/src/debug.c b/src/debug.c index 2877a8b3..a3f515a6 100644 --- a/src/debug.c +++ b/src/debug.c @@ -1,15 +1,14 @@ -#include "os.h" #include "debug.h" +#include "os.h" + // This symbol is defined by the link script to be at the start of the stack // area. extern unsigned long app_stack_canary; -#define STACK_CANARY (*((volatile uint32_t*) &app_stack_canary)) +#define STACK_CANARY (*((volatile uint32_t *)&app_stack_canary)) -void debug_init_stack_canary() { - STACK_CANARY = 0xDEADBEEF; -} +void debug_init_stack_canary() { STACK_CANARY = 0xDEADBEEF; } void debug_check_stack_canary() { if (STACK_CANARY != 0xDEADBEEF) { @@ -17,6 +16,4 @@ void debug_check_stack_canary() { } } -uint32_t debug_get_stack_canary() { - return STACK_CANARY; -} +uint32_t debug_get_stack_canary() { return STACK_CANARY; } diff --git a/src/get_app_configuration.c b/src/get_app_configuration.c index 9d63f358..6c784fd8 100644 --- a/src/get_app_configuration.c +++ b/src/get_app_configuration.c @@ -1,19 +1,14 @@ -#include - #include #include +#include #include "errors.h" #include "io.h" void handle_get_app_configuration( - uint8_t p1, - uint8_t p2, - const uint8_t* const buffer, - uint16_t len, - /* out */ volatile const unsigned int* const flags, - /* out */ volatile const unsigned int* const tx -) { + uint8_t p1, uint8_t p2, const uint8_t *const buffer, uint16_t len, + /* out */ volatile const unsigned int *const flags, + /* out */ volatile const unsigned int *const tx) { UNUSED(p1); UNUSED(p2); UNUSED(buffer); @@ -22,12 +17,12 @@ void handle_get_app_configuration( UNUSED(tx); // storage allowed? - G_io_apdu_buffer[0] = 0; + G_io_apdu_buffer[ 0 ] = 0; // version - G_io_apdu_buffer[1] = APPVERSION_M; - G_io_apdu_buffer[2] = APPVERSION_N; - G_io_apdu_buffer[3] = APPVERSION_P; + G_io_apdu_buffer[ 1 ] = APPVERSION_M; + G_io_apdu_buffer[ 2 ] = APPVERSION_N; + G_io_apdu_buffer[ 3 ] = APPVERSION_P; io_exchange_with_code(EXCEPTION_OK, 4); } diff --git a/src/get_public_key.c b/src/get_public_key.c index 4f28796d..b9c43829 100644 --- a/src/get_public_key.c +++ b/src/get_public_key.c @@ -1,46 +1,44 @@ +#include "get_public_key.h" + #include #include #include -#include "globals.h" -#include "printf.h" -#include "globals.h" #include "debug.h" #include "errors.h" +#include "globals.h" #include "handlers.h" #include "hedera.h" #include "io.h" -#include "utils.h" +#include "printf.h" #include "ui.h" -#include "get_public_key.h" +#include "utils.h" static struct get_public_key_context_t { uint32_t key_index; // Lines on the UI Screen - char ui_approve_l2[DISPLAY_SIZE + 1]; + char ui_approve_l2[ DISPLAY_SIZE + 1 ]; cx_ecfp_public_key_t public; // Public Key Compare uint8_t display_index; - uint8_t full_key[KEY_SIZE + 1]; - uint8_t partial_key[DISPLAY_SIZE + 1]; + uint8_t full_key[ KEY_SIZE + 1 ]; + uint8_t partial_key[ DISPLAY_SIZE + 1 ]; } ctx; #if defined(TARGET_NANOS) static const bagl_element_t ui_get_public_key_compare[] = { - UI_BACKGROUND(), - UI_ICON_LEFT(LEFT_ICON_ID, BAGL_GLYPH_ICON_LEFT), + UI_BACKGROUND(), UI_ICON_LEFT(LEFT_ICON_ID, BAGL_GLYPH_ICON_LEFT), UI_ICON_RIGHT(RIGHT_ICON_ID, BAGL_GLYPH_ICON_RIGHT), // <= => // Public Key // // UI_TEXT(LINE_1_ID, 0, 12, 128, "Public Key"), - UI_TEXT(LINE_2_ID, 0, 26, 128, ctx.partial_key) -}; + UI_TEXT(LINE_2_ID, 0, 26, 128, ctx.partial_key)}; static const bagl_element_t ui_get_public_key_approve[] = { UI_BACKGROUND(), @@ -55,17 +53,11 @@ static const bagl_element_t ui_get_public_key_approve[] = { }; void shift_partial_key() { - memmove( - ctx.partial_key, - ctx.full_key + ctx.display_index, - DISPLAY_SIZE - ); + memmove(ctx.partial_key, ctx.full_key + ctx.display_index, DISPLAY_SIZE); } static unsigned int ui_get_public_key_compare_button( - unsigned int button_mask, - unsigned int button_mask_counter -) { + unsigned int button_mask, unsigned int button_mask_counter) { UNUSED(button_mask_counter); switch (button_mask) { case BUTTON_LEFT: // Left @@ -76,7 +68,8 @@ static unsigned int ui_get_public_key_compare_button( break; case BUTTON_RIGHT: // Right case BUTTON_EVT_FAST | BUTTON_RIGHT: - if (ctx.display_index < KEY_SIZE - DISPLAY_SIZE) ctx.display_index++; + if (ctx.display_index < KEY_SIZE - DISPLAY_SIZE) + ctx.display_index++; shift_partial_key(); UX_REDISPLAY(); break; @@ -87,14 +80,12 @@ static unsigned int ui_get_public_key_compare_button( return 0; } -static const bagl_element_t* ui_prepro_get_public_key_compare( - const bagl_element_t* element -) { - if (element->component.userid == LEFT_ICON_ID - && ctx.display_index == 0) +static const bagl_element_t *ui_prepro_get_public_key_compare( + const bagl_element_t *element) { + if (element->component.userid == LEFT_ICON_ID && ctx.display_index == 0) return NULL; // Hide Left Arrow at Left Edge - if (element->component.userid == RIGHT_ICON_ID - && ctx.display_index == KEY_SIZE - DISPLAY_SIZE) + if (element->component.userid == RIGHT_ICON_ID && + ctx.display_index == KEY_SIZE - DISPLAY_SIZE) return NULL; // Hide Right Arrow at Right Edge return element; } @@ -102,22 +93,17 @@ static const bagl_element_t* ui_prepro_get_public_key_compare( void compare_pk() { // init partial key str from full str memmove(ctx.partial_key, ctx.full_key, DISPLAY_SIZE); - ctx.partial_key[DISPLAY_SIZE] = '\0'; - + ctx.partial_key[ DISPLAY_SIZE ] = '\0'; + // init display index ctx.display_index = 0; // Display compare with button mask - UX_DISPLAY( - ui_get_public_key_compare, - ui_prepro_get_public_key_compare - ); + UX_DISPLAY(ui_get_public_key_compare, ui_prepro_get_public_key_compare); } static unsigned int ui_get_public_key_approve_button( - unsigned int button_mask, - unsigned int button_mask_counter -) { + unsigned int button_mask, unsigned int button_mask_counter) { UNUSED(button_mask_counter); switch (button_mask) { case BUTTON_EVT_RELEASED | BUTTON_LEFT: // REJECT @@ -145,65 +131,30 @@ unsigned int io_seproxyhal_touch_pk_ok(const bagl_element_t *e) { } unsigned int io_seproxyhal_touch_pk_cancel(const bagl_element_t *e) { - io_exchange_with_code(EXCEPTION_USER_REJECTED, 0); - ui_idle(); - return 0; + io_exchange_with_code(EXCEPTION_USER_REJECTED, 0); + ui_idle(); + return 0; } -UX_STEP_NOCB( - ux_approve_pk_flow_1_step, - bn, - { - "Export Public", - ctx.ui_approve_l2 - } -); - -UX_STEP_VALID( - ux_approve_pk_flow_2_step, - pb, - io_seproxyhal_touch_pk_ok(NULL), - { - &C_icon_validate_14, - "Approve" - } -); - -UX_STEP_VALID( - ux_approve_pk_flow_3_step, - pb, - io_seproxyhal_touch_pk_cancel(NULL), - { - &C_icon_crossmark, - "Reject" - } -); - -UX_STEP_CB( - ux_compare_pk_flow_1_step, - bnnn_paging, - ui_idle(), - { - .title = "Public Key", - .text = (char*) ctx.full_key - } -); +UX_STEP_NOCB(ux_approve_pk_flow_1_step, bn, + {"Export Public", ctx.ui_approve_l2}); -UX_DEF( - ux_approve_pk_flow, - &ux_approve_pk_flow_1_step, - &ux_approve_pk_flow_2_step, - &ux_approve_pk_flow_3_step -); +UX_STEP_VALID(ux_approve_pk_flow_2_step, pb, io_seproxyhal_touch_pk_ok(NULL), + {&C_icon_validate_14, "Approve"}); -UX_DEF( - ux_compare_pk_flow, - &ux_compare_pk_flow_1_step -); +UX_STEP_VALID(ux_approve_pk_flow_3_step, pb, + io_seproxyhal_touch_pk_cancel(NULL), + {&C_icon_crossmark, "Reject"}); -void compare_pk() { - ux_flow_init(0, ux_compare_pk_flow, NULL); -} +UX_STEP_CB(ux_compare_pk_flow_1_step, bnnn_paging, ui_idle(), + {.title = "Public Key", .text = (char *)ctx.full_key}); + +UX_DEF(ux_approve_pk_flow, &ux_approve_pk_flow_1_step, + &ux_approve_pk_flow_2_step, &ux_approve_pk_flow_3_step); + +UX_DEF(ux_compare_pk_flow, &ux_compare_pk_flow_1_step); + +void compare_pk() { ux_flow_init(0, ux_compare_pk_flow, NULL); } #endif // TARGET @@ -216,17 +167,13 @@ void get_pk() { // Populate Key Hex String bin2hex(ctx.full_key, G_io_apdu_buffer, KEY_SIZE); - ctx.full_key[KEY_SIZE] = '\0'; + ctx.full_key[ KEY_SIZE ] = '\0'; } -void handle_get_public_key( - uint8_t p1, - uint8_t p2, - uint8_t* buffer, - uint16_t len, - /* out */ volatile unsigned int* flags, - /* out */ volatile unsigned int* tx -) { +void handle_get_public_key(uint8_t p1, uint8_t p2, uint8_t *buffer, + uint16_t len, + /* out */ volatile unsigned int *flags, + /* out */ volatile unsigned int *tx) { UNUSED(p2); UNUSED(len); UNUSED(tx); @@ -234,11 +181,12 @@ void handle_get_public_key( // Read Key Index ctx.key_index = U4LE(buffer, 0); - // If p1 != 0, silent mode, for use by apps that request the user's public key frequently - // Only do UI actions for p1 == 0 + // If p1 != 0, silent mode, for use by apps that request the user's public + // key frequently Only do UI actions for p1 == 0 if (p1 == 0) { // Complete "Export Public | Key #x?" - hedera_snprintf(ctx.ui_approve_l2, DISPLAY_SIZE, "Key #%u?", ctx.key_index); + hedera_snprintf(ctx.ui_approve_l2, DISPLAY_SIZE, "Key #%u?", + ctx.key_index); } // Populate context with PK diff --git a/src/get_public_key.h b/src/get_public_key.h index c208e64d..c92c2e8a 100644 --- a/src/get_public_key.h +++ b/src/get_public_key.h @@ -9,20 +9,15 @@ void compare_pk(); void shift_partial_key(); static unsigned int ui_get_public_key_compare_button( - unsigned int button_mask, - unsigned int button_mask_counter -); + unsigned int button_mask, unsigned int button_mask_counter); -static const bagl_element_t* ui_prepro_get_public_key_compare( - const bagl_element_t* element -); +static const bagl_element_t *ui_prepro_get_public_key_compare( + const bagl_element_t *element); void send_pk(); static unsigned int ui_get_public_key_approve_button( - unsigned int button_mask, - unsigned int button_mask_counter -); + unsigned int button_mask, unsigned int button_mask_counter); #elif defined(TARGET_NANOX) || defined(TARGET_NANOS2) diff --git a/src/handlers.h b/src/handlers.h index 7d9842d6..8b4db662 100644 --- a/src/handlers.h +++ b/src/handlers.h @@ -9,14 +9,9 @@ #define INS_GET_PUBLIC_KEY 0x02 #define INS_SIGN_TRANSACTION 0x04 -typedef void handler_fn_t( - uint8_t p1, - uint8_t p2, - uint8_t* buffer, - uint16_t len, - /* out */ volatile unsigned int* flags, - /* out */ volatile unsigned int* tx -); +typedef void handler_fn_t(uint8_t p1, uint8_t p2, uint8_t* buffer, uint16_t len, + /* out */ volatile unsigned int* flags, + /* out */ volatile unsigned int* tx); extern handler_fn_t handle_get_app_configuration; extern handler_fn_t handle_get_public_key; diff --git a/src/hedera.c b/src/hedera.c index 3def8c08..36236760 100644 --- a/src/hedera.c +++ b/src/hedera.c @@ -1,60 +1,40 @@ -#include +#include "hedera.h" + #include +#include #include + #include "globals.h" -#include "hedera.h" -bool hedera_derive_keypair( - uint32_t index, - /* out */ cx_ecfp_private_key_t* secret, - /* out */ cx_ecfp_public_key_t* public -) { - static uint8_t seed[32]; - static uint32_t path[5]; +bool hedera_derive_keypair(uint32_t index, + /* out */ cx_ecfp_private_key_t *secret, + /* out */ cx_ecfp_public_key_t *public) { + static uint8_t seed[ 32 ]; + static uint32_t path[ 5 ]; static cx_ecfp_private_key_t pk; - path[0] = 44 | 0x80000000; - path[1] = 3030 | 0x80000000; - path[2] = 0x80000000; - path[3] = 0x80000000; - path[4] = index | 0x80000000; - - os_perso_derive_node_bip32_seed_key( - HDW_ED25519_SLIP10, - CX_CURVE_Ed25519, - path, - 5, - seed, - NULL, - NULL, - 0 - ); - - if (CX_OK != cx_ecfp_init_private_key_no_throw( - CX_CURVE_Ed25519, - seed, - sizeof(seed), - &pk - )) { + path[ 0 ] = 44 | 0x80000000; + path[ 1 ] = 3030 | 0x80000000; + path[ 2 ] = 0x80000000; + path[ 3 ] = 0x80000000; + path[ 4 ] = index | 0x80000000; + + os_perso_derive_node_bip32_seed_key(HDW_ED25519_SLIP10, CX_CURVE_Ed25519, + path, 5, seed, NULL, NULL, 0); + + if (CX_OK != cx_ecfp_init_private_key_no_throw(CX_CURVE_Ed25519, seed, + sizeof(seed), &pk)) { return false; } if (public) { - if (CX_OK != cx_ecfp_init_public_key_no_throw( - CX_CURVE_Ed25519, - NULL, - 0, - public - )) { + if (CX_OK != cx_ecfp_init_public_key_no_throw(CX_CURVE_Ed25519, NULL, 0, + public)) { return false; } - if (CX_OK != cx_ecfp_generate_pair_no_throw( - CX_CURVE_Ed25519, - public, - &pk, - 1 - )) { + if (CX_OK != + cx_ecfp_generate_pair_no_throw(CX_CURVE_Ed25519, public, &pk, 1)) { return false; } } @@ -69,12 +49,8 @@ bool hedera_derive_keypair( return true; } -bool hedera_sign( - uint32_t index, - const uint8_t* tx, - uint8_t tx_len, - /* out */ uint8_t* result -) { +bool hedera_sign(uint32_t index, const uint8_t *tx, uint8_t tx_len, + /* out */ uint8_t *result) { static cx_ecfp_private_key_t pk; // Get Keys @@ -87,13 +63,13 @@ bool hedera_sign( // Claims to want Hashes, but other apps use the message itself // and complain that the documentation is wrong if (CX_OK != cx_eddsa_sign_no_throw( - &pk, // private key - CX_SHA512, // hashID - tx, // hash (really message) - tx_len, // hash length (really message length) - result, // signature - 64 // signature length - )) { + &pk, // private key + CX_SHA512, // hashID + tx, // hash (really message) + tx_len, // hash length (really message length) + result, // signature + 64 // signature length + )) { return false; } diff --git a/src/hedera.h b/src/hedera.h index 0800d9d0..984219d8 100644 --- a/src/hedera.h +++ b/src/hedera.h @@ -1,6 +1,7 @@ #ifndef LEDGER_HEDERA_HEDERA_H #define LEDGER_HEDERA_HEDERA_H 1 +#include #include // Forward declare to avoid including os.h in a header file @@ -9,18 +10,13 @@ struct cx_ecfp_256_private_key_s; extern bool hedera_derive_keypair( uint32_t index, - /* out */ struct cx_ecfp_256_private_key_s* secret, - /* out */ struct cx_ecfp_256_public_key_s* public -); + /* out */ struct cx_ecfp_256_private_key_s *secret, + /* out */ struct cx_ecfp_256_public_key_s *public); -extern bool hedera_sign( - uint32_t index, - const uint8_t* tx, - uint8_t tx_len, - /* out */ uint8_t* result -); +extern bool hedera_sign(uint32_t index, const uint8_t *tx, uint8_t tx_len, + /* out */ uint8_t *result); -extern char* hedera_format_tinybar(uint64_t tinybar); -extern char* hedera_format_amount(uint64_t amount, uint8_t decimals); +extern char *hedera_format_tinybar(uint64_t tinybar); +extern char *hedera_format_amount(uint64_t amount, uint8_t decimals); #endif // LEDGER_HEDERA_HEDERA_H diff --git a/src/hedera_format.c b/src/hedera_format.c index c4443948..a50dcaee 100644 --- a/src/hedera_format.c +++ b/src/hedera_format.c @@ -1,7 +1,7 @@ -#include - #include "hedera_format.h" +#include + char* hedera_format_tinybar(uint64_t tinybar) { return hedera_format_amount(tinybar, 8); } @@ -9,7 +9,7 @@ char* hedera_format_tinybar(uint64_t tinybar) { #define BUF_SIZE 32 char* hedera_format_amount(uint64_t amount, uint8_t decimals) { - static char buf[BUF_SIZE]; + static char buf[ BUF_SIZE ]; // NOTE: format of amounts are not sensitive memset(buf, 0, BUF_SIZE); @@ -17,8 +17,8 @@ char* hedera_format_amount(uint64_t amount, uint8_t decimals) { // Quick shortcut if the amount is zero // Regardless of decimals, the output is always "0" if (amount == 0) { - buf[0] = '0'; - buf[1] = '\0'; + buf[ 0 ] = '0'; + buf[ 1 ] = '\0'; return buf; } @@ -33,15 +33,15 @@ char* hedera_format_amount(uint64_t amount, uint8_t decimals) { int digit = amount % 10; amount /= 10; - buf[i++] = '0' + digit; + buf[ i++ ] = '0' + digit; if (i == decimals) { - buf[i++] = '.'; + buf[ i++ ] = '.'; } } - if (buf[i - 1] == '.') { - buf[i++] = '0'; + if (buf[ i - 1 ] == '.') { + buf[ i++ ] = '0'; } int size = i; @@ -51,17 +51,17 @@ char* hedera_format_amount(uint64_t amount, uint8_t decimals) { while (j < i) { i -= 1; - tmp = buf[j]; - buf[j] = buf[i]; - buf[i] = tmp; + tmp = buf[ j ]; + buf[ j ] = buf[ i ]; + buf[ i ] = tmp; j += 1; } for (j = size - 1; j > 0; j--) { - if (buf[j] == '0') { + if (buf[ j ] == '0') { continue; - } else if (buf[j] == '.') { + } else if (buf[ j ] == '.') { break; } else { j += 1; @@ -70,7 +70,7 @@ char* hedera_format_amount(uint64_t amount, uint8_t decimals) { } if (j < size - 1) { - buf[j] = '\0'; + buf[ j ] = '\0'; } return buf; diff --git a/src/hedera_format.h b/src/hedera_format.h index 06fb070a..18746c34 100644 --- a/src/hedera_format.h +++ b/src/hedera_format.h @@ -3,7 +3,7 @@ #include -extern char* hedera_format_tinybar(uint64_t tinybar); -extern char* hedera_format_amount(uint64_t amount, uint8_t decimals); +extern char *hedera_format_tinybar(uint64_t tinybar); +extern char *hedera_format_amount(uint64_t amount, uint8_t decimals); #endif // LEDGER_HEDERA_HEDERA_FORMAT_H diff --git a/src/io.c b/src/io.c index 1d164801..22b348c4 100644 --- a/src/io.c +++ b/src/io.c @@ -1,17 +1,17 @@ +#include "debug.h" #include "os.h" -#include "ux.h" #include "os_io_seproxyhal.h" -#include "debug.h" +#include "ux.h" // Everything below this point is Ledger magic. And the magic isn't well- // documented, so if you want to understand it, you'll need to read the // source, which you can find in the sdk repo for your device. // Fortunately, we are not meant to understand this. -unsigned char G_io_seproxyhal_spi_buffer[IO_SEPROXYHAL_BUFFER_SIZE_B]; +unsigned char G_io_seproxyhal_spi_buffer[ IO_SEPROXYHAL_BUFFER_SIZE_B ]; void io_seproxyhal_display(const bagl_element_t *element) { - io_seproxyhal_display_default((bagl_element_t*)element); + io_seproxyhal_display_default((bagl_element_t *)element); } unsigned char io_event(unsigned char channel) { @@ -21,7 +21,7 @@ unsigned char io_event(unsigned char channel) { debug_check_stack_canary(); // can't have more than one tag in the reply, not supported yet. - switch (G_io_seproxyhal_spi_buffer[0]) { + switch (G_io_seproxyhal_spi_buffer[ 0 ]) { case SEPROXYHAL_TAG_FINGER_EVENT: UX_FINGER_EVENT(G_io_seproxyhal_spi_buffer); break; @@ -31,7 +31,9 @@ unsigned char io_event(unsigned char channel) { break; case SEPROXYHAL_TAG_STATUS_EVENT: - if (G_io_apdu_media == IO_APDU_MEDIA_USB_HID && !(U4BE(G_io_seproxyhal_spi_buffer, 3) & SEPROXYHAL_TAG_STATUS_EVENT_FLAG_USB_POWERED)) { + if (G_io_apdu_media == IO_APDU_MEDIA_USB_HID && + !(U4BE(G_io_seproxyhal_spi_buffer, 3) & + SEPROXYHAL_TAG_STATUS_EVENT_FLAG_USB_POWERED)) { THROW(EXCEPTION_IO_RESET); } @@ -65,7 +67,8 @@ unsigned short io_exchange_al(unsigned char channel, unsigned short tx_len) { case CHANNEL_KEYBOARD: break; - // multiplexed io exchange over a SPI channel and TLV encapsulated protocol + // multiplexed io exchange over a SPI channel and TLV encapsulated + // protocol case CHANNEL_SPI: if (tx_len) { io_seproxyhal_spi_send(G_io_apdu_buffer, tx_len); @@ -74,10 +77,10 @@ unsigned short io_exchange_al(unsigned char channel, unsigned short tx_len) { reset(); } return 0; // nothing received from the master so far (it's a tx - // transaction) + // transaction) } else { return io_seproxyhal_spi_recv(G_io_apdu_buffer, - sizeof(G_io_apdu_buffer), 0); + sizeof(G_io_apdu_buffer), 0); } default: @@ -87,8 +90,8 @@ unsigned short io_exchange_al(unsigned char channel, unsigned short tx_len) { } void io_exchange_with_code(uint16_t code, uint16_t tx) { - G_io_apdu_buffer[tx++] = code >> 8; - G_io_apdu_buffer[tx++] = code & 0xff; + G_io_apdu_buffer[ tx++ ] = code >> 8; + G_io_apdu_buffer[ tx++ ] = code & 0xff; io_exchange(CHANNEL_APDU | IO_RETURN_AFTER_TX, tx); } diff --git a/src/io.h b/src/io.h index c983b93f..71754812 100644 --- a/src/io.h +++ b/src/io.h @@ -1,9 +1,9 @@ #ifndef LEDGER_HEDERA_IO_H #define LEDGER_HEDERA_IO_H 1 -#include #include #include +#include extern void io_exchange_with_code(uint16_t code, uint16_t tx); diff --git a/src/main.c b/src/main.c index f632ea12..3bdc008c 100644 --- a/src/main.c +++ b/src/main.c @@ -1,10 +1,10 @@ +#include "debug.h" #include "errors.h" +#include "globals.h" #include "handlers.h" -#include "ui.h" #include "io.h" +#include "ui.h" #include "utils.h" -#include "debug.h" -#include "globals.h" // This is the main loop that reads and writes APDUs. It receives request // APDUs from the computer, looks up the corresponding command handler, and @@ -28,7 +28,8 @@ void app_main() { BEGIN_TRY { TRY { rx = tx; - tx = 0; // ensure no race in catch_other if io_exchange throws an error + tx = 0; // ensure no race in catch_other if io_exchange throws + // an error rx = io_exchange(CHANNEL_APDU | flags, rx); flags = 0; @@ -38,55 +39,44 @@ void app_main() { } // malformed APDU - if (G_io_apdu_buffer[OFFSET_CLA] != CLA) { + if (G_io_apdu_buffer[ OFFSET_CLA ] != CLA) { THROW(EXCEPTION_MALFORMED_APDU); } // APDU handler functions defined in handlers - switch (G_io_apdu_buffer[OFFSET_INS]) { + switch (G_io_apdu_buffer[ OFFSET_INS ]) { case INS_GET_APP_CONFIGURATION: // handlers -> get_app_configuration handle_get_app_configuration( - G_io_apdu_buffer[OFFSET_P1], - G_io_apdu_buffer[OFFSET_P2], - G_io_apdu_buffer + OFFSET_CDATA, - G_io_apdu_buffer[OFFSET_LC], - &flags, - &tx - ); + G_io_apdu_buffer[ OFFSET_P1 ], + G_io_apdu_buffer[ OFFSET_P2 ], + G_io_apdu_buffer + OFFSET_CDATA, + G_io_apdu_buffer[ OFFSET_LC ], &flags, &tx); break; case INS_GET_PUBLIC_KEY: // handlers -> get_public_key - handle_get_public_key( - G_io_apdu_buffer[OFFSET_P1], - G_io_apdu_buffer[OFFSET_P2], - G_io_apdu_buffer + OFFSET_CDATA, - G_io_apdu_buffer[OFFSET_LC], - &flags, - &tx - ); + handle_get_public_key(G_io_apdu_buffer[ OFFSET_P1 ], + G_io_apdu_buffer[ OFFSET_P2 ], + G_io_apdu_buffer + OFFSET_CDATA, + G_io_apdu_buffer[ OFFSET_LC ], + &flags, &tx); break; case INS_SIGN_TRANSACTION: // handlers -> sign_transaction - handle_sign_transaction( - G_io_apdu_buffer[OFFSET_P1], - G_io_apdu_buffer[OFFSET_P2], - G_io_apdu_buffer + OFFSET_CDATA, - G_io_apdu_buffer[OFFSET_LC], - &flags, - &tx - ); + handle_sign_transaction(G_io_apdu_buffer[ OFFSET_P1 ], + G_io_apdu_buffer[ OFFSET_P2 ], + G_io_apdu_buffer + OFFSET_CDATA, + G_io_apdu_buffer[ OFFSET_LC ], + &flags, &tx); break; - default: + default: THROW(EXCEPTION_UNKNOWN_INS); } } - CATCH(EXCEPTION_IO_RESET) { - THROW(EXCEPTION_IO_RESET); - } + CATCH(EXCEPTION_IO_RESET) { THROW(EXCEPTION_IO_RESET); } CATCH_OTHER(e) { // Convert exception to response code and add to APDU return switch (e & 0xF000) { @@ -100,8 +90,8 @@ void app_main() { break; } - G_io_apdu_buffer[tx++] = sw >> 8; - G_io_apdu_buffer[tx++] = sw & 0xff; + G_io_apdu_buffer[ tx++ ] = sw >> 8; + G_io_apdu_buffer[ tx++ ] = sw & 0xff; } FINALLY { // explicitly do nothing @@ -114,9 +104,7 @@ void app_main() { void app_exit(void) { // All os calls must be wrapped in a try catch context BEGIN_TRY_L(exit) { - TRY_L(exit) { - os_sched_exit(-1); - } + TRY_L(exit) { os_sched_exit(-1); } FINALLY_L(exit) { // explicitly do nothing } @@ -139,13 +127,14 @@ __attribute__((section(".boot"))) int main() { BEGIN_TRY { TRY { - // Initialize the hardware abstraction layer (HAL) in + // Initialize the hardware abstraction layer (HAL) in // the Ledger SDK io_seproxyhal_init(); #ifdef TARGET_NANOX // grab the current plane mode setting - G_io_app.plane_mode = os_setting_get(OS_SETTING_PLANEMODE, NULL, 0); + G_io_app.plane_mode = + os_setting_get(OS_SETTING_PLANEMODE, NULL, 0); #endif // TARGET_NANOX #ifdef HAVE_BLE @@ -166,9 +155,7 @@ __attribute__((section(".boot"))) int main() { // reset IO and UX before continuing continue; } - CATCH_ALL { - break; - } + CATCH_ALL { break; } FINALLY { // explicitly do nothing } diff --git a/src/printf.c b/src/printf.c index 285615dd..6a43da10 100644 --- a/src/printf.c +++ b/src/printf.c @@ -22,19 +22,19 @@ // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. // -// \brief Tiny printf, sprintf and (v)snprintf implementation, optimized for speed on -// embedded systems with a very limited resources. These routines are thread -// safe and reentrant! -// Use this instead of the bloated standard/newlib printf cause these use -// malloc for printf (and may not be thread safe). +// \brief Tiny printf, sprintf and (v)snprintf implementation, optimized for +// speed on +// embedded systems with a very limited resources. These routines are +// thread safe and reentrant! Use this instead of the bloated +// standard/newlib printf cause these use malloc for printf (and may not +// be thread safe). // /////////////////////////////////////////////////////////////////////////////// -#include -#include - #include "printf.h" +#include +#include // define this globally (e.g. gcc -DPRINTF_INCLUDE_CONFIG_H ...) to include the // printf_config.h header file @@ -43,19 +43,18 @@ #include "printf_config.h" #endif - // 'ntoa' conversion buffer size, this must be big enough to hold one converted // numeric number including padded zeros (dynamically created on stack) // default: 32 byte #ifndef PRINTF_NTOA_BUFFER_SIZE -#define PRINTF_NTOA_BUFFER_SIZE 32U +#define PRINTF_NTOA_BUFFER_SIZE 32U #endif // 'ftoa' conversion buffer size, this must be big enough to hold one converted // float number including padded zeros (dynamically created on stack) // default: 32 byte #ifndef PRINTF_FTOA_BUFFER_SIZE -#define PRINTF_FTOA_BUFFER_SIZE 32U +#define PRINTF_FTOA_BUFFER_SIZE 32U #endif // support for the floating point type (%f) @@ -73,13 +72,13 @@ // define the default floating point precision // default: 6 digits #ifndef PRINTF_DEFAULT_FLOAT_PRECISION -#define PRINTF_DEFAULT_FLOAT_PRECISION 6U +#define PRINTF_DEFAULT_FLOAT_PRECISION 6U #endif // define the largest float suitable to print with %f // default: 1e9 #ifndef PRINTF_MAX_FLOAT -#define PRINTF_MAX_FLOAT 1e9 +#define PRINTF_MAX_FLOAT 1e9 #endif // support for the long long types (%llu or %p) @@ -98,817 +97,872 @@ /////////////////////////////////////////////////////////////////////////////// // internal flag definitions -#define FLAGS_ZEROPAD (1U << 0U) -#define FLAGS_LEFT (1U << 1U) -#define FLAGS_PLUS (1U << 2U) -#define FLAGS_SPACE (1U << 3U) -#define FLAGS_HASH (1U << 4U) -#define FLAGS_UPPERCASE (1U << 5U) -#define FLAGS_CHAR (1U << 6U) -#define FLAGS_SHORT (1U << 7U) -#define FLAGS_LONG (1U << 8U) -#define FLAGS_LONG_LONG (1U << 9U) +#define FLAGS_ZEROPAD (1U << 0U) +#define FLAGS_LEFT (1U << 1U) +#define FLAGS_PLUS (1U << 2U) +#define FLAGS_SPACE (1U << 3U) +#define FLAGS_HASH (1U << 4U) +#define FLAGS_UPPERCASE (1U << 5U) +#define FLAGS_CHAR (1U << 6U) +#define FLAGS_SHORT (1U << 7U) +#define FLAGS_LONG (1U << 8U) +#define FLAGS_LONG_LONG (1U << 9U) #define FLAGS_PRECISION (1U << 10U) #define FLAGS_ADAPT_EXP (1U << 11U) - // import float.h for DBL_MAX #if defined(PRINTF_SUPPORT_FLOAT) #include #endif - // output function type -typedef void (*out_fct_type)(char character, void* buffer, size_t idx, size_t maxlen); - +typedef void (*out_fct_type)(char character, void* buffer, size_t idx, + size_t maxlen); // wrapper (used as buffer) for output function type typedef struct { - void (*fct)(char character, void* arg); - void* arg; + void (*fct)(char character, void* arg); + void* arg; } out_fct_wrap_type; - // internal buffer output -static inline void _out_buffer(char character, void* buffer, size_t idx, size_t maxlen) -{ - if (idx < maxlen) { - ((char*)buffer)[idx] = character; - } +static inline void _out_buffer(char character, void* buffer, size_t idx, + size_t maxlen) { + if (idx < maxlen) { + ((char*)buffer)[ idx ] = character; + } } - // internal null output -static inline void _out_null(char character, void* buffer, size_t idx, size_t maxlen) -{ - (void)character; (void)buffer; (void)idx; (void)maxlen; +static inline void _out_null(char character, void* buffer, size_t idx, + size_t maxlen) { + (void)character; + (void)buffer; + (void)idx; + (void)maxlen; } - // internal _putchar wrapper -static inline void _out_char(char character, void* buffer, size_t idx, size_t maxlen) -{ - (void)buffer; (void)idx; (void)maxlen; - if (character) { - _putchar(character); - } +static inline void _out_char(char character, void* buffer, size_t idx, + size_t maxlen) { + (void)buffer; + (void)idx; + (void)maxlen; + if (character) { + _putchar(character); + } } - // internal output function wrapper -static inline void _out_fct(char character, void* buffer, size_t idx, size_t maxlen) -{ - (void)idx; (void)maxlen; - if (character) { - // buffer is the output fct pointer - ((out_fct_wrap_type*)buffer)->fct(character, ((out_fct_wrap_type*)buffer)->arg); - } +static inline void _out_fct(char character, void* buffer, size_t idx, + size_t maxlen) { + (void)idx; + (void)maxlen; + if (character) { + // buffer is the output fct pointer + ((out_fct_wrap_type*)buffer) + ->fct(character, ((out_fct_wrap_type*)buffer)->arg); + } } - // internal secure strlen -// \return The length of the string (excluding the terminating 0) limited by 'maxsize' -static inline unsigned int _strnlen_s(const char* str, size_t maxsize) -{ - const char* s; - for (s = str; *s && maxsize--; ++s); - return (unsigned int)(s - str); +// \return The length of the string (excluding the terminating 0) limited by +// 'maxsize' +static inline unsigned int _strnlen_s(const char* str, size_t maxsize) { + const char* s; + for (s = str; *s && maxsize--; ++s) + ; + return (unsigned int)(s - str); } - // internal test if char is a digit (0-9) // \return true if char is a digit -static inline bool _is_digit(char ch) -{ - return (ch >= '0') && (ch <= '9'); -} - +static inline bool _is_digit(char ch) { return (ch >= '0') && (ch <= '9'); } // internal ASCII string to unsigned int conversion -static unsigned int _atoi(const char** str) -{ - unsigned int i = 0U; - while (_is_digit(**str)) { - i = i * 10U + (unsigned int)(*((*str)++) - '0'); - } - return i; +static unsigned int _atoi(const char** str) { + unsigned int i = 0U; + while (_is_digit(**str)) { + i = i * 10U + (unsigned int)(*((*str)++) - '0'); + } + return i; } - // output the specified string in reverse, taking care of any zero-padding -static size_t _out_rev(out_fct_type out, char* buffer, size_t idx, size_t maxlen, const char* buf, size_t len, unsigned int width, unsigned int flags) -{ - const size_t start_idx = idx; - - // pad spaces up to given width - if (!(flags & FLAGS_LEFT) && !(flags & FLAGS_ZEROPAD)) { - for (size_t i = len; i < width; i++) { - out(' ', buffer, idx++, maxlen); +static size_t _out_rev(out_fct_type out, char* buffer, size_t idx, + size_t maxlen, const char* buf, size_t len, + unsigned int width, unsigned int flags) { + const size_t start_idx = idx; + + // pad spaces up to given width + if (!(flags & FLAGS_LEFT) && !(flags & FLAGS_ZEROPAD)) { + for (size_t i = len; i < width; i++) { + out(' ', buffer, idx++, maxlen); + } } - } - // reverse string - while (len) { - out(buf[--len], buffer, idx++, maxlen); - } + // reverse string + while (len) { + out(buf[ --len ], buffer, idx++, maxlen); + } - // append pad spaces up to given width - if (flags & FLAGS_LEFT) { - while (idx - start_idx < width) { - out(' ', buffer, idx++, maxlen); + // append pad spaces up to given width + if (flags & FLAGS_LEFT) { + while (idx - start_idx < width) { + out(' ', buffer, idx++, maxlen); + } } - } - return idx; + return idx; } - // internal itoa format -static size_t _ntoa_format(out_fct_type out, char* buffer, size_t idx, size_t maxlen, char* buf, size_t len, bool negative, unsigned int base, unsigned int prec, unsigned int width, unsigned int flags) -{ - // pad leading zeros - if (!(flags & FLAGS_LEFT)) { - if (width && (flags & FLAGS_ZEROPAD) && (negative || (flags & (FLAGS_PLUS | FLAGS_SPACE)))) { - width--; - } - while ((len < prec) && (len < PRINTF_NTOA_BUFFER_SIZE)) { - buf[len++] = '0'; - } - while ((flags & FLAGS_ZEROPAD) && (len < width) && (len < PRINTF_NTOA_BUFFER_SIZE)) { - buf[len++] = '0'; +static size_t _ntoa_format(out_fct_type out, char* buffer, size_t idx, + size_t maxlen, char* buf, size_t len, bool negative, + unsigned int base, unsigned int prec, + unsigned int width, unsigned int flags) { + // pad leading zeros + if (!(flags & FLAGS_LEFT)) { + if (width && (flags & FLAGS_ZEROPAD) && + (negative || (flags & (FLAGS_PLUS | FLAGS_SPACE)))) { + width--; + } + while ((len < prec) && (len < PRINTF_NTOA_BUFFER_SIZE)) { + buf[ len++ ] = '0'; + } + while ((flags & FLAGS_ZEROPAD) && (len < width) && + (len < PRINTF_NTOA_BUFFER_SIZE)) { + buf[ len++ ] = '0'; + } } - } - // handle hash - if (flags & FLAGS_HASH) { - if (!(flags & FLAGS_PRECISION) && len && ((len == prec) || (len == width))) { - len--; - if (len && (base == 16U)) { - len--; - } - } - if ((base == 16U) && !(flags & FLAGS_UPPERCASE) && (len < PRINTF_NTOA_BUFFER_SIZE)) { - buf[len++] = 'x'; - } - else if ((base == 16U) && (flags & FLAGS_UPPERCASE) && (len < PRINTF_NTOA_BUFFER_SIZE)) { - buf[len++] = 'X'; - } - else if ((base == 2U) && (len < PRINTF_NTOA_BUFFER_SIZE)) { - buf[len++] = 'b'; - } - if (len < PRINTF_NTOA_BUFFER_SIZE) { - buf[len++] = '0'; + // handle hash + if (flags & FLAGS_HASH) { + if (!(flags & FLAGS_PRECISION) && len && + ((len == prec) || (len == width))) { + len--; + if (len && (base == 16U)) { + len--; + } + } + if ((base == 16U) && !(flags & FLAGS_UPPERCASE) && + (len < PRINTF_NTOA_BUFFER_SIZE)) { + buf[ len++ ] = 'x'; + } else if ((base == 16U) && (flags & FLAGS_UPPERCASE) && + (len < PRINTF_NTOA_BUFFER_SIZE)) { + buf[ len++ ] = 'X'; + } else if ((base == 2U) && (len < PRINTF_NTOA_BUFFER_SIZE)) { + buf[ len++ ] = 'b'; + } + if (len < PRINTF_NTOA_BUFFER_SIZE) { + buf[ len++ ] = '0'; + } } - } - if (len < PRINTF_NTOA_BUFFER_SIZE) { - if (negative) { - buf[len++] = '-'; - } - else if (flags & FLAGS_PLUS) { - buf[len++] = '+'; // ignore the space if the '+' exists - } - else if (flags & FLAGS_SPACE) { - buf[len++] = ' '; + if (len < PRINTF_NTOA_BUFFER_SIZE) { + if (negative) { + buf[ len++ ] = '-'; + } else if (flags & FLAGS_PLUS) { + buf[ len++ ] = '+'; // ignore the space if the '+' exists + } else if (flags & FLAGS_SPACE) { + buf[ len++ ] = ' '; + } } - } - return _out_rev(out, buffer, idx, maxlen, buf, len, width, flags); + return _out_rev(out, buffer, idx, maxlen, buf, len, width, flags); } - // internal itoa for 'long' type -static size_t _ntoa_long(out_fct_type out, char* buffer, size_t idx, size_t maxlen, unsigned long value, bool negative, unsigned long base, unsigned int prec, unsigned int width, unsigned int flags) -{ - char buf[PRINTF_NTOA_BUFFER_SIZE]; - size_t len = 0U; - - // no hash for 0 values - if (!value) { - flags &= ~FLAGS_HASH; - } - - // write if precision != 0 and value is != 0 - if (!(flags & FLAGS_PRECISION) || value) { - do { - const char digit = (char)(value % base); - buf[len++] = digit < 10 ? '0' + digit : (flags & FLAGS_UPPERCASE ? 'A' : 'a') + digit - 10; - value /= base; - } while (value && (len < PRINTF_NTOA_BUFFER_SIZE)); - } - - return _ntoa_format(out, buffer, idx, maxlen, buf, len, negative, (unsigned int)base, prec, width, flags); +static size_t _ntoa_long(out_fct_type out, char* buffer, size_t idx, + size_t maxlen, unsigned long value, bool negative, + unsigned long base, unsigned int prec, + unsigned int width, unsigned int flags) { + char buf[ PRINTF_NTOA_BUFFER_SIZE ]; + size_t len = 0U; + + // no hash for 0 values + if (!value) { + flags &= ~FLAGS_HASH; + } + + // write if precision != 0 and value is != 0 + if (!(flags & FLAGS_PRECISION) || value) { + do { + const char digit = (char)(value % base); + buf[ len++ ] = + digit < 10 ? '0' + digit + : (flags & FLAGS_UPPERCASE ? 'A' : 'a') + digit - 10; + value /= base; + } while (value && (len < PRINTF_NTOA_BUFFER_SIZE)); + } + + return _ntoa_format(out, buffer, idx, maxlen, buf, len, negative, + (unsigned int)base, prec, width, flags); } - // internal itoa for 'long long' type #if defined(PRINTF_SUPPORT_LONG_LONG) -static size_t _ntoa_long_long(out_fct_type out, char* buffer, size_t idx, size_t maxlen, unsigned long long value, bool negative, unsigned long long base, unsigned int prec, unsigned int width, unsigned int flags) -{ - char buf[PRINTF_NTOA_BUFFER_SIZE]; - size_t len = 0U; - - // no hash for 0 values - if (!value) { - flags &= ~FLAGS_HASH; - } - - // write if precision != 0 and value is != 0 - if (!(flags & FLAGS_PRECISION) || value) { - do { - const char digit = (char)(value % base); - buf[len++] = digit < 10 ? '0' + digit : (flags & FLAGS_UPPERCASE ? 'A' : 'a') + digit - 10; - value /= base; - } while (value && (len < PRINTF_NTOA_BUFFER_SIZE)); - } - - return _ntoa_format(out, buffer, idx, maxlen, buf, len, negative, (unsigned int)base, prec, width, flags); +static size_t _ntoa_long_long(out_fct_type out, char* buffer, size_t idx, + size_t maxlen, unsigned long long value, + bool negative, unsigned long long base, + unsigned int prec, unsigned int width, + unsigned int flags) { + char buf[ PRINTF_NTOA_BUFFER_SIZE ]; + size_t len = 0U; + + // no hash for 0 values + if (!value) { + flags &= ~FLAGS_HASH; + } + + // write if precision != 0 and value is != 0 + if (!(flags & FLAGS_PRECISION) || value) { + do { + const char digit = (char)(value % base); + buf[ len++ ] = + digit < 10 ? '0' + digit + : (flags & FLAGS_UPPERCASE ? 'A' : 'a') + digit - 10; + value /= base; + } while (value && (len < PRINTF_NTOA_BUFFER_SIZE)); + } + + return _ntoa_format(out, buffer, idx, maxlen, buf, len, negative, + (unsigned int)base, prec, width, flags); } -#endif // PRINTF_SUPPORT_LONG_LONG - +#endif // PRINTF_SUPPORT_LONG_LONG #if defined(PRINTF_SUPPORT_FLOAT) #if defined(PRINTF_SUPPORT_EXPONENTIAL) -// forward declaration so that _ftoa can switch to exp notation for values > PRINTF_MAX_FLOAT -static size_t _etoa(out_fct_type out, char* buffer, size_t idx, size_t maxlen, double value, unsigned int prec, unsigned int width, unsigned int flags); +// forward declaration so that _ftoa can switch to exp notation for values > +// PRINTF_MAX_FLOAT +static size_t _etoa(out_fct_type out, char* buffer, size_t idx, size_t maxlen, + double value, unsigned int prec, unsigned int width, + unsigned int flags); #endif - // internal ftoa for fixed decimal floating point -static size_t _ftoa(out_fct_type out, char* buffer, size_t idx, size_t maxlen, double value, unsigned int prec, unsigned int width, unsigned int flags) -{ - char buf[PRINTF_FTOA_BUFFER_SIZE]; - size_t len = 0U; - double diff = 0.0; - - // powers of 10 - static const double pow10[] = { 1, 10, 100, 1000, 10000, 100000, 1000000, 10000000, 100000000, 1000000000 }; - - // test for special values - if (value != value) - return _out_rev(out, buffer, idx, maxlen, "nan", 3, width, flags); - if (value < -DBL_MAX) - return _out_rev(out, buffer, idx, maxlen, "fni-", 4, width, flags); - if (value > DBL_MAX) - return _out_rev(out, buffer, idx, maxlen, (flags & FLAGS_PLUS) ? "fni+" : "fni", (flags & FLAGS_PLUS) ? 4U : 3U, width, flags); - - // test for very large values - // standard printf behavior is to print EVERY whole number digit -- which could be 100s of characters overflowing your buffers == bad - if ((value > PRINTF_MAX_FLOAT) || (value < -PRINTF_MAX_FLOAT)) { +static size_t _ftoa(out_fct_type out, char* buffer, size_t idx, size_t maxlen, + double value, unsigned int prec, unsigned int width, + unsigned int flags) { + char buf[ PRINTF_FTOA_BUFFER_SIZE ]; + size_t len = 0U; + double diff = 0.0; + + // powers of 10 + static const double pow10[] = {1, 10, 100, 1000, + 10000, 100000, 1000000, 10000000, + 100000000, 1000000000}; + + // test for special values + if (value != value) + return _out_rev(out, buffer, idx, maxlen, "nan", 3, width, flags); + if (value < -DBL_MAX) + return _out_rev(out, buffer, idx, maxlen, "fni-", 4, width, flags); + if (value > DBL_MAX) + return _out_rev(out, buffer, idx, maxlen, + (flags & FLAGS_PLUS) ? "fni+" : "fni", + (flags & FLAGS_PLUS) ? 4U : 3U, width, flags); + + // test for very large values + // standard printf behavior is to print EVERY whole number digit -- which + // could be 100s of characters overflowing your buffers == bad + if ((value > PRINTF_MAX_FLOAT) || (value < -PRINTF_MAX_FLOAT)) { #if defined(PRINTF_SUPPORT_EXPONENTIAL) - return _etoa(out, buffer, idx, maxlen, value, prec, width, flags); + return _etoa(out, buffer, idx, maxlen, value, prec, width, flags); #else - return 0U; + return 0U; #endif - } - - // test for negative - bool negative = false; - if (value < 0) { - negative = true; - value = 0 - value; - } - - // set default precision, if not set explicitly - if (!(flags & FLAGS_PRECISION)) { - prec = PRINTF_DEFAULT_FLOAT_PRECISION; - } - // limit precision to 9, cause a prec >= 10 can lead to overflow errors - while ((len < PRINTF_FTOA_BUFFER_SIZE) && (prec > 9U)) { - buf[len++] = '0'; - prec--; - } - - int whole = (int)value; - double tmp = (value - whole) * pow10[prec]; - unsigned long frac = (unsigned long)tmp; - diff = tmp - frac; - - if (diff > 0.5) { - ++frac; - // handle rollover, e.g. case 0.99 with prec 1 is 1.0 - if (frac >= pow10[prec]) { - frac = 0; - ++whole; - } - } - else if (diff < 0.5) { - } - else if ((frac == 0U) || (frac & 1U)) { - // if halfway, round up if odd OR if last digit is 0 - ++frac; - } - - if (prec == 0U) { - diff = value - (double)whole; - if ((!(diff < 0.5) || (diff > 0.5)) && (whole & 1)) { - // exactly 0.5 and ODD, then round up - // 1.5 -> 2, but 2.5 -> 2 - ++whole; - } - } - else { - unsigned int count = prec; - // now do fractional part, as an unsigned number - while (len < PRINTF_FTOA_BUFFER_SIZE) { - --count; - buf[len++] = (char)(48U + (frac % 10U)); - if (!(frac /= 10U)) { - break; - } - } - // add extra 0s - while ((len < PRINTF_FTOA_BUFFER_SIZE) && (count-- > 0U)) { - buf[len++] = '0'; - } - if (len < PRINTF_FTOA_BUFFER_SIZE) { - // add decimal - buf[len++] = '.'; } - } - // do whole part, number is reversed - while (len < PRINTF_FTOA_BUFFER_SIZE) { - buf[len++] = (char)(48 + (whole % 10)); - if (!(whole /= 10)) { - break; + // test for negative + bool negative = false; + if (value < 0) { + negative = true; + value = 0 - value; } - } - // pad leading zeros - if (!(flags & FLAGS_LEFT) && (flags & FLAGS_ZEROPAD)) { - if (width && (negative || (flags & (FLAGS_PLUS | FLAGS_SPACE)))) { - width--; + // set default precision, if not set explicitly + if (!(flags & FLAGS_PRECISION)) { + prec = PRINTF_DEFAULT_FLOAT_PRECISION; } - while ((len < width) && (len < PRINTF_FTOA_BUFFER_SIZE)) { - buf[len++] = '0'; + // limit precision to 9, cause a prec >= 10 can lead to overflow errors + while ((len < PRINTF_FTOA_BUFFER_SIZE) && (prec > 9U)) { + buf[ len++ ] = '0'; + prec--; } - } - if (len < PRINTF_FTOA_BUFFER_SIZE) { - if (negative) { - buf[len++] = '-'; + int whole = (int)value; + double tmp = (value - whole) * pow10[ prec ]; + unsigned long frac = (unsigned long)tmp; + diff = tmp - frac; + + if (diff > 0.5) { + ++frac; + // handle rollover, e.g. case 0.99 with prec 1 is 1.0 + if (frac >= pow10[ prec ]) { + frac = 0; + ++whole; + } + } else if (diff < 0.5) { + } else if ((frac == 0U) || (frac & 1U)) { + // if halfway, round up if odd OR if last digit is 0 + ++frac; + } + + if (prec == 0U) { + diff = value - (double)whole; + if ((!(diff < 0.5) || (diff > 0.5)) && (whole & 1)) { + // exactly 0.5 and ODD, then round up + // 1.5 -> 2, but 2.5 -> 2 + ++whole; + } + } else { + unsigned int count = prec; + // now do fractional part, as an unsigned number + while (len < PRINTF_FTOA_BUFFER_SIZE) { + --count; + buf[ len++ ] = (char)(48U + (frac % 10U)); + if (!(frac /= 10U)) { + break; + } + } + // add extra 0s + while ((len < PRINTF_FTOA_BUFFER_SIZE) && (count-- > 0U)) { + buf[ len++ ] = '0'; + } + if (len < PRINTF_FTOA_BUFFER_SIZE) { + // add decimal + buf[ len++ ] = '.'; + } } - else if (flags & FLAGS_PLUS) { - buf[len++] = '+'; // ignore the space if the '+' exists + + // do whole part, number is reversed + while (len < PRINTF_FTOA_BUFFER_SIZE) { + buf[ len++ ] = (char)(48 + (whole % 10)); + if (!(whole /= 10)) { + break; + } } - else if (flags & FLAGS_SPACE) { - buf[len++] = ' '; + + // pad leading zeros + if (!(flags & FLAGS_LEFT) && (flags & FLAGS_ZEROPAD)) { + if (width && (negative || (flags & (FLAGS_PLUS | FLAGS_SPACE)))) { + width--; + } + while ((len < width) && (len < PRINTF_FTOA_BUFFER_SIZE)) { + buf[ len++ ] = '0'; + } } - } - return _out_rev(out, buffer, idx, maxlen, buf, len, width, flags); -} + if (len < PRINTF_FTOA_BUFFER_SIZE) { + if (negative) { + buf[ len++ ] = '-'; + } else if (flags & FLAGS_PLUS) { + buf[ len++ ] = '+'; // ignore the space if the '+' exists + } else if (flags & FLAGS_SPACE) { + buf[ len++ ] = ' '; + } + } + return _out_rev(out, buffer, idx, maxlen, buf, len, width, flags); +} #if defined(PRINTF_SUPPORT_EXPONENTIAL) -// internal ftoa variant for exponential floating-point type, contributed by Martijn Jasperse -static size_t _etoa(out_fct_type out, char* buffer, size_t idx, size_t maxlen, double value, unsigned int prec, unsigned int width, unsigned int flags) -{ - // check for NaN and special values - if ((value != value) || (value > DBL_MAX) || (value < -DBL_MAX)) { - return _ftoa(out, buffer, idx, maxlen, value, prec, width, flags); - } - - // determine the sign - const bool negative = value < 0; - if (negative) { - value = -value; - } - - // default precision - if (!(flags & FLAGS_PRECISION)) { - prec = PRINTF_DEFAULT_FLOAT_PRECISION; - } - - // determine the decimal exponent - // based on the algorithm by David Gay (https://www.ampl.com/netlib/fp/dtoa.c) - union { - uint64_t U; - double F; - } conv; - - conv.F = value; - int exp2 = (int)((conv.U >> 52U) & 0x07FFU) - 1023; // effectively log2 - conv.U = (conv.U & ((1ULL << 52U) - 1U)) | (1023ULL << 52U); // drop the exponent so conv.F is now in [1,2) - // now approximate log10 from the log2 integer part and an expansion of ln around 1.5 - int expval = (int)(0.1760912590558 + exp2 * 0.301029995663981 + (conv.F - 1.5) * 0.289529654602168); - // now we want to compute 10^expval but we want to be sure it won't overflow - exp2 = (int)(expval * 3.321928094887362 + 0.5); - const double z = expval * 2.302585092994046 - exp2 * 0.6931471805599453; - const double z2 = z * z; - conv.U = (uint64_t)(exp2 + 1023) << 52U; - // compute exp(z) using continued fractions, see https://en.wikipedia.org/wiki/Exponential_function#Continued_fractions_for_ex - conv.F *= 1 + 2 * z / (2 - z + (z2 / (6 + (z2 / (10 + z2 / 14))))); - // correct for rounding errors - if (value < conv.F) { - expval--; - conv.F /= 10; - } - - // the exponent format is "%+03d" and largest value is "307", so set aside 4-5 characters - unsigned int minwidth = ((expval < 100) && (expval > -100)) ? 4U : 5U; - - // in "%g" mode, "prec" is the number of *significant figures* not decimals - if (flags & FLAGS_ADAPT_EXP) { - // do we want to fall-back to "%f" mode? - if ((value >= 1e-4) && (value < 1e6)) { - if ((int)prec > expval) { - prec = (unsigned)((int)prec - expval - 1); - } - else { - prec = 0; - } - flags |= FLAGS_PRECISION; // make sure _ftoa respects precision - // no characters in exponent - minwidth = 0U; - expval = 0; - } - else { - // we use one sigfig for the whole part - if ((prec > 0) && (flags & FLAGS_PRECISION)) { - --prec; - } - } - } - - // will everything fit? - unsigned int fwidth = width; - if (width > minwidth) { - // we didn't fall-back so subtract the characters required for the exponent - fwidth -= minwidth; - } else { - // not enough characters, so go back to default sizing - fwidth = 0U; - } - if ((flags & FLAGS_LEFT) && minwidth) { - // if we're padding on the right, DON'T pad the floating part - fwidth = 0U; - } - - // rescale the float value - if (expval) { - value /= conv.F; - } - - // output the floating part - const size_t start_idx = idx; - idx = _ftoa(out, buffer, idx, maxlen, negative ? -value : value, prec, fwidth, flags & ~FLAGS_ADAPT_EXP); - - // output the exponent part - if (minwidth) { - // output the exponential symbol - out((flags & FLAGS_UPPERCASE) ? 'E' : 'e', buffer, idx++, maxlen); - // output the exponent value - idx = _ntoa_long(out, buffer, idx, maxlen, (expval < 0) ? -expval : expval, expval < 0, 10, 0, minwidth-1, FLAGS_ZEROPAD | FLAGS_PLUS); - // might need to right-pad spaces - if (flags & FLAGS_LEFT) { - while (idx - start_idx < width) out(' ', buffer, idx++, maxlen); +// internal ftoa variant for exponential floating-point type, contributed by +// Martijn Jasperse +static size_t _etoa(out_fct_type out, char* buffer, size_t idx, size_t maxlen, + double value, unsigned int prec, unsigned int width, + unsigned int flags) { + // check for NaN and special values + if ((value != value) || (value > DBL_MAX) || (value < -DBL_MAX)) { + return _ftoa(out, buffer, idx, maxlen, value, prec, width, flags); + } + + // determine the sign + const bool negative = value < 0; + if (negative) { + value = -value; + } + + // default precision + if (!(flags & FLAGS_PRECISION)) { + prec = PRINTF_DEFAULT_FLOAT_PRECISION; + } + + // determine the decimal exponent + // based on the algorithm by David Gay + // (https://www.ampl.com/netlib/fp/dtoa.c) + union { + uint64_t U; + double F; + } conv; + + conv.F = value; + int exp2 = (int)((conv.U >> 52U) & 0x07FFU) - 1023; // effectively log2 + conv.U = (conv.U & ((1ULL << 52U) - 1U)) | + (1023ULL << 52U); // drop the exponent so conv.F is now in [1,2) + // now approximate log10 from the log2 integer part and an expansion of ln + // around 1.5 + int expval = (int)(0.1760912590558 + exp2 * 0.301029995663981 + + (conv.F - 1.5) * 0.289529654602168); + // now we want to compute 10^expval but we want to be sure it won't overflow + exp2 = (int)(expval * 3.321928094887362 + 0.5); + const double z = expval * 2.302585092994046 - exp2 * 0.6931471805599453; + const double z2 = z * z; + conv.U = (uint64_t)(exp2 + 1023) << 52U; + // compute exp(z) using continued fractions, see + // https://en.wikipedia.org/wiki/Exponential_function#Continued_fractions_for_ex + conv.F *= 1 + 2 * z / (2 - z + (z2 / (6 + (z2 / (10 + z2 / 14))))); + // correct for rounding errors + if (value < conv.F) { + expval--; + conv.F /= 10; + } + + // the exponent format is "%+03d" and largest value is "307", so set aside + // 4-5 characters + unsigned int minwidth = ((expval < 100) && (expval > -100)) ? 4U : 5U; + + // in "%g" mode, "prec" is the number of *significant figures* not decimals + if (flags & FLAGS_ADAPT_EXP) { + // do we want to fall-back to "%f" mode? + if ((value >= 1e-4) && (value < 1e6)) { + if ((int)prec > expval) { + prec = (unsigned)((int)prec - expval - 1); + } else { + prec = 0; + } + flags |= FLAGS_PRECISION; // make sure _ftoa respects precision + // no characters in exponent + minwidth = 0U; + expval = 0; + } else { + // we use one sigfig for the whole part + if ((prec > 0) && (flags & FLAGS_PRECISION)) { + --prec; + } + } } - } - return idx; -} -#endif // PRINTF_SUPPORT_EXPONENTIAL -#endif // PRINTF_SUPPORT_FLOAT + // will everything fit? + unsigned int fwidth = width; + if (width > minwidth) { + // we didn't fall-back so subtract the characters required for the + // exponent + fwidth -= minwidth; + } else { + // not enough characters, so go back to default sizing + fwidth = 0U; + } + if ((flags & FLAGS_LEFT) && minwidth) { + // if we're padding on the right, DON'T pad the floating part + fwidth = 0U; + } + + // rescale the float value + if (expval) { + value /= conv.F; + } + + // output the floating part + const size_t start_idx = idx; + idx = _ftoa(out, buffer, idx, maxlen, negative ? -value : value, prec, + fwidth, flags & ~FLAGS_ADAPT_EXP); + + // output the exponent part + if (minwidth) { + // output the exponential symbol + out((flags & FLAGS_UPPERCASE) ? 'E' : 'e', buffer, idx++, maxlen); + // output the exponent value + idx = _ntoa_long(out, buffer, idx, maxlen, + (expval < 0) ? -expval : expval, expval < 0, 10, 0, + minwidth - 1, FLAGS_ZEROPAD | FLAGS_PLUS); + // might need to right-pad spaces + if (flags & FLAGS_LEFT) { + while (idx - start_idx < width) out(' ', buffer, idx++, maxlen); + } + } + return idx; +} +#endif // PRINTF_SUPPORT_EXPONENTIAL +#endif // PRINTF_SUPPORT_FLOAT // internal vsnprintf -static int _hedera_vsnprintf(out_fct_type out, char* buffer, const size_t maxlen, const char* format, va_list va) -{ - unsigned int flags, width, precision, n; - size_t idx = 0U; - - if (!buffer) { - // use null output function - out = _out_null; - } - - while (*format) - { - // format specifier? %[flags][width][.precision][length] - if (*format != '%') { - // no - out(*format, buffer, idx++, maxlen); - format++; - continue; - } - else { - // yes, evaluate it - format++; - } - - // evaluate flags - flags = 0U; - do { - switch (*format) { - case '0': flags |= FLAGS_ZEROPAD; format++; n = 1U; break; - case '-': flags |= FLAGS_LEFT; format++; n = 1U; break; - case '+': flags |= FLAGS_PLUS; format++; n = 1U; break; - case ' ': flags |= FLAGS_SPACE; format++; n = 1U; break; - case '#': flags |= FLAGS_HASH; format++; n = 1U; break; - default : n = 0U; break; - } - } while (n); - - // evaluate width field - width = 0U; - if (_is_digit(*format)) { - width = _atoi(&format); - } - else if (*format == '*') { - const int w = va_arg(va, int); - if (w < 0) { - flags |= FLAGS_LEFT; // reverse padding - width = (unsigned int)-w; - } - else { - width = (unsigned int)w; - } - format++; - } - - // evaluate precision field - precision = 0U; - if (*format == '.') { - flags |= FLAGS_PRECISION; - format++; - if (_is_digit(*format)) { - precision = _atoi(&format); - } - else if (*format == '*') { - const int prec = (int)va_arg(va, int); - precision = prec > 0 ? (unsigned int)prec : 0U; - format++; - } - } - - // evaluate length field - switch (*format) { - case 'l' : - flags |= FLAGS_LONG; - format++; - if (*format == 'l') { - flags |= FLAGS_LONG_LONG; - format++; - } - break; - case 'h' : - flags |= FLAGS_SHORT; - format++; - if (*format == 'h') { - flags |= FLAGS_CHAR; - format++; - } - break; -#if defined(PRINTF_SUPPORT_PTRDIFF_T) - case 't' : - flags |= (sizeof(ptrdiff_t) == sizeof(long) ? FLAGS_LONG : FLAGS_LONG_LONG); - format++; - break; -#endif - case 'j' : - flags |= (sizeof(intmax_t) == sizeof(long) ? FLAGS_LONG : FLAGS_LONG_LONG); - format++; - break; - case 'z' : - flags |= (sizeof(size_t) == sizeof(long) ? FLAGS_LONG : FLAGS_LONG_LONG); - format++; - break; - default : - break; - } - - // evaluate specifier - switch (*format) { - case 'd' : - case 'i' : - case 'u' : - case 'x' : - case 'X' : - case 'o' : - case 'b' : { - // set the base - unsigned int base; - if (*format == 'x' || *format == 'X') { - base = 16U; - } - else if (*format == 'o') { - base = 8U; - } - else if (*format == 'b') { - base = 2U; - } - else { - base = 10U; - flags &= ~FLAGS_HASH; // no hash for dec format +static int _hedera_vsnprintf(out_fct_type out, char* buffer, + const size_t maxlen, const char* format, + va_list va) { + unsigned int flags, width, precision, n; + size_t idx = 0U; + + if (!buffer) { + // use null output function + out = _out_null; + } + + while (*format) { + // format specifier? %[flags][width][.precision][length] + if (*format != '%') { + // no + out(*format, buffer, idx++, maxlen); + format++; + continue; + } else { + // yes, evaluate it + format++; } - // uppercase - if (*format == 'X') { - flags |= FLAGS_UPPERCASE; + + // evaluate flags + flags = 0U; + do { + switch (*format) { + case '0': + flags |= FLAGS_ZEROPAD; + format++; + n = 1U; + break; + case '-': + flags |= FLAGS_LEFT; + format++; + n = 1U; + break; + case '+': + flags |= FLAGS_PLUS; + format++; + n = 1U; + break; + case ' ': + flags |= FLAGS_SPACE; + format++; + n = 1U; + break; + case '#': + flags |= FLAGS_HASH; + format++; + n = 1U; + break; + default: + n = 0U; + break; + } + } while (n); + + // evaluate width field + width = 0U; + if (_is_digit(*format)) { + width = _atoi(&format); + } else if (*format == '*') { + const int w = va_arg(va, int); + if (w < 0) { + flags |= FLAGS_LEFT; // reverse padding + width = (unsigned int)-w; + } else { + width = (unsigned int)w; + } + format++; } - // no plus or space flag for u, x, X, o, b - if ((*format != 'i') && (*format != 'd')) { - flags &= ~(FLAGS_PLUS | FLAGS_SPACE); + // evaluate precision field + precision = 0U; + if (*format == '.') { + flags |= FLAGS_PRECISION; + format++; + if (_is_digit(*format)) { + precision = _atoi(&format); + } else if (*format == '*') { + const int prec = (int)va_arg(va, int); + precision = prec > 0 ? (unsigned int)prec : 0U; + format++; + } } - // ignore '0' flag when precision is given - if (flags & FLAGS_PRECISION) { - flags &= ~FLAGS_ZEROPAD; + // evaluate length field + switch (*format) { + case 'l': + flags |= FLAGS_LONG; + format++; + if (*format == 'l') { + flags |= FLAGS_LONG_LONG; + format++; + } + break; + case 'h': + flags |= FLAGS_SHORT; + format++; + if (*format == 'h') { + flags |= FLAGS_CHAR; + format++; + } + break; +#if defined(PRINTF_SUPPORT_PTRDIFF_T) + case 't': + flags |= (sizeof(ptrdiff_t) == sizeof(long) ? FLAGS_LONG + : FLAGS_LONG_LONG); + format++; + break; +#endif + case 'j': + flags |= (sizeof(intmax_t) == sizeof(long) ? FLAGS_LONG + : FLAGS_LONG_LONG); + format++; + break; + case 'z': + flags |= (sizeof(size_t) == sizeof(long) ? FLAGS_LONG + : FLAGS_LONG_LONG); + format++; + break; + default: + break; } - // convert the integer - if ((*format == 'i') || (*format == 'd')) { - // signed - if (flags & FLAGS_LONG_LONG) { + // evaluate specifier + switch (*format) { + case 'd': + case 'i': + case 'u': + case 'x': + case 'X': + case 'o': + case 'b': { + // set the base + unsigned int base; + if (*format == 'x' || *format == 'X') { + base = 16U; + } else if (*format == 'o') { + base = 8U; + } else if (*format == 'b') { + base = 2U; + } else { + base = 10U; + flags &= ~FLAGS_HASH; // no hash for dec format + } + // uppercase + if (*format == 'X') { + flags |= FLAGS_UPPERCASE; + } + + // no plus or space flag for u, x, X, o, b + if ((*format != 'i') && (*format != 'd')) { + flags &= ~(FLAGS_PLUS | FLAGS_SPACE); + } + + // ignore '0' flag when precision is given + if (flags & FLAGS_PRECISION) { + flags &= ~FLAGS_ZEROPAD; + } + + // convert the integer + if ((*format == 'i') || (*format == 'd')) { + // signed + if (flags & FLAGS_LONG_LONG) { #if defined(PRINTF_SUPPORT_LONG_LONG) - const long long value = va_arg(va, long long); - idx = _ntoa_long_long(out, buffer, idx, maxlen, (unsigned long long)(value > 0 ? value : 0 - value), value < 0, base, precision, width, flags); + const long long value = va_arg(va, long long); + idx = _ntoa_long_long( + out, buffer, idx, maxlen, + (unsigned long long)(value > 0 ? value : 0 - value), + value < 0, base, precision, width, flags); #endif - } - else if (flags & FLAGS_LONG) { - const long value = va_arg(va, long); - idx = _ntoa_long(out, buffer, idx, maxlen, (unsigned long)(value > 0 ? value : 0 - value), value < 0, base, precision, width, flags); - } - else { - const int value = (flags & FLAGS_CHAR) ? (char)va_arg(va, int) : (flags & FLAGS_SHORT) ? (short int)va_arg(va, int) : va_arg(va, int); - idx = _ntoa_long(out, buffer, idx, maxlen, (unsigned int)(value > 0 ? value : 0 - value), value < 0, base, precision, width, flags); - } - } - else { - // unsigned - if (flags & FLAGS_LONG_LONG) { + } else if (flags & FLAGS_LONG) { + const long value = va_arg(va, long); + idx = _ntoa_long( + out, buffer, idx, maxlen, + (unsigned long)(value > 0 ? value : 0 - value), + value < 0, base, precision, width, flags); + } else { + const int value = + (flags & FLAGS_CHAR) ? (char)va_arg(va, int) + : (flags & FLAGS_SHORT) ? (short int)va_arg(va, int) + : va_arg(va, int); + idx = _ntoa_long( + out, buffer, idx, maxlen, + (unsigned int)(value > 0 ? value : 0 - value), + value < 0, base, precision, width, flags); + } + } else { + // unsigned + if (flags & FLAGS_LONG_LONG) { #if defined(PRINTF_SUPPORT_LONG_LONG) - idx = _ntoa_long_long(out, buffer, idx, maxlen, va_arg(va, unsigned long long), false, base, precision, width, flags); + idx = _ntoa_long_long(out, buffer, idx, maxlen, + va_arg(va, unsigned long long), + false, base, precision, width, + flags); #endif - } - else if (flags & FLAGS_LONG) { - idx = _ntoa_long(out, buffer, idx, maxlen, va_arg(va, unsigned long), false, base, precision, width, flags); - } - else { - const unsigned int value = (flags & FLAGS_CHAR) ? (unsigned char)va_arg(va, unsigned int) : (flags & FLAGS_SHORT) ? (unsigned short int)va_arg(va, unsigned int) : va_arg(va, unsigned int); - idx = _ntoa_long(out, buffer, idx, maxlen, value, false, base, precision, width, flags); - } - } - format++; - break; - } + } else if (flags & FLAGS_LONG) { + idx = _ntoa_long(out, buffer, idx, maxlen, + va_arg(va, unsigned long), false, base, + precision, width, flags); + } else { + const unsigned int value = + (flags & FLAGS_CHAR) + ? (unsigned char)va_arg(va, unsigned int) + : (flags & FLAGS_SHORT) + ? (unsigned short int)va_arg(va, unsigned int) + : va_arg(va, unsigned int); + idx = _ntoa_long(out, buffer, idx, maxlen, value, false, + base, precision, width, flags); + } + } + format++; + break; + } #if defined(PRINTF_SUPPORT_FLOAT) - case 'f' : - case 'F' : - if (*format == 'F') flags |= FLAGS_UPPERCASE; - idx = _ftoa(out, buffer, idx, maxlen, va_arg(va, double), precision, width, flags); - format++; - break; + case 'f': + case 'F': + if (*format == 'F') flags |= FLAGS_UPPERCASE; + idx = _ftoa(out, buffer, idx, maxlen, va_arg(va, double), + precision, width, flags); + format++; + break; #if defined(PRINTF_SUPPORT_EXPONENTIAL) - case 'e': - case 'E': - case 'g': - case 'G': - if ((*format == 'g')||(*format == 'G')) flags |= FLAGS_ADAPT_EXP; - if ((*format == 'E')||(*format == 'G')) flags |= FLAGS_UPPERCASE; - idx = _etoa(out, buffer, idx, maxlen, va_arg(va, double), precision, width, flags); - format++; - break; -#endif // PRINTF_SUPPORT_EXPONENTIAL -#endif // PRINTF_SUPPORT_FLOAT - case 'c' : { - unsigned int l = 1U; - // pre padding - if (!(flags & FLAGS_LEFT)) { - while (l++ < width) { - out(' ', buffer, idx++, maxlen); - } - } - // char output - out((char)va_arg(va, int), buffer, idx++, maxlen); - // post padding - if (flags & FLAGS_LEFT) { - while (l++ < width) { - out(' ', buffer, idx++, maxlen); - } - } - format++; - break; - } - - case 's' : { - const char* p = va_arg(va, char*); - unsigned int l = _strnlen_s(p, precision ? precision : (size_t)-1); - // pre padding - if (flags & FLAGS_PRECISION) { - l = (l < precision ? l : precision); - } - if (!(flags & FLAGS_LEFT)) { - while (l++ < width) { - out(' ', buffer, idx++, maxlen); - } - } - // string output - while ((*p != 0) && (!(flags & FLAGS_PRECISION) || precision--)) { - out(*(p++), buffer, idx++, maxlen); - } - // post padding - if (flags & FLAGS_LEFT) { - while (l++ < width) { - out(' ', buffer, idx++, maxlen); - } - } - format++; - break; - } - - case 'p' : { - width = sizeof(void*) * 2U; - flags |= FLAGS_ZEROPAD | FLAGS_UPPERCASE; + case 'e': + case 'E': + case 'g': + case 'G': + if ((*format == 'g') || (*format == 'G')) + flags |= FLAGS_ADAPT_EXP; + if ((*format == 'E') || (*format == 'G')) + flags |= FLAGS_UPPERCASE; + idx = _etoa(out, buffer, idx, maxlen, va_arg(va, double), + precision, width, flags); + format++; + break; +#endif // PRINTF_SUPPORT_EXPONENTIAL +#endif // PRINTF_SUPPORT_FLOAT + case 'c': { + unsigned int l = 1U; + // pre padding + if (!(flags & FLAGS_LEFT)) { + while (l++ < width) { + out(' ', buffer, idx++, maxlen); + } + } + // char output + out((char)va_arg(va, int), buffer, idx++, maxlen); + // post padding + if (flags & FLAGS_LEFT) { + while (l++ < width) { + out(' ', buffer, idx++, maxlen); + } + } + format++; + break; + } + + case 's': { + const char* p = va_arg(va, char*); + unsigned int l = + _strnlen_s(p, precision ? precision : (size_t)-1); + // pre padding + if (flags & FLAGS_PRECISION) { + l = (l < precision ? l : precision); + } + if (!(flags & FLAGS_LEFT)) { + while (l++ < width) { + out(' ', buffer, idx++, maxlen); + } + } + // string output + while ((*p != 0) && + (!(flags & FLAGS_PRECISION) || precision--)) { + out(*(p++), buffer, idx++, maxlen); + } + // post padding + if (flags & FLAGS_LEFT) { + while (l++ < width) { + out(' ', buffer, idx++, maxlen); + } + } + format++; + break; + } + + case 'p': { + width = sizeof(void*) * 2U; + flags |= FLAGS_ZEROPAD | FLAGS_UPPERCASE; #if defined(PRINTF_SUPPORT_LONG_LONG) - const bool is_ll = sizeof(uintptr_t) == sizeof(long long); - if (is_ll) { - idx = _ntoa_long_long(out, buffer, idx, maxlen, (uintptr_t)va_arg(va, void*), false, 16U, precision, width, flags); - } - else { + const bool is_ll = sizeof(uintptr_t) == sizeof(long long); + if (is_ll) { + idx = _ntoa_long_long(out, buffer, idx, maxlen, + (uintptr_t)va_arg(va, void*), false, + 16U, precision, width, flags); + } else { #endif - idx = _ntoa_long(out, buffer, idx, maxlen, (unsigned long)((uintptr_t)va_arg(va, void*)), false, 16U, precision, width, flags); + idx = _ntoa_long( + out, buffer, idx, maxlen, + (unsigned long)((uintptr_t)va_arg(va, void*)), false, + 16U, precision, width, flags); #if defined(PRINTF_SUPPORT_LONG_LONG) - } + } #endif - format++; - break; - } - - case '%' : - out('%', buffer, idx++, maxlen); - format++; - break; - - default : - out(*format, buffer, idx++, maxlen); - format++; - break; + format++; + break; + } + + case '%': + out('%', buffer, idx++, maxlen); + format++; + break; + + default: + out(*format, buffer, idx++, maxlen); + format++; + break; + } } - } - // termination - out((char)0, buffer, idx < maxlen ? idx : maxlen - 1U, maxlen); + // termination + out((char)0, buffer, idx < maxlen ? idx : maxlen - 1U, maxlen); - // return written chars without terminating \0 - return (int)idx; + // return written chars without terminating \0 + return (int)idx; } - /////////////////////////////////////////////////////////////////////////////// -int hedera_printf_(const char* format, ...) -{ - va_list va; - va_start(va, format); - char buffer[1]; - const int ret = _hedera_vsnprintf(_out_char, buffer, (size_t)-1, format, va); - va_end(va); - return ret; +int hedera_printf_(const char* format, ...) { + va_list va; + va_start(va, format); + char buffer[ 1 ]; + const int ret = + _hedera_vsnprintf(_out_char, buffer, (size_t)-1, format, va); + va_end(va); + return ret; } - -int hedera_sprintf_(char* buffer, const char* format, ...) -{ - va_list va; - va_start(va, format); - const int ret = _hedera_vsnprintf(_out_buffer, buffer, (size_t)-1, format, va); - va_end(va); - return ret; +int hedera_sprintf_(char* buffer, const char* format, ...) { + va_list va; + va_start(va, format); + const int ret = + _hedera_vsnprintf(_out_buffer, buffer, (size_t)-1, format, va); + va_end(va); + return ret; } - -int hedera_snprintf_(char* buffer, size_t count, const char* format, ...) -{ - va_list va; - va_start(va, format); - const int ret = _hedera_vsnprintf(_out_buffer, buffer, count, format, va); - va_end(va); - return ret; +int hedera_snprintf_(char* buffer, size_t count, const char* format, ...) { + va_list va; + va_start(va, format); + const int ret = _hedera_vsnprintf(_out_buffer, buffer, count, format, va); + va_end(va); + return ret; } - -int hedera_vprintf_(const char* format, va_list va) -{ - char buffer[1]; - return _hedera_vsnprintf(_out_char, buffer, (size_t)-1, format, va); +int hedera_vprintf_(const char* format, va_list va) { + char buffer[ 1 ]; + return _hedera_vsnprintf(_out_char, buffer, (size_t)-1, format, va); } - -int hedera_vsnprintf_(char* buffer, size_t count, const char* format, va_list va) -{ - return _hedera_vsnprintf(_out_buffer, buffer, count, format, va); +int hedera_vsnprintf_(char* buffer, size_t count, const char* format, + va_list va) { + return _hedera_vsnprintf(_out_buffer, buffer, count, format, va); } - -int hedera_fctprintf(void (*out)(char character, void* arg), void* arg, const char* format, ...) -{ - va_list va; - va_start(va, format); - const out_fct_wrap_type out_fct_wrap = { out, arg }; - const int ret = _hedera_vsnprintf(_out_fct, (char*)(uintptr_t)&out_fct_wrap, (size_t)-1, format, va); - va_end(va); - return ret; +int hedera_fctprintf(void (*out)(char character, void* arg), void* arg, + const char* format, ...) { + va_list va; + va_start(va, format); + const out_fct_wrap_type out_fct_wrap = {out, arg}; + const int ret = _hedera_vsnprintf(_out_fct, (char*)(uintptr_t)&out_fct_wrap, + (size_t)-1, format, va); + va_end(va); + return ret; } diff --git a/src/printf.h b/src/printf.h index b30c54d4..d68575b4 100644 --- a/src/printf.h +++ b/src/printf.h @@ -10,10 +10,10 @@ // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: -// +// // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. -// +// // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -22,7 +22,8 @@ // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. // -// \brief Tiny printf, sprintf and snprintf implementation, optimized for speed on +// \brief Tiny printf, sprintf and snprintf implementation, optimized for speed +// on // embedded systems with a very limited resources. // Use this instead of bloated standard/newlib printf. // These routines are thread safe and reentrant. @@ -35,83 +36,82 @@ #include #include - #ifdef __cplusplus extern "C" { #endif - /** - * Output a character to a custom device like UART, used by the printf() function - * This function is declared here only. You have to write your custom implementation somewhere - * \param character Character to output + * Output a character to a custom device like UART, used by the printf() + * function This function is declared here only. You have to write your custom + * implementation somewhere \param character Character to output */ void _putchar(char character); - /** * Tiny printf implementation * You have to implement _putchar if you use printf() - * To avoid conflicts with the regular printf() API it is overridden by macro defines - * and internal underscore-appended functions like printf_() are used + * To avoid conflicts with the regular printf() API it is overridden by macro + * defines and internal underscore-appended functions like printf_() are used * \param format A string that specifies the format of the output - * \return The number of characters that are written into the array, not counting the terminating null character + * \return The number of characters that are written into the array, not + * counting the terminating null character */ #define hedera_printf hedera_printf_ int hedera_printf_(const char* format, ...); - /** * Tiny sprintf implementation - * Due to security reasons (buffer overflow) YOU SHOULD CONSIDER USING (V)SNPRINTF INSTEAD! - * \param buffer A pointer to the buffer where to store the formatted string. MUST be big enough to store the output! - * \param format A string that specifies the format of the output - * \return The number of characters that are WRITTEN into the buffer, not counting the terminating null character + * Due to security reasons (buffer overflow) YOU SHOULD CONSIDER USING + * (V)SNPRINTF INSTEAD! \param buffer A pointer to the buffer where to store the + * formatted string. MUST be big enough to store the output! \param format A + * string that specifies the format of the output \return The number of + * characters that are WRITTEN into the buffer, not counting the terminating + * null character */ #define hedera_sprintf hedera_sprintf_ int hedera_sprintf_(char* buffer, const char* format, ...); - /** * Tiny snprintf/vsnprintf implementation * \param buffer A pointer to the buffer where to store the formatted string - * \param count The maximum number of characters to store in the buffer, including a terminating null character - * \param format A string that specifies the format of the output - * \param va A value identifying a variable arguments list - * \return The number of characters that COULD have been written into the buffer, not counting the terminating - * null character. A value equal or larger than count indicates truncation. Only when the returned value - * is non-negative and less than count, the string has been completely written. + * \param count The maximum number of characters to store in the buffer, + * including a terminating null character \param format A string that specifies + * the format of the output \param va A value identifying a variable arguments + * list \return The number of characters that COULD have been written into the + * buffer, not counting the terminating null character. A value equal or larger + * than count indicates truncation. Only when the returned value is non-negative + * and less than count, the string has been completely written. */ -#define hedera_snprintf hedera_snprintf_ +#define hedera_snprintf hedera_snprintf_ #define hedera_vsnprintf hedera_vsnprintf_ -int hedera_snprintf_(char* buffer, size_t count, const char* format, ...); -int hedera_vsnprintf_(char* buffer, size_t count, const char* format, va_list va); - +int hedera_snprintf_(char* buffer, size_t count, const char* format, ...); +int hedera_vsnprintf_(char* buffer, size_t count, const char* format, + va_list va); /** * Tiny vprintf implementation * \param format A string that specifies the format of the output * \param va A value identifying a variable arguments list - * \return The number of characters that are WRITTEN into the buffer, not counting the terminating null character + * \return The number of characters that are WRITTEN into the buffer, not + * counting the terminating null character */ #define hedera_vprintf hedera_vprintf_ int hedera_vprintf_(const char* format, va_list va); - /** * printf with output function - * You may use this as dynamic alternative to printf() with its fixed _putchar() output - * \param out An output function which takes one character and an argument pointer - * \param arg An argument pointer for user data passed to output function - * \param format A string that specifies the format of the output - * \return The number of characters that are sent to the output function, not counting the terminating null character + * You may use this as dynamic alternative to printf() with its fixed _putchar() + * output \param out An output function which takes one character and an + * argument pointer \param arg An argument pointer for user data passed to + * output function \param format A string that specifies the format of the + * output \return The number of characters that are sent to the output function, + * not counting the terminating null character */ -int hedera_fctprintf(void (*out)(char character, void* arg), void* arg, const char* format, ...); - +int hedera_fctprintf(void (*out)(char character, void* arg), void* arg, + const char* format, ...); #ifdef __cplusplus } #endif - -#endif // _PRINTF_H_ +#endif // _PRINTF_H_ diff --git a/src/sign_transaction.c b/src/sign_transaction.c index 9b44501e..119b0514 100644 --- a/src/sign_transaction.c +++ b/src/sign_transaction.c @@ -1,69 +1,68 @@ -#include -#include -#include -#include -#include - -#include "printf.h" -#include "globals.h" -#include "debug.h" -#include "errors.h" -#include "handlers.h" -#include "hedera.h" -#include "hedera_format.h" -#include "io.h" -#include "TransactionBody.pb.h" -#include "utils.h" -#include "ui.h" #include "sign_transaction.h" #if defined(TARGET_NANOS) -static struct sign_tx_context_t { - // ui common - uint32_t key_index; - uint8_t transfer_to_index; - uint8_t transfer_from_index; - - // Transaction Summary - char summary_line_1[DISPLAY_SIZE + 1]; - char summary_line_2[DISPLAY_SIZE + 1]; - char title[DISPLAY_SIZE + 1]; - - // Account ID: uint64_t.uint64_t.uint64_t - // Most other entities are shorter - char full[ACCOUNT_ID_SIZE + 1]; - char partial[DISPLAY_SIZE + 1]; - - // Steps correspond to parts of the transaction proto - // type is set based on proto - enum TransactionStep step; - enum TransactionType type; - - uint8_t display_index; // 1 -> Number Screens - uint8_t display_count; // Number Screens - - // Parsed transaction - HederaTransactionBody transaction; -} ctx; - -// UI Definition for Nano S +/* + * Supported Transactions: + * + * Verify: + * "Verify Account with Key #0?" (Summary) <--> "Account" (Senders) <--> Confirm +<--> Deny + * + * Create: + * "Create Account with Key #0?" (Summary) <--> Operator <--> "Stake to" +(Senders) <--> "Collect Rewards? Yes / No" (Recipients) <--> "Initial Balance" +(Amount) <--> Fee <--> Memo <--> Confirm <--> Deny + * + * Update: + * "Update Account 0.0.0 with Key #0?" (Summary) <--> Operator <--> "Stake to" +(Senders) <--> "Collect Rewards (Yes / No)" (Recipients) <--> "Updated Account" +(Amount) <--> Fee <--> Memo <--> Confirm <--> Deny + * + * Transfer: + * "Transfer with Key #0?" (Summary) <--> Operator <--> Senders <--> Recipients +<--> Amount <--> Fee <--> Memo <--> Confirm <--> Deny + * + * Associate: + * "Associate Token with Key #0?" (Summary) <--> Operator <--> "Token" (Senders) +<--> "Updating" (Amount) <--> Fee <--> Memo <--> Confirm <--> Deny + * + * Dissociate: + * "Dissociate Token with Key #0?" (Summary) <--> Operator <--> "Token" +(Senders) <--> "Updating" (Amount) <--> Fee <--> Memo <--> Confirm <--> Deny + * + * TokenMint: + * "Mint Token with Key #0?" (Summary) <--> Operator <--> "Token" (Senders) <--> +Amount <--> Fee <--> Memo <--> Confirm <--> Deny + * + * TokenBurn: + * "Burn Token with Key #0?" (Summary) <--> Operator <--> "Token" (Senders) <--> +Amount <--> Fee <--> Memo <--> Confirm <--> Deny + * + * I chose the steps for the originally supported CreateAccount and Transfer +transactions, and the additional transactions have been added since then. Steps +may be skipped or modified (as described above) from the original transfer flow. +The implementation of the steps is in the 'intermediate' screen button handlers. +These functions control iterating through the steps and control paging for +entities that overflow display on a single screen. The nano X has a paging macro +for this in its UX system. We don't have much RAM to work with, so I couldn't +define entirely separate UI elements for each flow, which lead me to using the +screens defined below as singletons. + */ + // Step 1: Transaction Summary static const bagl_element_t ui_tx_summary_step[] = { - UI_BACKGROUND(), - UI_ICON_RIGHT(RIGHT_ICON_ID, BAGL_GLYPH_ICON_RIGHT), + UI_BACKGROUND(), UI_ICON_RIGHT(RIGHT_ICON_ID, BAGL_GLYPH_ICON_RIGHT), // () >> // Line 1 // Line 2 UI_TEXT(LINE_1_ID, 0, 12, 128, ctx.summary_line_1), - UI_TEXT(LINE_2_ID, 0, 26, 128, ctx.summary_line_2) -}; + UI_TEXT(LINE_2_ID, 0, 26, 128, ctx.summary_line_2)}; // Step 2 - 7: Operator, Senders, Recipients, Amount, Fee, Memo static const bagl_element_t ui_tx_intermediate_step[] = { - UI_BACKGROUND(), - UI_ICON_LEFT(LEFT_ICON_ID, BAGL_GLYPH_ICON_LEFT), + UI_BACKGROUND(), UI_ICON_LEFT(LEFT_ICON_ID, BAGL_GLYPH_ICON_LEFT), UI_ICON_RIGHT(RIGHT_ICON_ID, BAGL_GLYPH_ICON_RIGHT), // << >> @@ -71,13 +70,11 @@ static const bagl_element_t ui_tx_intermediate_step[] = { // UI_TEXT(LINE_1_ID, 0, 12, 128, ctx.title), - UI_TEXT(LINE_2_ID, 0, 26, 128, ctx.partial) -}; + UI_TEXT(LINE_2_ID, 0, 26, 128, ctx.partial)}; // Step 8: Confirm static const bagl_element_t ui_tx_confirm_step[] = { - UI_BACKGROUND(), - UI_ICON_LEFT(LEFT_ICON_ID, BAGL_GLYPH_ICON_LEFT), + UI_BACKGROUND(), UI_ICON_LEFT(LEFT_ICON_ID, BAGL_GLYPH_ICON_LEFT), UI_ICON_RIGHT(RIGHT_ICON_ID, BAGL_GLYPH_ICON_RIGHT), // << >> @@ -85,36 +82,32 @@ static const bagl_element_t ui_tx_confirm_step[] = { // UI_TEXT(LINE_1_ID, 0, 12, 128, "Confirm"), - UI_ICON(LINE_2_ID, 0, 24, 128, BAGL_GLYPH_ICON_CHECK) -}; + UI_ICON(LINE_2_ID, 0, 24, 128, BAGL_GLYPH_ICON_CHECK)}; // Step 9: Deny static const bagl_element_t ui_tx_deny_step[] = { - UI_BACKGROUND(), - UI_ICON_LEFT(LEFT_ICON_ID, BAGL_GLYPH_ICON_LEFT), + UI_BACKGROUND(), UI_ICON_LEFT(LEFT_ICON_ID, BAGL_GLYPH_ICON_LEFT), // << () // Deny // X UI_TEXT(LINE_1_ID, 0, 12, 128, "Deny"), - UI_ICON(LINE_2_ID, 0, 24, 128, BAGL_GLYPH_ICON_CROSS) -}; + UI_ICON(LINE_2_ID, 0, 24, 128, BAGL_GLYPH_ICON_CROSS)}; -// Step 1: Transaction Summary -unsigned int ui_tx_summary_step_button( - unsigned int button_mask, - unsigned int __attribute__ ((unused)) button_mask_counter -) { - switch(button_mask) { +// Step 1: Transaction Summary --> Operator, Senders +unsigned int ui_tx_summary_step_button(unsigned int button_mask, + unsigned int __attribute__((unused)) + button_mask_counter) { + switch (button_mask) { case BUTTON_EVT_RELEASED | BUTTON_RIGHT: - if (ctx.type == Verify || ctx.type == Associate || ctx.type == TokenMint || ctx.type == TokenBurn) { + ctx.current_page = 1; + + if (ctx.type == Verify) { ctx.step = Senders; - ctx.display_index = 1; reformat_senders(); } else { ctx.step = Operator; - ctx.display_index = 1; reformat_operator(); } UX_DISPLAY(ui_tx_intermediate_step, NULL); @@ -128,97 +121,102 @@ void handle_intermediate_left_press() { // Navigate Left (scroll or return to previous step) switch (ctx.step) { case Operator: { - if (first_screen()) { // Return to Summary + if (first_screen_of_step()) { + // All: Summary <-- Operator + ctx.current_page = 1; ctx.step = Summary; - ctx.display_index = 1; UX_DISPLAY(ui_tx_summary_step, NULL); - } else { // Scroll Left - ctx.display_index--; + } else { // Scroll Left + ctx.current_page--; reformat_operator(); - UX_REDISPLAY(); } } break; case Senders: { - if (first_screen()) { // Return to Operator - if (ctx.type == Verify || ctx.type == Associate || ctx.type == TokenMint || ctx.type == TokenBurn) { + if (first_screen_of_step()) { // Return to Operator + ctx.current_page = 1; + + if (ctx.type == Verify) { + // Verify: Summary <-- Senders ctx.step = Summary; - ctx.display_index = 1; UX_DISPLAY(ui_tx_summary_step, NULL); } else { + // All (!Verify): Operator <-- Senders ctx.step = Operator; - ctx.display_index = 1; reformat_operator(); } - } else { // Scroll Left - ctx.display_index--; + } else { // Scroll Left + ctx.current_page--; reformat_senders(); } - UX_REDISPLAY(); + } break; case Recipients: { - if (first_screen()) { // Return to Senders + if (first_screen_of_step()) { + // All: Senders <-- Recipients + ctx.current_page = 1; ctx.step = Senders; - ctx.display_index = 1; reformat_senders(); - } else { // Scroll Left - ctx.display_index--; + } else { // Scroll Left + ctx.current_page--; reformat_recipients(); } - UX_REDISPLAY(); + } break; case Amount: { - if (first_screen()) { - if (ctx.type == Create) { // Return to Operator - ctx.step = Operator; - ctx.display_index = 1; - reformat_operator(); - } else if (ctx.type == Transfer || ctx.type == TokenTransfer) { // Return to Recipients - ctx.step = Recipients; - ctx.display_index = 1; - reformat_recipients(); - } else if (ctx.type == TokenMint || ctx.type == TokenBurn) { // Return to Senders + if (first_screen_of_step()) { + ctx.current_page = 1; + + if (ctx.type == TokenMint || ctx.type == TokenBurn || + ctx.type == Associate || ctx.type == Dissociate) { + // Mint, Burn, Associate, Dissociate: Senders <-- Amount ctx.step = Senders; - ctx.display_index = 1; reformat_senders(); + } else { + // All (!Mint, !Burn, !Associate, !Dissociate): Recipients + // <-- Amount + ctx.step = Recipients; + reformat_recipients(); } - } else { // Scroll left - ctx.display_index--; + } else { // Scroll left + ctx.current_page--; reformat_amount(); } - UX_REDISPLAY(); + } break; case Fee: { - if (first_screen()) { // Return to Amount + if (first_screen_of_step()) { + // All: Amount <-- Fee + ctx.current_page = 1; ctx.step = Amount; - ctx.display_index = 1; reformat_amount(); - } else { // Scroll left - ctx.display_index--; + } else { // Scroll left + ctx.current_page--; reformat_fee(); } - UX_REDISPLAY(); + } break; case Memo: { - if (first_screen()) { // Return to Fee + if (first_screen_of_step()) { + // All: Fee <-- Memo + ctx.current_page = 1; ctx.step = Fee; - ctx.display_index = 1; reformat_fee(); - } else { // Scroll Left - ctx.display_index--; + } else { // Scroll Left + ctx.current_page--; reformat_memo(); } - UX_REDISPLAY(); + } break; case Summary: case Confirm: case Deny: - // ignore left button on Summary, Confirm, and Deny screens + // Should not occur, does not handle these steps break; } } @@ -227,114 +225,107 @@ void handle_intermediate_right_press() { // Navigate Right (scroll or continue to next step) switch (ctx.step) { case Operator: { - if (last_screen()) { - if (ctx.type == Create) { // Continue to Amount - ctx.step = Amount; - ctx.display_index = 1; - reformat_amount(); - } else { // Continue to Senders - ctx.step = Senders; - ctx.display_index = 1; - reformat_senders(); - } - } else { // Scroll Right - ctx.display_index++; + if (last_screen_of_step()) { + // All: Operator --> Senders + ctx.step = Senders; + ctx.current_page = 1; + reformat_senders(); + } else { // Scroll Right + ctx.current_page++; reformat_operator(); } - UX_REDISPLAY(); + } break; case Senders: { - if (last_screen()) { - if (ctx.type == Verify || ctx.type == Associate) { // Continue to Confirm + if (last_screen_of_step()) { + ctx.current_page = 1; + + if (ctx.type == Verify) { + // Verify: Senders --> Confirm ctx.step = Confirm; UX_DISPLAY(ui_tx_confirm_step, NULL); - } else if (ctx.type == TokenMint || ctx.type == TokenBurn) { + } else if (ctx.type == TokenMint || ctx.type == TokenBurn || + ctx.type == Associate || ctx.type == Dissociate) { + // Mint, Burn: Senders --> Amount ctx.step = Amount; - ctx.display_index = 1; reformat_amount(); - } else { // Continue to Recipients + } else { + // Create, Update, Transfer: Senders --> Recipients ctx.step = Recipients; - ctx.display_index = 1; reformat_recipients(); } - } else { // Scroll Right - ctx.display_index++; + } else { // Scroll Right + ctx.current_page++; reformat_senders(); } - UX_REDISPLAY(); + } break; case Recipients: { - if (last_screen()) { // Continue to Amount + if (last_screen_of_step()) { + // All (Create, Update, Transfer): Recipients --> Amount ctx.step = Amount; - ctx.display_index = 1; + ctx.current_page = 1; reformat_amount(); - } else { // Scroll Right - ctx.display_index++; + } else { // Scroll Right + ctx.current_page++; reformat_recipients(); } - UX_REDISPLAY(); + } break; case Amount: { - if (last_screen()) { - if (ctx.type == TokenMint || ctx.type == TokenBurn) { - // Continue to Confirm - ctx.step = Confirm; - ctx.display_index = 1; - UX_DISPLAY(ui_tx_confirm_step, NULL); - } else { - // Continue to Fee - ctx.step = Fee; - ctx.display_index = 1; - reformat_fee(); - } - } else { // Scroll Right - ctx.display_index++; + if (last_screen_of_step()) { + // All: Amount --> Fee + ctx.step = Fee; + ctx.current_page = 1; + reformat_fee(); + } else { // Scroll Right + ctx.current_page++; reformat_amount(); } - UX_REDISPLAY(); + } break; case Fee: { - if (last_screen()) { // Continue to Memo + if (last_screen_of_step()) { + // All: Fee --> Memo ctx.step = Memo; - ctx.display_index = 1; + ctx.current_page = 1; reformat_memo(); - } else { // Scroll Right - ctx.display_index++; + } else { // Scroll Right + ctx.current_page++; reformat_fee(); } - UX_REDISPLAY(); + } break; case Memo: { - if (last_screen()) { // Continue to Confirm + if (last_screen_of_step()) { + // All: Memo --> Confirm ctx.step = Confirm; - ctx.display_index = 1; + ctx.current_page = 1; UX_DISPLAY(ui_tx_confirm_step, NULL); - } else { // Scroll Right - ctx.display_index++; + } else { // Scroll Right + ctx.current_page++; reformat_memo(); - UX_REDISPLAY(); } } break; case Summary: case Confirm: case Deny: - // ignore left button on Summary, Confirm, and Deny screens + // Should not occur, does not handle these steps break; } } // Step 2 - 7: Operator, Senders, Recipients, Amount, Fee, Memo -unsigned int ui_tx_intermediate_step_button( - unsigned int button_mask, - unsigned int __attribute__ ((unused)) button_mask_counter -) { - switch(button_mask) { +unsigned int ui_tx_intermediate_step_button(unsigned int button_mask, + unsigned int __attribute__((unused)) + button_mask_counter) { + switch (button_mask) { case BUTTON_EVT_RELEASED | BUTTON_LEFT: handle_intermediate_left_press(); break; @@ -342,7 +333,7 @@ unsigned int ui_tx_intermediate_step_button( handle_intermediate_right_press(); break; case BUTTON_EVT_RELEASED | BUTTON_LEFT | BUTTON_RIGHT: - // Skip to confirm screen + // Skip to confirm screen on double press ctx.step = Confirm; UX_DISPLAY(ui_tx_confirm_step, NULL); break; @@ -351,23 +342,20 @@ unsigned int ui_tx_intermediate_step_button( return 0; } -unsigned int ui_tx_confirm_step_button( - unsigned int button_mask, - unsigned int __attribute__ ((unused)) button_mask_counter -) { - switch(button_mask) { +unsigned int ui_tx_confirm_step_button(unsigned int button_mask, + unsigned int __attribute__((unused)) + button_mask_counter) { + switch (button_mask) { case BUTTON_EVT_RELEASED | BUTTON_LEFT: - if (ctx.type == Verify || ctx.type == Associate) { // Return to Senders + ctx.current_page = 1; + + if (ctx.type == Verify) { + // Verify: Senders <-- Confirm ctx.step = Senders; - ctx.display_index = 1; reformat_senders(); - } else if (ctx.type == TokenMint || ctx.type == TokenBurn) { // Return to Amount - ctx.step = Amount; - ctx.display_index = 1; - reformat_amount(); - } else { // Return to Memo + } else { + // All (!Verify): Memo <-- Confirm ctx.step = Memo; - ctx.display_index = 1; reformat_memo(); } UX_DISPLAY(ui_tx_intermediate_step, NULL); @@ -387,11 +375,10 @@ unsigned int ui_tx_confirm_step_button( return 0; } -unsigned int ui_tx_deny_step_button( - unsigned int button_mask, - unsigned int __attribute__ ((unused)) button_mask_counter -) { - switch(button_mask) { +unsigned int ui_tx_deny_step_button(unsigned int button_mask, + unsigned int __attribute__((unused)) + button_mask_counter) { + switch (button_mask) { case BUTTON_EVT_RELEASED | BUTTON_LEFT: // Return to Confirm ctx.step = Confirm; @@ -409,11 +396,12 @@ unsigned int ui_tx_deny_step_button( } uint8_t num_screens(size_t length) { - // Number of screens is len / display size + 1 for overflow - if (length == 0) return 1; - + // Number of screens is (len text in chars / display size in chars) + 1 for + // overflowing text + if (length <= 0) return 1; + uint8_t screens = length / DISPLAY_SIZE; - + if (length % DISPLAY_SIZE > 0) { screens += 1; } @@ -421,146 +409,172 @@ uint8_t num_screens(size_t length) { return screens; } -void count_screens() { - ctx.display_count = num_screens(strlen(ctx.full)); -} +void count_screens_of_step() { ctx.page_count = num_screens(strlen(ctx.full)); } -void shift_display() { +void repaint() { // Slide window (partial) along full entity (full) by DISPLAY_SIZE chars explicit_bzero(ctx.partial, DISPLAY_SIZE + 1); - memmove( - ctx.partial, - ctx.full + (DISPLAY_SIZE * (ctx.display_index - 1)), - DISPLAY_SIZE - ); + memmove(ctx.partial, ctx.full + (DISPLAY_SIZE * (ctx.current_page - 1)), + DISPLAY_SIZE); + UX_REDISPLAY(); } -bool last_screen() { - return ctx.display_index == ctx.display_count; -} +bool last_screen_of_step() { return ctx.current_page == ctx.page_count; } -bool first_screen() { - return ctx.display_index == 1; -} +bool first_screen_of_step() { return ctx.current_page == 1; } void reformat_operator() { - hedera_snprintf( - ctx.full, - ACCOUNT_ID_SIZE, - "%llu.%llu.%llu", - ctx.transaction.transactionID.accountID.shardNum, - ctx.transaction.transactionID.accountID.realmNum, - ctx.transaction.transactionID.accountID.accountNum - ); - - count_screens(); - - hedera_snprintf( - ctx.title, - DISPLAY_SIZE, - "Operator (%u/%u)", - ctx.display_index, - ctx.display_count - ); - - shift_display(); + hedera_snprintf(ctx.full, ACCOUNT_ID_SIZE, "%llu.%llu.%llu", + ctx.transaction.transactionID.accountID.shardNum, + ctx.transaction.transactionID.accountID.realmNum, + ctx.transaction.transactionID.accountID.account.accountNum); + + count_screens_of_step(); + + hedera_snprintf(ctx.title, DISPLAY_SIZE, "Operator (%u/%u)", + ctx.current_page, ctx.page_count); + + repaint(); } void reformat_accounts(char* title_part, uint8_t transfer_index) { - hedera_snprintf( - ctx.full, - ACCOUNT_ID_SIZE, - "%llu.%llu.%llu", - ctx.transaction.data.cryptoTransfer.transfers.accountAmounts[transfer_index].accountID.shardNum, - ctx.transaction.data.cryptoTransfer.transfers.accountAmounts[transfer_index].accountID.realmNum, - ctx.transaction.data.cryptoTransfer.transfers.accountAmounts[transfer_index].accountID.accountNum - ); + hedera_snprintf(ctx.full, ACCOUNT_ID_SIZE, "%llu.%llu.%llu", + ctx.transaction.data.cryptoTransfer.transfers + .accountAmounts[ transfer_index ] + .accountID.shardNum, + ctx.transaction.data.cryptoTransfer.transfers + .accountAmounts[ transfer_index ] + .accountID.realmNum, + ctx.transaction.data.cryptoTransfer.transfers + .accountAmounts[ transfer_index ] + .accountID.account.accountNum); + + count_screens_of_step(); + + hedera_snprintf(ctx.title, DISPLAY_SIZE, "%s (%u/%u)", title_part, + ctx.current_page, ctx.page_count); +} + +void reformat_stake_target() { + switch (ctx.type) { + case Create: { + if (ctx.transaction.data.cryptoCreateAccount.which_staked_id == + Hedera_CryptoCreateTransactionBody_staked_account_id_tag) { + // An account ID and not a Node ID + hedera_snprintf( + ctx.full, ACCOUNT_ID_SIZE, "%llu.%llu.%llu", + ctx.transaction.data.cryptoCreateAccount.staked_id + .staked_account_id.shardNum, + ctx.transaction.data.cryptoCreateAccount.staked_id + .staked_account_id.realmNum, + ctx.transaction.data.cryptoCreateAccount.staked_id + .staked_account_id.account.accountNum); + } else if (ctx.transaction.data.cryptoCreateAccount + .which_staked_id == + Hedera_CryptoCreateTransactionBody_staked_node_id_tag) { + hedera_snprintf(ctx.full, ACCOUNT_ID_SIZE, "Node %lld", + ctx.transaction.data.cryptoCreateAccount + .staked_id.staked_node_id); + } else { + hedera_snprintf(ctx.full, DISPLAY_SIZE, "%s", "None"); + } + } break; - count_screens(); + case Update: { + if (ctx.transaction.data.cryptoUpdateAccount.which_staked_id == + Hedera_CryptoUpdateTransactionBody_staked_account_id_tag) { + // An account ID and not a Node ID + hedera_snprintf( + ctx.full, ACCOUNT_ID_SIZE, "%llu.%llu.%llu", + ctx.transaction.data.cryptoUpdateAccount.staked_id + .staked_account_id.shardNum, + ctx.transaction.data.cryptoUpdateAccount.staked_id + .staked_account_id.realmNum, + ctx.transaction.data.cryptoUpdateAccount.staked_id + .staked_account_id.account.accountNum); + } else if (ctx.transaction.data.cryptoUpdateAccount + .which_staked_id == + Hedera_CryptoUpdateTransactionBody_staked_node_id_tag) { + hedera_snprintf(ctx.full, ACCOUNT_ID_SIZE, "Node %lld", + ctx.transaction.data.cryptoUpdateAccount + .staked_id.staked_node_id); + } else { + hedera_snprintf(ctx.full, DISPLAY_SIZE, "%s", "None"); + } + } break; - hedera_snprintf( - ctx.title, - DISPLAY_SIZE, - "%s (%u/%u)", - title_part, - ctx.display_index, - ctx.display_count - ); + default: + break; + } + + count_screens_of_step(); + + hedera_snprintf(ctx.title, DISPLAY_SIZE, "Stake To (%u/%u)", + ctx.current_page, ctx.page_count); } void reformat_token() { switch (ctx.type) { case Associate: hedera_snprintf( - ctx.full, - ACCOUNT_ID_SIZE, - "%llu.%llu.%llu", - ctx.transaction.data.tokenAssociate.tokens[0].shardNum, - ctx.transaction.data.tokenAssociate.tokens[0].realmNum, - ctx.transaction.data.tokenAssociate.tokens[0].tokenNum - ); + ctx.full, ACCOUNT_ID_SIZE, "%llu.%llu.%llu", + ctx.transaction.data.tokenAssociate.tokens[ 0 ].shardNum, + ctx.transaction.data.tokenAssociate.tokens[ 0 ].realmNum, + ctx.transaction.data.tokenAssociate.tokens[ 0 ].tokenNum); break; - case TokenMint: + case Dissociate: hedera_snprintf( - ctx.full, - ACCOUNT_ID_SIZE, - "%llu.%llu.%llu", - ctx.transaction.data.tokenMint.token.shardNum, - ctx.transaction.data.tokenMint.token.realmNum, - ctx.transaction.data.tokenMint.token.tokenNum - ); + ctx.full, ACCOUNT_ID_SIZE, "%llu.%llu.%llu", + ctx.transaction.data.tokenDissociate.tokens[ 0 ].shardNum, + ctx.transaction.data.tokenDissociate.tokens[ 0 ].realmNum, + ctx.transaction.data.tokenDissociate.tokens[ 0 ].tokenNum); + + break; + + case TokenMint: + hedera_snprintf(ctx.full, ACCOUNT_ID_SIZE, "%llu.%llu.%llu", + ctx.transaction.data.tokenMint.token.shardNum, + ctx.transaction.data.tokenMint.token.realmNum, + ctx.transaction.data.tokenMint.token.tokenNum); break; case TokenBurn: - hedera_snprintf( - ctx.full, - ACCOUNT_ID_SIZE, - "%llu.%llu.%llu", - ctx.transaction.data.tokenBurn.token.shardNum, - ctx.transaction.data.tokenBurn.token.realmNum, - ctx.transaction.data.tokenBurn.token.tokenNum - ); + hedera_snprintf(ctx.full, ACCOUNT_ID_SIZE, "%llu.%llu.%llu", + ctx.transaction.data.tokenBurn.token.shardNum, + ctx.transaction.data.tokenBurn.token.realmNum, + ctx.transaction.data.tokenBurn.token.tokenNum); break; default: - return; + break; } - count_screens(); + count_screens_of_step(); - hedera_snprintf( - ctx.title, - DISPLAY_SIZE, - "Token (%u/%u)", - ctx.display_index, - ctx.display_count - ); + hedera_snprintf(ctx.title, DISPLAY_SIZE, "Token (%u/%u)", ctx.current_page, + ctx.page_count); } -void reformat_tokens_accounts(char *title_part, uint8_t transfer_index) { - hedera_snprintf( - ctx.full, - ACCOUNT_ID_SIZE, - "%llu.%llu.%llu", - ctx.transaction.data.cryptoTransfer.tokenTransfers[0].transfers[transfer_index].accountID.shardNum, - ctx.transaction.data.cryptoTransfer.tokenTransfers[0].transfers[transfer_index].accountID.realmNum, - ctx.transaction.data.cryptoTransfer.tokenTransfers[0].transfers[transfer_index].accountID.accountNum - ); - - count_screens(); - - hedera_snprintf( - ctx.title, - DISPLAY_SIZE, - "%s (%u/%u)", - title_part, - ctx.display_index, - ctx.display_count - ); +void reformat_tokens_accounts(char* title_part, uint8_t transfer_index) { + hedera_snprintf(ctx.full, ACCOUNT_ID_SIZE, "%llu.%llu.%llu", + ctx.transaction.data.cryptoTransfer.tokenTransfers[ 0 ] + .transfers[ transfer_index ] + .accountID.shardNum, + ctx.transaction.data.cryptoTransfer.tokenTransfers[ 0 ] + .transfers[ transfer_index ] + .accountID.realmNum, + ctx.transaction.data.cryptoTransfer.tokenTransfers[ 0 ] + .transfers[ transfer_index ] + .accountID.account.accountNum); + + count_screens_of_step(); + + hedera_snprintf(ctx.title, DISPLAY_SIZE, "%s (%u/%u)", title_part, + ctx.current_page, ctx.page_count); } void reformat_senders() { @@ -569,7 +583,13 @@ void reformat_senders() { reformat_accounts("Account", 0); break; + case Create: + case Update: + reformat_stake_target(); + break; + case Associate: + case Dissociate: case TokenMint: case TokenBurn: reformat_token(); @@ -587,11 +607,91 @@ void reformat_senders() { return; } - shift_display(); + repaint(); +} + +void reformat_collect_rewards() { + switch (ctx.type) { + case Create: { + bool declineRewards = + ctx.transaction.data.cryptoCreateAccount.decline_reward; + hedera_snprintf(ctx.full, MAX_MEMO_SIZE, "%s", + !declineRewards ? "Yes" : "No"); + } break; + + case Update: { + if (ctx.transaction.data.cryptoUpdateAccount.has_decline_reward) { + bool declineRewards = ctx.transaction.data.cryptoUpdateAccount + .decline_reward.value; + hedera_snprintf(ctx.full, MAX_MEMO_SIZE, "%s", + declineRewards ? "No" : "Yes"); + } else { + hedera_snprintf(ctx.full, MAX_MEMO_SIZE, "%s", "-"); + } + } break; + + default: + break; + } + + count_screens_of_step(); // 1 + + hedera_snprintf(ctx.title, DISPLAY_SIZE, "Collect Rewards?", + ctx.current_page, ctx.page_count); + + repaint(); +} + +void reformat_target_account() { + switch (ctx.type) { + case Associate: { + bool hasAccount = ctx.transaction.data.tokenAssociate.has_account; + if (hasAccount) { + hedera_snprintf( + ctx.full, ACCOUNT_ID_SIZE, "%llu.%llu.%llu", + ctx.transaction.data.tokenAssociate.account.shardNum, + ctx.transaction.data.tokenAssociate.account.realmNum, + ctx.transaction.data.tokenAssociate.account.account + .accountNum); + } else { + hedera_snprintf( + ctx.full, ACCOUNT_ID_SIZE, "%llu.%llu.%llu", + ctx.transaction.transactionID.accountID.shardNum, + ctx.transaction.transactionID.accountID.realmNum, + ctx.transaction.transactionID.accountID.account.accountNum); + } + } break; + + case Dissociate: { + bool hasAccount = ctx.transaction.data.tokenDissociate.has_account; + if (hasAccount) { + hedera_snprintf( + ctx.full, ACCOUNT_ID_SIZE, "%llu.%llu.%llu", + ctx.transaction.data.tokenDissociate.account.shardNum, + ctx.transaction.data.tokenDissociate.account.realmNum, + ctx.transaction.data.tokenDissociate.account.account + .accountNum); + } else { + hedera_snprintf( + ctx.full, ACCOUNT_ID_SIZE, "%llu.%llu.%llu", + ctx.transaction.transactionID.accountID.shardNum, + ctx.transaction.transactionID.accountID.realmNum, + ctx.transaction.transactionID.accountID.account.accountNum); + } + } break; + + default: + break; + } } void reformat_recipients() { switch (ctx.type) { + case Create: + case Update: + reformat_collect_rewards(); + break; + case TokenTransfer: reformat_tokens_accounts("Recipient", ctx.transfer_to_index); break; @@ -604,252 +704,245 @@ void reformat_recipients() { return; } - shift_display(); + repaint(); } void reformat_amount() { switch (ctx.type) { case Create: hedera_snprintf( - ctx.full, - DISPLAY_SIZE * 3, - "%s hbar", - hedera_format_tinybar(ctx.transaction.data.cryptoCreateAccount.initialBalance) - ); + ctx.full, DISPLAY_SIZE * 3, "%s hbar", + hedera_format_tinybar( + ctx.transaction.data.cryptoCreateAccount.initialBalance)); break; + case Update: { + if (ctx.transaction.data.cryptoUpdateAccount + .has_accountIDToUpdate) { + hedera_snprintf(ctx.full, ACCOUNT_ID_SIZE, "%llu.%llu.%llu", + ctx.transaction.data.cryptoUpdateAccount + .accountIDToUpdate.shardNum, + ctx.transaction.data.cryptoUpdateAccount + .accountIDToUpdate.realmNum, + ctx.transaction.data.cryptoUpdateAccount + .accountIDToUpdate.account.accountNum); + } else { + hedera_snprintf( + ctx.full, ACCOUNT_ID_SIZE, "%llu.%llu.%llu", + ctx.transaction.transactionID.accountID.shardNum, + ctx.transaction.transactionID.accountID.realmNum, + ctx.transaction.transactionID.accountID.account.accountNum); + } + } break; + case Transfer: - hedera_snprintf( - ctx.full, - DISPLAY_SIZE * 3, - "%s hbar", - hedera_format_tinybar(ctx.transaction.data.cryptoTransfer.transfers.accountAmounts[ctx.transfer_to_index].amount) - ); + hedera_snprintf(ctx.full, DISPLAY_SIZE * 3, "%s hbar", + hedera_format_tinybar( + ctx.transaction.data.cryptoTransfer.transfers + .accountAmounts[ ctx.transfer_to_index ] + .amount)); break; case TokenMint: - validate_decimals(ctx.transaction.data.tokenMint.expected_decimals.value); hedera_snprintf( - ctx.full, - DISPLAY_SIZE * 3, - "%s", + ctx.full, DISPLAY_SIZE * 3, "%s", hedera_format_amount( ctx.transaction.data.tokenMint.amount, - ctx.transaction.data.tokenMint.expected_decimals.value - ) - ); + 0)); // Must be lowest denomination without decimals break; case TokenBurn: - validate_decimals(ctx.transaction.data.tokenBurn.expected_decimals.value); hedera_snprintf( - ctx.full, - DISPLAY_SIZE * 3, - "%s", + ctx.full, DISPLAY_SIZE * 3, "%s", hedera_format_amount( ctx.transaction.data.tokenBurn.amount, - ctx.transaction.data.tokenBurn.expected_decimals.value - ) - ); + 0)); // Must be lowest denomination without decimals break; + case Associate: + case Dissociate: + reformat_target_account(); + break; + case TokenTransfer: - validate_decimals(ctx.transaction.data.cryptoTransfer.tokenTransfers[0].expected_decimals.value); hedera_snprintf( - ctx.full, - DISPLAY_SIZE * 3, - "%s", + ctx.full, DISPLAY_SIZE * 3, "%s", hedera_format_amount( - ctx.transaction.data.cryptoTransfer.tokenTransfers[0].transfers[ctx.transfer_to_index].amount, - ctx.transaction.data.cryptoTransfer.tokenTransfers[0].expected_decimals.value - ) - ); + ctx.transaction.data.cryptoTransfer.tokenTransfers[ 0 ] + .transfers[ ctx.transfer_to_index ] + .amount, + ctx.transaction.data.cryptoTransfer.tokenTransfers[ 0 ] + .expected_decimals.value)); break; default: - return; + break; } - count_screens(); + count_screens_of_step(); - hedera_snprintf( - ctx.title, - DISPLAY_SIZE, - "%s (%u/%u)", - ctx.type == Create ? "Balance" : "Amount", - ctx.display_index, - ctx.display_count - ); - - shift_display(); + switch (ctx.type) { + case Update: + case Associate: + case Dissociate: + hedera_snprintf(ctx.title, DISPLAY_SIZE, "%s (%u/%u)", "Updating", + ctx.current_page, ctx.page_count); + break; + case Create: + hedera_snprintf(ctx.title, DISPLAY_SIZE, "%s (%u/%u)", "Balance", + ctx.current_page, ctx.page_count); + break; + default: + hedera_snprintf(ctx.title, DISPLAY_SIZE, "%s (%u/%u)", "Amount", + ctx.current_page, ctx.page_count); + break; + } + + repaint(); } void reformat_fee() { - hedera_snprintf( - ctx.full, - DISPLAY_SIZE * 3, - "%s hbar", - hedera_format_tinybar(ctx.transaction.transactionFee) - ); + hedera_snprintf(ctx.full, DISPLAY_SIZE * 3, "%s hbar", + hedera_format_tinybar(ctx.transaction.transactionFee)); - count_screens(); + count_screens_of_step(); - hedera_snprintf( - ctx.title, - DISPLAY_SIZE, - "Max Fee (%u/%u)", - ctx.display_index, - ctx.display_count - ); - - shift_display(); + hedera_snprintf(ctx.title, DISPLAY_SIZE, "Max Fee (%u/%u)", + ctx.current_page, ctx.page_count); + + repaint(); } void reformat_memo() { hedera_snprintf( - ctx.full, - MAX_MEMO_SIZE, - "%s", - strlen(ctx.transaction.memo) > 0 ? ctx.transaction.memo : "" - ); - - if (strlen(ctx.full) > MAX_MEMO_SIZE) { - // :grimacing: - THROW(EXCEPTION_MALFORMED_APDU); - } + ctx.full, MAX_MEMO_SIZE, "%s", + strlen(ctx.transaction.memo) > 0 ? ctx.transaction.memo : ""); - count_screens(); + count_screens_of_step(); - hedera_snprintf( - ctx.title, - DISPLAY_SIZE, - "Memo (%u/%u)", - ctx.display_index, - ctx.display_count - ); - - shift_display(); + hedera_snprintf(ctx.title, DISPLAY_SIZE, "Memo (%u/%u)", ctx.current_page, + ctx.page_count); + + repaint(); } void handle_transaction_body() { explicit_bzero(ctx.summary_line_1, DISPLAY_SIZE + 1); explicit_bzero(ctx.summary_line_2, DISPLAY_SIZE + 1); - explicit_bzero(ctx.full, ACCOUNT_ID_SIZE + 1); + explicit_bzero(ctx.full, DISPLAY_SIZE * 3 + 1); explicit_bzero(ctx.partial, DISPLAY_SIZE + 1); // Step 1, Unknown Type, Screen 1 of 1 ctx.step = Summary; ctx.type = Unknown; - ctx.display_index = 1; - ctx.display_count = 1; + ctx.current_page = 1; + ctx.page_count = 1; - // + // // with Key #X? - hedera_snprintf( - ctx.summary_line_2, - DISPLAY_SIZE, - "with Key #%u?", - ctx.key_index - ); + hedera_snprintf(ctx.summary_line_2, DISPLAY_SIZE, "with Key #%u?", + ctx.key_index); // Handle parsed protobuf message of transaction body switch (ctx.transaction.which_data) { - case HederaTransactionBody_cryptoCreateAccount_tag: - // Create Account Transaction + case Hedera_TransactionBody_cryptoCreateAccount_tag: ctx.type = Create; - hedera_snprintf( - ctx.summary_line_1, - DISPLAY_SIZE, - "Create Account" - ); + hedera_snprintf(ctx.summary_line_1, DISPLAY_SIZE, "Create Account"); + break; + case Hedera_TransactionBody_cryptoUpdateAccount_tag: + ctx.type = Update; + hedera_snprintf(ctx.summary_line_1, DISPLAY_SIZE, "Update Account"); break; - case HederaTransactionBody_tokenAssociate_tag: + case Hedera_TransactionBody_tokenAssociate_tag: ctx.type = Associate; - hedera_snprintf( - ctx.summary_line_1, - DISPLAY_SIZE, - "Associate Token" - ); + hedera_snprintf(ctx.summary_line_1, DISPLAY_SIZE, + "Associate Token"); + break; + case Hedera_TransactionBody_tokenDissociate_tag: + ctx.type = Dissociate; + hedera_snprintf(ctx.summary_line_1, DISPLAY_SIZE, + "Dissociate Token"); break; - case HederaTransactionBody_tokenMint_tag: + case Hedera_TransactionBody_tokenMint_tag: ctx.type = TokenMint; - hedera_snprintf( - ctx.summary_line_1, - DISPLAY_SIZE, - "Mint Token" - ); - + hedera_snprintf(ctx.summary_line_1, DISPLAY_SIZE, "Mint Token"); break; - case HederaTransactionBody_tokenBurn_tag: + case Hedera_TransactionBody_tokenBurn_tag: ctx.type = TokenBurn; - hedera_snprintf( - ctx.summary_line_1, - DISPLAY_SIZE, - "Burn Token" - ); - + hedera_snprintf(ctx.summary_line_1, DISPLAY_SIZE, "Burn Token"); break; - case HederaTransactionBody_cryptoTransfer_tag: { - validate_transfer(); - - if ( // Only 1 Account (Sender), Fee 1 Tinybar, and Value 0 Tinybar - ctx.transaction.data.cryptoTransfer.transfers.accountAmounts[0].amount == 0 && - ctx.transaction.data.cryptoTransfer.transfers.accountAmounts_count == 1 && - ctx.transaction.transactionFee == 1 - ) { - // Verify Account Transaction + case Hedera_TransactionBody_cryptoTransfer_tag: { + if ( + /* + * "Verify Account Transaction" + * + * This is an arbitary transfer transaction that is designed + * to fail always. Transfer 0 hbar to no-one with a max fee + * of 1 tinybar. If this transaction fails with + * "insufficient fee" rather than "invalid signature", then + * we know that the signature provided by this key is indeed + * associated with the operator account for the transaction. + */ + ctx.transaction.data.cryptoTransfer.transfers + .accountAmounts[ 0 ] + .amount == 0 && + ctx.transaction.data.cryptoTransfer.transfers + .accountAmounts_count == 1 && + ctx.transaction.transactionFee == 1) { ctx.type = Verify; - hedera_snprintf( - ctx.summary_line_1, - DISPLAY_SIZE, - "Verify Account" - ); - } else if (ctx.transaction.data.cryptoTransfer.transfers.accountAmounts_count == 2) { - // Number of Accounts == 2 - // Some other Transfer Transaction + hedera_snprintf(ctx.summary_line_1, DISPLAY_SIZE, + "Verify Account"); + } else if (ctx.transaction.data.cryptoTransfer.transfers + .accountAmounts_count == 2) { + // Hbar Transfer between two accounts ctx.type = Transfer; - hedera_snprintf( - ctx.summary_line_1, - DISPLAY_SIZE, - "Send Hbar" - ); + hedera_snprintf(ctx.summary_line_1, DISPLAY_SIZE, "Send Hbar"); - // Determine Sender based on amount + // Determine Sender based on transfers.accountAmounts ctx.transfer_to_index = 1; ctx.transfer_from_index = 0; - if (ctx.transaction.data.cryptoTransfer.transfers.accountAmounts[0].amount > 0) { + if (ctx.transaction.data.cryptoTransfer.transfers + .accountAmounts[ 0 ] + .amount > 0) { ctx.transfer_to_index = 0; ctx.transfer_from_index = 1; } - } else if (ctx.transaction.data.cryptoTransfer.tokenTransfers_count == 1) { + } else if (ctx.transaction.data.cryptoTransfer + .tokenTransfers_count == 1) { + // Fungible Token Transfer (two token transfers with one + // transfer each) ctx.type = TokenTransfer; + validate_token_transfer(); + hedera_snprintf( - ctx.summary_line_1, - DISPLAY_SIZE, - "Send %llu.%llu.%llu", - ctx.transaction.data.cryptoTransfer.tokenTransfers[0].token.shardNum, - ctx.transaction.data.cryptoTransfer.tokenTransfers[0].token.realmNum, - ctx.transaction.data.cryptoTransfer.tokenTransfers[0].token.tokenNum - ); + ctx.summary_line_1, DISPLAY_SIZE, "Send %llu.%llu.%llu", + ctx.transaction.data.cryptoTransfer.tokenTransfers[ 0 ] + .token.shardNum, + ctx.transaction.data.cryptoTransfer.tokenTransfers[ 0 ] + .token.realmNum, + ctx.transaction.data.cryptoTransfer.tokenTransfers[ 0 ] + .token.tokenNum); // Determine Sender based on amount ctx.transfer_from_index = 0; ctx.transfer_to_index = 1; - if (ctx.transaction.data.cryptoTransfer.tokenTransfers[0].transfers[0].amount > 0) { + if (ctx.transaction.data.cryptoTransfer.tokenTransfers[ 0 ] + .transfers[ 0 ] + .amount > 0) { ctx.transfer_from_index = 1; ctx.transfer_to_index = 0; } @@ -862,52 +955,13 @@ void handle_transaction_body() { default: // Unsupported THROW(EXCEPTION_MALFORMED_APDU); + break; } UX_DISPLAY(ui_tx_summary_step, NULL); } #elif defined(TARGET_NANOX) || defined(TARGET_NANOS2) - -static struct sign_tx_context_t { - // ui common - uint32_t key_index; - uint8_t transfer_from_index; - uint8_t transfer_to_index; - - // Transaction Summary - char summary_line_1[DISPLAY_SIZE + 1]; - char summary_line_2[DISPLAY_SIZE + 1]; - char senders_title[DISPLAY_SIZE + 1]; - char amount_title[DISPLAY_SIZE + 1]; - char partial[DISPLAY_SIZE + 1]; - - enum TransactionType type; - - // Transaction Operator - char operator[DISPLAY_SIZE * 2 + 1]; - - // Transaction Senders - char senders[DISPLAY_SIZE * 2 + 1]; - - // Transaction Recipients - char recipients[DISPLAY_SIZE * 2 + 1]; - - // Transaction Amount - char amount[DISPLAY_SIZE * 2 + 1]; - - // Transaction Fee - char fee[DISPLAY_SIZE * 2 + 1]; - - // Transaction Memo - char memo[MAX_MEMO_SIZE + 1]; - - // Parsed transaction - HederaTransactionBody transaction; -} ctx; - -// UI Definition for Nano X - // Confirm Callback unsigned int io_seproxyhal_tx_approve(const bagl_element_t* e) { io_exchange_with_code(EXCEPTION_OK, 64); @@ -922,15 +976,8 @@ unsigned int io_seproxyhal_tx_reject(const bagl_element_t* e) { return 0; } -UX_STEP_NOCB( - ux_tx_flow_1_step, - bnn, - { - "Transaction Summary", - ctx.summary_line_1, - ctx.summary_line_2 - } -); +UX_STEP_NOCB(ux_tx_flow_1_step, bnn, + {"Transaction Summary", ctx.summary_line_1, ctx.summary_line_2}); UX_STEP_NOCB( ux_tx_flow_2_step, @@ -941,111 +988,75 @@ UX_STEP_NOCB( } ); -UX_STEP_NOCB( - ux_tx_flow_3_step, - bnnn_paging, - { - .title = (char*) ctx.senders_title, - .text = (char*) ctx.senders - } -); +UX_STEP_NOCB(ux_tx_flow_3_step, bnnn_paging, + {.title = (char*)ctx.senders_title, .text = (char*)ctx.senders}); -UX_STEP_NOCB( - ux_tx_flow_4_step, - bnnn_paging, - { - .title = "Recipient", - .text = (char*) ctx.recipients - } -); +UX_STEP_NOCB(ux_tx_flow_4_step, bnnn_paging, + {.title = (char*)ctx.recipients_title, + .text = (char*)ctx.recipients}); -UX_STEP_NOCB( - ux_tx_flow_5_step, - bnnn_paging, - { - .title = (char*) ctx.amount_title, - .text = (char*) ctx.amount - } -); +UX_STEP_NOCB(ux_tx_flow_5_step, bnnn_paging, + {.title = (char*)ctx.amount_title, .text = (char*)ctx.amount}); -UX_STEP_NOCB( - ux_tx_flow_6_step, - bnnn_paging, - { - .title = "Max Fee", - .text = (char*) ctx.fee - } -); +UX_STEP_NOCB(ux_tx_flow_6_step, bnnn_paging, + {.title = "Max Fee", .text = (char*)ctx.fee}); -UX_STEP_NOCB( - ux_tx_flow_7_step, - bnnn_paging, - { - .title = "Memo", - .text = (char*) ctx.memo - } -); +UX_STEP_NOCB(ux_tx_flow_7_step, bnnn_paging, + {.title = "Memo", .text = (char*)ctx.memo}); -UX_STEP_VALID( - ux_tx_flow_8_step, - pb, - io_seproxyhal_tx_approve(NULL), - { - &C_icon_validate_14, - "Confirm" - } -); +UX_STEP_VALID(ux_tx_flow_8_step, pb, io_seproxyhal_tx_approve(NULL), + {&C_icon_validate_14, "Confirm"}); -UX_STEP_VALID( - ux_tx_flow_9_step, - pb, - io_seproxyhal_tx_reject(NULL), - { - &C_icon_crossmark, - "Reject" - } -); +UX_STEP_VALID(ux_tx_flow_9_step, pb, io_seproxyhal_tx_reject(NULL), + {&C_icon_crossmark, "Reject"}); // Transfer UX Flow -UX_DEF( - ux_transfer_flow, - &ux_tx_flow_1_step, - &ux_tx_flow_2_step, - &ux_tx_flow_3_step, - &ux_tx_flow_4_step, - &ux_tx_flow_5_step, - &ux_tx_flow_6_step, - &ux_tx_flow_7_step, - &ux_tx_flow_8_step, - &ux_tx_flow_9_step -); +// Summary, Operator, Senders, Recipients, Amount, Fee, Memo, Confirm, Deny +UX_DEF(ux_transfer_flow, &ux_tx_flow_1_step, &ux_tx_flow_2_step, + &ux_tx_flow_3_step, &ux_tx_flow_4_step, &ux_tx_flow_5_step, + &ux_tx_flow_6_step, &ux_tx_flow_7_step, &ux_tx_flow_8_step, + &ux_tx_flow_9_step); // Create UX Flow -UX_DEF( - ux_create_flow, - &ux_tx_flow_1_step, - &ux_tx_flow_2_step, - &ux_tx_flow_5_step, - &ux_tx_flow_6_step, - &ux_tx_flow_7_step, - &ux_tx_flow_8_step, - &ux_tx_flow_9_step -); +// Summary, Operator, Senders (Stake To), Recipients (Collect Rewards), Amount +// (Initial Balance), Fee, Memo, Confirm, Deny +UX_DEF(ux_create_flow, &ux_tx_flow_1_step, &ux_tx_flow_2_step, + &ux_tx_flow_3_step, &ux_tx_flow_4_step, &ux_tx_flow_5_step, + &ux_tx_flow_6_step, &ux_tx_flow_7_step, &ux_tx_flow_8_step, + &ux_tx_flow_9_step); + +// Update UX Flow +// Summary, Operator, Senders (Stake To), Recipients (Collect Rewards), Amount +// (Updated Account), Fee, Memo, Confirm, Deny +UX_DEF(ux_update_flow, &ux_tx_flow_1_step, &ux_tx_flow_2_step, + &ux_tx_flow_3_step, &ux_tx_flow_4_step, &ux_tx_flow_5_step, + &ux_tx_flow_6_step, &ux_tx_flow_7_step, &ux_tx_flow_8_step, + &ux_tx_flow_9_step); // Verify UX Flow -UX_DEF( - ux_verify_flow, - &ux_tx_flow_1_step, - &ux_tx_flow_3_step, - &ux_tx_flow_8_step, - &ux_tx_flow_9_step -); +// Summary, Senders (Account), Confirm, Deny +UX_DEF(ux_verify_flow, &ux_tx_flow_1_step, &ux_tx_flow_3_step, + &ux_tx_flow_8_step, &ux_tx_flow_9_step); + +// TokenMint, TokenBurn +// Summary, Operator, Senders (Token), Amount, Fee, Memo, Confirm, Deny +UX_DEF(ux_mint_flow, &ux_tx_flow_1_step, &ux_tx_flow_2_step, &ux_tx_flow_4_step, + &ux_tx_flow_5_step, &ux_tx_flow_6_step, &ux_tx_flow_7_step, + &ux_tx_flow_8_step, &ux_tx_flow_9_step); + +// Associate, Dissociate +// Summary, Operator, Senders (Token), Recipients (Account), Fee, Memo, Confirm, +// Deny +UX_DEF(ux_associate_flow, &ux_tx_flow_1_step, &ux_tx_flow_2_step, + &ux_tx_flow_3_step, &ux_tx_flow_4_step, &ux_tx_flow_6_step, + &ux_tx_flow_7_step, &ux_tx_flow_8_step, &ux_tx_flow_9_step); void handle_transaction_body() { explicit_bzero(ctx.summary_line_1, DISPLAY_SIZE + 1); explicit_bzero(ctx.summary_line_2, DISPLAY_SIZE + 1); explicit_bzero(ctx.amount_title, DISPLAY_SIZE + 1); explicit_bzero(ctx.senders_title, DISPLAY_SIZE + 1); + explicit_bzero(ctx.recipients_title, DISPLAY_SIZE + 1); explicit_bzero(ctx.operator, DISPLAY_SIZE * 2 + 1); explicit_bzero(ctx.senders, DISPLAY_SIZE * 2 + 1); explicit_bzero(ctx.recipients, DISPLAY_SIZE * 2 + 1); @@ -1055,219 +1066,354 @@ void handle_transaction_body() { ctx.type = Unknown; - // + // // with Key #X? - hedera_snprintf( - ctx.summary_line_2, - DISPLAY_SIZE, - "with Key #%u?", - ctx.key_index - ); + hedera_snprintf(ctx.summary_line_2, DISPLAY_SIZE, "with Key #%u?", + ctx.key_index); - hedera_snprintf( - ctx.operator, - DISPLAY_SIZE * 2, - "%llu.%llu.%llu", - ctx.transaction.transactionID.accountID.shardNum, - ctx.transaction.transactionID.accountID.realmNum, - ctx.transaction.transactionID.accountID.accountNum - ); + hedera_snprintf(ctx.operator, DISPLAY_SIZE * 2, "%llu.%llu.%llu", + ctx.transaction.transactionID.accountID.shardNum, + ctx.transaction.transactionID.accountID.realmNum, + ctx.transaction.transactionID.accountID.account); - hedera_snprintf( - ctx.fee, - DISPLAY_SIZE * 2, - "%s hbar", - hedera_format_tinybar(ctx.transaction.transactionFee) - ); + hedera_snprintf(ctx.fee, DISPLAY_SIZE * 2, "%s hbar", + hedera_format_tinybar(ctx.transaction.transactionFee)); - hedera_snprintf( - ctx.memo, - MAX_MEMO_SIZE, - "%s", - ctx.transaction.memo - ); - - hedera_sprintf( - ctx.amount_title, - "Amount" - ); - - hedera_sprintf( - ctx.senders_title, - "Sender" - ); + hedera_snprintf(ctx.memo, MAX_MEMO_SIZE, "%s", ctx.transaction.memo); + + hedera_sprintf(ctx.amount_title, "Amount"); + hedera_sprintf(ctx.senders_title, "Sender"); + hedera_sprintf(ctx.recipients_title, "Recipient"); // Handle parsed protobuf message of transaction body switch (ctx.transaction.which_data) { - case HederaTransactionBody_cryptoCreateAccount_tag: + case Hedera_TransactionBody_cryptoCreateAccount_tag: { ctx.type = Create; - // Create Account Transaction - hedera_sprintf( - ctx.summary_line_1, - "Create Account" - ); - hedera_sprintf( - ctx.amount_title, - "Balance" - ); + hedera_sprintf(ctx.summary_line_1, "Create Account"); + hedera_sprintf(ctx.senders_title, "Stake To"); + hedera_sprintf(ctx.recipients_title, "Collect Rewards?"); + hedera_sprintf(ctx.amount_title, "Balance"); + + char stake_target[ ACCOUNT_ID_SIZE ]; + + if (ctx.transaction.data.cryptoCreateAccount.which_staked_id == + Hedera_CryptoCreateTransactionBody_staked_account_id_tag) { + hedera_snprintf(stake_target, ACCOUNT_ID_SIZE, "%llu.%llu.%llu", + ctx.transaction.data.cryptoCreateAccount + .staked_id.staked_account_id.shardNum, + ctx.transaction.data.cryptoCreateAccount + .staked_id.staked_account_id.realmNum, + ctx.transaction.data.cryptoCreateAccount + .staked_id.staked_account_id.account); + } else if (ctx.transaction.data.cryptoCreateAccount + .which_staked_id == + Hedera_CryptoCreateTransactionBody_staked_node_id_tag) { + hedera_snprintf(stake_target, ACCOUNT_ID_SIZE, "Node %lld", + ctx.transaction.data.cryptoCreateAccount + .staked_id.staked_node_id); + } else { + hedera_snprintf(stake_target, DISPLAY_SIZE * 2, "None"); + } + + hedera_snprintf(ctx.senders, DISPLAY_SIZE * 2, "%s", stake_target); + hedera_snprintf( - ctx.amount, - DISPLAY_SIZE * 2, - "%s hbar", - hedera_format_tinybar(ctx.transaction.data.cryptoCreateAccount.initialBalance) - ); - break; + ctx.recipients, DISPLAY_SIZE * 2, "%s", + ctx.transaction.data.cryptoCreateAccount.decline_reward + ? "No" + : "Yes"); - case HederaTransactionBody_tokenAssociate_tag: + hedera_snprintf( + ctx.amount, DISPLAY_SIZE * 2, "%s hbar", + hedera_format_tinybar( + ctx.transaction.data.cryptoCreateAccount.initialBalance)); + } break; + + case Hedera_TransactionBody_cryptoUpdateAccount_tag: { + ctx.type = Update; + hedera_sprintf(ctx.summary_line_1, "Update Account"); + hedera_sprintf(ctx.senders_title, "Stake To"); + hedera_sprintf(ctx.recipients_title, "Collect Rewards"); + hedera_sprintf(ctx.amount_title, "Updating"); + + const char stake_target[ DISPLAY_SIZE * 2 ]; + + if (ctx.transaction.data.cryptoUpdateAccount.which_staked_id == + Hedera_CryptoUpdateTransactionBody_staked_account_id_tag) { + hedera_snprintf(stake_target, DISPLAY_SIZE * 2, + "%llu.%llu.%llu", + ctx.transaction.data.cryptoUpdateAccount + .staked_id.staked_account_id.shardNum, + ctx.transaction.data.cryptoUpdateAccount + .staked_id.staked_account_id.realmNum, + ctx.transaction.data.cryptoUpdateAccount + .staked_id.staked_account_id.account); + } else if (ctx.transaction.data.cryptoUpdateAccount + .which_staked_id == + Hedera_CryptoUpdateTransactionBody_staked_node_id_tag) { + hedera_snprintf(stake_target, ACCOUNT_ID_SIZE, "Node %lld", + ctx.transaction.data.cryptoUpdateAccount + .staked_id.staked_node_id); + } else { + hedera_snprintf(stake_target, DISPLAY_SIZE * 2, "None"); + } + + hedera_snprintf(ctx.senders, DISPLAY_SIZE * 2, "%s", stake_target); + + if (ctx.transaction.data.cryptoUpdateAccount.has_decline_reward) { + bool declineRewards = ctx.transaction.data.cryptoUpdateAccount + .decline_reward.value; + hedera_snprintf(ctx.recipients, DISPLAY_SIZE, "%s", + declineRewards ? "No" : "Yes"); + } else { + hedera_snprintf(ctx.recipients, DISPLAY_SIZE, "%s", "-"); + } + + if (ctx.transaction.data.cryptoUpdateAccount + .has_accountIDToUpdate) { + Hedera_AccountID updatedAccount = + ctx.transaction.data.cryptoUpdateAccount.accountIDToUpdate; + hedera_snprintf(ctx.amount, DISPLAY_SIZE * 2, "%llu.%llu.%llu", + updatedAccount.shardNum, + updatedAccount.realmNum, + updatedAccount.account); + } else { + hedera_snprintf( + ctx.amount, DISPLAY_SIZE * 2, "%llu.%llu.%llu", + ctx.transaction.transactionID.accountID.shardNum, + ctx.transaction.transactionID.accountID.realmNum, + ctx.transaction.transactionID.accountID.account); + } + } break; + + case Hedera_TransactionBody_tokenAssociate_tag: { ctx.type = Associate; - hedera_sprintf( - ctx.summary_line_1, - "Associate Token" - ); + hedera_sprintf(ctx.summary_line_1, "Associate Token"); + hedera_sprintf(ctx.senders_title, "Token"); + hedera_sprintf(ctx.recipients_title, "Account"); + + hedera_snprintf( + ctx.senders, DISPLAY_SIZE * 2, "%llu.%llu.%llu", + ctx.transaction.data.tokenAssociate.tokens[ 0 ].shardNum, + ctx.transaction.data.tokenAssociate.tokens[ 0 ].realmNum, + ctx.transaction.data.tokenAssociate.tokens[ 0 ].tokenNum); + + bool hasAccount = ctx.transaction.data.tokenAssociate.has_account; + + if (hasAccount) { + hedera_snprintf( + ctx.recipients, ACCOUNT_ID_SIZE, "%llu.%llu.%llu", + ctx.transaction.data.tokenAssociate.account.shardNum, + ctx.transaction.data.tokenAssociate.account.realmNum, + ctx.transaction.data.tokenAssociate.account.account + .accountNum); + } else { + hedera_snprintf( + ctx.recipients, ACCOUNT_ID_SIZE, "%llu.%llu.%llu", + ctx.transaction.transactionID.accountID.shardNum, + ctx.transaction.transactionID.accountID.realmNum, + ctx.transaction.transactionID.accountID.account.accountNum); + } + } break; + + case Hedera_TransactionBody_tokenDissociate_tag: { + ctx.type = Dissociate; - hedera_sprintf( - ctx.senders_title, - "Token"); + hedera_sprintf(ctx.summary_line_1, "Dissociate Token"); + hedera_sprintf(ctx.senders_title, "Token"); + hedera_sprintf(ctx.recipients_title, "Account"); hedera_snprintf( - ctx.senders, - DISPLAY_SIZE * 2, - "%llu.%llu.%llu", - ctx.transaction.data.cryptoTransfer.tokenTransfers[0].token.shardNum, - ctx.transaction.data.cryptoTransfer.tokenTransfers[0].token.realmNum, - ctx.transaction.data.cryptoTransfer.tokenTransfers[0].token.tokenNum - ); + ctx.senders, DISPLAY_SIZE * 2, "%llu.%llu.%llu", + ctx.transaction.data.tokenDissociate.tokens[ 0 ].shardNum, + ctx.transaction.data.tokenDissociate.tokens[ 0 ].realmNum, + ctx.transaction.data.tokenDissociate.tokens[ 0 ].tokenNum); - break; + bool hasAccount = ctx.transaction.data.tokenAssociate.has_account; + + if (hasAccount) { + hedera_snprintf( + ctx.recipients, ACCOUNT_ID_SIZE, "%llu.%llu.%llu", + ctx.transaction.data.tokenDissociate.account.shardNum, + ctx.transaction.data.tokenDissociate.account.realmNum, + ctx.transaction.data.tokenDissociate.account.account + .accountNum); + } else { + hedera_snprintf( + ctx.recipients, ACCOUNT_ID_SIZE, "%llu.%llu.%llu", + ctx.transaction.transactionID.accountID.shardNum, + ctx.transaction.transactionID.accountID.realmNum, + ctx.transaction.transactionID.accountID.account.accountNum); + } + } break; + + case Hedera_TransactionBody_tokenMint_tag: { + ctx.type = TokenMint; + + hedera_sprintf(ctx.summary_line_1, "Mint Token"); + + hedera_sprintf(ctx.senders_title, "Token"); + + hedera_snprintf(ctx.senders, DISPLAY_SIZE * 2, "%llu.%llu.%llu", + ctx.transaction.data.tokenMint.token.shardNum, + ctx.transaction.data.tokenMint.token.realmNum, + ctx.transaction.data.tokenMint.token.tokenNum); + + hedera_snprintf( + ctx.amount, DISPLAY_SIZE * 2, "%s", + hedera_format_amount(ctx.transaction.data.tokenMint.amount, + 0)); // always lowest denomination of token + } break; + + case Hedera_TransactionBody_tokenBurn_tag: { + ctx.type = TokenBurn; - case HederaTransactionBody_cryptoTransfer_tag: { - validate_transfer(); + hedera_sprintf(ctx.summary_line_1, "Burn Token"); + hedera_sprintf(ctx.senders_title, "Token"); + + hedera_snprintf(ctx.senders, DISPLAY_SIZE * 2, "%llu.%llu.%llu", + ctx.transaction.data.tokenBurn.token.shardNum, + ctx.transaction.data.tokenBurn.token.realmNum, + ctx.transaction.data.tokenBurn.token.tokenNum); + + hedera_snprintf( + ctx.amount, DISPLAY_SIZE * 2, "%s", + hedera_format_amount(ctx.transaction.data.tokenBurn.amount, + 0)); // always lowest denomination of token + } break; + + case Hedera_TransactionBody_cryptoTransfer_tag: { if ( // Only 1 Account (Sender), Fee 1 Tinybar, and Value 0 Tinybar - ctx.transaction.data.cryptoTransfer.transfers.accountAmounts[0].amount == 0 && - ctx.transaction.data.cryptoTransfer.transfers.accountAmounts_count == 1 && - ctx.transaction.transactionFee == 1 - ) { + ctx.transaction.data.cryptoTransfer.transfers + .accountAmounts[ 0 ] + .amount == 0 && + ctx.transaction.data.cryptoTransfer.transfers + .accountAmounts_count == 1 && + ctx.transaction.transactionFee == 1) { // Verify Account Transaction ctx.type = Verify; - - hedera_sprintf( - ctx.summary_line_1, - "Verify Account" - ); - - hedera_sprintf( - ctx.senders_title, - "Account" - ); - - hedera_snprintf( - ctx.senders, - DISPLAY_SIZE * 2, - "%llu.%llu.%llu", - ctx.transaction.data.cryptoTransfer.transfers.accountAmounts[0].accountID.shardNum, - ctx.transaction.data.cryptoTransfer.transfers.accountAmounts[0].accountID.realmNum, - ctx.transaction.data.cryptoTransfer.transfers.accountAmounts[0].accountID.accountNum - ); - hedera_snprintf( - ctx.amount, - DISPLAY_SIZE * 2, - "%s hbar", - hedera_format_tinybar(ctx.transaction.data.cryptoTransfer.transfers.accountAmounts[0].amount) - ); - } else if (ctx.transaction.data.cryptoTransfer.transfers.accountAmounts_count == 2) { + hedera_sprintf(ctx.summary_line_1, "Verify Account"); + + hedera_sprintf(ctx.senders_title, "Account"); + + hedera_snprintf(ctx.senders, DISPLAY_SIZE * 2, "%llu.%llu.%llu", + ctx.transaction.data.cryptoTransfer.transfers + .accountAmounts[ 0 ] + .accountID.shardNum, + ctx.transaction.data.cryptoTransfer.transfers + .accountAmounts[ 0 ] + .accountID.realmNum, + ctx.transaction.data.cryptoTransfer.transfers + .accountAmounts[ 0 ] + .accountID.account); + } else if (ctx.transaction.data.cryptoTransfer.transfers + .accountAmounts_count == 2) { // Number of Accounts == 2 - // Some other Transfer Transaction + // Hbar transfer between two accounts ctx.type = Transfer; - hedera_sprintf( - ctx.summary_line_1, - "Send Hbar" - ); + hedera_sprintf(ctx.summary_line_1, "Send Hbar"); - // Determine Sender based on amount + // Determine Sender based on transfers.accountAmounts ctx.transfer_from_index = 0; ctx.transfer_to_index = 1; - if (ctx.transaction.data.cryptoTransfer.transfers.accountAmounts[0].amount > 0) { + if (ctx.transaction.data.cryptoTransfer.transfers + .accountAmounts[ 0 ] + .amount > 0) { ctx.transfer_from_index = 1; ctx.transfer_to_index = 0; } - hedera_snprintf( - ctx.senders, - DISPLAY_SIZE * 2, - "%llu.%llu.%llu", - ctx.transaction.data.cryptoTransfer.transfers.accountAmounts[ctx.transfer_from_index].accountID.shardNum, - ctx.transaction.data.cryptoTransfer.transfers.accountAmounts[ctx.transfer_from_index].accountID.realmNum, - ctx.transaction.data.cryptoTransfer.transfers.accountAmounts[ctx.transfer_from_index].accountID.accountNum - ); + hedera_snprintf(ctx.senders, DISPLAY_SIZE * 2, "%llu.%llu.%llu", + ctx.transaction.data.cryptoTransfer.transfers + .accountAmounts[ ctx.transfer_from_index ] + .accountID.shardNum, + ctx.transaction.data.cryptoTransfer.transfers + .accountAmounts[ ctx.transfer_from_index ] + .accountID.realmNum, + ctx.transaction.data.cryptoTransfer.transfers + .accountAmounts[ ctx.transfer_from_index ] + .accountID.account); + + hedera_snprintf(ctx.recipients, DISPLAY_SIZE * 2, + "%llu.%llu.%llu", + ctx.transaction.data.cryptoTransfer.transfers + .accountAmounts[ ctx.transfer_to_index ] + .accountID.shardNum, + ctx.transaction.data.cryptoTransfer.transfers + .accountAmounts[ ctx.transfer_to_index ] + .accountID.realmNum, + ctx.transaction.data.cryptoTransfer.transfers + .accountAmounts[ ctx.transfer_to_index ] + .accountID.account); hedera_snprintf( - ctx.recipients, - DISPLAY_SIZE * 2, - "%llu.%llu.%llu", - ctx.transaction.data.cryptoTransfer.transfers.accountAmounts[ctx.transfer_to_index].accountID.shardNum, - ctx.transaction.data.cryptoTransfer.transfers.accountAmounts[ctx.transfer_to_index].accountID.realmNum, - ctx.transaction.data.cryptoTransfer.transfers.accountAmounts[ctx.transfer_to_index].accountID.accountNum - ); - - hedera_snprintf( - ctx.amount, - DISPLAY_SIZE * 2, - "%s hbar", - hedera_format_tinybar(ctx.transaction.data.cryptoTransfer.transfers.accountAmounts[ctx.transfer_to_index].amount) - ); - } else if ( ctx.transaction.data.cryptoTransfer.tokenTransfers_count == 1) { + ctx.amount, DISPLAY_SIZE * 2, "%s hbar", + hedera_format_tinybar( + ctx.transaction.data.cryptoTransfer.transfers + .accountAmounts[ ctx.transfer_to_index ] + .amount)); + } else if (ctx.transaction.data.cryptoTransfer + .tokenTransfers_count == 1) { + // Fungible Token Transfer ctx.type = TokenTransfer; + validate_token_transfer(); + hedera_snprintf( - ctx.summary_line_1, - DISPLAY_SIZE * 2, - "Send %llu.%llu.%llu", - ctx.transaction.data.cryptoTransfer.tokenTransfers[0].token.shardNum, - ctx.transaction.data.cryptoTransfer.tokenTransfers[0].token.realmNum, - ctx.transaction.data.cryptoTransfer.tokenTransfers[0].token.tokenNum - ); + ctx.summary_line_1, DISPLAY_SIZE * 2, "Send %llu.%llu.%llu", + ctx.transaction.data.cryptoTransfer.tokenTransfers[ 0 ] + .token.shardNum, + ctx.transaction.data.cryptoTransfer.tokenTransfers[ 0 ] + .token.realmNum, + ctx.transaction.data.cryptoTransfer.tokenTransfers[ 0 ] + .token.tokenNum); // Determine Sender based on amount ctx.transfer_from_index = 0; ctx.transfer_to_index = 1; - if (ctx.transaction.data.cryptoTransfer.tokenTransfers[0].transfers[0].amount > 0) - { + if (ctx.transaction.data.cryptoTransfer.tokenTransfers[ 0 ] + .transfers[ 0 ] + .amount > 0) { ctx.transfer_from_index = 1; ctx.transfer_to_index = 0; } hedera_snprintf( - ctx.senders, - DISPLAY_SIZE * 2, - "%llu.%llu.%llu", - ctx.transaction.data.cryptoTransfer.tokenTransfers[0].transfers[ctx.transfer_from_index].accountID.shardNum, - ctx.transaction.data.cryptoTransfer.tokenTransfers[0].transfers[ctx.transfer_from_index].accountID.realmNum, - ctx.transaction.data.cryptoTransfer.tokenTransfers[0].transfers[ctx.transfer_from_index].accountID.accountNum - ); + ctx.senders, DISPLAY_SIZE * 2, "%llu.%llu.%llu", + ctx.transaction.data.cryptoTransfer.tokenTransfers[ 0 ] + .transfers[ ctx.transfer_from_index ] + .accountID.shardNum, + ctx.transaction.data.cryptoTransfer.tokenTransfers[ 0 ] + .transfers[ ctx.transfer_from_index ] + .accountID.realmNum, + ctx.transaction.data.cryptoTransfer.tokenTransfers[ 0 ] + .transfers[ ctx.transfer_from_index ] + .accountID.account); hedera_snprintf( - ctx.recipients, - DISPLAY_SIZE * 2, - "%llu.%llu.%llu", - ctx.transaction.data.cryptoTransfer.tokenTransfers[0].transfers[ctx.transfer_to_index].accountID.shardNum, - ctx.transaction.data.cryptoTransfer.tokenTransfers[0].transfers[ctx.transfer_to_index].accountID.realmNum, - ctx.transaction.data.cryptoTransfer.tokenTransfers[0].transfers[ctx.transfer_to_index].accountID.accountNum - ); - - validate_decimals(ctx.transaction.data.cryptoTransfer.tokenTransfers[0].expected_decimals.value); + ctx.recipients, DISPLAY_SIZE * 2, "%llu.%llu.%llu", + ctx.transaction.data.cryptoTransfer.tokenTransfers[ 0 ] + .transfers[ ctx.transfer_to_index ] + .accountID.shardNum, + ctx.transaction.data.cryptoTransfer.tokenTransfers[ 0 ] + .transfers[ ctx.transfer_to_index ] + .accountID.realmNum, + ctx.transaction.data.cryptoTransfer.tokenTransfers[ 0 ] + .transfers[ ctx.transfer_to_index ] + .accountID.account); + hedera_snprintf( - ctx.amount, - DISPLAY_SIZE * 2, - "%s", + ctx.amount, DISPLAY_SIZE * 2, "%s", hedera_format_amount( - ctx.transaction.data.cryptoTransfer.tokenTransfers[0].transfers[ctx.transfer_to_index].amount, - ctx.transaction.data.cryptoTransfer.tokenTransfers[0].expected_decimals.value - ) - ); + ctx.transaction.data.cryptoTransfer.tokenTransfers[ 0 ] + .transfers[ ctx.transfer_to_index ] + .amount, + ctx.transaction.data.cryptoTransfer.tokenTransfers[ 0 ] + .expected_decimals.value)); } else { // Unsupported THROW(EXCEPTION_MALFORMED_APDU); @@ -1281,13 +1427,23 @@ void handle_transaction_body() { } switch (ctx.type) { - case Associate: case Verify: ux_flow_init(0, ux_verify_flow, NULL); break; + case TokenMint: + case TokenBurn: + ux_flow_init(0, ux_mint_flow, NULL); + break; case Create: ux_flow_init(0, ux_create_flow, NULL); break; + case Update: + ux_flow_init(0, ux_update_flow, NULL); + break; + case Associate: + case Dissociate: + ux_flow_init(0, ux_associate_flow, NULL); + break; case TokenTransfer: case Transfer: ux_flow_init(0, ux_transfer_flow, NULL); @@ -1301,14 +1457,10 @@ void handle_transaction_body() { // Sign Handler // Decodes and handles transaction message -void handle_sign_transaction( - uint8_t p1, - uint8_t p2, - uint8_t* buffer, - uint16_t len, - /* out */ volatile unsigned int* flags, - /* out */ volatile unsigned int* tx -) { +void handle_sign_transaction(uint8_t p1, uint8_t p2, uint8_t* buffer, + uint16_t len, + /* out */ volatile unsigned int* flags, + /* out */ volatile unsigned int* tx) { UNUSED(p1); UNUSED(p2); UNUSED(tx); @@ -1317,7 +1469,7 @@ void handle_sign_transaction( ctx.key_index = U4LE(buffer, 0); // Raw Tx - uint8_t raw_transaction[MAX_TX_SIZE]; + uint8_t raw_transaction[ MAX_TX_SIZE ]; int raw_transaction_length = len - 4; // Oops Oof Owie @@ -1330,27 +1482,17 @@ void handle_sign_transaction( // Sign Transaction // TODO: handle error return here (internal error?!) - if (!hedera_sign( - ctx.key_index, - raw_transaction, - raw_transaction_length, - G_io_apdu_buffer - )) { + if (!hedera_sign(ctx.key_index, raw_transaction, raw_transaction_length, + G_io_apdu_buffer)) { THROW(EXCEPTION_INTERNAL); } // Make in memory buffer into stream - pb_istream_t stream = pb_istream_from_buffer( - raw_transaction, - raw_transaction_length - ); + pb_istream_t stream = + pb_istream_from_buffer(raw_transaction, raw_transaction_length); // Decode the Transaction - if (!pb_decode( - &stream, - HederaTransactionBody_fields, - &ctx.transaction - )) { + if (!pb_decode(&stream, Hedera_TransactionBody_fields, &ctx.transaction)) { // Oh no couldn't ... THROW(EXCEPTION_MALFORMED_APDU); } @@ -1360,44 +1502,21 @@ void handle_sign_transaction( *flags |= IO_ASYNCH_REPLY; } -// Validates whether or not a transfer is legal: -// Either a transfer between two accounts -// Or a token transfer between two accounts -void validate_transfer() { - if (ctx.transaction.data.cryptoTransfer.transfers.accountAmounts_count > 2) { - // More than two accounts in a transfer - THROW(EXCEPTION_MALFORMED_APDU); - } - - if ( - ctx.transaction.data.cryptoTransfer.transfers.accountAmounts_count == 2 && - ctx.transaction.data.cryptoTransfer.tokenTransfers_count != 0 - ) { - // Can't also transfer tokens while sending hbar - THROW(EXCEPTION_MALFORMED_APDU); - } - - if (ctx.transaction.data.cryptoTransfer.tokenTransfers_count > 1) { - // More than one token transferred +void validate_decimals(uint32_t decimals) { + if (decimals >= 20) { + // We only support decimal values less than 20 THROW(EXCEPTION_MALFORMED_APDU); } - - if (ctx.transaction.data.cryptoTransfer.tokenTransfers_count == 1) { - if (ctx.transaction.data.cryptoTransfer.tokenTransfers[0].transfers_count != 2) { - // More than two accounts in a token transfer - THROW(EXCEPTION_MALFORMED_APDU); - } - - if (ctx.transaction.data.cryptoTransfer.transfers.accountAmounts_count != 0) { - // Can't also transfer Hbar if the transaction is an otherwise valid token transfer - THROW(EXCEPTION_MALFORMED_APDU); - } - } } -void validate_decimals(uint32_t decimals) { - if (decimals >= 20) { - // We only support decimal values less than 20 +void validate_token_transfer() { + // One token transfer with two accountAmounts + if (ctx.transaction.data.cryptoTransfer.tokenTransfers[ 0 ] + .transfers_count != 2) { THROW(EXCEPTION_MALFORMED_APDU); } + + // Transactions fail if not given in the right denomination + validate_decimals(ctx.transaction.data.cryptoTransfer.tokenTransfers[ 0 ] + .expected_decimals.value); } diff --git a/src/sign_transaction.h b/src/sign_transaction.h index 8496d1dc..3cb980db 100644 --- a/src/sign_transaction.h +++ b/src/sign_transaction.h @@ -1,6 +1,25 @@ #ifndef LEDGER_APP_HEDERA_SIGN_TRANSACTION_H #define LEDGER_APP_HEDERA_SIGN_TRANSACTION_H 1 +#include +#include +#include +#include +#include + +#include "basic_types.pb.h" +#include "debug.h" +#include "errors.h" +#include "globals.h" +#include "handlers.h" +#include "hedera.h" +#include "hedera_format.h" +#include "io.h" +#include "printf.h" +#include "transaction_body.pb.h" +#include "ui.h" +#include "utils.h" + enum TransactionStep { Summary = 1, Operator = 2, @@ -17,68 +36,129 @@ enum TransactionType { Unknown = -1, Verify = 0, Create = 1, - Transfer = 2, - Associate = 3, - TokenTransfer = 4, - TokenMint = 5, - TokenBurn = 6, + Update = 2, + Transfer = 3, + Associate = 4, + Dissociate = 5, + TokenTransfer = 6, + TokenMint = 7, + TokenBurn = 8, }; +void handle_transaction_body(); +void validate_decimals(uint32_t decimals); +void validate_token_transfer(); + #if defined(TARGET_NANOS) +// Transaction Context +static struct sign_tx_context_t { + // ui common + uint32_t key_index; + uint8_t transfer_to_index; + uint8_t transfer_from_index; + + // Transaction Summary + char summary_line_1[ DISPLAY_SIZE + 1 ]; + char summary_line_2[ DISPLAY_SIZE + 1 ]; + char title[ DISPLAY_SIZE + 1 ]; + + // Account ID: uint64_t.uint64_t.uint64_t + // Most other entities are shorter + char full[ ACCOUNT_ID_SIZE + 1 ]; + char partial[ DISPLAY_SIZE + 1 ]; + + // Steps correspond to parts of the transaction proto + // type is set based on proto + enum TransactionStep step; + enum TransactionType type; + + uint8_t current_page; // 1 -> Number Screens + uint8_t page_count; // Number Screens + + // Parsed transaction + Hedera_TransactionBody transaction; +} ctx; + // Forward declarations for Nano S UI // Step 1 -unsigned int ui_tx_summary_step_button( - unsigned int button_mask, - unsigned int button_mask_counter -); +unsigned int ui_tx_summary_step_button(unsigned int button_mask, + unsigned int button_mask_counter); // Step 2 - 7 void handle_intermediate_left_press(); void handle_intermediate_right_press(); -unsigned int ui_tx_intermediate_step_button( - unsigned int button_mask, - unsigned int button_mask_counter -); +unsigned int ui_tx_intermediate_step_button(unsigned int button_mask, + unsigned int button_mask_counter); // Step 8 -unsigned int ui_tx_confirm_step_button( - unsigned int button_mask, - unsigned int button_mask_counter -); +unsigned int ui_tx_confirm_step_button(unsigned int button_mask, + unsigned int button_mask_counter); // Step 9 -unsigned int ui_tx_deny_step_button( - unsigned int button_mask, - unsigned int button_mask_counter -); +unsigned int ui_tx_deny_step_button(unsigned int button_mask, + unsigned int button_mask_counter); uint8_t num_screens(size_t length); -void count_screens(); -void shift_display(); -bool first_screen(); -bool last_screen(); - -#elif defined(TARGET_NANOX) || defined(TARGET_NANOS2) -// Forward declarations for Nano X UI -void x_start_tx_loop(); -void x_continue_tx_loop(); -void x_end_tx_loop(); -unsigned int io_seproxyhal_tx_approve(const bagl_element_t* e); -unsigned int io_seproxyhal_tx_reject(const bagl_element_t* e); - -#endif // TARGET - +void count_screens_of_step(); +bool first_screen_of_step(); +bool last_screen_of_step(); void reformat_token(); -void reformat_tokens_accounts(char *title_part, uint8_t transfer_index); -void reformat_accounts(char *title_part, uint8_t transfer_index); +void reformat_tokens_accounts(char* title_part, uint8_t transfer_index); +void reformat_accounts(char* title_part, uint8_t transfer_index); +void reformat_stake_target(); +void reformat_collect_rewards(); +void reformat_target_account(); void reformat_operator(); void reformat_senders(); void reformat_recipients(); void reformat_amount(); void reformat_fee(); void reformat_memo(); -void handle_transaction_body(); -void validate_transfer(); -void validate_decimals(uint32_t decimals); -#endif //LEDGER_APP_HEDERA_SIGN_TRANSACTION_H +#elif defined(TARGET_NANOX) || defined(TARGET_NANOS2) +// Transaction Context +static struct sign_tx_context_t { + // ui common + uint32_t key_index; + uint8_t transfer_from_index; + uint8_t transfer_to_index; + + // Transaction Summary + char summary_line_1[ DISPLAY_SIZE + 1 ]; + char summary_line_2[ DISPLAY_SIZE + 1 ]; + char senders_title[ DISPLAY_SIZE + 1 ]; + char recipients_title[ DISPLAY_SIZE + 1 ]; + char amount_title[ DISPLAY_SIZE + 1 ]; + char partial[ DISPLAY_SIZE + 1 ]; + + enum TransactionType type; + + // Transaction Operator + char operator[ DISPLAY_SIZE * 2 + 1 ]; + + // Transaction Senders + char senders[ DISPLAY_SIZE * 2 + 1 ]; + + // Transaction Recipients + char recipients[ DISPLAY_SIZE * 2 + 1 ]; + + // Transaction Amount + char amount[ DISPLAY_SIZE * 2 + 1 ]; + + // Transaction Fee + char fee[ DISPLAY_SIZE * 2 + 1 ]; + + // Transaction Memo + char memo[ MAX_MEMO_SIZE + 1 ]; + + // Parsed transaction + Hedera_TransactionBody transaction; +} ctx; + +// Forward declarations for Nano X UI +unsigned int io_seproxyhal_tx_approve(const bagl_element_t* e); +unsigned int io_seproxyhal_tx_reject(const bagl_element_t* e); + +#endif // TARGET + +#endif // LEDGER_APP_HEDERA_SIGN_TRANSACTION_H diff --git a/src/ui.c b/src/ui.c index 09cf020e..7766091e 100644 --- a/src/ui.c +++ b/src/ui.c @@ -9,108 +9,81 @@ ux_state_t ux; unsigned int ux_step; unsigned int ux_step_count; -static const ux_menu_entry_t menu_main[4]; - -static const ux_menu_entry_t menu_about[3] = { - { - .menu = NULL, - .callback = NULL, - .userid = 0, - .icon = NULL, - .line1 = "Version", - .line2 = APPVERSION, - .text_x = 0, - .icon_x = 0, - }, - - { - .menu = menu_main, - .callback = NULL, - .userid = 0, - .icon = &C_icon_back, - .line1 = "Back", - .line2 = NULL, - .text_x = 61, - .icon_x = 40, - }, - - UX_MENU_END -}; - -static const ux_menu_entry_t menu_main[4] = { - { - .menu = NULL, - .callback = NULL, - .userid = 0, - .icon = NULL, - .line1 = "Awaiting", - .line2 = "Commands", - .text_x = 0, - .icon_x = 0 - }, - { - .menu = menu_about, - .callback = NULL, - .userid = 0, - .icon = NULL, - .line1 = "About", - .line2 = NULL, - .text_x = 0, - .icon_x = 0, - }, - - { - .menu = NULL, - .callback = &os_sched_exit, - .userid = 0, - .icon = &C_icon_dashboard, - .line1 = "Quit app", - .line2 = NULL, - .text_x = 50, - .icon_x = 29, - }, - - UX_MENU_END -}; +static const ux_menu_entry_t menu_main[ 4 ]; + +static const ux_menu_entry_t menu_about[ 3 ] = {{ + .menu = NULL, + .callback = NULL, + .userid = 0, + .icon = NULL, + .line1 = "Version", + .line2 = APPVERSION, + .text_x = 0, + .icon_x = 0, + }, + + { + .menu = menu_main, + .callback = NULL, + .userid = 0, + .icon = &C_icon_back, + .line1 = "Back", + .line2 = NULL, + .text_x = 61, + .icon_x = 40, + }, + + UX_MENU_END}; + +static const ux_menu_entry_t menu_main[ 4 ] = {{.menu = NULL, + .callback = NULL, + .userid = 0, + .icon = NULL, + .line1 = "Awaiting", + .line2 = "Commands", + .text_x = 0, + .icon_x = 0}, + { + .menu = menu_about, + .callback = NULL, + .userid = 0, + .icon = NULL, + .line1 = "About", + .line2 = NULL, + .text_x = 0, + .icon_x = 0, + }, + + { + .menu = NULL, + .callback = &os_sched_exit, + .userid = 0, + .icon = &C_icon_dashboard, + .line1 = "Quit app", + .line2 = NULL, + .text_x = 50, + .icon_x = 29, + }, + + UX_MENU_END}; #elif defined(TARGET_NANOX) || defined(TARGET_NANOS2) ux_state_t G_ux; bolos_ux_params_t G_ux_params; -UX_STEP_NOCB( - ux_idle_flow_1_step, - nn, - { - "Awaiting", - "Commands" - } -); - -UX_STEP_NOCB( - ux_idle_flow_2_step, - bn, - { - "Version", - APPVERSION, - } -); - -UX_STEP_VALID( - ux_idle_flow_3_step, - pb, - os_sched_exit(-1), - { - &C_icon_dashboard_x, - "Exit" - } -); - -UX_DEF( - ux_idle_flow, - &ux_idle_flow_1_step, - &ux_idle_flow_2_step, - &ux_idle_flow_3_step -); +UX_STEP_NOCB(ux_idle_flow_1_step, nn, {"Awaiting", "Commands"}); + +UX_STEP_NOCB(ux_idle_flow_2_step, bn, + { + "Version", + APPVERSION, + }); + +UX_STEP_VALID(ux_idle_flow_3_step, pb, os_sched_exit(-1), + {&C_icon_dashboard_x, "Exit"}); + +UX_DEF(ux_idle_flow, &ux_idle_flow_1_step, &ux_idle_flow_2_step, + &ux_idle_flow_3_step); #endif // TARGET diff --git a/src/ui.h b/src/ui.h index dce88375..087a8309 100644 --- a/src/ui.h +++ b/src/ui.h @@ -1,8 +1,8 @@ #ifndef LEDGER_HEDERA_UI_H #define LEDGER_HEDERA_UI_H 1 -#include "glyphs.h" #include "globals.h" +#include "glyphs.h" #include "ux.h" #if defined(TARGET_NANOS) @@ -10,11 +10,51 @@ #include // Common UI element definitions for Nano S -#define UI_BACKGROUND() {{BAGL_RECTANGLE,0,0,0,128,32,0,0,BAGL_FILL,0,0xFFFFFF,0,0},NULL} -#define UI_ICON_LEFT(userid, glyph) {{BAGL_ICON,userid,3,12,7,7,0,0,0,0xFFFFFF,0,0,glyph},NULL} -#define UI_ICON_RIGHT(userid, glyph) {{BAGL_ICON,userid,117,13,8,6,0,0,0,0xFFFFFF,0,0,glyph},NULL} -#define UI_TEXT(userid, x, y, w, text) {{BAGL_LABELINE,userid,x,y,w,12,0,0,0,0xFFFFFF,0,BAGL_FONT_OPEN_SANS_REGULAR_11px|BAGL_FONT_ALIGNMENT_CENTER,0},(char *)(text)} -#define UI_ICON(userid, x, y, w, glyph) {{BAGL_ICON,userid,x,y,w,6,0,0,0,0xFFFFFF,0,BAGL_FONT_OPEN_SANS_REGULAR_11px|BAGL_FONT_ALIGNMENT_CENTER,glyph},NULL} +#define UI_BACKGROUND() \ + { \ + { \ + BAGL_RECTANGLE, 0, 0, 0, 128, 32, 0, 0, \ + BAGL_FILL, 0, 0xFFFFFF, 0, 0}, \ + NULL \ + } +#define UI_ICON_LEFT(userid, glyph) \ + { {BAGL_ICON, userid, 3, 12, 7, 7, 0, 0, 0, 0xFFFFFF, 0, 0, glyph}, NULL } +#define UI_ICON_RIGHT(userid, glyph) \ + { {BAGL_ICON, userid, 117, 13, 8, 6, 0, 0, 0, 0xFFFFFF, 0, 0, glyph}, NULL } +#define UI_TEXT(userid, x, y, w, text) \ + { \ + {BAGL_LABELINE, \ + userid, \ + x, \ + y, \ + w, \ + 12, \ + 0, \ + 0, \ + 0, \ + 0xFFFFFF, \ + 0, \ + BAGL_FONT_OPEN_SANS_REGULAR_11px | BAGL_FONT_ALIGNMENT_CENTER, \ + 0}, \ + (char*)(text) \ + } +#define UI_ICON(userid, x, y, w, glyph) \ + { \ + {BAGL_ICON, \ + userid, \ + x, \ + y, \ + w, \ + 6, \ + 0, \ + 0, \ + 0, \ + 0xFFFFFF, \ + 0, \ + BAGL_FONT_OPEN_SANS_REGULAR_11px | BAGL_FONT_ALIGNMENT_CENTER, \ + glyph}, \ + NULL \ + } #endif // TARGET diff --git a/src/utils.c b/src/utils.c index 1f4adf32..aab33333 100644 --- a/src/utils.c +++ b/src/utils.c @@ -1,20 +1,20 @@ #include "utils.h" -void public_key_to_bytes(unsigned char *dst, cx_ecfp_public_key_t *public) { +void public_key_to_bytes(unsigned char* dst, cx_ecfp_public_key_t* public) { for (int i = 0; i < 32; i++) { - dst[i] = public->W[64 - i]; + dst[ i ] = public->W[ 64 - i ]; } - if (public->W[32] & 1) { - dst[31] |= 0x80; + if (public->W[ 32 ] & 1) { + dst[ 31 ] |= 0x80; } } -void bin2hex(uint8_t *dst, uint8_t *data, uint64_t inlen) { - static uint8_t const hex[] = "0123456789abcdef"; - for (uint64_t i = 0; i < inlen; i++) { - dst[2*i+0] = hex[(data[i]>>4) & 0x0F]; - dst[2*i+1] = hex[(data[i]>>0) & 0x0F]; - } - dst[2*inlen] = '\0'; +void bin2hex(uint8_t* dst, uint8_t* data, uint64_t inlen) { + static uint8_t const hex[] = "0123456789abcdef"; + for (uint64_t i = 0; i < inlen; i++) { + dst[ 2 * i + 0 ] = hex[ (data[ i ] >> 4) & 0x0F ]; + dst[ 2 * i + 1 ] = hex[ (data[ i ] >> 0) & 0x0F ]; + } + dst[ 2 * inlen ] = '\0'; } diff --git a/src/utils.h b/src/utils.h index 29b00d5b..f080acb0 100644 --- a/src/utils.h +++ b/src/utils.h @@ -1,10 +1,10 @@ #ifndef LEDGER_HEDERA_UTILS_H #define LEDGER_HEDERA_UTILS_H 1 -#include #include +#include -extern void public_key_to_bytes(uint8_t *dst, cx_ecfp_public_key_t *public); -extern void bin2hex(uint8_t *dst, uint8_t *data, uint64_t inlen); +extern void public_key_to_bytes(uint8_t* dst, cx_ecfp_public_key_t* public); +extern void bin2hex(uint8_t* dst, uint8_t* data, uint64_t inlen); #endif // LEDGER_HEDERA_UTILS_H diff --git a/tests/.pdm.toml b/tests/.pdm.toml new file mode 100644 index 00000000..04b4f314 --- /dev/null +++ b/tests/.pdm.toml @@ -0,0 +1,2 @@ +[python] +path = "/home/chris/Projects/Ledger/ledger-app-hedera/tests/.venv/bin/python" diff --git a/tests/.vscode/settings.json b/tests/.vscode/settings.json new file mode 100644 index 00000000..48e647b5 --- /dev/null +++ b/tests/.vscode/settings.json @@ -0,0 +1,4 @@ +{ + "python.formatting.provider": "black", + "python.analysis.typeCheckingMode": "basic" +} \ No newline at end of file diff --git a/tests/__init__.py b/tests/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/tests/apps/__init__.py b/tests/apps/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/tests/apps/hedera.py b/tests/apps/hedera.py new file mode 100644 index 00000000..88bcb89f --- /dev/null +++ b/tests/apps/hedera.py @@ -0,0 +1,91 @@ +from typing import List, Generator, Dict +from enum import IntEnum +from contextlib import contextmanager +from time import sleep + +from ragger.backend.interface import BackendInterface, RAPDU + +from ..utils import validate_displayed_message +from .hedera_builder import hedera_transaction + + +class INS(IntEnum): + INS_GET_APP_CONFIGURATION = 0x01 + INS_GET_PUBLIC_KEY = 0x02 + INS_SIGN_TRANSACTION = 0x04 + +CLA = 0xE0 + +P1_CONFIRM = 0x00 +P1_NON_CONFIRM = 0x01 + +P2_EXTEND = 0x01 +P2_MORE = 0x02 + + +PUBLIC_KEY_LENGTH = 32 + +MAX_CHUNK_SIZE = 255 + + +STATUS_OK = 0x9000 + +class ErrorType: + EXCEPTION_USER_REJECTED = 0x6985 + + +def to_zigzag(n): + return n + n + (n < 0) + + +class HederaClient: + client: BackendInterface + + def __init__(self, client): + self._client = client + + def get_public_key_non_confirm(self, index: int) -> RAPDU: + index_b = index.to_bytes(4, "little") + return self._client.exchange(CLA, INS.INS_GET_PUBLIC_KEY, P1_NON_CONFIRM, 0, index_b) + + @contextmanager + def get_public_key_confirm(self, index: int) -> Generator[None, None, None]: + index_b = index.to_bytes(4, "little") + with self._client.exchange_async(CLA, INS.INS_GET_PUBLIC_KEY, P1_CONFIRM, 0, index_b): + sleep(0.5) + yield + + def validate(self): + self._client.right_click() + + def refuse(self): + self._client.left_click() + + def validate_screen(self, right_clicks: int): + validate_displayed_message(self._client, right_clicks) + + def get_async_response(self) -> RAPDU: + return self._client.last_async_response + + @contextmanager + def send_sign_transaction(self, + index: int, + operator_shard_num: int, + operator_realm_num: int, + operator_account_num: int, + transaction_fee: int, + memo: str, + conf: Dict) -> Generator[None, None, None]: + + transaction = hedera_transaction(operator_shard_num, + operator_realm_num, + operator_account_num, + transaction_fee, + memo, + conf) + + payload = index.to_bytes(4, "little") + transaction + + with self._client.exchange_async(CLA, INS.INS_SIGN_TRANSACTION, P1_CONFIRM, 0, payload): + sleep(0.5) + yield diff --git a/tests/apps/hedera_builder.py b/tests/apps/hedera_builder.py new file mode 100644 index 00000000..3f5da7df --- /dev/null +++ b/tests/apps/hedera_builder.py @@ -0,0 +1,319 @@ +from typing import Dict + +from proto import basic_types_pb2 as basics +from proto import crypto_create_pb2 as create +from proto import crypto_update_pb2 as update +from proto import crypto_transfer_pb2 as transfer +from proto import token_associate_pb2 as associate +from proto import token_dissociate_pb2 as dissociate +from proto import token_burn_pb2 as burn +from proto import token_mint_pb2 as mint +from proto import transaction_body_pb2 as tx_body +from proto import wrappers_pb2 as wrappers + + +def hedera_transaction( + operator_shard_num: int, + operator_realm_num: int, + operator_account_num: int, + transaction_fee: int, + memo: str, + conf: Dict, +) -> bytes: + operator = basics.AccountID( + shardNum=operator_shard_num, + realmNum=operator_realm_num, + accountNum=operator_account_num, + ) + + hedera_transaction_id = basics.TransactionID( + accountID=operator, + ) + + transaction = tx_body.TransactionBody( + transactionID=hedera_transaction_id, + transactionFee=transaction_fee, + memo=memo, + **conf, + ) + + return transaction.SerializeToString() + + +def crypto_create_account_conf(initialBalance: int) -> Dict: + crypto_create_account = create.CryptoCreateTransactionBody( + initialBalance=initialBalance, + ) + + return {"cryptoCreateAccount": crypto_create_account} + + +def crypto_create_account_stake_account_conf() -> Dict: + stake_target = basics.AccountID(shardNum=1, realmNum=2, accountNum=3) + + crypto_create_account = create.CryptoCreateTransactionBody( + initialBalance=5, staked_account_id=stake_target + ) + + return {"cryptoCreateAccount": crypto_create_account} + + +def crypto_create_account_stake_node_conf() -> Dict: + stake_target = 3 + + crypto_create_account = create.CryptoCreateTransactionBody( + initialBalance=5, staked_node_id=stake_target + ) + + return {"cryptoCreateAccount": crypto_create_account} + + +def crypto_create_account_stake_toggle_rewards_conf() -> Dict: + stake_target = basics.AccountID(shardNum=6, realmNum=6, accountNum=6) + + crypto_create_account = create.CryptoCreateTransactionBody( + initialBalance=5, staked_account_id=stake_target, decline_reward=True + ) + + return {"cryptoCreateAccount": crypto_create_account} + + +def account_update_conf() -> Dict: + stake_target = basics.AccountID(shardNum=6, realmNum=6, accountNum=6) + + crypto_update_account = update.CryptoUpdateTransactionBody( + staked_account_id=stake_target + ) + + return {"cryptoUpdateAccount": crypto_update_account} + + +def crypto_transfer_token_conf( + token_shardNum: int, + token_realmNum: int, + token_tokenNum: int, + sender_shardNum: int, + sender_realmNum: int, + sender_accountNum: int, + recipient_shardNum: int, + recipient_realmNum: int, + recipient_accountNum: int, + amount: int, + decimals: int, +) -> Dict: + + hedera_token_id = basics.TokenID( + shardNum=token_shardNum, + realmNum=token_realmNum, + tokenNum=token_tokenNum, + ) + + hedera_account_id_sender = basics.AccountID( + shardNum=sender_shardNum, + realmNum=sender_realmNum, + accountNum=sender_accountNum, + ) + + hedera_account_amount_sender = basics.AccountAmount( + accountID=hedera_account_id_sender, + amount=0, + ) + + hedera_account_id_recipient = basics.AccountID( + shardNum=recipient_shardNum, + realmNum=recipient_realmNum, + accountNum=recipient_accountNum, + ) + + hedera_account_amount_recipient = basics.AccountAmount( + accountID=hedera_account_id_recipient, + amount=amount, + ) + + hedera_transfer_list = basics.TransferList( + accountAmounts=[], + ) + + decimalsUInt32 = wrappers.UInt32Value( + value=decimals, + ) + + hedera_token_transfer_list = basics.TokenTransferList( + token=hedera_token_id, + transfers=[hedera_account_amount_recipient, hedera_account_amount_sender], + expected_decimals=decimalsUInt32, + ) + + crypto_transfer = transfer.CryptoTransferTransactionBody( + transfers=hedera_transfer_list, + tokenTransfers=[hedera_token_transfer_list], + ) + + return {"cryptoTransfer": crypto_transfer} + + +def crypto_transfer_hbar_conf( + sender_shardNum: int, + sender_realmNum: int, + sender_accountNum: int, + recipient_shardNum: int, + recipient_realmNum: int, + recipient_accountNum: int, + amount: int, +) -> Dict: + + hedera_account_id_sender = basics.AccountID( + shardNum=sender_shardNum, + realmNum=sender_realmNum, + accountNum=sender_accountNum, + ) + + hedera_account_amount_sender = basics.AccountAmount( + accountID=hedera_account_id_sender, + amount=0, + ) + + hedera_account_id_recipient = basics.AccountID( + shardNum=recipient_shardNum, + realmNum=recipient_realmNum, + accountNum=recipient_accountNum, + ) + + hedera_account_amount_recipient = basics.AccountAmount( + accountID=hedera_account_id_recipient, + amount=amount, + ) + + hedera_transfer_list = basics.TransferList( + accountAmounts=[hedera_account_amount_recipient, hedera_account_amount_sender], + ) + + crypto_transfer = transfer.CryptoTransferTransactionBody( + transfers=hedera_transfer_list, + tokenTransfers=[], + ) + + return {"cryptoTransfer": crypto_transfer} + + +def crypto_transfer_verify( + sender_shardNum: int, sender_realmNum: int, sender_accountNum: int +) -> Dict: + + hedera_account_id_sender = basics.AccountID( + shardNum=sender_shardNum, + realmNum=sender_realmNum, + accountNum=sender_accountNum, + ) + + hedera_account_amount_sender = basics.AccountAmount( + accountID=hedera_account_id_sender, + amount=0, + ) + + hedera_transfer_list = basics.TransferList( + accountAmounts=[hedera_account_amount_sender], + ) + + crypto_transfer = transfer.CryptoTransferTransactionBody( + transfers=hedera_transfer_list, + tokenTransfers=[], + ) + + return {"cryptoTransfer": crypto_transfer} + + +def token_associate_conf( + token_shardNum: int, + token_realmNum: int, + token_tokenNum: int, + sender_shardNum: int, + sender_realmNum: int, + sender_accountNum: int, +) -> Dict: + + hedera_account_id_sender = basics.AccountID( + shardNum=sender_shardNum, + realmNum=sender_realmNum, + accountNum=sender_accountNum, + ) + + hedera_token_id = basics.TokenID( + shardNum=token_shardNum, + realmNum=token_realmNum, + tokenNum=token_tokenNum, + ) + + token_associate = associate.TokenAssociateTransactionBody( + account=hedera_account_id_sender, + tokens=[hedera_token_id], + ) + + return {"tokenAssociate": token_associate} + + +def token_dissociate_conf( + token_shardNum: int, + token_realmNum: int, + token_tokenNum: int, + sender_shardNum: int, + sender_realmNum: int, + sender_accountNum: int, +) -> Dict: + + hedera_account_id_sender = basics.AccountID( + shardNum=sender_shardNum, + realmNum=sender_realmNum, + accountNum=sender_accountNum, + ) + + hedera_token_id = basics.TokenID( + shardNum=token_shardNum, + realmNum=token_realmNum, + tokenNum=token_tokenNum, + ) + + token_dissociate = dissociate.TokenDissociateTransactionBody( + account=hedera_account_id_sender, + tokens=[hedera_token_id], + ) + + return {"tokenDissociate": token_dissociate} + + +def token_burn_conf( + token_shardNum: int, + token_realmNum: int, + token_tokenNum: int, + amount: int, +) -> Dict: + hedera_token_id = basics.TokenID( + shardNum=token_shardNum, + realmNum=token_realmNum, + tokenNum=token_tokenNum, + ) + + token_burn = burn.TokenBurnTransactionBody(token=hedera_token_id, amount=amount) + + return {"tokenBurn": token_burn} + + +def token_mint_conf( + token_shardNum: int, + token_realmNum: int, + token_tokenNum: int, + amount: int, +) -> Dict: + + hedera_token_id = basics.TokenID( + shardNum=token_shardNum, + realmNum=token_realmNum, + tokenNum=token_tokenNum, + ) + + token_mint = mint.TokenMintTransactionBody( + token=hedera_token_id, + amount=amount, + ) + + return {"tokenMint": token_mint} diff --git a/tests/conftest.py b/tests/conftest.py new file mode 100644 index 00000000..522666e0 --- /dev/null +++ b/tests/conftest.py @@ -0,0 +1,99 @@ +from pathlib import Path +import pytest + +from ragger import Firmware +from ragger.backend import SpeculosBackend, LedgerCommBackend, LedgerWalletBackend + +from .utils import app_path_from_app_name + +def __str__(self): # also tried __repr__() + # Attempt to print the 'select' attribute in "pytest -v" output + return self.select + + +APPS_DIRECTORY = (Path(__file__).parent / "elfs").resolve() + +APP_NAME = "hedera" + +BACKENDS = ["speculos", "ledgercomm", "ledgerwallet"] + +FIRMWARES = [ + Firmware('nanos', '2.1'), + Firmware('nanox', '2.0.2'), + Firmware('nanosp', '1.0.3'), +] + +def pytest_addoption(parser): + parser.addoption("--backend", action="store", default="speculos") + parser.addoption("--display", action="store_true", default=False) + # Enable using --'device' in the pytest command line to restrict testing to specific devices + for fw in FIRMWARES: + parser.addoption("--"+fw.device, action="store_true", help="run on {} only".format(fw.device)) + + +@pytest.fixture(scope="session") +def backend(pytestconfig): + return pytestconfig.getoption("backend") + + +@pytest.fixture(scope="session") +def display(pytestconfig): + return pytestconfig.getoption("display") + + +# Glue to call every test that depends on the firmware once for each required firmware +def pytest_generate_tests(metafunc): + if "firmware" in metafunc.fixturenames: + fw_list = [] + ids = [] + # First pass: enable only demanded firmwares + for fw in FIRMWARES: + if metafunc.config.getoption(fw.device): + fw_list.append(fw) + ids.append(fw.device + " " + fw.version) + # Second pass if no specific firmware demanded: add them all + if not fw_list: + for fw in FIRMWARES: + fw_list.append(fw) + ids.append(fw.device + " " + fw.version) + metafunc.parametrize("firmware", fw_list, ids=ids) + + +def prepare_speculos_args(firmware, display: bool): + speculos_args = [] + + if display: + speculos_args += ["--display", "qt"] + + app_path = app_path_from_app_name(APPS_DIRECTORY, APP_NAME, firmware.device) + + return ([app_path], {"args": speculos_args}) + + +def create_backend(backend: str, firmware: Firmware, display: bool): + if backend.lower() == "ledgercomm": + return LedgerCommBackend(firmware, interface="hid") + elif backend.lower() == "ledgerwallet": + return LedgerWalletBackend(firmware) + elif backend.lower() == "speculos": + args, kwargs = prepare_speculos_args(firmware, display) + return SpeculosBackend(*args, firmware, **kwargs) + else: + raise ValueError(f"Backend '{backend}' is unknown. Valid backends are: {BACKENDS}") + +@pytest.fixture +def client(backend, firmware, display: bool): + with create_backend(backend, firmware, display) as b: + yield b + +@pytest.fixture(autouse=True) +def use_only_on_backend(request, backend): + if request.node.get_closest_marker('use_on_backend'): + current_backend = request.node.get_closest_marker('use_on_backend').args[0] + if current_backend != backend: + pytest.skip('skipped on this backend: {}'.format(current_backend)) + +def pytest_configure(config): + config.addinivalue_line( + "markers", "use_only_on_backend(backend): skip test if not on the specified backend", + ) diff --git a/tests/elfs/hedera_nanos.elf b/tests/elfs/hedera_nanos.elf new file mode 100755 index 0000000000000000000000000000000000000000..6309ae9299f34c23fc52873cc23b4d4b5575c6fa GIT binary patch literal 363372 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

%Ox!J&GBe>OGIFzJrc-Peg!T+Y{1X>P#6=d` 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

k8qy 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 literal 0 HcmV?d00001 diff --git a/tests/elfs/hedera_nanox.elf b/tests/elfs/hedera_nanox.elf new file mode 100755 index 0000000000000000000000000000000000000000..16bdff6f8d8a793ccc7a51dab5ea61b0f25b83eb GIT binary patch literal 626812 zcmeFZd3Y4ZwLVg8f*5&;lXezMLd$$_^$0Mw?{lB~ z&-YjBd8XA}-F51mx2jH^I(4dc+_X$&7=~Q_tE>v*9sI$f!Iu_R%nLStO+7?p9NFjd9AM zaY2mh?LF!fjmkq~mLR9BnluO`*C}QrC4DTea*4Q_H{BtKPLWlfnquuqUO3tR8+lY`BB*nJoyCgE#CndB9PYyMbz2kjb z<~8-r7eV?waq8zLHOK9(89dWy5QE;DQ=qVSi}URz+ZS^=l$JHP&6E=I@M+D&y;K@% ze8yXGDy{wJ={HFvJEco6Cbp)6Zrnk#zo{>+eNd&_blxBiHG_+Zag;d9u=ioSYg;?%?Em9LXJw&{&ohChjbh^&M}j{9OXO_hdl{Vkkm>!#drY6Ce?0R*S?b=Tj%3c}S;7UqaR&^NnQQbW zw3{MA)2?*AoY20?G*ISjsx(>ogqEb%vyIiJ{H8inqn8!QphXACGMddaDWGPcx4^T=MNm2F#uTAVsh`Hm09c(DbuZxfz8+nC>! za**4fc2KuJ?x24EjDyCxjFfbc$fO``|7RJg2j9&={(Un#jI)v6!N>_68@$D0QfoU; zT2kBB@@_Hy;I*Lsn=wXAgamO1ZjfvtN_$4|Y-2+6Jkh!@zljqp!S;&!#pYmI=<4*; zP)2%EXeUp4mJOIgT+kBI1@(IqLc98Agea}&#%2U#G|o2WHYFcO>3YGQ*!4n2T6jx( zYIs9>Qg{zf4sSfB+Zz|wH_r$^*=G&Yd`)9iLi)3|#O)OxVqE#CJ1Qw#FmyYuJ!@AT ze?QrfVNhO=4&APn(Nva!H?4jA6{11;`DLl^H`4T`j7s|z;vI7E2k6%qsnuLY?O@cr z{{lVB-m(n5ou=6GIf^y4F^c~xdyA(u4a%-4<$>~cw(+^`WN#gBIY7C4Flsv}-);(; z4{XLeV=%kvY-9I!62yC8X9@*)ZH-%rYpIQMNelK=MJfyW_{sQIuGzdwWSbIZhy*PB2rv&|ZzAB`DP1 zSv!C>Wb0z~v8~nvwfqr&Hjq9!W)2CrnS%1|27F@--dQ^Y{z|e*3$yPU5$(Oz#T(jJ z^Jef`$Qwg6&wr0u)I8>{?u)syo4U8hIY~3KU(FG2;w{MGp3d>ySoiH_v<}+yEGR>0 zI@kDv?Ho$6wKFYj>qqt`dsDi(qdh$txX?158l#e}J9qwjRQERYCM?%`6434#Un7Z! zRt)fD)(Xc1S@Du_md+=LdZq6?@%4BYi2shzryrhY(0YhKuhB$8zW-l@wBV=oKi2CI z(?q5@Ix-j~uB8$wVA|QBPUiM+$-2iu+@j<(lu2AuaebGU9V~5n$s2c^I4#A0m*R{6 zCiR**7kb#>je@~*jhHFx_J5lG3>on0m3z-K?N4km#mJ zC+IyV8iUqga=WGVO+LOOEdkB3f(nBvb9))yl81(RTeKMh0WV4%5*_1G!)yM(!&H3LX930bcwdGL3w6UFOybt zC|u94Oc_k6Bi`=*G?DH%jki~5KB z3grLR*oUZHOYP4{mz1&Lq`7K4i>)b=I0ZQ%wy=b+A= zVq;%&*bGVOlOaT}O8-B1FpiMCuR9sg%a8J(mpF|;V%5we4l*DBNO}y_(+OC=oAFUI5KYDbGZ$e{aGBnt2i*dM$%;nBAEW;5C*wq&v-CDoGwbx+rVk1} zL$JnY49Y&8vLmV&f8Y~pb;|Z=!f%<}AA6RTtt}&mdyjEJU8^aq|6%-Z49b>qvr6xc zUgk$7{%>QJa-F~Q1wPw_nFps_5oH81c+>vH!LogZic;tyIv){6iHkWwLPVC!2Kvg8 z|3>l{#;Z4aS9azlFhAy~%kSGTP5%DR8~`}}qO zFPAhm6)P!D_E>IHqBG)IUX&Jsi>$R_-)d*U@>xI49 z!ZqteeGfE7zOi7QcrB#=@s#leHq_(iLOy?yzx;VVTM*|Vy=Q9Ke%-;P`#E7ruySuo zMR|~>GfEri>rd!=NIh}sq~*XRD$r}aV{Ld%J6FHBK9@bqGo3ksUG=Z2_bCB(n`awg z1H36vBGPXM#2d*T;_q)neURKM{p`iMxCc@hg9g+CtJVXfY*gi8rt87f>qkAbsn{?- zdddG~T$WAa!hHdk1z&;7b6?5B>@V?<{uMkhjMD#`UbdBMVW9hUJtU9Ib)&y`r0I+@h*8dZ0wtmbEYeco$rO+|Ly>ZU-bdBz zs*vvRlKQ54Guy;70hdVM+(=mP{JUO#tF9#ub3y~BAwwrHPYl&?cF(+The$&6~-Dp%W9 ztcBeYGJH-ZL2XGl5*=iE3%&sE#fR#yt=kq@5MW_ZkX)Vr<;)eZKse?4$+90&Ole=g zev%O?f=sA9*po^7yrH5DsM4}sD4RLKPPem46)yv5t2*OLz0VFhG(W4hvP8ifG)`*{ zM&VRSpVu6;y<7iBTK}5(JgrM~{xbPRtw8DIsq%6!t~hYC?u!zSX08kuLdw@BE=l|v zsK+G!K$X~dQQ{X>`k$AW($81v#{{A^C8~9OseTf_#NB{sB8KTQE@*$hV;1O+k6)rUJ|3%Y z;S2PJC%#HC?u&z!zb!hO#4y%qOsr|)6=lUvk#wjw&rR+`EQxf{<6 z3~9EaQe>A{R{6^Z#GZIU{_)>0{5jCCN2;k>SJ~(#k-$--z$#CUeg3@(?@6|$%EYtI zV}8cj;4k%?1;Xi^L@AyMU@Yq82nqDlGy!S3Q$$H0B|_k+tzTC`y_I;LqIRYr+KxU} zOTUed3`YY;>HkmE{|05p1byb+RQxHsqN*%84nE#=43?D@R8n z(L@=t^CUCbnSeRCPI+`PI`Von?jjevr*sEM5&U-3vi)SzpcGEHd^RUj=C0|5>?ne? zJVS^DydJAJ8+O(w>sIsL`eck7q~65)%TJt8`kQ)LWgX zsi|yjO><48# zqNzgQ1*b__JSp2<`0trCbP6K1^G-viKUzuP75rD|uYXtXEch4_#Ka|)BIL@=7NaB7 zj!Bk00@=?5D@4=E0lVHgAM@4d$crdf4^9SDx~Y>)t{`%t%QLj@P1!^-j54&<@qwcr zq){J+LA(yWa#B#f+G8)Td7|cx8sp~j%};E8V>6^Kn=7S=DTQ~OWLizAu}XU}+T$-A zv*xm0TsZHYgI@Ms`jsGAa&`OXiX@NP;j`iU-agI-xn_EQy{J2AQd-8Dj*|2e)E@QA zA6r-N2zmb~8O2k>6=I3AbnQHurZ3<c0Y_(l!&6%9`q1-;^*tf~3;GS_DO3Ovp zdNw$BHBC7*$%Y%td+fE&(wYh}VE6cH;Tc|cX1HRxSj4l+;xSe!8~eS$1`F1_V5c<2 zNneeWe`q~{C-|>tsmEsM?0#JTe6~V-r_#fpC^)u>Z4cZET{3v$EO?kW0u=R15dVqv z8+;`#BX)dqz_S709GA}g=Byt1XAi~U`t!4Id`XrDRTc|mIrceO7Jo^WMPDh)3qwDi zmgUc*tn%LI=Vg&6F3Iw!D$7HvEcM{>2VaooTad*vElZ&)%h&MLfy-nup849@{a@nW zsq%khqNb+#bNv4mW5VTi@$SSI>w=;?U*%}-Sz0eE&ooTSQV&@kyiAtupOb}GWl2+W zCWFiSz95SUvV3nmRxhvNKarwmD#W`klco1e^vsqOE77iAUiXTf(N~HATxxAV-qgKhhyboU}qLSCvu zZGu4$QKlssKo6n3eM9AK%NbfLuMasYR)|;fjPgR1QJ#cw&Y#on@9 zm1>Eavm6{JTqe~Gkm{ZDu{t@A|3tb9-{?OlmHEuoXYPi9@G@kg>v-pvRfvrJ1HoKP z+$oYp+;S~BUMMaVGwkWBwzw@P|LRJY1r2{7W?6 z0*!A^)A)``W8iZ%;s*PNq9Z#dDUD+rmN;Hr+psCvN6YRRsuV5u)6Uh^Yu0-h8&BM< z1m0aAN{s7$=wxCqT|cnF!F2&6%53%p=))<TyaADp zK~J%$zbGMp!+$E5(*HznoTwLHUQq$7i#+vTD_{0VP2Q z6hN`%e5Lrb-M5=lpPoG5vsp|pdvMH#c2_B%86*H zx3siE+-)Cv&;?$rCcAeST>F83gS}#h*RkY5y({@WlPmi@i);O9v+DuL;%da(fPH)A ze-<*k;d^jSjeI9c9PZQU6^rMH-eu#7*Z1aHKU-?!RvwLdfjY;~A0q>0%x1Nwq z_~K4{vD5CWu z6lH4LPmNrOu>iB=b!AHed~S9_Rjf`M?4Ak}_%q$QW*(Dm%Q5BZD1UA6D8rkmhiCo< zaCn70HBzFYKqb1OVswFR_ssdlf&u89n2J#f*ymI>0gGiNB*+TIn5#0`=A5aKY84sE zQ{Hq*E7X!mE|6#i5^Wbs%0@|@$Pu2-vCD3+*uH?@&5QXZb}@GzR=tDSS1_pC)awBcsyc}W-VpiX|&h!>z$sB#FZ#H(7P$JZ}PV~*=%o> zvwj0m-B7Z*zSK`=`Sjac3trzuijC?#odgM8d%!9$iyWX98I??TrO5Cd>SE%jl_fx$`^=@7=xeKKPw}@{|JXQgeeWSfcZ*VV^qVDT1 zrd6HqJvv*>_5YBI@>04zM}7X`R2Js>E++wUj956&@?b_~DVAYML50rpjH(XVGRlgZ zx2G&~**#D1^d?1!J5@?m^FOJMo1&9J{+Pz5JX|~0dsK~HP#!{g7WK;qroW^m^&X{T z0hO2Py+bnotY5Sm7fd($ahlb70k(C zEv?1Xqh2>g)-e;l9N(ZSz$tp@u0l_8eFW7 zS&ul)%&}e3kv~q+(r&D*5O3o1oeuGv8w>J}Y%uH3`*Hs&@VVl97bDDAABysNRBbc|@AIoGhHb+M$r*y&FD(~ZK9@DAM z|Cus~-H#j8`+rOsMfq`R2cZ6^geOSwX5i3)Xt;Z%IJZ3l{|MR#>x_=PGqt?(E`H6^ zL2oi@vy3P9hV6^8!&R?tzfMR;UD7dNVuFtHvHQ=|duSK?GEvvoKh4X3O>x0Rm0S3} z?M2Qzs{Xls4z4wi31Ts{QQSO3wo$onJWl22*(o;I{dj_U->GtGQ}6dpt#@JuUN!I0 zYqJkk2~WWPIWPV}5-bDNEW=B1aqW%)_d;gJ`p2zrm{8_|S zR#l*U{_#xWEJ1B#Pw7Nfy~~_hx#FiPheUctUb=Ew#cpr%d-PiL-cno_OUDGl?DpOz zRpRO1h-+4$k0@7;({|V3e2YBgjXy2o%_50j?}&(MUFA;@Wnzqeb3^4*-W#Re-gVPC zH>*AT8kO?ZxK>7%i85M&4ru*p^6JXX{43c^&XZNo+6S_#a-=msgZ25m#ncxN9%}1om6foWcfpc6yts-ev7sdvJKD6k#56%67K(i^gzD_T6qnh zn{yocI!^L>y`@XV^?X6jui*>j#MaXM>?dIXeS17`l=kI7f1Ii-a@BFxCYkYM<}05z zL5~@s6;1pt&SMxYFn>NDI65`5e>9fw!ni^G_M|ZpWiC)hg3XQYx--63#}EA(mT&sG zoDA0L39th^v3%h7WghYwmE&XGO`gn#J{N3}-t$C=jYC+65OpegjFK}>iWun6vtzcS z9OUyOUi;SNbe?E=YJKG%*x@^2hsR-+oO)>kJM{1g!3u!}@Yr41BxhGu>0@hDyr<4n z%L1v>+OO2!2upX*gU9>yg@(vmJBXXZ_*`iZI2s>}(PCYR?{ThqlFoI#q<4K&rFng& zIg{GIu(QW;k%tlmu#-SY;a#-Ahz{%*%Lu<>lr6t|BN=g|GU(0%{r`{SI>`;(nR z_vxL7?xUs5UUJ-F+3keA+Njd05WV&SSj4T5G(WZKsWlGLLTwSt*agXERWiFtHrImn zo}iAd_qLP>HBJUrVS<{Umf!7f5Ik7OAUK?T_EcnX8FHx-qt7O6)k>qx+;`zl@J~7Y9 z_?b4H^0hHjuMM^VEsy%l=o$>kOQ}qQ?dt-kwda#6SBj7F6;A&e=J~vP4NhJ2u0E_# zmDrp#9+OdiGH$M*D?tlaEfE;!ysBK(1rM|Y@N@MTT_^E)6IC0B(!U1tx;O5_`W*hp z=E$WFVUGL|og=@xU7aIuzcfc~?B&F}MJ5mB3LGe2D)k|hiWMqwU|D5^y|4uOJ61BI zmOM6Uf;BlH(lV)Rt5N3r_)pgl46t+P+?@nhLbG1aTdpF|*DNAK?;EGO6*E-ae`_4k z7OEbv9Y>swc++xHoF8Eeb0hWk6}e;s+N+nYBi(?p+frhH4qP`*T+5}HC9(_tgHrp= zsy@61U%aCB?O&>Gnd(2|sLDZMF{}v>CKI|%q{t=Rtp3lH)_}eT^k+p#NH>dGAT)Ad z{n&Dmu6upzJht`E&W5cCC5NET6UJu29_`DcZO9(U1S%%pJZ;a+k~5L_3glfhrmifh zE$%At=CR-GWZS(}G?m&WF?-887_a8PU~grerzkV(S`1@n+n21SW4ZA;&cZrq~l21Jc1Ls+BKJ4vk^rW(?IS-LJ zH%cOWEyTS@x>@~yjkLn1Q`_T4TXc@ceAIacelGUl~YHGU_%S$N()-<)X2|9jq2W%3XGJonN$VlMxLi9 zN3NQ*UF$|;NsZUhOMPrnXU92D(j8+Vl2n+@Axfy0QT@!+6EhXS$FDS0{lp^HTL&L zi?KTUo$4Pux52Mxj68o0R~&bexGj-aR7<^p)_ipgPgOFvPU3`tvIYlYf@Q4q)KLvV zl%I|=VtvEQjSXJQDTm5o6F8g+x%!-o)phl>%2yh6!q1zwH$7v2sc${sj6EHHOz-P+ z^9y_fi1N2iz1$SAzuXY$+t$?R)kj#+zOI2psNXFKI=3nf0#7ObarE^CRm$UDix^Tl|*xw zBW7T|K3BK()kaGRhq#1_QUCg5jRd}$ok-Cm<;GECE@oWo3!7ZN0M7(}Cd|H7;@RMf zjYIZgvFB>i=CWH#*v>0$?GB=RFh%lWy9tajDw5K+szO3(w=Amvqi%C<;-u-^7O)0X%=X6wm0za8DZiYse&w6Vk?bg^{Bx2$ z+~_6J_F*dF$m9dV@IQ=RkoX^ydV$&}*9aaK@hGGB2n7ENN2#ARYJ~j?`;P9rGbpC1 z?#GCZ?z+QXxJgSeDsZSXPI+~*R;0cn3#h+2=@Tj1Oe7B01C3J%^kd(G^2#LDbvp6h zX*-fAQRIAXlEzPeF!>l7IpPUo5heUu$ZolZM}v?O(vmw^SOQ{I@Q*Y8foSGf76ZN#0RdVGkpVb`%5W^?K0 zhRyI1P3QeF^6IfSO})44Lhp&7NE7fDm8Ht|iFI_0hj8$3}NClf1{iafszlRA>ScxQYC&$sg} zc>h=Rz4fF~eeXeP)i&K$J>Ju|5995n^;pUm)m_m-;UtYH(TO(LDyy6es}L7nCpek9 zfYVua%pY+y_|2A5zX6E;W+E2P`No6+zV^)qbApGbBYEl0nC_tRQh6{x5gBo(keU-6 z`JEb9M4xx5&%eU6tv`W!4mQ!=L~Az#UN2aZf@z(}ZphhH7tJZWq8;mx>7qBF!|146 z`WF9|!=QY3+@{WFXq!^YQn6{Mr+%iGS1=}@4e?B$Mz5zaG8@y}*3${tZJ6l3MzXo9 zBAlyqFghYe8NqgRhWiSMcV8u?yDQME0{j5Rr*inbmjn45BQ#njI#M|Xs}MdtI%C@7 z+cJMojl*e>w_LYz&6Yy%sirKOJ45xCt+|yHj!0Pd<+l{3ihn=3CHHT`jLRBv8-39)~Cu6HJ$@~_#RU{|3$<&2I@sdv$l?wanpnn1xFMEM0~zDeq681v&R8c z-%z9IV{OIX&nU;DI&lDRk0J)&i9NU`Pl`n5BtxUKk?u!{%L_@cA8>qUAIYJf?1_=w z^VkCn&NC$cQIbc~s8u*I!Xte#(*G5i37l?&U2EbU`H%Z=0ja4AI z8*5B%^Pp+jvNFW1Eq@+6T|13J*}KM2S+JazN9!48;*K94IdbIYb?esA_LYPl#t0w=mS5ed=q<;57z~qwRNsK zIWwj=Xn$5?^Nu71OovVWrNVB~xuRpGv4?3i_2}z;eTJaVNTeA~yg zl&r2DktfhQU<)Bl#5&e}k)3!>g6;M4`KK`wK3pkceWC<2H%>VcrL8I*@lFfSr++&^ z{nxS5s?XP9h7iCWK{6P@8ub81BriDn1Ultz%x2CG3u0c$PS|F@k})r6T`QbichbJo zp9HN+Yg#yeX9bJBTlz5QqgNvSXx$2wejD;8VTOG5c)2WySta^*O5?j&gJ+s=sW9`T zIVdz%wK|MFT%eI>yF`CQW_zDONgZRtD=QMJNc)VsKl=CiZ}u;N4%LU>%6zhK7s|Ue zdee$5nMRugWJ746kCyQP`faLI5AJXOoMa!5ErMj%uAs7QIUXHZ3(4Nb`ZSd+0PQ`D z)`n=7bxrohx{83|z+uCR6VVau6Pm*v(1pw=5b+lA89XP@Hn9#Dus771WIb9$cuWTy zhm9!kM?AI;wCu!L8i~hKfgM!Ix!wc?O6L#oFD*ijdI(Ve^Z*vbQ0@}9%BWA zUPQfF(5TS!0~4iLjind*sNff1e^ATWj+v2n<2s?YFfKy9cWdf@P-v2vLOq^V^Ly&w zs!u9QlX{QRcdhlu>(k3dBaGk*RER;$M+zI)I%WsxdRar2P#-|#q+X7WTsP$k2=zwT z7Eb>Wc-dm>^>kf~u4^+r4gTBVhjC7~w2wy*sk&r%l&*xu)?^5FiLYHrac}S@O9^5T z=1yb*0R@=0bno9pTUu9~-@ndiK_n{06V;ZNvISzC=QcXI(?b)#_*anxSv7GE&{$ zx5z~X7v(wb^3r(9Ii=pD)Tpj{DV^=KYu zyQ@~Ms`i+ATvwmWMnqT%KWj7D*daJ^(6e;S%+vW#&PhzzPoQB z%3X+ZE5$VQmPBfCpya!v3E;z0{oTIf>6TS-6_)Dbyk%9zdXJ-GHI2u{YzLzklh4X* zK2b6ebwD**J=)MK_`QbToA?djN88kI@n5IT$1SLR)5UoP{hrRd>A1>O#C~*ar8H=M zN{8y(66o8ft4o$NA)?HQ5o(r1g2gMBiRbJdXeqrCA1$hIR+}x?ibL!2m+GA_`Gsn~ z-?dU+k7FTXk%G zrQ_IY>eKN!gXOe@3-VAqk;+Xmp>o>#i5q*ar+tWqCE-vkNC8x?dSze zDV7&--PNmLW|8!K!fRBcJvC$ylX?unl6v~|*bpNyL7n`7J@)*_5XtjHZ*fu{YV97! z=rFZsqa)v#@^8v>eH`)IMF&RsTzxAqGO|syN9NT(;2_y^+@tT6yRSKI5lgPM6grM` zZ6(>Wa5BeQ&voLWG9q#9mYh4wHt;2jQpNX&^W2-HLRc*SkW1>f!ovMnHiS)?h9E1X z$i+xMi}XUI|3&uKSGaW2R_w0#;rUPU1CH32j9~WZn+Jx!f%WLNl{*&S>rQ%atNTjn ze%Pw@?j-3|`3^UKx&mY1VYwO9Oz02;Ua~XFCHE?_E5j!9g}R=2j?8(LZD870{jW>DVc`WU-sF2WOk~= z%)UxuXU~Wbv@efTjMDU&4O~LW+Cx|NZk&Am9Lafg;|2#Q9FJ^*^qJ_bf&`TF^?P-} z-J1mS0-njEZO=WKC$Dscm!083CZx|=-FUN+zQD{1SM`6TMEdlvu?HM4dT~b2NxJv@!^l>(N0~dn4~sZogfHsg0(BI5WBhv= zSVih2k+(=X|cqxs|J zPyqeJ5-!2F#bUaQ6P?;k2MuD1e4)gdJjvE|n$>4uJIw>u0D`P&30u2JVY2j+H{sON z8Ro8j(7y`wW15f~e;`9A?Xb@ig>&X`);S_1Lr1W$FukVoUtq0y2i5}rf?o%IbbUdu zoH7ap1am27)UWQULH;J< zGwh)}{7z=z(<44c;YK$%H4&^BSi0}$gasbf#qMSHC7_0{L=7)NpX=Vazz|3fcHWS< zAnsV-0!E)$CksBJoQuNKtelO~{5V&`N7GKLX{V;s9#_+jt7(6TE{r?0(`{*Dt~InI zH1W=zv3&Ey*L{^Lz5iCf`+0OBV~#&G{nq1S5-;Uw=p&3F{`$mu>i6GQzyI!K<#(!S z;pw!1k6@2KQJU4%XQoqM_qi+qW}%@ep`530cdBo9L<^?NBwlcXV%N4=`Ob$HcMJ}P{j((g^18*y=wO9;t zZ$F()a6*8yi0rSMd{$qEkMl6X0JjVN;A9_-;hCC>yRztxUb@#1b#6pladbo%6`JT= z$aa*@qDWJz!`UGC*gZ|K_cMHzx23B@8z3g?slM@|zIqHJkuTK$Ne>qjFN*^%!JpsetBJ_RFlxt6~_gtjs zkwlE0)R=cqB2;<+0FcZOr@fo2bN3Mk%ggmGZtR+QK~5ZWf+j zc*PqKYaxK2j}Q$R9eH4i&KBui-IV`mZ~xjoOs;8mdStMc+8Ojjf=nO5c{v%G26#KH z>XQjiCNW7&7cu8?(zpgr#;#7-bAl*%dV$7cz1TrtXp>UuYLwe1_4qIrd(DHhQAgQg z2zxgW-|Qn9JvBFom@z;SmoE-0g+cF!Qc{t5kU4CFrw;RC>?t%$w(D#~|2fGVrg@_y zQq&;+b(rLz8J~^G$M&=Sk13vfpR2 zht2hseZ*b#HVa;eQUjkN=5mP1WDi^GKkXCT9}eDXVA|s(Ci_M=Gl+3hj^=-szSX<6 z6gzEBknD61(od4YlMx1*6M2i%q{BYqPDXV0JU?yeZ}s`nd)9i_mVVlovyhIp_A(&b z$w&n?@GjyD72ReoNb+2mC9`|q=(}<5%#*sqT!=v1(cMeB9s|6GB_86$X>rQGr{c?W zWuuw%3?H6gLL~#Rl|Y3J(W@WP`2iovrRN^Z_A!WopMSA-JXt+8S7N1vwu+s-X+VlN z?S7{}sfIb6j(WHqb)%P<@UKmUHAe89?WePOta|_x#%(x_)d`7lr$h)=Q}r^7wxf5) z;YpXxBljnW*yn+v9yLM#C*waY2d59dz~ICTYHPlWeWRS@Rx$tA2}<1-`{HnPBm<=z zB%C^hSw8mYPO)@-Mxa+ph59)dd}WHpYA9ZM)_0_4v#++s>2udG;XPj6;NhBXpC`S$ zhC!}gAVKr&@sUCUW(2Xl039eFb0S|&4U=C29OxN|S=1it!D$GAw6@eXOHXvYEMCT=TbA zvTbG=)*f~>!OE4ok(biwl1+!rM~pwD{on>j>yT~`%?HU`>}u^F+j1p=J?%t2b<%!q>S6G0bmV>D z4DE%Joml5Jsvg-s{P6HKV!#kcjE6jdrW;-6le54tlfB2|F$YNMVQY0tnROMVU^znj z;^-(Miab;YZ5+OBm~$6JX7uot-=Q9{Mh>yx1z683-NT@_W=bA68T2@pn5`1Yafn&s z_ekmsMeDaXQlaZR`=0fFc5+sZ-D8%7ob~A>_iWj3Jk2Ea$m;4a{Mv|{k7uq?cqsxvWj$ifdgq<~%O00xh(S$ckr^_Ji*)^Nhx4nplqU-<0Hba}f z4K{R-&hPRyK*P+G&XoC3_JcSf#fbAd3_*g~vc88qtUK~eq{o9NeI#EUT{ce;mw*w9 zD4U>991@+M{!?=AY4rXh!U1u858ZKpBiAFRhNw3} z`%8&?kt872-saXtvhN~=C6F}9pWrlkOjskWxr-ugiX6jLAE7qQNu1e7SEA0;ZoZ4s zeG&fnOq3WMDMSf;gyhbYpREOr8e6ultR$QDloZBCgu5*A<~=gbVDe2GWE(8167*W( zE}$Bq?ar!>0#D+!JbGR$^{-;|2LCotX3)le>NQ7L^iJqUp=2wA{z0SLzY(SRFi)Az z9b0V;KGI-lN@Uzd=<8aw_P&mm$@uSt#-1Hvi`Pb|bb8mylfFH3?^@VcTGmtR;Xl~S z9Hx4=a+2f|*IJZAf*5~X>!hAN3lS-@`Z#!U(pGW+HCG`mKqSP1zz4OpduZMdhhvC2 zBd$H}yUh6BA=U2r0P-pmzAs^TwThut`lz;6#V{Ti>QoFH(Pnvx(l7x87fUbNd;_Sr zS+HMNw-C``w8v?R=oRxM0dEWkX{;_s&nQA{QOusnlc@G(q?f&)4933y;{>nvrUxcc zWkj_H8T2#Sr-IOm@e*m*y+AFR=*W-81>Y|*`;J*gIBO5j1UmnWL8XXm(&v#`iwZ$85tT~Udo zFFGHgc^LO+kw`5af8RxPfT74C8H+xNuU#GZ)6@@wdZ7QUTG*F}ez5iLhF08zaVp8f!q#CiGIx&0M&>Qj z<~^KSK-@m!T-}?{N7*nFXzcUK9QqK|mUlw0I3jT}&DDTbZbS|?WO64)xG+#{PLSaf zgl5#a^RPGOy2zPYM8Su+SF>dj9GJ-jH}8SIa3kIVnxDnEFjVV96fx;D1+s90tsQx? zk%tLGx4b$-R?GLl*~iL5wJ4>A(C9%A*Aa(j)?0_iCy3E`s=i z*c<|uS-u%H;6_>^c8Qy=O@TkrA{i0)<>A>(stZHq29XQX5gWTZA~@F>d8r*L_f9<?}HW(4)?1y%C%%T;ii%5++zuQ{wYDN@}n^=}kY$6i@`N z1*O-}uaYH%MX2_oPW<>poUF?xvMGChO$?>~H%8BG#_6Rp1HT5frB9sLF0z$xIhxWv z>HhLV8~!|ib8D8ED|dRilMUDl8y)#a)L3a;f)(vS>OuCT(^wrE&qK(c2Z)3p+5Qfx z-~Nu$zqdEFHMtqP?^_t0n90afD;`};3epdxhE>l>q~uJV%OoY^gs+s2-tttO^q3ml z;rPd}ZC?fM;6sz?f0JM+gKomfEvaEkJtGtrn%|pUm?+IDOp;0p{~4j*Fv8!4g~DMe zr|={7*(UsTn5OFlS^dunr-u{wrgrARx+2OI(3hN)+C!A9&L_%+bK)Y2?aZ$?J5rkw zOV`4@%{mjxj?MJ&6&^b4jsx|C;7&I6fUBN3i(N_02@xM?$G6NVyStw5eL-E@Z{^Ldl=tp%Wk`3zzTP8m zL46#Su{Hu*`+ivZ^@uGzB-@IS=V!xf(Y1emNk#Hf&Pu(`uKsnTsUBcQvC7 zr!3%YEznI8wNm>MbV}eensu!5U6#tv})N%{M&oHtD-h z{v^{VJXTiZ^ZD%JFB92Tl4EVhzE5~wk3qo=@rNh?QU49Qv z_U!TgC$htyc;Ids-{+Cp@hy20LcHZXd_`Nit!vLYSN*GrmpEgalR{ju92{d7eu2~0 zILg_+&+~E{c&U*;EOX$bZrz)SK}!qWdDk@--#*{djdcenJg6p-z=v(cdX@nvzOIDl z)7r7iTX{UG`B-{Fv&Uf#Ue0gAG`~sV`1S>|s~-5NJRqv#D>%pm2U$2h*i}C*%YmM9 zoRC|bEX9Qq;CoFtep9-wi{cUM&-Y~E?VQix2^kPS)WI*&m3UxIW~`S_zQ4g?ZMAgp z^>i2aCI?QL%1UY;z{$5NNx#(HG@$Hzi6#gAL?_+4+M3iSmdA2SqO8jzp zM7DLsN=ZEM*83?P2XR6?8N4+MKGbk;`2sNwT5f0W^t?o*Elk&g-5t=Rua?nR)EsC| zocq&jgTIx9zcqyr3~J{&M)C%Bg2c?{n2-E(%N6CVk66^73meg0HMD%UpjGUvhm3-n}2idYS8=@OJrO znbH|{xOdiptgdUsxn=pCaX}6~DqC)MnNG|Or3LdsreH4o*+R$?By$s66I$Y%t!;Yv zc>=89fkh+~%Q>OcpdbjI&6o{-HqX{fa?=jt#MHfRj1j2^W+R@XekwVb)O;;`?VQpw zRgyl1vCRT+jV(+tCr)WM@iPva*3~%D!gV;qeNU-w&{U)ole>}*yfbJG8=7$jYO^`4 zYfi&?jTW5S$OPdJ2*&*|@i){XWLK^0*51r69_MT&wnCpqY{KJZ4)AV&G4uyAN9B5- zrPaJY#(4?l+?gp0@YrlFDEEAJ4fQ|J_@O5ePg+`5n?99o@mLC(LDZ~VlHJ7Hjx?{U zb3Ete22I7(S{NR*Vm@cWe9nxX#I;$_|CwgnMXu6DQ@|Dc3u3&)){{b3G)tA(pLMH) zAm)2RePtGzog$7zY#0OStjQdl(b;WGJCF*VlQCONI%w;%v|V$8%!!j^qg9FnzKgTE zOD&y-ea5bmGDFv#bc`K&Cinnm9yiTRJ85X9EzKkhWQ>)W+MnWg!`H48H#-!238Gf4 zQQ2PZ(0AzC4Pi^CY_v!(!cI5MHJmKL$viu-hQk~;&mA3<4W73R&D77B(y>LKdVJ)%9J0@;vxm2Z8r5n{vyjZn@9zsrPDUshPETXcGgAyKlZ*nKC0^c z``mkH&m@_I0Fw}sJCjKWVVkf9MVOf+mjn<(2pSM20RjWEghdG!aY8`DRwn^8EF$7k z+*(9YYqcE~t+=!^fEJ3I;(2v;wGQK#?urI&6R3w4&!@MbgyN}O zaJN4ZD>WicQ3;R69wXD*6yZ_LP8lmIH{iwv+SW*0Vt7bu(r+`kBtO&)clE-;UBI=DF&<`vEiek^S8^}@D6~BIjuJTQJg3{cezIH zryy^Z7nF+b&X${@Dy{F%ZF^>-} zsSVw^OAmiB-T*Z%*%7n>s`DvIO zFvVQnTjZSTz!;}jHv4!zMld@ju+YQdER052^Cvjfb|l##_u5ubw!7yp#AysC?;<%C zhagqXkC0`b#Pg8v@sMI9VgWr`ey&{{q@qBQ(J=JZ#-%++u2s*=%lz^=E|)RsZ* zbhKboCS>n**yezWp0nB6labd=pY-N=y@lsh8_8=0@=^Z@(Mcb1nZ|Q=2haUfZZ2<) zm3@M(Tm}|%?Z?>T<$J89-XWR&gxOQ7zy%~NgQOU19@1`=!Of1$n~^T9G2PmFr+koA zlvi4dz07_QyEKyW#o*EKJ##jwWvoaUFyTnD5J}m?Q?v1uUEJJ*(|sg2cja^+!Oiil z4})&TG;=(k>RP2jzPdkG8%b)RbrWS6GWcc}vq_cD~%W;k z*!}k=d%ZS)udHfeWO<%-v==9+hm3qbFc;k1XxbdJ#k}>p^nLo^K@pT4Ve5fBOyYT% zmd{upsG?Dfg+$2pfc{gcjULAOj$~}8#Mo{(?kFP6S|}^rieaCHG1Dv1zZ}6>4#HN# zeH84cZer|Rs93lSgnksTZg&x_0?ET|WwQ$}b3sR&HLF2hQEty{EXg-m zYrT$!gWik=VXnQwJ=fMC%#$13^U@n0n0IhqT7z(>=gzu2-@H>d-!(r%udU{XV!?+D zdki58j&AFB2IW9+Z@jnwns!92>jiBmLmaWT=1*M{LZ z-K^GzrI~+a*QpIQAJV~k>%}?5v(xD1glM^82?aG{F6#P`^24a>cLItsrI6|r$>1S* zHK*es@oYt(4=w6zdd%_?T}r?wrg34wdCBqd0B* zcQ|S7{~jmV91Z<&PK?$-vM&DbaFXK@8hxCZfPK6R(G*o~`u&(a(;EJWyBnyhy-`<> z-M|>NZMCS^({E(#5$L(7+b_WUG0f4jcTc6)qI!Prp5j7%7VKkOB2H9w#TjZyOo(ve zG0t&KxCw(LO>S#+m**d1*ShEyKTn+w9zC^AF=8W!Of07l9wD&<>CB z>N8FYpOl{kw=K^4mhGPM6nMz66)j%_dKQ1|L;tF0(LcOv!mhy%-aFG8-kb|puP=~S_sTO56%;h*ZxGkgMPHwYvo2{XT ztyu7s%dk!GE^(&`>^IDmS)GCR={+#}O@RdPv)&K7Ei`skei!F~`qINSA z5Y_$aIe;2S?zPQz3rTjsju1bWUyohPgiw(zK#tPeT3>uhFcZ9s-G4}u5U>*SMUIpkAg!QJuVhGUQ%B{SwLv^$t`LRP%wheQU7G z)J>t)mxA+Jr6*44zd11#GEw>-bEN0?lzvK*m2qF>ycP3+80)7v*Pp9gZ21angz3Qr zii8~wJ8oEwz>VPmUVbVTJ=S>Si6kz}!g{SSSici{5f@}GLEBbw-#$%yE=w*Qmjgm; z%eYIFS1ra8`!IIcdkedcTy5WhB*>BRMQD_J>BI@lZh)21YO|LL>!ymmb^Nv@PJx%V zwS0kjj7rT^4xeZ#{DI+Qa`k8fZcrug_-poo`hLML713#ezqM&_$339r39N$dzSC;7 zSVSxJpSIEM_YvY%cZs`y*cRANJ^^LIqpZSmVEw-Mo%$_tJ9S%PcWQAi5IeM3n-m(b zBg(`7vdx4&gp*HQ3uk{joDsXp4|v&Vk@d#e!v#!Qd;XTChS~yRQb2XjyJjRRj z$^HI)!n69rBG2KfHXX2iv-(>1CEWeQG8In8w5uX%|8o1aX_RxH+B$OYNUL!ir(dkO znueMSSDSA?r5;c|TYGJsfjrI&52$H$Og}S{zAi@i9$mVFYE)tyc3un5#Nqwp9x9WK z`x18=wsq%@I+yiE`Ps5_kVY zd1mtv!mrLIqO}n5;^k?`w?8zA>R26isc#&ETMlS-q+p%x284(S8@3nbNGI!T)N*OU zdh9CK@wQ9E%|F)sdMoW-^i+}+S8iO5Q*k@}o-aZeBQ>)ADM4+26IRsR&K%S8{ab#i>8`d>ay)Tq_hO?W!b&tXvY4dkD39 zV)KA2Mme##rmP0i;c6EvJ^^QL7+!TE9O`Uc0PV$dBu7Gn+Z!e;_THEHZK1{f#S<4p z{^H_dIaobG_E&r4lIl8}F=N*`x^qEwc@Ogc5Y$GfJD@6uFm|Psu_&Dkpwnp3>6s30 z8o1pAw_R|flTbbRonbmbB({QnTg0t8?9t+cUj=q&(Po*j(yPjSc)I4#kiw6b{_xtE z#$R0{_?v5(e}B!=6@yoNy<*>rp*3A6+^l>x`76jxU%phxJg~H7>9A${7Jt2XFy6M< zU(K4DtA(cOYOJW3_brj*nwJb-BAcq0h}dJtn;*@Gus6wqt@%<@LB;*Hgp7f}>5EHr z%8K%Ou-ar=U2QUZs*Q01Zut9fcGaZRLh8VWxX(&=pz8K*STSyeLp*2QP$O<0TN78) zRWaW5-2R{749l_fEzpxgHz_35u+EkaniChjdWp(F?9=@tp^pPM0@6ay>}QSd_GESu z^8Q0y%D|V1c{X?g->%9Z5H|sF!{?+vU4jSu;M_9aG&G?Fo4}=f)Y(X0N9bJC^(hV^ zY8%AE1eB(Uj1@q+pnL}o&Rt(Kwx)-;-5OI{7?U9`~cCW2nbI5zBQkX%M7FXkTyiKUU z86BQ3?XuGTBx}C=d>SZgklhp*$glx;noDF|jza1ww_pZW9InKu6CQMk% z&t(1lINtY@T_p-bR|w~3qct>i>_XyQjVp(=3yUoSA@PXp}Afg?ha=649?8M@%WTsQ7(czpx?F!oIRb>Fsy1nl}ADe)Cer~TBxA&7F zJEkr}TFf%?7mK(NKR4s>;4-}_Fr8x>`t;?&;Nwhbo8>nKi#WRlYfipyHDX8nG7 z)8d{NaDqi%n;EVjpy8)scee@lfnhCfv9ab6=S6$nfIgvvsTmvA?cWAy;v;dP+@4I% zt`@c@rel}nbc!-#P2+x@a-k*j@<2si%fQF-hRTh#p03Bk8*Q6v(U!8T*=uyNw|XyL zYB2FsZf;vxtql`AhFx3%C#BWhXe~lrf?U_{O8=m?VJ-RyX^9L9Nm%1K6Yhqy{&ppC zV8SZ8wNJBl8okn~C4L{7_YE4Jnr7=w$}o)J=uZAXWu!7d(LCZ!b9>zG4Qxv43%JQ! z7uGZi{o+D-HTQtVQbU6EwHm8(iPvaJNz|0!PDVvVcs-p76Z-WC*;h!LXL8CvzC!ee z@eWzQ$}}V|WzWj9E2%^>?yb0&T%{e{o$iV>iJ^B>aWVzu9kH11VP*8<4)710#c^rDb`DV{XHTikwsjy*{D z$vp+{64aQ4GK*DbKeSk|uU^dTp2feii;GQhhtU46<~(b_*`&6XUtQ)WVf_$P0-Rz` zt+fpd-!GTol;J$gJ|UNlW7RLDv1Ns^_ORpRkM??;p(bGJ4hj8~kj$~N0>8&sMCl;l z)jq+0V@(ZYL4Yp)U(}peO&Uf%cPeSjOR z%TweH;x>26gW%A3<(K>EOpD7pF_rrA;)_B*eJH&CletD~c;i5D?%S8bYr<$h!mD?q z{n&lCW_u1G>yf716TLiAlY%j}C(jAC$InSk!>z+o#HP1WUjgi4%4>j)aZ+;{plWfV z11D{^Uubz05VPvet=4S+U@6Y1++E?d_?WrGC-l<JF|p3`8q`53Pr*ZHZ7r zZ|zL9uC57y?mlp)%j!;5+qm!hxvi>???8^dZknj%45U-II87Mzy&?2zg`^@&HB30; zhx)^1zEIymdpmT_rmf``oJ~p&_E9nwd5EmIoaZW;?XkNhdroy$-6yN1>bW%%?l>4o zuJ`S9YHcn~P=N1Rzdc8%_sRV8Rx+uwF7W;lZh?=7>_eKnknB6$&83sE*r(J)W`Y9l z^ix|)ve!*x7?W_1m&qk1VsQz7$H@R+u&{p^O7t}m*|tv_PYd7W6q6>-Lgc9ey^9U)J^ zsX>C?iuD;fsY?Aj&W%GN8q3TqNh-=LnXf##xN@-o$$=W%C)L`lr>d)}CuC+;!K zEC;=8jwxhNbdWJF1*IGfsE_x7Wk};$>{SjgHURc-E?_=})FHIb9O2KND<2IjlxrF20hvjxKMSs^M7hX$)x@LkEZA&i z-Q_p)g|J~rY_K93&(_o3o$QvN%X_(H+GSC(t&kP}=)Xbg1ZLZ~uY$4w9GowNv;n#! zAoh_?o@Pg_-(6b^p`l%NjUzinByZc3B#E0#iSDpI_1RBAxhE^IybfI(h16C$yc&GwYnnr z-gL-gQKcc_^d_y@&}rr70ie1n5d}MJkeU%SeJFLx`E$q>oo=YxCpJM~4!*4G^hB_Cz4MIK za4uYbj76l{u;zJ}@2%iD$^ylPcFfTXp8oDB0i4Xt*g~v1 z`#jYWmV?uDIX%%T|24?&WMSXD%PqY?Lt$_IX!?rvEa$V}7xg5G zWi{%8NN&grYaZH4u$b57efb=)n)@QYKJPw!U2~s5N99(JSo+Z0_-aB~sGm;AXrt3d zta&OV9@W>}m#K9fs8-i`Ga!YHH4lS)8Qj>Boz>t2{#EY~{kTT#pL*;g*)~m9K5|Mp zg%7!mILT$l?Hi%m5T-L^72bWGl;A;de_P8_muFW{J%VJe%UCy#v@7XImDwsQM8r{j z8+od&klndEmStfR12eh=2r@4#9KSSoHmzSt2e)ww8)selpx9ek47VGwudaZ)S_1#+Oc8K>w` zAE=F1-<^nCabK@tF8u(_aW%DDFD}7KQU!3AdsEv_`OZQ*G2clid?A|e+rr)&ej*2_ zO{MIz5anEg+*&Wv?-TOjOpcK618=L4c3!fD)ewWQAMj>~4TuTd5OIlt%j@ki21H`i zUCId)tX>G)HRAT@r6>hXVO;v%64~62887FHF<~|3XD?A(gZo525x4GG^JAa~wT-44 zv3g96r+R(OyL=|-@tIbP<+HxkzV$1PuAq025BjP{Tfh}Qj8|^F#Q06TVUUeS{T!W3 z6Zt(kNQkXA)>NSPv;<{Ht-{KiVj3>?9&}v94IqhbaPVH_sSBc`H)N5-;1stB`yx8X zLBtB3!-iW%_H3KdEhPRd4;YqWO;31Quv>7uf;BJ0nP$~J2e&cv>i=HvN6oh=^lGtK zPa*O!V!hgzt+q*7uFS~0lo!Qb>fD)LsoaZjBvrSq zX*s&tqsLfWgV7}I&@g*~BKiyp$;lyEhV|In+zv%FkQ90w!N_CVdojG`fwSz`gNU`( z+9bQs=)yTaaq}RgIPaq1pmB__ooq94bDgB`wzVW*5_gbXR85#xyO0`ALZ$mCHy zq%(x4Rg3ijz--T%=c3RdXE(Oz?CVJB()>a|PDt91!74z4?_GS{6;Qa`Dfn4JNsveF zveUVh4}s6cmQSyUkakJoZ8%MKrRAkI8qHC7tgz7?U|@KuO0s-K^y9cg zV{>60@WqR9^p<6^Zw2NwsDZdaB45OKPgF=k2%R>&bWy}v&>}?-+2HPE!M=X6G{#q6 z*e%!C z<6wsr%J%r?Yy7`LnRkqT2KM0{!cV}yy5)eWrgT5c@q940M%Tw28e4B0_qfLpdZ#`S zaCA@(_&((P*cgJi41l zFycNKQ?ooLCbYg@4=Die)bB@#{dNNnu^b`rUfE@ubAE-j@KwOC2{?~~{yG%3xj5m= z-(o4WZDPG4x8W}r(joH=JwqMVZn>?6w&_B5tXos9 zX>0lI1wkgM?qoiCAr4UDiWghk?4<**v|MNv<@ku-FTg3pFI3ZMce1Uek(HhW+(c9K(Y!X{?qm#nTlR4FJYa^IUN%){E_Nt3d9 zKf^gmTANM8ylo%)WvqdJ&riesAd3p8BHLQJ0aLp9c>;H*JtgF3$IHf$Eeh!ds=Kz` z9jmGlSCdjSkYyy*94RYJyDe4jb0L(CR_v%=3Ld=AXE)^^T26CxzP9L3Qd0AA%cd8} z1{eGz74czdGfpl%vhj9@vG46mnWpJT*~Z)B?RM8QkS25pGX10-cc+R?quu*b@{}g` zpO0fJz^-ZX@V7;dCKCO~l>F_~1BYmi061 z6B}_V7w@bru>RHBZ`1Sad27G)e%`;PvLL-kG}n66YTUFD>qL*Sbyj1#(Yr47@4WR; z*Ff};X6KqFWDBRLmQ!18wtMnRtiBEE7@F2e_CXHoUvLwgaFK%~EpnrE-88JdXN=AN z#A?J{sII`}3E<+`#QMhLP26X!$E=MTXQplT7(RX+U(LsjY$8rotOHim8mVcUdD?Wk zJ(})BYtaVdhFXt!N|0T6ZwRJiZQR88SB*z&Dvv= z*eCTkq<w>#7>bke!DkuP^V1W(jj8d$d1;hpBGP<+4aw%!g&$?VvW`k;50CP; zrQ$9lQfH5{exHTN{z+(id-$no@2vUbIhEEbeav!2eh=Q0$61~8Uf4)$6_V{}e!VCA zzT6;V)8dOr}P!1YA^_ zyfyimjq5#Qj~*_UXdd=kQ@q7w-YAOMZI|!};PV5!vifzN3DeXhJe~()rtk2B#f6nz3!H z-`{Z}>4D^I(D9bmycxqckz^Iz$$_gcnawLsUBADPtu8N3y@3ASmn^JheXa0Yi`Koh z<)&7Rl0ENfUP|s%bFj5#aO-Z5fyb@gcyLW|YV8^}Z{7Z{FmG;aiQ`zQd}u1J_ZWjl zd`h`N#%uX=A+NLqD{a+tCgAaHPa1Kv@oej%XXYgw*$Jx@>CPxE(UyQF2y! z9?JjHV;q-O%>SvZ|B5lLnjT3ZHcWG+;e0f>Uv;B53uunP<#2PqH?9aY(}s%He+~Gg zTdM+joWFOK?6g8eei?hH_6m^4qqZgWgfhuEdo z=kfkd0%m{I3LUYFV>gtlxR`u24xn}Fx7sKzZ6vLaY#I)o#`{l3^73=QrLe5|ol6wf z+>V!y<7JHCW#IZpHhl;D2u^JT&M$%E!&lncGISs;`hYf^1nP*VB}a4o`gkt6E}j!R z;7Rq0ZKgdit>VCqB5FZPtw~l~%)qK-5O2k;D6o~hPjl3=2CreDDTC$>`!9s$tdfsp zw#`;T^MY*tJ`&OO7;skU)UD0!CE95Csjs${cOdOCpmb$;p9~6PNIsq!!dFZJ$_Eje zwY6NlqI;XDa1Ta0>R!Ik7^mRuFMpX#yOPPj&Tnfu*GlrjT&YIzd`fYF73&h`e^Ox` zhjBgnO6=PvXD*|Y1jb7VG85!-XTA_h!09yM5xYXUaAJPKn#W%VSJ18iNqZ?$3|L(b zpmi{yB|%N~y0D8Ro+5L7h1j%rG|d$#kCVGZ-!R0Osv@2 zWVDm#{cDsZ@~!T{ETeuj%ID3P_5D54=F=@PlDjpYOK^S8DcfmXu*>D@8cTLEB;60h z9QKAF-3VBN6MC$lCwL_JbI1Z}#r!4YkONBQ8IjGt}C%99w%3QsYh%zrEwFI!Zg05urfmJRL{LB zeRJQo*Omw?O-5aDTn;v$J#lry>QHS%?ZnzUQ?;9=;3V&}7z3}y$w#SCLaSbkJC@q;C_bkoiqm^7 ztofG9c~;!-%Mu^fKcv|zhF`X_>^VUbZhg%-rh}|O!^2|O)IUq<7JMVw)U?)niD@(HVC;Q`66pc|>_7_3J*3ZukR&L^d|6k!fIHv z3t{>MHIL|aX`5Jfm*7uvPE%@fLDqEaDgE{mCgD`RX0^C&MT)yt$dNG4WZAET(!%;C zcd8&WyS`Dx%{q2czkO7)3HL9tw{cv*BgM5Rq;J@LE*mMtBL#y0n~BmnYP9LuBO;US8(#5Q(TW=*lHxxXM{!zBmdO2&Z zyyUHk&o-cr#i5Q_Q8x8xam}GFVGGWeCh(Wa0?CzLBkI8r_|V!H_1VOGHZO6d%7x?> zZ3kHM+vmUA2dI71zv~0;L+eK{rVhfJCg zp(Nnh3wT22K|7w$<4q|+XN=dOjl@Z?>>Ba0CvINi1;}B^dCGe@ z9n6}KT=b?oC!5h%o}cLrYl?sXCCIf?R@wFn1(5Iag_?!Aadm zFH-84TYd$7BqWnE+^m=HVg5Pww()wr(U`5Yv^;+q_aspZ`ore|PuF7=knU0eLEM$z zSe)N#YxzZ+ko{-uk)7jXI~QPlj?(;`PL+k(whG95Nk9riFRAf9LHmVuHApif>~ulC z?`^e3Uh}Q;@iCUQu$oFr#g*Cf4I4bmj!VW3p6SOW(*{q$aVchlC;PZ$-r$Kn-exz7 ziLa4aJf4_n6sv;dn|z#wji$pe3CG`+0x6~LI&R*;&H3CsmYXTGa6E>a4+A>Fi#$9x zZ{X&9ZXV0cgaN{H^ZUmR11rQ3cnogdz|HyGJeHdYbHw20!^jK5GajCsH*hoMQ8+%9 zo82kwn4pxpEm&u4J15``8rG~kFM=MdcT4c@bGUDfe!RgYrTSev75RqEuH^hu&rIbw zbgX~%!3(~$Cxmu|R{9xcK895NOJb4u7^HsqCBQj|x+=Yd-RJ`}0&$)fcI;BbedgB* zZu5cPD5I6GnttZ~=#TW8B=acqHbpY8%D+8-PX5gN`;rHnKTF=J;70N(U&d`>lX9eB zEF_&y%+E9r)l?M>H9IsV1=D}~A#C44}`>h{I5M!0YAI8XLN zEiXY037qfEbjT=c{>Ax0DNTxe;|^ueiK)sYWwXnpq%+df*v~vSoP?y|(2v5mDNpox z!_E4z-`8MOmStf5VzZDj6`@G?Kxdn?!>c{NJr(se@1PecQY&t+U`@g{Y2OHr+aBdv z;O9}~j2$VZ%I{rnr3)LQtao*1NHss2>XCLR`FPjjRPd61r&6gbF_`jyWKfj2@U!TL z_jt@FpGbMcEy#}K1#YxEBOTV8-K@VZ_^juvQ?QY1|MMYA{WiQ!Hy7Avp6 zdza8y$6a@%L#Wh>Gkqyd!2lHo= zg)U*7sXs3}#jqh2XKc}G1r)q2t88ySjJr=yXOuVC! zL{Y$xMSg&Z9Vrus12d$E(Fzv5Z)bU<3r3+PhQ*`i&)fY4?r*}mPMn#B*?B<9F`trH zO#TjiYDn^$y^njWAi73u6ruVvUH6_&yIg%Q1Ptym``o6HhGN4CLxRzd}rFBGU3Kc$JChdIp&jU>~FsZ z`>*G|o4@|w%U>VXllAgihNM@_K`wvdeH1yh4E{sK59cr8I{BmA*G0855Q8puPIxY|BJ~|`s?Bb4brrkj=V-d-$M+p_su#12 z8f6?QyaWO3Dabc%S!TO1Y?P4YI-NX>**)EZBhz0tyu_YR zQdnxwSq1W;J)YK(!x^HRu~ zf|qF7Cs^CK2->w>xpKvapS!wx$)dZf*x0HSaz^G|qu98)3-6Sx7S3F2Pg)DQaoSivqK<2F8tayBJnLMe?U0TM$%VP_tOfM}|N((0y zP0ycjbIG{EvO*J6ic2Sz$@xW-$B$*>7tN}YGw08r#qt-;pI4f~kg2|QW=Moc{w0$ z!UZK(Jiee9At-ea!^HZrlDlTipF2|qFEID=%DKztE}X;Mc<%e=2?coH1eu5y_>2|H zs+P)?%j89~XD_W<#=%V@@)vQ6V8^9+G*K|hF~#FYM+>~PaCGscvcgh8Qzn$k<0q5> zw2HmBl)_2lCm=kqyS219 zN;&W%M@=R3Xz(mbvur~CgmKfsx|5Jq)rY8Q0#_}pV(x4Bw8ULp3UoWLL0R$5g%c)& zKohE~mQ*fVw1h=T&9e-)ysLlvhuu=OWGUE$p?*xSUbMVw2`5e@KfDAZbYyl!brUYzH?`gFLPjLUl5oc>r2iS~{VW zIdcaN8a!m^u)N`wGiJ`Jn#~GpsJ_W6|F9DGq)DjLa%tg2@ISFyZvWi=16lw6{n^cx zII3Dzg<6AJv=9|oEj_A<6mWdy!bNg9TRwN0m)KBkl8DSzOVnCBKEHHI3Flej>(Pb0 z9;4V%F=sAXxDd6Q>Zli>=U2&qH=zt@{40)YFF9U@OrA73KfiEN2Ug4P|O#}`aTJ61Ls!R2-~;fNL#PwG&++Z&mgydmS|!#VkTwS>1Byt3cw zE-s^bgYpDnZl1evS){}~6N<-C>wyNtEsrZ4Kf0_4%_JuVub&+o4%Mt;d<$Ts#zosX zYKTgZ0AN=wScC#uID77r1#Hr?$~&peX1uY!rj=^X$8{6psE;p1?Y?;e8UVu4r1IU> z7K#tq_ANN9W4?aHk?~vN(FqsEIR;&__rO!>SVYfz;Vsjp3!8>~_%%YyDKpj)BUa5`b&hA}(f2=p;naMN;I4xePOF(GM2O%=&OmTi zr4r6hVM!k8T3^Y6vhf@Ab##!)|ne$kl5$5ho+4jI{S0@_$rAU1g(1K z+1JnA^tUPRFT9(h%61O_$LH_wx@jo|W9+<1c3qd3NywH=cwIzr(Xf z;5VCy;CtcywGS7S;jDa3AH|D-o!zv6jt@-c^^NeA`Tz5EQTl)+F0UJH9%@$>@9Hv+x2*h(l_H_rLR$MeaA)aG1CR|!66B?!cG8d&t= z3iB_&KB?!iPtC`zXjTEzg0ccpHdlhj=l`gge>Zs`pFEcD?w3!^-m&0i6))GE7uASJ zV&*UYuppHZV*!p#-9c^y4kN8Z+rMtg7BkS}oHVO-vut1$r7Y#rI;yxS?<_z|*(IP!r%j8R`zW z&4GPB^d(GdSk4S6Go5h*;%4CdZ~K4u7%3+AzKzZI$i=DARJ2^w83!ao4>gK*y=#3Vc+7~>8=9Y&lG^pD{8 zXZU>!)dsUc)ESe+n1r69!Q5Ze$J_u_C~6HQP~}h+uzL|^DfE?44?s1-{s{D^pk9Fa zb?9$G1x1bSG~#>$^Pgb;Ml{7=gxM(RW0IiKp>iaxVThzN-UMBNeLU0@$rL{e`ckM> z@LLDJM(Eq2KMws_sF$P@Ck!Y!!E9tQyN})T(=&nBpE(oY1xp{lqgZsHL>?Q0CS0)q;r+LGWX^2_ek8l!!++Bz{NSL|kjr~yP5Ku03i7`T&# zeqqkY@PMO6V~&>*O#Cz&ooOI2&sZd{wybGRmzh9B=D+g*=<>x^AavrPXy~w0Mlxyn zguxoM+d*X#M5J%9@Cec9gloMa&W@0YN1`EX43q)q9e^nuj^fH@qyF+54ufo00cdn} zg1MqSKM|;bblhl;rl9JU0MnsU&~$K(H)uq+MI-uL5y$gBw?#g(x!z$bE=p`X;`qwI zG)!aw#(!wB%|&vp#@1?Z_+3JT9U#He;MOD@(%Uo%1s0sFj)r~!yJxj1nH=>NTY-h3;KvhHKdq_@6FdQ@(`;Vr zd8{PcVJ!A+v}9=7S%8u@ACi+iHiySi;K|nHJKK}SaKYe~fvWniS#4>KfJ9$tu@@lS zk(?>pUB4gRzyum$L?~TgNG|~8+?ps!&l?hD7t=ezE#hYpdiqASXH*3oB@XCA{~gf~ zbxDpQOM<%sQX3Kod5t--E?Z4D?P8*B!f#>Vp!jyPNHL0oya%e|&vc1P2@ zR&NEO#9cr58{u-fR(d=$rg2}+h4(;=A6hww-$u}*zZ#85KTVD5AZRSEnuIJK&{A0w zr3E~Fb-?9{#vn&)bDrChj>?1oD6Cey$73I%5m$O@^G7n`nw(7T=ECgSglrv#}f@4jqI`*c!L_2+(5-0R$Etvs4fxhD?mry znzuLWWI*l_e6{QZ{vH|%@}CcDW#9P);-l<_QixXb6B;8%FM1=>#aWoCdm1x#9l~PM z#;}-VFWhUH##j&40Qc=sKZDy5rZv9{x8Fez!|h8bK`?gh2GvK1Nk*^Hbqdr%s5+=7 zsOJTZ@etIzFrR?>6Vw$!Z|Ne&$r+-ldp^`usKsJTa=mEm`j}`)d|5R2cpK`hs4-p< z^%lKk?Al#2B=(i!+(fM*aXQS4wHo97TCMp( z*muDEyf#jL8SWoK{RQEf&eXlTP8Zi-r?-sIY0cww#;)ZsFVLBL+^aJrHo^Q1)N2Uy z4*X6+|10!Mh-U%i8T!#!Mq`(}SIz`1`yyi(zr!d-x<6()I^nTahe*X4?ro~$ldg?> zOCEc_TTa;#UdXA5iRLk-_B&w7#+YY|qmlUw8XFmNw{DEqtG6HIK^ZG0op-G0?0f|d zJD4+rhO^W`JWi~H>gxl?c?=lf!eG|8Y5XBOvmK6AvJ9iImmy7c>}A-+Bl`4igNHW` z8O0k_P=KlD5vfyU8lJB0{#qB}B_-BSP+3w`K(0QXcY+V}^|Hp23e8gA3r>Uw=D3Z$u-?vm>w2xRs99?K%y5VGo=7~(jD-`9D7VZf7p;G+ z2%~CFO!)bh+t)c7i-?`@<4N)SGasc&iA7w~I1l)E!Wf%SW+=H{=GDYze@Dikxg3Z@ zWdQ+PjgDM(o?5?m%+?%x0e59ZiH9lqh`-y+d=DBDFn9|TI6MVr27>W_r`_YQQ&Xx_ zdH&I&DCG9Jn?^@-Hw)%fJuq)`V7@hwiPA{Sx7<()+{Z$d!F)UBZZn{Jp)Y{jQmBhI<3%Y>&Y0S?DiAKLWqsLO%(=v(W#Ba2Mfb#5^n! zst4v>4yYU`C+tHp9~%XIG*k)ZVpCwB1${p3%VG9GuZO)sl(ah$=P}rS0`or1-44M0 z2-I((eh>9W_%|cYx6sj2$7nDwiYVt3w=Wjkt=yz8a@ndz@(qzw8I%Xsv?JfKiVT zy3AbIz^$-Y5@xw5qVugYfr3aJKlJCW8{fqYU5b2WO9>wWMdJh!{<98oh(@He*|;Ia z$|(uV-Lhc5qC#jP6V=Q@Oqrqf4F-jWW-L9%gxLNOyr*g;{KPg1}aSCO75b z#T~)L+_|J1SRvrN9oe$)3w(&?Nryl)@V5o#s2ky20RKP-oN2;HlYbTGS5Xd>c0Cm> zvm$?i2rbVej``r#yo&HAMSN*M-qbwiQMvj2uy+NnL2!NYK*4nqdFnY(@O=T@2LJQW zk!PPlu&~}vK~4eg{qodsxp`{1A$h9%aI0WRMILVgKV&2CZiI6p?}fRf8(1;?7f13= z`Htq5@=x{SBRkM%PUPwJ4*4QlP+!ootuO$V1q#mm7v=pQ?>!UH z;60hzEl9V6e`eRKVJSiZ{BT^SEpYfupy-J+ffu%)2~2}qStL%sYr-#!gts94&?nXK z8{xJl5`M@v;h%_vpZwIBKo#&g^$_v|x0fQ}2Sc9)wFQdsI1$I6*xqDa!Mgi1!T?jA}gSW{Pm-U|Ta*-rr+`0=#>@CY}TN z=nEB%SCr`CGh&)@6WnR=o7KVJw#LD0e$;;@{MK~vCphSxQ8VU*^HO(8t602`Gwe0# z?nIm?pq5n4nN>B8+Te%#vcVsAQSHJtcJUg!)NZdJPS3?6!L|EySM6?3enFvv^cSMM zKGfdx`#(WF55906xylR6esU&ItW(QpS_k)5gk2bMU)I4r9&Vc>?i)L}+u`EBqk$%KQ`JA7}|gIX|DoTYX9Gc z-W7dP5VboQeOHLhqV`?R!}X)#TrUyPhrwPWY~{M2ZR2_#dyMN|_GCmSTwbO28Y&5G zPZ<4>743C1lm&S027X?slaah-!);3kd~qZn$0)H$hQoJr*xa=^xr5(4-{gVH^jik{ znPBv@g=_(QC>jX9DLt#NYOlGl8GNo!WTI+h+n4n|}RPT{V+E8-7$5icojT z5uWOf3vPMQIMA(7MNkyZXiE@qS;$UpESVXZb-}NV!efF_>dLa(*j*S#JLyHaJQF#DMwiRg_*`xBK~$WIyZJ} z@%YJ;JUj^htU(*E{||Bg5wI&{dBAHpQY9=1ClAc3iTrZm=7vtL{ebH*#3(?FTzrS{ zxP>sQ7@s(?VcnU)8&LnOzsgg8Tz@8T8R{yokPE%(OdzWM2y+$uuZ_12ZU_ENyvZo% zTBx;9QTXd%eyoF?+@oocPU$5Id^YcTxGyAfiGnBz8p)`Mlg6QhXR$fFoa3bNDCvc$ zZ!#-qCP^*9T$W7$(W~=*8b(pLwk#+B#*<S#1Ao41HM{8 zWT~7(RHu%9Uet4~c+YkH>*24r=x|08B8MUnqw%A&OMQY4$Dgn7|G$A>(!WTb@N@it zzsaX&NS~+!&wn5PsQ>>w{@5f!`SCF)Q2IW7^`QTf@A*gZ(%Hxlk=r%vj`;N(bQkx` zT{RFP2lpS+p0ky>93rxrCsoN0s&n+7%73SxorHU?06#dQQ%e7x@c$h=S0vqW5xx9B z#ADWf82;bk)9L@8m4EfWq5sN%hC0>9HU&Pm;Se1GyC500{2G`v0yfPZ_(%-Gejp@h z96s~rBdk+*D~wr)CQQ)pKoGsgkerK)P1ESRVL9P&GGaY~aSh#Ac6+QwKnvi5*gV}9a2#(I!76;^}!br)mf z$(jbM+3Z3l8jwki46DVwwIp+X=vgE z-3XYyxNfcOrW+08azGR6^-Ju?s9>A~m)N=Z2yxZ;#yvovUHCBlM=yd#g7Gd`Ottt_ z{Rr?9g!n(8I0fTIa&E$BFm7>c5{38?C^^CSI9#-Q$?qk6ipj5wz@_MAYqA8h<22-5 z1GuIaaA#&W{QZ>CY*;nsToeV*Sq`iQbNA;X);_SB%y%OX+_x{RW^+T7D*a%MGfzeG z+;;%17W2?337xPenzN&za$!v}4}OcW*C^eAuy!+RP4H zDfn*_=+Mrlq6cCAgeZb!zLs%uUp59;vQ>VJ_=qi0`_hv7#>H zKo&Jt)a6r@awTetASGU#E~L8E0#7yFh_5&dWu!ugy4;DI>MDe;k#v3bXsoEqAAyM) zE9#Po9I4n^Be7m;uX9nCJKC|0x@?GzQmIEI))ItKF^sz021=@FMO|F&X{AMCjYTeQ zMN1+`5f`bweuLUp@Pi5=;>%8;WJLBfXdZ2KzCL94S6n0K~1 zovqIQRI9VBD$3W9&N0H*rQqWzU%!rCqY>QB`Fh;8>+-esKj7+Psd z*J-ai`MPtI_+K6+PR0D@hxqylw9nD@y2Zsmq!88IzRjwATs$L3`cr_;vYO-#HG!Y^ZZqulcXc>OaKT`Md2k zp6JB9@!Jl3y$SQxpFx@G%{p=iHck(s+FY)yw-&?JE z0weD0tX4@(9EV|u%8${tsXO7K){LmjPONqGLA?;9$V$}Jg<8BI@?eM zt-Tk+vg_2^|75l26wh&j6yR}>qDo8BX&!eh26tNN5E>Dk^g9pU(C=NSs-F-5Hobf0P@cL8pRB~5pRsKL!aRvi@HOe=SLH*KNW_ zPn#!ov_Y`Jpb^#@UjfEE<@*Waw3i~b2gD4)IOzFE%In1pG%@cH3Gg#U!wKL$y~X@Y<f`>j;g@q5{sfI|m? zf46@Pt9Tjj&0DfzdZUQj1{gu~MX*l*AHa7w+0VlM&{Nz_q_U7K!MA}B{0X@P+Dy8O zQZ$OA5I$kC$k;)Yxu_Qjg@n~;m{+2FMVVBa1A z*qLho2khHGMzKwx_=&W)BlcF~-iCqJufa#+DsJy$1+EF(b&QQBfc?Y}>`7Ju64{{= z4#4A9%GnKS>?^R3qkuQ6u@RUhqyXe-6o=?m1G!+o8w@3SxSarw(c<|5P%&W|B5P;E z@0jY>#YGU_M2!21ApcY$WFl062=;9RBJ86Hjg|<+u2dw|yjZ#tVeS(MZy|O+0urB# z_YonxorLuxR148ZR@RkbRLv0(DtDK+y2(O4tuHQVyzm!~Ga9U?KJ-0`hzx<2hj1 zUgY#UM(|>@Vddmgt<|t@p$r}S9r+qj1CA4sRO{=gBRuzN;6}9s^f%J zmvZDbVKSb4$O-^}L#;UX!oKz`*fUl8Td;F7W~ufYEvVvd`1ca1m21V5n_@p;Lt=kOBlgMSj? zzfQHk1N;5N4;xi`Kfvcjw?VZpgnb#|w~5;m2U6X5kmJtcDRUq349+JKE{8y3%L|CW zTe9U6Z^=%f=wiU2V?xs($0} zEKQIwdrY<82m7J*?e;F{kyye%0DyDab5e-xSqO9zeWv(=8tEYHr-s9RQngFn8T*{7 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

4j zdX%ZjT+M{F7$!9tMQP15Otu1=)MTD8nGTSPmG+gw} z+(sr=f+&Xy+9_1qM-AEsKH8&#=5+(ES>=5UbaIZ-tWBo;cBHo z44E@rtrUnMbB3#x0!hehHp{)2!7jd8o_X3AHY4W@S1U!7jGQxEt)zC!YGsD2l>#wx z&TzF-Ac>s40YKwgfU{=aY?g0?6pxFMdbN_9H@5peqQuc?r-jU&IrR)fE zy(7cb%6|}(>m3=cR%X~4T<^$mwX#Bp>m3=cR<;u2dPjzLp8gyb^U%OXX27S<0i?EdQHr z`VgDtTcSGN_V|f!mS?zRxe8)^S+dM<$#M%q3n&aOS&ksYiFk%fma=HbiFk%fmVA3t zmMk+|vgB1tvSgXzlI46toQP-Y(ekGWaU!1KlI1IeI1$fq$#NMXPQ)`@vgDiZvSgXz zl4X|4&WU)2OP2M7I1$fq$+9ycJrQ36L}s(RFCObedCG(FSmvXZd=4t>5lb&wdb{CK zFIgt{svX!Vk% zJnAJ&?>o?%ef58kjaC@Z70J^}mhz~VEag!zSytp#ecQTkqtIL42|F=n!_ZqUptrmX z2K*Z_;!na9IeDd=1rYKXsG(E9TGxDhbZgJq%3AG7=Jtm!B~Ac%$-Dr31>n9gt4@9$ zCMsv%CVF}; z^lxH%;WuM}QFwF*%W5rr0P4<#eV##RP?&|^)e3_!1L{&Z8k4gAg$qG3pfDHdYZi`~ zXjy9&cD~TE)-K#R8m6@{yNK(V3VS{T+fq2GD~xa9S)^}Ln7kP-c_`!|l4*s8>6SIU zaC9%rI-oH6DEN=UQ*$w73b%vvY*mIQIc`4+H94ifN!ProKeRLMj znygvN&#fQ`vfQ;`wQA2tV{(M>;(Vg^6;!Vip>;4&t-8m6$#1zNl*%+9nU{fheX`of zC$B)RbjBwBhh&OO%4`D6{m_1UP-ZwD*Frz5N!bNkqyJLYJ*dBJUB7XtQx8L@CTtw) z)UyyELahy*lVL)SavEL*Pv;YicD%FhLd2H06@HTFM!D%jbxPHvMMc#oZKIRUMzZRM zmZkZDPmFv^@urV7Z~DNL%TjDvnm2t2G!Q1p()WTvN_aE)O5kKv_6Gc8<;>A9iZk!R z6k8s~f>ofh?{yjjz7hgVyN4pSs#))7d@*q_64nsvB2kVLw0&V=?2dv~5{yoQQDE-t zf^j%81{p@9d`25-G@_JGXL)b#4Yci*oV3!McF-uy-b+xX|*|ETWuL21=vC*@I(zHjN^^hC2YyeoAuL!wr7}ygzIUu-Su+y+FSQ{%`7ktg^-} zLdNQn0k0sU!4KY)2C0oHifR}RtoI%kh;?Y130SI>lH#I7UqO-Wbx3p?kfdqrXryLV z`bw$zpF0By*PW4>YPb`KLuX406B=ynRXl+Rz^H=NOrqC?@Nr6ZIL3t#t^q_TVYn%Q zNS_JfdzjJKyBox&5kQpsjxmTtDxXam-pPW-nW{8?hx8QEnVCj$+G#Yim#-KFHRH6pmwmMC4I;fUZ;H(?kF&utL2q&}Kr=(fdu zla@COM7+{N4a&%s9;$CvuJp)0Isu7UxzZymS9)aSN{_5u>5-KyJ+kYe&B^Qu(9PNS zIGAyA{{W$D=X98AELNU-S?&nzO9(LUT#n8wIJX^(#yXFn%Zrvvnamcsyv{+<39rzj zMDIB?{K|WoKsfmwz@G3m_9_Ie6e(^HsxxR{x+&#VjyL17+b{^pO7{g~W-a_=H^vY3 z-RYGReRl@rsqcFunRiiHdFuN}5ILgnSsXz$`d)y(=c(`X?xOE`>igP+sPB2|`yfKp z_dNAoAnJRb`o0^cY&zydFs1B)b~8~oedIw&r{z8qQ2*; z@4}P%o~OPGo#=bE8-$?sy+-S6jn>y1t*Uy@}S_)-{`kD%J#T z%x$Grj6(kb|J(B*_rT7~T@&dY^#lk?%}Bj z==^tzhoOhxH9ZWqkw3ft1AY&8GKUuePm)~O!~Z!?;&+f5Gj$PqcqDpwSHFixM%~2P z=r6yAKkSSbYjEnP^RAlwyjG0z|3hwqHmAq$7&{HQ0X6Sv+{7VhxVVXq;wCNyC~iW$ z25wIT#VDa#6~4>v3O8}L5tZF_rJF!l^o!jD{Ut6A*dkQ1b1*TuV_2wSH&ex?!3b$L z(OPXpQY($ff6R#FABLBApTLjD<6pd7&E764m#f*^q?;-KI7|uWI4fh1|KJ>lUBN#!<`gWdIIE+ZxAePt z^=RyI$B@u$42604)9|Vu?)B<&dw6B+@n6xyPhNr^#&u`K34RZ+p?mmybiHjIfpP1{ z9)E|WxN4iQhu>}mMjsf0b)hTH>aH{VPnbR+9JLbMzeNXQc4m1y;HRBsibIhcE>m0u z0<%m3PgA{2u@Q2^Wr~vs1kmIl9MXcGBBJk!QtJ{K@X3`itMqzE+5O@s=F2-*9M$pNmBPJ zz^CUCyx9Y2orufmwWTffP<*yGD4tbPfm47rbT(lDZv)6RN)1}|B=|xTF?FWmjqP=>0gExQGm~JY zX^tuBU@0l$i^oH7&gH1vT0oJyT`qN-;Zs~OPU?pG$)6f?0x1^jx}6FvsoP?y+Z_O< zZUROZXa9O0hz{3vdjnWfx5K4w9iaFkg(Ib;+Aqwp=^9B*E2J)FNymmYtsr{8wjf5YOv?md)It8RP-QgEd zkajh{23YD;qeNhhruFb@J+YL9)2tx++9#^hL@g&9qOy{fG_sVJrKAR|oH`vyv@VdO zDIJ8UX-~ks{294Y1KYXNK8mWF6xC}mzUDEw7Ag!zWvHK~eAJ-L?8xN2p))^?haw$ORr1c1P zc%l_*_!`m{ur7N_TdjIBJzE$TIdblk^6I_@nrPL1L~9X^lE=Dj=bEm*k6mqbB<(_> zzjrC(^{>qQ# zy^d4`eX;xIc~ZR-o2*vhua*A-zuu4d;eF2b(Mh?_*QW*<9p-Mz;YEq! zhLz>LfM;IlY#*6_6^{|gSl;JIIARxwwOjscJhp0y!Kd56w@O37#eA6kd|=(Ny$Y5d zF6#`8f8Ppo;vDpodm(#TySikGO3~#4>h$8PP?vku4QRhgr%qK?x5t>k4fOO@03U(- zu*_eF~{Ujv*74`e@01F+}Y0G}o2 z%-sNAgXggSEZ`D=ufqk|&k@Yd=?s(3-E zfn~7(rw9cu9gV#&fp}wmiAIYI9Nt)88V`q6AykL8>=JLR7f5cbH+QYnc1C_3&8cIV zJ21*-U!)sq`vjV!ZnvI7KK>gPs?Kvup~9m=)mhLP7+bCC&kdSgr`OZbmFJZ^T>pm9 z@p@=QJ3CxeOA7qPMdG65$gLTbouBG-f@OUJ!UWEISt)+w;%Y)T^M!csM{=~$^mLDan4Ua(bvSf2Nwy6+vrvfOEZH^`Xfh~M{Kkbq`*RbK-?-Qv4AfMb#&_UV_8~M4 zrqRle#Ut*B!ibs7C%8GQW^)XXn`MxEhk=bxVLeIw;>8#x5~K_wTzVLw1Oyx14aMj=s@sL7ZVkYB#Qdv7fvPplm@j5wu{S^q(5jk&d`K zwjdT8dD-1pZbAH-EeIViTs=HgvERYK9f#?L~G*zz_uZ$P|YYglV zIPb&<$w$$Hsl>a1flXkJ6p0t!|4$m&$mYj;^!x)%yzrf|0L}o37g})uN{s4S)kgI} zxOxZQTPbb;6fvsXx3QRKZ4;{V^T7YpuAw@&Ql0-#TFmb_y=gHPb1YgE6)H9v*4CYl z9}f#=?QJfeiDbRGn7#y$nVazAS_!PJTJC)OWc5tlKSque`NN3^#9t1!@e6c?KB$|Fc)T{qSil8xivZ_ z+^FE0tZ<`(w@ri_6#@kt75vawxKSZcuu&mgf{hA+f{hA+f{hAFBiyJEDA=eFp20?i z(CLi|PTaNkFo*uL`g~bdpD(kXW%I2O7{b1;Z8!x7>2?owjncH=-37<^@t~YDaXSZ- zoQ?34zygvHs(ZpiSYN`utvs|h70Du0j|+@^D^d$JF$)>`kZKY_^>}EHhyO&V9uMsu zMTomU9uMtdDPIfKn6Np0fcxX?!P^cac?FmGodOWlz5QXaT z(B9eP!rdQ_hxP=bP(2>n6P^^R$3uHUCqhkZ3?ePml(F+^Im4NjGn{ET!}4p%;o59Q4>bE2M6|jW&NID`gFNL= zjd`U5u&-1~>04B+Pa}Q$IfD9+B7M3GWMuyZ1QK!C8=EfW(P{beD8CS@I=SY(0gvwu zoP<1iZ@}Xy4`BP)&A{$PNj8*AaSOG3f+bx7^ z<*2wkVk5}>sWE%7^=m3sdJWig@b;R-F7r(qd+o&v&k^juLG|rnz*c7&>|w+%bqDwc zSNOJm4HTvA0A9+f3{Tqt4*~cc!Vh~JB1ichvk0k}vz0FO`Hc~NkNf=g5PpC4`Rz%5 zR^|?Lyql=JkFs{fA~D{5Nq&OodM?)(u_n1f<8Xz>D2&Lz0zGj4$GR|qVy!PmgadsU zDu2Wt;Xpr+&HuG=i+Ll2ZRVdE^VJRD+EML8z-zz&yonumOx$-+8<@;9ifeLTFJ=5f5vXBktZ zoIByI?90L8BcH|Pg5olJzMwoxl!q{^D4gQ&Ou+S!2xmCJjqXGK!vw87DMnq)1|(XL z`ZgHP017uW?YGCmCMVAWxGAPl_EMIU63H&(WAa7h%sCc0O9cD@poDhskaf*$bV0KB zIi|QTq&Ta{L&~M~@l(46e)P%gIx+IjfHIBzen^&+*<~8}5vYManO%DjGPIGez{r}<<#LOQ<V1IP5rDYYrg&z8TyLYfjF2IeybvTDAtjRIUNzTELzFGr5D&1_65k z%;nDTrP3QSu7&GqnE^#@qa(bC+_at8pc&n3`#QjN6$Hp+GO z0tkC}nbme+wQv zWd?P`YES^v!?P>)`CnlRgIzA33gpm`6*w) zuWKqlr4_Z+RJE?N2wQIU5L8Q3A!RXBMuM}ZLdwfbxpc5kRdJoqn9_8qPlc3kn36>g zYAU4sz!V1^q04G?o$@nCDO~MSA*F>W9iaxA3Ms8j*(j)C2Yiy9DWj31YlxJ=Oj#GD zYbvB{&XgLM_ujA%%E8{t?nrS4QP(*59mHEfZIL^X_{Skfb3n=zq#!U|&v<@sgTSM#Cg<9id286wO{Nogeg@MxrL>pzZcuesz zo81VH=^DYz1egd>vUQ5tAOn!gOIZX4qNIEUC3VkXG`d1qQ-|z9fQvO~&dQ3el;}zw zT{)P4BQJz>*~rN(>;2I1CF9&kOQDoAP(^wKhH0K-gjW37{z^QpOuQZKbP(=9n=Gr%7mSg4Qe5slG8nz z_nYBVzH=N<$%9P2?NCR ztAH@(re6hYh{~4(BjPKXq9SdM59<#99TE<;`X`#5KsF-5wmKh`eO*-c(D>+hsFrH` zUD4L?gv#93>_qzoUkeLSTcRD&@qbG~po`zvOENKxI|2C=3Fx4ifas$ zLRTVW45A{@T2tGSa2c{2b6J>|`BTxB_Qd=%bTHC=p?p$-KrkZG(T>1ZxP8fS=8I_q z<=t*4w{3^0R$TN{tw@aI>OS-Q060DY59^u^>xvnmS-(VGtLK10JJ7NDXvY@(j;+xx zD7NQ0jJE!wh6IjH`qRNsG2oerfnuERD)8y-)q~KF;+FSm8zbkXmR@C zf`~I7E=U-IwTE$}W^FPMo-J2}S140D3*Exy&bLE3r{ikBLZ#IbkIuux?x^v* zs2J_IQaGcGOVTVP`Kv>LQu@=0FxqM}-;UZTL2qo^M_4tA_hYr4iWxst2CGQbNz{gp zaTC}n8ZoaDD>j%KwZ@Xs-Pp+vVoOnoRfE>;|R@YdCgi*Js)^ukKy@CoTFNlXPwF9^${2^rZEG1clrPK8#JOqzoAuEloKT*5 z?Gp=8n}t=A&`lKMHmjuNU+a6Fx^Uc2-^&&*P51|8Lgi<|8Zp-dOg<>#UjymOb)PR+VFV}?~(V%;>(NAGdHu>G$ z950f5I>eK>(nm8PdJ!(6!$@!*`_noiDo8Aoh8-U+l*)>x7dk6ALVr+&ZZK4-70sW6 z($ME{f8lOwO`vA7EQ?ul5cbMSc1f#3t#(8hd~7*fogZN_Hmztq5mzS>t57yX2V7%l z{hO#q&F!g9J5r|bu?!mR>W@Gpk5<>wWt`Q4l)#tM`l|0yWV}skI`hwIZdpLIPgxEi$pTp}CZQbp>Rz zt4#&Wd^c2Uf4eKHPDww+NQFZJ2M1t*IRLXUIiPfHh;xB##aQS4!H*HqmH=zm(M~V6 z*Pu4eimj}6S5bkMwY>1{1!`5j9yTiwOW?PoadIT43xyQjjM9Ch#Zlcb)-W5FLoU!U zEtWuW1uXbdqOR5Wx<;Vr1BjIUkrg&x^tG-Ly%9If!2p2}s+QHFi*CMwj!Lgd127)i zfWa)swX$7FR!czZLiOqabtgLeF#5e*b8gfQ)-((ygoh?duAH3L^rOFii!!4M%pa+am1@ktlsGC{6v(;7@V$7rFwc_{Xif1mEw`gM& zUkeDj7g2V!d$F++1>5bZ<;paw1ktseAf3`RTCc}cICnu-IN=sqx0R{iFOYrc4#mzD zeR-EC?^---q39L8Xkuq)!Tl)(B_uc-K9=E8g=o~;T#bfghVPsSu2VuYk)=vzDK zK3T5*_}OL`zaL_{NGxhy*D;;~QAOJVFIQtlWRdZ*ZUHob(-j}A3NJ#@5) zdBVP1)mOgNqKXnuI;Ga_cBAeHCv-fCYR9Mzj~lC5FbKRr>7)p(HAQ8BF^s?V*2064 zjv*Q?Tvx{pb+396HXfizgb=G)An4F3il9TMC}2LQsDK6fwfIp3BYcUU;kE@Wbc?zV z+APq*_{If7rx?+rdJ}>OxAqs0f{JNPi^eSe(E`co;5$#VyN9_-;5@}FcGAXe72mkE zhQ_V)KMho5f+9ds;)k7MAZZH_o(JPP1uYB>~=f5El+x-4#%MU+c+((S9@BPev>`yv? z91Uk=L!4FOM7a9gTFfBAcVV&?52avsqn@jc*`)<-yCe}hOPpMbM%9P{Lcdde!bb<4 z%h|M(Ww%f)pPorR~p&+>Mh;|BcS)0HbYNgfGgtJnW^(BcQn(xdd9kzMvS zdxYA5$h1w6G!&NNI#KZnZ@Eq;$`1DK^EWZ42oG^9?Lmr)U zcdZiDmDa%j$^t`Ytt+eQ<((CDU}OvD-yLB~^-Yu;?n=p|p%ezgwLw^hD4@{#*C zZ)a5kV*%e(A4X=_CGht&+HBr(1Yq-41S&ex?ykX46Ix`(8kXq#)%2?mK&;z)Gs6oNu z^3YIp^i34Ev9#F~^H#l-6DXYIwyXG|z(UW$W-j+YoYuLN-}_K%_P$;~HQg94po-0^ zjx57&#KqzyuJP3lo!}4dQrI=MQG3{CO+<^odR+uNcKOf_#Fto&=?xcHMLOXcoPbTf zo#)ntzcL~@{+WO2*cQJh!s8x-)Xqv9tpTX@QW@$fh%Y;73-m7@Z##3kxmUPx5L z0k!nmnuf<$hXZ?2y@3)9EZT$~l=eT<*k7)%?JHz;Y#Iy&t^ydV5~QK|`i!PADb;5* z<3fYRN(X`}A3B3yVqJWVggv2*D$CW#>NZkZPS97fH(q@X)HfAgd?+UMz)AT72k$np z=;bapg@$oCr$6IE8?UvK9U`w#0mDE*40K&o>_5pWVOcaGUP3c(vwev!4Yw}=gxi-= zU`9u=SVL#kqNkj=v(nD)I;G1uks<+qJ4r>SV%ypMj1?DnIG= zo&UW?gnpq|feYelEN0+Xl5KBThAVn90h6PpzQ+$=y_CGT(}r@=y*0$50y7tkFD048 z@I3&T(p9hU=`~6JoqH*;%~4YvH1#9ORdle^szaaZA!2Ns@2f+fseQ8lQby>i5HTah zsuqwQvRr72L`s=>;FQ%B$BBh7RLc9IOFOX_BCjAmgjbEu(c`hk3XVIq+uZ;1Sm$46 z{{DYu>sLByj1jCp4vZGZYe;kt!6*%oLamDY1lBs)p&a}F6?c2X! zxGSaIr@!hP`on+vdNlpz^5h)%m)HpoJ!6~o0(MM1=m?Yu%TM*byKh$rQK^P5K5WD< zn-)hMc{_Tf9=5pJ>g3a67($Z?X2kDc#YYe)k6y>pQ#zOfmC1*r8_rLi_4?h!NTN~k5sqb+O46eP#Gj8;?RNraS zXZGE9{P^BuXYAj5>a?j7dQTWTZc^|5{rargdqBSd{rmLq*LU2cseSwO=^Ml7J8A0p zDF^L6q3`}<$4{Izb%OP)867z5Kx_JpX)~u;2Tz!~_p}*(r;eREZTh%h&DgT`+qY}K z3@mF12yJUH<+f6e?Z|Pn8MCI(oVMAF31eqY=(9peZY7f3bfqMhqmiSgO`b4ylLHT& zHh$7SmE~q4%MDk`az(P-^q?72SFDmN#kgW4DJr=QZRQF`_E6DA3Uj56Y|qz>nlX0j zfn&$doHT9frqlMGwPIn?K-v~Bd0#2a>s}B6va$d9WsiVw9H#60BoJ0G#xsmvHRv$ONjhorZO>XNtYr5)EJAtYR z(R>T{!~ftYch!v3>u$H3w~zDE;ltdd=iHF!<654x`0zgNK+m}`ks9Q#;`MRU-q!AF z!`;T-ZrwJX^Yr0&yX$(+?ZDj{ndLt2h++7379DYboCgz^pkl+^JwP-J#NGS2t9tjky^+-2 z>-Yb$_a0zU7unwb^c2<1^pIi5Su!&{Gl1x>x@%g6Wpm~Vb1A^wodNo0FA3!<>&C6g9n=@RUR-YgBc)$>`V?9O? z^U^+Ow$#fV7_i+`*QmMe{0Iq@(v!`1&uxPPPFK@hPqn%Q&34Gk4@S(@=SO)C+wQ?J zwg{T$`j*=R;zIz|J#71i?IB?^lk^5b^E2t)zOoHyg^SPMX-&{n*|6*L zPlHwJTyqt}s1I+h9(@2@RA&DGj`E1@9JUi8bSibZf?SNA?V{9#YSm7&`PP@}1tXPx z`<2+nz3qXkg68`PHMXCb3VOw(%g_P+*FuAKNcz zc1)mgE(dhe3+;g8Z2t;dGT1gf*7n?Nn+~F2!Cov{~<9G}dB$80V!WG*Fl}E3&S|>R-mBMv223R0q>(_V}!rPAIWQ z@}W=I9_f(TKb#JZNRT!>nsn8H&J9D=Ap3_?W9WyJ*xp0ZzW;GB7?^&vL+?{vbq);* zHiIdgR_kF5kBB`KN`=~e_SFV%tlBwd4db_A(7Z%rw_D-b^DyRW*xW^1F#NXIXvN@R zw%{0BG9TiKZ20uSydQF`{j(!`uswFZEvXjS;ThFMd>Lf_;=T;BgGSksi*3PR8=hHQ z(T^|1$wJlkh)O%iRiuciI&ou?=XDFh^L~O+7QiT*6o>PSoQa+#fO7%?+aa{T)@P=Deo;gd`ldi$XWPOw zh}cGkR_HXq@vQu?*~IsjL31a#8ckRCnhh64m2w{`(DEX9LqW5Wd0tjxoALc|zL%L* zV1Ar$&4cCvayFrQzYCTJ&3fSVH4l-!VX)G+ET>DWl&PVBMr|8v5jM-nlovG52AD$+ z0|Z9$d|+p8Uc454>QjrCs71rjv|`(#pR38O;H4&Wb72HKF0A4q?=Bi<$Azv_ug(p_ zh+tNwCZE3ih*X!E=N%VDZHu6}gB;xxm5-`fTLwo5%_|pHQEzh(pBtCCS@1u zmUW(%<$7LAdJ~#fd7ij1B2N5j?nZG|bJvAndo35HQ0Dq%2^6&pn%AL-F0ie_=GF_v z>dp4tjX`rYg)f3TlK*&GdwPIXljUk7f6Y}FvhaK%bXQy$(F0_Urtza@4(MGIF*1H< zNlzw?ZmATw(M$y-4+ zE0}-1%7pD7p((#MxQz86VvAW&Bf+UE|Ir0*^4-W9SWs;nR@#C}7C;FB0NMqM;kTA1 zEal;MJZo~k>A~Ix5kT0&8~wdR71->*+|HLjs$@-Yer)Ci7b@>79@|pUSDA{9X&>C| zu~o&f#aO}9Gz4{82F!v=hS3FXB&={Ks8b}fPOC1cRf)B!SX7Z%osNpvN$YezbubTl zvR`y4MCVd)7MKmR=u-dbr6jsojiSE&?z})l*lfU^l?x}LfO z5eev@e8$T4d}2K9Fg3~HGP?o8Wp^-O3q$2B?_o2YHJ!ZE>qjbVztSPLf4S{9-wr6T zf1+`AB6xOZ&@mq({pd$G$l%Dr|B4yP%@=25Vfu`rNh02n&5NQLcyu(=OBF#7lE zM{U!SZ1b`qLv8zVd$2htVw?6qfxKb+Uralg0$_vE1X@)D%_5-j_ICYR+p;KV7E`(A z=1pK*cwzDayE#@6j8@6PNZRZ)qk}Y`ZqW77$ zOF8^Q_=dnZchX?)BLjM-5CzQ-P)m6;W&B1vENCvv6Cz3Mh#ZtFffYGw&y3mwOphul zFBE>`Jjt`>W^$L1n=CozZPH*{KLZe^(WTn99_2(821A?RaY3{9Jjd3q%wxH#w2c?o zF4JxCC?~d_5Hyuh!To_ei1F9v)#&Zx^TN4};!C0%q4(uUr7E|9YVHaR1YSeY%FTI^ zzx%1()zROa@jpYwi@6BAb~hq=<{4v0j2Sm_^eHEe7b3HuvqqdWaI5tZMBr7FvS|A!<%ixVi~mZQ1s17PG0GX zg!*4mFI^;xgafuq2nB4iZ9B_$9c0@SNf&7}*`7PdTGNao%O+LHfbw)s*iJO3h3(A& z#F}!q{H!Of+d_M5z(iT&Nn@3GIVXIwHBZ=rnWCVnIV&>I796PO27?_z2SU)zlN?3w z4_DG{N=0=dp%F3!ONYoKusv`2-{(?ZH=vN5YnWF_rBmU z90#Wjife#}J?K-KIuBtl5FC!GiF*1~ZdkwQ^5%1t;pV8joe?10@Y@vuvK_xU=5k=u z7vxo;^uE{yF>R<}C;DQlui>|<;dD>Y&-;CMfvTFurfzpQ#stj<5BeT~d)b4& zU+Um3Nr)+Y=1C89g@CTPpehaMYJfHm&A>AS$RUr* zoYqz|>PfYwLSJE=r*AK{IQ34Lp>_A?fmrCzX^z0SF6{3vD;N_ z)A{Km;Vz0bj!n|%JuUZ%mKQxOkBFA+gW+)x_X)vWnF@DIBj)MaeUbBkFSbF&mZlbS zJmY1GwN<;^=4sg^T5k8Wys?jVsqqlE3E~YI?XulLj7_IjezBS3fqyCBmwVvf>Ula2 z7P#_c4D*Qzl`{N)X4KN9Q!I#nn3&#@Gi}PejUn2h#UF)JZjGHh)4SK|`D09&Aez4q zMDKb;i-hQ{3`F;OM68`LEYEr@4`Su-Fc2IOvlh<_eC=5q9%S1OvW0_eTUMqvFv}-A z70+QEFL*p_EoCRCmYan9_6+17c;qdkH`?}-Z6R{bF=wOf`v$(+Q}i(u zRhX9E$iO^Y5F1O44b~hlE~GT?UJ^lk2`&-y&4l#ky#ixUD_3Vw{K2c%cmrzN-ZOsifmpkDB*!)xF1 z5El#Ln;8)A0wUFER^#CfE|1`KRUkV*tMPER3GNLUa6bmF3GKnaJ|08<4uPCI9;5qC0n8$G zOa~fk#`jdhuNlKwK*mR~9EJ6Zq0IcqHzq4cm5iYC^TM`rs2AfqnL;4GeO{O>H(RX`ba$PXUg=HF2)1RDEtsa#an)-+g=p3ffSFi|uRSkfKF$jpe&tTz#ByBbR6l8AIxy)B(2kqJc_wQ`g#_R(2?DMG5Zj!St%+5ta44x6+5y!Kf zpBph7aQyKrm(qHQ5-WifeTW<9t?3ZGhhy(K=Kgc5)GL&6h0}Uv6XXne z#-H+|c5Yy>9RuMucp%Xp)=Z0aSkvS(rtv9#@r!Y;*RBcy{L^vibLiSoz#bsh`rbG< z4sK#K(>QyFS7R22!aPCwB9gNWiH#ok-2(nf4EW!Prq6Yzw109V+Wy&d{$JRB#*Y0J zAcw zYU7Is%c-~LXcXO#J%`D)0eetl@wjVJ#JrkQW&AJBWAY#Xyqptps%wt92bfHzS93tf z$F#}hY+tCaQPUa?>!Rz3)_Wt%BY}-E!le`@TlNX;IkfC* z03=#=IUyEnu{5Rp%E$8rCZQ(I2(S{Ev@CgWzY&Mwg4q%#zn4AjJ#G8NuqrKz|9Ksf zv#-E5mAOF`_%x8)gV}$J?bgS3I$rK5@yO;Z>c`l&$JkECs2WWNnHCh-?d=D%bN%qB zP{>b8B|i5SjjIwCjbRFfh?whgt75-l{c1711`|Y~tAyecsKj-$WPFrr$#}2{9WWnD zhKvqGaTNJl1kLN-qOlm`NCy+rfQ?9k-ZOBE4$5;sR*26w*mw$LTA9rmwT{J z$WXGUrAbrz=xP8tDdhui1i3**kZm5~d_l}E*KYAZ?-0<9sX$%7+yl_&PSrr5 zlTC5G2mXM7KktFN7=-M=S9su03V3Y>@aF;EffMNPs5+x)48>g@#mlk}nFeawD25#% zI8%;8lwE7O)?@or*sjVj>3jt?tg*x(F@|HPrh8PoLDii0p8)_^-Np5y8qMbC^8r+y zFmYr@`i(a)Tqg6v&J2UaJj@H}NVj_P!gXK~(ro|$>EamDH-+@pUqSk^M|z)-zL4J%(9(i3j?%fL`i>Ds*)pqxfPEv`SWqpC+bH+-X=P=ml0bHH9oK zOx;VYZ~w0`Xwd#w@G4s*v95}AjbqB*>07-KWWLb7mth211iCttW~0ZrM7EvH-ommp zfgz)Tp7y|(3HZ8lI;`HYjhp95*8K*_gxRSMsVNva2M|z?yDZ|y@LBvh7IN+;HFRPH6DH~W*ANE zwE$pXt>abPWSI;jq{(wBwwo(!ZLLFxxqtfdxtjBlt$xA+=;kid}9QdfE4 zUkLaW87;LF;BDO!Jl#XxBXiOKdm^HU37hH(%!{8Bz_XM8tv8a)l96P0hNWT-MiTfE zrm`6MG8-`y=MgUB>{em3bvz|&5>}Y(SYG#7ZWoqK8CdT1Sn6=UXFZ|^g(yW<`33H$ z04Kzi^}_K`29B4q;8@~uY}|hwS9=_v3&)iiIKIw;W17dYcmHwh^2UcbGNXKzVMe(U z%SN36^`W<~&NS zN+8JI-H&-J&kD=K8C7^5Eb$3`mq+ljsK3Wkzc~RsV>&GGa6b^-n=;^joKF4a9{A@; z>Ms%XdlFWkEILq?M{%)?2|s5T6Q*HIsMA1Sd!xc7EL5@i@cFrvyeeU;$bw?4w^z&; ziuY1c{7pjPLQpuNaI*)EHW;jb3yUTBM$2Sxk~2`pKNztf}IEL2NUQMm#1dYt(A9{4*VexWD+g9O;R#9!?p zelCbtW3ARocX#PE7dW6ltJEL+p z;+LI0<8QA2d&IUF$Qo0x8QiOn+}X1jtH-&aL})J(j>P^UNH+(?$5NJQd8C8)xQt+{ zQteZY(sgc^W8M)&^b(Zfjdw3%+sbAczr&lwHhZ&}S;8yUq}O?Ef}o{sUXa5)yk(Me zNxUVDi&8QEP4##ej7<@16)t@p2$7<;tUA>w_AN#+!odu`l5w?5sb!Fjd)lMqQ1B7^UWPSn7S=GW*3F^&OCS6+ zM*&Y?dArd4dzqpXPDWQfttvn2tNh$Ps(iPn zeWPf<Z&#jHTRHXuJyRcrR?e4 z@-x@G)0|FosVDlIIz%TeR8u^lpGEY=8AM-<{Y<7VDMx#~&1_a3n^_Xjm)>SJPd2m9 zG7NFo0?33idhTrsvD7V27(Rz%(!%h`rZ4@<;CUk6gy z;N1@69@~ZqzTT7mh)B=k`qC~g*^m=d43kk48!}Yzs|^R*O{MKnIaoN|Y~h>Bl!o=G zn88sIkg?5V&&lBUpr_#FI*pf%O1#YjeN&CMIK$xhwyR3UEWg&1y*-ue*lscH8q<#1 z&-kWcpJV3vJzlXbW$6QE2N;@bxX*;nM$Rw_yYVy=02k*>bwUItdz!0dyZbT2b~hE< zUDg@C)0_Na`@zx)xpH5{w)$f8h3&l^Es`e56Zdq!aml}JN+8ES@4#m!dt9``E>^`OH{brXe_-Ss@U}z zOYe5K^b&8_@MdSK(n3w8cJD)osOB>~=I2!3+K=#g)@U{kvjHCV3!iV}c#PI>F!PP6 zmBHPo#@D7@er=kiwQ09!^OuRu`yO(WHN}d%-2=T&oc^N>pfvz3RiL}=HQ5%OV!Oe> z-th1j3I1Ci{@qFVZn;l^uPww7{ixtSodJIt@SR#K-y0leHCv5|C7nopF;y*>L+!}~ z?Ce&B`#pk}gy7zcrD_uhvaB%kDMY(}kXT>YwRIKk{weLwuOzu`kRnOWYgS8W@b z!N50VO2_bXb_{#`LU2jyLhu#q*BsU_e%X;|E=?>1U;BlCZ^&>NOU>okmzr%J!%e9e z-T}ixFz~B=mGcuA-t!pvMj%86hQ$uU9v7zjs$XI5*~hxP-eY|v73(^%vL%}x*>dKZ z$M~i*Epp6LB+zoP?b_)+U3n`V(}+1J*J@E-exXKPa(SyGz&_yNZP1duG((}B6ekVaO(i|R2vlWWvsqDq##kVeurXofa`!b=t#$zIn%bX@re3-pQ=6Xy!6PSi2 z_Gr5;+{nDU_~u8|Y~Lg7-&UsdQMEVTHr2j6h;ojnI35C&LP?MUF^w3mcQ)09IGr>qK>R#x}A=ABY&=2j&+% z=7)rNeJW-rV?P4sEDGo<3c&-`fFhxSK6XLGJO$_BSG;!}-#qVK<}vV1aqlT@b#!y; z_AD4WOHjJk*GOBf74UPntIsO{y!!%L@3no9zt{tRN8~R|C4ZiPzYp-P0)CAL{!tA0 zRSx*40KZDWKi>!N*&g^F0iT%)e5-(e3-ERVKG_5RN&es}LFPwpx-3zkd%TZswj6)E zG8}(b;P^`f@OGM!620pkf!D|p_=$G}F4FT`J{tS>dMWXPaTDf7kLqrrdL;wZQs-kl zgIEkA)I9Wu1aZBGzAQ<9ojJVH16?Pe%QAra&~ycocTR*pCZp7y+X1#F3YPc8!H z%X;C-iAd?m#4cls_EdbeZ)fLpPsk4?eT6v9Hwwn`Rp#0&n`>DeCEA@*9hJx8Q#F_fk!~ITUg)rAf2x?i^BUF zfEXfoGXxSty)fhSc9E8mD*n2^4(KHz+iu$3ph3-VFb;%Se5 zdBXRY;mKLoVy*1M|Yb%zYK$1A|;ut4OPJN3RvaI;kFW?!v$Q>%3&)!It6 z_*J#uPgJYMSBr0~x*65_&{2>f%gyx|cBW#O1%};V;Fp6X%&r6mMfB5fd}Gzk=>G3r z!!2fHcn{%ZT&S8PKk#bI6hg^6a+E@cQmP#_d*x)Em2k3VH0KxIFL{;xlAmVyC9lOV z=|_f#7cp-O-eSSa(u}WpU`qvT!}xUd>wX994L8i56s^cn`vA1U1A1D39?bystOJzM z#CK7MvAHod&i+>7>|ZC&o?o3AvN;iFzr@Gc^Nrb@QSUdw;P}u@zKP#ckpFy7^ET0( zWyzc8Y5r0)U!DO`9$qbZQQO{c2Tizlfjq-Qo}6$m*7b9J>phFJ9Mvf62>9xjjlVxoWpesC^`<|log74h8^iZg!QW4T>eHf3PB%VB|6Kku>J2NbcK z^>U<|hX}r3uQ>ZhlECXoQ%`u{j|=#!4B%@39&gV&o9iF+#a>jg`%>NAzHcd(W!&FF zAx6<#iQNdps5H9~-h)VfIaSBJ!?)Hj+Z-IsPW9uPGNpIdHiv<6f53t``@39j?ypo$ zKkDmLbB0I#T`KA-Q2zvKe(hoKXukQyaSFQ?;PHH82xOqH!WHWFUnEiQl6Up8nCCZr zyZfi!^Lvf=`~sL-ZyOgeH?Wa_U!5^{osZk4)*p>?sQIQ$>9xKI)J~Up)4O=_V6$<^ zJDzV%ICtxAuzkh*b(hMoyCDPO{XlflxlehBj|k#39^$ej#5!%c(nDM)h|4lu)6cr* z$>1P&`BvDNXa#nnETR?Oq80cR2ieTGR1Ol~=bhvzw|LByQQ`E~c`x2E+AMsHufwOw zPN_4eF7xEDdf_d@Y#TxP`ERUkF!uEUN_hagXJxebnK85BViQzBi)|8-d)w z?UpC-KDNp(^1$B^@LN3aZF;`JSK-stD#R7ac^=D`!g6^A{X4;u#acLpLa?2m0O$o{ z`ufLnu+lcbO3R5@1o%%TzFC`|;?}|(^D`gd0pwBU^r1Grfmr(tf>_USHjvqvSjBXA z@M_FlpcMwo33<>ffpvV%Ci-vlIBFVDoA=N0GFdH$o8-ES68^PQDD$F;EKv+&`i_GEdTSvIQ>%^El$@NoTp8n0vpMKe=&rmle2GU)T^bxTd&q3pmX-Pbm z-^Sf;P!iE&J~UvRoEouBMO*ZI8>h^$_wpV52Z`AlALR)&Zt2)Tyx!+-+S1 zHdPR*hGGovg);DGkux`Y3;7-1LT(fTz*eKXFw5)Yg@ZY}!v|Qr;<4W=>@Q_F03HH6 z^(2Z^l~fJadRIfOTn#BPq)zJ35-{?B2fsn!mu6J%6~M>ORk+my-Ymz+5}v8s+p1d@ zo&5$6^kV_NHUsE(fVvZG=6Hx-3gYD+;@3%tb^NZ=Jj5RbG1Emb8Dnk}4t{BgUFuu! z%$+KG?)Todd&xem-CuYc^i{HUf0|(-z7C+OyMVsyf!1gfkq^XqQ>Nlu6M(a{>?aYx{&f$;FJGq-Yf26_JmZ{Sy}{sL<8r?m zbKF^{{OWBvez0&y2q} zPkV2X_FkCw-ZJgIRoZ*&wD&e??`_lG+oip?PrmnRfxo3g@_m5bJ0{r@o zm$dh;Y3~Q5y?0A{@1FMFBkjFs+Iz3G_ugsmebV0hro9&>-w#)Pi<9r=dJiYxPtyY|cL#r9+WSFi?+2&7|1RzQ_i68kq`e=S_I_B} z`ybNY|CsiUR9JU_Kc1fOM0&!S^n|tP3B=0O1^Q%q!c*x9Pp2n5lb-Nwdcykjgy+%| zo=;DBAwA*6^n?xR2`{B5yquo!N_xVp=?Sl;Cu~el*p!~IIXz)ZdIAANbsL$j`E?WC zOiy?#J>l*2gm=;th##&C^u6?i_tO(TNKe?Bl5mzL$+naPH%mTDPxvT3;p3Eq3k2hn zlmrKZ$f&xMewv=}S$YB|TGlP{MS8-Q=?Od16TV7M*qNU2b$Y_C^n`EH6LzO35OH0X z(!J>k-=-&gm!9x_dcqIs2|uPJ%upk9*~H;pdiQfH;K5FEeu=jJC)fMka{j9~LY`7_ z^0-PLlbBP_u)N=>3S%KF;s0S6wZ}#L6%+clRNt_uBk;X!BT#+r!d?Gq&M3~Q ztl)f@v(D0)z|ql_@d~;lt1|{Cr=lmXE9G$E9LC&+*mz|Bk<9#KB0AFJw85NUKg|Y) z5E|<}ZQaS9o3m-33T=k8t7DSKjZfU&m1wz)jPb+W|GCeQ86-l7H>g! z`RpkbQJ&FR&OB$txUr)-=-lNSH=bX5)!&h}H^z;v4OI`Rbo|&|gVvxB#xwAl3s|z;qYLs`QW0I8(D_y z>jJ)Z;;sQ3tO{;fVLN_pb@KCTP?N`U;jqqAzIz>%;qIuR{NSn99&htcvUU%*70I&x z;6=3@MWiUydvr+1Nn8Wk6HOdARx*k}8 zbgFHVH=ag{AOZzVd;Xu|d|W-{&BDU28)~@KC20O0F`dJf__@E=D6+aM zM&19?#aO0W-ieeaVo597RTRSXjS!-Tn}!Z08`yUlL6fONtD)`Tex(O}=itW)H-+ zZxlP<*Q{*Q{kKf8l;!xJY_Z+{Rdn>3e*7evqt-JmVhkW2$DVY~X^9syyL9(`zZTHs z+6cH*mLO57v^B#H@!W>E>~2WhUU#rkn<#adZsM_YX44>!qC@TP5#pOOYMK%?Fe8|E zmpQS@^a@8Jd1Ir|+^)^?I_GWGSTSdjx1niYt1RVJWo90YEP zih&5`9j;Hqt4wK~l21p?aGgTeu_~DNv^lxTbkyg$(RfL|pDf6wwZWPQSv#B3NMvJe zZV~rB><;FJn?*N9YQo`Ylz$OZ&O+I1V@C3cBoEjaOv_kWCuMlVl%|3j?m?xL5tO1# z;C~^x<3^~f&F$4J;y^?^H7EN50uf7bd8tlH(#a7U3Yy>L7NJoQxQX0yjJwzA56sS> zIa0@cn(kax_a8AIWn0@0>D(E4~_%XcUI`9d0GRZEBNF8N5Bl*@03nC^`XA1Fbtm zbR-@`T*pfq?y=NKEAwLqCqCL(%fVk6vl&9iKiNz_^Q^HY87e@^l`11fpMI9V$~U{9 zP)A$%B|!UiH_QJ=Sw1^yDYbCOvn+DylF68gQz|RY9)UOCODD1Sv(7$q?3p9a)J4Xu z1aP&{XO1|hg4FR7IIAF$dQQdIv7^tZlq4U|mUwh5kJQva0ci+H2FFLqIcJ|yNue|y zL8aoC%;d!-ptCeA7ZM}dg$22#yD9MX@m!5(ZYA2Z3xRyO#DTm_FzY?_BmBZo?jfpG z54sU$DPgU-oV~uu=Jw+*-mb+qcghquh@T=5wMASK>edw`ci@q26PjwdmoQ+K1c+2H zZ{rsZG8GCGHTD!YPafiSLvg=nl*j7W?-2Kk!+HYz;aPu&CL5pGkjFE-ytUC;>u^DE zA;n2M8epUy8BcqdG(zB>BkhoQ+I^%Qflr>aKf1I91efFUrBbir7w$}2M@0Zs+E$g8 z%m3JeaGcFuV7r?4a^UP7O&>6=BR1DeW4d=Wjc5;!(hnFNiV#m+m$TD$pAQfkiK7W8 z<=sWjuF9F$g{+%$c=UMR@GqA%^yQ-y=vWP+J-JEwt<-x``?imC<2fs$h!P6#G4I`r~7$_^bF0fOuyjnNY zb%I;!!aQA~4QlTGYirKt&QNr+$6%Ks^Aw{jKUiVwjTtHS{Rl%3+3p2WTP=6ZPC%ip zcdQLyH6zU0YlPC`o)+rXy3V#a`|NADt%zGA+amFS0=+G4qOo9NN#a|Tc`9_aV~_{A z<&Wc^s|UM|Ig+~$OLlYT*?Wyo~|(pn8GSM&utK;;nIx0*b?YFJr_A9FZZW~}+UV0Nxziv9<;QY%ll8bU+4!mnGrUy6D{ z{5M4FH)gF-eL04KU~ev;W_VAozfny+8M(F_`{g+0>i{~r3&U2O%uSX*(hlyLU$ygO zf$F3kWX+jiEOP|;t9^ZVpjv9Ka%^F%R*=RG7`L~13!8^p5cl=Oeoe5Xkj^#=M`f$kY=B{K^yFk*l^=i~?jSyJO|00H%?z#Aa zn%tw~J^i=dH2&>u#!}-WtL9R1uC8iR%g&LFJaIj#OBs^#tCIptU_2wMY<*LvOV?{H zqd-m9gF5vJ+a7u=;Vr_T)y&UlxHAc-GLVnarWAO~Kv<)0Xdws&5SisBU-Ea0kdDkE_cO2}Uf-6f2bVur1MkN+~Qz(wOO zVIaUwKGRM2I^45!yfr%ar8RW8C#}KV2xMar?y5(B&pscLgM_`(#iB46HM95(TmDX) z@}_Z<&Uf6TQ}>tKb$q(*6EtBBVaLS^84zpOC$*2l8m?_3>b2fLPGqEE%>gu{htW9| z2K2=dao1h8fIW9j`Qv=*1y{hx zTdI4bTyC$-F7&ONGLMa%3Q5PS8#|*_IA)Z?4n3D+1v}5`nZfQ(;qMYjj`-Za#T)m{ zA{zH{HWI{{N_}XfH$G$ML47kXPrJ=OOd98Ex z>E*7>-Fhrx!)-knF^v9Iia7=(_EN55_fYJh&`{gC)ONVhb{=5+^o57B{gweyhP95z zuECKUl@rz-(Y=HHT~aQ3e+fyf@qYl9?&L*mSU{9rDqZu0U?m80LBNDD3`}URP0h1Z zd33-|8!aGOZr{(50CO9ROae@)*t&*x&xN+_LK|F;{KS6w*9i}7NA229Ww5a7Vlde0 zS6KqLbIl`@7$6Hd)Q8hrIP8XwbUm%t{My0Ag9i_`T@UoDdk?MI|Hb9;(~88j+&Ju_ z1)s@d7C=v{yc3BrM}VR5wm{?*-BI0qlUKKays;B<0Y^&Ig*isEi z#}44;?w-}Q`6Szvcu26(tPivG(wTKt;#!s1Mu{%Sg`FsI09OT<46(T-w*NP_$1>aO zSlfhGio*CVn;6M$Et<40)hneaR@}Hs*X>sgxmfN}Mq@XXe-6|Kgcin8Zm~V)+h#YU zpj-mA347jn75SMWexZ9(k*ANbgN_YNQ?+64`w3Far|I##39zQ=w06%0PA=L#p~}pH z5!Xl1-N@V+;wP_6MoA0D<)tXF}W8ov5$)gUBHyG{=*1Rf&E6Ndd_&chAQ+7n#Y4x zl$QszjK_3Y5cUG!Y8rZ1y#1|y!?_$_>|GmX(dxWM+Rw*66G zs9HcdswbxKpwj-7f1UCTL(Y=8h^wvO{%>+TF${3A=a?VZDq@)_CXP1`MJzXGb~a<* z{{-Frmlg7ax$-v{qxWBrPSKm?0`tmsB5`C)OHT2AC2m@E*1of2%Cxij>xjPL>P&(p zY+rm%&5G57GdKpXFS9m>&PPJz;s`%>lzo)46U)F(F=UF#lOkp^r=akQn2z^Ms$CSW z6c%; zK-3;w1--7aM`+37+K;e309D=K$S~p%2f%*81@n-lTxM&fnHSMZ;mA@Eeh-DxgkfKh zLIT-4L4Z_Ha$@j8RbgQ}k~}%w0Sos-S%y^rk}YuL!Zi0G2~^;EzOt)-8*d@9vqDP> z`27?}3!7^^z)$(8)eaSZ9vuXV9i;RnWt2e7Ar};UEjD~9b~eWf)CT1T(gs?tT#v2A z#z3#E4$yu@D77t0Z4uUa!#3Ol;JP5^D~_1l>BtJw8v5DXKIN89YsEMIb!HW7tgb}N z37%$8<~N7cJ#2@vzE|1d)S5av%}D8hB;DQGF2+@4514Kl3F^%QkX8m3vqDFRtJh{} z7lKcgzNgxQD)>xeHmtJk5zfgS2v&1~Hl6DhAWOxH22!z}5<;50(|;HpO#m4v@jhK; z8K^7?wHTc^sS&#&-GVuhoAdW>C| z?=@Lcbs!dtNe2{4chnK}W>ZL6KPM))q?T1qIV)rh3?4@pwV?x>(!U*oD~B?O+6=ZG zO;60iNNk4PDYm^vV?U0xVS9Gic6SD0{>G2EVOH>lgcFUr;>s2@=WUF?KuULxU{`&n zA@6$PUKFACu@{BQp!y;J{F_@XV~2gEc(dmoM5_>`Mo7?TPGy=@i`59-QZsZ&FdA{A zol(SScf$bjV6f*$a?I!CP?$I|?8xP1&P;zx< zJSk`be(cs2EL`<*%t)BzN&JiPb+j{b{N4*ijNUgz#s)^O36+)D0)IkAikHL@bQs8v z6tcCNP|KN6jf3V%riel^+HKLC4S4so5in>uddP}g@s z-9lHZT|24De9R?L*OIThcoM-QVo3)vC&2W3fr3p>LQiLf(R!n0u0AjD8kst0`~7Eo zb9ALr!Ev@zG2#GeFu0${LxCy^@OCkKxp>n7dAwc0G%TpJ#g(>2Il}%yH8%ey#jdDI z@ze9%pIoLutfzYOi)Z^Xa-`N$DRSDZU~WW|W`(I=mM(%BPAjym(~iju)+#3DnpHjRVu zo7b+K{a?l7PEje| zSVv;v86HnO#t`hW@Qhe`EDSM5%_#}O#wK?SI?MgwCTomoP>TwbFQp4tO?|Eh zwtG#{IrG9%A?bnzZ*5$@>ir~93FI}kCG>@Wl28^`h<}$37?zK&a*!*K{ z-%8dtS#;6%7hhN-VAtUgu8&Ny)$a-3OUe4?L>2GF_~52YJ-#4s){G0oMxR>}|Dymg z$rix5=E55D3CWH1a&;Vv%042AK_0?@8Q{x{wg((->!2;){7JwMaUulJlRovFLsW6x zZYDHz7bAZ0Y*4jqLS=$@g#pV-_-q+@r>Kr3mY#W(^Dvp=o!5zqAhg0#wl&&5lj9&uq zsL&|QP9%}pnBKZ$*>fU9Z`ti;O{~F3x|@_Rrfdm}B}f+XKZCssjXf1118Jo#HVeZE z6}=2z(cVS2xD+2j#2y{C{~osgOMlJV*e{vl3+TlT{Y&ftWo0rxprr!}_jdov*fUo= zOTLMMPwFH_!9eg-B+~f#X&R=z4u$qdu%ixyZ*{G-J*F^$Wl$)!`6aePIf#(9!uTjo zU;s#ATR{SJc0;I|gR2%^^$wT|l-xZyd_}RXU+&y5S3)KEz9RkiW&}2uskX}vw&!qL zQtTx0{9t*dljm+rX3Uq@IbixC+0BWcBPS|dm+6YG0})$fmoc%(@5IO5d~6z`ou>n> ztN9kJ2g>0x&DKW|9cl}Q+D@ML6{3Lmp(cmX1GH$w4hq{*QLEt`EJ==%t!fzE*;OAu zyZMr!0G!fS;r~}F^bD3Sw!O-1JDqr$PrMaRx<=>K@%*_3QNQO9+kB|)Mj$wZ^n}~e zz2-T9Fl!&y32V<1P=E})2LGn*X9Fno598fVnDkwRp9g!FP|3||F}Pw7w~Jw}RAO`( zpTe(Q-Z#jLvc$r3bH=xAiEr0teEZDfSU%WxD+P&6QY;OixHKc{H$LkMkwN%69AipG zo}V-Fe3$C3a-?30OUuSq$uHwat0g+}3cjk+gP>@X9Rx*(bI7lZVdai44rWVs(%%oG zljOSVi1wJj(staWAhy4j+6jyi&ZN>AMp8~fOtp@R^5{Ioc06rxAKSLSHFWD^@dL?( zeyM;xkdKb{+_{A5hRmx#K;|`faT7ODyqohGmP{UM#Aqp3Lt&v-2w42H=k$AwKT z9~uUWI75 zSExHSW!%lZY3=TC;NBIO2M5|hbDG?$>SgD#S$rOH0P3l@$4lp?3~e`6o^T|i89(OR z>V<;HkgrjVsV9Y=(RoadaBdSF_*?;u+C1p9y+$?67@hBw0`Ldb;vE2nLW?*gr^NG7 z4X8kMaz;6{+a1~x+u#<^XyyHr&09`ACyqt6(NhJ==uF!P}y$(q;g2nN|8~JcEJiXhs~I_5^-%2q|Qv z1j{b~(0RmZU`0s0_*LLzC|nY08JG@WsAiXG>`Y>xVF)^a6QSj>az)@I~?XYENZmu!x+9gZsAq}Y;BR?DBGbJo0~57DJ3?QG(DEMBh5Z?^;zj3xoD?eb<;#AV#PqwDQph~ zy0*L^Cz4QKn%RnrHqzqe1#XzPqmksaWD;=VII${v6xDdcRRd`g@13hFHMTGogtr^e zL**`8iBg}N)BgW*7Vr1W_^k$`-)vhckzYV_?JSH6W21h4GM7#|Tj9}6Jk2p}C((S1 z+b7&~iyI;Mp!xQ(8k9?6@;E<`v3HD{2byjL{pnRi00waZCTa$Ye<4Z&(=)nX`@~=$7B?3#}SQWZm0yFc1rZPl<}ZN`fKJJGQm|0 ztG;eDnC*-+R~VPEnZ~@3zj74TX2P3eKwFtzNE-4#7CC7=$6U$i>5LN@FyOz8A?~vx z)ngU^7SG%CNx5AEJVkk`W$2lOx+k6a@D5RnF}R%wx2RR3ju_Mi%v#1Wp06tumiGnW zixm4Vx5^cphR!QF&@fJ)B2e;R9zo7?R7D;&tgug`ymnO{oYe%$6b37l78Ue0q;)hp zjrBqB_cG7%-kN2YugF_3@kTxF<*f%gup&vh$z2cp%1mqCB}Y-I;#F`^L*3Pa0=wf@ z0{ILIgB-Jc32C(L9^>LSXHt+H-xy-OfqeMj% z2ILMyY#7C59e`+4?(VQ{M(cQ4nk7IvTK9$XYaCBy#21}U zJJ9?4I>u>UQ&y&qWyNCx`I$jGZJpqTJ1|K9o+<2R2501|$@fmE)y%k5?T_Opk(K9( zc_%txjOu4{2*7WRwSu#IF*i6YwBFYf-Bj69pLV!yd=;bEd{v+HIXu%*JM=sk-IPI2 zdUBA@B@}@U`Ci|rlD8wmdY;#2(0DuY!l((GA9!i)UUHJp?uj8alLMupcn<<`55~6+ zrQUvCR1f^RIiT~ni>UvHNWyf9Uj1Zvn*<=-286_9cm+5#=e>DU@g>Uh{q8(J6<#64 zvyivgRCr0(6W1!=lfa>x%Yf5y3UiiXwAC`3Ht!2`bDmm%D>VmME zn=>Grba8IQ8K<0iw%apy*2%wpng7Sf5&Q-{Bq!&rlMyMXc7|9lQ9mKpBU&V$kvYyf znax?JpUycZz6+ca^9;4NPEW9*`L=aALOA@{>g`yVl1H2HQ2PxmY+#svI z_9Q0RUPT_vAXbP6ueGbC%ZJh(QXu|Fcl-$yEosA!EMKoWaUY*LbRg~v#d?yM{M;?a zYA2I%N|e@k!CCIQ6+Me+v`V-Dd1BU9*Qv_FF-$m5u%(T%efZvl=Ehpy4Z%?%fIIE6 z@CR^eL&KlKisiALNeJ6xg4&GQk0M=z16a_ARih&hhTx%LPPS#^kGY0yE`<9-USUdA zdS^#la#(#R3Ka9+n5iynRE}8&211RWp-w#j+9-m;;=D>PQo3Q8Ej|vG<)n*NGGMs{ z_)OR~Vg|c_`|jae0`OJHr#&49>if=9)ykS?p9V2d6<&Pu7`8X zlYFBRkLTu{=*HD!O~fSs_Ae%x(7%3(NhUHm<{4MgJoh}MV&s{p#E#d2nZ{mY%ruYL zyGy;tae54=N^Q+{yyFdcM^kBH>dt128M!^MI=99&%E+7r`|#`lp?;(v_GC1~@k_p@ z6d|tKF(#7>-pAfPImC`OagggK)p}=}@c;cd@N=4>{T)_$&Kc23(J~jbm&z&ocM|>|UX){h^L^qevWiG0Cvpx0vvP zvj{l6KErEMc45K}u#r++yJ~47&ZL&!_ma?X|D_&mpD2&$1Ma1(VBYOD(EDI3H2I5s zY-sL-96jMleTYH<0?%M}`h+7aP~%#xZIsozR+) znR5}cy4j1O6L!3$5i&QR@zR>90A{uNiC0<2ajFxTqz!SReli~m;E+sb8BcydQJa#R zf}utjI1dlU7!Ih!Fk*11HQg}ULpwm&>{PSu5jc{akXlyc)pKeUk%viptb<%`;@FnZHu#2 z>Z4et^05sxV^(xo1^~r-54Eiswo{TwmMHsfvbS(+4E+NCreD4VK9sRA4Rg~Z5FDN? z-I-DyIPOgXPsL|sgK7f_v_@f{&hOhF84uo)Y~xh}AMZhnPos9_B2j}X4)8)|_cge5|2)PK`KixAD(Som4}TqItJ zR`W=J>YXST8cmnUJ^3Ag*iZ;mzDz@1D(1^~=vAfejo5J4pnJU5bO{<;#C*f&epqD4 zeMB*9H)<|g6w30h`cgG!1B~H+Po8#mvI(Cnita(ddl?YS)TNYyShE2j1DQ3_0oS7g z@}OU-oy*b92el$e8g}9=nbPAfJmwL90oQRP?~CdK$YMl zMpr4JKPA69#rtD2BaWGC$=n62Gp`-VPGlmqTul*X>8?CP+}UxLrH0GaKWi>XwAq?@F`h_%)EW^zNsWdreLw_OTW66wW?KoO{6=$oluQbOzj&~1p zF*7~+tV$>yiq?fv*v&wJddh)X>~J3FL{9E~2nBLJ|X8~wfJ}zZ;6~b3DJ!+J!;scXw4RAEMBoC@fYDw;nWl8yUH~{s2u6{T@ij8H;O%mN5wmTecRt9gcLyhnR!;hc|cfQh!1Pf>T%Uwc+DQOuDte7+7M8_C!p zCUT{>L+#*m8UGKdRrBgzKc;ld9->jrUVfB2VoS(_&p?L6!(0)67*$gguM?!4{DH*6 z2sZ%I$Vl_ERSJ~5#I>#`@}e^}kn6RK-!ABp2P;lS5j0K1=5sh5%w;!kT}~4tnF<-S z=I!+($(}m#uQbU0G)O44#Z~rMGEtkyC;Xb%2CY zP|0Z9QyY~PjpnIuUup*pg2jQ)RiHP*Vj*wb-$Qv?eMvn`L7TC$qG;~IaLq@fD|Kns z-PDfCCP((t|3zDVMD$csmRdQI=z?o>?dWG>qVr%2^w3w#9p|E&@R#n&1{ld;Waw|tnzu7 zoqh_=4MvlL=Fk(NZ>H;O?T4)r?ius%{=`S=7*R8scnsR48df54rbTcVznmEnT;+!5K=tJ= z;yGC~Z;}h;0|EV_L(O)^{8DC&kq5x^SbIVbi zGD>%-{hsvE6AZX2g<80v3nm$Zstczk(?Z1OQbEoEWTRe_GHsYsKLmo6$>ARUcL03> zpgy6gNK~K-F&sfJpafRvS^NGHKQ(^iZkjMFJiAL#tWzPtVYQ! z3>{~ijk0z)F2hMFl8ej0X`_7^xoy31!LnX(NU6+^%~_}{4CxpK{b4Dxiz~%71;{Rn zmUV-e%iSESJ}SzfWSgZTb6MiV)O83}s{ZDR{|M7Y{zXw{>4B3?!7Um!Kd?l>yQZ_m zAtrpwBE{RK{&bwLd258(6>lHkcKF5Y%6cgZnghHQz{Aj~*-*x!Eosbr%qrJ9O}1n8 zx`1kZ!HP#b9RTN&x1rg=duJU|acR6L^8ogd5F!5of#oMD?F$WKWl@+us$_35Do!35lr z-lH{9hHu8@3Mp^%oq8;(mm)~JYCnl2&@8mvVgisj`T*-cbN)5)@H_FG!h$xj#^+lh=5_a~wabg^i^$cfn+(`jo4~n`CTEMpfWue8sS__tYr!y)*fJ zhMrU%+eAkfCHbE#TU!r{&^nD#^LRa4a}{Oih&6KQui%+RT}ye*on~@-tl}h~$LrPT z7kuU!8oWul)TR7VCL#qG-5Z2_DbMJgFHyKzsclhg3kTbL0NhVc(2Sc%*I;VE++;$g zQS}8i%BLggxjDeeH(!xGC-E$skOEFpq!Cw{Zz3v8Op7#4m#j|EI>?Q;~fF9uE{Ym!<5QEgdLesmc&Iab8! zHjIc{n3GHd!a$sLSI1~KGXqGae9&G1>gLJ_Ayq-FjJ18N7I0&yvJ zMh3w*m^H)Z66~5h(W~X0GuGG}Ly+{4!C6Sl%q-SXjH+vOPQm?{&)|?RbG@BL$#G7L z7{Ex8$;Md9`6_IQKlOmEQqKrtRVOw{FX7M8_Mxvs(Gp;O$BbLu)Kr5v|Mg|UlK z4$?5s@zvajZ4Z5(Z(=+*x^=zWmNHoxyUN4Zy_L)Hj@1?!8GD0}C<@3F?x_S0oj<~~QnQrf;h1L99wyv%MT%~8h? zna2c$)`n3!L+oucN}mkW+q75q28_M7$M~__U2AT5dj(IGlbY+u~d7|I()1!YGgK zEXrFbE*j~3G}G?EKCXk_aTe-@Y|VWKgE9Qr6{2qFiic3In;8y3zKz127>1j9rTOk8 z3XsFeVOc|63%yKPIL(9LKLivl8CZwt6zi7dPGesOc~pE=dd0cTRjbtt-c0Osu(nvidvtn-FLbS)4xg+YZrgvL^bJXEwI0m+_)-jeY_ZB1NW?_SIY3|10m&^Bc=nX(wc>qH-6S;7jkhv{4{zbu zVI*bhFaLTxjzla@Pp4X(TM%%Gm9WYtVqVb)#kj=3r1il&t`Cm0eJ8s$@dlmN zx(EHp1?6-`I>gRId7V4inHMK&9^n2WSlP}+{-f)f9W;6~v@05&h#nOsc>pXKGa^)7 z!7E$F0x9aAYms>vG3727_unpS)^(uN@n=UkG%3p22dG9z(P;o`#z?`yaWsRalp3OU zaqvnSJ>LIq#lJO7_a7U0 z?-~iU$?rPepD3C{aIe#=V!^!>%&Di)a5plpqXTVdv&}EFHm@rl#PK!0ik8@kPk?hTkElS+{iP5UOz}WL*e0#C20ndOiOdJ;}VkV z+XcUYg?ez?$=MD|6_L3znC+>jc_Ar&r=Bh&6XulJ0Fc7oFdQ|zkcC*s6{gq%oqQ*+ zAe_T%^8>N{$Z)p<>1i%f6u(*qZXisO1yUg}qbh8>Qq}vmx$1*wr~hviKs!K zA)P!A03n(9tWSJes2}wpU-Tf&eJBt4=0)N-?<1~KMZW^n08H+*CJchAeg{L%=N1?& zocB%4?Z&PkDj-nvRTjsPr3vmMW!Z8Z;aPJ7C5BZwk(&P4-ZuPMlfSk5dmjO}70AZz@6* zYlW5kc-sLT$8AG>ACim2ehC0&J2l4tQ}Ay$hx9LC-B$p%Q}8C1NDc^8XFTD;AYt1p zC(siLc`V+9x(JXqW-V`>gBQECq+RedF@NVEKYwnJ(b;Ooyru^44yuUH8vkp zm>OI|Y3lO{`MM|$krST_>7F~F0yhW0ZrE-nmzJ(2*xPyLw?<^WA!dCGfC}}fC*li) zb}{+h6qSl(*J{wlXt9Wssa<0IbW98OOO_JISm?=khi0W0o(|^CbpwgRPLQE6Fahsb z03*W0P857j;4ZesCAN_9_YmdU(Azp+)lg#q`eYI_wmN1(bwKBq5mZCI@>!J%GiO>mDZko)sP z-02bD6|FB*{tnkz1X2Z2RyLYdxlw+d6<}R%-dOa=3wKHmUX#01R?Zq8BK$fDT1Uo9 zT5E*v zoacG&eQwf#yzk3=K9dh6dCvKt|JnchImdvwTSsu>NGfv#;w28WcszFr{W$1n$Z~fh zHv;`D`oe*1qXkG$H&Bp0^3!Q_@p_aJ=5WE+-p80z0G01@qsNYcX@Edc7-IUv}Eq5?ZhATk#42$Lpus|rDRTYZz zJB~k5QWU1sMIaGjI?%~WX$M5@zx4N3DM~mzHQax8nyJEbRHq#bX3_tiu|)@YYt>o^ z;BSGMO*;sR$yGlP5Arh|jKY@~g`;LpKPES0`a9Sk4)xdR0u+hcF=jxKK1-ueUcRln zkUovR|7~*jVFk-RbsV80+FL|#p)Y*=&0Rb~X4L0n4%7F5J(@LEBM9Jg)fX6jskOsb zbFdOmQG6`Bj_1GIiAuY&GqYf!`~8;+ote@Q^3+3o!@b=Dd3!#+t;1f2^f%%BMNjdi zklG=#L@oLD!Oksuh|(V4Xm138o@JL(#kb@#6auIM7jzJ;QC*QQR zt9Sf+@Eyg1f5JSOntUbR(l-}*JhD(6j_UBm;}_5kEOJN?s2^V#XUz!VlRX()GctHV zVIbeH)2LB5EUA68XwPmMHV4%@@9a%wB+kIH3Br9s?(Fdmoovjn7=tW% zv+#DM-)rgiX5lVwb1=53s}b*2=C8>td$aI+O8-qd{Sl>KPaqi=22VfwE`EM+dHxj7A~+G@W}ltVEp9J> zM0|;eqC>Lt5Nh|i@y5IE%DwuBCi<+Xet7!pbNl}b62{u90f;(R$38_l{x|}o+)h#W z_Y$`T#($b#)q|<@E-U>zU;2kC{auL9=Bo8Xz;L={W>p_XF%GvNxpC+F-0O3Po}b%) zXYRy@a))Bah2R`qy(Tw*aqiW9xkZ=cUOhjzsGF+>cyNt-LgrMRJuSCr;X`~QYc0v{ zS9Ku% zUHL7UhamFJKnUM|e(tsFU|XA>%D!ht7r(bw_|5eSo4QDkelr&cmA}}ex2IkM)10w@ zcU<0t$~mvsW@jL$ z6mt7?+9Dtx4&mV%#W!GH{1u++Yi3PiRull4^g(<8|B-^1uNQ^xY?r)5739Lx6+ z;AZ2aLePJ|!}8CwkO4kPeRgTe%c!sQ4b=B?iKbJ3K+_s}z6w4{LuIO)ww@J_Tb_nK zHY>4-FBH(v0h%L|)n{`H&d^R&;H{kaKtHZPiK}UlZZT>>g3V_BhW}Sh`{SH_NZ}ke z9F_knU;XCH3!6If9c_Jm3x)-$(@wWh>&uQl`si02Z6Z=LiP_9+`Tz4qJ648S_+NH( z)ij#+io<2CIS!M=6gmD&^lF5OuMzxzcQibD7MBSWBk?cZ?(xVKu;HLLCChIuR<3(% zkW4)NS|qxq70Z&I-YpgfVXAhvE3#0*J9&Pzt>Dx7yEFV9)l_m?fmgWzY9DZTs1aTr z{oP;aA1rQhpBW4Nzgzp^Wiq$-&d;F?W)ZX76Mn-7m0zQL@_4*~jq>_(Pv7y%CgaR5 zif89z;^gCuawvkC_n)~AX?L9tIAjU^5m-Yx*s=gtZ+8FJ=+2oCi9JzX47dJ^N zXt<^?%Kr*J9ar6*_}gX@0*wDnm_CyNy*C2=qyzmI56ZO_WwqXKpl&3nmJ?xR01rjD zZUPtG90!*!S>iND8R(-C==H8z-Bzv^zApu;%bYa<2kTHI6gvg*ga_cH*G$N8cCDO_ zW%WHB)h7=mBf{A;L&rI^GEf~1vl+bvpCFLB+*uWK$!r;N(*1ipBsbxfL4Gwr-r*qc^^muxAiraf+I~761Je6F=*Lo^-w#M{bx0rf zkT<6wb^D`rX{UqysfWBi1^I6Q@>&Ne72cL|3i62nd6k2F+C%<*3R1U4x-BlHo-X~t zgKkfOJ{N&r>_9I@owpVJrt%@xjgk)QAJFQ-s?&Y~T(0)0mW z`nUsqw+H=Y3iMh7W%2(TCI;%q*KYOWNiVB^XMp^XgS^E<{xAi3Yk>T|gZ#LM{B8*#LQugXGObYv=A1HWq@S&?xL$GFs9S?6=r0GncR9S@@Q`<;AiotLKjk3*#Y27~1$n!)@U+MVYY@mK!J?Nl6=ArLTA^wCxGg#ko9s5TQ`K=V>9Z9@jb$Gw%p}&-Z z{!+kux5N825Bb>?jVZ{V z8l(pHy{=2Y@SxYG2KJW$shrl#){`Fcsua?v3{q?0Z4N08ZL9ySDNw~G8V!<{9Hf8t zkQb*Q(egbBd=57)pxbf2YPIkrVc8ORr-2SMG&ol9D+hm_hkq;u&k0aa`z7;Z2Yri& z{$UFGR)c2Ad>@xG?fAHd{B8(H0C(-%Op z7j86;*zo&^Ome*SC-|p9z0-qo!*f~RKWLy)D}Rs#cv717M?3)M>@<4c-I6#WV%%Yu z0nmADSY+KTY|ehs2*>)|8(aq=>|OK#I#8@3{5vnsAAAG?-5qsJ6aNAOiZ72fZ?d z^_d7%_c8(cdk@Ox(Pa(zW7L4H4ph-%8sLjk4cLky-*(3zaoB@&hlhMNxB{Z4ULGKy zc92(j$R|^f?+lQ?0+Nx^txH-1ZHg6W6^6I1@DaEW#_9GBv4a@9VI2Y_lX$6us%{<{?D6%puf9OyedXmpvku@z&iG=B<4HS+B-rUzUo^0c@OzdNk~Kd#i$KmaBa|S0&4E(Qf>H}fkrFh(uLJepuKHX?816t(gBr$&uby_4H9w5T6XLhcl*YYZ|wQ=*Y4LciePHLLsm zzRZu3W$sg%o2-l%z8-SWw|VIACZVk@y5hrao9{T#+db$vlb}xu@f`-LwflX|(n)5GsTr2TCRb^ho|0}x*|AM;-U))e_7s*o^i1Qc6^`vi2WFX>m zv^Y;oLTEa4ce6#Mxaej>PuC;O0X#UTloOn@|28&HRn*XyZyV^$kMxr@P#m3tV+ zV%xy5izAI9JSQH_AH#{NGWWmq_ju(9spxUcd@nacy9+ZazJIyrcQ#+F_$8J#$H69D z>Uz3T?Il=8!K5V*Su!7l*_6M+qQD)c5^UrC3=gvK740a*jW{xv$Q}0zAeM zk(xh>6{H&FDiGy>nSBJTb!BhSMf?xzKG2)>p76iwuN#&2?-`v{(qF$+ z+Pew+Ah_>CiZXu)H@J>Pac}Xl#GoTTUMV;pXUH9T8PSAm70J$t>)hfW<;!a?H2 zTp(4=OL`dDURk}K!>e}cF;_i603e~OItugo+@Ty_;;}An1K}nQtck8B!s_0EZ~o}) zAcx=X{w!AdH%~vUss<)yZ~ZMDrAHseMIZY6&*9opd-X}Vw_7ea8I7+bbI(=o7s;J5 z^8++vZZ*dZK1bvLReo*S0uHwj*?Q>oZ=KGCs5$PdoPIQ4N9Sg6r!n_}T1?`DT=%KV zCO;IS2KHuOy7q& zLz2sO0`Vp8cL%v*{;%Ycbz3(XTLMNy}=1?J;Y&uf$~3@g&gs`oKfQx2?=)7 zCWoRi*yF(_;RC94{7pbyg@<}t_GNL_wU)5IC3M-7Ha2^Ys)rxJy?r=gm#(@>tIptb$4@bFG?VylBG7N*-LDzhM|e?4QI7}U*np4l@aX(LKD6{8avPvY zp3A(Q(^qK<$DvMLmOtnG+zIP&`hsL$_P6k+zlMV7?!$em`|Onk){oqdi-hl3eFnoWQ8C=aHWOYk-C!@+r| z@X?BYUrpow_k!%jykp~k#|&bZuv`NlI0TnXZei}_cc0FW@uVM_OY_Hp{b&ZB6!Zs5 zpy6L9J#3J?2H;GUf;?smkO~;ol}5T?gD1bLxmW*l)m0}Pz(Za(9beUeGx~Z$=@qbK zxPUGRS`0-vq9Hf`K~5I9D|1^&eFco#4iucfmNEYfr_5e%yi~{3?Ckn?bdK&*oS^*9 zv@U*gzynt{HSoUad~WDi!96Cg(2#U-dx;L|!T!_=TL+7|9KvpUIyC`n~jx^gDWzjaPv<$ZmJ6gxg&-ICTQj z+tCNj?9Cmp!N%t~;;&etJGk>kJZKJ=L+ExBs{6i<{&9~F>3Ri#&OgEZ)9Ana=5}GudB?O}?*cK_j<3{S|Na=^~5^pJSn~%l?>ysqd#EHra=`-%K?h!gl1h9@gUZ z((0-u2iRL#48o7~hL#3_N&h(&AK%U06*QYWjh%q->naYzzmr@2I7aeYwajjm%`KPL zpUdE~%hqxhnHw!Rp?;og*_Xh^QOSE~X!{R1bF)Bu^?xx)8jbE;-|4wCNNclOWwrRa zsC$uibfT+%j;rp3Yi*m(egTL)f3XSL!M^2B8aqbTK!L zH0DlbZrN(tg&aNQ-Ohzf4-?0!(N{LHYqs6avtZ-x7gWsJ;rv(1-VzO${o25f+_lXNw&$l<^ zUcO|0?ogf&;EFyvafGcHu9MUxTc@^j*%J;+4bV@0tj~caw|xg`q_X*`vfMVdFfiST znRkFl9mE{%bpq1p*kng9!}*Q)0EV=W$!}~~k*_Ok>g_1x8++S}ZN)7MR}K~n3mXPH{_-0sU)0x+GIXkw zfgbR$CEBOEiv=k+&aC{vQA+4#_|MbuFOjBpaBkoEx&63ae10yABZreEI>H6Wm_Rr% za`eo_?%8W{?|6%Imyo?POe~jj&)ABKhnKM-k2?s1;bNTbaBa?m0(+c!-e=|x5##Lo z(?iyC%FECT`bdd zhXEn_p_bcJ;NL405U-`cAFROkxWKb2Kw$h#UZ-IFXRqXjRw8q_f6cf1@QVPr1|4vp znf>%!0~j@Vx$-_{c{FczZhr_0Pejc(vXZUdz*v0!O)wp}qfuFUR8*0#T9ED!%tPO zQrEdsKTnqWh)QweMjm@fS#R$Z&UH%6b*! zh3#+_9XyE8z?=h``QTm8JID)i=j#rS({pp?>o!?kI6R}em&5011PtmI zJ^is|`~@}p8)~+$t0uZz&DN8ssC|Er5UsmN6U|<`HrH$-tZz2=ysOzXxOS_xSC3O4 z9k=%c-b&?*dudpSH1mL)P0c-(lkD82GJ75|R@60%#mI0TiOus0nF0Smzx3n+x{ema zLi)8~ZSE}V*I$vaAIkDNhDGnx^ycr=0zWm(O*V&{Lh{ zIB@2U+!1ZL!&&2x5ctpD`!G}P7t{>Do*UVGTF=?<0RpOBpo->tT&V6gR0qQ2;*7_X z@eMMvGf#&h)nqsTNDU9N{;es#68onTc&_upcD#K&}|dt~1n^+3hM*(HBaSE z%Fg1g!fbXU7xsMtN(UPfvu9At9fe< zJ)G?{NBX3as;jf;*Zz?UPDEpw`>W4!m+xU+hUPWEzAB6MPYqYX0`}&PlI#OuhcK^| z_B*S39YIQL%o$h!)Y7H7X&3Ow_NPE~Vs^Id1O!Dd;xBhCns(<+m(oj7hJAPtNd^Nh z@`T}M?C{jS7?dz2$as^<-UxBPYVmu$@O>H74f6bR2*utDFUif4A&G2m{&<3lx%!nc z6$}Z#QNpS5us*H|FJX%xHuL=4-l)yLLmP$-UWJ7(XY}+^u#g7+cat_thLfYuFim&{ z?iM=#eQbiX}Gm&GgVna0_zT8{WVyLqGnC8*eQjj z_gStLp9PwIQRX#%FIOxg=14t)GJ_jIa0v9qgYr#bc{hh4W<&SXwx4qn0xa*#b?M?N z7LhI@lVI``ZN-?IC_DW!%6`laQkXCXBX;aa2U##g{UbPD!J~A-aUeLjGz2{07|7un z<2v<-sTlSBDVU(ikr7%$_jjt|6UaUL&%D(3>&x*<(knGe?R|l_Yt;AU#cZsXpC9K~A>ztX}bNj7RzZvzLz<}=da|+2_cRVI6R^(O& zQjg!NrX6ZR_8o7w*DknpOtVL_?uTc@xlwGbp8u=fj`0{thNbmsIJ?^)EUj-MWRP~X zPs?O=N|@3&aMPU4m~Q``Wv>s6BSsy~gXvYeCT4E+1KBUL>yRQ4U)Xx!VKMx3Qk1!K z2R-^012`8tDBG*<&yRoe;DLR|zjYISH2jaM^dmO>-5AHa;~bk9u3+Zn07Qn%nO8>W zS?2X9M(7nLnjKW#$gO+2dQODlQXbVseqWp2ig^t2;?D?BEV%;~=VqU5Ak(V*%FtiV zxsBN<_Chebdgna-QQZeE*%&uZ^IS%4y8NxQX%|~PJM#-S?dG9IClo8|Ze{5n zgsk3avqkwjvpoFj1uU~YY3h3lgqeyM_0qHSP41=*_T0))A-6;n43eP_!wKd>w@jz9 z5=*0YbWe_t&q0>AKl8%{VvfhQ^zcx<-8ttBzq_>%Oo!vc#?SlN8L1OB^1EV}!;$B`0UEIxITeF`Y zdq4#_MMWslnAiPO@G%v9zzQOLAgA5L!=ykyD#)G5DxMRhjzz(RQBJ7>k@In?I6ypi zYxXKqD0s2n+59t)UoOWyh{QGr*=g?^;0PN|$Hm%%v>~u&gNcWr^=%-(j8i7rnIG7( z`)JFuT%u-!nzRe4tH0d*H(l^7Q7M0&A$j>=QhLbZb z^ySOb>5H`Xt=YTWDHl%g@c03J!L9o>q~gkbIm2M$zC0`BI=4CtaV5)iT=zzQTt!t+ zzk=K+61i_r=FU~_Wvrf1_P62qr^=q7T;0kaarH+iL$>)mR+OV_a|~6PUfDi z+>a-6zmv@EQSQe$PBBY*5k2}&IDn&8jVbq0P8#skEp~~VUMJIl@Bir^san5p*K;-0yjJ&`x9`Z8T_uR|Wsa=+U_VbdP-_jKXwTnU$*+5NlR-p|m9 zyB~UR=k()0AWbE=hWC~lAmr1Gv8 zz(OXGBTD={FGvy*hDZpR7{h-9A*GkD$OaI2gZY_yrYNRpVxQ5}{S-0faKiYGB4#jy z#S(D?o%5Ht)Q@LNS8uIO5b2sLDey-M9534td3VL@zy#zg5F!pl3#$QHw(-txER7Pm7E|UIRAb)9h!6XCHEem6 zKh38-d*0ir>hNi~VFP8)X*DE+k?_#;xi#iU6_t?o)*Iu5go{ z+VzMkP`tqLGz?3`@pQH$cl=_yZcp)IME{5@t2+W`*Atx+eaijCW5Wd0;RXvEJy&(m zRiOMaC{ei+jlK~IMXMi+TfIS|&q7-4Ixu6sML1ubY@Si4TOlV^JZTdmmTf#$$#yc1 z#{j=KL*jIUE6hi9W9hiuVB-Rv{4FqN@*)Z97iRlhGn0z(WG!~jt+}(X8j-H> z8zO^_=XKJT6L-cEsK&WO*+)>;m|9+*vVifp$B(How^eB6lgg0tb}Y^Jt^B67@-t)3X(9%G`d-i|Pb z1V?497KI00%5n8GZynEABRTKb_008Fy>NDt0N=(`VgdaVNRI`_BK7nVr+r@{C)%Ih zlvvOYzLRdf2Xl6{7Gd@cWe~XwVJ9lL746z288u~3+}KPglI4q z8B0U!;bFMkagDi!4Y}hku{V$r5UUwo-Hg8%G-z!j#8v@f3s=kdn0)|LO!B8Nyh$#k z@_6mp4%tTIj%T-tI6RA`je7OsUKw?$uD+-#jB_UYBuHyG@<12-fMbe&f@ldlEU)P_ z)c*+Ty`c@$c+m{8^ucO9IuXP4y^FEA3m60h^b)Nxx0MD8dkc5&i`e!hT}Ar4SMGyivbJ+YK!(eLrFl=M1; z!EtG@f5w3EKqhjmyj8tELQhk&0U$c|bHg)FPkn_^n-kz(yIJfY63u0k9Kf-kC=JE%uW7oe_J66&&8kx!7 zx2K+c$oK4}xKM4TY@;R@>T{Yg1i`RS+ty}}iWlnNB^K%l*8q7;#f5s71Jm^gRhb)J zlJhw*&|bP!Z9-ooW^zI93^@OCjBXgV5C@NRo-xGK1N8*i*4zcKdE28pY z#KSH8LGHwc+>twT3tySb7BEU9ogRs!73p*lk%+`;L&SfHq%EFo#~E)`@%K@D16=;E zPls`9yZiuie-i3mK`G{T=1gSXPbk1H`!D#WxLn&wMA|Wr3P{(kZ@@V8>P88ixojfP zpB86`2cDKY$5o}XNJKVRZI2{tGeAlIR@+Cdw(nEhN0YS~kZx{2N451Je4%Bp&8=o@ zBL#XFx0>~gn)M*qPT|OG_Jd%XDMdk|q6`u{a(lPuUcNrJ_xZUa&OoEi?elrLi?ezx z8t?ya&?t_~&g#M-A=eu(({bLn8F_bW?$oupvmrfFH5j*EJFLW0((%|{@os9?4bxeP zz0+S)o&9!@c-635mHqc*Yv`ATp(pz7Kax<^&vyc)QQOy)Ol10X*7|AHK>s`meUEUy z7ie(>^nBeO`I8{FMr7?qYg4QTM;RZiknx~UeyBo*wd|u6G9FV29yZ7lAbR98wxsab zA55^$tdmTp+VvKm`9YF@Z5KhaiY`RUUtqC*3mM@Vr(ch-&uIcoljb=6yQf&hYqMV@ z5&O6jAs{LwY)aS7h#gMZ^@kt{JgbhtvE@^l6oZ0Kb4`mS7M-;8#d4KYw4(7 z@-dy|O9VZjK4<-J=`3s$LVk|a0ht+>&_Q%PwSRtY23f2*LRtXPx$#f4wk28Fro38s zKMCGLnR8rP@+j%uTAd9fihzg(Z2UUaiaUmAk9Z62R>50*!DSSD4XTn9SmyeS+)*c& zB4G%8;r*d4RhiE-qc5gX@|TI{Wv5iUs2+s(vfP9K|D?u1M+CDoZ_X|FyflA37qB4v z4XEJU>V9PTu3SB`LG|54igsc6SU}_#N8ku``!y;r>+*gXW;AR&bL<)X2;F?cy?$TVKvz|5_bFy4YbDc_pgb5 z`5Sl0eLgkLvTE$i`%$t?=#_vuc3@9;>zhK#WA)h0k`{?$-pgQpiorTic0oM6xz|QS zdxHsuAAOM*#fzhOEA7f{4IZkMW36#t}p({)}< z?6e_$X^M$MrP{wy_rG>y__vHp4$pY&49;wYfFf0~HIkRp&vEf>%ca z20=cbVI_{qUZW8uWoXNW(Q11nHH_Zapp#{#)`rJCXqma;J&dzNo2S9|;)~;dAw8>X zZ?K;KRjkH!t<4@PH4YAcb9MIIgc@g%$GMeO*6)oDY~4$F$9iGCT%>h7*7~+M-m#6g z+Fli{wn;Z^oe?)&67hb$(=EUIv|l4PMI`3PO)=?yy~Xd>m*hICY!0vyJS<*E?Q63~ z#_Q}|Qc5AsgrX_i3gGcMwpFIjlA+zsRz z$t*75aiq;H!mqOkkK;Xggab)!-Ndd!4!6n8|Htaz2)BPA$AfIMxQFNnCVn<2x{$xN=8)BKQ*t7UImW@W zpTzSrSft6bEzoKa;$oAR*&`nZ2Xjx-+sCiN1ddCVIR5<+_R*=U*XIu1#wydz3#i~& z&rJi53f>DvLfGG#n_I{o%DP>OaER;91otnRzXYF(s8VS$*{2c?%}-*^t;*aq^%3+H;fI}_-Q+?VmQv;MdSza{YR=6*k%&3e+Q(394`E?WyHq!rCA>_J3!A)R zIxwM_2nFJsTMQi8FI6qLD0h;*MUG0ykq@ZLC(#hN>g*e+40E$YjUC0=4Y|YClH@Dd zE~xTx`K2`(@`u};bKe?LU5Iw@!?|2XZdyNjNl-MSY1?Lsrk1Kv#RKRq<$scdTXP-l z-)YJihZGb|FfDr^cVamQAeyq1q-{zCsa!+=Gm=#BaWpMx>5mi; z{XukY{?P9j)2+hvV=ztUggcra)3BIf)15E)9vS*m`8{_&dKD_tEWFeV%>L}JKQMHQ zoykY%APxuWpdO4ZcGrp?bKj>schGiLS66nMyv*4#E3=Bz@os`Dr{$e-s)87gM}dW*Nt4Ru~yQjsI6>1237FrvFbD6epkGHl45H z{luBfY_|8G`QdHY3+K$F}sB{5zTKOn_N3 zV|@4PA>3s!I|LKzxnlPC?k2v=V3vh^vNHFk>lr&p8UAMuzikXIt4fWP@XS+%{G7(W z6?68xa@zK)OS9YdS}}*gt067qUuXFxBjPlb6dY0p&fJP4kv({+74*{`YK5zJKDGZmQDbbIbBZ_l2_S?w80 z<4MiwMC1H?*4IRR3OM@ajPKsl8l9*eHS{5@;|lvJHQ!T#8B32#YJ4lKi4@FvX*{X+ zOr@@=z)WSn&z(YhCYq}n%7$^S(4N$~xiDQ<3g+xIOlo|3rU0|2IlYzjHI?-<6__3A z_B>d=_omY3^U`=y>t~{V&8BRUFKQpnchIG}l-~N;H zl+c!m<}Kg>U8VxBO!d3MI(k7c=TTqTT&3_#w(mo~rUEmSeobY3rUEmS@tF#qsr2i` zs%t9ieJU_hnbQ{wW-4Pil{QahoGb8z)LPvW%(?7Sw~tF?+K9JkJ>LY(RK{mdc-UH# z%5`DyOr@@?z*VwO>*n0K7il&83wVagVOGpZjn7}w=Govc=Pe`qkjPJkIbK#ny7Kor zV0`yv^Ad2R+Mnp7V9o{4MD0J^*Tt_)AOA|mYQ>zWEy|w?j?)ZBg4Qo``dMgeg*uvQ zC=>FhQpXOfqhuW}Pxiy%NVI`f`h4!WWm(CyCL%yxs(3cA3Z9Rni$<|$f+0(ew#7qS|W+MqW zDzsyH4dp`qM0Et1N159SGK-CQay%-GdDP#!11s8cO6KkADZo4i%tZSrw3n`Brm{w+ zvevEwSJ^sB_4_n~Nzf-xBg6Ps8kgj_RVrTt&QQK-f;K!~m}f3srUK26 zbf3`XsnDGY`|m#KiOI1!kMFYaFIl@4)@4MyLt84~NWo0h@8{E&sjSP1#$^xnMEi*0 zs6>}+{F69__AqV}t^Fj9<%XklUDuEn#u$snalt9nW#(+c>(4;{w|{tQ6B@$RPbyo$CHq|1D*=&ELzV2W}^A8 z0e^s*Y#jxdiN-vMXQK9$kEy=r9-7HqcM#{=`CI?=y^C+*OZrHZt{;^t$D?xRk$)fM zPT=okx#S!QZU=DB`uYM~NS}T1_-;+HrEjaU_6YtM(x-=Xd^Q1o-UR7OCrCeybd?SD zYMlyy6X_Mkey-Z0{Hw|Dv2xJ8%gh&KW1zg}$UB6*@-Y$ak;53%L&kUSwz8#kDCB>S z{Kj;CO*uZb`yTMs{8hRSN?%I)b7?#$RKhcx$`{Qo9aFVO>B~sJmBB9CJJufMKU(9~ zhQ>zUnWIDd;G&Sf?AY<$ zSEb9(Rei$$b@Bxp;2-1rG=q=YykZU=QlA80bKLmu+0)eSC_l=Zcl`M7*3z;z_bPW0 zdGalWdamO8Uc*z;uel-r+!M!l-;>Ud`dxGK`0l&Y`ExbCs_&6`uz$=EClbGFwax6VR4j^Vp(+|3^w^2f;UOOI7e$bW3{`0i)Z_0@#7KC)zd z_W_};m*E@V&(TA*^-1!Uhdk&~D6{C4KquqAm#=YsUw9NW23VC-d-UDIcP8E5xl#Vo z@!gMEoh9QF-80D#^`FYO)@FJ8=w{~dnoOpS{6=ff8tb3Z zu6k8Tzp)g#_A4(#yuhveKe0zv%vqksul03d4ZHzdYEP0DC|y5-v3}R+3tGm%61)tY z^`nM04<5lL;a^<=KAAt39_KZhi%@^GhZGaRfF$!Ot%*<$GFh=dDiiw6pP8w`sgGg* zCCg8gp2VAkkJ`*yRoQYLJp1MFV8&5p!hGm&rRyh|uCY-1>}BJ-xAAvkUJSSLt|Cw4 z9dO*n_n5(2oQchq;Ewt0indOpXUe~je67dwHeE46`gNqQ3GlwJ!t)sEYIkVQbA0b* zYoN3}nZK#b_d~fl@}sfzu_D5MCh1k+*VyX&Y`#@SW1w&SH1e;EhngKp`F+6Ooz7nt z#`=WQLOyiG(cGvn!X2##+7!wteJ%fNetemb_ZavtEXxahRJju@&+(AZC#7pH%D*Qn zmrPIc{Hdf1rhLv-|I(1o+=j6|?==-|Mn)Gkw!6r`wkkFD(b%q89_BnA+b~X7kT+y? z#`HYosXcB^EqkdhVyNa`S#?=<`(BskwpFi~b6yIs*1~PzZ8{wp zjK7ogQ0eEA9_>lSC%^-mqO-~NY99AGK9d=sd<}mm_ld?tc~_G6h4h%#gtCq6#&^#P zWxXDt`c-y}Jm~?Uy`jvNq@Nwi_gZr z!L=&1Bca12$4Kou0b=kBuzdzw(ykL!hw{(c5XR8aQ_YjoFCtwuBfwq7carA^{O=|G z&NTj-kl)-Cbc)jY)fd%s1Nkh4)Ep}B9`efO$o67r)05<%W@R0{3w6#rV|=$rcY?n~ zdsukalONGFFDHbuMe1mgVT^uF zx^VdQNVnYHS6^nfRvx2J_EhpwZA;3Aye9IFEXxaR9U$-BmKV{vNJdw^du<%wU7@cv zp)ao|zb3|Qv`XdPNcy;?myFT!Q197ij_-c$B>C?q|IqZlj>_*k3mqq2eo^T2X=g(h zEI;a3w8sBHUUH3xGJBmfzWZ@2V|&EbQfTj!y^Q zFXS~Eu0-FLIhi};^O@X-C3v@oyb5@ihrF^r2fR*xE$QH!&BHen$-D(2&(oSDKGE2KFPZMvl%vU-m(V`f_L6>^Z7bxL z^m~z$`9hxBl*HxaXyz{Tb(vcm0shED+mhujudx4;{Vk&#w%!6xx7J<1lKrg-b$Q!I zfIlRpd-))w(=|74UTzNQ=URHyr;_znE>kD#*M6~i@VY^A?rAF9nb#iG6Urys7s_orFR~el)md1( z=0UJ3cRTsh6ZPE9_dLE$cAI@=)wZmW5*wpXPmSeUe{63EUn(!bGee&1A2OlGD?G{e zm&fU=+%ISk>@aHYFZmW+sPkFAE72a6UC=hZ`>Vi~$-HA>Y@Q+Ct;3QrJui&Sng14kpE1_`0kIS>oXfya;>P(I~OC@bf$H3rQc4v`j_1EO23zM%~e=~0nhi! z(rY~aM@WBkR;vF`(uGWbxqArxiSLpzs++TurDkKUdRyP%WZh8T`F!tZW!#z$=@*io z+;bYoWWUv?YnNm)cLS#}^Zl>|7V;h>FY0@OPO6-KO7d#lcf~va1I|>r$@1vf3o7^j z8E46OzR*6Djb{nY$@({0-v14pW%W(Don>tSO}qvt%PXs|q}*hAli_@!d6U)mQp$Uw z{rhiPj%K^HB)*3LrZp1i(qwspi|8PL$#PT918~A}ljXh8`kqHQKqnlRDfe%(`pWt@ zWm-^HuB0t5G;gwYzRPk?E#p>r&goyqC1ItbbEpyOZ^=EN{v<%i1zoJExqNXv;FjrKBxoV_lM$D96y* zzKQr>S-Fz7ywJQveXZr~OysF8leKfQyouU5M12$GrTU&|%Z~DLiM&*~$;M@}a*4d1 z<@ME+(lbEaevm#^mN(hBl-SP``{>R+)HfNL$Q+ex`a02m#V{;(|0yN^6T8d1UQzIMd_RYA zwS3G&J*t#U)8tImM;3clq(4CQX&JED!03+=m)^mDD<>Ha6}gu)}|^}IKi z`r1PJGSZXyE6q!0HGXU0G@mM`@3CY#A7i5Qoun@VL6-Yj?tb7RnaMkNg(imR~;3YFE!1Rjo+_PJ;Zpv0$zNVtms>03=_k35 zRfozPaB*Ty@jZ|4a=)wK^yBJ|=FY84pBKhgu&08fQaeLGh9<}l{rCv^?bMf;Yqz$+ zJ$vi;?oU}>$r#iG++QGnJe@x`;J)sX@!c!RaEGxNC$E~k@ckIy>R0&wh5rt?9_Ksq zHz#OU7_Vem(AXLbxGH^X+?Ai)qx$Z|S$5L4*f*f><$U*$=Vf{uAEn<)`g4|Ey0+D3 z<==E^i0zB#G2}f?-ashp`=dRra>xcFPapph^7P()`S^r9y=Q;s z1a*;I5`z=U=z;p?vND=?wNKB?Pfyciqxs6$qwOaE8~USX*!8!U1#B-1PCv`}mt1>c z4wP5Jzw$X!8>TlB-viDHelA;^%GdkYjuw=xU2CKA^+{G|o!b^T&%UJz7JKj*zDpjs;gnlHVJyUWtk^RIU672ISy_3mx>POb-y$Jlz- z8~O7LUp!ACPw%L@xsCJGK9$o?G^XB{uXMejI)}WlCjz{lP^|>72UHJ9z-zpd?Ns@i z4b%x-g2&l-C|!?uo^9nz#v^sMMs@c9uQxCq&5Qe_I+dqKE05vt0ISz19qu%&9+F%J ztj!l?^$H}zU(#>k)Xz-*g|%+`PIUpl&C*NSZ84rIr#BWWmD3Z8S5+t%@an z*0hIu9{26p6Wl>CDZQN))$7}%biI@nrB`T==Aacg{dDrLjJDev3;BC$$8{dhp5X48 z0-W0QIBRpXXZ3E7`9#vwc~;q7&A>aOv3`eOIcxQs49>PO?qOwkGMop3?OW&Q#z- zzw`>uxoMfFCe)+HV_HK${2EmM^!Q714F-6hQxyDoZdh$c@ zYWhy{1GRh6M)o!Nef(W%Z7W|dUQD)Tg=Y*n{fzOi5}uI1-16hK71ERaFK?&D<3W!< zg7f2-N}phy=1REbXQF%8}PI)zF@jrg9;9o)qb~1p^b7N4lH%(s)W$Vhys{W9d+%J{t-|6dU z3^+XBvp$ojYrapjywdtZK3SFSd@(vK+`5e0wU0IC*ND<}t@gQw*R8!IzNHoFv$^qY zO^#_u*EQGWv`6*yk?z`GT90n1zO6z%gOD@W5!#jU%vO- zIH$5GRiFCXO4@5bHmM9cs^a^%nX%^SvX5 zVtzQYrqEd^wzc%M6+0X1^8LfzKBaZ=g2KSM-hq+UV%xxQTgOQ6;J}K(&Ml$zK-XY^ z6hK#@*vQ)q`Qg!aaO8U@$d2)^EN&SZ88qaS-D4$_gA47(hJle&mYmtvH(DrZgZHN_GK1%zFmyy(9f?LmQgv*XLVm*SF+b z>en@_*w9#)U%V*4_>`uzGj+YiLdQtHwzIQX7#_|v5B3!@Z5_S&?zSO@qjx0VF|;VN zVZ(}iUE4@ozOgV6>wYkUym%+K_l%udRZKM_pZJqh{E%}ixLj^wGkZC5_P9Wwy!YIJ<^kD zT-TIus%^}l=~|Onvoha0I70K*kM`#q>+`iM8{JGa@m@t?WFkEIBD1Cr(oA1}cXwe} z^>-G!+D7|E@`+jvn%S^UP*HoKXrtS=q=Qw!(i>ojXl#bsif#P`?ZD9?$_qDBJT%(g z*V~afswMTp~1~Gez2=6(>B!G2t;3|VS`ZQYn$pe(#e+k zRuvf?ZqN7hb~1_`h2BlBKcmC>LZ)kUpkp`_(Y%q&=D}j;QYG}WN!z;Jk{lTflR2Ep z4~z`5hz19`?SGm4;HY-Sri`|n^;|o&IFj$}9Mc=>BV+llzQN7;Qy9d;P%>qyOW9}> zoarhQJiW}f_EPysTmMjIB&Mxw-`>u;(V|=Nz9Y?r4%*w=!|Lc6?CZ>o1frbDJG#x9 zhD_J>4i67@^si-m6HzPKgdT^Pv}h0z9eIN-hj%9R0n6U{ljuq89pJCJW5?Sjas`rktL20Dk6 zEM;^_SH5kib5z&^C9&0WR&7J8U+MXVy2kp9Agya62iiY0M`>YVi-n=SEt-#BR%mjL z@|)WFGO&O`aiFcQRlI-&RhMsU%&+Pj9qy@ba^Lj>okN4-e^A4^LYGTy(bW4t3nPKn zTltkEeJkM=y#u3#W?LDyEIN7$9T%v^-cGf}(ilzX8?6nm80LA?*my)Di6QPC=+?Mv zrznFZ11hnS_^Y#bc&M*!OTN%o;CUnnXj@-jJ78g`SM?3HjTmPr;fX71S2yO@Z&+WS zvANTzT#itI9W!i^^?0KKO*dPR=y=}PA*E_(*;ycqhIAYVDVvYd= zY*BzQ>gM{@8yjnz^NSag<(DvvBqcf|2$ADqT4sTpii-?DAU!=54>C3w@;ymy>)hmM zvlws4Q(2=l`Tn-y3rcu$X0W3xQ;aJr=aT?0_ISwhm53^6dJ#HQ&Bl!gQCcyX4P9MY zkrB)7gsu4(lOTRY(OJt(GT!du;OJ1yew$b2JufNYK*d7;ARMEsfSkaxw|bKt%5h6WlOj;&ThGoniLPf>o}FL0vH8sU{L0bdroz&t%i@%EtjN_H*3~zkldoT27x-Sx z5d%LwJKwUV_LYm5Wco)&^8E4VkTUthnn6`p8`4eKEzEv@xU zj))i=5kFbeP?xc3%!rp1hVo+&EF*61qa!0MwqbapUo(TFh>%62N-ea`vD=oW4eML# z%lKE=p5o`3{x--$-^#Y3jOUCH7ixeKEIyU3nY6(JV_9Zw#E4e?%DR?XR!_&! zl2@L3!QzbP62+F@?q!s5polICg(ZBqdW(LAPI;Q^*L(w|(g|R|MreNd4Du?JH@^`uc6uZ{SA7OuqMIfRn^Wx^EW(%#$I2^C;yVv4>b9vnzUpa_z%pq3J&>k17bn2tjC6<12I zgiLq!c4vl6$`rmpmAiV2Wn|frTi*o~j8m67V(L|>Sj)+4NJFmFk+K`hPp$5%XONlIQdJ-k3^o~GzDL> zB!9}Hn24|H?JGd~662Djxa@zzcKvEHxdj{U>&;tia558Z9uY)RgplVAvSq5osmpSr2DKK z?C(ePc3O)eb7VKxjw1F@uE1>Wkz!~=H{AP1G!JU_>_e3xwj)QArmh6NrGo~mwc228 zl71WX)$2Fb)V9DPN-jLLR;^7p=f~tTkELpNN0}buy z86CKwjP#>57#G@bR(&(N;F< z)(Z@!1E8MvnYIV%EzOdE%($AemS-(Q((6CV zwm2r+!=tQZvL0><4wrya2!M2r$GJC^N zU`EcGRsqq|C-rBlz%5^TU< z&`tJA(nbmk>;-wZoRaBfiy+CzOhal$gsfe^T52a_jHuJzZ6as}f@tQ%;vgG5qrHR; zwIbt;xbHHj{gm?NzCOO;O?59 z)Y`Y%~pg;pJd#_7(*bSj@fk^bELbS*n?!=OtaX)J`HH7XG_Vq zQKLxDD#>Dt_4Z?pEH@x}YB#ybJ1I7M3z~?sGa*V%3!HIuD46nWJIDw)oYs%(>jG3T z46@WbpF;>nCY6j(*d&bw6AN}${>~JKF&i1taU2oeZ>H>Y#=vMl`-U|(*pFb)JIsn{ z$EGQ*!Wly)DKysCt%f5vHE(F$uyRAA6Tb6UdA8J_T}Jcz3!S}f6e;D2j$oU@mRT)+ z**3go011LhBFl)S2ZNy}jg#0AM=~3Rne}yr{uXE<+Fyrtxzlu7FSA4iJ3w?Y{N=5CY&Gc8$^o9gqOs{txc1c{clxmLt|#M*FMFxHZTtu z0%Sdzgg*_VWwtMDXpw zAWM1dj4`_`;e(!A%51=J!!&z`(K-T4Y>->d8TDG6;m&;^z!&qT6fQnBV;_=k5`MUe zO?$@d#4Yn{oC77|T@y0CQvOJbO%KD??ww?oAGacbSNf({Ll*}9(Ox{i(Bj~js-%l% z*2ooC<{y*8Qf@VI0dv(kBp7>)q-*u!GcbWMHZ;O2oFWWG>9>s(%#gL6SOZ3|F~VlG z*OKUE&5b=}L0E{jR42o*Jmf)67%2n$t)RW42O8n(>TByB&d7#o?$uZsJ*&O}^{%zK zwxz`kjxc*nO^8}%AdEa$`LpU*uoog_x&fE`q1i0ulz6 z^k7AV#GC!n+o^+iGD(dUR4VYrT*WjjCw#?;Udf8sO(G}3gh-9}O|j60D%z8Y))B&1 z@Btc$#$K3|Vkg!COCmC8YV5RXti{K@1r@u9tu)h{vS^lb2sObNP6dnRVsG{IE7C7f zCr%~V7ks42{3+}4HiQ_3ytmCo9Hwn_q-U_$`$qHU%4UiG9~vgVgaRPWf&dL}&NLO^ zecp}exC;A3MD;9L>C8x1KLFR4eWAN66YEGrLWvo)APq^bRwJ)Q`aA}Ym6FC495eS+ zyv5jGf=8HMX1quHBcX699%OVB*Lqwv8kVSfWHud=sz|toJaY8VYD44n?)ym`t$w?vRqh++6&7O2%Io_bb zcEe_hu_QY&B&mtC+WZU+3cImMjBTHu8;L84>1wA0gC?d)+kDRZ@BF-?gMc_qhxzd! zvCXR&USw8E=lxpI*s>U7`m)9O)r&=#utqbjBSC*lST@1w!a&Z>H#aoZud7>p>LSHg zEbOr$E}XQAw_$@gYq>KG!pOw92NH`_GQLKj(<@2xw|kZ~y0krt+)yNk0g6jwAq*T_ zy(5032Vu}`V6s9Yv?-QBhD<+{83REF>+cwqFg1cbqD)<5!P!Lg4#vu$*VqCXbBrsf zYi8mJ`q)YWC}gHw>{$_%8bvEJJUCj!x9apNpXQaUuHG@0jT;cpxR5K2EqUb$^C6yP ziU(0L4$vUW>02gA1ii|Ow;2;gqHwmzK52HP;D$4f5mF-SRC1pcp5(lHW z$#@qUTM@~a@n`c5D|*E=v_kLDl2cAOMd>#9VH5D(J~%i+EC7I!otV^QEQi)zQ85HI zoyhVR7_-xtg}Ri4TbRjlb1#;4(@kQt-f#$)K)1oy8mTtSW4X3N($GeX2a^9B8bUBy zB$q&*y1g>Ava8$Jsa82bXMGCAo0w6=oXvJ6D<7+}<878OI$$e^_3M2V1MLW{04ZV- zGh{*-38942@e_K_2+E@c4kf;#7&VER@j+vKhz6%A+fsF;D@X$ZE!I%gj_WDARqhg7*e#Y~7G=+_3U=@6Jnj`s(V>Y*<;p9*RA{Y>UEKnwxk0y57CpxgG+6orX!+C z4t99`(OfxBS%gt))%UYo@kE#@QXJL-VIZ%?(E-?sabx0B%$FirhnSBiPG zXje%3kVUCNA;A(G7h$7)eIcB&WvEc-49t0TVPwUImY8d^Xhf_wKs&v)(dh;O-f*JK z);CF)wJ$W%yb!mQ#4e+uqTkTv5jKglNKv~qR}nj`03$l)mktI> zGh1pB%-IIZMnFdFanX;7MZ>Zy6m(*(Ql5X3#7uWfFwJtyDN z@cR0E>p4yJ`FyOp5`GKo9x{sVR#P}Jk%)M48BsisBnOu?nWr&qi#U|XbmJfG{;8H_0K zzmQU*%YBn!J4rV7vaMNJCzi_~W1HK@#um!{y%51=aG?mBPDa3O;2}konxhRIW7y;vvsaUwOQVVEy|x`% zWIA6rah7?6f2WZv2xLGJO!@VS2{e7zZI{dn6S3GACU6OtRq2F}rbtg7&cvQlUeSYN{0)|!+FVxV|+OX0N zSh!^*C7MC8{u2%+yG4gWMC8IF@}EOC2{}WiEu@;(;1yM~q;@6039Aw1jN+W4*vr06 ztWo~UXND7JFF--eHVOiwhsncCf=L9!6X;YD_+WKxNn`@{Y3bpMmGup0;x~3i?S%tv z1A{~D3nRu4IDcyqiJ%M(Vx#Tj%mW%o5KuEJLb9YwxG_WTDT|beW+GirS@fzUEENl1 z^~45iR)`w5u&jKo)<7G69<6JngM80s&%t5MgPp+~jNq(fLT44zFB#cs$u4#k&H|h6 z_d8DP#d3|qD^%Y^D|nL;QfUOH+qrdR$I6JEWiC+e2J)Pl*p#^dcjxf%P*0I~d2evw z2+I&&WJCy5NMbA4xx<{#=wB3iZFIkai#AFA8`iJdV4iU2evq>@@OvNWYN}+Y5+j_&EAU9vE+0=qe37iru8ad}BJd zmyD1>y#!z+u(4ERIJK!Yzids#V5PwF!{J81F%yDwnepBOlp4*GUG)GOR}D(i0a&k- zU(Wg+^Xmp==@G@v1}@rRx@9J~U_CnwpXP^^xa#cB`iw0Ag)y-)WJXVhB`X+22^;pN z1+T;-=*ssFxpJZad^r(uBxNYhfVenQhms>UDLNsMwao8o`DP5C$dXWE`<8XTgE5oF zpmuvMZp=AhlU4o3s4*1UiH-nBmxJ=_T&W?$FgUBP^D>HgPZhg$g2^rnjbxCZI0k8> z5$pz0l{ROk=N#V<_FuFk68kJg3A{l8vhQqW7WymWdg?r6S=#2dqO`KW{Jr%ck3f-W zvj`bQIO>qapo_USlR$IrSxFYWqFE=Q*4MYRWQrJ;+qz_{v4|oU=_doZBgE$X9AVoR zgZN1av!4b_pTZbUT?)l@q(g4g3}mTjT-vlA+G2`N;!FcFt`5jWEHYE@Hj~6|@=0J0 zHt9*!4UF=o?$^lf-8$&PVIwRn2+cNQoAFP`&9H_L|cAMkIh-umu*${RD7sf{Hfa0}BVAJYrDH@!8%0}1%6kj5U}`Z2QqN`;WtGs$b-1yD z+t@aSGmm4Kb-`hg1)g0L4Dbo+;CU~TYBIi?nZSON6XJ4$li5u8GPW(W6dgixtd`(8 zuN#<9K2~OYkDSMW3$7%x4-H!;`pA9bIbP}6mn3%!1R;-!)w2wz=(=EC@ubS3x-8Ff zC$b$PvJk1DpEARVfZhbLmjDt6GQ|}eyfcN!M!csIu)R|5#@Vx&@yVKB$wT0nvt!*c zbO_~IfMdf-j;PdO@@`2ouBPUOGiz6# zljlx=`eZr^;JVtCwRO!&CDLpD31LF23N67QX2G}i*T$tQ>IscnDU6b8SQX3$t}B=x zJ{Jvz`5ZawqUb#@j>x_ox}?8@;u&a(xMzd|!O*c&H_dHD7abd7XPtQpV(p@mG%TW7 zECnBZYq3)P^dYKeKQU6`u#y5G4*W&nVn)QHm+foeg>o2&b1_C-)Q!N0y}x4Pzy$+? zn+Gyy;$!XF60t|EEm^XfIWoB!(@yVTr!h(ly1Gfl1u+H5KG>y`rfQv*v`7GVG}GDf zEfr{nt5oYB7U2l)dVjY6H24lnHP8*FEb z>7c$HR~HiavT4&HvI^I|DbU7z^9tuP>_{EM*p)5b++;EcicTB_rYZTLZlc=>k_whz zFAeg-TC9~ZG-e|{>*?nsiZ60JBf)6OmMz0c9}n(54;rK z=K)`?A$vubBcuL=KXEwPa?c0nQ2SIH5yq4@`oQxJ$q&)l6 zwkzu=3KWEuDEMZ`rXGnSd1BTrE7`WqR-I`Z==5N>emC6vB{Gl-y&y#oOoSd}i z4BO&;%vy@EQu>q&Ekn~u*q`yZm)x3A-`u>RIT_1r{8BMw zNhdd5Ot`bd*)?@U7Fjz)WZs5eY{@Q6`OI3vlv|w-+TGDqra9md zJF1p(;bKO4g6)s^F`xL2l}}2< zP9{w4`Doe8+MMo}yEJQsJ0Mh2PU32wX{?=wLNeS(t4od{#+N?4{V7+p0f)Ru^ z2vfoKZ9OSx`pAW4*I`HoiEz=#gm&wgw2acxrGIwTBhkKONqA+rNGTa=uW-Vk`}#IV zf$5$Gdx3(pg;LQ2&WZvFgAlx;PBw|W2*IS@;lxd|6~#JX^4wBnLr8GT=mL$w3xb&8 zE$H6xS?@j+ajyTu(7d7fdjI?g1`!gFG>jD(4; z;S@*39PJXL=A>$eEWH?ol6-lY@nxmpr^SJT4Ox*}#ZEYFWB`Z^e?BZ6W@!wz+$ex~ zz$jO3C&*+q@U+X9cjrq&Vv2A^)g=@%$H#Fcm+=2!WANw=Q=nz3djTWUlyjo5h*y+L zSUqO`aDwjeUzhsBx0om~;Ld$vjc6hOz@4=SH3#o!i}PMgNMXxcmF6RRxZcn(6D7xi z@eQl;{MV$|&-JKTy8g1E8Sz)9_Fzbt(C@AyD6uOz*^EUl!(jPgVZzoG$ug3uZ(5XZ z9%ClC0yo6SSqPl*`-ugWqz6DpfaO$2PI2Oe`R41ic=v!{st1gF@e;h@|FHKipn6?b zp64f7mKB%ErMT5@jWOYl(YQ4pwR0^iZjHwi^p51n@^>G)a*Xkn^{{0}mei7LD<%mh zgb;!;AqgQAMPV|bF+~U_gb+d~L@>+4x)kJ5AJw}*bg8pKNxAT9! z2wek!-txw;bp=R?jaZPKl&WhR4bFl{+nixxz!T-N>EM2R>g=;I$g^FNEdjI7X;hSZ z4e0y#Yw@!jZq|`*$uKWU1aCKezT)ZWd*a%r)PP<(P1YhOpVDNdYun#jhA92V(qdwJ zJ(f>=Ph36Hm{@_B9errmczK^LX=tvwXl@^7KHi!5d$YVz^0BB|7U2iS0<6MoPg88A z6$`Yn6BwV-ElwV}dlRUcQERv%gVVv|R>YN}SYRf4arEGLfd&%MeM3~9mTH&LCr?W? z*GAp5V|#5Iwts%CCHAGeQ_t1src&9Ja~CYJIN#4G)>3IuiA{zWu#>a&2a!qcDJX=n#1m!KdeiAW1d_a zUp@HH{J!PAyB2qq8SlN@cOP6FSte^)_zAdHOfBx6REnCtipkM;r_Mb=Xqn4~%3M~k zHd$pwtR~5I@c-<(dF~p!#|(TfX;`3{K8w95#lpIbw2^qXU}RB_|dZb%|35hZgcWisvnXz=bI!JG~n~vmN-qfYkN)M zG^b-!8Z9JfV8DnWj{e5n_tbgzHIy0FWzz22M@5^Ip^7Z{LvEI_lGZzPL1Kt?9b=-G zaN?;x12ue2Qfd?H5y$V$6eG#`XU}q^`~T=?=SWLsna$iJ$O*gh^28J6cdVBNT zkK3yLTUM{9j-iI!m&&&5r=sB!}%fwr9=2`l988k|wYK@a4 zkTxe#N8@s9Z8AKrQ;gAOBiTg77ObS>=%Ta@7d0V^m5ev`)a5n2%9|$6K6P9z;v>B6 zR&1@dl;IgRZFN6c%-F25%IRHA-;|9yhi>xLBHme9QkQLM8PcD7im9C=Deqk4jH|$H z2Q{%q+Fl$ein58B)A*+ECu_KS4_N9JWrPA!IrwEmCLip>_2fAjh}qUDmqVq09_MZf zS@Uz7o5-X^l=eXHS*-qS3DE4a3Pru3xuA(PC9hrkLZyMgdJ}^4n!d2W=2MXqT{I^M zPo>SJwt^`OWUsBKw6}qG?DKo+Sxb+a?TvJOqec|-v2r_#_UA?-S-V?VX~lG4DYLmg z&{|J8(weO4qt)i6eJ?0d-lP#bwm!LWu-H5=xCGtBS2c83wN)CbD6ffoGLUL8O^ujS zBBhpFJCzAjSXh_IMPZd9GY+;3to>!js|l1yV;XODG>C14cOO|?eCTjohH>cNl)Ky; zL*8<^MI2;``3P!OCQu)X>60#d$GC}&RSnE_yTa6SK)$@awuR~vA!<-oSNmk>tiFnw zst?8-vYm}j)g1C{yjePx4%4iI?@~0ot^=1A!pkha*3+V^C(&S(x)*b}i`&!E#ZN_ck$;Il@~m*yOf zR(>^W5JNw8GA25jyI=lTt0vPB*^&Tr%W91T5P`@AD5ANs#FbeD}`#E6eoEgzV<+*ztCZM(55v=np~T##gA4JbIQ$@+H-0S>``(~ z=Srx%gvUa;ppR7$^+)D*lKunN<2LcE!mDxv)RJ-!P%=G%1PWv^tbNe^7J( z!pW)Fbkn$R+13iSKTDuvWIAETa7FFh>MM@o$EINGSM*=_52?MF^-bzW*6g*xWux9} zTJqEN11CPlpjZv>HHc7btPQkNq=s2K3Lr2`ST(J(zB{yQHy3sD>5?he-k1HtvfASr zsTLP5OSAd-OHKsu&T(A1w7%wnqR2}~TV7rGkf+oJ=8g3}WS!bW&!6qy?o=<{X`xbE z&RVkUnh~|%D#=BQxV65Sa{1V-M`jmJp{pFA4P{;VJa3Oip)okj8}*xmGd?LJi|@Sk zUbc&6*Y2X04;L5P^+W44hG5H>pN9R9W9Q7!dqq|ywIZtuntHCgHR?P$Ddr%Mr>gEx@h6W58r}$f|`Nl1EKiQ5+LbFhrc34GY4(`d7jW|j*Z{@kr z(Vo?ArZsn0`F1{0P=_-{;f`P_`XT|EUC1)&swdDUu2f3>!2?n=PJMaDe11D1tdwGA zCepNaO6|fw>*kN^L~~hd9i6yzxt)qG9@VK;-6ObfFKb03L4Yn0_EFs0Z+vLi;e9rU&TEY^kJIXiu4B|)WF0FMnIu;>Db?LpWk|r? z?AmnNBeQER|CcQkg_fSh$_5J?xA^n2y}QJbG~dpk4T#RN>i^j+tA-UYOIAqmTy~9c zeO54U81%NE2P2_>F*2^rFdQ!Xnz-bk(wpqzszkcIx595*Ja+u{yX?}hlNP?Zd}C-< zdi<&LS}aEM`jo6~#G79qeM)t$Nr+l5qSb?fX&aN)5UtAclA|r^JQ!(gfmuR^vpr4M z9xuj_W&MF=Nu7BvU-XiemUCBG6ktN?!ReEz>+ywiC-pgl?gWx;zQxNr)WV+M8m;3oPO_I9Lqj_b&a{li0B-W6YTtC{?li4MFpN%} zIrG%{i(2epTZff#j)TkSE4IfhJR~e8CZLo1WzAH!eB7q+Q>}a50a;Gb2h)^bcfZV2 zNHu>hjOK9^$@f&tA!#KU>pK-u0J3E5=#7kUws);LTNQi^tjvKvcIx6;EypT}G23Cy zsn)`hwNdSPEwjm}gq;SJ<9sQURH&9GwC3VZhAAa&a52|x^m2>Wnr37nnyM)kvr3dZ z)pAE`vurzkd^fyoiXv8$(g_br=;>Rbr`xYYK0~l8c#FCo3kHxE{x;Qx$VS?HkAj z(nk!N#a7+asc#s@EfQsY7GvG?iOWaKve@1p(g$fc7pl`z+)h&OJU(;wN!{ryjm^#LY8#1V zO@t7^$esPWK8$@txx7I;TA2AU+w+9A%uziibx#>RxqSY_0q#}Ql+bETVgt<<$8ogN zr~s^8%ZxL0U~M`Z>t&9LA&oAd(Jh3JFF)7ZI$S*Rx31l3wP5T6YXSJF#~I^U;>W~* zTk~YDcX3jYJ#<0IGf~v7@T!#@nhfdQ^E@7-UnkC7sD80r%e}ujw{%A#ets3rMQ@ZK zTzc-TKg^2SkvwDg*{HslFy~HU*;EOcP;6#YfX7R*ygaPom&z%N8&tFsyP%!b^RiSa zM*R616L>?JJ##*U@5ELlGnKM?dHj@C6}0S7J_)I&^d}Tmn*^r|}zEnn8oq4Rf zNa+@8S^Z!XC|AU~`T(flp>y+orAo7{Gy~4h#|+`L_9o@?Z?>92LWSaml31ven5gly+ckp`Le3 zUFT)B-TR0Ye7VCwwuA}>lv;UqH;+?+tiI!Ob^M*MHn%bns4z-+n7x4 zdUUJAT=>E(D{aG6z3dvWYmTd@(ECpE#Z0t@`n;wkXs8eG+p}lahdZZ!^|iC+2fS zNs*uP4gMo83()16o!fWga>d3EPE&6z+axNv?Gv7lQE{w>-@BbpK>K@lQ(6I{YkyhP z=A*}>X2#lBavY)wTI`&+S6gxDDh4(TUi9H^X(c3H zXAI-nd2I4Nr6UR+v1oZlBb8{tX2^0;JIu0~(YQqBRNC{6?fx*3kLjOBTAE>BI2(hH z(mAZj_BIO?6+wDeWbB@QXxH97Txpi)a+(k9rlFkFZ8O1NuFNM=?=#Y(N9AEv&55|s zQKZlpCW$$vA={5EXuP7;QjM9_sN&FMkX#ec&|iB78ukqAEGu6Ra+ur;qurh^o7g#v zF9QZHFLnF1V~7}zlu?;Zd1-j2QtP;@C)m6BWE9f*Vo+G$qIgony=C^OT4mm@VCR;- z;)K&Rl>5?w_R%`=7sy(QyeJj z1@<}jXdb?NNDX>cCQYf8>9@llv1?GmBq0{QTQz6vp+>Fcg#+2H1YpGED-+X*DTd@) z0(8>NYBbzY-#?MIc-3cpR$88J)^5wft@mJyeY_YVw)-Gn>cv(^Ss_XXO2!to*Bhja z_%`=av9>>`r5_#sTi(MNaUC0^maXnnJy_?6d~8bQk+LQhg(~IjTD#H4*m}h9Zp3A@ zEJLKNQTy5LobeVrTHS7Isj__8f=8c)W)>LRb%@WW&Z(m{o3}#;O84xNwf-S??8+4v z+Zx?AsR>f&mCf2AMaQSY(S<@Sw>tT@oN5rG8AEH3TW$e>+I-j!i%yot{UxrlOs&r8 zixRy}9G{XsH`1r;w4iGFl@s>r?jB1)c99o6xzg;|-?L)RxufZ{53T7rQ^-=Im_U!3 zxitzZzS)W?%@bvsT?QR$Cw3F92wlI*me-SSDLCoF(6tsZ_cY?pte=Ni)adqK$dj$=`elA!Hc7-h-FZDrNr)gy z;Ay$1>ncz1Bix!r;)BbU z`3rk`AKp;`bkK^S0y0)(SnvKFq+p_Qqex=9wX(6SQ%L2c)$1~nZgUUNMUb)&(B4@5RQsd*~nKv?`nlDS0N-8roaBm^?0S%y}7r=I5+?Z>8X54+jA zdVXK$R)(BLg=*o`zFlQr^in(NWt81c_D1g97!-}qJ+IkBOgN}VZ&E!=Wp zto_2yg>x4#>Z3=K-xP23-o(92BwsJ#%J!K{Ep&UFKMSs&$vsC;N-pT4=keYn%k7s2 z_8-(&<|aMoL8`YZ4<42cQ|EgG7(VGthpO$xT`lk0oG2_YHNo*cA0Iw->b&HLwn9B? zQW-9PjKK==CcSj6hSsPr9hVV`s8T*Mj`1mbGHhi%d*+~o{|T-7Nj*s}jARltG3)Yp zs!>ugl4vhfirrAGMWy*dzhKRZSUf*^LU-l*(x4He0`%5mhDg>#1;#qzC18RyMe@E^8$ElQQNA%rcod@YKn6 z)wbHDB)GSAIUd?IRrNZG3!Nw`$y;Jpi?p2AZGSbF8fDLyNP7IzQhN>r)#h8hyn%NW zZPD83bnS+!=}9{s3JJi9rVrzJG?3$y*1)G;*eRhMzVZx-d>4EtfP`s%?RGmjXz7Fn6XUiU?rty2D zj}ZI0aD?vLgGz>RVs6C!hM3hjLNncB&LeJ!yAqnDJUg;V_gJ*5snl9d@w8~us@RUd zvp}+;0lQ!8ZlVxezVEFIJjfZJvJ`Yu0#bvuN$NkPTt1@DU-|A`EqRGv5^2q#SepHrOV3VdY1^`4Vl;J4 zR5>2jJ@aE9q>NkrCvA*aI^|4leDr78U;UA)!hnl8poTGNO`uJ0RK1Oo>|%m?bl1Vf z_%^^tG~a5+fjTJ|lTs;M#!K0inVvH%lojs&gF5+n=p*|cp2CjIug_tPO?HVdsK zF+?vrlijgE2J)SsL4-2p$jxn!n9e+YT*tL8V5F=`#`$G!k;G>$b;9my2#6++-eWTN ztn{x|Q=6q)SwLzpmT%*owrPE#wanF?M*tXQ$RAEiW2Dq zLOCdEKZe`Pr(5yaGk<0`7h+cT22|K;LrXz<#TZ7P_GN{=KQ{2tAQwhgy3;~C2@@Nl z?V4=alErFihlsb|U#c8S5**FX&Xn79W0n{{gxIK5v@;sD^$7{nP9Uvn8yaI2toT>r{`K5oNyrrR?mK`C@8&$x401U57rKSj|m= zuBDHM#PaZbWAf^;mY0klTs$%wUhItdWR50R=%%)4%VwR_ffGwHYW6V5oUUjq!_8(c zS{-WHv3*g8T4G{Suc!J3o}wR{)zPJ0hx9ooS-_4D>P#2Q7BXQC8(AF#&^M`uK1`#} z)E&sXP9EHMcyaR6G@;Ip=&pcWdzn%m#9WmXRumX3rI?;@fbY=0y&uxC8S?eeJy$HW ztUURx^8OaIQWB#!2S4LXO`Q8QTd)}VppSt{7hyBPv@9+LqSr5d^6-T=QrYk<-z3;xjU_Fmckx zmCKA}!Kgu5twtCt``!b6NZ?7Y@W)z2TuhO3m$V!*`==+yQv+vMJ2>q`*c*CGc_a_p zUAkhO#a`Np*f=R;3VbAy$~EyUH>#l}vKPFzkeXycTWwlM(K4ZL#<|EsmJS-A&qKCL zXE38MzTD+wu#L%VnRDvy+*Vk3=b`jng znY2bCtvfBn(xSDV^@iS_gY$bdvTir`2Da+*KudKnv$dtY8@3%C? zEo**Hoz)dV&7{y*?rK_d{DQ8Vl~~Yn8iqchMD;Pcm8^M2yJQEaiN~&Dx0%bf zHfPKAeLCT~>~F*8&ZZ`>UMqWQ^7FQ>vL@@CTr=(4r^FMtoxvl8G(Jj&&>`jH!b;luWx=dmmi`O|JHnaN)0%LtZZiP*6YX}u%IwE_F=j6U2a zRw})B=I(8G&E7TppYD0qfp>p$n|^J->jOoSJe4b>$BQt(EMAI`Z5snhB-#~ z{vQ41)ZF`-p(E$K^qSjfD3U_*l;fmxIG)<@uC8jcPEhOT6 z-MvM4X_^w3yvvB*bCCK7WAk-%TBg+ng^XQ25O(#U1vn8?e;jP|bZc{Rl*0~3#v{qt zJcmz7STa9%-lr=V5|n*iUoX+@6?9H)oIR(TQ`9!6pFOKjJF>f}QLC0`X!@tMhS|(> z9(v*l)p3N~$u6%}UO0F5+_M)opY@3rL^(5{(_&g?LE1Fib>YeJh-I*xl9by^i-2Yj z8ukODi_%)UCqevM88TMliN?2^_>X+v)-cxL*HrX-D71AuG#H3mqal^9x=mjCf@eD1nlmii!Jiefb zAyWMD3s_``!0LHy>)CbwbbFnJV(Z>{4egX(b5ufGm%3i(Y7?A#SkEbnrtN4E%nNI4 zjT9}pX>4)3X_$6c)GXp@y|tW+i90k@cDH(~jmlsrf_?NS28cQS4kHwQSeUgPuWg54ccxU$ zvAO{hQ>4PK)30HV6qF6S#G%Z4F*#JTiX zxMa%H+5a2TwOtI#^>}=2+Z!vo1H718M#)j@T7v8@lUmVh+-PqUXHoW}@vdUQ(%69J z&;b?V(xfh~S3O;%O5Is4D@(6_Y9ysX`3|luT0xaaXNptD&b^A|lc$-=LX3G8DrW^% z9v)MOliO31sgS#AjOKMt`%}n8DrvB>~NHY_RE+S zJh*S~!Ci4lf|i(d@sPH&bWOOn%9=Y}y0)U7k2;qFnHZaeNsuRv8WofagOq7->9aSBT|H?STg^(?~9B2BHhT7?e+3U{~&| zi>nB7-f&4v*Q2?~J6naSMa+)c_YBc%j1PTyc$+E|p_VZxZ*A)n7Q!}zw0hw&5}hD< zjZjn_D*+PiSl{Y`xX^B_ScozFQEMwbvCNbM24yp=RH4dF21QkIOE~tzeczZz#w~I> zu>uc?19Y%|Zz!H3i{k*jmKhnA98!NQ7K?kIjbWkoOLw)$vG-uIQdY@QnIS!zPgwXw zl8yLVjlo0^mBE!s-Pzyd4x1RavX`-z#5^X3?If5sD;jrK`(%w0Bbego=(tRVu*TC@ z1)C!Unm=0Uq%P4;nqwZa{m8-j4_oGw>x7|DM$~GEGC1G02l2`MMcr@1q=rlIVbvJL zH#fvA$JSVDaLJn52e#eK_1iJ?@}1M(`#yC7qswxCLRej@wxoN~wtkJo-?yX2#VeR2OBG z^)RHW_;4FPPh2>m$-?R9nQDpgbO$M%2W?QR-fFS*wpFff~*VKKJ|1MnyAR!m`miyc;SS`xs1xXhT|z~ z-NDjKx;wy+4WRDEjKtgBl>tO^dCES|^Dpf_b7~=EM5aG!YpGjQm}uyDcJr~rdL}Zl zj;AGuOHXOdETp}qb|ac?5IHIDTa;ZPvB#F!PBvxv`DZkqIsWXER$i9nV_yU#aV`5U z?&Mq;J*bO_G#qE>8Fsv7Xg{zVr*YBbvRj!KA={hfH1nzYsRmN*PK^;;6!)M&C{v2% z2ZI89hbb61Exm$&S!K6=nmk3Op>1m=kvgGVVcp$c(PBuke6Zb`4A|33{h|&8mqBZp zqHC0Z+MK#8Qr=HoPPa-lXD8^2xh4Xug4FcyI ztkBE4UmC|-h)9Fw;V(`X$bw6)rNxF9o_g|y$De#sgG?oLIxG`p;t;EQUJui+Fq(^< z7_Zt%M(1!_!%>j}LpO~Qn(qusP%8cMd4||(3p2OwMowAN>ksbJTEQO;axW0Z;w}Fk897&`XC1D-Nm?8)ay`hbq#duUv^o1J4iDE zk!N?yrCBG7#>#c5(l88y>!lqH3M6FV9gSwnu)P_8*N7zyy}B#4>ZJax@j1-Skv^UO z(Ec(y>w?xTk@-Hr@#NX~TI}fz4+0O^1{4E;GKjaP6H`@llxDI>-70^{?Bps<5PfE44!^@Q(iHYXp2$f0*h2cTr>Sdaux^ks0W39(b)IX`| zmK5)|@;-)5br; z%MF{mF@XqUy1fS%gmReAp~wub{;Hk#ck;%iW&qUL0;=zr-ZQ^XUl={~(4G&=GW^i4 zkN6w58rF)Io&9``q_sZ)-Mvzy@xmxKnIzL=Wo3_SY%P2i#{2f|RiZ~H<{xNWT}_~A zkyoR2)#U}rmKdbO)O=ZrQ{M=Y4RwB2AqKI`EE+X(DefSWUm2!~^NQuQ7=SZGGKjt> z>;yDllW~ks--ztS=crMM84Cl=*jB@x@Uf1SZqYbq|EW{fJiU+Kw0G`uKU92e$dzUS*rDLF8t8p|Fd{$pvZDuqw%h7yF_Yuga zIlUXTkx$w2*6m|Yo|9F?>1Q-tQ2&%V&21s&TDo|>52ede9)D&wabhHO$ul3Vi(k67 zIZtmcQBl{H5RnY)lj@7w41D|v8ng_ZbXGNw4s+kvGy3Gwi6@@)JWTUjnOSQ{s@>2((;z7c!xcyW2hfgHdTE|99Jbw_F;MtQkYQcsF_kxjAlN3 zk5(+UxSd+H;Y@y4S@8LBltHKoOroV1_Ki^v^NZ@*jQ&}(I4NOh%i^#OY;J8(M=Ild z7V-6YY2A3F#i$Qqc`fs735SYoJAR4odIBr9S^Vm;^W~87$s_dk(&vV3w{5C^LnL`x&&~RZIlT z8)1HRLUtJXNrzx8bncmA&wVaF#gisqn%ZgCf^Qa$p5VgLv(HIbhiYX@>f%VJV0Ir_ z_=tCEWHi5^Pp5gqz$SjD&g$6wnJK$I&DMKd+r@;^SD=I=+M5MSU2vgg^ql1uxEwpq zp?sQcfqL01$8R4RzPnhHxCMO!RpuatNn%vN_shd218TM(W0Dhon2^PSnNeB;g$T~` zHmAHoW)vN_SrFf9%*^6!dsqo=5tfB945ywxwqLg7J$dp@i@3C@UV12wjtQssNedy3 zm%`q~`w^T7^IgQ9xlXN3C)mhC)reEoDutF~Uu&X&i#Kph!4-affSdB2BLF*`M zcAC#<t z`1Pr_Ww&OtX!hXam*+2gqf=ZwsqWeXM6Hr5*2ndSO7WWbc4?~$^(7ps!W9#@KzGOK zY%e#x2S(&$%ed}=t#_i+w0`)I!_nyO5dlt^LoPeXwHIx@%bKF!#? zo@=>CYs9FLqlQK8Nux|3tcSW}e?Y5;%gaxmeU_ave;!_D%%LsDyO)nH>Z7E5+_ag= zRO@AF04Md?TtBQEjNM7Q6Wra+ddnM(!ziZcSRu@Io+#l>Nj-4g=jc>8cP+4Ss?0`^X9TPah zL?{W|=8Wh^Pkl^tZEo{7%@tam5tV9F_cw=l$t^!!s+B_#uuK)=Gi^CNkx2^t)*k9< z+1TmCsEx0imhH7r4OWplxusw>Vp7B8S8bj;dqyjittzNCRLa-YSV7=ej?!&ZghWv6 z#56uDEx0w)l}w89RGS>P=96BARw1p?T7QVrAN)_MmHxzI}39X!E^L zoh>12!REG#-sOPKr>yzOG%VH#eHu+v0E>Is#bgRQ8KCYGE>vk zY-%EnO#(W2VrJJ6gD~>wniq7grP!k#ll=DT6vf(zE19{r>XmfMusX+~jb7DQWW|ru zr3Q|2uZ#*&a&fZJC;%<)9tN0C!W8)=s9rqi)mQns)qMA?QMHI@UX zx;IbU9X}u3_3)mDj>t?w|)O#i!qde zJc`R=RJ#qQ&TDGN$vyVkm(T08w+5ivGhJzBArs5zk6*t0eqCH}>iydP&=mF3Dcu3_ z_!%is4b-F}-hcM-v**qqf4}r$NLPgnE%>#%ltn+Cu{!P%CBtmo7eA^?9*S)_yHsws zN{RZKK<(lPRVIX~WDA9#EBhOrSu0{WZ1%&byet{&pld4I<{VLTbzt1@-yqbp$c%Kb zIkpnWoI9CVJyl=0aO!D}^He&P!9wgN)xP3unu=K*ONh92y@C%HUb1DEI>0l`9x*EQ z7b3#eq0yuaFr@Za@n_1HmgMB+OC>uqJxv0`d|XR{Y*_f?Kvt$2Z&{scdsxHjGiP+y zf-XsTPE0c!qh3_2JXA5?FZ#T8?qsa3X<^LY<}|mJjp?b{q&ySU`VSW~os~6!CMNO? zL!{BfW&E)u(rQc}vCXx`TE|uwYtcvawt$K z!ocjTYj@PB%X;x+&q(BOpJyDxct|Qs{mAp$IKIJJYbi#gxSW>Z)fSqj@R!OiZspq> zul9#B@$uD(#nZuCtaN~Iq53jOZjz@q^(VJN%<03$;>5T|*9UB^u_w=8#Tnhvh5u5` zb(y7zUncY*^A{zkQ}dE|jc&8LEh5Ai6VqG_yK9AuPCpfkt*I}YGAhWk;)$#8+k&){ zX;{Jjsasq9-4v}K)Wl%Z#vAwgf*gljTgILqC+d^YDpd*tJQL>SH|jA@gJBc^QoFMsiapbf^ke7U8K!0z{8Tlrz@F= z*W<~m@6)B*&wEYIr_1dE1D~5Kdx6bi+{uMrKCZ3_Y;zH`gsb#`Pj97wo*2t8Q*Q0d ztMAbr*flT9F@1}3Ve#M|9jMGJ9(Ao5Vz|0EBSxE-G~<*oJH^^DLil8&G$RCkDnLiZ zSV}Gf12y9I_5_(kzO-;&q#v_Hv39Jt#Wc$sg$E9P=)i=o3u_oJG@DJs<_q<6?yQbB zQKTudk=-+?yHMSpkIT3`IM*W1mbW=Fuun5iXs6gGxEQF61`vG;i4OzC*NU4#N13Z% zKnkKVsatb!je(5>qO@Bqh}*I>1{&bDhvOJ|lwbb7URj#An_EA`W)iNP+G9nj8Ac$; zl%X5=vlz$Nw!3;4Bj(H0}gFKHdpmuJe`;JUp(!v z4dse-GZs+`)N}c>IhAKeLf!4cC=6*k#xUkWjV|3nr6)FZtQCNUyfJ+#lQBjps&-gK z@v$ToGzTbUlRl0kVEEeHoWkO=_L)UN4UlqBv4=D13uUOHVaW6o%@M`R&`bjN>SoLH zV*fm9rarP)_h&Be=VbjnOI6N7+buG7^6gG#VW5lz;FBpF-PQIP?YMaR|JAc<6whq} zt43qMtlsNJ|Iey%gp7>$>gb&-{9dnDcz_pI<6QiLz~1ZZyd>~uINuVue7${%#zS`9 zWadcbPQ9x}OMoA%G}nzj@#g67<@mhP^$#+*pyd36ES}3Bm*pTohh&cap~U?3^PDHo zEqYgtjsi-aZ`66dF{<)>V^rn&#;D5kjZu~78_th^{X7@Q^A)|TMn~4GYFqTmd8fc# z;oK&0Z#aeKCzB!WXZ5Zc%>rJra||G@dt@==vOE$}%z=Kx>Us|Ng$ z9bd8kJm4GYkK?uQ2mB=cas1T&W57SBKaOA6e+~f2oIVbyr6K?zmi;HF26^lcRSK*8 zsAiQP)vWTPnpJ*Ov&xTZR{4<%63-+-R*&90f-o2Ks+ZB;e`)8^4+WyVj{>4K-)k66 zxCEHht9Sr7N-W+o)|e`MK75s!pE~~!%16`~Cd?JH61j>RS4N+bgzRC zU$3e9dQH{WYpT9pQ}y*Mc!#Q!C0EP7<&Hp^>#{q5(mzoGfT#6JZ~#g%->QrGR$a`u z>SDfC7xS&Um~Zupxm`ZNmpx^4UO}(u70Uv?X6HQM=Xzaa9P3=nF(A6nygdD6BYsN1 z2oiH_EkO;Lz9WzSrdRsue+ZDEocix4Q$X}ncJ;gnXu0>>O85sZ!aR((K>}3#cue4l zaKdUY=#?+v3wkLCFf{2B4ES#G2L52pU?FxYJ<=6DVC#PjCt$TAts2b%?uvAF0JqtD ze4oG*dPT7x+wrvh=O%0NC8hLpCwgQk2nDTz(_ns*HeXd~zv&Xs0w}z4x?;ya+kXjg zr-uqh0gvc43XWs;@3h(GweMUZi*ncCWqN#W~yCm0kgin`xHM*%RfD!2g%)ullIpD*6PSM9w3AYEa+ zCh*O0>c5{XAf-B_S6oSw$HIAB;H7W^zGml9{r6MHy;DAlyD0FeoxPTPLEbMqhz$IY zz@0Y)mu!%asts5t?(H>l7jLe{>tvO9>zv*^Ae!e0fDw+!w)vR)cnHSvKg#*f?)jY- z@20arI``>SGXqLGvv11%mc8c?##@}uT$?2H@RL;~oqrORI?lIN{ag+eCw{D!V{QJ3 zNFkmm3DMvHMSE=($(J-s21Zav?qx%3+)FS|jTT1<9JC6V;w|v{;AE6e(a!Y`B zjBo_-uANJOf3WiiAX<6}fM%0m1H5DB65uD{3!rw&4G>*omL{b?%2#Rm$qH`Jujuw; zz`c4!h}Z3iiqHS0{GtX&Nb_e-ehk}3@?(Yj$u!}Rh`R_lsaG127P!xG=Kzn|c?57e ze9sF!7rua~@?4wGVq1-#u=pqCLDP$AXJ~a2z%6e-Sv2bZx?Z&>Rr*;ttJt?yv2UXY zLCskq`l%E8zI;kTe;-c3yLK)B{)e5jB>!_e7XYQ4TdJJ4kkeawl^m_PLZ;t}Gy&hX za}1y|s_)j}N^PyO+Dca6iL3zMwQ~$0XA-$e38;=c3yzx{eVz;$vua?~&Wz?~<+G$$ z*jMa$#3*xZqt9o>ogfq-bET4Hu)p&0lf?hBaQ@PG9p2map3p*cS_vhS-}yd;1C1@Enb)uy*bJ{2CNQw860G5@Q6sMLU1 z;5iCd(kowi`pFEbTgm0~B1Aj`fiLv}Zx-&fB799@(kB20sxBIiC`4z-0Cg@4@3fo2 z6O+%#sVG-QIBv4IIRdytul;en7XE<0Nq-!XMMrs)1*L^bOpt&FqF6t&oZJNm^{uPvnsV5TMZP%|O!s#M>eF1--({FoIrMA1oCV8v_pM?G0=ak9JWKfNgdz z0y0V`>1>&`#v21(H*pr_@sPSzETE+DR-M9Iqbh}NM^T)O0q;zw6ejM3Nh?=`*Rb3jSq*J<5SnzM^+39+E*-03_aEk0LYmC_v)%h^jD; zm?Z!2t?(A`=SkwPk^9Sf)ktrsw($%EzBL#K1tbWs18xlWDj-#m{|!KdoZM@Hw}tz9 z;FfS3?g;m~OM)-x9bmttp1O<>{A4kS{T00vgGtDr(rF;U!wNp>Sc60+ztU)5lJi;` zE%64^s~RowuGVOYH`r)jaG|C&S_%9&(P-3SN~1;4k`Vl4d;aE)wo&P*(E!KvUQ44T z-e9BMqD0iw0Esu)Xz;mu8UWUwP}wjd%5H8^gT{cyqW7S@)qw0q+R+p8&Up z`#r#8;r>$rKS?)K>@mF))PB2+7%JlI6jqNo;89FCRYfoaQSOvv78~Hv;R&0_YUWSh zxgy`Pq%pov&eM8(StTAVEn)!@uhR~Rx5IezfW+&xL*nf;-U1-;I-LhRsz^hrT9!{V znB0E?oC)_@AOb-C*8@vStO0Hb|LcHEP=&J^SXyWmaC`V0QV`)lF+a3cmIF~H$@{(4 zIHJVQf3G8H!Q55?Cy1Sm5=`om;9jRUv2~kxRJy2_#On|nJczSSFO>qqQgRy-N$%?e z{3P4KFN94L@1?>E$bI!mzyZBIUPwIXui^m`uTwnm)+i7{Qam6mP4R$4lA9X%p?Jih zcM&#Gyrjy%QR@A;P>))QdH|SA>xBC6hx&D~JjmayK#dvK1MkwS$VS({ehkkcXB4Cu z>wv^sF^0FYABh-i9u+)R+{Xo9DsBNknIWYoj#&N8)fve@GM0Ztq_&(@v^VN#Z>+AO zbw@1_1kriBUYG<}I`68g^STqi95_9GmUo$t{?7Z${|NmA*?7 z;#RH+NA_(|Nic=)Qrick@qO1V)r-^->q))Vq=k;JwppFa!k0huU z1p>~7dlm3ry%XJ!C>!*W-juRcWY{UJYa#=PDnS;!VLZq{*p#ejL=_M)W9Op&`$;+#}pTlU{Gx2(q0I!lqxi`@>Dh!$q4*!k zU~0ja5+{I5dZ%(jC07&gYTS@`gWM45EdY=f>T>$;C)=;;WozhV$TB)UknTc{1I~o| zdSDE_-g^shOZaaDZVmU%z}awb0B#TWO~4)DUJtx4+ z@Oiyc2|G6493b&}q)=F~1(=7Ji8n~tP+(qiO1!~twm}JrgntI4ZgT%Aa3p8=2Rol5qN#+w5q-XPiO7-gj|@dn9GVIve^@ z&E;gGbk+&@NgCX)UxZEJN|F$H0Pya$kSFo3MxMkQBo7=R@??J^-$C+RaG^fI(sn#q zuWO*)I@tF%y`swvz%mS33!Dl6>w$%p4aedC9w0RsU`Mz=f@oboSt@=6hx}23HlpBn zB|$fexZ+j7PQ8P?im0Fg)Z~UB%Dqa!Pc{_YZl~TU-Qo@hjR6nq9n4Dp7Kl<+a75w_ zc8lm{^MJ$~>=s*vpl$(3yk57Uix;V}9=JiTs(2&t=5VhALMQpJ1v1)|dkt_?xK{&b z!fi-~!hw2zl2r5-!lsalB-JW_1A3>DitPRs2GUSV#RJUPxde#z9c-$IFb4>Ve8LMQ zkLkB&OhV~eg`?mfamm1C0j7P^-|&u7Q5oG#2e(W zEy_$B21vX?4!cnZlpR>O?RsG8Tx)=Z^Hu|koHaz*D(($Sf}wlHa`{OTK;BDwd#g*D-?6^&Fx9e4V>%X7Oj~}Q)1pyZIP9=Geat@GqgCw63f`$Ts#Jd{F6K{~@ zh0HfpWL{g5`FhBFvtE&Q4RB+)R|9MElZkMkqMxL}t@=gS0Oh~~zx0&dao!3(wVxmv~nz9(ccQ@rZMk;@v0|H7;Pr&L#c#ljP?|VAX3>p5%awE%yKUwH% zNa~^KrxmKU&$jBQi>iT73T&1|J(Jd&hG(k4);3XY`AX(QW4=$CqGF)^4OqP#Qm0aP}KPO zZ>Q%?le?J+8T2q24^&$A*pe)_`XYX85$;=lj9&ABJk&Vdb1ilQS|f+|$SrcM21Y${9H#j96VgGk~1BTMfeS$zKxhM!CWd2yFs7zMaD+^Y@?lBCSQ z05279;A`Qn|9`}J$Acc9~fM`23?k;i}$Pm5LWaJmO?kH}!~kYx&;NY}*wpn@iL zPPP+z%6>!GOK|UmR177T5{h2j6MtH{bXrCds(ll8UaDJcl-T?#8<>}a|{r- zo0gm48%j$Yya68hR&jq@@VmwRJ;5Iqw}2l?+)c{ugql-Q8-X;!#Of_Epg1|IIo@8K zS^7uj=^vS?e+b=A=1K>k2_Q2NzJScYrEp(&UNDMq6!4bb3I3%tP$;k#Rv%C{#Cs8RiT{!jM zPd{0+OW~@`#Q1x?s>SBF1>Y_1p9ucExCQ)VQtS1L_+pS>tj+}dBUA8?Ou|1Rg;o|- zX}nvf@$Tv>jdxd9X}r67GL4EC*T9Q2df`hT{TaRlJ{|7szaU6)EBXuNdfMTi!(0FT zWKDPK*XQ*Ph{@gZ{)&TomfLXOmmJiQB{bUv$9-I0@DK1sy^{F)?*S*)8UT0`f(R^vZqy400oR9n4e+LLuLf=kx8aU(uLUChCK@l3r47_+ zzSCiN0&h`36lYd0KglNiAXrHP_Ui2sE9C}760rb@*C7^oYxPn^`V(+Nxa$e>8hQE2 zGEiL-oH8Wd=pe5h(|HDqN4AA}h9FV|0Y8})R3>anR{zE+0XrA2o=S;|r_5W05*?y% zc<(z`l$2+5N)G}fdwP@wZ<4YgPEr;;C`;HB$_DRv&GdnxtdhrWbrPNgCti=ogi?6c zw#13o>5vn=*xPl6l&XdW1qsMaP5mUZz`KM^sZzz4$As0RURG(wNz4I`=>>1FO1CRe zG6s-%y(%fJEPyZEQQ-})N!};~RcjrvNSU>jl<6%4LwZO8yg%IU0UpykA;_p2z56k} zk~m!>TLNkBV|u5M4$6x004McMCEaG@c{w-n21y4kL^?p?4U+Co<1GLZuSYuAph&Q_ zz(Ph_+#w%CqSe5ea2xIn_YJ`PdQ~_5_mj*-vd8uI1T^G=8!6BLxn`Q6-grSFmaBiH zWII0m%_&JtQ4;W|-l;svSfLCV5^soo^BVz_(gB%HmM{#E5@>3VOQj`Z2IF(o-_B~`sydJTt4%Ztp5J?^Gx+p>0 z%;mdV(^lbq@S>3BBHiE@AfMa?Gvy#8XgxF?A&SQGP>rq1f z1SU;y~+UT|( zb0l6*hmv04`It_O)p}TH+I4!-w7{Zu4Y!B?b-?@d4rp4qnG#GHq*TnF|j2H<`?BQap7-zynTViVa02h!Ss55XB(lUv+Kn zkFqry;rC|S`&*3k7O#=#5^s>_D&+^>z$%J-iz@v+D!(YpEP3;!sK;HgXx8j%>Ob-R ze@=l%``Zt!RrCgQ;4uWNS7|_GFe2awih{@BBo;h6#Qs`8tB{ftA};aDKoF349bzZm zj1V-|0wmtN+BfXj8RS>gdsJA1)RX^cMsHajOuWG=-EKT@5+z=* zN0ZDP9BakIe#PEe*P!nqcAhA}Au|UMnL=63pCySC{RCG`m5|P1KFK|Wy$Ojk@ zxFy^+M!PfIJ_-4`aIY2clR5K)cq%*KjNYkS7F3x7B;FvGZF73_fW#Z*vU`o^1FDJF z<1z}oL9gof9w4nQcYT}LpWG_H+rob>5cvx|fHUD<4Xo*LDE!w0$$WtO$ogr$qI>@^ z3UrQmki$<+(rWy)SAkPW8Zzs*Hj22e6rmX+z))m7MXvk-ib`5bObpnmmwvfhaDQGPKo5TwGPFoxTiv(`eD?VKXMAFM` zxINsff%oa1kSj#LS>BQVAp5P4SOA36fFYTD%aWMw{Z8xWBxzFOMPfGiD`*tnPqKW~ z)7<0e8Pu$xnJphJl)hTmNW80c4e)4f3PWDNA}I`EfBCN#@IzUNbCs^q=OYhX3Lkmf z@Cl_SVwH5es%`}dMwpE|vEJno`(g=My5pE|$RiNA>MQ!>%IpIBcpp^s&h+@Xt~6g2#( z3Xj~Gu!jgC#k@Xs>ANo&ui+iAP!NBwj^vyhph;CKv;uW$-nHo{2|+fRQwIiObHyY z<$ys4LXsfl2r#(4e+XDX9&v~r5Ir+`#SXq{aEsjX)_*@W2Y{+f0h{fl1NrG=`A}i$ zU~A}LkLZQvn5LaBZUH|Ty&AClXvgger7FOu!`&O*l0e0p2#-O2f$bp==>b8U#+rmp zVNHr6@&KsaU{>-k1p3__AE(G#{sCmZz4_4^1;QMvmX~}`IdWeIghX<$2A27eA&JSq zcM=-zA#4g6svb(?P9+0biDdwZ*PABNGWB3>n|`ZEtAIQ74sau6AiXK2t9s3DVIkvb z(gVf)fZ)fATfk4UAU`7diX)p69g6$uN3T^{Pa~G-WHcqZ4gX8wdm6Dsr>#5DNsl<1 zrM}VB*gvw${t=P7W7XeMIsDF}yB_;hQW}qjE2=5W-ch{KU>?c-UPl3|vo!tYcVT|l zBD<>RG`>DwNH)D>EAn-TKFHUa|beQ3`1bK;m`U2Rw>`_=i3~kmatg^_Y>DALu|F_>BZ7YWJmUEMDSWt$5)5 zy2T^Tl;Zug6pt1Z^#D8d_NWKmWVRqe6#+j`0z9(Xsds`BiFb#CeB%}E*~=>NqDa1v zDDgTCm3TCeHn#wY*Xc-!x7BzHfW+%`B=C?)6kpZ44oDfOBCs&QT43os*8^wt3dfLy zk_-0uY*2=|`>$Kn1{AQey< z)&nW5-2aP!A36qPrmP$EN>skK8b{RXc|JcCPh#F&0;li`38}XNcIsuyvs-X~aZ|S7 z#IC5M3_N7LlBi6)tI49Q6YQhY!^@eo{gt~Ad5K_whuXSS|#Sy8pR3;V03IWig z27E*iyaYTP?%pQ0yno|Gxiw=&&d#wU_Y->QKmvY}6Da^=ISKo>il=7Hf@UBLIJB2r~>z48{=;X_(=)DvUIHfJXMy^8|AccSdDn`2z zMl0l74?Gq)c>76`(XWr`ox&vR9OQl%h3VbUAcT4eqOg(|!R~P69$Bhlx<7zM@qv$o zn_BtFV)CPES*kH`$;T#n7h=@izSlD*QroHDkbJk`{^C9$c#V9rQ>cS{LV@d!3Zg2S zjovH@&`}AS(gxH@91Wm!gIUSHX350s(H^`|#x_$;yq=n%=(IiU0)*u#`XuX-fc&o$ z@RRKYTM;&;N+f@kP8yuhm!@PB-NmA-bQfR1wlz`(gD1;^J7QRL&FCks4J5Y8q5ppR zF)X^Ka6U}Ph*I^p!A7ut=W8)Gt|>fCo&D6gKwA|60QXU@y@Cgd`vJkz#Vz2cAH7~9 z=`G%s=;Y9g{y%B9V2*(UL>Uhps1j6)60|Kt=OAnfmr&+H9J+`Z9|v80K;e*D-TPtc z>qhUrA`nkaIgph$;Ay>6J5@*;FTy0=V5bTOGrPbClJkHqcCHY?BL6O7spWk^8tQGJ zZX}ORf}%i*CHE>InaF(ukmz#%2O#B@`#%c!$?79q37bN78cvh}JfL?fW&V}M^w%Id z7FBF|l7OGAI6okyY6rN}PLTcdv6{Uj65A}Kt2U?Gzo-rCvd0vQradNjzPJVaWQLU- zu{E$I(o&NGYXty#}!!aXJcVO38Xf&Dctm=r;A&_Pd^iPx)Qy2 zeQt@~qtIlhJEO#hnwUKQ00&^Vt6J)C00iJ*FOdK5d}A1yrlki!=G$9(s5<)fba*t8 znr00U-6i+`j7{P{z*dfd()5pJrtG9MXwU&Tpcif!9J2(8e&-+fyAA<_D4+uZktlNa zZegZyaDsrJlm&1FVZXT?epIoMIQeAC{HAoG4gg^;6TjWQnAJGH9? zalPi9c!P})#j#wEcIzE?2BUNuLsEvEz%oF-0Z2CT2i;FrnodX96ml}>QH20V-KiCt zG2R>?@dhgtwU`Ga9!kJZ7KtC5^-6XC60avas7v9bYd+dh$YU{2!XgPt_{sbk>=HJG zBzHMz41g7;l4RC+K8KKagCyB%ym>(44U%NL@fHAyH%OAwq5cfGL9eQK6L4d=*8>X~ zZmhUu9b9r-;H-E)VN2k6fJ{M@KFRw@65gR-giRq~rIE(Mno7dp0-Gu&-XIBQoYg!a z@dimq(The(yp>3JBP67Q&~bnp!o3zqAD91%U%DU@;rxk!pCk{YCTt3M$V#0KFsoNW zXdQ4zcOnz8Dr!pJ7Ule2F z4KiDZ#Oc?hrlLhWiP-?8H?SH^5Jje@K-f+0-^HD0jH=ZP-D^@Q8Nw}!19SMP*@9rT zKVYxksl?i3yx;mn&>)wP@syr{>{9UnJM|70uNqSRHgiY%sImean3k3NEi$h*o}!wi zai@)QdaJ6)7c!ng34&ETKyvF~KZhDB9$*R=Dx_4xYB^+ckMk?4uA(c$0OD1{9pSzX z_(8oYm;U=n-Wp&#!Xb>X0p#0hPyH_204{xoHzgyS9#pP_$?$pn^O=!DeGri09fAL) zfB()Eh1KPFL_a5Hu!%(<6)gc^QQD?7R5bB|=JSAv(jiA;MUWQ-Gqq0HepSj=wKP=h z(1=_&-V${P`85W-wh|tUs9FHNp;x+s?&POVF3^0Qs-Tf_gZ876>n8cA1p$NIB=IWR z1y?UcTCtAN#quOSusY-2E|w{GhqLc!qM82?^nf?kj>cbHGxtUK%MTUYUcw`)?^8vc zh)q5%@RFSk6J-Rr2duTDB`1jce!c6Yo4>f`6YIaYhF>uM4PfBGk4N=p6x@&bca#bD zF}*i92^Eqb6roL%U!T>RN#Le{*O3Q~SM+8e?qBG2prD^DKjqz_S4{;tZ0AwHX}#is z4Zx3wH{ertjscWH$5+Vj>)`}kv9rV3Q1)x`{+WY1jgmpcL~H=RZ?w7B1>OuN;B7m{ z?+E-PoIe$aBzw7iQ$dkTr|Zma3KpOTs>XnIdV5`GN5Ladcz~dwZcg~6e!MP?=}3Pg z$LCjw9N)|z-;(1tC26!7Ilh`dl(HWhha#NOud{kp1i)pz zjQM~s*t;WTh_OTExlgZR0QTx725`TtOtO5Roy?ZhKSv2~kUd6ag1{-(km2)f4P*U_yjP1Ml+9*=ZQ-2Eai_fZM$i)imxi%ECGXEf(5nL9 z9>!X$1^pZKD#xt?_l0vZ$G?#GD-m=>;D^IlZ_E4L5+rWAN$&u?V7AQ>v{!)Tg9)tB z|Jv&y`&FWeF=}GXIA{*ARWA%ZhvP22VjRHz>AzEsNUGD=hf0Rk0PcMyN~gIK?{ zIKCSGfUl=Nj_-v(;BV3&$6MhKpvEqbpdYHR<9~bS3O_1(Mb@2)cCk#E!0M>&H;zKYEeIk3J z^?Raw9{Nu`vg|chhx&;XL^1WjqL`h&_oaSnoBF9G7A>V#0)W*^?X{8`V^I|w9=|P| zfb&D7Aqse3G2SfTFYLS<@S2_50N=9n0N~qpehBbgJNE&0Xw$?9o`L7o2|)yjexUy;1OxUL(ohPiB3Wei1lfD)rO5 zdu2Z^OpWIN-_YySaJ;K`;+XQ=+urd?4!ukz@aGh6HriPK{gD69gvJm0Z|TO{?d^(g!Sf*E-als?g(!(<+31=I( zQ~1-{qwtkX*yadFb_;weociy_nUx4tW)Wejjj;4tq5n|tM57)0Krgc`###j2Y3CSl zzuq2QGIo`7#6AMp>e$xb8M`Abh)uu&<81@b)~iPM08ZNZ0sZ$wMYrA?gDJIwS$X)W^PqzY3-GXB$$%N)aeMc&kZ+NUa|p;Ky^66B7%}Eg%K3y| zDm(XaIX;~~1pU;x2Mc)n>w;>nv<3?qX)kzLgkdn!2@}rp_~4eMB!Pz{kS90r+(B z2cFR@(g8{{&?0{7jQ7h&83PX3Ii43NF<@dp8G{-J<>tO4=XdogGBtkP&bhx4h#JpP z{xvQ{kL%GPujn0U+HcF7^rTkb6nHC~`tK*pL3f1LCYBwQo7ol-BKk~IzM%1})vF=^ z;K-?RFz~#lns~h`DSk=MtC)!gG5uu8`BCLdMW*I^qXNsoGVxZ(_xE29B!uV($ny2N zs=`WrO~1q&tVfkzRDBV!Uhe>-kT6shfdF7xL<;(;2_ATsiitNrg!ivrfQmDcgRVx= z#2ch&r1xuaichjLdX@B6fd|5QNZ@oh_1_N>HvgZIVU)$Q;)t*~gaz9uSwLVd4PiwU zy%--@omqY6xXo!T0KlS(9p(G+QnHE}1_;*0a_0)H4rjk~O=)$prlmFdzhY8)pUdA_ ztWJqq5%YktIs{0pI~_C!0BdTujU+nt$s{7ELpFlwz(G?DEb^hXCj#Hhux8Xy#eAa^ zct*9xqiT)Y^>bpBkXY*+)JUX>-UAjabhEKM0N-ur;(h^C--JRV!V~iTxP#^aU(+ky zX85YTI}(BzXXG7;bsA~Q{k@uiwgJqF4{5Rzf1UQvL;?+xc=fr!v)aw0se zAc9wo4(Y$2%;shN`hwmGVUVqSql0XY4%vDoO*|S;NdO|sAkUD58Uz5jCrF)X-R2-$ z`++r;IZH->I~-*RkWqRCAlc2vn*~IaaYmV#%~F;&LZ^LyS{kt;&1omw$uY4ic06FL zPLBa=M&6M?FB=LML4&#lJ`gzp)M#qsYzjQUig?khY;=3qO6lF|^!(wI#Osvr*#8~# z$XIZ?8xTovqj4T^>`q;Y0M=Fq9RY0bW4$IU`PQqbje?@BLMk2sJg4?k7hMm$9PUlP z7xao^fX@`~?+d20+U_%sPBQRD0=ievi=Hd;!Pp{Gd?6h+M5PN5ylpNDfm3Jex ze$g27RW)wQvMUW`=qHPQQopFYYIsJq`(#wMAX!3F!G9LUFN`(bD2%&|)oI8BJEMu# zD5~fTh*s&S^p^_O+Q0%lZRZMDR*8Yt5pSeL0`Sc0(FXGlOsU)f^d7u{5xY}fRmM+M zlKt`+>`8kSK%i1~9Q}iQzbci9mbat~zV|N8?N^InR=LAio!W2S6_i{T2>@=f^9W#v zor{1o;rn%gH^Zs_ekffg12alK10wEH;6xn~D>Cya{RM@iX8S`k+~% zQ|hnmj#9683=4X)?9ubBg10H~02GLnfsceY;0e8sj)THvp*}0OI2rJ2@dmyg-hems z4(5D80mPHcf2rV2i2v92L_G$YuN%~nd;h(}y4h)aaIrbEp@H{@lS=(CoQMF{Sd=+n zy~@q-oSqfZ@|A4Z{VHY?(Xmf z6`}?dU!q}Ffc*$LDa_t*Qh>5*!-~-7?0fgi0w%xQ_dFmdQ;}n_t!-7s#kO9HZK*nPqRwCSB>S)HrG394_;{Eh?VdJC z$5iPv;Zy>C>VlxERSy73sk|G2(Jf}_7NmtY@R$>tZOK$M9(}Brd~~||03^F=w6jh9 zzD!-cvQ7NHHu3w~Hn?vx@jIFn$2;Xb?8L`U2s|CmO9Bihq&onw=%q1$>?lhB14`vK zzNCu1?8=P+SRV;{D+Tyfcuy9ft0boqU4*5U96ego*o^MP26V`8g_ExL58-V4+jz2I-x0=l18Xt}Q=~WgK|4Ma zO6FGKD@VW5pb_wwK?Fj zor{1M?HmJsW#{6J;@j0O`Xb<@US+fa_-1$m#*zO9AWbAv0KQYaf!_^pz?I?+jFwwe zW`45Z6p;pzOrbGCxGn)MyFVQPe9lg5`o9X_^(xD~F4hsi{dSH4-wa>C_rmwD1s;u( zYz4w~(sO{nwDSmn29Ph{@ARtfTY>L{chX)MDw?0H!Kd{r1lN6(b;+5!Q_! zPrDkk0OFDxk|!`E+YTq@UY0MTQ1SG;0za{H8$e$8-Y5_gxVcB< z41F&W*u;6H^oG>fraXW?UjX5WkCw*ar`RhoeB+c^)Q zEmVLlz`t_xOU&Niv2*-WfymUI|NF`qWFS3WTH==iTZ0^1fZOzn!vQcD*udyPvw*)X z-tgSpdetHT_)ZZ4zYJfM&QFr@0TqT8RjzQ---Z+Lww-qaD%}K`2Dq4HFz}J6xF8S= zJx~2#ul|_e~D!3{%G+4h^|RNr?o28||F7EtL`08LL?Y zW)|3)sde$DZ%aK|3a~Z`06>#Tz5>cTPcA>SeMX34dU6j|uKT4yVHWWI1-q zn_%^OFrxo;CYxk-QgL3zf1rH{}&Eg0=!~pr%gzpE#i_8{A2>()vq7uRZob3 zHtnCvgK7+9`wIpAGGYPl5|*TZVZ`Va;U=L(P_GEHO;D!@haQZ6S}_S7z|4tbtMl(r zB%=_lmH}+Bv%>&jZIJgJfu;X`pa?-QR&ZlSqFgS;sl-NLb<%#hkM*$9n`ACwZI<_5 z2X$&q0w0t&o)c@T|E;85^;VjHqInXFYKR7a3wCzs4%P$mKIEWI2_8EfbgwEJh3Qlj zELvb&KLItTpQ@a+;s120^1IIW8-)b1Y1 zA6PEq&&o#)4#@cPZI<&9Avz~f*308INAU%}cZRdZ`gtk-O%C!-c+}*`cKMvPZ>RTU z1jL?d0w97*OqAW>57WXBy_#fvil&+XB12D3BEt?39eXG^ZG$6tX_G3EFd6uPL|weO zO$tc7j-2V@`GVxc>(CE8xI6Og^m2k=)(Dz)5%iBze7=;HVDSI|0n;mO7td-d@j9jb z^O7EcN)PZIJ3Eci#j;3?_E`jcN-u&J_+>|41bm}-10&52-MeYpu3?KKFSY4(qy-Tu zACy;i>vjmJI|zf{~5<12c_Nc!&wB9hW({kl`{s?mRrfS@lyh-6aHf&mG9 zE1df8hXm%w?_A+WMKu^w*{|O(_&{+B_~}P62}_hURTLPa6NMZK8vqXJT{~L*;+iAf zQ>SepafmR%ogM z;7&VzWpk(*-}!-1)HF{2{ZQbHyHP$O6M*8FOgNy~q(q}ek?I^^yI$kth%7qA+dB8o z6@`cen&L&Oi}>)Ai!0HUm6N^Td3Ia4500%rMe*l%IhQN?z^MC_-;e&ZWKU6o9jUw9CjWOCp)4f@U zQdMNVu-pl8oKZ5W73(pthLiP%ABS_@YR!T5PEv|+Nk*c;ezWQ zW$&h7l4J_=bqe!!3Z2?#3e-Uz5Adj+G=QJXrwy9@g#y;PYO@8YDNSOn9?i}?rod0> zmB0sl*Ulxt55gC)+UYE<7ho4b(?md!^C)#VAHIN~>`^LnlgZiP52}*cYZZlRe1{CQ z`v8pW=Kvd&0N%jc^h$gH$Q19S9B%UZM)A*P#9yiS8K6#;@uoK8ah35VGQL%>dNdio zFEZE!oC$A0DbJ>=Je#WWY^ut$X|g;F41IllsCL4%6LlL6oO*xuH^;}OgmvXGH z%CSD%0G!FB5Ni=*vX&D(&%ont_$`fY7BK5?78{bbW`Rwn!P4oHm8$omTp>UFx; z<^7Ki>Zl@^_=oZi$uSFf*H{azR{ldc>k|BQ;hih|t`x+L`f0(0KMy7C;!Pj9cJaK< zlIeBo@Q)>5T3>7ofHJ*&6EAeD^#phm!~(0J>?mFd=@OcSrlbW1-| zu)v@*tL+VMb#n7xT!Ujq@7j@mEPQbd?%VZV$8SMD5cb|urfMn{iA+p%60a%~coT#e z_fvbHuzF-oyec*DCQ>_FQmdHb%f{*`X|O0gGC`67uv@Q4vf*LDllC585O}$G3;3b_ z#HP9WvDa5oXfZz-rOL%?7$xaMGtaI$(ra$i(nKY@Shn{*EG!j&%~+6u5^e!M6rdZ$ zv)K}5T@?kYO^ISf8D;5^l7w$koCxB-AM$*pR0eKShXLH8*DZ@9n4vjpY=3%6G^;Ns zoJo8^KmBw)KF)MKr-*cIdzl^7ma;QSL5eRD3K`KY;(T31U#=fXb?4rs8A;98Nxe{N z8~o`J|0ad2>F7jsMptmJ9RD@^0k5V%jvt4={`;Y>q)O$8HZhnYh!Q;Qpu67?_)$3Z z-wz2qywu~U4=QjXtuB^1DzKJHQs&MsmYFE9Itr$XWxffl#X7AomvSL$#TVieX{lr)u?t1NL(7s}cGsZgdX@Sp#Q~&*tV@9CG#i;;#DU36R1KP+RKvnIJ<7D^) zUP^yKKXtkr-@2X~c*T2Mic7#7Rg(z`&h^00BdonM^{& z$Ye4z$qYQi>W|;8IH|($PjPr75L|y_CijZSX}KHTFh} z7QFBGxAtCh_Bqcp$=K#zY~_4r&Dy`c)?WMH+WYKt&OYZ6lR11dvufY1aI5tSTo+Wb zvgW!*Wjz^dL%f*EXYmT$5#q&ESc_NSo)9m#!{ZhBa)=ju)Z^iHr1c5y zRxdUclHGa*LL=6nNANNTHxOG1nTi6jW5m1)^$LXMtry!2nZ5#{t?R{9a*J2s3lR3j zc6hu3p%?7k(?>lXZilMy^XLU*h+$3;I|`EBT2ta*su#Rv@Qn)T<;LHr_wN}{x?>^i ziOq)0o&q%x@nUKgi&tO~M7-EOkB8f#{N3(oV(4-)=@rk?xR5BW#Vb`X9Lk`3`MLr3TXXlla&D5g{JYmlwq`0kj(JE166@UaM4 z-4U|G>vJaPJV=9719m0kB~WRufh<=AJ`Bk$g}8^H&RsDV1yx{Ax|{GGsB96bHdKC^ z22`^Kxbn3;4q5<|?C_Eo+e^)&ih2=(cJLhKdOH!HhAgLId7nh^v(*EdM za?#qoIvby3+8fnttu1M$>dbXCQr4A zIvm4dmwCJbt3o{g?I_RCR#>si#WcDphFB;@u6kY!m6BEz3tBmclh#B;ax`p-T?lEy zPCRiox}A z-XlHDxIr&BawSqX2T?U4JJM2&CWg|Ag<+HHPcOsCre*7xQwUmr!tE%xX1iH}wOqHj zwIt6)m?&H>xK=2%T`ov#$UK9dT`;&_S^KDhpdVUsAs9V zSPfLM>craw&DlfdkBxffoxyH>YS$hg1iQ9qtZ{v~9cc@N^4drH-0l(ug54#l-Sk0z zTHZ46Kaup)Am(W?b*WB*Fgw!hgCE(gw~Yu3r-lk%8MKx~Q+7VgYne}0nXRQ_=RrEN ziC+fMh<&gR$7q-xUMQ9QYzS9zwIRGFIIXQ|m1u~ft1anYF=-9izd_Hs)b%P3D9uI; zC^7Yo?Ab?uCWm;jDIO2E!|SFJtH1qzpu#ewl^zR7*{gzFtg!4wF(EtLnnvMxhz1qY zOg>aEx0qV3SQ})8hTGxh1i}!rfp`?Ka4z?oi#`VhT zr2bPy3d>wKaf*p*#njY8RyT12*DK44^yxd%p~^!P{TOuV7ctkXXfIUJRz0p)*5xXj z+V}`qDX?pewiR+csL>(SF zVaD+U!`w7Wxl~)~>0%+nvY8u6x^rcUCCJ?g^1e*mA!t=x!Xzykv>KFyj~n9L;7Foa9ciA!(@OelHU_L;6iE8(OpjM!8AShzUFz`) zTo&TRG?kd0%L#lf#EX5$;}zH!;>GrRyaGQB@nSD~yaK-n@nYm(*?-i^!2{}N6Fl2g z>$B3;t3c~QEdTBB7P}gB6U5XhcB=)ai+#a@W!<`IP*gU8ypXgLN_KcQ0*Nymr2B%F zohgD=SvCb*E5O|H6W0w<9g-vBcnAV(V#i zruz@WZVJJmp81^IR?`ESiCu#hWtiY86fP!Fqb|23bpx=SAy`GqX_iNw*o79n#O+W; z)a>x0%7m&+--)SG+*f}Z7V1_lHo?p^h#hOeWx6r0yja&PfGx6MwODu|L#4CB^VtLn z#uGDTTFUnsh;|TDhFUdvZVD4^hZ`19BuT_>w_wHTMvWY&h%+tNAQn8mPAsG?D-@F0 z(zR+WjR_l~3iLqaEY|1o3fvIl#Ws38+>W&5#}h-D#7=}{*S4;Pp=iH4HQVDAsDaQI zTL7890*fKy#k_oV3akk6Vk;rjS6~%{zE~S%@d^ZwuM_k7*p~^{5rMv#*QadaR0U?5 zUbR>#H_wu@@>Oe0H$c8zSxI;`g!hSsqL4&+uMhE8!)|~)2|+v3Rvb?Zy&yILQf=(< z<8dKgY?8+-5L$icCyuzC9brh?(!lKwUc1p6$D-tRhkD}ZrbeL~U38oU?R6PhC6@no zq;)!q81fKPKGs8~#6Q>bX~XWes<5(mu!b6{K_-)qa)_M_SpzCCEyRn-BP||ohZjO1 zbb#GB8Eg=xp8`<{F;8FSHX{*+)~OZ?MOl*NUU3vxFQ1+az?)LX3gTCm|UnBL7SJRSF7vwkoCZiIa#euwboN7%z4Oe_@DifL(4uJ7so;*lyU>Ay(|e zA@(}h4Hm2uyU~KRn_xGESg~6|>{i%z3pR+|3(@FLS>S;XFZPH9?fbTmhuEiKdn~wA z>_rRK?uY#xG8+oKZ1GFS;Q7Zu)LKid@P=FM9D?EHzgn@d^UvM`tPQ&Lu!ay6TW-O+ z%V4WQYzwR{1oe(?UkFa5OOA)g?ZdDeLr`q11#`25y6QMed21-C*dIcy0OyK7WYP6v z+NYst@uMs!dxw021(%9x%_@zF@RM;t*5cK$86mh5))|7=!1Q`K3i>$3-VoGhH)uM= zis@ZnSrZRFymT7DFcO!FT^cpSFN3JC*nKftF8i!SFFlruhbCDnrnZo2aXGMZjE4`$ zF<`X|=OVFC#7k7ft!DBP<)V?zT3_S(#1Nbe3l?)%0BYs=m{|}kifK8|+@U^R7J^xC zF6$&_Pl){v>_7x%*@{>-lV&S|YM&2>ph~LQidgcs!)v((v=gG1 zVvkv{RxJ2=^%Dd)lP#@PEq;%cWR6%3CKaum)DQ}*CDhgmCk?GR%nr}@KG4@7dMpUS zsZY(M9A7d~wU|Z`!)d1lwA-1YijB8my_j6jROEMYvfWuyQPdkIQD7RxTvH935rSeD zLZ+fXeTXMZJG`{=_>gsdQM3h7Xp^!!K7r_Ihz~xz2-|1DIp_UD>QOQC^iRD?&4=#bgew(!5A(6 zghiLl6Z$a3jlpKI9d;4@jESa;?X}>HYy{4D7L(r%SfNmSveYtRQ-&iR#7T z(4La@=Mr_|LhHA(F|1DnbXwwCu^S*&T#1)K3Kxr_+CLhSq#`=aj-&Wr@Y%d5*JgQ9 z&Uf;n+&X9D$~^_iLZY`az{kzKw>Q>SSA;?41vWT>^2Qp;$CwbUc!*#}#> z>|HCYSnPISh3s=x_9UUi`TM&{8)n-Ev5;Y|Rg_xMQ=lPwU~~|Pg(Y9kK)%IoSsk=; z^~!4vUKKJFv1*4V1=rF^0+E<%W$Pma##?-Y*g;C7Wi?e1Q$HwmE!>VYmr2AhcEwz; zVwpo<*y{1%y|3aA(feMrV5?$r5|5LXc^ur1wAe}GxL(CZ3|Zy+>if|LnMKq>V#h#b zE%Z{F3+Ara~X7>+cDm~vA^p$dxGm#pBI0_-O_d0|%J z)zBFGP0(FD4;5-NjqoF&3SVv-{49y>>J!=y9i<;C;g>{r@(*Z-muNlcMyN1v9Eg1@ z*Fq$=6)N_vtI1gyhGJ1I*SD@#Woq?eQ7zZEt`@ysEUM-DR%&YH`4D|8rnX=SCw7Yk zbCZB4n1G1JJz(A*Qmeh~PmrgeVV9O;>d7OEHPgh)P4 z{C0@>K}-u=C9hcaMW(kztOFwX1o1mUw3sK)O|Qz`>q}=ni(WXq!V=0I5k6yqaIunG zU=@r!6-|U*D+qU06viBOS`KZfa4FRTdoTpW9<1nOB7zxvQoS+&y6fAeGRmgil zY3)$$4m1aM8cPhlE;b%AcT(V9NWB2FBTZ9944o=A8&YeZ39o_F*RX|9SzmjWV@%H$ z3o=gyWJO5`*22CJg8a85&00mnmBoU~EE8J=QHm<{x!eW~{@dY+H5Z1&wml@Q3oa3h zHI;%Lp2Ay!zTfFG8;Pn%A{?kFR6QutT=9kwwk^nE#!`$O#mq=DCzb7PVL$Qf@npzu zx+|~^I#Q>t+eRsPC&X_*3$m|5=x&JffMPgl-8M@29_Z*Kj)xwK`U3QZB>LJd=qqvu zG`=XnzTzK%CKP4YZYHH94?=ILD7|eAxk~&H^wuF%uHA$kDLf1ve=sFVBb@=L>R@`; zZp5Orz6QPHkeZZHijP4j9a8z)>#!}=UC@-_sb6y2C}}?hy?fXxSQaS3-$B!UnMCXZ zQJUwV>Az$;8bZmQhi3lrN!fFvlzXAm|6Qr+UM2n)=*)kw0e3?d4z@QBW^Ko<6 z+s2r;nS)qQ(ls2*(%YMxyf&|6BkRiRf&MdI<$#Gq24 z5z|TSk?yi{&nDz{?x~~~&JuPt?|QkVk=vsHO#OC2t))xhHeX)LHiTE1R&Fwumh8m! z+ufrSSPvah>c4x`bp%2YuDv^V!ti8$rg`o5QA!dux0h*FAq=b7hU=nU;mV`o%FsmN zlw}W^k43Yri7t&oHG7qBkqo!re%;z{xPBV+mWa7O=a!Q0&!L@d*<5j4y56sPI}f*A{;Sk?xb-*& z2jE&p%=@?E{CBwfcewrWTE4$p^WSUzmcKFce{24Gwc7b`kGI$C{l~`dtK|o;cL%*Csb1Oj%xH`p2XXIt3d|1Omv$fd&s_Fb%Wway%+rs+y5#)H{5$Qhr7PNZuVaDzyH|U_|+PhhucqwJKkQKyMOt)`?WUv z<=gCV`}cp9dG6JkZ-(1`!<|Q7t^PgS`5tb2!)@ooov-czuoX~D+b4#+N1+=I+@lb4 zy^8lJs!Xq5%=PLC+mYU1s3L|Pdt$Cv@gBvAC=~a{=^lmdUqsnVf_Aw5L{?pt3BNWk zzxwm?;r8RhZSU0@kFQp~hr9iL)$I+porB(?pK<&;&ZEC>ef*#CyfLUAD~-3{2e!A^ z^>Xvd;U1R_ao!uQ{~d0ta<0^Q*82pia#7a(?Cg8?Ni^+ug30JCEn}>|;i* zmphM3Pv>#1GdPb=h1ro_lSf%@zrjPp>~GgQRDZkPaQl0>?S8n&%i${DQ~&;XPQEeZ zy!7jMJ##2u*f&gHb-hFR>ZIO10~#cWZ~3_~cMf&E#GdQr#tp{= zdbP10htlgP*E^^W9?G7VFKItNhvwSP^@6=azu)w$ZZGLyuW!Zv4SGZ0yVxH4L-$cR zr-)63%H{;u3)g&gVy>6-KiAU)&$XeL>*dOq*ISb6<<2S6(>di7h!?UShlN8Ym4a}m z%j^xbf^c9+VeyhPO<26`{8VhN@mQm|#B}y7YcAJQ-yCdPpX+H1&|G3}FV|doy`i`D zNl(qCshhH^S?%ysu)yJR?ftPW!jKwz*)p~-OmX4W8vDwKyt1s#s-m9CPuq$euwVoK z?NBXTEA&AA7j)Eo;UsvPb?g!-ioM~c+`cKYp%!gTJ}Y$P~T+<47v*>55Rt=!}`CFVKDY}JaXGM1+TY9MMRcB#iJa6^a}yV2tn zxFf`iZS!~q?g{Z?U+{Ri9jcR;BY0$;n3ux_jH*Um#k?H$&F{-YyjVA6ZK}Z4AzsYO zSEsl|= z4W&LM1eIWB2=agM7)>b7kdrKEzr+zNC!dlXY%3)UY0O_Qv^0aGMAGpVWnV~9e%68t zs7c}+b+*SVurS1n$(rfI?NF6&xN6UUz%dXd6&nXxE5PkY^~Ml`hl#n~VChr6V6Q&4 zm+RcEG2dX%zG<}IOy?%!yq4t}vp5bwIihq1|LsuQ>@Ux`8ev%pr8jiW$B|@2X||YBkKlVD@lYOJ@kpl8*S7A%=*U=T`qyfO3-#%nq;8cF^4r?r!n?lW6AEp|)zRIJV{GWi7g(TrYmG zJGJIost_58)mZQnvBef#D)tl?MoeX+z!?6sq%c5AuN2yB(G()(_BNRD391xiwJ7^E_}8tpVmI-8FI+Y z!FetFHTYn5naqX+`frB{zVgGv8)56Co<=SWA$B5E){xtyUeYmhD(O92o^M5aFPH0G zTFIX4g?ZbyW4T_=aa^wfBTP_Yu9rJ!=Jl4Odb!mqu5L#%Lro>3tX*7h975(EG1tqL z&-EDTYG*OEb(y`DzZLo|IS(v2nBGxl&#p6qL*z#Jj$vAJy@OkODOyYFP;qd&-h@y# zG1tqr$)xMbd~|Z9y1HIcI@inDtBLl4o_!{0MkRZ$mz2--4r0%~xD@7#rDE!4dXoQk zXwbRgPyoBEli|W_(NkV+*(-Ae*GpW>^>W2@y^!l*F=a33`gg>9b*81@VlzYO#De$K zik%6SmBv$t3BcyKkb0Szk`&JIo**e!NU$_ZkSpKQ z6IDk^?wd@biKMn-vFJl<4RwJ#{`xXU4UK5O+Bz}hAa)#7)^eUY>Bk9C&($VvSuPN7+(Og%++B3tGzv*`c2A9#)R7b?_Xeb?6+w5OYl0YZb*Q3~tvNZz8*6 zCoQ#pZqSasA-Gi1Vh@yCbFI)8_Mx8p&?>I9T`d^1Z;nPa#n_=Xdo<>m42eAm3pH@9 zWT5Xxi#&rR{-?%*_vi0@FGMG_O}*IVkQ$&~fj)>6wAe0>hua~$+ddK+CMl#UVeYHI ze5g=jCDHH*MX_-av~oVWCmK%rPkEG$i@i~Aq-8Ypnfk?H>g|hqNrlcXuY-@qL*@E^ zOHWP9EFh*aUe+q7Y%KFvxwz>m5N4`cF?Gd|=|d~n*!T1{NW%1%8zMC^%h0X0V!n*9 zU(TIM1Vt9p%x_sLFgL`D)j$@nzyb(;v4xPuE3hcUi`9C(0u3QvY`MoPup-2Zt%S^u z0xb~s#o8c?hua~~&ex|dtF`J3rK?F0GG!usYPIF0D^p zR-d}GK6P1r>eBkut)$eUK6Pn*a{Y5}>>v3H^%ffoS-ll_+2WO*9cltkA~99Xv~nX= zS`w`^t!lB=kY+vctq`ZbJ7AB5pxDph9%7E!3k!viTiD@+knbgSlo*p@&s(r= zh_rWqbk6_^wsxn^qX^1{3KNoRRhg(x>_o_VPJw9<)faP5%(bl2Pl>|9o!EV`0AU>2 zvZm9l<=Q!~Wuq-<<=Xku8$)GOBq}2|8L|#kU}}gLQ&BA*ZigDu)5ozZrt4j+rUJok zU24~!rJjt8>WjJET=h4_awT<~Z%J}>bgd+JtrIMF1!^pbjTEJ}c(@%Z{Sz@4^q=o9b7#l=ILLVH$OL2Up{Az0Rj z&quwa4<}fXT)TTqg+8>KO2Gx~Ixci)uE{(>nAz;&x`J!CmRgvKhaX#eKI9sPUOEG%I-jH?wFmJ>SKl#xE(6YSDqwP-)8)vm1`tvNn^Pgs1{oV z;TB`WyF;|tH8FZ4{6>qe<-Z+XLbbxx5QP`J$%485Rd(ZumTk1e+8~`i#6yZ|LUzdR zO&<#mIhq)HMr?)!bB^X(!6VG^rB&v(k3?%DgEcXEa9IZpM7=3NPwbRRdM}liPI~da z@r4A{lHw~vH2>{T)mm;EPSx&+T1Sx%_YxZql~wJ*s3#!}C8lDRRn7I(S=bYEy<8J79M zn9ZRL4y8A7n0ix&sW)esdJBiCw|tm-ZNt=CAN7K>*NUCu?We$n5biAI&RDBJM~D~e zgsi<4xFy7kZSi;owuX2y&C6x|JTsH<)~9&Q-~My za@1wzs7uR{8(fobE}NyMnW+Y`8z3vX0=I;C{@bB3^h|l`qY#$WcJDCt4n)1Accxad z=X&9^kzb>YA%PMVCIwFtrjB|P>`*PLZV7ELkr?`3%x9(ApcQV-xL%l7?AN#_Sds>@ zkh-Gbv8I(1`64G6uTc7JQyXZeT>gCEOJM18^3@-&<;1L z#?!)bbcr7h;panqk@-5|YscO;O718l{7{d6osF0|pfe%+Ssw+0{g57LhwQ&ZQRE4s zD7ik__=!}MtH6XUsVJ9fB_df*nrbeP;U?Ax(Q3xmTXfE@601M2F;Q-G?MI}ZxipAY zz%CELPS{N$$bUOjv+F(?3ZkyXmBm7i>JmGo^)gyAdp5+vO{@)48O1v+y0#nkWQ-Pn zIz;o|4jFp()?9WP)3Qs>Vq2iH!JAKFi*&gYo+Gy0f=k72gvy*KpW2>aYiMyvB(~Cm z4Pu@;*G)?8!opPOb48d_>}HEJ%Ze{ORa3$tOeAezahP`878-4$naEGAlZdMd@snXw zLQrffR8|@{mCS^$mvgbZW0r}3suDCh|Lst3?nX<)F0^QEl-M2k{fNdBp$gHvsc6F1 zP@SaZW|&saFHz<-kft&5g;2r6?=5e4H60BimJCRp zZOXh(sWrGml3amzMZ+3C2U|k8-YC0ox!pF61JnL0MK%rB*>> zX$aY&Hglf}1+aN8RJ%b;(+|ZL)48$Cuu>nw@S$2DUx1-oAg@;}XgG7*7Z<9ADyT{# zVeu|ec~{+n7G9&8*`bCykW;gp5Q`DA%~7Y6Eg@*y{3}mjtG;MgZEc6t?!A4_fI!j# zVNz`{75=%FiW7S}6;)`M&>A@d(i)V zr!|L|ZD|{nudW`McVy<-5ahodp6@D9Cq$bDL2!+lJAwnnQ?Z!Ft2MU|T$0EqR85Q5 zVt6h@yx4q?hufhn-L9rSrcE)oYmW@8LcEyUt&`mv2z@cPn{$t?vAl`H2Y;=rBFSW^ zFi8)TCzu$tRHiBA3HHYX(@bQyvb6%Snkz6f#EYFmSCu)Yrw1vzwbpiZi^7Dm1Rwx*eO$3e`KglD*Prf-5K9vl_jElS)h86GRpLA`F09F`eVA;0nxv7$af}Jzmp9m|ttf zuJ(Ai9Yc7M(ht!;iL=ZdTI)m;*==QMsf-mHE$G#Yxt?YhJJPZRy(Ot$?*5r~!WdH0 z24d>pAv-nb*^@lit609EXOE{`uVVR<1;Tkl<*UL^fjE(z3DcZhI5nsiYG0jPk0_1% zg4fC>xqZ=plJ2iIJ>Kn9KrTSl#g=(I+>W#<#}b2{*i@*ji570#GeCU0Xbx+LoHKTm zYsnf;Bc=+Fhgc|9Sz1jrQA<j(O+7 znp&GywU7= z-Fq1A{d>!yGVK2)%Hi#*G*jOY=y|y3ukeH8GOX~pH)h!Nid;G?hM`wX_p6Fkm%Ag4 z8h_~e4^8SJ^pZW`NGUdHLrqSD9=TamcvCY&~WQ1-R@sPf4FvE z(;J@8sqL>hNc&5+=^*l7m3CGcw?RJc6uvLgQ*bY*%U>dH?3)5jhKr^~nh6)pjZ_O4 zZH@FYTr~dJEWZhapNUlU<}7{{;ST6V=%FNDIx{0xPt5cmK7P-@1 zfw%1$7=XS8?S!6yz6-hh0O677kAg-+W1%UK%cmiq3!M$sK<7cLAeT?5+B0w>G#NS> zIt4lpa{1YBXS_p;p;~Ae)C0MEHhC?8&Vv?0i=oRQm#-&$BeV&+3EBeffLz`-Y0tnu zNP21fa>}q8YJ)C^I-#2&PxlOE_ztue`Y!Z+Xmlc18_$XKJn^E^34s>DMcu;jxP$QH z(38;aBwjj`PYg8YBy2*DN7@S)Rh=AY>O1i%=(MWd<%O@@osN7_4`@<6+11o|O-KU95Mpjx=sSK&6NnS`N5 zvjR<>O+BF5kru!`-Fm{?paanHr)TjE;1$p+Xj2k@JK@KnUC>iW{PCqd0~bQeply)b zS6*At69s*)I}*8%>!G;YQQGIAqTX)eUaAmZ)ccQOFUQ9B?iu()=mF^Xxmi6I6K;dH zLr*60D%;pOS-BP75@`oqH2I7`*T6-aBW;6=_C|UcE-I0?XhEc9aMAKe9dNI&!c!=Z zXfNdP&K0-vtnzr550}fveUTQ{Fn2(kBfSiFI|`pTFT>uhlZm@yexUo{qNgI=cMceO z5pw;PFJQc1NS&b3@5|z)Gw1w3wMo3fDyxh(YSG?PEK9pUTJ3o}(q2zAozZ&;?Z>R5eK=(m^m-OT4 z%NVy%sgZF6xqdBiE1^4xyC;c%@Pm5>9)_NR9*F6tAeY{wsUEWLLW=vBB>wxv9e`?x zQ<||W@n^{M-PnYE=xfkp&@Sjn$mO$FQ7)(jS`B%;_uGrqZ6o#^EBs)jN8q9tA(s!u zrSttrFTq9AD2M1kq?^cJbYG+c&B&lTTe5O}dG(%wTi4JAYbkG67C*I(^(NF!+;@|B zrF{T;5ZV>#8MtV7q({1`2h?z7pv&Q+tD$S49gw%nBZQxgv>!fHeP4?o-gWD1?ew3c zo#gBKfuCZ3DQ-@M_@dr$v25u_M24#`-R^_vOQs*`aC-{t$0-~axn%k=gJQg6$@KAm z$3t=H=!5h_$t4@r8%Q6J7tMi+`iiTKqz}1^HbF(be=n9TeSO>0E37YCi}bZ=k5^b< zm3Hj&q2lzRWs$yhEYi1(Mf!5EXw14m`a-YhWJsTc)kj!G$6b}pua6Rb4B7)-w?2y> z{~^u;(8JJ9=)`NV4Sg9Jdu^uIO*(xERdg$)&xY!opCWy`Q=~6siu5H)k-h^dnh)uV zg!)XNs5_EA^C!}0{6tSe`V`*O4`=x*JR6z=`B(4MMhffeb|QVfPNc8XiGB|0OK|$y znzyTS#p!!!B7MnBq%V+(^nou?PbB}wmGVBx^H2)D@Qq9_PK)$nw8&q4 zmX5-D!C9ntl|{EhdLvnH2aELnuSl=piu7i!=(EqP9ru;Uc}ADAId|BE3f_@|XEk4~46438c5tyd4zQTW2D@RVLEgU`nGy z;X9%2&`U|Y!Ye-!NN-4qc1O}{Q6jy@e4Une`wcrIb;`AbjXb0r+dL?7Zrvf#=J>Jth_xSn0%{m); z0QwimC}7 z!zhR6@8x-N8}|>Pz0jE7Ew6`c-V1p;g|(MSw2(9&?_6=(T_n;*8c{=H*YkC*bbgE~ z{rLa9(E(ie9R+-P0c$6YAJQM($wQ>D_6_+Vyxsv^_{IXh8QeF@+hK(L7DCnN4F5Lr zmIQADXZLMKlR;{kuLaXu2O-ZO*Is}WYhOT$wKpKediI~;l&Oav;%{y{8hqte~&?XaAeB z{?&M`O0dSuq6BOH+?-(9*E9T3#}W2pBx4i#T?q8N-sNk^U(f6v>wKeU{*KoopPFFJ z2igPRa*emS3D$gDn_zti{}u4D#B01gOg9q5SRz?+1t7yhoJ23VsA!73I6Z6Gvq7e+K*E z{!*RfukuWtnB}MPWcwUKd9@N^`OIZRAy8`Nurv7Y}dmaVKW!H9p3?GsBC~ z?@Mq4c;dS<`K7Y=?hLO4UpFdqo`o1gw1{j{gm; zy(5lC@J5FAkvM)GSbIqvYkt&T7sp2<*FF=+zX{e}6UT1>Yu}0Ew}Z9!#PLaB?L%>_ z`BnR99BY2nUK+>mM*lCtlZepxsRmz9dmj_A=HDYJPgTUTke>wBD;d&%Klpd3Z-?uH zHz4mIU&%iTzMuBn9PxJWw$|z{&F~oX z+Y+q#e)8N*uKE4>1ZzI8Ju8#TA2ufCI|h3@68Qvhbxo#!9C%}btH3WMSpIZxV$bI1 zq&{jt?S)cnslD#vzxF)|32T17Cc!#?Yaf(}k!!xzUMR;WlfU*wIo9>I?TxaC5hY!Z z+CHg>r=qX@QUKi9~2TEkplY%J1{v zYVggZ?~d}{0#DevN5c;75vAL~Zvlt#H=^_fupgRV{-l8A-`C8~^4EN`Bf;{ooe7qI z+;L8(FaLNZ!SWC70SkGC@v8k`j@7=}6Xsa$qy1ry)gIa-=2-3VJIE&zq4xNT3gw@4 zex|ST*Ss&oDo?iGER;w4%H00nVDD|T*Ek~7e*X)6YJ&f%ke}>j`_aPsRr}H0-uEl$ zYmb@Bw-L~OGsjwgXwR8r&1c$w=2-2eJ!p=#-qn6I$7;XJ7H3%Vwf3U9{HK)X6X-7| zLhbju*MZ6ZQPK$?5B9^)KPxWI(rZ3@eo2NkpKea%YL9H+TbK{D-z(S*>v`?@a;*75 z`@bA(e$XB;$C@9sAI!1l2kixOtocEE!W?Tor~P4$)t=g;=2-K`Q4JZ^`fhfDHJ@k? znd@sl(S9<=noqQ+%(2#g+F$1Q6xvUF%p7aJ(Oxsh)yTE)%(1NxFUjy9Akcm~m(NCD z`_de1{iwZZj^`rR9yQ0BzqDV?vF>MS&zfVcFSUQo@qE&251V7HH?^P5vHVMW`W(x@ zw7<`>uCKJm&#}g<_WL=O|7p*kg+W~$*SnoFrKL-9c?E8A;Y4DF}AD90l_$SoAChGqT{2s8& zUpJ;yS_|G3`jh%8~9Z4i4lJhJd6Gb?-P$GJq-3kJ$59caw3&Ik7;a*a>z6?1zUpV~L(SmRTB(j04iYA=~% zjZf_p6_)SffPnm=Dk$}4}?9ypiFf3+XZvHVwi;v9dI z_V^iiHWBLYe*k}v@^53@2>$^5&&Yi}{IB5qDUZ&pl8<^l{zmz||K9+95BRZY@9p3} zCOyea|J~s4fho4(SxQfRz7X-*;E!Y9{pSL(AMywF*GnB)`E@^Md3T0&KWD*}8NL*J zcY@_VkGEuU-OriQmSNq`(LTM9XIP(S`}@NAP zUVHZ(>-t@L_#FQM0qp~Htp3$rK*yTDv@g)H<}2+jbgcee-kxDyuP(*@vBaytbieSa zBd>mL6ALO`|LOjEwtsL$X$9^5U{apdh4xp!KaL_Ve`%Wpk+W`chUT$|t_MAB$57r(t$8P~^kD22tu=bQWekWLa$Q(}tYpi+37>$395UncZtSl1g160Gyf@&xO8V^oq} z{-Hf=p-y4_sr_n>HUIc8%gcYX{?y(zmutPLJ#3EUKiUiDSo4ea#5vaaLwn;K>-?cT za*lsW{h$Az;VU7!o_GbkAI#|jG@>-}H(0-eF>81N__+j60zaGJDd0T`J`a2#!Iyx4 zn&3|G?gW1r{32NA7v+Bw`1RCR*E^c;ZU_6}>;JZ^vihifCnfl^1$~`g=3blW+w+11 z>;A_S_Q-`i!g^%m`V8y*vM<3pzf^6=Z`A2&d z9qas~J&TTYeLL&wZ2j;@wC_C1SB--D=PwHFt@HEpq&?L>**?bjJSCAoUP%9J0e`Q6 zUn*dY-|obo?tk6QUPc(lh?2(h{sa?Mns8kv*ZAI+q_^>$=&StMe#_9G{_C}}ukq@? zD=Vz=>c0#ttp3xUN-GXn{pUZRD!KYk`z&3q{?lGg$Lc@r>2$3A)80?=`#*50I?cWUTuf3Z=E7V7OFdfT3wHMQ|>Zg5~j^(e~o9S5f_1_Xy{_WF1_4QxzlU(D`f09o4F0l4+ z!Z^Zs^j~rkR(<_%X8Se0+uaX)h^i9HD;xgFM12pa1ZV@Vg4>HD308EK6_earTm$IrKGOF8p|g zb$?}Bf;C_6OR(-2kJ_B+&mzAG3D*7N$q9Zh@|g*q2VRh1jmPCldCo`PkjO6rwne_>N7jo?h_VUXAwRhRE_9s1)$Zda8f_I?kzq+LQ zX*~F^Aqi`|YtJ)`gXeSf@3g;U@4X?$D|i6>K*S#bPXge+Irb!G8m8r+&Wv_zw6w(yxr^e+0fDk&ii={E&No6Tv^De?0v(@bk#E>{Nc| zgTG1rUA_YRLV~Xa_dOAwA4>m5@cWbeJ_nwLJzuXq0DgTU|10ne}AJ`8+|7cHmhzs+T_J=$E0|Nf5B`UG} z$A6tfcn5Or6?gsX3-)hDa3GOud}=Sb>udhko^r<@BmK4a?iqL^5o(`L73^t#T=9ua zU-RMfTQW?N(lwvVusu&pu;#~SZq4MHAKPxru;#xz60G^}*#v9;yDrIJ^WVNiuK91= z*36!+N1jdewSF0wlvmdyD-x{s$@bTW`Ad7|y?r!)Y5%-q&0pF>?^yGd_R>4ne5F10 zjx}FtzrJJ5SK4duSo4wpc7%FB^O5%2yIk{;_S`$xe5Aeij^!VE2f(q;r+Od2vCf}* zC&2MN^luaL$wX+q`Y`x<%6m=3-;f;rjS+vZf4Y)r7~w=>C4 zOGg=38ey-VR({dsSqFaOuO6)xBL**`O{ z{?>TVI~6Y1c+k5Qjx`?ij)h~52fb_ISmVKe+Cla-9`r7V%de$B{u-?Pe)9i&!1GA& z`#qinFZyfVA3?79@I~-fk^A-CFTmd>z0Pk+e>^9y7bx!v@)14@{3-OOM)?w**y7>- zTlMLzJZj(UJ(1vVdKV-l8Byva{Yl{CiIDwkD%jhR=&Qf?Cs_9NE{WSyfB5&TRl|=L z?0u$yzgWNz7w{7WEdOcyOqQSe!@q5;{B{@gUo7CC7BERlZQC+?8V`3TSm&48-_7Kz z|J_Ocn*U!+u;%{-NqYIO-YN0+k^k!5633d)^^S>SwV&QuaV-DRJ1dSg-|F2J$0KxN zjfeVQ_ouV>RYsKFfIP+8pZ&~oPx1QFKO$cm>o<}g&7Jrz=I1-(^9S%NX9oFEltXga zZ$lm|Fn_+6^&42-Ao-gLSo$4_{$to*3!WJD-+_LLrN1%JS9$MEu;e=u{EZVzrH_K` zc^&z`vqF39O!OZ^|Lb5IkLWKV{}fkBKk>6!eg7N!ZvlTUX^%&?XY$#|zXCos)=%Yq zCXuT?rMoiyQ_=q>^0`redWG_jOZ00h$R{Q8iz~<{C-TM$@~Mfuvx0nXBLA%l@&$?f zzgLjgCh{#6cu$u8 zcq5a;F7UHpt^b980KRfG?=6GJgO6mQKJE3q&&s?c{5J5-V|m9r%1;Hq`*n;b@{#;( z@aIdchj^YOycB#A_7+9`X7F9T;d~(ZM)2Q)tD^k3!S{b4JnxhIGvJRQpBUwz2S4(K zJp*5%JSy+w;Boiu8F(k>G2wp#?|Nv@Kzo#zev|zQf5`ij__O5i0MGf849^G8ek8-q z;Ftd>oZqB>9rz*a>3k>rJHoV=;|IY{J(}TX!27@|uk?Qa-V4_KXyIc>I3GW`@Ia_nw0MiOhhk&y}eEWcY`NK{l(ycME?r#4lva=dt1O;D6iN5KJY_H zeg0DVV6X4@!J|m;`1Nn*{zzi~1n@Yp*LNPc>Tk08EC<)UFQk`$w}3wg#%*o9bc5F( z6Xr|FZvy}Q(YzNM<-ZO7Jo1GRKL)-T`J#w-gHHf=M0^Ad{Vm4pf{5P+zUb5}{VCvY zzk&C!qkJy-RPcil*MUFy#!P=L_>ExC??&*Clk#o_|M581b20rNfqx(Ul@b31_=Dp! zdwak~f|p16OW+rNGb`_ex3C`&?DI`E_}l2WME!d3rxJNL`1g_Pe53Ze8oU61zXmM- zxflF=G9La0JOHkW@?U@_d@bv*@yBs}i`@NXK6v6+Gx-(Zv0(RyZQun-f8P(TM!q@P z|3~otB>m{OGM|BGM)@r8%TH$Z-v{nU?5zSno5(kS-!);+0Ll4E|A^8J;8_X26+AD& z_k%A=@HfEkPw)Y7Yl44+fpKMm-wM7q!PCJXOYj-sdyl^QIhAJ|`w1=t-;cZsto~>Q z|1MbVDf}Vuw@we^Pxwag7~0>*&t2egU?1OK0pG`d>pGjyk0?C}{#)!#iT3^(e9;ME z{L9{mw~_uYvi=(n9!T&>;Ja?g{O?roS#Qe9HwRn?_VM%Iz@GxQ#r&3n-*hbRt4DkV z_$w>J^^5Yq27EO7xV6>y)8L;a^?wk&f&5R7^2fnvd^oGmQ{ZQ)zt4aF1fH4TSHM$~ z_IfK9IxUHO7I;M>UjlAO@H+5J@TNq6DtKd}Ujx1-(Qg3X4fgyy!P^q~Ch%EzW&Qcv;BVruK7aon z_~@RjefEN9y_xS?ltTOb415CE$LkwT%(o}w}F`kEdA%fKcId-{=N);VQx4d$o^B{>E!4B{$239kUtXBk9r5=mHEl* ze**aZ@6GUg!IywXM*TYQ8RX~rcYuFP{TyEpUYnHfcJR_ff1C6Z`Io?-;(YDt{{;N4 zsoDDZo8T*Hj|XG^FMv-tne!3tt@^zLKAQA3Q9gb$<>P&xEfJpxt~)JjpVPtZV3Jz; z3&9u73ioql?}Oks;!i$)Itut2@Y@o9`#AWd1b+s60RQy)>>lu_of&=ryf=}51^m5p z7@tRk^6UbCEa}g`1K*Y47r@UX>Hh_M#`)B5R7n4C;FE6VyCAXtN1nv{Q}nO5&oSV0 zXX9V7{%;0BaLK7;;t z|Lg(tk$!$bJ6$9C#+cmMe^xQY2q{ipTY^WZ;C^!2ky-~PR9z41Em&Fi!E&D+3#du_Jf zeh>H$z%VQC3Id=1OqO34cvmuCZv;P{;O*d@34Rp(NP_n%>+zP(vqU?P15%B*9_Wrva+(>%&_x}Oj zfSk)RtM50!pRdc>=Lg^ymSp4cU%@{D`+Pe36yEP^V1Io~KM`C9W?5tQP67W0cxuFR z!C$Y<@P*(dU_T#y0Q|{|v-~>2*Mr@EJ__!oe6ypyJHbDpJ{=L?1O74g=0^M=m^&DQ z>*+rgernHvV#jem^sB<_UC#G6Oh1!91-|P8+4bhPz#nCOT1_(f^AErS?3bGe*7ebt zcXNJeq5s$yC3zM2vtU2}odN!1u=FLb1Hb(B?0UNy+y}-j%w7-pORT@Vzdj0nHqpNo zyeQHCJ>i|%`QVSiHQ=$)-d}-R68X2lE5Ku-{C|V5N#sY;aeayWt>CSR{8aGfM1Br< zMb?KZes6Z@XW+sD|l*xuLDm?^tXe*nb`Yt@HXV$e@}vUg4O>j@3+8L zFh9FL{|J07*!}5s)97z7>gFHgz*UcB{Wldn6|D1x>|Fp}2zL7$z-?gn$IpRRfX7Dt zZ-B2$R~Kh?zaFN1#!o*D6k8LVf~e<|X3f|s*j zM)}DfW`auzUI>0EY44TbiHW=qJPz#ru^GHDk#7grB=U#Aa}xYb@RUUVU%{tx{e4s{ z-^9~s?@wj({VCwJoKJmzo&)~UZ)NlUMc@s|_4^8N6WHg=cJR;8pB(Lf2>c52mWXcx z_gHTQ!VqK{|(;EdM}K>BTD}V zyd}Y7>8LANpSizOfzRUpg!|WN;1j^^UyH!aU_bw^0>2OJ_3a0LgZyh^{?~(l2kiDg z4*t_k*?Q%3;NK*F_s6e-PfyD8P4KB;@1N(v^EPJdqaT6q|L^!i^w(Fwjo|v2|JYeP zuR!0+`*!f_kuQt#_kcHS&c@qW;Gb~4pz*BnvKahr$~z(A72prt$aldbz5@Jt?7tlG zhru61K0o4{!N32}Y`yxs;2(fHqkISWuh94P^CRG|d@NgE?*e}n?EU@E;Gcmt|EPRN zv#|I$*!%mf;Ga<5+oSvx@K^EoGr%_9z%PTVB0dZJ!cAHK)q`IFFOTWlzz@Ayz)MN*?b8L`yer(Fl>HmQuO#wMgVXEtFM@x32lI6t zKRdynzdh^E=fFQ2Ya-i~*xv(wCb7Tty_Dmw%zs+JcY*JT-WJ&a(#Gjw6_DC-Y;~^h?%)3qy!*&Z z{xj((*BeKuV@i7l^nVQ?fbE^D zyFA>qYE@6`I!7Jtovj{T-P5#o5cKx-czj1!b7|VV`irJD_4W0%uj=p140|@c8`kzU zttw6HZ6jR>1zwup)Z5T-4s#7a`g9HZ}LPcXiJ1YT1xPu5RrK=#rkM?(Wu}nCYsfH67$Vxn{?A)AetT{+&@$%Er}QoqfHeH?XE-Lw8$1)U2^DtJ

    NgQhN7Kjg<@fiotaj37Dd>Y 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.0.1", + "crcmod~=1.7", + "ecdsa~=0.15", + "ed25519-blake2b~=1.4", + "py-sr25519-bindings<2.0.0,>=0.1.3", + "pycryptodome~=3.6", + "pynacl~=1.4", +] + +[[package]] +name = "bip32" +version = "3.3" +summary = "Minimalistic implementation of the BIP32 key derivation scheme" +dependencies = [ + "base58~=2.0", + "coincurve<18,>=15.0", +] + +[[package]] +name = "black" +version = "22.10.0" +requires_python = ">=3.7" +summary = "The uncompromising code formatter." +dependencies = [ + "click>=8.0.0", + "mypy-extensions>=0.4.3", + "pathspec>=0.9.0", + "platformdirs>=2", + "tomli>=1.1.0; python_full_version < \"3.11.0a7\"", +] + +[[package]] +name = "cbor2" +version = "5.4.3" +requires_python = ">=3.7" +summary = "CBOR (de)serializer with extensive tag support" + +[[package]] +name = "certifi" +version = "2022.9.24" +requires_python = ">=3.6" +summary = "Python package for providing Mozilla's CA Bundle." + +[[package]] +name = "cffi" +version = "1.15.1" +summary = "Foreign Function Interface for Python calling C code." +dependencies = [ + "pycparser", +] + +[[package]] +name = "charset-normalizer" +version = "2.1.1" +requires_python = ">=3.6.0" +summary = "The Real First Universal Charset Detector. Open, modern and actively maintained alternative to Chardet." + +[[package]] +name = "click" +version = "8.1.3" +requires_python = ">=3.7" +summary = "Composable command line interface toolkit" +dependencies = [ + "colorama; platform_system == \"Windows\"", +] + +[[package]] +name = "coincurve" +version = "17.0.0" +requires_python = ">=3.7" +summary = "Cross-platform Python CFFI bindings for libsecp256k1" +dependencies = [ + "asn1crypto", + "cffi>=1.3.0", +] + +[[package]] +name = "colorama" +version = "0.4.6" +requires_python = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,!=3.6.*,>=2.7" +summary = "Cross-platform colored terminal text." + +[[package]] +name = "construct" +version = "2.10.68" +requires_python = ">=3.6" +summary = "A powerful declarative symmetric parser/builder for binary data" + +[[package]] +name = "coverage" +version = "6.5.0" +requires_python = ">=3.7" +summary = "Code coverage measurement for Python" + +[[package]] +name = "coverage" +version = "6.5.0" +extras = ["toml"] +requires_python = ">=3.7" +summary = "Code coverage measurement for Python" +dependencies = [ + "coverage==6.5.0", + "tomli; python_full_version <= \"3.11.0a6\"", +] + +[[package]] +name = "crcmod" +version = "1.7" +summary = "CRC Generator" + +[[package]] +name = "ecdsa" +version = "0.18.0" +requires_python = ">=2.6, !=3.0.*, !=3.1.*, !=3.2.*" +summary = "ECDSA cryptographic signature library (pure python)" +dependencies = [ + "six>=1.9.0", +] + +[[package]] +name = "ed25519-blake2b" +version = "1.4" +summary = "Ed25519 public-key signatures (BLAKE2b fork)" + +[[package]] +name = "exceptiongroup" +version = "1.0.4" +requires_python = ">=3.7" +summary = "Backport of PEP 654 (exception groups)" + +[[package]] +name = "flask" +version = "2.2.2" +requires_python = ">=3.7" +summary = "A simple framework for building complex web applications." +dependencies = [ + "Jinja2>=3.0", + "Werkzeug>=2.2.2", + "click>=8.0", + "itsdangerous>=2.0", +] + +[[package]] +name = "flask-restful" +version = "0.3.9" +summary = "Simple framework for creating REST APIs" +dependencies = [ + "Flask>=0.8", + "aniso8601>=0.82", + "pytz", + "six>=1.3.0", +] + +[[package]] +name = "idna" +version = "3.4" +requires_python = ">=3.5" +summary = "Internationalized Domain Names in Applications (IDNA)" + +[[package]] +name = "iniconfig" +version = "1.1.1" +summary = "iniconfig: brain-dead simple config-ini parsing" + +[[package]] +name = "itsdangerous" +version = "2.1.2" +requires_python = ">=3.7" +summary = "Safely pass data to untrusted environments and back." + +[[package]] +name = "jinja2" +version = "3.1.2" +requires_python = ">=3.7" +summary = "A very fast and expressive template engine." +dependencies = [ + "MarkupSafe>=2.0", +] + +[[package]] +name = "jsonschema" +version = "3.2.0" +summary = "An implementation of JSON Schema validation for Python" +dependencies = [ + "attrs>=17.4.0", + "pyrsistent>=0.14.0", + "setuptools", + "six>=1.11.0", +] + +[[package]] +name = "markupsafe" +version = "2.1.1" +requires_python = ">=3.7" +summary = "Safely add untrusted strings to HTML/XML markup." + +[[package]] +name = "mnemonic" +version = "0.20" +requires_python = ">=3.5" +summary = "Implementation of Bitcoin BIP-0039" + +[[package]] +name = "mypy-extensions" +version = "0.4.3" +summary = "Experimental type system extensions for programs checked with the mypy typechecker." + +[[package]] +name = "mypy-protobuf" +version = "3.3.0" +requires_python = ">=3.7" +summary = "Generate mypy stub files from protobuf specs" +dependencies = [ + "protobuf>=3.19.4", + "types-protobuf>=3.19.12", +] + +[[package]] +name = "packaging" +version = "21.3" +requires_python = ">=3.6" +summary = "Core utilities for Python packages" +dependencies = [ + "pyparsing!=3.0.5,>=2.0.2", +] + +[[package]] +name = "pathspec" +version = "0.10.2" +requires_python = ">=3.7" +summary = "Utility library for gitignore style pattern matching of file paths." + +[[package]] +name = "pillow" +version = "9.3.0" +requires_python = ">=3.7" +summary = "Python Imaging Library (Fork)" + +[[package]] +name = "platformdirs" +version = "2.5.4" +requires_python = ">=3.7" +summary = "A small Python package for determining appropriate platform-specific dirs, e.g. a \"user data dir\"." + +[[package]] +name = "pluggy" +version = "1.0.0" +requires_python = ">=3.6" +summary = "plugin and hook calling mechanisms for python" + +[[package]] +name = "protobuf" +version = "3.20.3" +requires_python = ">=3.7" +summary = "Protocol Buffers" + +[[package]] +name = "py-sr25519-bindings" +version = "0.1.4" +summary = "Python bindings for sr25519 library" + +[[package]] +name = "pycparser" +version = "2.21" +requires_python = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" +summary = "C parser in Python" + +[[package]] +name = "pycryptodome" +version = "3.15.0" +requires_python = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" +summary = "Cryptographic library for Python" + +[[package]] +name = "pyelftools" +version = "0.29" +summary = "Library for analyzing ELF files and DWARF debugging information" + +[[package]] +name = "pynacl" +version = "1.5.0" +requires_python = ">=3.6" +summary = "Python binding to the Networking and Cryptography (NaCl) library" +dependencies = [ + "cffi>=1.4.1", +] + +[[package]] +name = "pyparsing" +version = "3.0.9" +requires_python = ">=3.6.8" +summary = "pyparsing module - Classes and methods to define and execute parsing grammars" + +[[package]] +name = "pyqt5" +version = "5.15.7" +requires_python = ">=3.7" +summary = "Python bindings for the Qt cross platform application toolkit" +dependencies = [ + "PyQt5-Qt5>=5.15.0", + "PyQt5-sip<13,>=12.11", +] + +[[package]] +name = "pyqt5-qt5" +version = "5.15.2" +summary = "The subset of a Qt installation needed by PyQt5." + +[[package]] +name = "pyqt5-sip" +version = "12.11.0" +requires_python = ">=3.7" +summary = "The sip module support for PyQt5" + +[[package]] +name = "pyrsistent" +version = "0.19.2" +requires_python = ">=3.7" +summary = "Persistent/Functional/Immutable data structures" + +[[package]] +name = "pytest" +version = "7.2.0" +requires_python = ">=3.7" +summary = "pytest: simple powerful testing with Python" +dependencies = [ + "attrs>=19.2.0", + "colorama; sys_platform == \"win32\"", + "exceptiongroup>=1.0.0rc8; python_version < \"3.11\"", + "iniconfig", + "packaging", + "pluggy<2.0,>=0.12", + "tomli>=1.0.0; python_version < \"3.11\"", +] + +[[package]] +name = "pytest-cov" +version = "4.0.0" +requires_python = ">=3.6" +summary = "Pytest plugin for measuring coverage." +dependencies = [ + "coverage[toml]>=5.2.1", + "pytest>=4.6", +] + +[[package]] +name = "pytz" +version = "2022.6" +summary = "World timezone definitions, modern and historical" + +[[package]] +name = "ragger" +version = "0.7.0" +requires_python = ">=3.6" +summary = "Testing framework using Speculos and LedgerComm as backends" +dependencies = [ + "bip-utils>=2.4.0", + "bip32>=3.3", + "py-sr25519-bindings==0.1.4", + "semver>=2.13.0", +] + +[[package]] +name = "ragger" +version = "0.7.0" +extras = ["speculos", "tests"] +requires_python = ">=3.6" +summary = "Testing framework using Speculos and LedgerComm as backends" +dependencies = [ + "pytest", + "pytest-cov", + "ragger==0.7.0", + "speculos>=0.1.128", +] + +[[package]] +name = "requests" +version = "2.28.1" +requires_python = ">=3.7, <4" +summary = "Python HTTP for Humans." +dependencies = [ + "certifi>=2017.4.17", + "charset-normalizer<3,>=2", + "idna<4,>=2.5", + "urllib3<1.27,>=1.21.1", +] + +[[package]] +name = "semver" +version = "2.13.0" +requires_python = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" +summary = "Python helper for Semantic Versioning (http://semver.org/)" + +[[package]] +name = "setuptools" +version = "65.5.1" +requires_python = ">=3.7" +summary = "Easily download, build, install, upgrade, and uninstall Python packages" + +[[package]] +name = "six" +version = "1.16.0" +requires_python = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*" +summary = "Python 2 and 3 compatibility utilities" + +[[package]] +name = "speculos" +version = "0.1.157" +requires_python = ">=3.6.0" +summary = "Ledger Blue and Nano S/X application emulator" +dependencies = [ + "construct<3.0.0,>=2.10.56", + "flask-restful<1.0,>=0.3.9", + "flask<3.0.0,>=2.0.0", + "jsonschema<4.0.0,>=3.2.0", + "mnemonic<1.0,>=0.19", + "pillow<10.0.0,>=8.0.0", + "pyelftools<1.0,>=0.27", + "pyqt5<6.0.0,>=5.15.2", + "requests<3.0.0,>=2.25.1", +] + +[[package]] +name = "tomli" +version = "2.0.1" +requires_python = ">=3.7" +summary = "A lil' TOML parser" + +[[package]] +name = "types-protobuf" +version = "3.20.4.5" +summary = "Typing stubs for protobuf" + +[[package]] +name = "urllib3" +version = "1.26.12" +requires_python = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, !=3.5.*, <4" +summary = "HTTP library with thread-safe connection pooling, file post, and more." + +[[package]] +name = "werkzeug" +version = "2.2.2" +requires_python = ">=3.7" +summary = "The comprehensive WSGI web application library." +dependencies = [ + "MarkupSafe>=2.1.1", +] + +[metadata] +lock_version = "4.0" +content_hash = "sha256:38717b41c12cd6cc82e65935b165b9fbaccb282850ed20fd7e7ab88120a0f1e0" + +[metadata.files] +"aniso8601 9.0.1" = [ + {url = "https://files.pythonhosted.org/packages/cb/72/be3db445b03944bfbb2b02b82d00cb2a2bcf96275c4543f14bf60fa79e12/aniso8601-9.0.1.tar.gz", hash = "sha256:72e3117667eedf66951bb2d93f4296a56b94b078a8a95905a052611fb3f1b973"}, + {url = "https://files.pythonhosted.org/packages/e3/04/e97c12dc034791d7b504860acfcdd2963fa21ae61eaca1c9d31245f812c3/aniso8601-9.0.1-py2.py3-none-any.whl", hash = "sha256:1d2b7ef82963909e93c4f24ce48d4de9e66009a21bf1c1e1c85bdd0812fe412f"}, +] +"asn1crypto 1.5.1" = [ + {url = "https://files.pythonhosted.org/packages/c9/7f/09065fd9e27da0eda08b4d6897f1c13535066174cc023af248fc2a8d5e5a/asn1crypto-1.5.1-py2.py3-none-any.whl", hash = "sha256:db4e40728b728508912cbb3d44f19ce188f218e9eba635821bb4b68564f8fd67"}, + {url = "https://files.pythonhosted.org/packages/de/cf/d547feed25b5244fcb9392e288ff9fdc3280b10260362fc45d37a798a6ee/asn1crypto-1.5.1.tar.gz", hash = "sha256:13ae38502be632115abf8a24cbe5f4da52e3b5231990aff31123c805306ccb9c"}, +] +"attrs 22.1.0" = [ + {url = "https://files.pythonhosted.org/packages/1a/cb/c4ffeb41e7137b23755a45e1bfec9cbb76ecf51874c6f1d113984ecaa32c/attrs-22.1.0.tar.gz", hash = "sha256:29adc2665447e5191d0e7c568fde78b21f9672d344281d0c6e1ab085429b22b6"}, + {url = "https://files.pythonhosted.org/packages/f2/bc/d817287d1aa01878af07c19505fafd1165cd6a119e9d0821ca1d1c20312d/attrs-22.1.0-py2.py3-none-any.whl", hash = "sha256:86efa402f67bf2df34f51a335487cf46b1ec130d02b8d39fd248abfd30da551c"}, +] +"base58 2.1.1" = [ + {url = "https://files.pythonhosted.org/packages/4a/45/ec96b29162a402fc4c1c5512d114d7b3787b9d1c2ec241d9568b4816ee23/base58-2.1.1-py3-none-any.whl", hash = "sha256:11a36f4d3ce51dfc1043f3218591ac4eb1ceb172919cebe05b52a5bcc8d245c2"}, + {url = "https://files.pythonhosted.org/packages/7f/45/8ae61209bb9015f516102fa559a2914178da1d5868428bd86a1b4421141d/base58-2.1.1.tar.gz", hash = "sha256:c5d0cb3f5b6e81e8e35da5754388ddcc6d0d14b6c6a132cb93d69ed580a7278c"}, +] +"bip-utils 2.7.0" = [ + {url = "https://files.pythonhosted.org/packages/e7/2f/baba669c680fef1e841d05840f4089d24841cd485fa4b0c7ce4bedd24d25/bip_utils-2.7.0.tar.gz", hash = "sha256:bc6302840a95695609e215ad362ddb42d70d472b3cb1494d1fb2112d08c1c707"}, + {url = "https://files.pythonhosted.org/packages/f7/5f/0327b3d8938453ebfdbf1e9b95f69f5c0efe533536950371517c17cee38a/bip_utils-2.7.0-py3-none-any.whl", hash = "sha256:b04c0f60628f1ab2792e8946f8547515b72269d8f431f722592f6a71fa7ff9fc"}, +] +"bip32 3.3" = [ + {url = "https://files.pythonhosted.org/packages/61/b1/37685f64de6d6f5ede0394fe70a9ab45f4f0691a2fe99a231f1b569e1c6d/bip32-3.3-py3-none-any.whl", hash = "sha256:c1ed0b2896b090e090cbd3c7de94ed10a9e1f9157e264f09f1a7177cb0b31b6d"}, + {url = "https://files.pythonhosted.org/packages/7e/ec/bc151473168920d24ca6af7288dd5cdacb71c69cf6d357b146945777c4b2/bip32-3.3.tar.gz", hash = "sha256:664e0700ee53c79bf2573b277f278b7f4a6ca14ee4ce5e8499721c4c752e32c1"}, +] +"black 22.10.0" = [ + {url = "https://files.pythonhosted.org/packages/2c/11/f2737cd3b458d91401801e83a014e87c63e8904dc063200f77826c352f54/black-22.10.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:2039230db3c6c639bd84efe3292ec7b06e9214a2992cd9beb293d639c6402edb"}, + {url = "https://files.pythonhosted.org/packages/3d/c5/b3ab9b563f35fb284d37ab2b14acaed9a27d8cdea9c31364766eb54946a7/black-22.10.0-cp37-cp37m-win_amd64.whl", hash = "sha256:9311e99228ae10023300ecac05be5a296f60d2fd10fff31cf5c1fa4ca4b1988d"}, + {url = "https://files.pythonhosted.org/packages/56/df/913d71817c7034edba25d596c54f782c2f809b6af30367d2f00309e8890a/black-22.10.0-cp311-cp311-win_amd64.whl", hash = "sha256:21199526696b8f09c3997e2b4db8d0b108d801a348414264d2eb8eb2532e540d"}, + {url = "https://files.pythonhosted.org/packages/69/21/846c95710cc6561ba980bd6c72479dbcdde742e927ff5ef7340916d003ac/black-22.10.0-1fixedarch-cp38-cp38-macosx_10_16_x86_64.whl", hash = "sha256:2644b5d63633702bc2c5f3754b1b475378fbbfb481f62319388235d0cd104c2d"}, + {url = "https://files.pythonhosted.org/packages/69/84/903cdf41514088d5a716538cb189c471ab34e56ae9a1c2da6b8bfe8e4dbf/black-22.10.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:974308c58d057a651d182208a484ce80a26dac0caef2895836a92dd6ebd725e0"}, + {url = "https://files.pythonhosted.org/packages/71/f8/57e47ea67f59613c4368a952062bc3429131249920cffbb8362fd404b733/black-22.10.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:fba8a281e570adafb79f7755ac8721b6cf1bbf691186a287e990c7929c7692ff"}, + {url = "https://files.pythonhosted.org/packages/86/da/edebcc6c13441d91eff6761e50512bc6d6886a556dc5357b399694122b4f/black-22.10.0-1fixedarch-cp37-cp37m-macosx_10_16_x86_64.whl", hash = "sha256:197df8509263b0b8614e1df1756b1dd41be6738eed2ba9e9769f3880c2b9d7b6"}, + {url = "https://files.pythonhosted.org/packages/91/e6/d9b78987d7d903369ba1a0b795bce4de06f0155be6609f15e8950aef8f7e/black-22.10.0-cp38-cp38-win_amd64.whl", hash = "sha256:444ebfb4e441254e87bad00c661fe32df9969b2bf224373a448d8aca2132b395"}, + {url = "https://files.pythonhosted.org/packages/a3/89/629fca2eea0899c06befaa58dc0f49d56807d454202bb2e54bd0d98c77f3/black-22.10.0.tar.gz", hash = "sha256:f513588da599943e0cde4e32cc9879e825d58720d6557062d1098c5ad80080e1"}, + {url = "https://files.pythonhosted.org/packages/a5/5f/9cfc6dd95965f8df30194472543e6f0515a10d78ea5378426ef1546735c7/black-22.10.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:14ff67aec0a47c424bc99b71005202045dc09270da44a27848d534600ac64fc7"}, + {url = "https://files.pythonhosted.org/packages/a6/84/5c3f3ffc4143fa7e208d745d2239d915e74d3709fdbc64c3e98d3fd27e56/black-22.10.0-1fixedarch-cp311-cp311-macosx_11_0_x86_64.whl", hash = "sha256:5d8f74030e67087b219b032aa33a919fae8806d49c867846bfacde57f43972ef"}, + {url = "https://files.pythonhosted.org/packages/ab/15/61119d166a44699827c112d7c4726421f14323c2cb7aa9f4c26628f237f9/black-22.10.0-cp39-cp39-win_amd64.whl", hash = "sha256:432247333090c8c5366e69627ccb363bc58514ae3e63f7fc75c54b1ea80fa7de"}, + {url = "https://files.pythonhosted.org/packages/ae/49/ea03c318a25be359b8e5178a359d47e2da8f7524e1522c74b8f74c66b6f8/black-22.10.0-1fixedarch-cp310-cp310-macosx_11_0_x86_64.whl", hash = "sha256:5cc42ca67989e9c3cf859e84c2bf014f6633db63d1cbdf8fdb666dcd9e77e3fa"}, + {url = "https://files.pythonhosted.org/packages/b0/9e/fa912c5ae4b8eb6d36982fc8ac2d779cf944dbd7c3c1fe7a28acf462c1ed/black-22.10.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b8b49776299fece66bffaafe357d929ca9451450f5466e997a7285ab0fe28e3b"}, + {url = "https://files.pythonhosted.org/packages/b9/51/403b0b0eb9fb412ca02b79dc38472469f2f88c9aacc6bb5262143e4ff0bc/black-22.10.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:72ef3925f30e12a184889aac03d77d031056860ccae8a1e519f6cbb742736383"}, + {url = "https://files.pythonhosted.org/packages/ce/6f/74492b8852ee4f2ad2178178f6b65bc8fc80ad539abe56c1c23eab6732e2/black-22.10.0-py3-none-any.whl", hash = "sha256:c957b2b4ea88587b46cf49d1dc17681c1e672864fd7af32fc1e9664d572b3458"}, + {url = "https://files.pythonhosted.org/packages/d0/5a/5f31494e3acbb6319ee60c3a3a09d3e536a3fd2353f76af9cbff799c4999/black-22.10.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:915ace4ff03fdfff953962fa672d44be269deb2eaf88499a0f8805221bc68c87"}, + {url = "https://files.pythonhosted.org/packages/e2/2f/a8406a9e337a213802aa90a3e9fbf90c86f3edce92f527255fd381309b77/black-22.10.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:5b9b29da4f564ba8787c119f37d174f2b69cdfdf9015b7d8c5c16121ddc054ae"}, + {url = "https://files.pythonhosted.org/packages/e3/b4/9203f1a0c99aa30389b61fa8cb54bc9f4bf16ac3aa74630c6b974ed3f3b0/black-22.10.0-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1e464456d24e23d11fced2bc8c47ef66d471f845c7b7a42f3bd77bf3d1789650"}, + {url = "https://files.pythonhosted.org/packages/f2/23/f4278377cabf882298b4766e977fd04377f288d1ccef706953076a1e0598/black-22.10.0-1fixedarch-cp39-cp39-macosx_11_0_x86_64.whl", hash = "sha256:e41a86c6c650bcecc6633ee3180d80a025db041a8e2398dcc059b3afa8382cd4"}, + {url = "https://files.pythonhosted.org/packages/ff/ce/22281871536b3d79474fd44d48dad48f7cbc5c3982bddf6a7495e7079d00/black-22.10.0-cp310-cp310-win_amd64.whl", hash = "sha256:819dc789f4498ecc91438a7de64427c73b45035e2e3680c92e18795a839ebb66"}, +] +"cbor2 5.4.3" = [ + {url = "https://files.pythonhosted.org/packages/06/bc/a06502ec2156236bf3de33d88a8afcad31834fb2a315f4762710af5e551e/cbor2-5.4.3-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:e10f2f4fcf5ab6a8b24d22f7109f48cad8143f669795899370170d7b36ed309f"}, + {url = "https://files.pythonhosted.org/packages/0b/79/30c4336c03e2f22cf4780d680af89b3d1a7b20dcf935a745ec1f6920c992/cbor2-5.4.3-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:37ae0ce5afe864d1a1c5b05becaf8aaca7b7131cb7b0b935d7e79b29fb1cea28"}, + {url = "https://files.pythonhosted.org/packages/0e/74/0c5b7d875031cd39734a9eb369d32560712512e68fd520408a02e59e366a/cbor2-5.4.3-cp39-cp39-win_amd64.whl", hash = "sha256:4e8590193fcbbb9477010ca0f094f6540a5e723965c90eea7a37edbe75f0ec4d"}, + {url = "https://files.pythonhosted.org/packages/0f/58/d8fa51d2fb85fdcc539a7e434dc91f5a53a40676ab04ccfb3c2105694d8b/cbor2-5.4.3-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:981b9ffc4f2947a0f030e71ce5eac31334bc81369dd57c6c1273c94c6cdb0b5a"}, + {url = "https://files.pythonhosted.org/packages/17/9f/649aa0e5927ffb0f5920d5b4ab2c9236d3c7243f6aae6a79dc8239dbbce5/cbor2-5.4.3-cp310-cp310-win_amd64.whl", hash = "sha256:0a3a1b2f6b83ab4ce806df48360cc16d34cd315f17549dbda9fdd371bea04497"}, + {url = "https://files.pythonhosted.org/packages/19/58/0caea0a5bc265b8eb09cb633873be06ea8bf4779a5338e42d389c9113c37/cbor2-5.4.3-cp38-cp38-win_amd64.whl", hash = "sha256:5c50da4702ac5ca3a8e7cb9f34f62b4ea91bc81b76c2fba03888b366da299cd8"}, + {url = "https://files.pythonhosted.org/packages/3b/e6/6d070295033b286b79a066577c4e2f32a30da87b9080cdcbb4bff0bb02c5/cbor2-5.4.3-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c07975f956baddb8dfeca4966f1871fd2482cb36af24c461f763732a44675225"}, + {url = "https://files.pythonhosted.org/packages/45/aa/078ff9bb5f6075289434db76f8f0ab3f0e0815a7c8d1b42250983df552a7/cbor2-5.4.3-cp37-cp37m-win_amd64.whl", hash = "sha256:c617c7f94936d65ed9c8e99c6c03e3dc83313d69c6bfea810014ec658e9b1a9d"}, + {url = "https://files.pythonhosted.org/packages/69/3e/23c195efcc1a09c0cb3ad3cf255ac628290e69c325a6094427552faf1bc2/cbor2-5.4.3-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:9538ab1b4207e76ee02a52362d77e312921ec1dc75b6fb42182887d87d0ca53e"}, + {url = "https://files.pythonhosted.org/packages/6b/b3/ba530faf197f4fa76715f65f375af50e36848468e9154ae4847a7a9da0ef/cbor2-5.4.3-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:0e4ae67a697c664b579b87c4ef9d60e26c146b95bff443a9a38abb16f6981ff0"}, + {url = "https://files.pythonhosted.org/packages/7a/7a/95def2895c54362eeec30b336b6b00b9a7e5d77ddce5f15902f8f15f75c7/cbor2-5.4.3-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ab6c934806759d453a9bb5318f2703c831e736be005ac35d5bd5cf2093ba57b1"}, + {url = "https://files.pythonhosted.org/packages/7d/80/cd612cc982cb1e3b4e801d241dec977a7e60acdef204862e19ab5607e2f2/cbor2-5.4.3-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:70789805b9aebd215626188aa05bb09908ed51e3268d4db5ae6a08276efdbcb1"}, + {url = "https://files.pythonhosted.org/packages/81/2b/c9f71180c14cc8009b8ea3a4a33e5a5e82cd14f78d5bd3e53e465ae54da0/cbor2-5.4.3-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:b35c5d4d14fe804f718d5a5968a528970d2a7046aa87045538f189a98e5c7055"}, + {url = "https://files.pythonhosted.org/packages/92/15/c8df882191534848c094cdba1ee43c24a1f203158317055b88b5c1ef8b9c/cbor2-5.4.3-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:20291dad09cf9c4e5f434d376dd9d60f5ab5e066b308005f50e7c5e22e504214"}, + {url = "https://files.pythonhosted.org/packages/92/b7/d68849bb65dfd6fa359be214451e714f433973f16123b1454bdd24c9dc1c/cbor2-5.4.3-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:cbe7cdeed26cd8ec2dcfed2b8876bc137ad8b9e0abb07aa5fb05770148a4b5c7"}, + {url = "https://files.pythonhosted.org/packages/96/39/e4c02d596fbfe74cb87435648b278f08298ad12547501c8f4ffddd2d7839/cbor2-5.4.3-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:8a643b19ace1584043bbf4e2d0b4fae8bebd6b6ffab14ea6478d3ff07f58e854"}, + {url = "https://files.pythonhosted.org/packages/96/d5/1636607ae4080bec89bded6a7191245449555d1f64c053c90578634b3362/cbor2-5.4.3-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:4b09ff6148a8cd529512479a1d6521fb7687fb03b448973933c3b03711d00bfc"}, + {url = "https://files.pythonhosted.org/packages/9c/08/bd9e416077e1f35de5ab9d5616eba237922f679287a4dcc60f3f78b69c9c/cbor2-5.4.3-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:5aaf3406c9d661d11f87e792edb9a38561dba1441afba7fb883d6d963e67f32c"}, + {url = "https://files.pythonhosted.org/packages/9d/c9/cfa5c35a62642a19c14bf9a12dfbf0ee134466be1f062df2258a2ec2f2f7/cbor2-5.4.3.tar.gz", hash = "sha256:62b863c5ee6ced4032afe948f3c1484f375550995d3b8498145237fe28e546c2"}, + {url = "https://files.pythonhosted.org/packages/ac/11/b163ea396a02a2e27bdbd63a4e44d317feecd2cb72094a61977dbdf6bb82/cbor2-5.4.3-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:62fc15bfe187e4994c457e6055687514c417d6099de62dd33ae766561f05847e"}, + {url = "https://files.pythonhosted.org/packages/ae/52/2e690a63afb3822da5825048a47accaccddf713d7148e2696fe0445c1215/cbor2-5.4.3-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:cbca58220f52fd50d8985e4079e10c71196d538fb6685f157f608a29253409a4"}, + {url = "https://files.pythonhosted.org/packages/af/ec/2f48f091d7be9ea98aed93ee3b74bc544295efef65f0b38fa68fe4a03e72/cbor2-5.4.3-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d21ccd1ec802e88dba1c373724a09538a0237116ab589c5301ca4c59478f7c10"}, + {url = "https://files.pythonhosted.org/packages/b4/6c/02b19eeafb7161f70516d5caf385f9d27eab2d20abd4d462ccd38fc2eecf/cbor2-5.4.3-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6fab0e00c28305db59f7005150447d08dd13da6a82695a2132c28beba590fd2c"}, + {url = "https://files.pythonhosted.org/packages/b5/65/5a5e224bc3f0fa78c6a723f64a30c129e7a0c770584a8cd31e7b3dcbe4fa/cbor2-5.4.3-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:3843a9bb970343e9c896aa71a34fa80983cd0ddec6eacdb2284b5e83f4ee7511"}, + {url = "https://files.pythonhosted.org/packages/c4/1a/5d8f054f79e40bd864cb05a4e0bddd0b99d87400a14e7ba68de27d87206d/cbor2-5.4.3-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2de925608dc6d73cd1aab08800bff38f71f90459c15db3a71a67023b0fc697da"}, + {url = "https://files.pythonhosted.org/packages/cd/7a/258d271ffbac9a6222f79c91f84c5a0ff2fdc71a158286e22e3477b292cb/cbor2-5.4.3-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:2f30f7ef329ea6ec630ceabe5a539fed407b9c81e27e2322644e3efbbd1b2a76"}, + {url = "https://files.pythonhosted.org/packages/ee/e5/6d3a4a6ebc47554b9042c4b934f2d3d0111abbf331c545b016df293036c8/cbor2-5.4.3-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:6bc8c5606aa0ae510bdb3c7d987f92df39ef87d09e0f0588a4d1daffd3cb0453"}, + {url = "https://files.pythonhosted.org/packages/fc/90/47c8068827cca8df95b5ce603f44cff8be525bcf7792b465f5a822892c4a/cbor2-5.4.3-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d549abea7115c8a0d7c61a31a895c031f902a7b4c875f9efd8ce41e466baf83a"}, +] +"certifi 2022.9.24" = [ + {url = "https://files.pythonhosted.org/packages/1d/38/fa96a426e0c0e68aabc68e896584b83ad1eec779265a028e156ce509630e/certifi-2022.9.24-py3-none-any.whl", hash = "sha256:90c1a32f1d68f940488354e36370f6cca89f0f106db09518524c88d6ed83f382"}, + {url = "https://files.pythonhosted.org/packages/cb/a4/7de7cd59e429bd0ee6521ba58a75adaec136d32f91a761b28a11d8088d44/certifi-2022.9.24.tar.gz", hash = "sha256:0d9c601124e5a6ba9712dbc60d9c53c21e34f5f641fe83002317394311bdce14"}, +] +"cffi 1.15.1" = [ + {url = "https://files.pythonhosted.org/packages/00/05/23a265a3db411b0bfb721bf7a116c7cecaf3eb37ebd48a6ea4dfb0a3244d/cffi-1.15.1-cp27-cp27m-win_amd64.whl", hash = "sha256:e00b098126fd45523dd056d2efba6c5a63b71ffe9f2bbe1a4fe1716e1d0c331e"}, + {url = "https://files.pythonhosted.org/packages/03/7b/259d6e01a6083acef9d3c8c88990c97d313632bb28fa84d6ab2bb201140a/cffi-1.15.1-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:173379135477dc8cac4bc58f45db08ab45d228b3363adb7af79436135d028405"}, + {url = "https://files.pythonhosted.org/packages/0e/65/0d7b5dad821ced4dcd43f96a362905a68ce71e6b5f5cfd2fada867840582/cffi-1.15.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:59c0b02d0a6c384d453fece7566d1c7e6b7bae4fc5874ef2ef46d56776d61c9e"}, + {url = "https://files.pythonhosted.org/packages/0e/e2/a23af3d81838c577571da4ff01b799b0c2bbde24bd924d97e228febae810/cffi-1.15.1-cp310-cp310-win_amd64.whl", hash = "sha256:ce4bcc037df4fc5e3d184794f27bdaab018943698f4ca31630bc7f84a7b69c6d"}, + {url = "https://files.pythonhosted.org/packages/10/72/617ee266192223a38b67149c830bd9376b69cf3551e1477abc72ff23ef8e/cffi-1.15.1-cp311-cp311-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a591fe9e525846e4d154205572a029f653ada1a78b93697f3b5a8f1f2bc055b9"}, + {url = "https://files.pythonhosted.org/packages/18/8f/5ff70c7458d61fa8a9752e5ee9c9984c601b0060aae0c619316a1e1f1ee5/cffi-1.15.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:54a2db7b78338edd780e7ef7f9f6c442500fb0d41a5a4ea24fff1c929d5af585"}, + {url = "https://files.pythonhosted.org/packages/1d/76/bcebbbab689f5f6fc8a91e361038a3001ee2e48c5f9dbad0a3b64a64cc9e/cffi-1.15.1-cp27-cp27m-manylinux1_x86_64.whl", hash = "sha256:9ad5db27f9cabae298d151c85cf2bad1d359a1b9c686a275df03385758e2f914"}, + {url = "https://files.pythonhosted.org/packages/22/c6/df826563f55f7e9dd9a1d3617866282afa969fe0d57decffa1911f416ed8/cffi-1.15.1-cp38-cp38-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1e74c6b51a9ed6589199c787bf5f9875612ca4a8a0785fb2d4a84429badaf22a"}, + {url = "https://files.pythonhosted.org/packages/23/8b/2e8c2469eaf89f7273ac685164949a7e644cdfe5daf1c036564208c3d26b/cffi-1.15.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:3d08afd128ddaa624a48cf2b859afef385b720bb4b43df214f85616922e6a5ac"}, + {url = "https://files.pythonhosted.org/packages/2b/a8/050ab4f0c3d4c1b8aaa805f70e26e84d0e27004907c5b8ecc1d31815f92a/cffi-1.15.1.tar.gz", hash = "sha256:d400bfb9a37b1351253cb402671cea7e89bdecc294e8016a707f6d1d8ac934f9"}, + {url = "https://files.pythonhosted.org/packages/2d/86/3ca57cddfa0419f6a95d1c8478f8f622ba597e3581fd501bbb915b20eb75/cffi-1.15.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5d598b938678ebf3c67377cdd45e09d431369c3b1a5b331058c338e201f12b27"}, + {url = "https://files.pythonhosted.org/packages/2e/7a/68c35c151e5b7a12650ecc12fdfb85211aa1da43e9924598451c4a0a3839/cffi-1.15.1-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a8c4917bd7ad33e8eb21e9a5bbba979b49d9a97acb3a803092cbc1133e20343c"}, + {url = "https://files.pythonhosted.org/packages/32/2a/63cb8c07d151de92ff9d897b2eb27ba6a0e78dda8e4c5f70d7b8c16cd6a2/cffi-1.15.1-cp37-cp37m-win_amd64.whl", hash = "sha256:a0b71b1b8fbf2b96e41c4d990244165e2c9be83d54962a9a1d118fd8657d2045"}, + {url = "https://files.pythonhosted.org/packages/32/bd/d0809593f7976828f06a492716fbcbbfb62798bbf60ea1f65200b8d49901/cffi-1.15.1-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:fa6693661a4c91757f4412306191b6dc88c1703f780c8234035eac011922bc01"}, + {url = "https://files.pythonhosted.org/packages/37/5a/c37631a86be838bdd84cc0259130942bf7e6e32f70f4cab95f479847fb91/cffi-1.15.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:94411f22c3985acaec6f83c6df553f2dbe17b698cc7f8ae751ff2237d96b9e3c"}, + {url = "https://files.pythonhosted.org/packages/3a/12/d6066828014b9ccb2bbb8e1d9dc28872d20669b65aeb4a86806a0757813f/cffi-1.15.1-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:6975a3fac6bc83c4a65c9f9fcab9e47019a11d3d2cf7f3c0d03431bf145a941e"}, + {url = "https://files.pythonhosted.org/packages/3a/75/a162315adeaf47e94a3b7f886a8e31d77b9e525a387eef2d6f0efc96a7c8/cffi-1.15.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:fcd131dd944808b5bdb38e6f5b53013c5aa4f334c5cad0c72742f6eba4b73db0"}, + {url = "https://files.pythonhosted.org/packages/3f/fa/dfc242febbff049509e5a35a065bdc10f90d8c8585361c2c66b9c2f97a01/cffi-1.15.1-cp27-cp27m-macosx_10_9_x86_64.whl", hash = "sha256:a66d3508133af6e8548451b25058d5812812ec3798c886bf38ed24a98216fab2"}, + {url = "https://files.pythonhosted.org/packages/43/a0/cc7370ef72b6ee586369bacd3961089ab3d94ae712febf07a244f1448ffd/cffi-1.15.1-cp311-cp311-win_amd64.whl", hash = "sha256:04ed324bda3cda42b9b695d51bb7d54b680b9719cfab04227cdd1e04e5de3104"}, + {url = "https://files.pythonhosted.org/packages/47/51/3049834f07cd89aceef27f9c56f5394ca6725ae6a15cff5fbdb2f06a24ad/cffi-1.15.1-cp36-cp36m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:cec7d9412a9102bdc577382c3929b337320c4c4c4849f2c5cdd14d7368c5562d"}, + {url = "https://files.pythonhosted.org/packages/47/97/137f0e3d2304df2060abb872a5830af809d7559a5a4b6a295afb02728e65/cffi-1.15.1-cp38-cp38-win32.whl", hash = "sha256:8b7ee99e510d7b66cdb6c593f21c043c248537a32e0bedf02e01e9553a172314"}, + {url = "https://files.pythonhosted.org/packages/50/34/4cc590ad600869502c9838b4824982c122179089ed6791a8b1c95f0ff55e/cffi-1.15.1-cp37-cp37m-win32.whl", hash = "sha256:e229a521186c75c8ad9490854fd8bbdd9a0c9aa3a524326b55be83b54d4e0ad9"}, + {url = "https://files.pythonhosted.org/packages/5b/1a/e1ee5bed11d8b6540c05a8e3c32448832d775364d4461dd6497374533401/cffi-1.15.1-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8102eaf27e1e448db915d08afa8b41d6c7ca7a04b7d73af6514df10a3e74bd82"}, + {url = "https://files.pythonhosted.org/packages/5d/4e/4e0bb5579b01fdbfd4388bd1eb9394a989e1336203a4b7f700d887b233c1/cffi-1.15.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:91fc98adde3d7881af9b59ed0294046f3806221863722ba7d8d120c575314325"}, + {url = "https://files.pythonhosted.org/packages/5d/6f/3a2e167113eabd46ed300ff3a6a1e9277a3ad8b020c4c682f83e9326fcf7/cffi-1.15.1-cp36-cp36m-win32.whl", hash = "sha256:2470043b93ff09bf8fb1d46d1cb756ce6132c54826661a32d4e4d132e1977adf"}, + {url = "https://files.pythonhosted.org/packages/69/bf/335f8d95510b1a26d7c5220164dc739293a71d5540ecd54a2f66bac3ecb8/cffi-1.15.1-cp36-cp36m-win_amd64.whl", hash = "sha256:30d78fbc8ebf9c92c9b7823ee18eb92f2e6ef79b45ac84db507f52fbe3ec4497"}, + {url = "https://files.pythonhosted.org/packages/71/d7/0fe0d91b0bbf610fb7254bb164fa8931596e660d62e90fb6289b7ee27b09/cffi-1.15.1-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:03425bdae262c76aad70202debd780501fabeaca237cdfddc008987c0e0f59ef"}, + {url = "https://files.pythonhosted.org/packages/77/b7/d3618d612be01e184033eab90006f8ca5b5edafd17bf247439ea4e167d8a/cffi-1.15.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6c9a799e985904922a4d207a94eae35c78ebae90e128f0c4e521ce339396be9d"}, + {url = "https://files.pythonhosted.org/packages/79/4b/33494eb0adbcd884656c48f6db0c98ad8a5c678fb8fb5ed41ab546b04d8c/cffi-1.15.1-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:87c450779d0914f2861b8526e035c5e6da0a3199d8f1add1a665e1cbc6fc6d02"}, + {url = "https://files.pythonhosted.org/packages/7c/3e/5d823e5bbe00285e479034bcad44177b7353ec9fdcd7795baac5ccf82950/cffi-1.15.1-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:50a74364d85fd319352182ef59c5c790484a336f6db772c1a9231f1c3ed0cbd7"}, + {url = "https://files.pythonhosted.org/packages/85/1f/a3c533f8d377da5ca7edb4f580cc3edc1edbebc45fac8bb3ae60f1176629/cffi-1.15.1-cp39-cp39-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7473e861101c9e72452f9bf8acb984947aa1661a7704553a9f6e4baa5ba64415"}, + {url = "https://files.pythonhosted.org/packages/87/4b/64e8bd9d15d6b22b6cb11997094fbe61edf453ea0a97c8675cb7d1c3f06f/cffi-1.15.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:320dab6e7cb2eacdf0e658569d2575c4dad258c0fcc794f46215e1e39f90f2c3"}, + {url = "https://files.pythonhosted.org/packages/87/ee/ddc23981fc0f5e7b5356e98884226bcb899f95ebaefc3e8e8b8742dd7e22/cffi-1.15.1-cp311-cp311-win32.whl", hash = "sha256:a0f100c8912c114ff53e1202d0078b425bee3649ae34d7b070e9697f93c5d52d"}, + {url = "https://files.pythonhosted.org/packages/88/89/c34caf63029fb7628ec2ebd5c88ae0c9bd17db98c812e4065a4d020ca41f/cffi-1.15.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dd86c085fae2efd48ac91dd7ccffcfc0571387fe1193d33b6394db7ef31fe2a4"}, + {url = "https://files.pythonhosted.org/packages/91/bc/b7723c2fe7a22eee71d7edf2102cd43423d5f95ff3932ebaa2f82c7ec8d0/cffi-1.15.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3548db281cd7d2561c9ad9984681c95f7b0e38881201e157833a2342c30d5e8c"}, + {url = "https://files.pythonhosted.org/packages/93/d0/2e2b27ea2f69b0ec9e481647822f8f77f5fc23faca2dd00d1ff009940eb7/cffi-1.15.1-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0e2642fe3142e4cc4af0799748233ad6da94c62a8bec3a6648bf8ee68b1c7426"}, + {url = "https://files.pythonhosted.org/packages/9f/52/1e2b43cfdd7d9a39f48bc89fcaee8d8685b1295e205a4f1044909ac14d89/cffi-1.15.1-cp310-cp310-win32.whl", hash = "sha256:cba9d6b9a7d64d4bd46167096fc9d2f835e25d7e4c121fb2ddfc6528fb0413b2"}, + {url = "https://files.pythonhosted.org/packages/a4/42/54bdf22cf6c8f95113af645d0bd7be7f9358ea5c2d57d634bb11c6b4d0b2/cffi-1.15.1-cp27-cp27mu-manylinux1_x86_64.whl", hash = "sha256:ed9cb427ba5504c1dc15ede7d516b84757c3e3d7868ccc85121d9310d27eed0b"}, + {url = "https://files.pythonhosted.org/packages/a8/16/06b84a7063a4c0a2b081030fdd976022086da9c14e80a9ed4ba0183a98a9/cffi-1.15.1-cp39-cp39-win_amd64.whl", hash = "sha256:70df4e3b545a17496c9b3f41f5115e69a4f2e77e94e1d2a8e1070bc0c38c8a3c"}, + {url = "https://files.pythonhosted.org/packages/a9/ba/e082df21ebaa9cb29f2c4e1d7e49a29b90fcd667d43632c6674a16d65382/cffi-1.15.1-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3bcde07039e586f91b45c88f8583ea7cf7a0770df3a1649627bf598332cb6984"}, + {url = "https://files.pythonhosted.org/packages/aa/02/ab15b3aa572759df752491d5fa0f74128cd14e002e8e3257c1ab1587810b/cffi-1.15.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2012c72d854c2d03e45d06ae57f40d78e5770d252f195b93f581acf3ba44496e"}, + {url = "https://files.pythonhosted.org/packages/ad/26/7b3a73ab7d82a64664c7c4ea470e4ec4a3c73bb4f02575c543a41e272de5/cffi-1.15.1-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:db0fbb9c62743ce59a9ff687eb5f4afbe77e5e8403d6697f7446e5f609976f76"}, + {url = "https://files.pythonhosted.org/packages/af/cb/53b7bba75a18372d57113ba934b27d0734206c283c1dfcc172347fbd9f76/cffi-1.15.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:33ab79603146aace82c2427da5ca6e58f2b3f2fb5da893ceac0c42218a40be35"}, + {url = "https://files.pythonhosted.org/packages/af/da/9441d56d7dd19d07dcc40a2a5031a1f51c82a27cee3705edf53dadcac398/cffi-1.15.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5635bd9cb9731e6d4a1132a498dd34f764034a8ce60cef4f5319c0541159392f"}, + {url = "https://files.pythonhosted.org/packages/b3/b8/89509b6357ded0cbacc4e430b21a4ea2c82c2cdeb4391c148b7c7b213bed/cffi-1.15.1-cp36-cp36m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:4289fc34b2f5316fbb762d75362931e351941fa95fa18789191b33fc4cf9504a"}, + {url = "https://files.pythonhosted.org/packages/b5/7d/df6c088ef30e78a78b0c9cca6b904d5abb698afb5bc8f5191d529d83d667/cffi-1.15.1-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:198caafb44239b60e252492445da556afafc7d1e3ab7a1fb3f0584ef6d742375"}, + {url = "https://files.pythonhosted.org/packages/b5/80/ce5ba093c2475a73df530f643a61e2969a53366e372b24a32f08cd10172b/cffi-1.15.1-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e263d77ee3dd201c3a142934a086a4450861778baaeeb45db4591ef65550b0a6"}, + {url = "https://files.pythonhosted.org/packages/b7/8b/06f30caa03b5b3ac006de4f93478dbd0239e2a16566d81a106c322dc4f79/cffi-1.15.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4f2c9f67e9821cad2e5f480bc8d83b8742896f1242dba247911072d4fa94c192"}, + {url = "https://files.pythonhosted.org/packages/b9/4a/dde4d093a3084d0b0eadfb2703f71e31a5ced101a42c839ac5bbbd1710f2/cffi-1.15.1-cp27-cp27mu-manylinux1_i686.whl", hash = "sha256:d61f4695e6c866a23a21acab0509af1cdfd2c013cf256bbf5b6b5e2695827162"}, + {url = "https://files.pythonhosted.org/packages/c1/25/16a082701378170559bb1d0e9ef2d293cece8dc62913d79351beb34c5ddf/cffi-1.15.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a5c84c68147988265e60416b57fc83425a78058853509c1b0629c180094904a5"}, + {url = "https://files.pythonhosted.org/packages/c2/0b/3b09a755ddb977c167e6d209a7536f6ade43bb0654bad42e08df1406b8e4/cffi-1.15.1-cp37-cp37m-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:5ef34d190326c3b1f822a5b7a45f6c4535e2f47ed06fec77d3d799c450b2651e"}, + {url = "https://files.pythonhosted.org/packages/c5/ff/3f9d73d480567a609e98beb0c64359f8e4f31cb6a407685da73e5347b067/cffi-1.15.1-cp27-cp27m-win32.whl", hash = "sha256:b3bbeb01c2b273cca1e1e0c5df57f12dce9a4dd331b4fa1635b8bec26350bde3"}, + {url = "https://files.pythonhosted.org/packages/c6/3d/dd085bb831b22ce4d0b7ba8550e6d78960f02f770bbd1314fea3580727f8/cffi-1.15.1-cp39-cp39-win32.whl", hash = "sha256:40f4774f5a9d4f5e344f31a32b5096977b5d48560c5592e2f3d2c4374bd543ee"}, + {url = "https://files.pythonhosted.org/packages/c9/e3/0a52838832408cfbbf3a59cb19bcd17e64eb33795c9710ca7d29ae10b5b7/cffi-1.15.1-cp38-cp38-win_amd64.whl", hash = "sha256:00a9ed42e88df81ffae7a8ab6d9356b371399b91dbdf0c3cb1e84c03a13aceb5"}, + {url = "https://files.pythonhosted.org/packages/d3/56/3e94aa719ae96eeda8b68b3ec6e347e0a23168c6841dc276ccdcdadc9f32/cffi-1.15.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:cc4d65aeeaa04136a12677d3dd0b1c0c94dc43abac5860ab33cceb42b801c1e8"}, + {url = "https://files.pythonhosted.org/packages/d3/e1/e55ca2e0dd446caa2cc8f73c2b98879c04a1f4064ac529e1836683ca58b8/cffi-1.15.1-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5df2768244d19ab7f60546d0c7c63ce1581f7af8b5de3eb3004b9b6fc8a9f84b"}, + {url = "https://files.pythonhosted.org/packages/da/ff/ab939e2c7b3f40d851c0f7192c876f1910f3442080c9c846532993ec3cef/cffi-1.15.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:98d85c6a2bef81588d9227dde12db8a7f47f639f4a17c9ae08e773aa9c697bf3"}, + {url = "https://files.pythonhosted.org/packages/df/02/aef53d4aa43154b829e9707c8c60bab413cd21819c4a36b0d7aaa83e2a61/cffi-1.15.1-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3b926aa83d1edb5aa5b427b4053dc420ec295a08e40911296b9eb1b6170f6cca"}, + {url = "https://files.pythonhosted.org/packages/e8/ff/c4b7a358526f231efa46a375c959506c87622fb4a2c5726e827c55e6adf2/cffi-1.15.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:39d39875251ca8f612b6f33e6b1195af86d1b3e60086068be9cc053aa4376e21"}, + {url = "https://files.pythonhosted.org/packages/ea/be/c4ad40ad441ac847b67c7a37284ae3c58f39f3e638c6b0f85fb662233825/cffi-1.15.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:285d29981935eb726a4399badae8f0ffdff4f5050eaa6d0cfc3f64b857b77185"}, + {url = "https://files.pythonhosted.org/packages/ed/a3/c5f01988ddb70a187c3e6112152e01696188c9f8a4fa4c68aa330adbb179/cffi-1.15.1-cp310-cp310-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3eb6971dcff08619f8d91607cfc726518b6fa2a9eba42856be181c6d0d9515fd"}, + {url = "https://files.pythonhosted.org/packages/ef/41/19da352d341963d29a33bdb28433ba94c05672fb16155f794fad3fd907b0/cffi-1.15.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:21157295583fe8943475029ed5abdcf71eb3911894724e360acff1d61c1d54bc"}, + {url = "https://files.pythonhosted.org/packages/f9/96/fc9e118c47b7adc45a0676f413b4a47554e5f3b6c99b8607ec9726466ef1/cffi-1.15.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:3799aecf2e17cf585d977b780ce79ff0dc9b78d799fc694221ce814c2c19db83"}, + {url = "https://files.pythonhosted.org/packages/ff/fe/ac46ca7b00e9e4f9c62e7928a11bc9227c86e2ff43526beee00cdfb4f0e8/cffi-1.15.1-cp27-cp27m-manylinux1_i686.whl", hash = "sha256:470c103ae716238bbe698d67ad020e1db9d9dba34fa5a899b5e21577e6d52ed2"}, + {url = "https://test-files.pythonhosted.org/packages/de/b0/ee80a110b7efabc2e7a952973c74c1bbffd1e4eda707f9e932fcd53fdca4/cffi-1.15.1-cp311-cp311-win_arm64.whl", hash = "sha256:e2fb0d88adc12260498e8c291b20d4ecf8f74dea78c5cd3d5880c1e68158345f"}, +] +"charset-normalizer 2.1.1" = [ + {url = "https://files.pythonhosted.org/packages/a1/34/44964211e5410b051e4b8d2869c470ae8a68ae274953b1c7de6d98bbcf94/charset-normalizer-2.1.1.tar.gz", hash = "sha256:5a3d016c7c547f69d6f81fb0db9449ce888b418b5b9952cc5e6e66843e9dd845"}, + {url = "https://files.pythonhosted.org/packages/db/51/a507c856293ab05cdc1db77ff4bc1268ddd39f29e7dc4919aa497f0adbec/charset_normalizer-2.1.1-py3-none-any.whl", hash = "sha256:83e9a75d1911279afd89352c68b45348559d1fc0506b054b346651b5e7fee29f"}, +] +"click 8.1.3" = [ + {url = "https://files.pythonhosted.org/packages/59/87/84326af34517fca8c58418d148f2403df25303e02736832403587318e9e8/click-8.1.3.tar.gz", hash = "sha256:7682dc8afb30297001674575ea00d1814d808d6a36af415a82bd481d37ba7b8e"}, + {url = "https://files.pythonhosted.org/packages/c2/f1/df59e28c642d583f7dacffb1e0965d0e00b218e0186d7858ac5233dce840/click-8.1.3-py3-none-any.whl", hash = "sha256:bb4d8133cb15a609f44e8213d9b391b0809795062913b383c62be0ee95b1db48"}, + {url = "https://test-files.pythonhosted.org/packages/59/87/84326af34517fca8c58418d148f2403df25303e02736832403587318e9e8/click-8.1.3.tar.gz", hash = "sha256:7682dc8afb30297001674575ea00d1814d808d6a36af415a82bd481d37ba7b8e"}, + {url = "https://test-files.pythonhosted.org/packages/c2/f1/df59e28c642d583f7dacffb1e0965d0e00b218e0186d7858ac5233dce840/click-8.1.3-py3-none-any.whl", hash = "sha256:bb4d8133cb15a609f44e8213d9b391b0809795062913b383c62be0ee95b1db48"}, +] +"coincurve 17.0.0" = [ + {url = "https://files.pythonhosted.org/packages/02/73/3e04569c0cb7478383710d1f7612e8da4d79eac1aa18522ac44f7dae5ec6/coincurve-17.0.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6aec70238dbe7a5d66b5f9438ff45b08eb5e0990d49c32ebb65247c5d5b89d7a"}, + {url = "https://files.pythonhosted.org/packages/08/63/f2510bae1af0ce4bf6f6272bbe27fd20876695362b20d5df114d9295f7c5/coincurve-17.0.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b1bef812da1da202cdd601a256825abcf26d86e8634fac3ec3e615e3bb3ff08c"}, + {url = "https://files.pythonhosted.org/packages/28/cf/eccd05c927792538bfe3e3357c9ad07584d288a3984ff55527e268b50a64/coincurve-17.0.0-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f47806527d3184da3e8b146fac92a8ed567bbd225194f4517943d8cdc85f9542"}, + {url = "https://files.pythonhosted.org/packages/29/06/b84a8ea38c24f168b8674fda3f87e99478692df52856dd43b692a57ad740/coincurve-17.0.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:0503326963916c85b61d16f611ea0545f03c9e418fa8007c233c815429e381e8"}, + {url = "https://files.pythonhosted.org/packages/29/94/293294bd71a0370a6dae079773db9cd2aed825ff1df975cb865158a1f0ec/coincurve-17.0.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1013c1597b65684ae1c3e42497f9ef5a04527fa6136a84a16b34602606428c74"}, + {url = "https://files.pythonhosted.org/packages/34/8e/5b705213841580f5f1378f7e9a8766b2d698037bc84892db8d1a41c87deb/coincurve-17.0.0-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:74cedb3d3a1dc5abe0c9c2396e1b82cc64496babc5b42e007e72e185cb1edad8"}, + {url = "https://files.pythonhosted.org/packages/3f/01/970679d7c3c152a6710b550298d4d09e415c9f5cfdbcc7fb95b282bed5fa/coincurve-17.0.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:c71caffb97dd3d0c243beb62352669b1e5dafa3a4bccdbb27d36bd82f5e65d20"}, + {url = "https://files.pythonhosted.org/packages/63/e9/31d148c8333d43cd5f0d406ddd5baf43be4dac69fcf96590150e80f649da/coincurve-17.0.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:b88642edf7f281649b0c0b6ffade051945ccceae4b885e40445634877d0b3049"}, + {url = "https://files.pythonhosted.org/packages/65/5f/2c2b9d86f62b3453104e63aa2aaed987a58762b8101e0d878f6bd7880995/coincurve-17.0.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:ac8c87d6fd080faa74e7ecf64a6ed20c11a254863238759eb02c3f13ad12b0c4"}, + {url = "https://files.pythonhosted.org/packages/65/e9/e64d29c3f1ec9fe0fe4a114b95556e23d63bde0d48ec80e5ba22a3531a1f/coincurve-17.0.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:db874c5c1dcb1f3a19379773b5e8cffc777625a7a7a60dd9a67206e31e62e2e9"}, + {url = "https://files.pythonhosted.org/packages/66/32/8c15a00d4452f65e01b18cf543d49897882b4a8a48e7f65470ce152a2696/coincurve-17.0.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:896b01941254f0a218cf331a9bddfe2d43892f7f1ba10d6e372e2eb744a744c2"}, + {url = "https://files.pythonhosted.org/packages/66/e3/43c2766e850ad6dad13bf4b2005f22007f33f300064fe444f0f832381d7a/coincurve-17.0.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8852dc01af4f0fe941ffd04069f7e4fecdce9b867a016f823a02286a1a1f07b5"}, + {url = "https://files.pythonhosted.org/packages/69/1c/d6f976de439a1e98faea23a6dee96cfaf47ea01c94b87335efbaa2260fb8/coincurve-17.0.0-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:e2c2e8a1f0b1f8e48049c891af4ae3cad65d115d358bde72f6b8abdbb8a23170"}, + {url = "https://files.pythonhosted.org/packages/83/a3/98a8e1cbad2b12f869966ce14f31c722dbf116b20dea6f3f8139b1b655d1/coincurve-17.0.0-py3-none-win_amd64.whl", hash = "sha256:630388080da3026e0b0176cc6762eaabecba857ee3fc85767577dea063ea7c6e"}, + {url = "https://files.pythonhosted.org/packages/88/4d/16a487d4fc1d854b7266d208af2507e4babd07f52d5ede1a7b4c07a233ae/coincurve-17.0.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:25dfa105beba24c8de886f8ed654bb1133866e4e22cfd7ea5ad8438cae6ed924"}, + {url = "https://files.pythonhosted.org/packages/89/16/6bf9aa224615cafedc319cf5ed355d3a984144bbc82a9e7d1d19da97afd8/coincurve-17.0.0-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e4beef321fd6434448aab03a0c245f31c4e77f43b54b82108c0948d29852ac7e"}, + {url = "https://files.pythonhosted.org/packages/8a/24/4b218c110341cadb728efed4e0ea40450dd7e1cc080b574673ac96f5095e/coincurve-17.0.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4ea057f777842396d387103c606babeb3a1b4c6126769cc0a12044312fc6c465"}, + {url = "https://files.pythonhosted.org/packages/8d/0b/317a2d20a29cd296a5d19abb6f642d067b2a596695781a8051a01c8ed070/coincurve-17.0.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:73f39579dd651a9fc29da5a8fc0d8153d872bcbc166f876457baced1a1c01501"}, + {url = "https://files.pythonhosted.org/packages/94/6a/60401d0723aff65138e6eba7be09f63998ac96bfb64509c4aa020541abd6/coincurve-17.0.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:f1ef72574aa423bc33665ef4be859164a478bad24d48442da874ef3dc39a474d"}, + {url = "https://files.pythonhosted.org/packages/95/79/646c5fc4fc204c11a2129ab8ef2fdda9e64ce2f4ce04b79a274899ae5d84/coincurve-17.0.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d154e2eb5711db8c5ef52fcd80935b5a0e751c057bc6ffb215a7bb409aedef03"}, + {url = "https://files.pythonhosted.org/packages/98/9f/da66d4a851925110dc03371db036551074a039700c089ce5f94af3ac7842/coincurve-17.0.0-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:747215254e51dd4dfbe6dded9235491263da5d88fe372d66541ca16b51ea078f"}, + {url = "https://files.pythonhosted.org/packages/9e/f2/482210b2330fb453fd84b7309b9b79e49e6f17dd0efa70ff4d427156f144/coincurve-17.0.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:ad2f6df39ba1e2b7b14bb984505ffa7d0a0ecdd697e8d7dbd19e04bc245c87ed"}, + {url = "https://files.pythonhosted.org/packages/a8/8d/74eb01cbf256ecb10140bf67e1a2e0f5ac1751fbc1347bc7e52f399f2b89/coincurve-17.0.0.tar.gz", hash = "sha256:68da55aff898702952fda3ee04fd6ed60bb6b91f919c69270786ed766b548b93"}, + {url = "https://files.pythonhosted.org/packages/b8/1c/558879c99e3abdea2a870cac35601fe8957b6006c8ff76851968326c5f61/coincurve-17.0.0-py3-none-win32.whl", hash = "sha256:b956b0b2c85e25a7d00099970ff5d8338254b45e46f0a940f4a2379438ce0dde"}, + {url = "https://files.pythonhosted.org/packages/b9/e5/8f7b2d8e9d777b42e16eca3e8ab308953cf4539eb5e04e7bb1200fe752e4/coincurve-17.0.0-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:3d694ad194bee9e8792e2e75879dc5238d8a184010cde36c5ad518fcfe2cd8f2"}, + {url = "https://files.pythonhosted.org/packages/c9/10/f0d5eaa344fd147bda5e80d254807a5fc500c1758034140199d2858392f6/coincurve-17.0.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:abbefc9ccb170cb255a31df32457c2e43084b9f37589d0694dacc2dea6ddaf7c"}, + {url = "https://files.pythonhosted.org/packages/d5/8b/fad420c85fb6772485dbc63388a6593d56b0a6d4c24448bffc9d92ce4490/coincurve-17.0.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:abbd9d017a7638dc38a3b9bb4851f8801b7818d4e5ac22e0c75e373b3c1dbff0"}, + {url = "https://files.pythonhosted.org/packages/d7/04/8e69159edcce60a7a60df2afbc85300158a5d756061ebdfede15801efe6b/coincurve-17.0.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:dfd4fab857bcd975edc39111cb5f5c104f138dac2e9ace35ea8434d37bcea3be"}, + {url = "https://files.pythonhosted.org/packages/db/83/6c42d6bf051034c5b4a01b8e5d4d8aa905af7340fec864f69e38338554fe/coincurve-17.0.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:8c571445b166c714af4f8155e38a894376c16c0431e88963f2fff474a9985d87"}, + {url = "https://files.pythonhosted.org/packages/e0/f6/7502bdc8b3768441e8769eea5959d3ff586dc5baa7b9840986a6702e5e07/coincurve-17.0.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d24284d17162569df917a640f19d9654ba3b43cf560ced8864f270da903f73a5"}, + {url = "https://files.pythonhosted.org/packages/e7/5b/d30131984b8b048a2f778384b109471cbe5e3f0ebf2b3bcc289269600c88/coincurve-17.0.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:698efdd53e4fe1bbebaee9b75cbc851be617974c1c60098e9145cb7198ae97fb"}, + {url = "https://files.pythonhosted.org/packages/f2/69/b0e6e1cee2f14f7bd1e1af640a3e2a9649aab19de124dfd8422c9218358f/coincurve-17.0.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:30dd44d1039f1d237aaa2da6d14a455ca88df3bcb00610b41f3253fdca1be97b"}, + {url = "https://files.pythonhosted.org/packages/f2/c1/dda5434308b3940dfdb84bc24351cf34f2aa846b2a7aaaefdaad528283d5/coincurve-17.0.0-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:51e56373ac79f4ec1cfc5da53d72c55f5e5ac28d848b0849ef5e687ace857888"}, + {url = "https://files.pythonhosted.org/packages/fc/bd/9d0ef98d759005bab56212d9ff21b84dda6f49b9b43a08f0e0416d032410/coincurve-17.0.0-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:a80a207131813b038351c5bdae8f20f5f774bbf53622081f208d040dd2b7528f"}, +] +"colorama 0.4.6" = [ + {url = "https://files.pythonhosted.org/packages/d1/d6/3965ed04c63042e047cb6a3e6ed1a63a35087b6a609aa3a15ed8ac56c221/colorama-0.4.6-py2.py3-none-any.whl", hash = "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6"}, + {url = "https://files.pythonhosted.org/packages/d8/53/6f443c9a4a8358a93a6792e2acffb9d9d5cb0a5cfd8802644b7b1c9a02e4/colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44"}, + {url = "https://test-files.pythonhosted.org/packages/d1/d6/3965ed04c63042e047cb6a3e6ed1a63a35087b6a609aa3a15ed8ac56c221/colorama-0.4.6-py2.py3-none-any.whl", hash = "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6"}, + {url = "https://test-files.pythonhosted.org/packages/d8/53/6f443c9a4a8358a93a6792e2acffb9d9d5cb0a5cfd8802644b7b1c9a02e4/colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44"}, +] +"construct 2.10.68" = [ + {url = "https://files.pythonhosted.org/packages/e0/b7/a4a032e94bcfdff481f2e6fecd472794d9da09f474a2185ed33b2c7cad64/construct-2.10.68.tar.gz", hash = "sha256:7b2a3fd8e5f597a5aa1d614c3bd516fa065db01704c72a1efaaeec6ef23d8b45"}, +] +"coverage 6.5.0" = [ + {url = "https://files.pythonhosted.org/packages/02/7a/a45f3958442d50b9a930a62f0dba9ee502521213ebd016203c2890ea212f/coverage-6.5.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:20c8ac5386253717e5ccc827caad43ed66fea0efe255727b1053a8154d952398"}, + {url = "https://files.pythonhosted.org/packages/05/63/a789b462075395d34f8152229dccf92b25ca73eac05b3f6cd75fa5017095/coverage-6.5.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:d900bb429fdfd7f511f868cedd03a6bbb142f3f9118c09b99ef8dc9bf9643c3c"}, + {url = "https://files.pythonhosted.org/packages/06/f1/5177428c35f331f118e964f727f79e3a3073a10271a644c8361d3cea8bfd/coverage-6.5.0-cp38-cp38-win_amd64.whl", hash = "sha256:7ccf362abd726b0410bf8911c31fbf97f09f8f1061f8c1cf03dfc4b6372848f6"}, + {url = "https://files.pythonhosted.org/packages/07/82/79fa21ceca9a9b091eb3c67e27eb648dade27b2c9e1eb23af47232a2a365/coverage-6.5.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:2198ea6fc548de52adc826f62cb18554caedfb1d26548c1b7c88d8f7faa8f6ba"}, + {url = "https://files.pythonhosted.org/packages/0d/ef/8735875a8dc09e1c4e484a5436c8b4148731b70daccc6f203c50b05e7505/coverage-6.5.0-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:027018943386e7b942fa832372ebc120155fd970837489896099f5cfa2890f79"}, + {url = "https://files.pythonhosted.org/packages/10/9e/68e384940179713640743a010ac7f7c813d1087c8730a9c0bdfa73bdffd7/coverage-6.5.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:97117225cdd992a9c2a5515db1f66b59db634f59d0679ca1fa3fe8da32749cae"}, + {url = "https://files.pythonhosted.org/packages/11/9e/7afba355bdabc550b3b2669e3432e71aec87d79400372d7686c09aab0acf/coverage-6.5.0-cp310-cp310-win32.whl", hash = "sha256:5dbec3b9095749390c09ab7c89d314727f18800060d8d24e87f01fb9cfb40b32"}, + {url = "https://files.pythonhosted.org/packages/13/f3/c6025ba30f2ce21d20d5332c3819880fe8afdfc008c2e2f9c075c7b67543/coverage-6.5.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:83516205e254a0cb77d2d7bb3632ee019d93d9f4005de31dca0a8c3667d5bc04"}, + {url = "https://files.pythonhosted.org/packages/15/b0/3639d84ee8a900da0cf6450ab46e22517e4688b6cec0ba8ab6f8166103a2/coverage-6.5.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b4a5be1748d538a710f87542f22c2cad22f80545a847ad91ce45e77417293eb4"}, + {url = "https://files.pythonhosted.org/packages/18/95/27f80dcd8273171b781a19d109aeaed7f13d78ef6d1e2f7134a5826fd1b4/coverage-6.5.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b9023e237f4c02ff739581ef35969c3739445fb059b060ca51771e69101efffe"}, + {url = "https://files.pythonhosted.org/packages/2f/8b/ca3fe3cfbd66d63181f6e6a06b8b494bb327ba8222d2fa628b392b9ad08a/coverage-6.5.0-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:a1170fa54185845505fbfa672f1c1ab175446c887cce8212c44149581cf2d466"}, + {url = "https://files.pythonhosted.org/packages/32/40/e2b1ffa42028365e3465d1340e7d390d096fc992dec2c80e4afed6361e83/coverage-6.5.0-cp37-cp37m-win32.whl", hash = "sha256:b5604380f3415ba69de87a289a2b56687faa4fe04dbee0754bfcae433489316b"}, + {url = "https://files.pythonhosted.org/packages/36/f3/5cbd79cf4cd059c80b59104aca33b8d05af4ad5bf5b1547645ecee716378/coverage-6.5.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c4ed2820d919351f4167e52425e096af41bfabacb1857186c1ea32ff9983ed75"}, + {url = "https://files.pythonhosted.org/packages/3c/7d/d5211ea782b193ab8064b06dc0cc042cf1a4ca9c93a530071459172c550f/coverage-6.5.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:af4fffaffc4067232253715065e30c5a7ec6faac36f8fc8d6f64263b15f74db0"}, + {url = "https://files.pythonhosted.org/packages/40/3b/cd68cb278c4966df00158811ec1e357b9a7d132790c240fc65da57e10013/coverage-6.5.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6c4459b3de97b75e3bd6b7d4b7f0db13f17f504f3d13e2a7c623786289dd670e"}, + {url = "https://files.pythonhosted.org/packages/4b/66/6e588f5dfc93ccedd06d6785c8143f17bb92b89247d50128d8789e9588d0/coverage-6.5.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:cca4435eebea7962a52bdb216dec27215d0df64cf27fc1dd538415f5d2b9da6b"}, + {url = "https://files.pythonhosted.org/packages/50/cf/455930004231fa87efe8be06d13512f34e070ddfee8b8bf5a050cdc47ab3/coverage-6.5.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:4a5375e28c5191ac38cca59b38edd33ef4cc914732c916f2929029b4bfb50795"}, + {url = "https://files.pythonhosted.org/packages/58/2c/213861cec1d9f6451d29c0b1838769b558f6a8c6844b001f6e98c37c4b1b/coverage-6.5.0-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:42eafe6778551cf006a7c43153af1211c3aaab658d4d66fa5fcc021613d02518"}, + {url = "https://files.pythonhosted.org/packages/5c/66/38d1870cb7cf62da49add1d6803fdbcdef632b2808b5c80bcac35b7634d8/coverage-6.5.0.tar.gz", hash = "sha256:f642e90754ee3e06b0e7e51bce3379590e76b7f76b708e1a71ff043f87025c84"}, + {url = "https://files.pythonhosted.org/packages/61/a6/af54588e2091693026df94b09106ee10dcbcdc8c9b2c3989149e6e44a324/coverage-6.5.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:4433b90fae13f86fafff0b326453dd42fc9a639a0d9e4eec4d366436d1a41b6d"}, + {url = "https://files.pythonhosted.org/packages/63/e9/f23e8664ec4032d7802a1cf920853196bcbdce7b56408e3efe1b2da08f3c/coverage-6.5.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:95203854f974e07af96358c0b261f1048d8e1083f2de9b1c565e1be4a3a48cfc"}, + {url = "https://files.pythonhosted.org/packages/64/7f/13f5d58f5ca41182d7020af5257c8fd08ddf33921d2a28cf66753571c278/coverage-6.5.0-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:12adf310e4aafddc58afdb04d686795f33f4d7a6fa67a7a9d4ce7d6ae24d949f"}, + {url = "https://files.pythonhosted.org/packages/6a/63/8e82513b7e4a1b8d887b4e85c1c2b6c9b754a581b187c0b084f3330ac479/coverage-6.5.0-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a8fb6cf131ac4070c9c5a3e21de0f7dc5a0fbe8bc77c9456ced896c12fcdad91"}, + {url = "https://files.pythonhosted.org/packages/6b/ba/ef67c1e859b8ddd8cafb81199986ff702efcd4ee5d373670a0bc0a293d1f/coverage-6.5.0-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:94e2565443291bd778421856bc975d351738963071e9b8839ca1fc08b42d4bef"}, + {url = "https://files.pythonhosted.org/packages/6b/f2/919f0fdc93d3991ca074894402074d847be8ac1e1d78e7e9e1c371b69a6f/coverage-6.5.0-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8f830ed581b45b82451a40faabb89c84e1a998124ee4212d440e9c6cf70083e5"}, + {url = "https://files.pythonhosted.org/packages/6e/e6/b31a4b2aa9489da59b35ee0ea4259d6fe9b321a1eaa6492f19342d03d53b/coverage-6.5.0-pp36.pp37.pp38-none-any.whl", hash = "sha256:1431986dac3923c5945271f169f59c45b8802a114c8f548d611f2015133df77a"}, + {url = "https://files.pythonhosted.org/packages/76/44/78c1936c2bd9e7705f170d5e413ed34d9d6d7d0324757786627f88df1514/coverage-6.5.0-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:851cf4ff24062c6aec510a454b2584f6e998cada52d4cb58c5e233d07172e50c"}, + {url = "https://files.pythonhosted.org/packages/78/98/253ce0cfcc3b352d3072940940ed44a035614f2abe781477f77038d21d9f/coverage-6.5.0-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:1ef221513e6f68b69ee9e159506d583d31aa3567e0ae84eaad9d6ec1107dddaa"}, + {url = "https://files.pythonhosted.org/packages/85/03/9dcc8b7e269cfeaf5519d433d841a7d78f283c5fb016385d4690e1aedfc1/coverage-6.5.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f4f05d88d9a80ad3cac6244d36dd89a3c00abc16371769f1340101d3cb899fc3"}, + {url = "https://files.pythonhosted.org/packages/89/58/5ec19b43a6511288511f64fc4763d95af8403f5926e7e4556e6b29b03a26/coverage-6.5.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:33a7da4376d5977fbf0a8ed91c4dffaaa8dbf0ddbf4c8eea500a2486d8bc4d7b"}, + {url = "https://files.pythonhosted.org/packages/89/a2/cbf599e50bb4be416e0408c4cf523c354c51d7da39935461a9687e039481/coverage-6.5.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:784f53ebc9f3fd0e2a3f6a78b2be1bd1f5575d7863e10c6e12504f240fd06660"}, + {url = "https://files.pythonhosted.org/packages/8f/17/e1d54e0e5a1e82dea1b1d9463dfe347ded58037beda00d326f943a9ef2d4/coverage-6.5.0-cp39-cp39-win32.whl", hash = "sha256:d9ecf0829c6a62b9b573c7bb6d4dcd6ba8b6f80be9ba4fc7ed50bf4ac9aecd72"}, + {url = "https://files.pythonhosted.org/packages/a1/6b/7efeeffc7559150a705931b2144b936042c561e63ef248f0e0d9f4523d74/coverage-6.5.0-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:de3001a203182842a4630e7b8d1a2c7c07ec1b45d3084a83d5d227a3806f530f"}, + {url = "https://files.pythonhosted.org/packages/a3/a0/4c59586df0511b18f7b59593672a4baadacef8f393024052d59c6222477c/coverage-6.5.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:dbdb91cd8c048c2b09eb17713b0c12a54fbd587d79adcebad543bc0cd9a3410b"}, + {url = "https://files.pythonhosted.org/packages/a8/d9/b367c52cb1297414ba967e38fe9b5338ee4700a2d1592fc78532dc9f882f/coverage-6.5.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:7b6be138d61e458e18d8e6ddcddd36dd96215edfe5f1168de0b1b32635839b62"}, + {url = "https://files.pythonhosted.org/packages/ac/bc/c9d4fd6b3494d2cc1e26f4b98eb19206b92a59094617ad02d5689ac9d3c4/coverage-6.5.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:a6b7d95969b8845250586f269e81e5dfdd8ff828ddeb8567a4a2eaa7313460c4"}, + {url = "https://files.pythonhosted.org/packages/ae/a3/f45cb5d32de0751863945d22083c15eb8854bb53681b2e792f2066c629b9/coverage-6.5.0-cp310-cp310-win_amd64.whl", hash = "sha256:59f53f1dc5b656cafb1badd0feb428c1e7bc19b867479ff72f7a9dd9b479f10e"}, + {url = "https://files.pythonhosted.org/packages/b6/08/a88a9f3a11bb2d97c7a6719535a984b009728433838fbc65766488867c80/coverage-6.5.0-cp39-cp39-win_amd64.whl", hash = "sha256:fc2af30ed0d5ae0b1abdb4ebdce598eafd5b35397d4d75deb341a614d333d987"}, + {url = "https://files.pythonhosted.org/packages/bd/a0/e263b115808226fdb2658f1887808c06ac3f1b579ef5dda02309e0d54459/coverage-6.5.0-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6b07130585d54fe8dff3d97b93b0e20290de974dc8177c320aeaf23459219c0b"}, + {url = "https://files.pythonhosted.org/packages/c0/18/2a0a9b3c29376ce04ceb7ca2948559dad76409a2c9b3f664756581101e16/coverage-6.5.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:11b990d520ea75e7ee8dcab5bc908072aaada194a794db9f6d7d5cfd19661e5a"}, + {url = "https://files.pythonhosted.org/packages/c4/8d/5ec7d08f4601d2d792563fe31db5e9322c306848fec1e65ec8885927f739/coverage-6.5.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:ef8674b0ee8cc11e2d574e3e2998aea5df5ab242e012286824ea3c6970580e53"}, + {url = "https://files.pythonhosted.org/packages/c8/e8/e712b61abf1282ce3ac9826473ab4b245a4319303cce2e4115a8de1435f2/coverage-6.5.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:723e8130d4ecc8f56e9a611e73b31219595baa3bb252d539206f7bbbab6ffc1f"}, + {url = "https://files.pythonhosted.org/packages/cd/48/65d314e702b4a7095ea96da0a319a5a377e594354a4a6badde483832bb5a/coverage-6.5.0-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:255758a1e3b61db372ec2736c8e2a1fdfaf563977eedbdf131de003ca5779b7d"}, + {url = "https://files.pythonhosted.org/packages/d6/00/3e12af83af2a46c1fd27b78486f404736934d0288bda4975119611a01cb3/coverage-6.5.0-cp37-cp37m-win_amd64.whl", hash = "sha256:4a8dbc1f0fbb2ae3de73eb0bdbb914180c7abfbf258e90b311dcd4f585d44bd2"}, + {url = "https://files.pythonhosted.org/packages/d6/0f/012a7370aaf61123a222b34b657dedc63e03ce2af8d064ac5c5afe14f29c/coverage-6.5.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:265de0fa6778d07de30bcf4d9dc471c3dc4314a23a3c6603d356a3c9abc2dfcf"}, + {url = "https://files.pythonhosted.org/packages/e5/fb/11982f5faf2990d4d9159e01a12bbf0a7d7873893d4d2e2acec012ad69ae/coverage-6.5.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:e07f4a4a9b41583d6eabec04f8b68076ab3cd44c20bd29332c6572dda36f372e"}, + {url = "https://files.pythonhosted.org/packages/e6/24/7fe8ededb4060dd8c3f1d86cb624fcb3452f66fbef5051ed7fab126c5c0c/coverage-6.5.0-cp311-cp311-win_amd64.whl", hash = "sha256:bc8ef5e043a2af066fa8cbfc6e708d58017024dc4345a1f9757b329a249f041b"}, + {url = "https://files.pythonhosted.org/packages/e9/f0/3be949bd129237553714149b1909d34c94137ca4b86e036bc7060431da18/coverage-6.5.0-cp38-cp38-win32.whl", hash = "sha256:6d4817234349a80dbf03640cec6109cd90cba068330703fa65ddf56b60223a6d"}, + {url = "https://files.pythonhosted.org/packages/ea/52/c08080405329326a7ff16c0dfdb4feefaa8edd7446413df67386fe1bbfe0/coverage-6.5.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:633713d70ad6bfc49b34ead4060531658dc6dfc9b3eb7d8a716d5873377ab745"}, + {url = "https://files.pythonhosted.org/packages/ff/27/339089b558672f04e62d0cd2d49b9280270bad3bc95de24e7eb03deb4638/coverage-6.5.0-cp311-cp311-win32.whl", hash = "sha256:98e8a10b7a314f454d9eff4216a9a94d143a7ee65018dd12442e898ee2310578"}, + {url = "https://test-files.pythonhosted.org/packages/02/7a/a45f3958442d50b9a930a62f0dba9ee502521213ebd016203c2890ea212f/coverage-6.5.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:20c8ac5386253717e5ccc827caad43ed66fea0efe255727b1053a8154d952398"}, + {url = "https://test-files.pythonhosted.org/packages/05/63/a789b462075395d34f8152229dccf92b25ca73eac05b3f6cd75fa5017095/coverage-6.5.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:d900bb429fdfd7f511f868cedd03a6bbb142f3f9118c09b99ef8dc9bf9643c3c"}, + {url = "https://test-files.pythonhosted.org/packages/06/f1/5177428c35f331f118e964f727f79e3a3073a10271a644c8361d3cea8bfd/coverage-6.5.0-cp38-cp38-win_amd64.whl", hash = "sha256:7ccf362abd726b0410bf8911c31fbf97f09f8f1061f8c1cf03dfc4b6372848f6"}, + {url = "https://test-files.pythonhosted.org/packages/07/82/79fa21ceca9a9b091eb3c67e27eb648dade27b2c9e1eb23af47232a2a365/coverage-6.5.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:2198ea6fc548de52adc826f62cb18554caedfb1d26548c1b7c88d8f7faa8f6ba"}, + {url = "https://test-files.pythonhosted.org/packages/0d/ef/8735875a8dc09e1c4e484a5436c8b4148731b70daccc6f203c50b05e7505/coverage-6.5.0-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:027018943386e7b942fa832372ebc120155fd970837489896099f5cfa2890f79"}, + {url = "https://test-files.pythonhosted.org/packages/10/9e/68e384940179713640743a010ac7f7c813d1087c8730a9c0bdfa73bdffd7/coverage-6.5.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:97117225cdd992a9c2a5515db1f66b59db634f59d0679ca1fa3fe8da32749cae"}, + {url = "https://test-files.pythonhosted.org/packages/11/9e/7afba355bdabc550b3b2669e3432e71aec87d79400372d7686c09aab0acf/coverage-6.5.0-cp310-cp310-win32.whl", hash = "sha256:5dbec3b9095749390c09ab7c89d314727f18800060d8d24e87f01fb9cfb40b32"}, + {url = "https://test-files.pythonhosted.org/packages/13/f3/c6025ba30f2ce21d20d5332c3819880fe8afdfc008c2e2f9c075c7b67543/coverage-6.5.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:83516205e254a0cb77d2d7bb3632ee019d93d9f4005de31dca0a8c3667d5bc04"}, + {url = "https://test-files.pythonhosted.org/packages/15/b0/3639d84ee8a900da0cf6450ab46e22517e4688b6cec0ba8ab6f8166103a2/coverage-6.5.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b4a5be1748d538a710f87542f22c2cad22f80545a847ad91ce45e77417293eb4"}, + {url = "https://test-files.pythonhosted.org/packages/18/95/27f80dcd8273171b781a19d109aeaed7f13d78ef6d1e2f7134a5826fd1b4/coverage-6.5.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b9023e237f4c02ff739581ef35969c3739445fb059b060ca51771e69101efffe"}, + {url = "https://test-files.pythonhosted.org/packages/2f/8b/ca3fe3cfbd66d63181f6e6a06b8b494bb327ba8222d2fa628b392b9ad08a/coverage-6.5.0-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:a1170fa54185845505fbfa672f1c1ab175446c887cce8212c44149581cf2d466"}, + {url = "https://test-files.pythonhosted.org/packages/32/40/e2b1ffa42028365e3465d1340e7d390d096fc992dec2c80e4afed6361e83/coverage-6.5.0-cp37-cp37m-win32.whl", hash = "sha256:b5604380f3415ba69de87a289a2b56687faa4fe04dbee0754bfcae433489316b"}, + {url = "https://test-files.pythonhosted.org/packages/36/f3/5cbd79cf4cd059c80b59104aca33b8d05af4ad5bf5b1547645ecee716378/coverage-6.5.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c4ed2820d919351f4167e52425e096af41bfabacb1857186c1ea32ff9983ed75"}, + {url = "https://test-files.pythonhosted.org/packages/3c/7d/d5211ea782b193ab8064b06dc0cc042cf1a4ca9c93a530071459172c550f/coverage-6.5.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:af4fffaffc4067232253715065e30c5a7ec6faac36f8fc8d6f64263b15f74db0"}, + {url = "https://test-files.pythonhosted.org/packages/40/3b/cd68cb278c4966df00158811ec1e357b9a7d132790c240fc65da57e10013/coverage-6.5.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6c4459b3de97b75e3bd6b7d4b7f0db13f17f504f3d13e2a7c623786289dd670e"}, + {url = "https://test-files.pythonhosted.org/packages/4b/66/6e588f5dfc93ccedd06d6785c8143f17bb92b89247d50128d8789e9588d0/coverage-6.5.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:cca4435eebea7962a52bdb216dec27215d0df64cf27fc1dd538415f5d2b9da6b"}, + {url = "https://test-files.pythonhosted.org/packages/50/cf/455930004231fa87efe8be06d13512f34e070ddfee8b8bf5a050cdc47ab3/coverage-6.5.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:4a5375e28c5191ac38cca59b38edd33ef4cc914732c916f2929029b4bfb50795"}, + {url = "https://test-files.pythonhosted.org/packages/58/2c/213861cec1d9f6451d29c0b1838769b558f6a8c6844b001f6e98c37c4b1b/coverage-6.5.0-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:42eafe6778551cf006a7c43153af1211c3aaab658d4d66fa5fcc021613d02518"}, + {url = "https://test-files.pythonhosted.org/packages/5c/66/38d1870cb7cf62da49add1d6803fdbcdef632b2808b5c80bcac35b7634d8/coverage-6.5.0.tar.gz", hash = "sha256:f642e90754ee3e06b0e7e51bce3379590e76b7f76b708e1a71ff043f87025c84"}, + {url = "https://test-files.pythonhosted.org/packages/61/a6/af54588e2091693026df94b09106ee10dcbcdc8c9b2c3989149e6e44a324/coverage-6.5.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:4433b90fae13f86fafff0b326453dd42fc9a639a0d9e4eec4d366436d1a41b6d"}, + {url = "https://test-files.pythonhosted.org/packages/63/e9/f23e8664ec4032d7802a1cf920853196bcbdce7b56408e3efe1b2da08f3c/coverage-6.5.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:95203854f974e07af96358c0b261f1048d8e1083f2de9b1c565e1be4a3a48cfc"}, + {url = "https://test-files.pythonhosted.org/packages/64/7f/13f5d58f5ca41182d7020af5257c8fd08ddf33921d2a28cf66753571c278/coverage-6.5.0-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:12adf310e4aafddc58afdb04d686795f33f4d7a6fa67a7a9d4ce7d6ae24d949f"}, + {url = "https://test-files.pythonhosted.org/packages/6a/63/8e82513b7e4a1b8d887b4e85c1c2b6c9b754a581b187c0b084f3330ac479/coverage-6.5.0-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a8fb6cf131ac4070c9c5a3e21de0f7dc5a0fbe8bc77c9456ced896c12fcdad91"}, + {url = "https://test-files.pythonhosted.org/packages/6b/ba/ef67c1e859b8ddd8cafb81199986ff702efcd4ee5d373670a0bc0a293d1f/coverage-6.5.0-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:94e2565443291bd778421856bc975d351738963071e9b8839ca1fc08b42d4bef"}, + {url = "https://test-files.pythonhosted.org/packages/6b/f2/919f0fdc93d3991ca074894402074d847be8ac1e1d78e7e9e1c371b69a6f/coverage-6.5.0-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8f830ed581b45b82451a40faabb89c84e1a998124ee4212d440e9c6cf70083e5"}, + {url = "https://test-files.pythonhosted.org/packages/6e/e6/b31a4b2aa9489da59b35ee0ea4259d6fe9b321a1eaa6492f19342d03d53b/coverage-6.5.0-pp36.pp37.pp38-none-any.whl", hash = "sha256:1431986dac3923c5945271f169f59c45b8802a114c8f548d611f2015133df77a"}, + {url = "https://test-files.pythonhosted.org/packages/76/44/78c1936c2bd9e7705f170d5e413ed34d9d6d7d0324757786627f88df1514/coverage-6.5.0-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:851cf4ff24062c6aec510a454b2584f6e998cada52d4cb58c5e233d07172e50c"}, + {url = "https://test-files.pythonhosted.org/packages/78/98/253ce0cfcc3b352d3072940940ed44a035614f2abe781477f77038d21d9f/coverage-6.5.0-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:1ef221513e6f68b69ee9e159506d583d31aa3567e0ae84eaad9d6ec1107dddaa"}, + {url = "https://test-files.pythonhosted.org/packages/85/03/9dcc8b7e269cfeaf5519d433d841a7d78f283c5fb016385d4690e1aedfc1/coverage-6.5.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f4f05d88d9a80ad3cac6244d36dd89a3c00abc16371769f1340101d3cb899fc3"}, + {url = "https://test-files.pythonhosted.org/packages/89/58/5ec19b43a6511288511f64fc4763d95af8403f5926e7e4556e6b29b03a26/coverage-6.5.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:33a7da4376d5977fbf0a8ed91c4dffaaa8dbf0ddbf4c8eea500a2486d8bc4d7b"}, + {url = "https://test-files.pythonhosted.org/packages/89/a2/cbf599e50bb4be416e0408c4cf523c354c51d7da39935461a9687e039481/coverage-6.5.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:784f53ebc9f3fd0e2a3f6a78b2be1bd1f5575d7863e10c6e12504f240fd06660"}, + {url = "https://test-files.pythonhosted.org/packages/8f/17/e1d54e0e5a1e82dea1b1d9463dfe347ded58037beda00d326f943a9ef2d4/coverage-6.5.0-cp39-cp39-win32.whl", hash = "sha256:d9ecf0829c6a62b9b573c7bb6d4dcd6ba8b6f80be9ba4fc7ed50bf4ac9aecd72"}, + {url = "https://test-files.pythonhosted.org/packages/a1/6b/7efeeffc7559150a705931b2144b936042c561e63ef248f0e0d9f4523d74/coverage-6.5.0-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:de3001a203182842a4630e7b8d1a2c7c07ec1b45d3084a83d5d227a3806f530f"}, + {url = "https://test-files.pythonhosted.org/packages/a3/a0/4c59586df0511b18f7b59593672a4baadacef8f393024052d59c6222477c/coverage-6.5.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:dbdb91cd8c048c2b09eb17713b0c12a54fbd587d79adcebad543bc0cd9a3410b"}, + {url = "https://test-files.pythonhosted.org/packages/a8/d9/b367c52cb1297414ba967e38fe9b5338ee4700a2d1592fc78532dc9f882f/coverage-6.5.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:7b6be138d61e458e18d8e6ddcddd36dd96215edfe5f1168de0b1b32635839b62"}, + {url = "https://test-files.pythonhosted.org/packages/ac/bc/c9d4fd6b3494d2cc1e26f4b98eb19206b92a59094617ad02d5689ac9d3c4/coverage-6.5.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:a6b7d95969b8845250586f269e81e5dfdd8ff828ddeb8567a4a2eaa7313460c4"}, + {url = "https://test-files.pythonhosted.org/packages/ae/a3/f45cb5d32de0751863945d22083c15eb8854bb53681b2e792f2066c629b9/coverage-6.5.0-cp310-cp310-win_amd64.whl", hash = "sha256:59f53f1dc5b656cafb1badd0feb428c1e7bc19b867479ff72f7a9dd9b479f10e"}, + {url = "https://test-files.pythonhosted.org/packages/b6/08/a88a9f3a11bb2d97c7a6719535a984b009728433838fbc65766488867c80/coverage-6.5.0-cp39-cp39-win_amd64.whl", hash = "sha256:fc2af30ed0d5ae0b1abdb4ebdce598eafd5b35397d4d75deb341a614d333d987"}, + {url = "https://test-files.pythonhosted.org/packages/bd/a0/e263b115808226fdb2658f1887808c06ac3f1b579ef5dda02309e0d54459/coverage-6.5.0-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6b07130585d54fe8dff3d97b93b0e20290de974dc8177c320aeaf23459219c0b"}, + {url = "https://test-files.pythonhosted.org/packages/c0/18/2a0a9b3c29376ce04ceb7ca2948559dad76409a2c9b3f664756581101e16/coverage-6.5.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:11b990d520ea75e7ee8dcab5bc908072aaada194a794db9f6d7d5cfd19661e5a"}, + {url = "https://test-files.pythonhosted.org/packages/c4/8d/5ec7d08f4601d2d792563fe31db5e9322c306848fec1e65ec8885927f739/coverage-6.5.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:ef8674b0ee8cc11e2d574e3e2998aea5df5ab242e012286824ea3c6970580e53"}, + {url = "https://test-files.pythonhosted.org/packages/c8/e8/e712b61abf1282ce3ac9826473ab4b245a4319303cce2e4115a8de1435f2/coverage-6.5.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:723e8130d4ecc8f56e9a611e73b31219595baa3bb252d539206f7bbbab6ffc1f"}, + {url = "https://test-files.pythonhosted.org/packages/cd/48/65d314e702b4a7095ea96da0a319a5a377e594354a4a6badde483832bb5a/coverage-6.5.0-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:255758a1e3b61db372ec2736c8e2a1fdfaf563977eedbdf131de003ca5779b7d"}, + {url = "https://test-files.pythonhosted.org/packages/d6/00/3e12af83af2a46c1fd27b78486f404736934d0288bda4975119611a01cb3/coverage-6.5.0-cp37-cp37m-win_amd64.whl", hash = "sha256:4a8dbc1f0fbb2ae3de73eb0bdbb914180c7abfbf258e90b311dcd4f585d44bd2"}, + {url = "https://test-files.pythonhosted.org/packages/d6/0f/012a7370aaf61123a222b34b657dedc63e03ce2af8d064ac5c5afe14f29c/coverage-6.5.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:265de0fa6778d07de30bcf4d9dc471c3dc4314a23a3c6603d356a3c9abc2dfcf"}, + {url = "https://test-files.pythonhosted.org/packages/e5/fb/11982f5faf2990d4d9159e01a12bbf0a7d7873893d4d2e2acec012ad69ae/coverage-6.5.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:e07f4a4a9b41583d6eabec04f8b68076ab3cd44c20bd29332c6572dda36f372e"}, + {url = "https://test-files.pythonhosted.org/packages/e6/24/7fe8ededb4060dd8c3f1d86cb624fcb3452f66fbef5051ed7fab126c5c0c/coverage-6.5.0-cp311-cp311-win_amd64.whl", hash = "sha256:bc8ef5e043a2af066fa8cbfc6e708d58017024dc4345a1f9757b329a249f041b"}, + {url = "https://test-files.pythonhosted.org/packages/e9/f0/3be949bd129237553714149b1909d34c94137ca4b86e036bc7060431da18/coverage-6.5.0-cp38-cp38-win32.whl", hash = "sha256:6d4817234349a80dbf03640cec6109cd90cba068330703fa65ddf56b60223a6d"}, + {url = "https://test-files.pythonhosted.org/packages/ea/52/c08080405329326a7ff16c0dfdb4feefaa8edd7446413df67386fe1bbfe0/coverage-6.5.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:633713d70ad6bfc49b34ead4060531658dc6dfc9b3eb7d8a716d5873377ab745"}, + {url = "https://test-files.pythonhosted.org/packages/ff/27/339089b558672f04e62d0cd2d49b9280270bad3bc95de24e7eb03deb4638/coverage-6.5.0-cp311-cp311-win32.whl", hash = "sha256:98e8a10b7a314f454d9eff4216a9a94d143a7ee65018dd12442e898ee2310578"}, +] +"crcmod 1.7" = [ + {url = "https://files.pythonhosted.org/packages/6b/b0/e595ce2a2527e169c3bcd6c33d2473c1918e0b7f6826a043ca1245dd4e5b/crcmod-1.7.tar.gz", hash = "sha256:dc7051a0db5f2bd48665a990d3ec1cc305a466a77358ca4492826f41f283601e"}, +] +"ecdsa 0.18.0" = [ + {url = "https://files.pythonhosted.org/packages/09/d4/4f05f5d16a4863b30ba96c23b23e942da8889abfa1cdbabf2a0df12a4532/ecdsa-0.18.0-py2.py3-none-any.whl", hash = "sha256:80600258e7ed2f16b9aa1d7c295bd70194109ad5a30fdee0eaeefef1d4c559dd"}, + {url = "https://files.pythonhosted.org/packages/ff/7b/ba6547a76c468a0d22de93e89ae60d9561ec911f59532907e72b0d8bc0f1/ecdsa-0.18.0.tar.gz", hash = "sha256:190348041559e21b22a1d65cee485282ca11a6f81d503fddb84d5017e9ed1e49"}, +] +"ed25519-blake2b 1.4" = [ + {url = "https://files.pythonhosted.org/packages/1d/f1/035bafb5b2ed5b379abd4bf26ebad6e9fed73e21756971cefe027bd55ec2/ed25519-blake2b-1.4.tar.gz", hash = "sha256:d1a1cb9032ec307ce95b41c619440fd4d3fcecc18f224035cc7d6dc7a7d8ef40"}, + {url = "https://test-files.pythonhosted.org/packages/1e/6a/7c1ef79662d40e2e031e5b1a155c0d6f0dd6029d3747fc9f3d5b27c49740/ed25519-blake2b-1.4.tar.gz", hash = "sha256:0ef98ed9ebec59f312a447a0693c2d8bcc8a4d011ca5bb7d09104d358669b122"}, +] +"exceptiongroup 1.0.4" = [ + {url = "https://files.pythonhosted.org/packages/ce/2e/9a327cc0d2d674ee2d570ee30119755af772094edba86d721dda94404d1a/exceptiongroup-1.0.4-py3-none-any.whl", hash = "sha256:542adf9dea4055530d6e1279602fa5cb11dab2395fa650b8674eaec35fc4a828"}, + {url = "https://files.pythonhosted.org/packages/fa/e1/4f89a2608978a78876a76e69e82fa1fc5ce3fb346297eed2a51dd3df2dcf/exceptiongroup-1.0.4.tar.gz", hash = "sha256:bd14967b79cd9bdb54d97323216f8fdf533e278df937aa2a90089e7d6e06e5ec"}, +] +"flask 2.2.2" = [ + {url = "https://files.pythonhosted.org/packages/0f/43/15f4f9ab225b0b25352412e8daa3d0e3d135fcf5e127070c74c3632c8b4c/Flask-2.2.2-py3-none-any.whl", hash = "sha256:b9c46cc36662a7949f34b52d8ec7bb59c0d74ba08ba6cb9ce9adc1d8676d9526"}, + {url = "https://files.pythonhosted.org/packages/69/b6/53cfa30eed5aa7343daff36622843688ba8c6fe9829bb2b92e193ab1163f/Flask-2.2.2.tar.gz", hash = "sha256:642c450d19c4ad482f96729bd2a8f6d32554aa1e231f4f6b4e7e5264b16cca2b"}, + {url = "https://test-files.pythonhosted.org/packages/0f/43/15f4f9ab225b0b25352412e8daa3d0e3d135fcf5e127070c74c3632c8b4c/Flask-2.2.2-py3-none-any.whl", hash = "sha256:b9c46cc36662a7949f34b52d8ec7bb59c0d74ba08ba6cb9ce9adc1d8676d9526"}, + {url = "https://test-files.pythonhosted.org/packages/69/b6/53cfa30eed5aa7343daff36622843688ba8c6fe9829bb2b92e193ab1163f/Flask-2.2.2.tar.gz", hash = "sha256:642c450d19c4ad482f96729bd2a8f6d32554aa1e231f4f6b4e7e5264b16cca2b"}, +] +"flask-restful 0.3.9" = [ + {url = "https://files.pythonhosted.org/packages/5c/50/4892719b13abd401f40a69359c3d859d0ea76bf78e66db058d6c06a95b01/Flask-RESTful-0.3.9.tar.gz", hash = "sha256:ccec650b835d48192138c85329ae03735e6ced58e9b2d9c2146d6c84c06fa53e"}, + {url = "https://files.pythonhosted.org/packages/a9/02/7e21a73564fe0d9d1a3a4ff478dfc407815c4e2fa4e5121bcfc646ba5d15/Flask_RESTful-0.3.9-py2.py3-none-any.whl", hash = "sha256:4970c49b6488e46c520b325f54833374dc2b98e211f1b272bd4b0c516232afe2"}, +] +"idna 3.4" = [ + {url = "https://files.pythonhosted.org/packages/8b/e1/43beb3d38dba6cb420cefa297822eac205a277ab43e5ba5d5c46faf96438/idna-3.4.tar.gz", hash = "sha256:814f528e8dead7d329833b91c5faa87d60bf71824cd12a7530b5526063d02cb4"}, + {url = "https://files.pythonhosted.org/packages/fc/34/3030de6f1370931b9dbb4dad48f6ab1015ab1d32447850b9fc94e60097be/idna-3.4-py3-none-any.whl", hash = "sha256:90b77e79eaa3eba6de819a0c442c0b4ceefc341a7a2ab77d7562bf49f425c5c2"}, +] +"iniconfig 1.1.1" = [ + {url = "https://files.pythonhosted.org/packages/23/a2/97899f6bd0e873fed3a7e67ae8d3a08b21799430fb4da15cfedf10d6e2c2/iniconfig-1.1.1.tar.gz", hash = "sha256:bc3af051d7d14b2ee5ef9969666def0cd1a000e121eaea580d4a313df4b37f32"}, + {url = "https://files.pythonhosted.org/packages/9b/dd/b3c12c6d707058fa947864b67f0c4e0c39ef8610988d7baea9578f3c48f3/iniconfig-1.1.1-py2.py3-none-any.whl", hash = "sha256:011e24c64b7f47f6ebd835bb12a743f2fbe9a26d4cecaa7f53bc4f35ee9da8b3"}, + {url = "https://test-files.pythonhosted.org/packages/75/f0/6126fa58c2647daefb619a9ea449c53b5b61acd44f6d2693beae754977e0/iniconfig-1.1.1.tar.gz", hash = "sha256:714dfcaf550420126ed7e66bb1cbc893752af388742828f294c21f847d78b88a"}, + {url = "https://test-files.pythonhosted.org/packages/76/83/2373f13f03040a54c77272adac18956b8202a50b60e8221449df00d19e87/iniconfig-1.1.1-py2.py3-none-any.whl", hash = "sha256:8cd395a2a89caee27b08d7879c1515fa9d93e0c477a5b38c9893787fc5e51896"}, +] +"itsdangerous 2.1.2" = [ + {url = "https://files.pythonhosted.org/packages/68/5f/447e04e828f47465eeab35b5d408b7ebaaaee207f48b7136c5a7267a30ae/itsdangerous-2.1.2-py3-none-any.whl", hash = "sha256:2c2349112351b88699d8d4b6b075022c0808887cb7ad10069318a8b0bc88db44"}, + {url = "https://files.pythonhosted.org/packages/7f/a1/d3fb83e7a61fa0c0d3d08ad0a94ddbeff3731c05212617dff3a94e097f08/itsdangerous-2.1.2.tar.gz", hash = "sha256:5dbbc68b317e5e42f327f9021763545dc3fc3bfe22e6deb96aaf1fc38874156a"}, + {url = "https://test-files.pythonhosted.org/packages/68/5f/447e04e828f47465eeab35b5d408b7ebaaaee207f48b7136c5a7267a30ae/itsdangerous-2.1.2-py3-none-any.whl", hash = "sha256:2c2349112351b88699d8d4b6b075022c0808887cb7ad10069318a8b0bc88db44"}, + {url = "https://test-files.pythonhosted.org/packages/7f/a1/d3fb83e7a61fa0c0d3d08ad0a94ddbeff3731c05212617dff3a94e097f08/itsdangerous-2.1.2.tar.gz", hash = "sha256:5dbbc68b317e5e42f327f9021763545dc3fc3bfe22e6deb96aaf1fc38874156a"}, +] +"jinja2 3.1.2" = [ + {url = "https://files.pythonhosted.org/packages/7a/ff/75c28576a1d900e87eb6335b063fab47a8ef3c8b4d88524c4bf78f670cce/Jinja2-3.1.2.tar.gz", hash = "sha256:31351a702a408a9e7595a8fc6150fc3f43bb6bf7e319770cbc0db9df9437e852"}, + {url = "https://files.pythonhosted.org/packages/bc/c3/f068337a370801f372f2f8f6bad74a5c140f6fda3d9de154052708dd3c65/Jinja2-3.1.2-py3-none-any.whl", hash = "sha256:6088930bfe239f0e6710546ab9c19c9ef35e29792895fed6e6e31a023a182a61"}, + {url = "https://test-files.pythonhosted.org/packages/7a/ff/75c28576a1d900e87eb6335b063fab47a8ef3c8b4d88524c4bf78f670cce/Jinja2-3.1.2.tar.gz", hash = "sha256:31351a702a408a9e7595a8fc6150fc3f43bb6bf7e319770cbc0db9df9437e852"}, + {url = "https://test-files.pythonhosted.org/packages/bc/c3/f068337a370801f372f2f8f6bad74a5c140f6fda3d9de154052708dd3c65/Jinja2-3.1.2-py3-none-any.whl", hash = "sha256:6088930bfe239f0e6710546ab9c19c9ef35e29792895fed6e6e31a023a182a61"}, +] +"jsonschema 3.2.0" = [ + {url = "https://files.pythonhosted.org/packages/69/11/a69e2a3c01b324a77d3a7c0570faa372e8448b666300c4117a516f8b1212/jsonschema-3.2.0.tar.gz", hash = "sha256:c8a85b28d377cc7737e46e2d9f2b4f44ee3c0e1deac6bf46ddefc7187d30797a"}, + {url = "https://files.pythonhosted.org/packages/c5/8f/51e89ce52a085483359217bc72cdbf6e75ee595d5b1d4b5ade40c7e018b8/jsonschema-3.2.0-py2.py3-none-any.whl", hash = "sha256:4e5b3cf8216f577bee9ce139cbe72eca3ea4f292ec60928ff24758ce626cd163"}, +] +"markupsafe 2.1.1" = [ + {url = "https://files.pythonhosted.org/packages/06/7f/d5e46d7464360b6ac39c5b0b604770dba937e3d7cab485d2f3298454717b/MarkupSafe-2.1.1-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:e04e26803c9c3851c931eac40c695602c6295b8d432cbe78609649ad9bd2da8a"}, + {url = "https://files.pythonhosted.org/packages/0f/53/b14de4ede9c2bd76d28e7911033b065ac42896f1cfb258d3ff65cf0332d2/MarkupSafe-2.1.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:8e3dcf21f367459434c18e71b2a9532d96547aef8a871872a5bd69a715c15f96"}, + {url = "https://files.pythonhosted.org/packages/18/a6/913b1d80fe93f7c3aa79206544b98841616c3eaa7790f37bdfb9fc13311e/MarkupSafe-2.1.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8e576a51ad59e4bfaac456023a78f6b5e6e7651dcd383bcc3e18d06f9b55d6d1"}, + {url = "https://files.pythonhosted.org/packages/1b/b3/93411f10caaccc6fc9c53bbdae4f6d26997248ae574e2f0c90e912b67f73/MarkupSafe-2.1.1-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:d5ee4f386140395a2c818d149221149c54849dfcfcb9f1debfe07a8b8bd63f9a"}, + {url = "https://files.pythonhosted.org/packages/1d/97/2288fe498044284f39ab8950703e88abbac2abbdf65524d576157af70556/MarkupSafe-2.1.1.tar.gz", hash = "sha256:7f91197cc9e48f989d12e4e6fbc46495c446636dfc81b9ccf50bb0ec74b91d4b"}, + {url = "https://files.pythonhosted.org/packages/25/c4/a75659da6d6b03d2d8ef296b2a8bc73e8c5b1533ee31569a958a292f0929/MarkupSafe-2.1.1-cp39-cp39-win32.whl", hash = "sha256:d4306c36ca495956b6d568d276ac11fdd9c30a36f1b6eb928070dc5360b22e1c"}, + {url = "https://files.pythonhosted.org/packages/26/03/2c11ba1a8b2327adea3f59f1c9c9ee9c59e86023925f929e63c4f028b10a/MarkupSafe-2.1.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:b87db4360013327109564f0e591bd2a3b318547bcef31b468a92ee504d07ae4f"}, + {url = "https://files.pythonhosted.org/packages/2c/81/91062a81ac8a18f557f12e2618475b53878755c016c9914c8aa207155c4e/MarkupSafe-2.1.1-cp38-cp38-win_amd64.whl", hash = "sha256:fc7b548b17d238737688817ab67deebb30e8073c95749d55538ed473130ec0c7"}, + {url = "https://files.pythonhosted.org/packages/3a/fc/dccc18170917f2cc2a5b77aad97f5f27d992ef0f2b9fb9e334ee71bf5301/MarkupSafe-2.1.1-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:33b74d289bd2f5e527beadcaa3f401e0df0a89927c1559c8566c066fa4248ab7"}, + {url = "https://files.pythonhosted.org/packages/3c/d3/c7ab031b14ae4e83214949acee957a8fcf6a992698edff039ee1e77eb4e1/MarkupSafe-2.1.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:0212a68688482dc52b2d45013df70d169f542b7394fc744c02a57374a4207003"}, + {url = "https://files.pythonhosted.org/packages/3d/4b/15e5b9d40c4b58e97ebcb8ed5845a215fa5b7cf49a7f1cc7908f8db9cf46/MarkupSafe-2.1.1-cp310-cp310-win_amd64.whl", hash = "sha256:dda30ba7e87fbbb7eab1ec9f58678558fd9a6b8b853530e176eabd064da81417"}, + {url = "https://files.pythonhosted.org/packages/3f/38/f422a81b41bdac48f1d19c45f6e203c04bc45d2c35505873fdecdddee1ec/MarkupSafe-2.1.1-cp37-cp37m-win_amd64.whl", hash = "sha256:97a68e6ada378df82bc9f16b800ab77cbf4b2fada0081794318520138c088e4a"}, + {url = "https://files.pythonhosted.org/packages/48/a9/cf226ea201542a724b113bac70dd0dfb72106da3621120c525c8eafadac2/MarkupSafe-2.1.1-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3799351e2336dc91ea70b034983ee71cf2f9533cdff7c14c90ea126bfd95d65a"}, + {url = "https://files.pythonhosted.org/packages/5c/1a/ac3a2b2a4ef1196c15dd8a143fc28eddeb6e6871d6d1de64dc44ef7f59b6/MarkupSafe-2.1.1-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:694deca8d702d5db21ec83983ce0bb4b26a578e71fbdbd4fdcd387daa90e4d5e"}, + {url = "https://files.pythonhosted.org/packages/5e/3d/0a7df21deca52e20de81f8a895ac29df68944588c0030be9aa1e6c07877c/MarkupSafe-2.1.1-cp310-cp310-win32.whl", hash = "sha256:4a33dea2b688b3190ee12bd7cfa29d39c9ed176bda40bfa11099a3ce5d3a7ac6"}, + {url = "https://files.pythonhosted.org/packages/68/b5/b3aafabe7e1f71aa64ffe32fd8c767fd7db1bb304d339d8df6f2fdd2543c/MarkupSafe-2.1.1-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:089cf3dbf0cd6c100f02945abeb18484bd1ee57a079aefd52cffd17fba910b88"}, + {url = "https://files.pythonhosted.org/packages/69/60/08791e4a971ea976f0fd58fb916d76de7c962dc8e26430564258820ac21f/MarkupSafe-2.1.1-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:96e37a3dc86e80bf81758c152fe66dbf60ed5eca3d26305edf01892257049925"}, + {url = "https://files.pythonhosted.org/packages/6c/44/cd459988fe29cb82f0482fe6b6c47ec17ae700a500634edd876075d5e1ee/MarkupSafe-2.1.1-cp38-cp38-win32.whl", hash = "sha256:421be9fbf0ffe9ffd7a378aafebbf6f4602d564d34be190fc19a193232fd12b1"}, + {url = "https://files.pythonhosted.org/packages/71/dc/41cbfe0d9aefdf14226dbf4eccfd0079a0e297809a17c5b902c9a7a3cc9a/MarkupSafe-2.1.1-cp39-cp39-win_amd64.whl", hash = "sha256:46d00d6cfecdde84d40e572d63735ef81423ad31184100411e6e3388d405e247"}, + {url = "https://files.pythonhosted.org/packages/73/68/628f6dbbf5088723a2b939d97c0a2e059d0cc654ce92a6fac5c7959edaff/MarkupSafe-2.1.1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3ce11ee3f23f79dbd06fb3d63e2f6af7b12db1d46932fe7bd8afa259a5996603"}, + {url = "https://files.pythonhosted.org/packages/7f/d7/a0ee1e3a608ca2f80c66c43c699ab063b4b8979c51f8299229b1960f6860/MarkupSafe-2.1.1-cp37-cp37m-win32.whl", hash = "sha256:8dc1c72a69aa7e082593c4a203dcf94ddb74bb5c8a731e4e1eb68d031e8498ff"}, + {url = "https://files.pythonhosted.org/packages/82/3d/523e40c45dc1f53b35e60c6e8563dec523f7b6c113f823d5e123dd431631/MarkupSafe-2.1.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:99a2a507ed3ac881b975a2976d59f38c19386d128e7a9a18b7df6fff1fd4c1d6"}, + {url = "https://files.pythonhosted.org/packages/87/31/ab37f60fde001c02ac115da6f66a2d934d37407f257ad8e15ed69093c7fb/MarkupSafe-2.1.1-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6fbf47b5d3728c6aea2abb0589b5d30459e369baa772e0f37a0320185e87c980"}, + {url = "https://files.pythonhosted.org/packages/8c/96/7e608e1a942232cb8c81ca24093e71e07e2bacbeb2dad62a0f82da28ed54/MarkupSafe-2.1.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:f121a1420d4e173a5d96e47e9a0c0dcff965afdf1626d28de1460815f7c4ee7a"}, + {url = "https://files.pythonhosted.org/packages/92/7c/3c33294e506eafa7f1c40dd283089a45652ea0f073fc0ce24419d46bfe4b/MarkupSafe-2.1.1-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:e8c843bbcda3a2f1e3c2ab25913c80a3c5376cd00c6e8c4a86a89a28c8dc5452"}, + {url = "https://files.pythonhosted.org/packages/9e/82/2e089c6f34e77c073aa5a67040d368aac0dfb9b8ccbb46d381452c26fc33/MarkupSafe-2.1.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:10c1bfff05d95783da83491be968e8fe789263689c02724e0c691933c52994f5"}, + {url = "https://files.pythonhosted.org/packages/9f/83/b221ce5a0224f409b9f02b0dc6cb0b921c46033f4870d64fa3e8a96af701/MarkupSafe-2.1.1-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e72591e9ecd94d7feb70c1cbd7be7b3ebea3f548870aa91e2732960fa4d57a37"}, + {url = "https://files.pythonhosted.org/packages/a3/47/9dcc08eff8ab94f1e50f59f9cd322b710ef5db7e8590fdd8df924406fc9c/MarkupSafe-2.1.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b7bd98b796e2b6553da7225aeb61f447f80a1ca64f41d83612e6139ca5213aa4"}, + {url = "https://files.pythonhosted.org/packages/ad/fa/292a72cddad41e3c06227b446a0af53ff642a40755fc5bd695f439c35ba8/MarkupSafe-2.1.1-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:b09bf97215625a311f669476f44b8b318b075847b49316d3e28c08e41a7a573f"}, + {url = "https://files.pythonhosted.org/packages/ba/16/3627f852d8a846c0fc52ad1beac6e27894a8344cc2c26036db51acb82c3e/MarkupSafe-2.1.1-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:43093fb83d8343aac0b1baa75516da6092f58f41200907ef92448ecab8825135"}, + {url = "https://files.pythonhosted.org/packages/ba/a9/6291d3fdaf0ecac5fbafe462258c5174f11fd752076ba05c2c022ee64f77/MarkupSafe-2.1.1-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:e1c0b87e09fa55a220f058d1d49d3fb8df88fbfab58558f1198e08c1e1de842a"}, + {url = "https://files.pythonhosted.org/packages/be/d8/5ab7f07d8f60155c4f12b4b2dca785355b8ee7e16b2d3f00c3830add5f10/MarkupSafe-2.1.1-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:6a074d34ee7a5ce3effbc526b7083ec9731bb3cbf921bbe1d3005d4d2bdb3a63"}, + {url = "https://files.pythonhosted.org/packages/d0/1f/9677deb5b2768ca503e5ed8464a28f47a854d415b9d1b84445efa8363ca6/MarkupSafe-2.1.1-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:bcb3ed405ed3222f9904899563d6fc492ff75cce56cba05e32eff40e6acbeaa3"}, + {url = "https://files.pythonhosted.org/packages/d3/4f/9ea1c0a7796f7f81371b40d32aa31766b76fbdba316abf888897042e6e0f/MarkupSafe-2.1.1-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:6d0072fea50feec76a4c418096652f2c3238eaa014b2f94aeb1d56a66b41403f"}, + {url = "https://files.pythonhosted.org/packages/d9/60/94e9de017674f88a514804e2924bdede9a642aba179d2045214719d6ec76/MarkupSafe-2.1.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:86b1f75c4e7c2ac2ccdaec2b9022845dbb81880ca318bb7a0a01fbf7813e3812"}, + {url = "https://files.pythonhosted.org/packages/df/06/c515c5bc43b90462e753bc768e6798193c6520c9c7eb2054c7466779a9db/MarkupSafe-2.1.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:56442863ed2b06d19c37f94d999035e15ee982988920e12a5b4ba29b62ad1f77"}, + {url = "https://files.pythonhosted.org/packages/f9/f8/13ffc95bf8a8c98d611b9f9fa5aa88625b9a82fce528e58f1aafba14946b/MarkupSafe-2.1.1-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:671cd1187ed5e62818414afe79ed29da836dde67166a9fac6d435873c44fdd02"}, + {url = "https://files.pythonhosted.org/packages/fc/e4/78c7607352dd574d524daad079f855757d406d36b919b1864a5a07978390/MarkupSafe-2.1.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:efc1913fd2ca4f334418481c7e595c00aad186563bbc1ec76067848c7ca0a933"}, + {url = "https://files.pythonhosted.org/packages/fd/f4/524d2e8f5a3727cf309c2b7df7c732038375322df1376c9e9ef3aa92fcaf/MarkupSafe-2.1.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4b9fe39a2ccc108a4accc2676e77da025ce383c108593d65cc909add5c3bd601"}, + {url = "https://files.pythonhosted.org/packages/ff/3a/42262a3aa6415befee33b275b31afbcef4f7f8d2f4380061b226c692ee2a/MarkupSafe-2.1.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a49907dd8420c5685cfa064a1335b6754b74541bbb3706c259c02ed65b644b3e"}, + {url = "https://test-files.pythonhosted.org/packages/06/7f/d5e46d7464360b6ac39c5b0b604770dba937e3d7cab485d2f3298454717b/MarkupSafe-2.1.1-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:e04e26803c9c3851c931eac40c695602c6295b8d432cbe78609649ad9bd2da8a"}, + {url = "https://test-files.pythonhosted.org/packages/0f/53/b14de4ede9c2bd76d28e7911033b065ac42896f1cfb258d3ff65cf0332d2/MarkupSafe-2.1.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:8e3dcf21f367459434c18e71b2a9532d96547aef8a871872a5bd69a715c15f96"}, + {url = "https://test-files.pythonhosted.org/packages/18/a6/913b1d80fe93f7c3aa79206544b98841616c3eaa7790f37bdfb9fc13311e/MarkupSafe-2.1.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8e576a51ad59e4bfaac456023a78f6b5e6e7651dcd383bcc3e18d06f9b55d6d1"}, + {url = "https://test-files.pythonhosted.org/packages/1b/b3/93411f10caaccc6fc9c53bbdae4f6d26997248ae574e2f0c90e912b67f73/MarkupSafe-2.1.1-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:d5ee4f386140395a2c818d149221149c54849dfcfcb9f1debfe07a8b8bd63f9a"}, + {url = "https://test-files.pythonhosted.org/packages/1d/97/2288fe498044284f39ab8950703e88abbac2abbdf65524d576157af70556/MarkupSafe-2.1.1.tar.gz", hash = "sha256:7f91197cc9e48f989d12e4e6fbc46495c446636dfc81b9ccf50bb0ec74b91d4b"}, + {url = "https://test-files.pythonhosted.org/packages/25/c4/a75659da6d6b03d2d8ef296b2a8bc73e8c5b1533ee31569a958a292f0929/MarkupSafe-2.1.1-cp39-cp39-win32.whl", hash = "sha256:d4306c36ca495956b6d568d276ac11fdd9c30a36f1b6eb928070dc5360b22e1c"}, + {url = "https://test-files.pythonhosted.org/packages/26/03/2c11ba1a8b2327adea3f59f1c9c9ee9c59e86023925f929e63c4f028b10a/MarkupSafe-2.1.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:b87db4360013327109564f0e591bd2a3b318547bcef31b468a92ee504d07ae4f"}, + {url = "https://test-files.pythonhosted.org/packages/2c/81/91062a81ac8a18f557f12e2618475b53878755c016c9914c8aa207155c4e/MarkupSafe-2.1.1-cp38-cp38-win_amd64.whl", hash = "sha256:fc7b548b17d238737688817ab67deebb30e8073c95749d55538ed473130ec0c7"}, + {url = "https://test-files.pythonhosted.org/packages/3a/fc/dccc18170917f2cc2a5b77aad97f5f27d992ef0f2b9fb9e334ee71bf5301/MarkupSafe-2.1.1-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:33b74d289bd2f5e527beadcaa3f401e0df0a89927c1559c8566c066fa4248ab7"}, + {url = "https://test-files.pythonhosted.org/packages/3c/d3/c7ab031b14ae4e83214949acee957a8fcf6a992698edff039ee1e77eb4e1/MarkupSafe-2.1.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:0212a68688482dc52b2d45013df70d169f542b7394fc744c02a57374a4207003"}, + {url = "https://test-files.pythonhosted.org/packages/3d/4b/15e5b9d40c4b58e97ebcb8ed5845a215fa5b7cf49a7f1cc7908f8db9cf46/MarkupSafe-2.1.1-cp310-cp310-win_amd64.whl", hash = "sha256:dda30ba7e87fbbb7eab1ec9f58678558fd9a6b8b853530e176eabd064da81417"}, + {url = "https://test-files.pythonhosted.org/packages/3f/38/f422a81b41bdac48f1d19c45f6e203c04bc45d2c35505873fdecdddee1ec/MarkupSafe-2.1.1-cp37-cp37m-win_amd64.whl", hash = "sha256:97a68e6ada378df82bc9f16b800ab77cbf4b2fada0081794318520138c088e4a"}, + {url = "https://test-files.pythonhosted.org/packages/48/a9/cf226ea201542a724b113bac70dd0dfb72106da3621120c525c8eafadac2/MarkupSafe-2.1.1-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3799351e2336dc91ea70b034983ee71cf2f9533cdff7c14c90ea126bfd95d65a"}, + {url = "https://test-files.pythonhosted.org/packages/5c/1a/ac3a2b2a4ef1196c15dd8a143fc28eddeb6e6871d6d1de64dc44ef7f59b6/MarkupSafe-2.1.1-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:694deca8d702d5db21ec83983ce0bb4b26a578e71fbdbd4fdcd387daa90e4d5e"}, + {url = "https://test-files.pythonhosted.org/packages/5e/3d/0a7df21deca52e20de81f8a895ac29df68944588c0030be9aa1e6c07877c/MarkupSafe-2.1.1-cp310-cp310-win32.whl", hash = "sha256:4a33dea2b688b3190ee12bd7cfa29d39c9ed176bda40bfa11099a3ce5d3a7ac6"}, + {url = "https://test-files.pythonhosted.org/packages/68/b5/b3aafabe7e1f71aa64ffe32fd8c767fd7db1bb304d339d8df6f2fdd2543c/MarkupSafe-2.1.1-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:089cf3dbf0cd6c100f02945abeb18484bd1ee57a079aefd52cffd17fba910b88"}, + {url = "https://test-files.pythonhosted.org/packages/69/60/08791e4a971ea976f0fd58fb916d76de7c962dc8e26430564258820ac21f/MarkupSafe-2.1.1-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:96e37a3dc86e80bf81758c152fe66dbf60ed5eca3d26305edf01892257049925"}, + {url = "https://test-files.pythonhosted.org/packages/6c/44/cd459988fe29cb82f0482fe6b6c47ec17ae700a500634edd876075d5e1ee/MarkupSafe-2.1.1-cp38-cp38-win32.whl", hash = "sha256:421be9fbf0ffe9ffd7a378aafebbf6f4602d564d34be190fc19a193232fd12b1"}, + {url = "https://test-files.pythonhosted.org/packages/71/dc/41cbfe0d9aefdf14226dbf4eccfd0079a0e297809a17c5b902c9a7a3cc9a/MarkupSafe-2.1.1-cp39-cp39-win_amd64.whl", hash = "sha256:46d00d6cfecdde84d40e572d63735ef81423ad31184100411e6e3388d405e247"}, + {url = "https://test-files.pythonhosted.org/packages/73/68/628f6dbbf5088723a2b939d97c0a2e059d0cc654ce92a6fac5c7959edaff/MarkupSafe-2.1.1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3ce11ee3f23f79dbd06fb3d63e2f6af7b12db1d46932fe7bd8afa259a5996603"}, + {url = "https://test-files.pythonhosted.org/packages/7f/d7/a0ee1e3a608ca2f80c66c43c699ab063b4b8979c51f8299229b1960f6860/MarkupSafe-2.1.1-cp37-cp37m-win32.whl", hash = "sha256:8dc1c72a69aa7e082593c4a203dcf94ddb74bb5c8a731e4e1eb68d031e8498ff"}, + {url = "https://test-files.pythonhosted.org/packages/82/3d/523e40c45dc1f53b35e60c6e8563dec523f7b6c113f823d5e123dd431631/MarkupSafe-2.1.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:99a2a507ed3ac881b975a2976d59f38c19386d128e7a9a18b7df6fff1fd4c1d6"}, + {url = "https://test-files.pythonhosted.org/packages/87/31/ab37f60fde001c02ac115da6f66a2d934d37407f257ad8e15ed69093c7fb/MarkupSafe-2.1.1-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6fbf47b5d3728c6aea2abb0589b5d30459e369baa772e0f37a0320185e87c980"}, + {url = "https://test-files.pythonhosted.org/packages/8c/96/7e608e1a942232cb8c81ca24093e71e07e2bacbeb2dad62a0f82da28ed54/MarkupSafe-2.1.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:f121a1420d4e173a5d96e47e9a0c0dcff965afdf1626d28de1460815f7c4ee7a"}, + {url = "https://test-files.pythonhosted.org/packages/92/7c/3c33294e506eafa7f1c40dd283089a45652ea0f073fc0ce24419d46bfe4b/MarkupSafe-2.1.1-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:e8c843bbcda3a2f1e3c2ab25913c80a3c5376cd00c6e8c4a86a89a28c8dc5452"}, + {url = "https://test-files.pythonhosted.org/packages/9e/82/2e089c6f34e77c073aa5a67040d368aac0dfb9b8ccbb46d381452c26fc33/MarkupSafe-2.1.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:10c1bfff05d95783da83491be968e8fe789263689c02724e0c691933c52994f5"}, + {url = "https://test-files.pythonhosted.org/packages/9f/83/b221ce5a0224f409b9f02b0dc6cb0b921c46033f4870d64fa3e8a96af701/MarkupSafe-2.1.1-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e72591e9ecd94d7feb70c1cbd7be7b3ebea3f548870aa91e2732960fa4d57a37"}, + {url = "https://test-files.pythonhosted.org/packages/a3/47/9dcc08eff8ab94f1e50f59f9cd322b710ef5db7e8590fdd8df924406fc9c/MarkupSafe-2.1.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b7bd98b796e2b6553da7225aeb61f447f80a1ca64f41d83612e6139ca5213aa4"}, + {url = "https://test-files.pythonhosted.org/packages/ad/fa/292a72cddad41e3c06227b446a0af53ff642a40755fc5bd695f439c35ba8/MarkupSafe-2.1.1-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:b09bf97215625a311f669476f44b8b318b075847b49316d3e28c08e41a7a573f"}, + {url = "https://test-files.pythonhosted.org/packages/ba/16/3627f852d8a846c0fc52ad1beac6e27894a8344cc2c26036db51acb82c3e/MarkupSafe-2.1.1-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:43093fb83d8343aac0b1baa75516da6092f58f41200907ef92448ecab8825135"}, + {url = "https://test-files.pythonhosted.org/packages/ba/a9/6291d3fdaf0ecac5fbafe462258c5174f11fd752076ba05c2c022ee64f77/MarkupSafe-2.1.1-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:e1c0b87e09fa55a220f058d1d49d3fb8df88fbfab58558f1198e08c1e1de842a"}, + {url = "https://test-files.pythonhosted.org/packages/be/d8/5ab7f07d8f60155c4f12b4b2dca785355b8ee7e16b2d3f00c3830add5f10/MarkupSafe-2.1.1-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:6a074d34ee7a5ce3effbc526b7083ec9731bb3cbf921bbe1d3005d4d2bdb3a63"}, + {url = "https://test-files.pythonhosted.org/packages/d0/1f/9677deb5b2768ca503e5ed8464a28f47a854d415b9d1b84445efa8363ca6/MarkupSafe-2.1.1-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:bcb3ed405ed3222f9904899563d6fc492ff75cce56cba05e32eff40e6acbeaa3"}, + {url = "https://test-files.pythonhosted.org/packages/d3/4f/9ea1c0a7796f7f81371b40d32aa31766b76fbdba316abf888897042e6e0f/MarkupSafe-2.1.1-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:6d0072fea50feec76a4c418096652f2c3238eaa014b2f94aeb1d56a66b41403f"}, + {url = "https://test-files.pythonhosted.org/packages/d9/60/94e9de017674f88a514804e2924bdede9a642aba179d2045214719d6ec76/MarkupSafe-2.1.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:86b1f75c4e7c2ac2ccdaec2b9022845dbb81880ca318bb7a0a01fbf7813e3812"}, + {url = "https://test-files.pythonhosted.org/packages/df/06/c515c5bc43b90462e753bc768e6798193c6520c9c7eb2054c7466779a9db/MarkupSafe-2.1.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:56442863ed2b06d19c37f94d999035e15ee982988920e12a5b4ba29b62ad1f77"}, + {url = "https://test-files.pythonhosted.org/packages/f9/f8/13ffc95bf8a8c98d611b9f9fa5aa88625b9a82fce528e58f1aafba14946b/MarkupSafe-2.1.1-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:671cd1187ed5e62818414afe79ed29da836dde67166a9fac6d435873c44fdd02"}, + {url = "https://test-files.pythonhosted.org/packages/fc/e4/78c7607352dd574d524daad079f855757d406d36b919b1864a5a07978390/MarkupSafe-2.1.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:efc1913fd2ca4f334418481c7e595c00aad186563bbc1ec76067848c7ca0a933"}, + {url = "https://test-files.pythonhosted.org/packages/fd/f4/524d2e8f5a3727cf309c2b7df7c732038375322df1376c9e9ef3aa92fcaf/MarkupSafe-2.1.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4b9fe39a2ccc108a4accc2676e77da025ce383c108593d65cc909add5c3bd601"}, + {url = "https://test-files.pythonhosted.org/packages/ff/3a/42262a3aa6415befee33b275b31afbcef4f7f8d2f4380061b226c692ee2a/MarkupSafe-2.1.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a49907dd8420c5685cfa064a1335b6754b74541bbb3706c259c02ed65b644b3e"}, +] +"mnemonic 0.20" = [ + {url = "https://files.pythonhosted.org/packages/ae/95/3e07c33ffb26f5823b45a1c30db8acea44763198c2bd393e07e884f3295f/mnemonic-0.20-py3-none-any.whl", hash = "sha256:acd2168872d0379e7a10873bb3e12bf6c91b35de758135c4fbd1015ef18fafc5"}, + {url = "https://files.pythonhosted.org/packages/f8/8d/d4dc2b2bddfeb57cab4404a41749b577f578f71140ab754da9afa8f5c599/mnemonic-0.20.tar.gz", hash = "sha256:7c6fb5639d779388027a77944680aee4870f0fcd09b1e42a5525ee2ce4c625f6"}, +] +"mypy-extensions 0.4.3" = [ + {url = "https://files.pythonhosted.org/packages/5c/eb/975c7c080f3223a5cdaff09612f3a5221e4ba534f7039db34c35d95fa6a5/mypy_extensions-0.4.3-py2.py3-none-any.whl", hash = "sha256:090fedd75945a69ae91ce1303b5824f428daf5a028d2f6ab8a299250a846f15d"}, + {url = "https://files.pythonhosted.org/packages/63/60/0582ce2eaced55f65a4406fc97beba256de4b7a95a0034c6576458c6519f/mypy_extensions-0.4.3.tar.gz", hash = "sha256:2d82818f5bb3e369420cb3c4060a7970edba416647068eb4c5343488a6c604a8"}, +] +"mypy-protobuf 3.3.0" = [ + {url = "https://files.pythonhosted.org/packages/9d/59/48f1df10f87cf87d0638dd38f54549e98cb43fcf7ce0ab6c159816e85f23/mypy-protobuf-3.3.0.tar.gz", hash = "sha256:24f3b0aecb06656e983f58e07c732a90577b9d7af3e1066fc2b663bbf0370248"}, + {url = "https://files.pythonhosted.org/packages/d3/7b/b00434b3f508eb4bc637b83c2238cacaf1ce3cc5e540a2b76f5f99302446/mypy_protobuf-3.3.0-py3-none-any.whl", hash = "sha256:15604f6943b16c05db646903261e3b3e775cf7f7990b7c37b03d043a907b650d"}, + {url = "https://test-files.pythonhosted.org/packages/9d/59/48f1df10f87cf87d0638dd38f54549e98cb43fcf7ce0ab6c159816e85f23/mypy-protobuf-3.3.0.tar.gz", hash = "sha256:24f3b0aecb06656e983f58e07c732a90577b9d7af3e1066fc2b663bbf0370248"}, + {url = "https://test-files.pythonhosted.org/packages/d3/7b/b00434b3f508eb4bc637b83c2238cacaf1ce3cc5e540a2b76f5f99302446/mypy_protobuf-3.3.0-py3-none-any.whl", hash = "sha256:15604f6943b16c05db646903261e3b3e775cf7f7990b7c37b03d043a907b650d"}, +] +"packaging 21.3" = [ + {url = "https://files.pythonhosted.org/packages/05/8e/8de486cbd03baba4deef4142bd643a3e7bbe954a784dc1bb17142572d127/packaging-21.3-py3-none-any.whl", hash = "sha256:ef103e05f519cdc783ae24ea4e2e0f508a9c99b2d4969652eed6a2e1ea5bd522"}, + {url = "https://files.pythonhosted.org/packages/df/9e/d1a7217f69310c1db8fdf8ab396229f55a699ce34a203691794c5d1cad0c/packaging-21.3.tar.gz", hash = "sha256:dd47c42927d89ab911e606518907cc2d3a1f38bbd026385970643f9c5b8ecfeb"}, +] +"pathspec 0.10.2" = [ + {url = "https://files.pythonhosted.org/packages/42/79/94b21d5fabb97749ca94590315abe150a750483c87add8543781bcb6cd26/pathspec-0.10.2-py3-none-any.whl", hash = "sha256:88c2606f2c1e818b978540f73ecc908e13999c6c3a383daf3705652ae79807a5"}, + {url = "https://files.pythonhosted.org/packages/a2/29/959c72e1a6c3c25eaa46b9bfcc7fd401f65af83163d4796af09272c83c8a/pathspec-0.10.2.tar.gz", hash = "sha256:8f6bf73e5758fd365ef5d58ce09ac7c27d2833a8d7da51712eac6e27e35141b0"}, +] +"pillow 9.3.0" = [ + {url = "https://files.pythonhosted.org/packages/00/73/000575ca7b7635ecd4075e71925b71f2648300d725b6c9a1f969fe2d5a87/Pillow-9.3.0-cp37-cp37m-macosx_10_10_x86_64.whl", hash = "sha256:772a91fc0e03eaf922c63badeca75e91baa80fe2f5f87bdaed4280662aad25c9"}, + {url = "https://files.pythonhosted.org/packages/06/2f/c17a2d559009b875f7da804a3a4e0f47baca6df2dfedb29a1df641c51e1a/Pillow-9.3.0-pp38-pypy38_pp73-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:12ce4932caf2ddf3e41d17fc9c02d67126935a44b86df6a206cf0d7161548627"}, + {url = "https://files.pythonhosted.org/packages/0d/87/f696d8464c949c5a7ac133c8b7297a4243e0319fd29ae3a90b4ac90f0a5b/Pillow-9.3.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:7db8b751ad307d7cf238f02101e8e36a128a6cb199326e867d1398067381bff4"}, + {url = "https://files.pythonhosted.org/packages/15/13/232be66adb8482f0636b3f3e254d9e18d7093bd1848b3610ffaf72717924/Pillow-9.3.0-cp310-cp310-manylinux_2_28_aarch64.whl", hash = "sha256:829f97c8e258593b9daa80638aee3789b7df9da5cf1336035016d76f03b8860c"}, + {url = "https://files.pythonhosted.org/packages/16/11/da8d395299ca166aa56d9436e26fe8440e5443471de16ccd9a1d06f5993a/Pillow-9.3.0.tar.gz", hash = "sha256:c935a22a557a560108d780f9a0fc426dd7459940dc54faa49d83249c8d3e760f"}, + {url = "https://files.pythonhosted.org/packages/1d/15/054644ecbed79d3af017a56eaabd13bf712b21c3a667b8a67a335174f4b7/Pillow-9.3.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:89dca0ce00a2b49024df6325925555d406b14aa3efc2f752dbb5940c52c56b11"}, + {url = "https://files.pythonhosted.org/packages/23/b3/20f97e1bacd02b89953b50b2502be1b10e01d36a0618fb197e4a055e50f4/Pillow-9.3.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:68943d632f1f9e3dce98908e873b3a090f6cba1cbb1b892a9e8d97c938871fbe"}, + {url = "https://files.pythonhosted.org/packages/26/d6/9355d59a2ee9406e4d5129ff0ff99835e7f6adb6133815fab2099e1879b5/Pillow-9.3.0-cp310-cp310-macosx_10_10_x86_64.whl", hash = "sha256:0b7257127d646ff8676ec8a15520013a698d1fdc48bc2a79ba4e53df792526f2"}, + {url = "https://files.pythonhosted.org/packages/2c/3d/36cd1f6c04ab30ab7e6bc8d17a4337fc29fa5b35ebd4c520d916ce7e39e6/Pillow-9.3.0-cp38-cp38-macosx_10_10_x86_64.whl", hash = "sha256:b03ae6f1a1878233ac620c98f3459f79fd77c7e3c2b20d460284e1fb370557d4"}, + {url = "https://files.pythonhosted.org/packages/2c/74/109e3d1fd2847c19c556fe4ce9b3f4aac2147b56c7b5d0924ae9586d2a47/Pillow-9.3.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b9a65733d103311331875c1dca05cb4606997fd33d6acfed695b1232ba1df193"}, + {url = "https://files.pythonhosted.org/packages/2e/c8/03495501bb9beabf34979781b14cc625f39cbd8ff5310a93a85e45987590/Pillow-9.3.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:4390e9ce199fc1951fcfa65795f239a8a4944117b5935a9317fb320e7767b40f"}, + {url = "https://files.pythonhosted.org/packages/2f/73/ec6b3e3f6b311cf1468eafc92a890f690a2cacac0cfd0f1bcc2b891d1334/Pillow-9.3.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:af0372acb5d3598f36ec0914deed2a63f6bcdb7b606da04dc19a88d31bf0c05b"}, + {url = "https://files.pythonhosted.org/packages/39/5e/585dfbe0eb4660ea3ee082289625f94e402239282458c4bf78ecc84fbb93/Pillow-9.3.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:40e1ce476a7804b0fb74bcfa80b0a2206ea6a882938eaba917f7a0f004b42502"}, + {url = "https://files.pythonhosted.org/packages/40/57/c8695a77561a83bd39eba30daf4d894b0b910aad55e2b60f0ef1b1b5205c/Pillow-9.3.0-cp310-cp310-win_amd64.whl", hash = "sha256:9f47eabcd2ded7698106b05c2c338672d16a6f2a485e74481f524e2a23c2794b"}, + {url = "https://files.pythonhosted.org/packages/41/e9/7bae68c360de8d1e7e32aeab252c6dc9336c0d779c9ad5e24ce475d523fd/Pillow-9.3.0-pp37-pypy37_pp73-macosx_10_10_x86_64.whl", hash = "sha256:ab388aaa3f6ce52ac1cb8e122c4bd46657c15905904b3120a6248b5b8b0bc228"}, + {url = "https://files.pythonhosted.org/packages/47/b2/6e5fc952713bfee71c5e25e7917b18207b6f445d81746008b14d9c80a91b/Pillow-9.3.0-cp38-cp38-manylinux_2_28_aarch64.whl", hash = "sha256:15c42fb9dea42465dfd902fb0ecf584b8848ceb28b41ee2b58f866411be33f07"}, + {url = "https://files.pythonhosted.org/packages/48/92/820b43fcb333fe7f4cf726ed3c0cfcfd062f65b8fd23c0e6972a6107f440/Pillow-9.3.0-pp38-pypy38_pp73-macosx_10_10_x86_64.whl", hash = "sha256:b59430236b8e58840a0dfb4099a0e8717ffb779c952426a69ae435ca1f57210c"}, + {url = "https://files.pythonhosted.org/packages/4b/f9/2fa7d6cce0b9867ec3917878d03d5298d7a88522ed7dadc6cac4642bce8b/Pillow-9.3.0-pp37-pypy37_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bca31dd6014cb8b0b2db1e46081b0ca7d936f856da3b39744aef499db5d84d02"}, + {url = "https://files.pythonhosted.org/packages/4e/8c/84131e85d4ebd600a823fad1707157d55055a7ea80ce6c8c2f6e2de93f2c/Pillow-9.3.0-cp38-cp38-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a0a06a052c5f37b4ed81c613a455a81f9a3a69429b4fd7bb913c3fa98abefc20"}, + {url = "https://files.pythonhosted.org/packages/56/02/2c8fde18b251c6ce2061b23b4fa04f3e71d386c725a09753bad19649e1b1/Pillow-9.3.0-cp38-cp38-manylinux_2_28_x86_64.whl", hash = "sha256:51e0e543a33ed92db9f5ef69a0356e0b1a7a6b6a71b80df99f1d181ae5875636"}, + {url = "https://files.pythonhosted.org/packages/5b/48/1e4437f90c0531c0a8f5c5b1e793e0f234fe8203019de04001213b4fb38e/Pillow-9.3.0-cp311-cp311-manylinux_2_28_x86_64.whl", hash = "sha256:90fb88843d3902fe7c9586d439d1e8c05258f41da473952aa8b328d8b907498c"}, + {url = "https://files.pythonhosted.org/packages/5f/1e/8a26e1ff2064b665f3923a727cb9240919cdcdce303e4800729635aefc40/Pillow-9.3.0-cp39-cp39-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b0915e734b33a474d76c28e07292f196cdf2a590a0d25bcc06e64e545f2d146c"}, + {url = "https://files.pythonhosted.org/packages/5f/71/ad106c6e3a28f7ff81b2e172a05c158181b61de2a6292896355f0e50f46c/Pillow-9.3.0-pp37-pypy37_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:c7025dce65566eb6e89f56c9509d4f628fddcedb131d9465cacd3d8bac337e7e"}, + {url = "https://files.pythonhosted.org/packages/6c/a8/3cb2d902c4094b6ad06f069b937c2696fd47c5fc02da107e33470f468534/Pillow-9.3.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:3dd6caf940756101205dffc5367babf288a30043d35f80936f9bfb37f8355b32"}, + {url = "https://files.pythonhosted.org/packages/6d/d2/610687610050eb3ce0ebdd0a3f87d4bb3f1637a89f9fe00060a080a167da/Pillow-9.3.0-1-cp37-cp37m-win32.whl", hash = "sha256:e6ea6b856a74d560d9326c0f5895ef8050126acfdc7ca08ad703eb0081e82b74"}, + {url = "https://files.pythonhosted.org/packages/6f/64/3acfbffd532ec2e82f69d4f22de9c29197540ae61926f5b7072654281e91/Pillow-9.3.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:afa4107d1b306cdf8953edde0534562607fe8811b6c4d9a486298ad31de733b2"}, + {url = "https://files.pythonhosted.org/packages/77/56/bb8dc927b3c44df0ca938b4a17b08c59ef5e1e7cc06300bddf20d4e2935f/Pillow-9.3.0-cp38-cp38-win_amd64.whl", hash = "sha256:276a5ca930c913f714e372b2591a22c4bd3b81a418c0f6635ba832daec1cbcfc"}, + {url = "https://files.pythonhosted.org/packages/78/8c/ae0c7cfb6cae4eb0946b7369258f78e3104c22eeffda45ad6228bc0838f5/Pillow-9.3.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3033fbe1feb1b59394615a1cafaee85e49d01b51d54de0cbf6aa8e64182518a1"}, + {url = "https://files.pythonhosted.org/packages/88/9f/012551c5a9d8b4d0304b66d16119b9c79bac052e0b0bd37de29b64c1bf0c/Pillow-9.3.0-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:073adb2ae23431d3b9bcbcff3fe698b62ed47211d0716b067385538a1b0f28b8"}, + {url = "https://files.pythonhosted.org/packages/8a/e8/124718316b3f4f9fa24e4b7e915d8e02d58d43a5e3c44fcbceef17d60647/Pillow-9.3.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:b90f7616ea170e92820775ed47e136208e04c967271c9ef615b6fbd08d9af0e3"}, + {url = "https://files.pythonhosted.org/packages/a0/6c/6e11abff7f944b51dbeea1bdfe14ad21976858e822ef667fa4eb82ec6f7c/Pillow-9.3.0-cp37-cp37m-win_amd64.whl", hash = "sha256:41e0051336807468be450d52b8edd12ac60bebaa97fe10c8b660f116e50b30e4"}, + {url = "https://files.pythonhosted.org/packages/a1/81/10f4f9665ce366c7501141c973c755cd5c9ebe577886ebfa7ca3e9a115f0/Pillow-9.3.0-cp38-cp38-win32.whl", hash = "sha256:f1ff2ee69f10f13a9596480335f406dd1f70c3650349e2be67ca3139280cade0"}, + {url = "https://files.pythonhosted.org/packages/a7/9e/8acd4d170596fa876b0baaae3542de3b6d0a709b4652ce78285aff59e849/Pillow-9.3.0-cp37-cp37m-win32.whl", hash = "sha256:82409ffe29d70fd733ff3c1025a602abb3e67405d41b9403b00b01debc4c9a29"}, + {url = "https://files.pythonhosted.org/packages/ac/0b/cb7ecd88cea2422818057db720966bbb56bbcec3b359f4a5cafdf737d9e5/Pillow-9.3.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:9aaa107275d8527e9d6e7670b64aabaaa36e5b6bd71a1015ddd21da0d4e06448"}, + {url = "https://files.pythonhosted.org/packages/af/7f/c5f7a35fd7053a4aee79c41fc4b125281745577c6ce3445e57ed8b4eff56/Pillow-9.3.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2e0918e03aa0c72ea56edbb00d4d664294815aa11291a11504a377ea018330d3"}, + {url = "https://files.pythonhosted.org/packages/b7/34/7a88f5ec5f26ac68d3d7a158c67c0a610a4e6b6d22c35266d0e715485b09/Pillow-9.3.0-cp37-cp37m-manylinux_2_28_aarch64.whl", hash = "sha256:6c738585d7a9961d8c2821a1eb3dcb978d14e238be3d70f0a706f7fa9316946b"}, + {url = "https://files.pythonhosted.org/packages/b9/b8/3e2c23766019a9a03ee26ac6b7af9392aba8574806ce10e5074733987240/Pillow-9.3.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:1c7c8ae3864846fc95f4611c78129301e203aaa2af813b703c55d10cc1628535"}, + {url = "https://files.pythonhosted.org/packages/bb/0e/83dd785dff8d62b4d663391ac62390ffadfcdfa4bd11959742f90d02127c/Pillow-9.3.0-cp39-cp39-win32.whl", hash = "sha256:bac18ab8d2d1e6b4ce25e3424f709aceef668347db8637c2296bcf41acb7cf48"}, + {url = "https://files.pythonhosted.org/packages/bc/28/0bcf18f0c22cd89626ee2e071edbe5736d54f9031fe986ae94389776864b/Pillow-9.3.0-cp310-cp310-win32.whl", hash = "sha256:655a83b0058ba47c7c52e4e2df5ecf484c1b0b0349805896dd350cbc416bdd91"}, + {url = "https://files.pythonhosted.org/packages/be/3e/a757fd2fdd5814aa0e9e1e838f79d33e0098e10a2e3afb7acdcb72278290/Pillow-9.3.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:03150abd92771742d4a8cd6f2fa6246d847dcd2e332a18d0c15cc75bf6703040"}, + {url = "https://files.pythonhosted.org/packages/c0/47/4023dab2d77ea3f687939770b06e0c191b4a5a20590f158a6e8dbb03e357/Pillow-9.3.0-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:77ec3e7be99629898c9a6d24a09de089fa5356ee408cdffffe62d67bb75fdd72"}, + {url = "https://files.pythonhosted.org/packages/c0/8f/dfa473f3a6241bff91ae8bb905bd0afceb827f37de2917a94b5c4b1112bf/Pillow-9.3.0-cp39-cp39-win_amd64.whl", hash = "sha256:b472b5ea442148d1c3e2209f20f1e0bb0eb556538690fa70b5e1f79fa0ba8dc2"}, + {url = "https://files.pythonhosted.org/packages/c1/c3/be8222fce0553e05264bfe66f2cc73483567b961f144acef88753fba9c6c/Pillow-9.3.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5d77adcd56a42d00cc1be30843d3426aa4e660cab4a61021dc84467123f7a00c"}, + {url = "https://files.pythonhosted.org/packages/c2/1d/5d0fd887bb790a42a9efb7fe742358f1eae332ee3120a7d4f79ee37358c9/Pillow-9.3.0-cp311-cp311-macosx_10_10_x86_64.whl", hash = "sha256:57751894f6618fd4308ed8e0c36c333e2f5469744c34729a27532b3db106ee20"}, + {url = "https://files.pythonhosted.org/packages/c8/7c/f5fe5b37b6a8f2218db98f33d2278f2900e0fc4ef019cd4d9e522d6e3206/Pillow-9.3.0-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ae5331c23ce118c53b172fa64a4c037eb83c9165aba3a7ba9ddd3ec9fa64a699"}, + {url = "https://files.pythonhosted.org/packages/c9/b8/27c526c45f482450a53c0faab6c0c4baf9cddee0a8f879a8526f7dd8adf0/Pillow-9.3.0-cp37-cp37m-manylinux_2_28_x86_64.whl", hash = "sha256:828989c45c245518065a110434246c44a56a8b2b2f6347d1409c787e6e4651ee"}, + {url = "https://files.pythonhosted.org/packages/ca/97/9677bf1d97c408779e5940b89675e38a8ebe8bcc9dbae8adfc9e7080a314/Pillow-9.3.0-cp39-cp39-macosx_10_10_x86_64.whl", hash = "sha256:73bd195e43f3fadecfc50c682f5055ec32ee2c933243cafbfdec69ab1aa87cad"}, + {url = "https://files.pythonhosted.org/packages/cf/22/fed65d07e5e7b19cc608754e940a9b101bebe78cb6cd9d764639717848a4/Pillow-9.3.0-pp37-pypy37_pp73-win_amd64.whl", hash = "sha256:ebf2029c1f464c59b8bdbe5143c79fa2045a581ac53679733d3a91d400ff9efb"}, + {url = "https://files.pythonhosted.org/packages/d0/ae/b5e8750a7e745926e2227a43766d905c8c6a0f03739c7aec5aea9e975355/Pillow-9.3.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:871b72c3643e516db4ecf20efe735deb27fe30ca17800e661d769faab45a18d7"}, + {url = "https://files.pythonhosted.org/packages/d1/6f/b5e87428a5566563b6d661824c694bbc4b0386aed1c939b9aec47d9ee573/Pillow-9.3.0-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:22b012ea2d065fd163ca096f4e37e47cd8b59cf4b0fd47bfca6abb93df70b34c"}, + {url = "https://files.pythonhosted.org/packages/d4/0d/e8f6ed8e2328007020bb242a0443d925f23ee06d059486c5f1308f2a5e26/Pillow-9.3.0-cp311-cp311-win_amd64.whl", hash = "sha256:18498994b29e1cf86d505edcb7edbe814d133d2232d256db8c7a8ceb34d18cef"}, + {url = "https://files.pythonhosted.org/packages/d5/31/b026f9f7c87adf8027f51f98f392f6558982485b7202af5f9276492b2141/Pillow-9.3.0-1-cp37-cp37m-win_amd64.whl", hash = "sha256:32a44128c4bdca7f31de5be641187367fe2a450ad83b833ef78910397db491aa"}, + {url = "https://files.pythonhosted.org/packages/d5/79/191ea841f818aba4eb9783b9f91a3c16c51deff7326f5a2f47de54959a28/Pillow-9.3.0-pp37-pypy37_pp73-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:dbb8e7f2abee51cef77673be97760abff1674ed32847ce04b4af90f610144c7b"}, + {url = "https://files.pythonhosted.org/packages/d6/be/996d629efd03aa305472a17183fcdfe2dd8529acea767d0ba2242d90cbfa/Pillow-9.3.0-cp310-cp310-manylinux_2_28_x86_64.whl", hash = "sha256:801ec82e4188e935c7f5e22e006d01611d6b41661bba9fe45b60e7ac1a8f84de"}, + {url = "https://files.pythonhosted.org/packages/db/b0/6438c96e80d4cad5b6381ba774018de9d8eae591d65bdfd80e3ad630928a/Pillow-9.3.0-cp39-cp39-manylinux_2_28_x86_64.whl", hash = "sha256:97aabc5c50312afa5e0a2b07c17d4ac5e865b250986f8afe2b02d772567a380c"}, + {url = "https://files.pythonhosted.org/packages/dc/20/30e5ea4ecb35b36d9bc4ff4e8edc048e017a8e3d2e087a512b0622bfdde3/Pillow-9.3.0-cp311-cp311-win32.whl", hash = "sha256:3168434d303babf495d4ba58fc22d6604f6e2afb97adc6a423e917dab828939c"}, + {url = "https://files.pythonhosted.org/packages/e0/59/74d88751801101259abd695f77c44b97a828b6a4e7981a79a75d2c3379ae/Pillow-9.3.0-cp311-cp311-manylinux_2_28_aarch64.whl", hash = "sha256:502526a2cbfa431d9fc2a079bdd9061a2397b842bb6bc4239bb176da00993812"}, + {url = "https://files.pythonhosted.org/packages/ec/4f/bc65f543b4d774d6c888cb0936a8b91cf7c5fbb25e16f923e332822b279b/Pillow-9.3.0-cp37-cp37m-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b4012d06c846dc2b80651b120e2cdd787b013deb39c09f407727ba90015c684f"}, + {url = "https://files.pythonhosted.org/packages/f1/e4/2f7e4efeb79ab0a2c5ecba320b2e5a3aad7a49cc543407f4c1268ed804bb/Pillow-9.3.0-pp38-pypy38_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:0b07fffc13f474264c336298d1b4ce01d9c5a011415b79d4ee5527bb69ae6f65"}, + {url = "https://files.pythonhosted.org/packages/f7/11/763c3992c3e6d00e9f6de81b0d721306757bb7201155d135a16032460943/Pillow-9.3.0-cp39-cp39-manylinux_2_28_aarch64.whl", hash = "sha256:ad58d27a5b0262c0c19b47d54c5802db9b34d38bbf886665b626aff83c74bacd"}, + {url = "https://files.pythonhosted.org/packages/fc/12/32101461796addca02fd14dc4d2b76068a2cbf895002ed668550caf3fcc1/Pillow-9.3.0-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:be55f8457cd1eac957af0c3f5ece7bc3f033f89b114ef30f710882717670b2a8"}, +] +"platformdirs 2.5.4" = [ + {url = "https://files.pythonhosted.org/packages/61/e0/15ba41c6716acb033c3793be3a02f26c53914ecd9bdd6b315001f8f5f581/platformdirs-2.5.4-py3-none-any.whl", hash = "sha256:af0276409f9a02373d540bf8480021a048711d572745aef4b7842dad245eba10"}, + {url = "https://files.pythonhosted.org/packages/cb/5f/dda8451435f17ed8043eab5ffe04e47d703debe8fe845eb074f42260e50a/platformdirs-2.5.4.tar.gz", hash = "sha256:1006647646d80f16130f052404c6b901e80ee4ed6bef6792e1f238a8969106f7"}, +] +"pluggy 1.0.0" = [ + {url = "https://files.pythonhosted.org/packages/9e/01/f38e2ff29715251cf25532b9082a1589ab7e4f571ced434f98d0139336dc/pluggy-1.0.0-py2.py3-none-any.whl", hash = "sha256:74134bbf457f031a36d68416e1509f34bd5ccc019f0bcc952c7b909d06b37bd3"}, + {url = "https://files.pythonhosted.org/packages/a1/16/db2d7de3474b6e37cbb9c008965ee63835bba517e22cdb8c35b5116b5ce1/pluggy-1.0.0.tar.gz", hash = "sha256:4224373bacce55f955a878bf9cfa763c1e360858e330072059e10bad68531159"}, +] +"protobuf 3.20.3" = [ + {url = "https://files.pythonhosted.org/packages/00/e7/d23c439c55c90ae2e52184363162f7079ca3e7d86205b411d4e9dc266f81/protobuf-3.20.3-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:398a9e0c3eaceb34ec1aee71894ca3299605fa8e761544934378bbc6c97de23b"}, + {url = "https://files.pythonhosted.org/packages/11/a5/e52b731415ad6ef3d841e9e6e337a690249e800cc7c06f0749afab26348c/protobuf-3.20.3-cp39-cp39-win_amd64.whl", hash = "sha256:03038ac1cfbc41aa21f6afcbcd357281d7521b4157926f30ebecc8d4ea59dcb7"}, + {url = "https://files.pythonhosted.org/packages/28/55/b80e8567ec327c060fa39b242392e25690c8899c489ecd7bb65b46b7bb55/protobuf-3.20.3-cp310-cp310-manylinux2014_aarch64.whl", hash = "sha256:f4bd856d702e5b0d96a00ec6b307b0f51c1982c2bf9c0052cf9019e9a544ba99"}, + {url = "https://files.pythonhosted.org/packages/2a/7c/e7091f0eea6eec70547d28c6c0d8c7335ee58f6b13456608beec8c94a62a/protobuf-3.20.3-cp37-cp37m-manylinux2014_aarch64.whl", hash = "sha256:d9e4432ff660d67d775c66ac42a67cf2453c27cb4d738fc22cb53b5d84c135d4"}, + {url = "https://files.pythonhosted.org/packages/31/be/80a9c6f16dfa4d41be3edbe655349778ae30882407fa8275eb46b4d34854/protobuf-3.20.3-cp310-cp310-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:9aae4406ea63d825636cc11ffb34ad3379335803216ee3a856787bcf5ccc751e"}, + {url = "https://files.pythonhosted.org/packages/32/f8/52f598bceb16fe365f4ef8e957ac8890aeb56abf97d365ff5abd8c1250cf/protobuf-3.20.3-cp38-cp38-win_amd64.whl", hash = "sha256:447d43819997825d4e71bf5769d869b968ce96848b6479397e29fc24c4a5dfe9"}, + {url = "https://files.pythonhosted.org/packages/36/8b/433071fed0058322090a55021bdc8da76d16c7bc9823f5795797803dd6d0/protobuf-3.20.3-cp39-cp39-win32.whl", hash = "sha256:819559cafa1a373b7096a482b504ae8a857c89593cf3a25af743ac9ecbd23480"}, + {url = "https://files.pythonhosted.org/packages/3c/14/16ef7da61d30a519d84e6841d096fe446c4d8a2c39b083b0376b4785f1f3/protobuf-3.20.3-cp38-cp38-win32.whl", hash = "sha256:c02ce36ec760252242a33967d51c289fd0e1c0e6e5cc9397e2279177716add86"}, + {url = "https://files.pythonhosted.org/packages/4c/12/62e1d5505c172e1a7f803d83b0b1693f7952c3c271eb2f155703012ae67a/protobuf-3.20.3-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:74480f79a023f90dc6e18febbf7b8bac7508420f2006fabd512013c0c238f454"}, + {url = "https://files.pythonhosted.org/packages/55/5b/e3d951e34f8356e5feecacd12a8e3b258a1da6d9a03ad1770f28925f29bc/protobuf-3.20.3.tar.gz", hash = "sha256:2e3427429c9cffebf259491be0af70189607f365c2f41c7c3764af6f337105f2"}, + {url = "https://files.pythonhosted.org/packages/6f/5e/fc6feb366b0a9f28e0a2de3b062667c521cd9517d4ff55077b8f351ba2f3/protobuf-3.20.3-cp310-cp310-win_amd64.whl", hash = "sha256:67a3598f0a2dcbc58d02dd1928544e7d88f764b47d4a286202913f0b2801c2e7"}, + {url = "https://files.pythonhosted.org/packages/8d/14/619e24a4c70df2901e1f4dbc50a6291eb63a759172558df326347dce1f0d/protobuf-3.20.3-py2.py3-none-any.whl", hash = "sha256:a7ca6d488aa8ff7f329d4c545b2dbad8ac31464f1d8b1c87ad1346717731e4db"}, + {url = "https://files.pythonhosted.org/packages/98/07/4c75a689fa173c12b92c9a64a82efad44797b9b2b784c8562f36ab28b551/protobuf-3.20.3-cp37-cp37m-win_amd64.whl", hash = "sha256:8c0c984a1b8fef4086329ff8dd19ac77576b384079247c770f29cc8ce3afa06c"}, + {url = "https://files.pythonhosted.org/packages/99/25/5825472ecd911f4ac2ac4e9ab039a48b6d03874e2add92fb633e080bf3eb/protobuf-3.20.3-cp39-cp39-manylinux2014_aarch64.whl", hash = "sha256:bf01b5720be110540be4286e791db73f84a2b721072a3711efff6c324cdf074b"}, + {url = "https://files.pythonhosted.org/packages/9c/d8/dc6a9ee6ec43a1001e3d71cccda70cf50ac0098000fc455023dba3b46ebf/protobuf-3.20.3-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:899dc660cd599d7352d6f10d83c95df430a38b410c1b66b407a6b29265d66469"}, + {url = "https://files.pythonhosted.org/packages/9f/1a/6848ed1669a6c70bf947d25d64ce6dcc65ccec06e917072df516944fa17e/protobuf-3.20.3-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:de78575669dddf6099a8a0f46a27e82a1783c557ccc38ee620ed8cc96d3be7d7"}, + {url = "https://files.pythonhosted.org/packages/b5/b6/ec87636b9381137f17292851461902ceac7632a00476c2afbcd864ed5447/protobuf-3.20.3-cp38-cp38-manylinux2014_aarch64.whl", hash = "sha256:f4c42102bc82a51108e449cbb32b19b180022941c727bac0cfd50170341f16ee"}, + {url = "https://files.pythonhosted.org/packages/c7/df/ec3ecb8c940b36121c7b77c10acebf3d1c736498aa2f1fe3b6231ee44e76/protobuf-3.20.3-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:daa564862dd0d39c00f8086f88700fdbe8bc717e993a21e90711acfed02f2402"}, + {url = "https://files.pythonhosted.org/packages/da/e4/4d62585593e9f962cb02614534f62f930de6a80a0a3784282094a01919b2/protobuf-3.20.3-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:44246bab5dd4b7fbd3c0c80b6f16686808fab0e4aca819ade6e8d294a29c7050"}, + {url = "https://files.pythonhosted.org/packages/db/96/948d3fcc1fa816e7ae1d27af59b9d8c5c5e582f3994fd14394f31da95b99/protobuf-3.20.3-cp310-cp310-win32.whl", hash = "sha256:28545383d61f55b57cf4df63eebd9827754fd2dc25f80c5253f9184235db242c"}, + {url = "https://files.pythonhosted.org/packages/ef/d4/765a106ca96d487f94f3c99e46b399218f53735628c3b2d759a832e2adab/protobuf-3.20.3-cp37-cp37m-win32.whl", hash = "sha256:b6cc7ba72a8850621bfec987cb72623e703b7fe2b9127a161ce61e61558ad905"}, + {url = "https://files.pythonhosted.org/packages/fe/8f/d9db035740002d61b4140aaef53a8bac7e316b18ec8744eb6c1fcf83c310/protobuf-3.20.3-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:e64857f395505ebf3d2569935506ae0dfc4a15cb80dc25261176c784662cdcc4"}, + {url = "https://test-files.pythonhosted.org/packages/8d/14/619e24a4c70df2901e1f4dbc50a6291eb63a759172558df326347dce1f0d/protobuf-3.20.3-py2.py3-none-any.whl", hash = "sha256:a7ca6d488aa8ff7f329d4c545b2dbad8ac31464f1d8b1c87ad1346717731e4db"}, + {url = "https://test-files.pythonhosted.org/packages/f4/de/904b3f09af0e6a2f0072a25878d784d151283546a5bb3e2ba12def8997c6/protobuf-3.20.3.tar.gz", hash = "sha256:e8a258d4d36b076db944e6ed7f023b47443e197d134858cb0e87b7f9b973e9bd"}, +] +"py-sr25519-bindings 0.1.4" = [ + {url = "https://files.pythonhosted.org/packages/00/17/33406429b979af786a6cf2066b6463e224a2ac763105e82483f513bfaadb/py_sr25519_bindings-0.1.4-cp38-cp38-macosx_10_7_x86_64.whl", hash = "sha256:721cae28e86038682dd522191f9cb58a71b3455ef461433ba27a76d2d321197c"}, + {url = "https://files.pythonhosted.org/packages/06/41/3d76392a2e0dd37e3035528291c84488e9d074f16e121565dde1928f1bd4/py_sr25519_bindings-0.1.4-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:8e62369aca9455131330cf63b0fcec3be198cabad936317321aa0db9d143435b"}, + {url = "https://files.pythonhosted.org/packages/08/18/c25beaad05e559c7105e40b97aa2929cc8c0174b9b69bd8c4a7cf0705ec6/py_sr25519_bindings-0.1.4-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:aed508e15e695c5e3147be936db7a40f7bf5cb0a4078a9eb0e25fbdeb7c08982"}, + {url = "https://files.pythonhosted.org/packages/0c/81/cbe028f361e6d395635ab761e7324adaa3db5dd9c8e8a44df74202d698e3/py_sr25519_bindings-0.1.4-pp37-pypy37_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:cb1edb9db13548252fe3410868111dcda48a5b6ecda11cebb156930f0f472368"}, + {url = "https://files.pythonhosted.org/packages/21/36/8a3eb5cf00999d6f137bfe2a1e2a6e374f35e06d6cf31aa082142c1a1ef1/py_sr25519_bindings-0.1.4-cp37-cp37m-manylinux_2_28_armv7l.whl", hash = "sha256:6be4f52320d021fe8a86d72d71fae821b6c251f12b36e7e3deee5a1140da55b6"}, + {url = "https://files.pythonhosted.org/packages/25/c0/3041d947eaeabf8f84032934bc7a1f39a308befd59f27896f891f2fe9aa7/py_sr25519_bindings-0.1.4-cp38-none-win_amd64.whl", hash = "sha256:127057216b8cd32ea322d64aa52e70ba7b42a55cd4eb31e8df7c0120934f2445"}, + {url = "https://files.pythonhosted.org/packages/29/c6/e18d4c1a2882d1f1389948c859d8bfe0a0cebe4e7cb118b9516c09488c8e/py_sr25519_bindings-0.1.4-cp37-none-win_amd64.whl", hash = "sha256:d13e3a6b262494f66f36de3ba45d1040fee7a0c4104d56086b15315332026db9"}, + {url = "https://files.pythonhosted.org/packages/38/21/dd5ca55d51bf77ad63f641e080c4cc6a0b09bccd07bf44ec9886e2e29107/py_sr25519_bindings-0.1.4-cp39-cp39-macosx_10_7_x86_64.whl", hash = "sha256:5a0f591f9b474ca31f0ca199ebc5d2c70a8869ff6e211188a1562310614558dd"}, + {url = "https://files.pythonhosted.org/packages/3f/02/0d807a6e7d970580485c65b55e8f3a6d737da6700de4ef23dde8cc6fd1be/py_sr25519_bindings-0.1.4-cp310-none-win_amd64.whl", hash = "sha256:1ca0d8e1ca66a17c41e3f6da0c3837e7dbf5b391eb4ea41cfe6026bad0adc8ea"}, + {url = "https://files.pythonhosted.org/packages/44/02/d8a4d2e5b314e8b4d9d0e18f3ce8b89b3fe5e59fbb0413e787c8b1f6e671/py_sr25519_bindings-0.1.4-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6715852eb2ea733c4978b77f9a049cc9eb763d54270d5b1263b198256656c38e"}, + {url = "https://files.pythonhosted.org/packages/4c/2c/d263ede4827a7a5e02290b7e8d34515b244897d80005ea345d69311cb99d/py_sr25519_bindings-0.1.4-cp39-none-win32.whl", hash = "sha256:0a09f5886a706fcee6786f94dd59a04bdc95f2d6c4b7e1b3118ca805d322a055"}, + {url = "https://files.pythonhosted.org/packages/64/82/f55600547af686b1ef3db123471493800ce6f9a61ac7a9e355b3bd6360aa/py_sr25519_bindings-0.1.4.tar.gz", hash = "sha256:5e12ca977014f148f4bfb6ba662f1529b15cc8ce030719d726c4e16a379e976e"}, + {url = "https://files.pythonhosted.org/packages/6a/7c/b4c3ea21d696507b7bf129e6ee1eda0a7bb505604ff5aebe8666a021f7d9/py_sr25519_bindings-0.1.4-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:b901675f8ea8ca4a6e55887ea48448a3f6bf55f22baa4acfa77d7c844e82e9db"}, + {url = "https://files.pythonhosted.org/packages/74/a7/377ba7820127f72a97cf6355cfa59ee92a767e64c0730d3c2de5b99f3a36/py_sr25519_bindings-0.1.4-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:3f52666b02075483dfdd294b9d0fd903eaf96ac7140e5be45390b25ded52ca6a"}, + {url = "https://files.pythonhosted.org/packages/76/cb/0e5541edee87356945beac027e9180cdb1a7850c92890c76e1b45d67d24f/py_sr25519_bindings-0.1.4-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:4940ebfcb482b33468c41dda9e8c19137c14cc3b993e1084e55387c6acfa11ab"}, + {url = "https://files.pythonhosted.org/packages/7b/48/7ff1093cf5237c79c7d5c80693b19f0bb2c9fc46f828b596ca65add25cc0/py_sr25519_bindings-0.1.4-cp38-cp38-manylinux_2_28_armv7l.whl", hash = "sha256:9b80e4aa4037b1e8fd3d5ff0fb4e2c3d92e04b2936f29c79d5411c5a22562f25"}, + {url = "https://files.pythonhosted.org/packages/7e/7c/b6f9996af8ccd71ee9436e69a0e35229805e44fa12913a276230d3e43493/py_sr25519_bindings-0.1.4-cp38-none-win32.whl", hash = "sha256:ce3639509e87ab04652c62aab626f13a80e308347047173bf74749397d0be539"}, + {url = "https://files.pythonhosted.org/packages/81/07/fa3613aa467368f6a8bbbba1342e2e4ad5f01c4c69bdbae320910c748d7d/py_sr25519_bindings-0.1.4-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:67dd46da0a571859418fc938af15ab9a0586e47244d21f0f26c5cbf4daf10a3b"}, + {url = "https://files.pythonhosted.org/packages/82/32/8ceb7a90a7ef390c06483ddf801da300f0f53b9d534d54d20b191b6ae70a/py_sr25519_bindings-0.1.4-cp310-cp310-manylinux_2_28_armv7l.whl", hash = "sha256:34635da67e6798bb4535543e63c3e1d3b19f17a4df1f9b613c69b66fc8296fa3"}, + {url = "https://files.pythonhosted.org/packages/93/65/c2571cd841cacbc686b992d3dc2c86943300e5b018277865b02e627623f3/py_sr25519_bindings-0.1.4-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1121e5da273c81b2e7ba0ca4bef8a89c527a6e25ed3110a95e93fd2caa04c50b"}, + {url = "https://files.pythonhosted.org/packages/9a/b2/de252739677fbbae043cdec66c85c41947fe45e05a262f36afb417f3b287/py_sr25519_bindings-0.1.4-cp39-cp39-macosx_10_9_x86_64.macosx_11_0_arm64.macosx_10_9_universal2.whl", hash = "sha256:197892cd89077baf2be51e3307a40de2c32006a2b89fec7d767a1d0b2749712d"}, + {url = "https://files.pythonhosted.org/packages/a3/6a/da96376c02c6b11bb1ec84dd225016bcaebd39e73ed0635b39017e0c919a/py_sr25519_bindings-0.1.4-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:d1c1247b4bf4c5670767e8a35bc259b425b275c8d72c6e3f1cfac47cf9b80e89"}, + {url = "https://files.pythonhosted.org/packages/a5/ae/16878ea5c1be67708bfd39b7e3f98fa29f0a22a8952499daa18568abc528/py_sr25519_bindings-0.1.4-cp38-cp38-macosx_10_9_x86_64.macosx_11_0_arm64.macosx_10_9_universal2.whl", hash = "sha256:d1b1b51d997363a264fb3f91978f21ea784f5ee50ed26e11ed0a0f26c497a4eb"}, + {url = "https://files.pythonhosted.org/packages/ae/58/3af038d8a625f4fe6b2a8208a3aabdd7d7fa7a56adc8506f9a2ec7d02e2c/py_sr25519_bindings-0.1.4-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:3845f55a88dcba825c16e65fc9e26742cbb9103fba5229fd0c3e9e8deffd323b"}, + {url = "https://files.pythonhosted.org/packages/af/5f/a876044eba658ed2272cc640d56cc13c1378f801b0d921858fbaaa677a64/py_sr25519_bindings-0.1.4-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:72b49cba419f5c76436bf06de4575ee27713afd8b867c4c14cb7a29e1046c30a"}, + {url = "https://files.pythonhosted.org/packages/b0/94/439f7574765167520ef20f89a2d11e77fafa097ba7e0b212942f3d29384a/py_sr25519_bindings-0.1.4-cp39-none-win_amd64.whl", hash = "sha256:855af2efee23ebbb4b5544027b2b9a4818db34717b88741bcfd74f5739e9152f"}, + {url = "https://files.pythonhosted.org/packages/b3/ef/342e55303451366e28381fd48117b248168fdb251995ded395364389b185/py_sr25519_bindings-0.1.4-cp310-cp310-macosx_10_9_x86_64.macosx_11_0_arm64.macosx_10_9_universal2.whl", hash = "sha256:14a06ca42d5fd07673138bf9970db9091059a1e4d704545bdf156dd05de3e3c6"}, + {url = "https://files.pythonhosted.org/packages/b8/98/b40bc2afa4e1a47fa18b083cf467a437512377366746c1100e53b517a554/py_sr25519_bindings-0.1.4-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:42097fab2702186a6591471bc366d7c804c7c30744acd59d6c6a38fdcad4bedb"}, + {url = "https://files.pythonhosted.org/packages/c5/a2/0d05e8b565cddfb32fa21ea78fcea9e400360217e1955aa7047eafe2a977/py_sr25519_bindings-0.1.4-cp39-cp39-manylinux_2_28_armv7l.whl", hash = "sha256:465c2ae7e3191f24ac10519aece185772a6b9d6179b8948fad78c3b1dbe77d8c"}, + {url = "https://files.pythonhosted.org/packages/ca/80/d476d745110b1a727e976242a1f7fbaee47115b7c093fcc0f4dd99576887/py_sr25519_bindings-0.1.4-cp37-none-win32.whl", hash = "sha256:1fb9ca7b65e60b64bd6e81ee2d5e6556d93b317af3c95a2e24bf45a3c44041a0"}, + {url = "https://files.pythonhosted.org/packages/cd/dd/904edf234ede3847ff879fe2ca65cf3085255442935e006ea02306afd1bb/py_sr25519_bindings-0.1.4-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:34786ba33f602d9d4f2495bd29d9f0cb357813a6ee8ae5cd9d37dbda86c141a4"}, + {url = "https://files.pythonhosted.org/packages/e3/d8/7fb1e71f673c4d50fc54051ed7a3c08612b8e9b86d6d086ce31c3220cdf3/py_sr25519_bindings-0.1.4-cp310-cp310-macosx_10_7_x86_64.whl", hash = "sha256:9cbee7341ed35d08533c7dac4d227e2fe21b815072ef66178a7ddb77f4e7be36"}, + {url = "https://files.pythonhosted.org/packages/e8/6d/d10583af0eb1f8d01f4ec641ee72d45893327e037333586d3b9e2ede4857/py_sr25519_bindings-0.1.4-cp37-cp37m-macosx_10_7_x86_64.whl", hash = "sha256:9e07cc588754da27c03185e2d3823537790f616b5aab3df1703ca0f6f578114c"}, + {url = "https://files.pythonhosted.org/packages/e8/99/a9d5da4aea85990fe4d088bebfff28d27067dc8d5249763b748821691953/py_sr25519_bindings-0.1.4-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9e5118cc7e1a77083307d260ccda21a0ec14efb0b98535f8fc9e2c54c7594836"}, + {url = "https://files.pythonhosted.org/packages/f6/39/08b76be2855ebf643e3a5de5de7fc383b961221e3911df547806be9561c8/py_sr25519_bindings-0.1.4-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:2ec17c935f8ae9a00bb5d6adac6cc455fd6052042959ace5563448c355e2960a"}, + {url = "https://files.pythonhosted.org/packages/f8/dd/38bd462934574c44f8e7ca635d5fcc843fbaa3e1252724183c67651dd695/py_sr25519_bindings-0.1.4-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0046dda17c554376f5ba11ea91163b1b883ac61fcc1b1ba588e31b1cb58add28"}, + {url = "https://files.pythonhosted.org/packages/ff/35/b25799b4ce26db05c08027dfbafa6e7f60812576d22b02e5e52db4531c90/py_sr25519_bindings-0.1.4-cp310-none-win32.whl", hash = "sha256:f7ca8f4e62aee8bc33916f6422e8ac5ffeeb96bc11f7ca52792354b771216bd8"}, + {url = "https://test-files.pythonhosted.org/packages/1d/f9/7680e56c118871726cf7d75cf5b6fce8eb2444748d85db675b82925a410a/py_sr25519_bindings-0.1.4-cp37-cp37m-macosx_10_7_x86_64.whl", hash = "sha256:938190d97f27566953468caf19baba3c7ee776d60eef816c7d233224624b00a6"}, + {url = "https://test-files.pythonhosted.org/packages/5e/3d/752274043b7af794cfb7e541127d35df56bfb0b42120813c54ab52c9628b/py_sr25519_bindings-0.1.4.tar.gz", hash = "sha256:d9c7fd291c3233de404161c739b0626ff10ace60aabfd8334e4a8432a0a9e702"}, +] +"pycparser 2.21" = [ + {url = "https://files.pythonhosted.org/packages/5e/0b/95d387f5f4433cb0f53ff7ad859bd2c6051051cebbb564f139a999ab46de/pycparser-2.21.tar.gz", hash = "sha256:e644fdec12f7872f86c58ff790da456218b10f863970249516d60a5eaca77206"}, + {url = "https://files.pythonhosted.org/packages/62/d5/5f610ebe421e85889f2e55e33b7f9a6795bd982198517d912eb1c76e1a53/pycparser-2.21-py2.py3-none-any.whl", hash = "sha256:8ee45429555515e1f6b185e78100aea234072576aa43ab53aefcae078162fca9"}, +] +"pycryptodome 3.15.0" = [ + {url = "https://files.pythonhosted.org/packages/00/07/5a262e3213a9358e2f7caf9080aa8a984f44bf4aee84592dfb965dd34355/pycryptodome-3.15.0-cp35-abi3-win_amd64.whl", hash = "sha256:c77126899c4b9c9827ddf50565e93955cb3996813c18900c16b2ea0474e130e9"}, + {url = "https://files.pythonhosted.org/packages/01/bc/7c67348624581fc57e5cb34e650ba09ba668e08e41937d1d1bbdc8cd9e9b/pycryptodome-3.15.0-cp27-cp27m-manylinux2010_i686.whl", hash = "sha256:7c9ed8aa31c146bef65d89a1b655f5f4eab5e1120f55fc297713c89c9e56ff0b"}, + {url = "https://files.pythonhosted.org/packages/11/e4/a8e8056a59c39f8c9ddd11d3bc3e1a67493abe746df727e531f66ecede9e/pycryptodome-3.15.0.tar.gz", hash = "sha256:9135dddad504592bcc18b0d2d95ce86c3a5ea87ec6447ef25cfedea12d6018b8"}, + {url = "https://files.pythonhosted.org/packages/1e/ed/e908d15473f14975f1b29d52de57fee7b035f87ff9560f9dae2e37bf9bc2/pycryptodome-3.15.0-cp27-cp27m-manylinux1_x86_64.whl", hash = "sha256:2ea63d46157386c5053cfebcdd9bd8e0c8b7b0ac4a0507a027f5174929403884"}, + {url = "https://files.pythonhosted.org/packages/2e/6f/27fbd8f3fd8b48feba2b4226f7f8d23af7755c54957fccc3fe6f44b764cf/pycryptodome-3.15.0-cp35-abi3-manylinux1_i686.whl", hash = "sha256:4c3ccad74eeb7b001f3538643c4225eac398c77d617ebb3e57571a897943c667"}, + {url = "https://files.pythonhosted.org/packages/2f/dc/e5bb825eb7348773b77ace0d977f549af851c1d8300f1ba60119e88ba715/pycryptodome-3.15.0-cp35-abi3-macosx_10_9_x86_64.whl", hash = "sha256:9ee40e2168f1348ae476676a2e938ca80a2f57b14a249d8fe0d3cdf803e5a676"}, + {url = "https://files.pythonhosted.org/packages/34/09/ab89d75316862ae9fced5516ba533dc17da89938e7de4d5ddfd8483fd9e8/pycryptodome-3.15.0-cp27-cp27mu-manylinux1_x86_64.whl", hash = "sha256:0926f7cc3735033061ef3cf27ed16faad6544b14666410727b31fea85a5b16eb"}, + {url = "https://files.pythonhosted.org/packages/35/5b/ba592bfd0d3bad9450645b751c132cf1028dc111ae699fd8e70808414941/pycryptodome-3.15.0-cp35-abi3-manylinux2014_aarch64.whl", hash = "sha256:092a26e78b73f2530b8bd6b3898e7453ab2f36e42fd85097d705d6aba2ec3e5e"}, + {url = "https://files.pythonhosted.org/packages/38/a7/ff3d1e9ef28726433b5d6edb5ded96a0b9d85722dad9c3faf27a1372b0a3/pycryptodome-3.15.0-pp36-pypy36_pp73-win32.whl", hash = "sha256:9c772c485b27967514d0df1458b56875f4b6d025566bf27399d0c239ff1b369f"}, + {url = "https://files.pythonhosted.org/packages/55/60/28d873c1efe46cf62494a0393fe34e4757821123fb1af9c45be3b2eeba8a/pycryptodome-3.15.0-cp35-abi3-win32.whl", hash = "sha256:e244ab85c422260de91cda6379e8e986405b4f13dc97d2876497178707f87fc1"}, + {url = "https://files.pythonhosted.org/packages/5a/3d/56084bd2b973c262a59d6b7c5618d93f8ee6045c484e7675e97104e48ac3/pycryptodome-3.15.0-cp27-cp27mu-manylinux2010_x86_64.whl", hash = "sha256:c3640deff4197fa064295aaac10ab49a0d55ef3d6a54ae1499c40d646655c89f"}, + {url = "https://files.pythonhosted.org/packages/5c/9c/2cfbb08a3f573e35818fe49d4f6efdc6c157553b71bc7d65592de49f623f/pycryptodome-3.15.0-cp27-cp27m-win_amd64.whl", hash = "sha256:7e3a8f6ee405b3bd1c4da371b93c31f7027944b2bcce0697022801db93120d83"}, + {url = "https://files.pythonhosted.org/packages/6a/09/84ac32b49e991308749d615e7a5b9ae13b94adb01279224fbca584636977/pycryptodome-3.15.0-cp27-cp27m-manylinux1_i686.whl", hash = "sha256:2ffd8b31561455453ca9f62cb4c24e6b8d119d6d531087af5f14b64bee2c23e6"}, + {url = "https://files.pythonhosted.org/packages/6c/73/7b25e21cbb4aa8817f85fa86537798d681f3dd479fd5d4737e9f3efbaf9e/pycryptodome-3.15.0-cp27-cp27m-manylinux2014_aarch64.whl", hash = "sha256:2ec709b0a58b539a4f9d33fb8508264c3678d7edb33a68b8906ba914f71e8c13"}, + {url = "https://files.pythonhosted.org/packages/74/4d/1340e63264e07ff5f1e1daec9d66015ade99d64f3b966a52ff7ff3f4a362/pycryptodome-3.15.0-pp36-pypy36_pp73-manylinux1_x86_64.whl", hash = "sha256:ecaaef2d21b365d9c5ca8427ffc10cebed9d9102749fd502218c23cb9a05feb5"}, + {url = "https://files.pythonhosted.org/packages/74/f8/e6e9e2426f332b2216950df88bdf160ed90b2dbe42dfd5fc5e8ac33bd583/pycryptodome-3.15.0-cp27-cp27mu-manylinux2010_i686.whl", hash = "sha256:2aa55aae81f935a08d5a3c2042eb81741a43e044bd8a81ea7239448ad751f763"}, + {url = "https://files.pythonhosted.org/packages/7d/ac/843a78bc3c5c680f4c22f530bdb6e2927b770f77630948b0e0247cc23c04/pycryptodome-3.15.0-cp27-cp27m-macosx_10_9_x86_64.whl", hash = "sha256:ff7ae90e36c1715a54446e7872b76102baa5c63aa980917f4aa45e8c78d1a3ec"}, + {url = "https://files.pythonhosted.org/packages/7d/be/e3e56f7f92bebf506aec486eb71d91952d2e9faf5e10872a89931db4120f/pycryptodome-3.15.0-cp35-abi3-manylinux2010_x86_64.whl", hash = "sha256:4b52cb18b0ad46087caeb37a15e08040f3b4c2d444d58371b6f5d786d95534c2"}, + {url = "https://files.pythonhosted.org/packages/86/93/93d5752292d6cf2709d9c3343c26e5a6f308976a566b6e4a389094b83fbe/pycryptodome-3.15.0-cp27-cp27m-manylinux2010_x86_64.whl", hash = "sha256:5099c9ca345b2f252f0c28e96904643153bae9258647585e5e6f649bb7a1844a"}, + {url = "https://files.pythonhosted.org/packages/9b/c0/6aac989804de5526099062b263be17c7216901fc2fbbc4e08b6e44d9c236/pycryptodome-3.15.0-cp27-cp27mu-manylinux2014_aarch64.whl", hash = "sha256:045d75527241d17e6ef13636d845a12e54660aa82e823b3b3341bcf5af03fa79"}, + {url = "https://files.pythonhosted.org/packages/9b/e8/628f92b38ee4475d7b316d04c2913d397cdcc3f3a873bdbea10a438ba9fe/pycryptodome-3.15.0-pp27-pypy_73-manylinux1_x86_64.whl", hash = "sha256:ff287bcba9fbeb4f1cccc1f2e90a08d691480735a611ee83c80a7d74ad72b9d9"}, + {url = "https://files.pythonhosted.org/packages/b1/54/ad3e2e07a5a7ceb926971398f7e3a0eeee85b6e1d3e658df8f71a4497daa/pycryptodome-3.15.0-cp35-abi3-manylinux1_x86_64.whl", hash = "sha256:1b22bcd9ec55e9c74927f6b1f69843cb256fb5a465088ce62837f793d9ffea88"}, + {url = "https://files.pythonhosted.org/packages/b1/6c/4ee93e2e863e95caffc5a356b867e86f5596f4e38cddb43848412dd69176/pycryptodome-3.15.0-pp27-pypy_73-manylinux2010_x86_64.whl", hash = "sha256:60b4faae330c3624cc5a546ba9cfd7b8273995a15de94ee4538130d74953ec2e"}, + {url = "https://files.pythonhosted.org/packages/b1/d5/4a140b9d316681e9d2e55ac8a29f7f70b446c795e0af5f3de2500d7654b0/pycryptodome-3.15.0-cp27-cp27m-win32.whl", hash = "sha256:fd2184aae6ee2a944aaa49113e6f5787cdc5e4db1eb8edb1aea914bd75f33a0c"}, + {url = "https://files.pythonhosted.org/packages/b1/e4/079a70b03928a01d5517cc69a5cf4bca79df7c3d85e27e4e66e9b4e211e7/pycryptodome-3.15.0-cp27-cp27mu-manylinux1_i686.whl", hash = "sha256:b9c5b1a1977491533dfd31e01550ee36ae0249d78aae7f632590db833a5012b8"}, + {url = "https://files.pythonhosted.org/packages/b5/de/a1d1407e0bfd396e62c9efe3261be0c76888a8f3722b9b7f61f460e0e328/pycryptodome-3.15.0-pp36-pypy36_pp73-manylinux2010_x86_64.whl", hash = "sha256:d2a39a66057ab191e5c27211a7daf8f0737f23acbf6b3562b25a62df65ffcb7b"}, + {url = "https://files.pythonhosted.org/packages/bb/7a/0e51d1dc253d0571106009b94762b8ab5a7c905079c354247b721ae1f198/pycryptodome-3.15.0-pp27-pypy_73-macosx_10_9_x86_64.whl", hash = "sha256:9eaadc058106344a566dc51d3d3a758ab07f8edde013712bc8d22032a86b264f"}, + {url = "https://files.pythonhosted.org/packages/c5/b4/526dd68f6c8ff6b785d7a08da7a6bba5646cced508454f1d1ab948e6b737/pycryptodome-3.15.0-cp35-abi3-manylinux2010_i686.whl", hash = "sha256:57f565acd2f0cf6fb3e1ba553d0cb1f33405ec1f9c5ded9b9a0a5320f2c0bd3d"}, + {url = "https://files.pythonhosted.org/packages/c7/d0/319a673a6514beb9a203fdb60f28b87135bbbdda0b3ea782c022414a9034/pycryptodome-3.15.0-pp36-pypy36_pp73-macosx_10_9_x86_64.whl", hash = "sha256:b9cc96e274b253e47ad33ae1fccc36ea386f5251a823ccb50593a935db47fdd2"}, + {url = "https://files.pythonhosted.org/packages/c8/03/1f745c158299000664a6fb5c0b28d5359837b05b4ba1f5a37645da5cad4d/pycryptodome-3.15.0-pp27-pypy_73-win32.whl", hash = "sha256:a8f06611e691c2ce45ca09bbf983e2ff2f8f4f87313609d80c125aff9fad6e7f"}, +] +"pyelftools 0.29" = [ + {url = "https://files.pythonhosted.org/packages/04/7c/867630e6e6293793f838b31034aa1875e1c3bd8c1ec34a0929a2506f350c/pyelftools-0.29-py2.py3-none-any.whl", hash = "sha256:519f38cf412f073b2d7393aa4682b0190fa901f7c3fa0bff2b82d537690c7fc1"}, + {url = "https://files.pythonhosted.org/packages/0e/35/e76da824595452a5ad07f289ea1737ca0971fc6cc7b6ee9464279be06b5e/pyelftools-0.29.tar.gz", hash = "sha256:ec761596aafa16e282a31de188737e5485552469ac63b60cfcccf22263fd24ff"}, +] +"pynacl 1.5.0" = [ + {url = "https://files.pythonhosted.org/packages/25/2d/b7df6ddb0c2a33afdb358f8af6ea3b8c4d1196ca45497dd37a56f0c122be/PyNaCl-1.5.0-cp36-abi3-win32.whl", hash = "sha256:e46dae94e34b085175f8abb3b0aaa7da40767865ac82c928eeb9e57e1ea8a543"}, + {url = "https://files.pythonhosted.org/packages/3d/85/c262db650e86812585e2bc59e497a8f59948a005325a11bbbc9ecd3fe26b/PyNaCl-1.5.0-cp36-abi3-musllinux_1_1_aarch64.whl", hash = "sha256:a422368fc821589c228f4c49438a368831cb5bbc0eab5ebe1d7fac9dded6567b"}, + {url = "https://files.pythonhosted.org/packages/59/bb/fddf10acd09637327a97ef89d2a9d621328850a72f1fdc8c08bdf72e385f/PyNaCl-1.5.0-cp36-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_24_aarch64.whl", hash = "sha256:52cb72a79269189d4e0dc537556f4740f7f0a9ec41c1322598799b0bdad4ef92"}, + {url = "https://files.pythonhosted.org/packages/5d/70/87a065c37cca41a75f2ce113a5a2c2aa7533be648b184ade58971b5f7ccc/PyNaCl-1.5.0-cp36-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a36d4a9dda1f19ce6e03c9a784a2921a4b726b02e1c736600ca9c22029474394"}, + {url = "https://files.pythonhosted.org/packages/5e/22/d3db169895faaf3e2eda892f005f433a62db2decbcfbc2f61e6517adfa87/PyNaCl-1.5.0-cp36-abi3-win_amd64.whl", hash = "sha256:20f42270d27e1b6a29f54032090b972d97f0a1b0948cc52392041ef7831fee93"}, + {url = "https://files.pythonhosted.org/packages/66/28/ca86676b69bf9f90e710571b67450508484388bfce09acf8a46f0b8c785f/PyNaCl-1.5.0-cp36-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:06b8f6fa7f5de8d5d2f7573fe8c863c051225a27b61e6860fd047b1775807858"}, + {url = "https://files.pythonhosted.org/packages/a7/22/27582568be639dfe22ddb3902225f91f2f17ceff88ce80e4db396c8986da/PyNaCl-1.5.0.tar.gz", hash = "sha256:8ac7448f09ab85811607bdd21ec2464495ac8b7c66d146bf545b0f08fb9220ba"}, + {url = "https://files.pythonhosted.org/packages/ce/75/0b8ede18506041c0bf23ac4d8e2971b4161cd6ce630b177d0a08eb0d8857/PyNaCl-1.5.0-cp36-abi3-macosx_10_10_universal2.whl", hash = "sha256:401002a4aaa07c9414132aaed7f6836ff98f59277a234704ff66878c2ee4a0d1"}, + {url = "https://files.pythonhosted.org/packages/ee/87/f1bb6a595f14a327e8285b9eb54d41fef76c585a0edef0a45f6fc95de125/PyNaCl-1.5.0-cp36-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_24_x86_64.whl", hash = "sha256:0c84947a22519e013607c9be43706dd42513f9e6ae5d39d3613ca1e142fba44d"}, + {url = "https://files.pythonhosted.org/packages/fd/1a/cc308a884bd299b651f1633acb978e8596c71c33ca85e9dc9fa33a5399b9/PyNaCl-1.5.0-cp36-abi3-musllinux_1_1_x86_64.whl", hash = "sha256:61f642bf2378713e2c2e1de73444a3778e5f0a38be6fee0fe532fe30060282ff"}, +] +"pyparsing 3.0.9" = [ + {url = "https://files.pythonhosted.org/packages/6c/10/a7d0fa5baea8fe7b50f448ab742f26f52b80bfca85ac2be9d35cdd9a3246/pyparsing-3.0.9-py3-none-any.whl", hash = "sha256:5026bae9a10eeaefb61dab2f09052b9f4307d44aee4eda64b309723d8d206bbc"}, + {url = "https://files.pythonhosted.org/packages/71/22/207523d16464c40a0310d2d4d8926daffa00ac1f5b1576170a32db749636/pyparsing-3.0.9.tar.gz", hash = "sha256:2b020ecf7d21b687f219b71ecad3631f644a47f01403fa1d1036b0c6416d70fb"}, +] +"pyqt5 5.15.7" = [ + {url = "https://files.pythonhosted.org/packages/14/75/596d5e9ed7a135918bb157ed315004ac008e09b9b4c9328f94568c88f003/PyQt5-5.15.7-cp37-abi3-macosx_10_13_x86_64.whl", hash = "sha256:1a793748c60d5aff3850b7abf84d47c1d41edb11231b7d7c16bef602c36be643"}, + {url = "https://files.pythonhosted.org/packages/22/0d/4ea05714826a5f6478dc2845cd94ad76dce3c4c0ead0842b06cacd4e3492/PyQt5-5.15.7-cp37-abi3-manylinux1_x86_64.whl", hash = "sha256:e319c9d8639e0729235c1b09c99afdadad96fa3dbd8392ab561b5ab5946ee6ef"}, + {url = "https://files.pythonhosted.org/packages/bd/85/31a12415765acb48fddac3e207cfffcbbae826fe194cf1d92179d8872f59/PyQt5-5.15.7-cp37-abi3-win_amd64.whl", hash = "sha256:232fe5b135a095cbd024cf341d928fc672c963f88e6a52b0c605be8177c2fdb5"}, + {url = "https://files.pythonhosted.org/packages/c6/ea/5fa344ed69086218b30542c3b2e381c1f52ec4b141f878e9601e3b81dc71/PyQt5-5.15.7-cp37-abi3-win32.whl", hash = "sha256:08694f0a4c7d4f3d36b2311b1920e6283240ad3b7c09b515e08262e195dcdf37"}, + {url = "https://files.pythonhosted.org/packages/e1/57/2023316578646e1adab903caab714708422f83a57f97eb34a5d13510f4e1/PyQt5-5.15.7.tar.gz", hash = "sha256:755121a52b3a08cb07275c10ebb96576d36e320e572591db16cfdbc558101594"}, +] +"pyqt5-qt5 5.15.2" = [ + {url = "https://files.pythonhosted.org/packages/1c/7e/ce7c66a541a105fa98b41d6405fe84940564695e29fc7dccf6d9e8c5f898/PyQt5_Qt5-5.15.2-py3-none-win32.whl", hash = "sha256:9cc7a768b1921f4b982ebc00a318ccb38578e44e45316c7a4a850e953e1dd327"}, + {url = "https://files.pythonhosted.org/packages/37/97/5d3b222b924fa2ed4c2488925155cd0b03fd5d09ee1cfcf7c553c11c9f66/PyQt5_Qt5-5.15.2-py3-none-win_amd64.whl", hash = "sha256:750b78e4dba6bdf1607febedc08738e318ea09e9b10aea9ff0d73073f11f6962"}, + {url = "https://files.pythonhosted.org/packages/62/09/99a222b0360616250fb2e6003a54e43a2a06b0774f0f8d5daafb86a2c375/PyQt5_Qt5-5.15.2-py3-none-macosx_10_13_intel.whl", hash = "sha256:76980cd3d7ae87e3c7a33bfebfaee84448fd650bad6840471d6cae199b56e154"}, + {url = "https://files.pythonhosted.org/packages/83/d4/241a6a518d0bcf0a9fcdcbad5edfed18d43e884317eab8d5230a2b27e206/PyQt5_Qt5-5.15.2-py3-none-manylinux2014_x86_64.whl", hash = "sha256:1988f364ec8caf87a6ee5d5a3a5210d57539988bf8e84714c7d60972692e2f4a"}, +] +"pyqt5-sip 12.11.0" = [ + {url = "https://files.pythonhosted.org/packages/0a/0a/5386772f8e4fe865d306e9e6d91f3605c09209a3e226919b898270127340/PyQt5_sip-12.11.0-cp37-cp37m-win_amd64.whl", hash = "sha256:b69a1911f768b489846335e31e49eb34795c6b5a038ca24d894d751e3b0b44da"}, + {url = "https://files.pythonhosted.org/packages/0d/1c/ccc6fd48150c07cbae52f6d2c9c40500e3252aa23cd98d5813973b7a150a/PyQt5_sip-12.11.0-cp39-cp39-manylinux1_x86_64.whl", hash = "sha256:205f3e1b3eea3597d8e878936c1a06e04bd23a59e8b179ee806465d72eea3071"}, + {url = "https://files.pythonhosted.org/packages/0e/bf/af987c45abd8604efcc99551550546f8cdef5e986b258eb09e0e88ede239/PyQt5_sip-12.11.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:9356260d4feb60dbac0ab66f8a791a0d2cda1bf98c9dec8e575904a045fbf7c5"}, + {url = "https://files.pythonhosted.org/packages/12/0f/54228b287741959a486d0a38a6626e0ba0ffc7c1c8d4fab0951c77c11e3a/PyQt5_sip-12.11.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:bd733667098cac70e89279d9c239106d543fb480def62a44e6366ccb8f68510b"}, + {url = "https://files.pythonhosted.org/packages/22/9b/deddfddae70651d058df6ca674790c4214d4021b59f22c3ae3a51ceb2551/PyQt5_sip-12.11.0-cp39-cp39-win32.whl", hash = "sha256:686071be054e5be6ca5aaaef7960931d4ba917277e839e2e978c7cbe3f43bb6e"}, + {url = "https://files.pythonhosted.org/packages/25/e3/e869173f015fbff0a6764f002f5217ac2b8da2ae137b2792547bc81c65c0/PyQt5_sip-12.11.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:f1f9e312ff8284d6dfebc5366f6f7d103f84eec23a4da0be0482403933e68660"}, + {url = "https://files.pythonhosted.org/packages/29/f9/aed0c4194c1efe8840f658719efad248d10ee797278fecb23dcf236c52f3/PyQt5_sip-12.11.0-cp38-cp38-win_amd64.whl", hash = "sha256:f6b72035da4e8fecbb0bc4a972e30a5674a9ad5608dbddaa517e983782dbf3bf"}, + {url = "https://files.pythonhosted.org/packages/2e/1a/cf06313fb7d19d075d0185fcab5fc64ade7b8429788092fd1e3fd3c4e5bd/PyQt5_sip-12.11.0-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:ec5e9ef78852e1f96f86d7e15c9215878422b83dde36d44f1539a3062942f19c"}, + {url = "https://files.pythonhosted.org/packages/39/5f/fd9384fdcb9cd0388088899c110838007f49f5da1dd1ef6749bfb728a5da/PyQt5_sip-12.11.0.tar.gz", hash = "sha256:b4710fd85b57edef716cc55fae45bfd5bfac6fc7ba91036f1dcc3f331ca0eb39"}, + {url = "https://files.pythonhosted.org/packages/41/b5/473fbe697cfe01b5389c968ba16bbcb6fa4080f594661ed44e8cc3ea5f7a/PyQt5_sip-12.11.0-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:4e5c1559311515291ea0ab0635529f14536954e3b973a7c7890ab7e4de1c2c23"}, + {url = "https://files.pythonhosted.org/packages/53/32/af0a7d44f0abfceae185134efa4ef65770eeac20f21239bdce4aee0460bd/PyQt5_sip-12.11.0-cp311-cp311-win32.whl", hash = "sha256:43dfe6dd409e713edeb67019b85419a7a0dc9923bfc451d6cf3778471c122532"}, + {url = "https://files.pythonhosted.org/packages/6e/8c/00fee4ad4602c3cbf4b73e1b42a0bba1018005633ec7ef831db33dbbd80a/PyQt5_sip-12.11.0-cp311-cp311-win_amd64.whl", hash = "sha256:afa4ffffc54e306669bf2b66ea37abbc56c5cdda4f3f474d20324e3634302b12"}, + {url = "https://files.pythonhosted.org/packages/71/47/a25ac7a064ab715a785bacd6d516e5787e56eaff19285fd0650d5d910a10/PyQt5_sip-12.11.0-cp37-cp37m-win32.whl", hash = "sha256:d12b81c3a08abf7657a2ebc7d3649852a1f327eb2146ebadf45930486d32e920"}, + {url = "https://files.pythonhosted.org/packages/84/43/f64bb816feb9bb9e02d472092199635c243ae86ba12e77528dac05eab8db/PyQt5_sip-12.11.0-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:ec1d8ce50be76c5c1d1c86c6dc0ccacc2446172dde98b663a17871f532f9bd44"}, + {url = "https://files.pythonhosted.org/packages/c3/b6/da9a15efacb7b4a73c976e3fe13f9b6ff9694299093bc32d288ff89ddcc4/PyQt5_sip-12.11.0-cp310-cp310-win32.whl", hash = "sha256:ad21ca0ee8cae2a41b61fc04949dccfab6fe008749627d94e8c7078cb7a73af1"}, + {url = "https://files.pythonhosted.org/packages/c7/8b/0f35a6e016c9f49da0cd8834ee2918e4d45dea449fba9ed1321d87826afd/PyQt5_sip-12.11.0-cp310-cp310-manylinux1_x86_64.whl", hash = "sha256:4031547dfb679be309094bfa79254f5badc5ddbe66b9ad38e319d84a7d612443"}, + {url = "https://files.pythonhosted.org/packages/c8/62/cd0c7bab5ee60f8a4416857aa703bb7e285bf09d3b2564e136e55a5c3a79/PyQt5_sip-12.11.0-cp38-cp38-win32.whl", hash = "sha256:9bca450c5306890cb002fe36bbca18f979dd9e5b810b766dce8e3ce5e66ba795"}, + {url = "https://files.pythonhosted.org/packages/d1/85/e30b11daf7b8d4e00ed51c17204ec3df446041206d22087d2c5dc17d8543/PyQt5_sip-12.11.0-cp39-cp39-win_amd64.whl", hash = "sha256:42320e7a94b1085ed85d49794ed4ccfe86f1cae80b44a894db908a8aba2bc60e"}, + {url = "https://files.pythonhosted.org/packages/d2/f9/7f62da7cc4a15d6a9c83a7d18b29ec9a6a04235fb9989973facbfbf51080/PyQt5_sip-12.11.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:0f77655c62ec91d47c2c99143f248624d44dd2d8a12d016e7c020508ad418aca"}, + {url = "https://files.pythonhosted.org/packages/ea/58/13becbb979991ea31ac08cdc7a1d3581b0ec9c4c85e76cb39c0ae645c720/PyQt5_sip-12.11.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:51e377789d59196213eddf458e6927f33ba9d217b614d17d20df16c9a8b2c41c"}, + {url = "https://files.pythonhosted.org/packages/fa/88/d8846f019aa9b2f0e7f0a49e1ee9ba84ac200175d8856178b2167c8e770d/PyQt5_sip-12.11.0-cp310-cp310-win_amd64.whl", hash = "sha256:3126c84568ab341c12e46ded2230f62a9a78752a70fdab13713f89a71cd44f73"}, +] +"pyrsistent 0.19.2" = [ + {url = "https://files.pythonhosted.org/packages/16/dd/17f6f147234f7c99b5a23fdcc318adac1c84ef5d179ce1bfe6afe19213a9/pyrsistent-0.19.2-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:879b4c2f4d41585c42df4d7654ddffff1239dc4065bc88b745f0341828b83e78"}, + {url = "https://files.pythonhosted.org/packages/23/d9/3ffebba2a20084b56f8132ab1fa959161dcf6da4f27c85a4a4c9cc438db1/pyrsistent-0.19.2-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:f1258f4e6c42ad0b20f9cfcc3ada5bd6b83374516cd01c0960e3cb75fdca6770"}, + {url = "https://files.pythonhosted.org/packages/3c/55/666888db7c7070e4d64944ea2a786073e5a53aaaa67efdfe99a6d6c605b0/pyrsistent-0.19.2-cp37-cp37m-win_amd64.whl", hash = "sha256:3ba4134a3ff0fc7ad225b6b457d1309f4698108fb6b35532d015dca8f5abed73"}, + {url = "https://files.pythonhosted.org/packages/42/c2/019693915e5d6fc88a145f4a4846fb4dc2a83cfa0a04256c76771eafb015/pyrsistent-0.19.2-cp310-cp310-win32.whl", hash = "sha256:456cb30ca8bff00596519f2c53e42c245c09e1a4543945703acd4312949bfd41"}, + {url = "https://files.pythonhosted.org/packages/44/91/42f8dab8dbe3bb1f07409566085feeb237c28e9cf6e8957aa2377cad78c1/pyrsistent-0.19.2-cp39-cp39-win_amd64.whl", hash = "sha256:dec3eac7549869365fe263831f576c8457f6c833937c68542d08fde73457d291"}, + {url = "https://files.pythonhosted.org/packages/54/d3/986fcfeaf62047840c571a857fb8f3ad1e9622081d5e7d0ee5e3451ca2e7/pyrsistent-0.19.2-py3-none-any.whl", hash = "sha256:ea6b79a02a28550c98b6ca9c35b9f492beaa54d7c5c9e9949555893c8a9234d0"}, + {url = "https://files.pythonhosted.org/packages/54/d8/96308460ee237abf28b7798c491f8545a51e1c3e2f01895da4530c7bff86/pyrsistent-0.19.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:187d5730b0507d9285a96fca9716310d572e5464cadd19f22b63a6976254d77a"}, + {url = "https://files.pythonhosted.org/packages/57/79/562894286bce4d1391abf4efbafa8a4a63ae482e1408ff08bf8a855c8358/pyrsistent-0.19.2-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e371b844cec09d8dc424d940e54bba8f67a03ebea20ff7b7b0d56f526c71d584"}, + {url = "https://files.pythonhosted.org/packages/5e/f7/31748ccbbe68eb990347f252c4a39fcb1766e22907314922262a1dc5e1f6/pyrsistent-0.19.2-cp310-cp310-win_amd64.whl", hash = "sha256:b39725209e06759217d1ac5fcdb510e98670af9e37223985f330b611f62e7425"}, + {url = "https://files.pythonhosted.org/packages/7d/f2/ad0363cb87673d3b076f6116c5d4385dc01fde8cce8292c7c7e133ba2fff/pyrsistent-0.19.2-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:111156137b2e71f3a9936baf27cb322e8024dac3dc54ec7fb9f0bcf3249e68bb"}, + {url = "https://files.pythonhosted.org/packages/8c/a8/bd70a21552061cc43e4ea9aa329990ca16af0ab747d3f8524d3778aba2f0/pyrsistent-0.19.2-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:bfd880614c6237243ff53a0539f1cb26987a6dc8ac6e66e0c5a40617296a045e"}, + {url = "https://files.pythonhosted.org/packages/8f/2b/737a53eeb4b2036c58d8ac2e033590f1e4a2ffe7b174850aca4787a899a4/pyrsistent-0.19.2-cp37-cp37m-win32.whl", hash = "sha256:d690b18ac4b3e3cab73b0b7aa7dbe65978a172ff94970ff98d82f2031f8971c2"}, + {url = "https://files.pythonhosted.org/packages/96/ad/a95f96af0f645ff74dc2145ab3d920c77a0d9d547dbaddb721c31bbeec53/pyrsistent-0.19.2-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:d6982b5a0237e1b7d876b60265564648a69b14017f3b5f908c5be2de3f9abb7a"}, + {url = "https://files.pythonhosted.org/packages/99/79/4ba4ef77bce2fb0c1140929e456a5101e5668af3aa46723e0a1daf2f437f/pyrsistent-0.19.2-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c43bec251bbd10e3cb58ced80609c5c1eb238da9ca78b964aea410fb820d00d6"}, + {url = "https://files.pythonhosted.org/packages/a1/96/15848046e77dfe560f11099face554dc2e4b50f8b28d152be0ed72cd5a08/pyrsistent-0.19.2-cp39-cp39-win32.whl", hash = "sha256:71d332b0320642b3261e9fee47ab9e65872c2bd90260e5d225dabeed93cbd42b"}, + {url = "https://files.pythonhosted.org/packages/a4/8d/7d7e504e14d1030e31e8ea656482e5fe5b556e11ce43ac899cf5ed1467f5/pyrsistent-0.19.2-cp38-cp38-win_amd64.whl", hash = "sha256:9cd3e9978d12b5d99cbdc727a3022da0430ad007dacf33d0bf554b96427f33ab"}, + {url = "https://files.pythonhosted.org/packages/a5/55/165b1e579eeba5711f796362e151a4eba5a7bab6c307af68231b5d49c83f/pyrsistent-0.19.2-cp38-cp38-win32.whl", hash = "sha256:e5d8f84d81e3729c3b506657dddfe46e8ba9c330bf1858ee33108f8bb2adb38a"}, + {url = "https://files.pythonhosted.org/packages/b8/ef/325da441a385a8a931b3eeb70db23cb52da42799691988d8d943c5237f10/pyrsistent-0.19.2.tar.gz", hash = "sha256:bfa0351be89c9fcbcb8c9879b826f4353be10f58f8a677efab0c017bf7137ec2"}, + {url = "https://files.pythonhosted.org/packages/cd/2d/cf7bcdfcf5aba1a68ced5b32620e7c165d0491bd962d6cd1e78b1c1b2d7a/pyrsistent-0.19.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:21455e2b16000440e896ab99e8304617151981ed40c29e9507ef1c2e4314ee95"}, + {url = "https://files.pythonhosted.org/packages/d9/85/f175c246505fecf2ba073384e98188216b5f1547a82f8a69c58d78c698d3/pyrsistent-0.19.2-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:a178209e2df710e3f142cbd05313ba0c5ebed0a55d78d9945ac7a4e09d923308"}, + {url = "https://files.pythonhosted.org/packages/d9/ca/47cbb30a777aa74e4c40221385fb0c5eee5adfdb5406d29b4d10170dd243/pyrsistent-0.19.2-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:055ab45d5911d7cae397dc418808d8802fb95262751872c841c170b0dbf51eed"}, + {url = "https://files.pythonhosted.org/packages/f6/3a/3cfb47a3cfd3993d0f57ba305ef71697d490b8e2efe8c3752bc5b0f321f4/pyrsistent-0.19.2-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:2aede922a488861de0ad00c7630a6e2d57e8023e4be72d9d7147a9fcd2d30712"}, + {url = "https://test-files.pythonhosted.org/packages/0a/59/b0a557f8868d0b0fd0838e4e8736bd3d855814ffc13edd1711c1bb53b00b/pyrsistent-0.19.2-cp310-cp310-win32.whl", hash = "sha256:366d5880bfea17db0701d30ed31d213f3bfb701041f1d3dca8f28c2f5b2e1b57"}, + {url = "https://test-files.pythonhosted.org/packages/11/33/79dd36095faf26cc5283b6845476bf403cf3f9bc4632c8e1d67b21bca507/pyrsistent-0.19.2-cp37-cp37m-win_amd64.whl", hash = "sha256:355eb7ba5207b0083d6eac5277d1eb15d7c8ecff501789f90fa2cfefede36aa8"}, + {url = "https://test-files.pythonhosted.org/packages/1e/d9/9fcb5f5c4a97c921e5564a971e34e3f64a78cbe01cc7851e309588371419/pyrsistent-0.19.2-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3bd37861e2ba095ff93a0ae5e03c6ae69493ec6139f9d5612bc4bcc16050e636"}, + {url = "https://test-files.pythonhosted.org/packages/23/a6/a6652b0d30e56c68a8ff083de3c9f3d4e1672de14d06356bf6bf9be72120/pyrsistent-0.19.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e673ad715330f2b77f43be88bd40682bb74f986dcd8ea517acc865b6968282dc"}, + {url = "https://test-files.pythonhosted.org/packages/3e/73/3659176beb7e8e3b344659e239150a64ab6263637ed39cbf78da947dcff7/pyrsistent-0.19.2-cp37-cp37m-win32.whl", hash = "sha256:38e82add4c51dee3af852d687b17d606c8c9620288fbe5c2619ba1becd63bc89"}, + {url = "https://test-files.pythonhosted.org/packages/40/71/ae801fa4edce35d6631678e683de898ebfaf218332068ecc6b880a03a4a9/pyrsistent-0.19.2-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:656a4ccad1c9bca66cde99fb1a3644cc7d404bb0dbcc46c7b069a9d2afa76764"}, + {url = "https://test-files.pythonhosted.org/packages/54/41/2d741180d5848977e4594301db4dc37a6c357baf91399036b7b7ed85e87d/pyrsistent-0.19.2.tar.gz", hash = "sha256:3798f2578f7df1f073ad77fa0c75f28ad8ae389a3d4d491268e63618530900cc"}, + {url = "https://test-files.pythonhosted.org/packages/57/42/c9a50e25af9dc14c8fb257786247728c1432e8ef2552dcb608b6b918a10a/pyrsistent-0.19.2-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:9ff5be704ea20f4e50f82c3f34c19bb7cf62cd722c7a270211edbb299ab06864"}, + {url = "https://test-files.pythonhosted.org/packages/57/e6/3fd3c54b417b9898ecbd33d4c487e167976204276efae873df2ed4d50b11/pyrsistent-0.19.2-cp38-cp38-win_amd64.whl", hash = "sha256:46123c3478c02a2369c20465a40e012e17a493629ab2dcba4f243adfffb4a5f5"}, + {url = "https://test-files.pythonhosted.org/packages/58/07/5ad851368c22c10c198003b9f6346206a543cab8c45cfc4bfef6f80f4c31/pyrsistent-0.19.2-py3-none-any.whl", hash = "sha256:ce0eec0b2bff4374f45f065f51ba12362328dc6a94204b604974092506513477"}, + {url = "https://test-files.pythonhosted.org/packages/64/c3/b68f450df9084480ef0220c719ddc0ff87477b5315c68020be23066b4445/pyrsistent-0.19.2-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:46b9e70c4816fff946fbb845fc960a3c905a967d258b97d120f3e08eeba312f9"}, + {url = "https://test-files.pythonhosted.org/packages/67/61/99dd9971507f3076486064fd8c9290c187a9278517f266aabccdef32775b/pyrsistent-0.19.2-cp310-cp310-win_amd64.whl", hash = "sha256:2cbb12fbbdad4bc06e4691b7e1b39149eb74e3b96cc64e9077e1c2563763756f"}, + {url = "https://test-files.pythonhosted.org/packages/6e/43/a4cdf6d7febc0b1610a25b02c1477a934efa3a254c1e52879b1b9edcf266/pyrsistent-0.19.2-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:5387688a245d7636e7c608376268fdd6713e686e1b38ce492dcbf015d18191ca"}, + {url = "https://test-files.pythonhosted.org/packages/80/67/6dfc93f8335be5fafac8611b4b5417aa44f1092e3e20ad7d9238266381be/pyrsistent-0.19.2-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:0add490da5d10f906cea2c3e131f8c86c842b021fb77037c451744afa67f00a4"}, + {url = "https://test-files.pythonhosted.org/packages/90/f2/6f3c8b0ef92520bc929ec0c867003ef2c107d1b9dd706e1e8843b867e5f1/pyrsistent-0.19.2-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:982753d01827a54e982dee341c68469d1e357224fde5c60c8a32882ebec371ff"}, + {url = "https://test-files.pythonhosted.org/packages/a2/0f/390999a7c47d46f14fbfea7a13d2d2460fa5caeec9f8da564638e5f1c533/pyrsistent-0.19.2-cp39-cp39-win32.whl", hash = "sha256:064da395ebb976c6489a785b3f2b6c7672e38294c450eb7618beb19d5396ca4c"}, + {url = "https://test-files.pythonhosted.org/packages/a6/51/40812842800ac3efb5a662b81322634f6b09e6cb3fbdd14f25df1d1a004a/pyrsistent-0.19.2-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:445de06b3445903459621ca8da19aa560d8093bc0450bbb91d9e50f9e24ea66f"}, + {url = "https://test-files.pythonhosted.org/packages/c5/7f/ebc7ff7c63331ce0f1973e6ead6ee866b40c83ec71caf0a98dcfb13fc697/pyrsistent-0.19.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9b25f04d43e829c61bd67b7e424ac340112dfab1c710e45a5fec7ea044917523"}, + {url = "https://test-files.pythonhosted.org/packages/da/af/b0e16e72699f06584a9187dfdb759a2372f2e5d7bc155db81562c033de87/pyrsistent-0.19.2-cp38-cp38-win32.whl", hash = "sha256:1a342d37e7bc9339ee23eba1fc5a3e0d18cdb8abc3302052fd18ecf21e4ebba3"}, + {url = "https://test-files.pythonhosted.org/packages/ed/f2/3fcb6bc123bb0dbdd46c54a2c2bc2c8654e5f212e84a19b97750601d85e2/pyrsistent-0.19.2-cp39-cp39-win_amd64.whl", hash = "sha256:b51d9226e1d83f6aa5475405fe0ff244b7920dd2346766c5cc278bb0d5991863"}, + {url = "https://test-files.pythonhosted.org/packages/ef/19/99ba519948e1c0a4625258770fc8ee025b4385a364f8856dc80075c50692/pyrsistent-0.19.2-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:475bcdd31a8751eddad1187da473f367254a9e5294a6c4746ea691511421086a"}, + {url = "https://test-files.pythonhosted.org/packages/f5/b4/6c3c619372ab53a614f6ed3374e7fe52492f4deaf7580f316bdbc5fa1eea/pyrsistent-0.19.2-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e212ba610996f7f9c5b7925d7c6f4bba984adc6a3e9759fc600dd371ab30338f"}, +] +"pytest 7.2.0" = [ + {url = "https://files.pythonhosted.org/packages/0b/21/055f39bf8861580b43f845f9e8270c7786fe629b2f8562ff09007132e2e7/pytest-7.2.0.tar.gz", hash = "sha256:c4014eb40e10f11f355ad4e3c2fb2c6c6d1919c73f3b5a433de4708202cade59"}, + {url = "https://files.pythonhosted.org/packages/67/68/a5eb36c3a8540594b6035e6cdae40c1ef1b6a2bfacbecc3d1a544583c078/pytest-7.2.0-py3-none-any.whl", hash = "sha256:892f933d339f068883b6fd5a459f03d85bfcb355e4981e146d2c7616c21fef71"}, +] +"pytest-cov 4.0.0" = [ + {url = "https://files.pythonhosted.org/packages/ea/70/da97fd5f6270c7d2ce07559a19e5bf36a76f0af21500256f005a69d9beba/pytest-cov-4.0.0.tar.gz", hash = "sha256:996b79efde6433cdbd0088872dbc5fb3ed7fe1578b68cdbba634f14bb8dd0470"}, + {url = "https://files.pythonhosted.org/packages/fe/1f/9ec0ddd33bd2b37d6ec50bb39155bca4fe7085fa78b3b434c05459a860e3/pytest_cov-4.0.0-py3-none-any.whl", hash = "sha256:2feb1b751d66a8bd934e5edfa2e961d11309dc37b73b0eabe73b5945fee20f6b"}, +] +"pytz 2022.6" = [ + {url = "https://files.pythonhosted.org/packages/76/63/1be349ff0a44e4795d9712cc0b2d806f5e063d4d34631b71b832fac715a8/pytz-2022.6.tar.gz", hash = "sha256:e89512406b793ca39f5971bc999cc538ce125c0e51c27941bef4568b460095e2"}, + {url = "https://files.pythonhosted.org/packages/85/ac/92f998fc52a70afd7f6b788142632afb27cd60c8c782d1452b7466603332/pytz-2022.6-py2.py3-none-any.whl", hash = "sha256:222439474e9c98fced559f1709d89e6c9cbf8d79c794ff3eb9f8800064291427"}, +] +"ragger 0.7.0" = [ + {url = "https://test-files.pythonhosted.org/packages/09/e3/e96cbe8924818c956a3a250fa7f147989dac83575e4a4ffc7e60519da20d/ragger-0.7.0-py3-none-any.whl", hash = "sha256:7cd2ca1b53edd4c62ca2bb38861f6fa7f8faf4d67c1ec6b97de00dc8b0f97900"}, + {url = "https://test-files.pythonhosted.org/packages/7a/90/539a89548e8fc77041c566ab59a971a3a7cebfe0f2e8b9289a34e09dd379/ragger-0.7.0.tar.gz", hash = "sha256:4a81a226a0f47017835b8c4074a4cae85f61dcad3c510364b12640c2897a94b0"}, +] +"requests 2.28.1" = [ + {url = "https://files.pythonhosted.org/packages/a5/61/a867851fd5ab77277495a8709ddda0861b28163c4613b011bc00228cc724/requests-2.28.1.tar.gz", hash = "sha256:7c5599b102feddaa661c826c56ab4fee28bfd17f5abca1ebbe3e7f19d7c97983"}, + {url = "https://files.pythonhosted.org/packages/ca/91/6d9b8ccacd0412c08820f72cebaa4f0c0441b5cda699c90f618b6f8a1b42/requests-2.28.1-py3-none-any.whl", hash = "sha256:8fefa2a1a1365bf5520aac41836fbee479da67864514bdb821f31ce07ce65349"}, +] +"semver 2.13.0" = [ + {url = "https://files.pythonhosted.org/packages/0b/70/b84f9944a03964a88031ef6ac219b6c91e8ba2f373362329d8770ef36f02/semver-2.13.0-py2.py3-none-any.whl", hash = "sha256:ced8b23dceb22134307c1b8abfa523da14198793d9787ac838e70e29e77458d4"}, + {url = "https://files.pythonhosted.org/packages/31/a9/b61190916030ee9af83de342e101f192bbb436c59be20a4cb0cdb7256ece/semver-2.13.0.tar.gz", hash = "sha256:fa0fe2722ee1c3f57eac478820c3a5ae2f624af8264cbdf9000c980ff7f75e3f"}, + {url = "https://test-files.pythonhosted.org/packages/0b/70/b84f9944a03964a88031ef6ac219b6c91e8ba2f373362329d8770ef36f02/semver-2.13.0-py2.py3-none-any.whl", hash = "sha256:ced8b23dceb22134307c1b8abfa523da14198793d9787ac838e70e29e77458d4"}, + {url = "https://test-files.pythonhosted.org/packages/31/a9/b61190916030ee9af83de342e101f192bbb436c59be20a4cb0cdb7256ece/semver-2.13.0.tar.gz", hash = "sha256:fa0fe2722ee1c3f57eac478820c3a5ae2f624af8264cbdf9000c980ff7f75e3f"}, +] +"setuptools 65.5.1" = [ + {url = "https://files.pythonhosted.org/packages/26/f4/ca5cb6df512f453ad50f78900bf7ec6a5491ee44bb49d0f6f76802dbdd43/setuptools-65.5.1.tar.gz", hash = "sha256:e197a19aa8ec9722928f2206f8de752def0e4c9fc6953527360d1c36d94ddb2f"}, + {url = "https://files.pythonhosted.org/packages/b6/40/353c051f77ee5618adaf1fd96f4f6bae9714ed0a22c7142c01c24eb77fe4/setuptools-65.5.1-py3-none-any.whl", hash = "sha256:d0b9a8433464d5800cbe05094acf5c6d52a91bfac9b52bcfc4d41382be5d5d31"}, +] +"six 1.16.0" = [ + {url = "https://files.pythonhosted.org/packages/71/39/171f1c67cd00715f190ba0b100d606d440a28c93c7714febeca8b79af85e/six-1.16.0.tar.gz", hash = "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926"}, + {url = "https://files.pythonhosted.org/packages/d9/5a/e7c31adbe875f2abbb91bd84cf2dc52d792b5a01506781dbcf25c91daf11/six-1.16.0-py2.py3-none-any.whl", hash = "sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254"}, +] +"speculos 0.1.157" = [ + {url = "https://test-files.pythonhosted.org/packages/2b/0e/64fbe15430b4d0b978c71496f1eaccb00e50d88eb5fd8dd14c776111a21e/speculos-0.1.157-py3-none-any.whl", hash = "sha256:5e6284649675229e7a836d2fa8466054f378e636bdbbe1ddc25160b353bc1ebb"}, + {url = "https://test-files.pythonhosted.org/packages/2d/63/5d6442d5e4249e71e792b23a76f83639051c26023881c589cc9acec4eda2/speculos-0.1.157.tar.gz", hash = "sha256:e432468cf8cc0c19a9b425d18384f56ef6b20e52a7478a6d0cc3122864b01a44"}, +] +"tomli 2.0.1" = [ + {url = "https://files.pythonhosted.org/packages/97/75/10a9ebee3fd790d20926a90a2547f0bf78f371b2f13aa822c759680ca7b9/tomli-2.0.1-py3-none-any.whl", hash = "sha256:939de3e7a6161af0c887ef91b7d41a53e7c5a1ca976325f429cb46ea9bc30ecc"}, + {url = "https://files.pythonhosted.org/packages/c0/3f/d7af728f075fb08564c5949a9c95e44352e23dee646869fa104a3b2060a3/tomli-2.0.1.tar.gz", hash = "sha256:de526c12914f0c550d15924c62d72abc48d6fe7364aa87328337a31007fe8a4f"}, +] +"types-protobuf 3.20.4.5" = [ + {url = "https://files.pythonhosted.org/packages/0a/e3/d80ef95536b29285096f2de61b83e4ef733eb2ef34cbcc4f9e8bd4b40ee1/types-protobuf-3.20.4.5.tar.gz", hash = "sha256:e9b45008d106e1d10cc77a29d2d344b85c0f01e2e643aaccf32f69e9e81b0cdd"}, + {url = "https://files.pythonhosted.org/packages/92/02/cebbb618bf72fb671e9e0a710da26c959579a8964d8df79e1c60b3d38187/types_protobuf-3.20.4.5-py3-none-any.whl", hash = "sha256:97af5ce70d890fdb94cb0c906f5a6624ca2fef58bc04e27990a25509e992a950"}, +] +"urllib3 1.26.12" = [ + {url = "https://files.pythonhosted.org/packages/6f/de/5be2e3eed8426f871b170663333a0f627fc2924cc386cd41be065e7ea870/urllib3-1.26.12-py2.py3-none-any.whl", hash = "sha256:b930dd878d5a8afb066a637fbb35144fe7901e3b209d1cd4f524bd0e9deee997"}, + {url = "https://files.pythonhosted.org/packages/b2/56/d87d6d3c4121c0bcec116919350ca05dc3afd2eeb7dc88d07e8083f8ea94/urllib3-1.26.12.tar.gz", hash = "sha256:3fa96cf423e6987997fc326ae8df396db2a8b7c667747d47ddd8ecba91f4a74e"}, +] +"werkzeug 2.2.2" = [ + {url = "https://files.pythonhosted.org/packages/c8/27/be6ddbcf60115305205de79c29004a0c6bc53cec814f733467b1bb89386d/Werkzeug-2.2.2-py3-none-any.whl", hash = "sha256:f979ab81f58d7318e064e99c4506445d60135ac5cd2e177a2de0089bfd4c9bd5"}, + {url = "https://files.pythonhosted.org/packages/f8/c1/1c8e539f040acd80f844c69a5ef8e2fccdf8b442dabb969e497b55d544e1/Werkzeug-2.2.2.tar.gz", hash = "sha256:7ea2d48322cc7c0f8b3a215ed73eabd7b5d75d0b50e31ab006286ccff9e00b8f"}, + {url = "https://test-files.pythonhosted.org/packages/c8/27/be6ddbcf60115305205de79c29004a0c6bc53cec814f733467b1bb89386d/Werkzeug-2.2.2-py3-none-any.whl", hash = "sha256:f979ab81f58d7318e064e99c4506445d60135ac5cd2e177a2de0089bfd4c9bd5"}, + {url = "https://test-files.pythonhosted.org/packages/f8/c1/1c8e539f040acd80f844c69a5ef8e2fccdf8b442dabb969e497b55d544e1/Werkzeug-2.2.2.tar.gz", hash = "sha256:7ea2d48322cc7c0f8b3a215ed73eabd7b5d75d0b50e31ab006286ccff9e00b8f"}, +] diff --git a/tests/proto b/tests/proto new file mode 120000 index 00000000..5c8d3525 --- /dev/null +++ b/tests/proto @@ -0,0 +1 @@ +../proto \ No newline at end of file diff --git a/tests/pyproject.toml b/tests/pyproject.toml new file mode 100644 index 00000000..faafe071 --- /dev/null +++ b/tests/pyproject.toml @@ -0,0 +1,26 @@ +[project] +name = "" +version = "" +description = "" +authors = [ + {name = "", email = "chris@launchbadge.com"}, +] +dependencies = [ + "base58", + "bip32", + "ragger[speculos,tests]", + "protobuf==3.20.3", + "black>=22.10.0", + "mypy-protobuf>=3.3.0", +] +requires-python = ">=3.10" +license = {text = "MIT"} + +[build-system] +requires = ["pdm-pep517>=1.0.0"] +build-backend = "pdm.pep517.api" + +[[tool.pdm.source]] +url = "https://test.pypi.org/simple/" +verify_ssl = true +name = "PyPI Tests" diff --git a/tests/requirements.txt b/tests/requirements.txt new file mode 100644 index 00000000..1151f759 --- /dev/null +++ b/tests/requirements.txt @@ -0,0 +1,4 @@ +base58 +bip32 +ragger[tests,speculos] +protobuf==3.20.3 diff --git a/tests/test_hedera.py b/tests/test_hedera.py new file mode 100644 index 00000000..bbf26221 --- /dev/null +++ b/tests/test_hedera.py @@ -0,0 +1,476 @@ +from ragger.backend.interface import RAPDU, RaisePolicy + +from .apps.hedera import HederaClient, ErrorType +from .apps.hedera_builder import crypto_create_account_conf +from .apps.hedera_builder import crypto_create_account_stake_account_conf +from .apps.hedera_builder import crypto_create_account_stake_node_conf +from .apps.hedera_builder import crypto_create_account_stake_toggle_rewards_conf +from .apps.hedera_builder import account_update_conf +from .apps.hedera_builder import crypto_transfer_token_conf +from .apps.hedera_builder import crypto_transfer_hbar_conf +from .apps.hedera_builder import crypto_transfer_verify +from .apps.hedera_builder import token_associate_conf +from .apps.hedera_builder import token_dissociate_conf +from .apps.hedera_builder import token_burn_conf +from .apps.hedera_builder import token_mint_conf + + +def test_hedera_get_public_key_ok(client, firmware): + hedera = HederaClient(client) + values = [ + (0, "78be747e6894ee5f965e3fb0e4c1628af2f9ae0d94dc01d9b9aab75484c3184b"), + (11095, "644ef690d394e8140fa278273913425bc83c59067a392a9e7f703ead4973caf8"), + (294967295, "02357008e57f96bb250f789c63eb3a241c1eae034d461468b76b8174a59bdc9b"), + ( + 2294967295, + "2cbd40ac0a3e25a315aed7e211fd0056127075dfa4ba1717a7a047a2030b5efb", + ), + ] + for (index, key) in values: + from_public_key = hedera.get_public_key_non_confirm(index).data + assert from_public_key.hex() == key + with hedera.get_public_key_confirm(index): + if firmware.device == "nanos": + hedera.validate() + else: + hedera.validate_screen(1) + + from_public_key = hedera.get_async_response().data + assert from_public_key.hex() == key + + +def test_hedera_get_public_key_refused(client, firmware): + hedera = HederaClient(client) + with hedera.get_public_key_confirm(0): + client.raise_policy = RaisePolicy.RAISE_NOTHING + if firmware.device == "nanos": + hedera.refuse() + else: + hedera.validate_screen(1 + 1) + + rapdu = hedera.get_async_response() + assert rapdu.status == ErrorType.EXCEPTION_USER_REJECTED + + +def test_hedera_crypto_create_account_ok(client, firmware): + hedera = HederaClient(client) + conf = crypto_create_account_conf(initialBalance=5) + with hedera.send_sign_transaction( + index=0, + operator_shard_num=1, + operator_realm_num=2, + operator_account_num=3, + transaction_fee=5, + memo="this_is_the_memo", + conf=conf, + ): + hedera.validate_screen(7) + + +def test_hedera_crypto_create_account_refused(client, firmware): + hedera = HederaClient(client) + conf = crypto_create_account_conf(initialBalance=5) + with hedera.send_sign_transaction( + index=0, + operator_shard_num=1, + operator_realm_num=2, + operator_account_num=3, + transaction_fee=5, + memo="this_is_the_memo", + conf=conf, + ): + client.raise_policy = RaisePolicy.RAISE_NOTHING + hedera.validate_screen(8) + + rapdu = hedera.get_async_response() + assert rapdu.status == ErrorType.EXCEPTION_USER_REJECTED + + +def test_hedera_crypto_create_account_stake_account(client, firmware): + hedera = HederaClient(client) + conf = crypto_create_account_stake_account_conf() + with hedera.send_sign_transaction( + index=0, + operator_shard_num=1, + operator_realm_num=2, + operator_account_num=3, + transaction_fee=5, + memo="this_is_the_memo", + conf=conf, + ): + hedera.validate_screen(7) + + +def test_hedera_crypto_create_account_stake_node(client, firmware): + hedera = HederaClient(client) + conf = crypto_create_account_stake_node_conf() + with hedera.send_sign_transaction( + index=0, + operator_shard_num=1, + operator_realm_num=2, + operator_account_num=3, + transaction_fee=5, + memo="this_is_the_memo", + conf=conf, + ): + hedera.validate_screen(7) + + +def test_hedera_crypto_create_account_stake_toggle_rewards(client, firmware): + hedera = HederaClient(client) + conf = crypto_create_account_stake_toggle_rewards_conf() + with hedera.send_sign_transaction( + index=0, + operator_shard_num=1, + operator_realm_num=2, + operator_account_num=3, + transaction_fee=5, + memo="this_is_the_memo", + conf=conf, + ): + hedera.validate_screen(7) + + +def test_hedera_account_update(client, firmware): + hedera = HederaClient(client) + conf = account_update_conf() + with hedera.send_sign_transaction( + index=0, + operator_shard_num=1, + operator_realm_num=2, + operator_account_num=3, + transaction_fee=5, + memo="this_is_the_memo", + conf=conf, + ): + hedera.validate_screen(7) + + +def test_hedera_transfer_token_ok(client, firmware): + hedera = HederaClient(client) + conf = crypto_transfer_token_conf( + token_shardNum=15, + token_realmNum=16, + token_tokenNum=17, + sender_shardNum=57, + sender_realmNum=58, + sender_accountNum=59, + recipient_shardNum=100, + recipient_realmNum=101, + recipient_accountNum=102, + amount=1234567890, + decimals=9, + ) + + with hedera.send_sign_transaction( + index=0, + operator_shard_num=1, + operator_realm_num=2, + operator_account_num=3, + transaction_fee=5, + memo="this_is_the_memo", + conf=conf, + ): + hedera.validate_screen(7) + + +def test_hedera_transfer_token_refused(client, firmware): + hedera = HederaClient(client) + conf = crypto_transfer_token_conf( + token_shardNum=15, + token_realmNum=16, + token_tokenNum=17, + sender_shardNum=57, + sender_realmNum=58, + sender_accountNum=59, + recipient_shardNum=100, + recipient_realmNum=101, + recipient_accountNum=102, + amount=1234567890, + decimals=9, + ) + + with hedera.send_sign_transaction( + index=0, + operator_shard_num=1, + operator_realm_num=2, + operator_account_num=3, + transaction_fee=5, + memo="this_is_the_memo", + conf=conf, + ): + client.raise_policy = RaisePolicy.RAISE_NOTHING + hedera.validate_screen(7 + 1) + + rapdu = hedera.get_async_response() + assert rapdu.status == ErrorType.EXCEPTION_USER_REJECTED + + +def test_hedera_transfer_hbar_ok(client, firmware): + hedera = HederaClient(client) + conf = crypto_transfer_hbar_conf( + sender_shardNum=57, + sender_realmNum=58, + sender_accountNum=59, + recipient_shardNum=100, + recipient_realmNum=101, + recipient_accountNum=102, + amount=1234567890, + ) + + with hedera.send_sign_transaction( + index=0, + operator_shard_num=1, + operator_realm_num=2, + operator_account_num=3, + transaction_fee=5, + memo="this_is_the_memo", + conf=conf, + ): + hedera.validate_screen(7) + + +def test_hedera_transfer_hbar_refused(client, firmware): + hedera = HederaClient(client) + conf = crypto_transfer_hbar_conf( + sender_shardNum=57, + sender_realmNum=58, + sender_accountNum=59, + recipient_shardNum=100, + recipient_realmNum=101, + recipient_accountNum=102, + amount=1234567890, + ) + + with hedera.send_sign_transaction( + index=0, + operator_shard_num=1, + operator_realm_num=2, + operator_account_num=3, + transaction_fee=5, + memo="this_is_the_memo", + conf=conf, + ): + client.raise_policy = RaisePolicy.RAISE_NOTHING + hedera.validate_screen(7 + 1) + + rapdu = hedera.get_async_response() + assert rapdu.status == ErrorType.EXCEPTION_USER_REJECTED + + +def test_hedera_token_associate_ok(client, firmware): + hedera = HederaClient(client) + conf = token_associate_conf( + token_shardNum=57, + token_realmNum=58, + token_tokenNum=59, + sender_shardNum=100, + sender_realmNum=101, + sender_accountNum=102, + ) + + with hedera.send_sign_transaction( + index=0, + operator_shard_num=1, + operator_realm_num=2, + operator_account_num=3, + transaction_fee=5, + memo="this_is_the_memo", + conf=conf, + ): + hedera.validate_screen(6) + + +def test_hedera_token_associate_refused(client, firmware): + hedera = HederaClient(client) + conf = token_associate_conf( + token_shardNum=57, + token_realmNum=58, + token_tokenNum=59, + sender_shardNum=100, + sender_realmNum=101, + sender_accountNum=102, + ) + + with hedera.send_sign_transaction( + index=0, + operator_shard_num=1, + operator_realm_num=2, + operator_account_num=3, + transaction_fee=5, + memo="this_is_the_memo", + conf=conf, + ): + client.raise_policy = RaisePolicy.RAISE_NOTHING + hedera.validate_screen(7) + + rapdu = hedera.get_async_response() + assert rapdu.status == ErrorType.EXCEPTION_USER_REJECTED + + +def test_hedera_token_dissociate_ok(client, firmware): + hedera = HederaClient(client) + conf = token_dissociate_conf( + token_shardNum=57, + token_realmNum=58, + token_tokenNum=59, + sender_shardNum=666, + sender_realmNum=666, + sender_accountNum=666, + ) + with hedera.send_sign_transaction( + index=0, + operator_shard_num=1, + operator_realm_num=2, + operator_account_num=3, + transaction_fee=5, + memo="this_is_the_memo", + conf=conf, + ): + hedera.validate_screen(6) + + +def test_hedera_token_dissoicate_refused(client, firmware): + hedera = HederaClient(client) + conf = token_dissociate_conf( + token_shardNum=57, + token_realmNum=58, + token_tokenNum=59, + sender_shardNum=666, + sender_realmNum=666, + sender_accountNum=666, + ) + with hedera.send_sign_transaction( + index=0, + operator_shard_num=1, + operator_realm_num=2, + operator_account_num=3, + transaction_fee=5, + memo="this_is_the_memo", + conf=conf, + ): + client.raise_policy = RaisePolicy.RAISE_NOTHING + hedera.validate_screen(7) + + rapdu = hedera.get_async_response() + assert rapdu.status == ErrorType.EXCEPTION_USER_REJECTED + + +def test_hedera_token_burn_ok(client, firmware): + hedera = HederaClient(client) + conf = token_burn_conf( + token_shardNum=57, token_realmNum=58, token_tokenNum=59, amount=7745309389 + ) + + with hedera.send_sign_transaction( + index=0, + operator_shard_num=1, + operator_realm_num=2, + operator_account_num=3, + transaction_fee=5, + memo="this_is_the_memo", + conf=conf, + ): + hedera.validate_screen(6) + + +def test_hedera_token_burn_refused(client, firmware): + hedera = HederaClient(client) + conf = token_burn_conf( + token_shardNum=57, token_realmNum=58, token_tokenNum=59, amount=7745309389 + ) + + with hedera.send_sign_transaction( + index=0, + operator_shard_num=1, + operator_realm_num=2, + operator_account_num=3, + transaction_fee=5, + memo="this_is_the_memo", + conf=conf, + ): + client.raise_policy = RaisePolicy.RAISE_NOTHING + hedera.validate_screen(7) + + rapdu = hedera.get_async_response() + assert rapdu.status == ErrorType.EXCEPTION_USER_REJECTED + + +def test_hedera_token_mint_ok(client, firmware): + hedera = HederaClient(client) + conf = token_mint_conf( + token_shardNum=57, token_realmNum=58, token_tokenNum=59, amount=7745309389 + ) + + with hedera.send_sign_transaction( + index=0, + operator_shard_num=1, + operator_realm_num=2, + operator_account_num=3, + transaction_fee=5, + memo="this_is_the_memo", + conf=conf, + ): + hedera.validate_screen(6) + + +def test_hedera_token_mint_refused(client, firmware): + hedera = HederaClient(client) + conf = token_mint_conf( + token_shardNum=57, token_realmNum=58, token_tokenNum=59, amount=7745309389 + ) + + with hedera.send_sign_transaction( + index=0, + operator_shard_num=1, + operator_realm_num=2, + operator_account_num=3, + transaction_fee=5, + memo="this_is_the_memo", + conf=conf, + ): + client.raise_policy = RaisePolicy.RAISE_NOTHING + hedera.validate_screen(7) + + rapdu = hedera.get_async_response() + assert rapdu.status == ErrorType.EXCEPTION_USER_REJECTED + + +def test_hedera_transfer_verify_ok(client, firmware): + hedera = HederaClient(client) + conf = crypto_transfer_verify( + sender_shardNum=57, sender_realmNum=58, sender_accountNum=59 + ) + + with hedera.send_sign_transaction( + index=0, + operator_shard_num=1, + operator_realm_num=2, + operator_account_num=3, + transaction_fee=1, + memo="this_is_the_memo", + conf=conf, + ): + hedera.validate_screen(2) + + +def test_hedera_transfer_verify_refused(client, firmware): + hedera = HederaClient(client) + conf = crypto_transfer_verify( + sender_shardNum=57, sender_realmNum=58, sender_accountNum=59 + ) + + with hedera.send_sign_transaction( + index=0, + operator_shard_num=1, + operator_realm_num=2, + operator_account_num=3, + transaction_fee=1, + memo="this_is_the_memo", + conf=conf, + ): + client.raise_policy = RaisePolicy.RAISE_NOTHING + hedera.validate_screen(3) + + rapdu = hedera.get_async_response() + assert rapdu.status == ErrorType.EXCEPTION_USER_REJECTED diff --git a/tests/utils.py b/tests/utils.py new file mode 100644 index 00000000..88cc0973 --- /dev/null +++ b/tests/utils.py @@ -0,0 +1,57 @@ +from typing import Optional, Tuple +from pathlib import Path +from bip32 import HARDENED_INDEX +from enum import IntEnum + +from ragger.backend import SpeculosBackend + + +def app_path_from_app_name(app_dir, app_name: str, device: str) -> Path: + assert app_dir.is_dir(), f"{app_dir} is not a directory" + app_path = app_dir / (app_name + "_" + device + ".elf") + assert app_path.is_file(), f"{app_path} must exist" + return app_path + +def prefix_with_len(to_prefix: bytes) -> bytes: + return len(to_prefix).to_bytes(1, byteorder="big") + to_prefix + +def validate_displayed_message(client: SpeculosBackend, num_screen_skip: int): + for _ in range(num_screen_skip): + client.right_click() + client.both_click() + +# DERIVATION PATHS CALCULATIONS + +class BtcDerivationPathFormat(IntEnum): + LEGACY = 0x00 + P2SH = 0x01 + BECH32 = 0x02 + CASHADDR = 0x03 # Deprecated + BECH32M = 0x04 + +def pack_derivation_path(derivation_path: str) -> bytes: + split = derivation_path.split("/") + assert split.pop(0) == "m", "master expected" + derivation_path: bytes = (len(split)).to_bytes(1, byteorder='big') + for i in split: + if (i[-1] == "'"): + derivation_path += (int(i[:-1]) | HARDENED_INDEX).to_bytes(4, byteorder='big') + else: + derivation_path += int(i).to_bytes(4, byteorder='big') + return derivation_path + +def bitcoin_pack_derivation_path(format: BtcDerivationPathFormat, derivation_path: str) -> bytes: + assert isinstance(format, BtcDerivationPathFormat) + return format.to_bytes(1, "big") + pack_derivation_path(derivation_path) + + +# CURRENCY CONFIG CALCULATIONS + +def create_currency_config(main_ticker: str, application_name: str, sub_coin_config: Optional[Tuple[str, int]] = None) -> bytes: + sub_config: bytes = b"" + if sub_coin_config is not None: + sub_config = prefix_with_len(sub_coin_config[0].encode()) + sub_coin_config[1].to_bytes(1, byteorder="big") + coin_config: bytes = b"" + for element in [main_ticker.encode(), application_name.encode(), sub_config]: + coin_config += prefix_with_len(element) + return coin_config