diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index 431389c..8ef9d18 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -13,15 +13,15 @@ jobs: - name: Checkout source code uses: actions/checkout@v4 - - name: Install hatch - run: pipx install hatch - - name: Set up Python 3.12 uses: actions/setup-python@v5 with: python-version: "3.12" cache: "pip" + - name: Install hatch + run: pip install hatch + - name: Start LocalNet run: pipx install algokit && algokit localnet start diff --git a/.gitignore b/.gitignore index bc8e7e5..a5ffbcd 100644 --- a/.gitignore +++ b/.gitignore @@ -14,3 +14,6 @@ examples/**/*.trace # coverage output .coverage coverage.xml +.venv* + +.cursorignore diff --git a/examples/auction/test_contract.py b/examples/auction/test_contract.py index 2aae01b..7971b9d 100644 --- a/examples/auction/test_contract.py +++ b/examples/auction/test_contract.py @@ -1,165 +1,159 @@ -# import time -# from collections.abc import Generator - -# import algopy -# import pytest -# from algopy_testing import AlgopyTestContext, algopy_testing_context - -# from .contract import AuctionContract - - -# @pytest.fixture() -# def context() -> Generator[AlgopyTestContext, None, None]: -# with algopy_testing_context() as ctx: -# yield ctx -# ctx.reset() - - -# def test_opt_into_asset(context: AlgopyTestContext) -> None: -# # Arrange -# asset = context.any.asset() -# contract = AuctionContract() - -# # Act -# contract.opt_into_asset(asset) - -# # Assert -# assert contract.asa.id == asset.id -# inner_txn = context.txn.last_group.last_itxn.asset_transfer -# assert ( -# inner_txn.asset_receiver == context.get_app_for_contract(contract).address -# ), "Asset receiver does not match" -# assert inner_txn.xfer_asset == asset, "Transferred asset does not match" - - -# def test_start_auction( -# context: AlgopyTestContext, -# ) -> None: -# # Arrange -# contract = AuctionContract() -# app = context.get_app_for_contract(contract) -# latest_timestamp = context.any.uint64(1, 1000) -# starting_price = context.any.uint64() -# auction_duration = context.any.uint64(100, 1000) -# axfer_txn = context.any.txn.asset_transfer( -# asset_receiver=app.address, -# asset_amount=starting_price, -# ) -# contract.asa_amount = starting_price -# context.ledger.patch_global_fields( -# latest_timestamp=latest_timestamp, -# ) - -# # Act -# with context.txn.create_group(txn_op_fields={"sender": context.default_sender}): -# contract.start_auction( -# starting_price, -# auction_duration, -# axfer_txn, -# ) - -# # Assert -# assert contract.auction_end == latest_timestamp + auction_duration -# assert contract.previous_bid == starting_price -# assert contract.asa_amount == starting_price - - -# def test_bid(context: AlgopyTestContext) -> None: -# # Arrange -# account = context.default_sender -# auction_end = context.any.uint64(min_value=int(time.time()) + 10_000) -# previous_bid = context.any.uint64(1, 100) -# pay_amount = context.any.uint64() - -# contract = AuctionContract() -# contract.auction_end = auction_end -# contract.previous_bid = previous_bid -# pay = context.any.txn.payment(sender=account, amount=pay_amount) - -# # Act -# contract.bid(pay=pay) - -# # Assert -# assert contract.previous_bid == pay_amount -# assert contract.previous_bidder == account -# assert contract.claimable_amount[account] == pay_amount - - -# def test_claim_bids( -# context: AlgopyTestContext, -# ) -> None: -# # Arrange -# account = context.any.account() -# contract = AuctionContract() -# claimable_amount = context.any.uint64() -# contract.claimable_amount[account] = claimable_amount -# contract.previous_bidder = account -# previous_bid = context.any.uint64(max_value=int(claimable_amount)) -# contract.previous_bid = previous_bid - -# # Act -# with context.txn.create_group(txn_op_fields={"sender": account}): -# contract.claim_bids() - -# # Assert -# expected_payment = claimable_amount - previous_bid -# last_inner_txn = context.txn.last_group.last_itxn.payment - -# assert last_inner_txn.amount == expected_payment -# assert last_inner_txn.receiver == account -# assert contract.claimable_amount[account] == claimable_amount - expected_payment - - -# def test_claim_asset(context: AlgopyTestContext) -> None: -# # Arrange -# context.ledger.patch_global_fields(latest_timestamp=context.any.uint64()) -# contract = AuctionContract() -# contract.auction_end = context.any.uint64(1, 100) -# contract.previous_bidder = context.default_sender -# asa_amount = context.any.uint64(1000, 2000) -# contract.asa_amount = asa_amount -# asset = context.any.asset() - -# # Act -# contract.claim_asset(asset) - -# # Assert -# last_inner_txn = context.txn.last_group.last_itxn.asset_transfer -# assert last_inner_txn.xfer_asset == asset -# assert last_inner_txn.asset_close_to == context.default_sender -# assert last_inner_txn.asset_receiver == context.default_sender -# assert last_inner_txn.asset_amount == asa_amount - - -# def test_delete_application( -# context: AlgopyTestContext, -# ) -> None: -# # Arrange -# account = context.any.account() - -# # Act -# # setting sender will determine creator -# with context.txn.create_group(txn_op_fields={"sender": account}): -# contract = AuctionContract() - -# with context.txn.create_group( -# gtxns=[ -# context.any.txn.application_call( -# on_completion=algopy.OnCompleteAction.DeleteApplication -# ) -# ] -# ): -# contract.delete_application() - -# # Assert -# inner_transactions = context.txn.last_group.last_itxn.payment -# assert inner_transactions -# assert inner_transactions.type == algopy.TransactionType.Payment -# assert inner_transactions.receiver == account -# assert inner_transactions.close_remainder_to == account - - -# @pytest.mark.usefixtures("context") -# def test_clear_state_program() -> None: -# contract = AuctionContract() -# assert contract.clear_state_program() +import time +from collections.abc import Generator + +import algopy +import pytest +from algopy_testing import AlgopyTestContext, algopy_testing_context + +from .contract import AuctionContract + + +@pytest.fixture() +def context() -> Generator[AlgopyTestContext, None, None]: + with algopy_testing_context() as ctx: + yield ctx + + +def test_opt_into_asset(context: AlgopyTestContext) -> None: + # Arrange + asset = context.any.asset() + contract = AuctionContract() + + # Act + contract.opt_into_asset(asset) + + # Assert + assert contract.asa.id == asset.id + inner_txn = context.txn.last_group.last_itxn.asset_transfer + assert ( + inner_txn.asset_receiver == context.get_app_for_contract(contract).address + ), "Asset receiver does not match" + assert inner_txn.xfer_asset == asset, "Transferred asset does not match" + + +def test_start_auction( + context: AlgopyTestContext, +) -> None: + # Arrange + contract = AuctionContract() + app = context.get_app_for_contract(contract) + latest_timestamp = context.any.uint64(1, 1000) + starting_price = context.any.uint64() + auction_duration = context.any.uint64(100, 1000) + axfer_txn = context.any.txn.asset_transfer( + asset_receiver=app.address, + asset_amount=starting_price, + ) + contract.asa_amount = starting_price + context.ledger.patch_global_fields( + latest_timestamp=latest_timestamp, + ) + + # Act + contract.start_auction( + starting_price, + auction_duration, + axfer_txn, + ) + + # Assert + assert contract.auction_end == latest_timestamp + auction_duration + assert contract.previous_bid == starting_price + assert contract.asa_amount == starting_price + + +def test_bid(context: AlgopyTestContext) -> None: + # Arrange + account = context.default_sender + auction_end = context.any.uint64(min_value=int(time.time()) + 10_000) + previous_bid = context.any.uint64(1, 100) + pay_amount = context.any.uint64() + + contract = AuctionContract() + contract.auction_end = auction_end + contract.previous_bid = previous_bid + pay = context.any.txn.payment(sender=account, amount=pay_amount) + + # Act + contract.bid(pay=pay) + + # Assert + assert contract.previous_bid == pay_amount + assert contract.previous_bidder == account + assert contract.claimable_amount[account] == pay_amount + + +def test_claim_bids( + context: AlgopyTestContext, +) -> None: + # Arrange + account = context.any.account() + contract = AuctionContract() + claimable_amount = context.any.uint64() + contract.claimable_amount[account] = claimable_amount + contract.previous_bidder = account + previous_bid = context.any.uint64(max_value=int(claimable_amount)) + contract.previous_bid = previous_bid + + # Act + with context.txn.create_group(active_txn_overrides={"sender": account}): + contract.claim_bids() + + # Assert + expected_payment = claimable_amount - previous_bid + last_inner_txn = context.txn.last_group.last_itxn.payment + + assert last_inner_txn.amount == expected_payment + assert last_inner_txn.receiver == account + assert contract.claimable_amount[account] == claimable_amount - expected_payment + + +def test_claim_asset(context: AlgopyTestContext) -> None: + # Arrange + context.ledger.patch_global_fields(latest_timestamp=context.any.uint64()) + contract = AuctionContract() + contract.auction_end = context.any.uint64(1, 100) + contract.previous_bidder = context.default_sender + asa_amount = context.any.uint64(1000, 2000) + contract.asa_amount = asa_amount + asset = context.any.asset() + + # Act + contract.claim_asset(asset) + + # Assert + last_inner_txn = context.txn.last_group.last_itxn.asset_transfer + assert last_inner_txn.xfer_asset == asset + assert last_inner_txn.asset_close_to == context.default_sender + assert last_inner_txn.asset_receiver == context.default_sender + assert last_inner_txn.asset_amount == asa_amount + + +def test_delete_application( + context: AlgopyTestContext, +) -> None: + # Arrange + account = context.any.account() + + # Act + # setting sender will determine creator + with context.txn.create_group(active_txn_overrides={"sender": account}): + contract = AuctionContract() + + with context.txn.create_group( + active_txn_overrides={"on_completion": algopy.OnCompleteAction.DeleteApplication} + ): + contract.delete_application() + + # Assert + inner_transactions = context.txn.last_group.last_itxn.payment + assert inner_transactions + assert inner_transactions.type == algopy.TransactionType.Payment + assert inner_transactions.receiver == account + assert inner_transactions.close_remainder_to == account + + +@pytest.mark.usefixtures("context") +def test_clear_state_program() -> None: + contract = AuctionContract() + assert contract.clear_state_program() diff --git a/examples/box/test_contract.py b/examples/box/test_contract.py deleted file mode 100644 index 9ef04b8..0000000 --- a/examples/box/test_contract.py +++ /dev/null @@ -1,26 +0,0 @@ -from collections.abc import Generator - -import pytest -from algopy import op -from algopy_testing import AlgopyTestContext, algopy_testing_context - -from .contract import BoxContract - - -@pytest.fixture() -def context() -> Generator[AlgopyTestContext, None, None]: - with algopy_testing_context() as ctx: - yield ctx - - -def test_enums(context: AlgopyTestContext) -> None: - # Arrange - contract = BoxContract() - - # Act - contract.store_enums() - oca, txn = contract.read_enums() - - # Assert - assert context.ledger.get_box(contract, b"oca") == op.itob(oca.native) - assert context.ledger.get_box(contract, b"txn") == op.itob(txn.native) diff --git a/examples/htlc_logicsig/test_signature.py b/examples/htlc_logicsig/test_signature.py index b5cd2cc..0317a6d 100644 --- a/examples/htlc_logicsig/test_signature.py +++ b/examples/htlc_logicsig/test_signature.py @@ -12,7 +12,6 @@ def context() -> Generator[AlgopyTestContext, None, None]: with algopy_testing_context() as ctx: yield ctx - ctx.reset() def test_seller_receives_payment(context: AlgopyTestContext) -> None: diff --git a/examples/marketplace/test_contract.py b/examples/marketplace/test_contract.py index 122bf51..43ebf1c 100644 --- a/examples/marketplace/test_contract.py +++ b/examples/marketplace/test_contract.py @@ -17,7 +17,6 @@ def context() -> Generator[AlgopyTestContext, None, None]: with algopy_testing_context() as ctx: yield ctx - ctx.reset() @pytest.fixture() @@ -250,7 +249,7 @@ def test_bid( ) # Act - with context.txn.create_group(txn_op_fields={"sender": bidder}): + with context.txn.create_group(active_txn_overrides={"sender": bidder}): contract.bid( owner=owner, asset=test_asset, diff --git a/examples/proof_of_attendance/test_contract.py b/examples/proof_of_attendance/test_contract.py index 535bc4c..c3a4e6f 100644 --- a/examples/proof_of_attendance/test_contract.py +++ b/examples/proof_of_attendance/test_contract.py @@ -12,7 +12,6 @@ def context() -> Generator[AlgopyTestContext, None, None]: with algopy_testing_context() as ctx: yield ctx - ctx.reset() @pytest.fixture() diff --git a/examples/scratch_storage/test_contract.py b/examples/scratch_storage/test_contract.py index f3475c2..68baaf7 100644 --- a/examples/scratch_storage/test_contract.py +++ b/examples/scratch_storage/test_contract.py @@ -10,7 +10,6 @@ def context() -> Generator[AlgopyTestContext, None, None]: with algopy_testing_context() as ctx: yield ctx - ctx.reset() def test_arc4_contract(context: AlgopyTestContext) -> None: @@ -34,7 +33,11 @@ def test_simple_contract(context: AlgopyTestContext) -> None: # Act with context.txn.create_group( - gtxns=[context.any.txn.application_call(scratch_space=[0, 5, b"Hello World"])] + gtxns=[ + context.any.txn.application_call( + app_id=context.get_app_for_contract(contract), scratch_space=[0, 5, b"Hello World"] + ) + ] ): result = contract.approval_program() diff --git a/examples/simple_voting/test_contract.py b/examples/simple_voting/test_contract.py index bbebe2f..8c98850 100644 --- a/examples/simple_voting/test_contract.py +++ b/examples/simple_voting/test_contract.py @@ -11,7 +11,6 @@ def context() -> Generator[AlgopyTestContext, None, None]: with algopy_testing_context() as ctx: yield ctx - ctx.reset() @pytest.mark.usefixtures("context") @@ -37,7 +36,7 @@ def test_vote(context: AlgopyTestContext) -> None: gtxns=[ context.any.txn.application_call( sender=voter, - app_id=context.any.application(), + app_id=context.get_app_for_contract(contract), app_args=[algopy.Bytes(b"vote"), voter.bytes], ), context.any.txn.payment( diff --git a/examples/zk_whitelist/test_contract.py b/examples/zk_whitelist/test_contract.py index 9c4255e..5319fff 100644 --- a/examples/zk_whitelist/test_contract.py +++ b/examples/zk_whitelist/test_contract.py @@ -13,7 +13,6 @@ def context() -> Generator[AlgopyTestContext, None, None]: with algopy_testing_context() as ctx: yield ctx - ctx.reset() @pytest.fixture() diff --git a/pyproject.toml b/pyproject.toml index cd4da7d..5038e67 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -72,6 +72,7 @@ validate_examples = "python scripts/validate_examples.py" check_stubs_cov = "python scripts/check_stubs_cov.py" pre_commit = [ "hatch run lint:fix", + "hatch run lint:check", "mypy_testing", "hatch run examples:pre_commit", ] @@ -96,16 +97,18 @@ dependencies = [ "black", "ruff==0.5.6", "ruff-lsp", - "docformatter", + "docformatter>=1.7", + "pydoclint>=0.5.6", ] [tool.hatch.envs.lint.scripts] check = [ "black --check .", "ruff check", + "pydoclint --config=pyproject.toml src", ] fix = [ - "docformatter -i -r src", + "- docformatter -i -r --black --style sphinx src", "black .", "ruff check --fix", ] @@ -315,3 +318,12 @@ upload_to_vcs_release = true [tool.semantic_release.remote.token] env = "GITHUB_TOKEN" + +[tool.pydoclint] +style = 'sphinx' +check-return-types = false +skip-checking-raises = true +arg-type-hints-in-docstring = false + +[tool.docformatter] +style = "sphinx" diff --git a/src/algopy_testing/_context_helpers/context_storage.py b/src/algopy_testing/_context_helpers/context_storage.py index 11b9937..992ba53 100644 --- a/src/algopy_testing/_context_helpers/context_storage.py +++ b/src/algopy_testing/_context_helpers/context_storage.py @@ -21,9 +21,9 @@ class _InternalContext: - """For accessing implementation specific functions, with a convenient - single entry point for other modules to import Also allows for a single - place to check and provide.""" + """For accessing implementation specific functions, with a convenient single entry + point for other modules to import Also allows for a single place to check and + provide.""" @property def value(self) -> AlgopyTestContext: @@ -47,11 +47,11 @@ def txn(self) -> TransactionContext: def any(self) -> AlgopyValueGenerator: return self.value.any - def get_txn_op_fields(self) -> dict[str, typing.Any]: + def get_active_txn_fields(self) -> dict[str, typing.Any]: active_group = self.txn._active_group if active_group is None: return {} - return (active_group._txn_op_fields or {}).copy() + return (active_group._active_txn_overrides or {}).copy() @property def active_group(self) -> TransactionGroup: diff --git a/src/algopy_testing/_context_helpers/ledger_context.py b/src/algopy_testing/_context_helpers/ledger_context.py index 17c534e..5d3013a 100644 --- a/src/algopy_testing/_context_helpers/ledger_context.py +++ b/src/algopy_testing/_context_helpers/ledger_context.py @@ -5,6 +5,7 @@ from algopy_testing.constants import MAX_BOX_SIZE from algopy_testing.models.account import Account +from algopy_testing.primitives.uint64 import UInt64 from algopy_testing.utils import as_bytes, assert_address_is_valid, get_default_global_fields if typing.TYPE_CHECKING: @@ -17,8 +18,9 @@ class LedgerContext: + """Context for managing the ledger state.""" + def __init__(self) -> None: - """Initialize the LedgerContext with default values.""" from algopy_testing.models.account import AccountContextData, get_empty_account self.account_data = defaultdict[str, AccountContextData](get_empty_account) @@ -27,8 +29,20 @@ def __init__(self) -> None: self.blocks: dict[int, dict[str, int]] = {} self.global_fields: GlobalFields = get_default_global_fields() - self.asset_id = iter(range(1001, 2**64)) - self.app_id = iter(range(1001, 2**64)) + self._asset_id = iter(range(1001, 2**64)) + self._app_id = iter(range(1001, 2**64)) + + def get_next_asset_id(self) -> int: + while True: + asset_id = next(self._asset_id) + if asset_id not in self.asset_data: + return asset_id + + def get_next_app_id(self) -> int: + while True: + app_id = next(self._app_id) + if app_id not in self.app_data: + return app_id def get_account(self, address: str) -> algopy.Account: """Get an account by address. @@ -56,16 +70,26 @@ def account_exists(self, address: str) -> bool: assert_address_is_valid(address) return address in self.account_data - def update_account(self, address: str, **account_fields: typing.Unpack[AccountFields]) -> None: + def update_account( + self, + address: str, + opted_asset_balances: dict[int, algopy.UInt64] | None = None, + **account_fields: typing.Unpack[AccountFields], + ) -> None: """Update account fields. Args: address (str): The account address. + opted_asset_balances (dict[int, algopy.UInt64] | None): The opted asset balances . **account_fields: The fields to update. """ assert_address_is_valid(address) self.account_data[address].fields.update(account_fields) + if opted_asset_balances is not None: + for asset_id, balance in opted_asset_balances.items(): + self.account_data[address].opted_asset_balances[UInt64(asset_id)] = balance + def get_asset(self, asset_id: algopy.UInt64 | int) -> algopy.Asset: """Get an asset by ID. @@ -334,7 +358,7 @@ def get_block_content(self, index: int, key: str) -> int: """ content = self.blocks.get(index, {}).get(key, None) if content is None: - raise ValueError( + raise KeyError( f"Block content for index {index} and key {key} not found in testing context!" ) return content diff --git a/src/algopy_testing/_context_helpers/txn_context.py b/src/algopy_testing/_context_helpers/txn_context.py index 085687b..c77ab26 100644 --- a/src/algopy_testing/_context_helpers/txn_context.py +++ b/src/algopy_testing/_context_helpers/txn_context.py @@ -21,7 +21,7 @@ import algopy from algopy_testing._itxn_loader import InnerTransactionResultType - from algopy_testing.models.txn_fields import TransactionBaseFields + from algopy_testing.models.txn_fields import ActiveTransactionFields from algopy_testing import gtxn from algopy_testing._itxn_loader import ITxnLoader @@ -77,6 +77,8 @@ def _maybe_implicit_txn_group( else: if not active_group.txns: active_group._set_txn_group(gtxns) + elif gtxns[-1].app_id != active_group.active_app_id: + raise ValueError("Executing contract has different app_id than active txn") ctx = contextlib.nullcontext() with ctx: yield @@ -87,16 +89,8 @@ def defer_app_call( *args: TParamSpec.args, **kwargs: TParamSpec.kwargs, ) -> DeferredAppCall[TReturn]: - """Prepare an application call transaction group for a contract method - without executing it. - - :param method: The decorated contract method (baremethod or - abimethod). - :param args: Positional arguments for the method. - :param kwargs: Keyword arguments for the method. - :return: A DeferredAppCall object containing the transaction - group and method info. - """ + r"""Prepare an application call transaction group for a contract method without + executing it.""" from algopy_testing.models import ARC4Contract arc4_metadata = get_arc4_metadata(method) @@ -119,7 +113,7 @@ def defer_app_call( app_id = contract.__app_id__ # Handle ABI methods if arc4_metadata.arc4_signature: - ordered_args = get_ordered_args(fn, args, kwargs) # type: ignore[arg-type] + ordered_args = get_ordered_args(fn, args, kwargs) txns = create_abimethod_txns( app_id=app_id, arc4_signature=arc4_metadata.arc4_signature, @@ -135,26 +129,23 @@ def defer_app_call( def create_group( self, gtxns: ( - typing.Sequence[algopy.gtxn.TransactionBase | DeferredAppCall[TReturn]] | None + typing.Sequence[algopy.gtxn.TransactionBase | DeferredAppCall[typing.Any]] | None ) = None, active_txn_index: int | None = None, - txn_op_fields: TransactionBaseFields | None = None, + active_txn_overrides: ActiveTransactionFields | None = None, ) -> Iterator[None]: - """Adds a new transaction group using a list of transactions and an - optional index to indicate the active transaction within the group. - - :param gtxns: List of transactions. - :type gtxns: list[algopy.gtxn.TransactionBase] - :param active_txn_index: Index of the active transaction. - :type active_txn_index: int - :param active_txn_index: Index of the active transaction. - Defaults to None. - :type active_txn_index: int - :param gtxn: list[algopy.gtxn.TransactionBase]: - :param active_txn_index: int | None: (Default value = None) - :param txn_op_fields: dict[str, typing.Any] | None: (Default - value = None) + """Adds a new transaction group using a list of transactions and an optional + index to indicate the active transaction within the group. + + :param gtxns: List of transactions + :param active_txn_index: Index of the active transaction + :param active_txn_overrides: Overrides for active txn + :return: None """ + if gtxns and active_txn_overrides: + raise ValueError("cannot specified gtxns and active_txn_overrides at the same time") + if active_txn_index is not None and not gtxns: + raise ValueError("must specify gtxns if providing active_txn_index") processed_gtxns = [] @@ -174,7 +165,7 @@ def create_group( self._active_group = TransactionGroup( txns=processed_gtxns, active_txn_index=active_txn_index, - txn_op_fields=typing.cast(dict[str, typing.Any], txn_op_fields), + active_txn_overrides=typing.cast(dict[str, typing.Any], active_txn_overrides), ) try: yield @@ -201,12 +192,12 @@ def __init__( self, txns: Sequence[algopy.gtxn.TransactionBase] = (), active_txn_index: int | None = None, - txn_op_fields: dict[str, typing.Any] | None = None, + active_txn_overrides: dict[str, typing.Any] | None = None, ): self._set_txn_group(txns, active_txn_index) self._itxn_groups: list[Sequence[InnerTransactionResultType]] = [] self._constructing_itxn_group: list[InnerTransaction] = [] - self._txn_op_fields = txn_op_fields or {} + self._active_txn_overrides = active_txn_overrides or {} def _set_txn_group( self, @@ -291,12 +282,10 @@ def get_scratch_slot( self, index: algopy.UInt64 | int, ) -> algopy.UInt64 | algopy.Bytes: - """Retrieves the scratch values for a specific slot in the active - transaction. + """Retrieves the scratch values for a specific slot in the active transaction. - :param index: algopy.UInt64 | int: Which scratch slot to query - :returns: Scratch slot value for the active transaction. - :rtype: algopy.UInt64 | algopy.Bytes + :param index: Which scratch slot to query + :return: Scratch slot value for the active transaction """ # this wraps an internal method on TransactionBase, so it can be exposed to # consumers of algopy_testing @@ -307,8 +296,8 @@ def get_scratch_space( ) -> Sequence[algopy.Bytes | algopy.UInt64]: """Retrieves scratch space for the active transaction. - :returns: List of scratch space values for the active - transaction. + :return: List of scratch space values for the active transaction + :rtype: Sequence[algopy.Bytes | algopy.UInt64] """ return self._active_txn.get_scratch_space() diff --git a/src/algopy_testing/_itxn_loader.py b/src/algopy_testing/_itxn_loader.py index fae68cb..c0726b8 100644 --- a/src/algopy_testing/_itxn_loader.py +++ b/src/algopy_testing/_itxn_loader.py @@ -24,12 +24,12 @@ class ITxnLoader: - """A helper class for handling access to individual inner transactions in - test context. + """A helper class for handling access to individual inner transactions in test + context. - This class provides methods to access and retrieve specific types of - inner transactions. It performs type checking and conversion for - various transaction types. + This class provides methods to access and retrieve specific types of inner + transactions. It performs type checking and conversion for various transaction + types. """ _TXN_TYPE_MAP: typing.ClassVar = { @@ -57,8 +57,7 @@ def _get_itxn(self, txn_type: type[_T]) -> _T: def payment(self) -> algopy.itxn.PaymentInnerTransaction: """Retrieve the last PaymentInnerTransaction. - :raises ValueError: If the transaction is not found or not of - the expected type. + :raises ValueError: If the transaction is not found or not of the expected type. """ return self._get_itxn(itxn.PaymentInnerTransaction) @@ -66,8 +65,7 @@ def payment(self) -> algopy.itxn.PaymentInnerTransaction: def asset_config(self) -> algopy.itxn.AssetConfigInnerTransaction: """Retrieve the last AssetConfigInnerTransaction. - :raises ValueError: If the transaction is not found or not of - the expected type. + :raises ValueError: If the transaction is not found or not of the expected type. """ return self._get_itxn(itxn.AssetConfigInnerTransaction) @@ -75,8 +73,7 @@ def asset_config(self) -> algopy.itxn.AssetConfigInnerTransaction: def asset_transfer(self) -> algopy.itxn.AssetTransferInnerTransaction: """Retrieve the last AssetTransferInnerTransaction. - :raises ValueError: If the transaction is not found or not of - the expected type. + :raises ValueError: If the transaction is not found or not of the expected type. """ return self._get_itxn(itxn.AssetTransferInnerTransaction) @@ -84,8 +81,7 @@ def asset_transfer(self) -> algopy.itxn.AssetTransferInnerTransaction: def asset_freeze(self) -> algopy.itxn.AssetFreezeInnerTransaction: """Retrieve the last AssetFreezeInnerTransaction. - :raises ValueError: If the transaction is not found or not of - the expected type. + :raises ValueError: If the transaction is not found or not of the expected type. """ return self._get_itxn(itxn.AssetFreezeInnerTransaction) @@ -93,8 +89,7 @@ def asset_freeze(self) -> algopy.itxn.AssetFreezeInnerTransaction: def application_call(self) -> algopy.itxn.ApplicationCallInnerTransaction: """Retrieve the last ApplicationCallInnerTransaction. - :raises ValueError: If the transaction is not found or not of - the expected type. + :raises ValueError: If the transaction is not found or not of the expected type. """ return self._get_itxn(itxn.ApplicationCallInnerTransaction) @@ -102,8 +97,7 @@ def application_call(self) -> algopy.itxn.ApplicationCallInnerTransaction: def key_registration(self) -> algopy.itxn.KeyRegistrationInnerTransaction: """Retrieve the last KeyRegistrationInnerTransaction. - :raises ValueError: If the transaction is not found or not of - the expected type. + :raises ValueError: If the transaction is not found or not of the expected type. """ return self._get_itxn(itxn.KeyRegistrationInnerTransaction) @@ -111,20 +105,18 @@ def key_registration(self) -> algopy.itxn.KeyRegistrationInnerTransaction: def transaction(self) -> algopy.itxn.InnerTransactionResult: """Retrieve the last InnerTransactionResult. - :raises ValueError: If the transaction is not found or not of - the expected type. + :raises ValueError: If the transaction is not found or not of the expected type. """ return self._get_itxn(itxn.InnerTransactionResult) class ITxnGroupLoader: - """A helper class for handling access to groups of inner transactions in - test context. + """A helper class for handling access to groups of inner transactions in test + context. - This class provides methods to access and retrieve inner - transactions from a group, either individually or as slices. It - supports type-specific retrieval of inner transactions and - implements indexing operations. + This class provides methods to access and retrieve inner transactions from a group, + either individually or as slices. It supports type-specific retrieval of inner + transactions and implements indexing operations. """ @typing.overload @@ -157,74 +149,57 @@ def _get_itxn(self, index: int) -> InnerTransactionResultType: def payment(self, index: int) -> algopy.itxn.PaymentInnerTransaction: """Return a PaymentInnerTransaction from the group at the given index. - :param index: int - :param index: int: - :returns: algopy.itxn.PaymentInnerTransaction: The - PaymentInnerTransaction at the given index. + :param index: The index of the transaction in the group. + :returns: The PaymentInnerTransaction at the given index. + :raises TypeError: If the transaction is not found or not of """ return ITxnLoader(self._get_itxn(index)).payment def asset_config(self, index: int) -> algopy.itxn.AssetConfigInnerTransaction: - """Return an AssetConfigInnerTransaction from the group at the given - index. + """Return an AssetConfigInnerTransaction from the group at the given index. - :param index: int - :param index: int: - :returns: algopy.itxn.AssetConfigInnerTransaction: The - AssetConfigInnerTransaction at the given index. + :param index: The index of the transaction in the group. + :returns: The AssetConfigInnerTransaction at the given index. + :raises TypeError: If the transaction is not found or not of the expected type. """ return ITxnLoader(self._get_itxn(index)).asset_config def asset_transfer(self, index: int) -> algopy.itxn.AssetTransferInnerTransaction: - """Return an AssetTransferInnerTransaction from the group at the given - index. + """Return an AssetTransferInnerTransaction from the group at the given index. - :param index: int - :param index: int: - :returns: algopy.itxn.AssetTransferInnerTransaction: The - AssetTransferInnerTransaction at the given index. + :param index: The index of the transaction in the group. + :returns: The AssetTransferInnerTransaction at the given index. """ return ITxnLoader(self._get_itxn(index)).asset_transfer def asset_freeze(self, index: int) -> algopy.itxn.AssetFreezeInnerTransaction: - """Return an AssetFreezeInnerTransaction from the group at the given - index. + """Return an AssetFreezeInnerTransaction from the group at the given index. - :param index: int - :param index: int: - :returns: algopy.itxn.AssetFreezeInnerTransaction: The - AssetFreezeInnerTransaction at the given index. + :param index: The index of the transaction in the group. + :returns: The AssetFreezeInnerTransaction at the given index. """ return ITxnLoader(self._get_itxn(index)).asset_freeze def application_call(self, index: int) -> algopy.itxn.ApplicationCallInnerTransaction: - """Return an ApplicationCallInnerTransaction from the group at the - given index. + """Return an ApplicationCallInnerTransaction from the group at the given index. - :param index: int - :param index: int: - :returns: algopy.itxn.ApplicationCallInnerTransaction: The - ApplicationCallInnerTransaction at the given index. + :param index: The index of the transaction in the group. + :returns: The ApplicationCallInnerTransaction at the given index. """ return ITxnLoader(self._get_itxn(index)).application_call def key_registration(self, index: int) -> algopy.itxn.KeyRegistrationInnerTransaction: - """Return a KeyRegistrationInnerTransaction from the group at the given - index. + """Return a KeyRegistrationInnerTransaction from the group at the given index. - :param index: int - :param index: int: - :returns: algopy.itxn.KeyRegistrationInnerTransaction: The - KeyRegistrationInnerTransaction at the given index. + :param index: The index of the transaction in the group. + :returns: The KeyRegistrationInnerTransaction at the given index. """ return ITxnLoader(self._get_itxn(index)).key_registration def transaction(self, index: int) -> algopy.itxn.InnerTransactionResult: """Return an InnerTransactionResult from the group at the given index. - :param index: int - :param index: int: - :returns: algopy.itxn.InnerTransactionResult: The - InnerTransactionResult at the given index. + :param index: The index of the transaction in the group. + :returns: The InnerTransactionResult at the given index. """ return ITxnLoader(self._get_itxn(index)).transaction diff --git a/src/algopy_testing/_value_generators/arc4.py b/src/algopy_testing/_value_generators/arc4.py index 984e33f..9ced824 100644 --- a/src/algopy_testing/_value_generators/arc4.py +++ b/src/algopy_testing/_value_generators/arc4.py @@ -21,7 +21,6 @@ def address(self) -> algopy.arc4.Address: """Generate a random Algorand address. :returns: A new, random Algorand address. - :rtype: algopy.arc4.Address """ return arc4.Address(algosdk.account.generate_account()[1]) @@ -30,15 +29,8 @@ def uint8(self, min_value: int = 0, max_value: int = MAX_UINT8) -> algopy.arc4.U """Generate a random UInt8 within the specified range. :param min_value: Minimum value (inclusive). Defaults to 0. - :type min_value: int - :param max_value: Maximum value (inclusive). Defaults to - MAX_UINT8. - :type max_value: int - :param min_value: int: (Default value = 0) - :param max_value: int: (Default value = MAX_UINT8) + :param max_value: Maximum value (inclusive). Defaults to MAX_UINT8. :returns: A random UInt8 value. - :rtype: algopy.arc4.UInt8 - :raises AssertionError: If values are out of UInt8 range. """ return arc4.UInt8(generate_random_int(min_value, max_value)) @@ -46,15 +38,8 @@ def uint16(self, min_value: int = 0, max_value: int = MAX_UINT16) -> algopy.arc4 """Generate a random UInt16 within the specified range. :param min_value: Minimum value (inclusive). Defaults to 0. - :type min_value: int - :param max_value: Maximum value (inclusive). Defaults to - MAX_UINT16. - :type max_value: int - :param min_value: int: (Default value = 0) - :param max_value: int: (Default value = MAX_UINT16) + :param max_value: Maximum value (inclusive). Defaults to MAX_UINT16. :returns: A random UInt16 value. - :rtype: algopy.arc4.UInt16 - :raises AssertionError: If values are out of UInt16 range. """ return arc4.UInt16(generate_random_int(min_value, max_value)) @@ -62,15 +47,8 @@ def uint32(self, min_value: int = 0, max_value: int = MAX_UINT32) -> algopy.arc4 """Generate a random UInt32 within the specified range. :param min_value: Minimum value (inclusive). Defaults to 0. - :type min_value: int - :param max_value: Maximum value (inclusive). Defaults to - MAX_UINT32. - :type max_value: int - :param min_value: int: (Default value = 0) - :param max_value: int: (Default value = MAX_UINT32) + :param max_value: Maximum value (inclusive). Defaults to MAX_UINT32. :returns: A random UInt32 value. - :rtype: algopy.arc4.UInt32 - :raises AssertionError: If values are out of UInt32 range. """ return arc4.UInt32(generate_random_int(min_value, max_value)) @@ -78,15 +56,8 @@ def uint64(self, min_value: int = 0, max_value: int = MAX_UINT64) -> algopy.arc4 """Generate a random UInt64 within the specified range. :param min_value: Minimum value (inclusive). Defaults to 0. - :type min_value: int - :param max_value: Maximum value (inclusive). Defaults to - MAX_UINT64. - :type max_value: int - :param min_value: int: (Default value = 0) - :param max_value: int: (Default value = MAX_UINT64) + :param max_value: Maximum value (inclusive). Defaults to MAX_UINT64. :returns: A random UInt64 value. - :rtype: algopy.arc4.UInt64 - :raises AssertionError: If values are out of UInt64 range. """ return arc4.UInt64(generate_random_int(min_value, max_value)) @@ -96,14 +67,8 @@ def biguint128( """Generate a random UInt128 within the specified range. :param min_value: Minimum value (inclusive). Defaults to 0. - :type min_value: int :param max_value: Maximum value (inclusive). Defaults to (2^128 - 1). - :type max_value: int - :param min_value: int: (Default value = 0) - :param max_value: int: (Default value = (1 << 128) - 1) :returns: A random UInt128 value. - :rtype: algopy.arc4.UInt128 - :raises AssertionError: If values are out of UInt128 range. """ return arc4.UInt128(generate_random_int(min_value, max_value)) @@ -113,14 +78,8 @@ def biguint256( """Generate a random UInt256 within the specified range. :param min_value: Minimum value (inclusive). Defaults to 0. - :type min_value: int :param max_value: Maximum value (inclusive). Defaults to (2^256 - 1). - :type max_value: int - :param min_value: int: (Default value = 0) - :param max_value: int: (Default value = (1 << 256) - 1) :returns: A random UInt256 value. - :rtype: algopy.arc4.UInt256 - :raises AssertionError: If values are out of UInt256 range. """ return arc4.UInt256(generate_random_int(min_value, max_value)) @@ -128,15 +87,8 @@ def biguint512(self, min_value: int = 0, max_value: int = MAX_UINT512) -> algopy """Generate a random UInt512 within the specified range. :param min_value: Minimum value (inclusive). Defaults to 0. - :type min_value: int - :param max_value: Maximum value (inclusive). Defaults to - MAX_UINT512. - :type max_value: int - :param min_value: int: (Default value = 0) - :param max_value: int: (Default value = MAX_UINT512) + :param max_value: Maximum value (inclusive). Defaults to MAX_UINT512. :returns: A random UInt512 value. - :rtype: algopy.arc4.UInt512 - :raises AssertionError: If values are out of UInt512 range. """ return arc4.UInt512(generate_random_int(min_value, max_value)) @@ -145,10 +97,7 @@ def dynamic_bytes(self, n: int) -> algopy.arc4.DynamicBytes: :param n: The number of bits for the dynamic bytes. Must be a multiple of 8, otherwise the last byte will be truncated. - :type n: int - :param n: int: :returns: A new, random dynamic bytes of size `n` bits. - :rtype: algopy.arc4.DynamicBytes """ # rounding up num_bytes = (n + 7) // 8 @@ -166,10 +115,7 @@ def string(self, n: int) -> algopy.arc4.String: """Generate a random string of size `n` bits. :param n: The number of bits for the string. - :type n: int - :param n: int: :returns: A new, random string of size `n` bits. - :rtype: algopy.arc4.String """ # Calculate the number of characters needed (rounding up) num_chars = (n + 7) // 8 diff --git a/src/algopy_testing/_value_generators/avm.py b/src/algopy_testing/_value_generators/avm.py index b38a567..3c6ca42 100644 --- a/src/algopy_testing/_value_generators/avm.py +++ b/src/algopy_testing/_value_generators/avm.py @@ -10,7 +10,7 @@ import algopy_testing from algopy_testing._context_helpers import lazy_context from algopy_testing.constants import ALWAYS_APPROVE_TEAL_PROGRAM, MAX_BYTES_SIZE, MAX_UINT64 -from algopy_testing.models.account import AccountContextData, AccountFields +from algopy_testing.models.account import AccountFields from algopy_testing.models.application import ApplicationContextData, ApplicationFields from algopy_testing.models.asset import AssetFields from algopy_testing.utils import generate_random_int @@ -20,20 +20,15 @@ class AVMValueGenerator: - """Factory for generating test data for AVM abstractions (uint64, bytes, - string, accounts, assets and applications).""" + """Factory for generating test data for AVM abstractions (uint64, bytes, string, + accounts, assets and applications).""" def uint64(self, min_value: int = 0, max_value: int = MAX_UINT64) -> algopy.UInt64: """Generate a random UInt64 value within a specified range. :param min_value: Minimum value. Defaults to 0. - :type min_value: int :param max_value: Maximum value. Defaults to MAX_UINT64. - :type max_value: int - :param min_value: int: (Default value = 0) - :param max_value: int: (Default value = MAX_UINT64) :returns: The randomly generated UInt64 value. - :rtype: algopy.UInt64 :raises ValueError: If `max_value` exceeds MAX_UINT64 or `min_value` exceeds `max_value`. """ if max_value > MAX_UINT64: @@ -48,12 +43,8 @@ def uint64(self, min_value: int = 0, max_value: int = MAX_UINT64) -> algopy.UInt def bytes(self, length: int | None = None) -> algopy.Bytes: """Generate a random byte sequence of a specified length. - :param length: Length of the byte sequence. Defaults to - MAX_BYTES_SIZE. - :type length: int - :param length: int: (Default value = MAX_BYTES_SIZE) + :param length: Length of the byte sequence. Defaults to MAX_BYTES_SIZE. :returns: The randomly generated byte sequence. - :rtype: algopy.Bytes """ length = length or MAX_BYTES_SIZE return algopy_testing.Bytes(secrets.token_bytes(length)) @@ -62,6 +53,7 @@ def string(self, length: int = MAX_BYTES_SIZE) -> algopy.String: """Generate a random string of a specified length. :param length: int: (Default value = MAX_BYTES_SIZE) + :returns: The randomly generated string. """ return algopy_testing.String( "".join(secrets.choice(string.ascii_uppercase + string.digits) for _ in range(length)) @@ -88,37 +80,29 @@ def account( new_account_address = address or algosdk.account.generate_account()[1] new_account = algopy.Account(new_account_address) - new_account_fields = AccountFields(**account_fields) - new_account_data = AccountContextData( - fields=new_account_fields, - opted_asset_balances=opted_asset_balances or {}, - opted_apps={app.id: app for app in opted_apps}, - ) - - lazy_context.ledger.account_data[new_account_address] = new_account_data + # defaultdict of account_data ensures we get a new initialized account + account_data = lazy_context.ledger.account_data[new_account_address] + # update so defaults are preserved + account_data.fields.update(account_fields) + # can set these since it is a new account + account_data.opted_asset_balances = opted_asset_balances or {} + account_data.opted_apps = {app.id: app for app in opted_apps} return new_account def asset( self, asset_id: int | None = None, **asset_fields: typing.Unpack[AssetFields] ) -> algopy.Asset: - """Generate and add a new asset with a unique ID. - - :param asset_id: Optional asset ID. If not provided, a new ID - will be generated. - :type asset_id: int | None :param **asset_fields: Additional - asset fields. - :param asset_id: int | None: (Default value = None) :param - **asset_fields: Unpack[AssetFields]: - :returns: The newly generated asset. - :rtype: algopy.Asset - """ + r"""Generate and add a new asset with a unique ID.""" import algopy if asset_id and asset_id in lazy_context.ledger.asset_data: raise ValueError("Asset with such ID already exists in testing context!") - # TODO: 1.0 ensure passed fields are valid names and types - new_asset = algopy.Asset(asset_id or next(lazy_context.ledger.asset_id)) + for key in asset_fields: + if key not in AssetFields.__annotations__: + raise AttributeError(f"Invalid field '{key}' for Asset") + + new_asset = algopy.Asset(asset_id or lazy_context.ledger.get_next_asset_id()) default_asset_fields = { "total": lazy_context.any.uint64(), "decimals": lazy_context.any.uint64(1, 6), @@ -144,31 +128,20 @@ def application( # type: ignore[misc] logs: list[bytes] | None = None, # type: ignore[valid-type] **application_fields: typing.Unpack[ApplicationFields], ) -> algopy.Application: - """Generate and add a new application with a unique ID. - - :param id: Optional application ID. If not provided, a new ID - will be generated. - :type id: int | None - :param address: Optional application address. If not provided, - it will be generated. - :type address: algopy.Account | None - :param logs: Optional sequence of log messages for the - application. - :type logs: typing.Sequence[bytes] | None :param - **application_fields: Additional application fields. :type - **application_fields: typing.Unpack[ApplicationFields] - :return: The newly generated application. - :rtype: algopy.Application - """ + r"""Generate and add a new application with a unique ID.""" import algopy_testing - new_app_id = id if id is not None else next(lazy_context.ledger.app_id) + new_app_id = id if id is not None else lazy_context.ledger.get_next_app_id() if new_app_id in lazy_context.ledger.app_data: raise ValueError( f"Application id {new_app_id} has already been configured in test context!" ) + for key in application_fields: + if key not in ApplicationFields.__annotations__: + raise AttributeError(f"Invalid field '{key}' for Application") + new_app = algopy_testing.Application(new_app_id) # Set sensible defaults diff --git a/src/algopy_testing/_value_generators/txn.py b/src/algopy_testing/_value_generators/txn.py index 4f7dadb..f56fe1b 100644 --- a/src/algopy_testing/_value_generators/txn.py +++ b/src/algopy_testing/_value_generators/txn.py @@ -34,13 +34,10 @@ def application_call( ) -> algopy.gtxn.ApplicationCallTransaction: """Generate a new application call transaction. - :param scratch_space: Scratch space data. :param **fields: - Fields to be set in the transaction. :type **fields: - Unpack[ApplicationCallFields] - :param scratch_space: Sequence[algopy.Bytes | algopy.UInt64 | - int | bytes] | None: (Default value = None) :param **fields: - Unpack[ApplicationCallFields]: - :returns: New application call transaction. + :param scratch_space: Scratch space data. + :param **fields: Fields to be set in the transaction. + :return: New application call transaction. + :raises TypeError: If `app_id` is not an instance of algopy.Application """ try: app = fields["app_id"] @@ -62,22 +59,16 @@ def asset_transfer( ) -> algopy.gtxn.AssetTransferTransaction: """Generate a new asset transfer transaction with specified fields. - :param **fields: Fields to be set in the transaction. :type - **fields: Unpack[AssetTransferFields] :param **fields: - Unpack[AssetTransferFields]: - :returns: The newly generated asset transfer transaction. - :rtype: algopy.gtxn.AssetTransferTransaction + :param **fields: Fields to be set in the transaction. + :return: The newly generated asset transfer transaction. """ return self._new_gtxn(gtxn.AssetTransferTransaction, **fields) def payment(self, **fields: typing.Unpack[PaymentFields]) -> algopy.gtxn.PaymentTransaction: """Generate a new payment transaction with specified fields. - :param **fields: Fields to be set in the transaction. :type - **fields: Unpack[PaymentFields] :param **fields: - Unpack[PaymentFields]: - :returns: The newly generated payment transaction. - :rtype: algopy.gtxn.PaymentTransaction + :param **fields: Fields to be set in the transaction. + :return: The newly generated payment transaction. """ return self._new_gtxn(gtxn.PaymentTransaction, **fields) @@ -86,7 +77,8 @@ def asset_config( ) -> algopy.gtxn.AssetConfigTransaction: """Generate a new ACFG transaction with specified fields. - :param **fields: Unpack[AssetConfigFields]: + :param **fields: Fields to be set in the transaction. + :return: The newly generated asset config transaction. """ return self._new_gtxn(gtxn.AssetConfigTransaction, **fields) @@ -95,7 +87,8 @@ def key_registration( ) -> algopy.gtxn.KeyRegistrationTransaction: """Generate a new key registration transaction with specified fields. - :param **fields: Unpack[KeyRegistrationFields]: + :param **fields: Fields to be set in the transaction. + :return: The newly generated key registration transaction. """ return self._new_gtxn(gtxn.KeyRegistrationTransaction, **fields) @@ -104,7 +97,8 @@ def asset_freeze( ) -> algopy.gtxn.AssetFreezeTransaction: """Generate a new asset freeze transaction with specified fields. - :param **fields: Unpack[AssetFreezeFields]: + :param **fields: Fields to be set in the transaction. + :return: The newly generated asset freeze transaction. """ return self._new_gtxn(gtxn.AssetFreezeTransaction, **fields) @@ -114,11 +108,8 @@ def transaction( ) -> algopy.gtxn.Transaction: """Generate a new transaction with specified fields. - :param **fields: Fields to be set in the transaction. :type - **fields: Unpack[TransactionFields] :param **fields: - Unpack[TransactionFields]: - :returns: The newly generated transaction. - :rtype: algopy.gtxn.Transaction + :param **fields: Fields to be set in the transaction. + :return: The newly generated transaction. """ return self._new_gtxn(gtxn.Transaction, **fields) diff --git a/src/algopy_testing/arc4.py b/src/algopy_testing/arc4.py index cfaa316..06571fe 100644 --- a/src/algopy_testing/arc4.py +++ b/src/algopy_testing/arc4.py @@ -139,8 +139,8 @@ def from_bytes(cls, value: algopy.Bytes | bytes, /) -> typing.Self: @classmethod def from_log(cls, log: algopy.Bytes, /) -> typing.Self: - """Load an ABI type from application logs, checking for the ABI return - prefix `0x151f7c75`""" + """Load an ABI type from application logs, checking for the ABI return prefix + `0x151f7c75`""" if log[:4] == ARC4_RETURN_PREFIX: return cls.from_bytes(log[4:]) raise ValueError("ABI return prefix not found") @@ -200,8 +200,7 @@ def __init__(self, value: algopy.String | str = "", /) -> None: @property def native(self) -> algopy.String: - """Return the String representation of the UTF8 string after ARC4 - decoding.""" + """Return the String representation of the UTF8 string after ARC4 decoding.""" import algopy return algopy.String.from_bytes(self._value[_ABI_LENGTH_SIZE:]) @@ -323,8 +322,7 @@ class UIntN(_UIntN, typing.Generic[_TBitSize]): # type: ignore[type-arg] @property def native(self) -> algopy.UInt64: - """Return the UInt64 representation of the value after ARC4 - decoding.""" + """Return the UInt64 representation of the value after ARC4 decoding.""" import algopy return algopy.UInt64(int.from_bytes(self._value)) @@ -359,8 +357,7 @@ class BigUIntN(_UIntN, typing.Generic[_TBitSize]): # type: ignore[type-arg] @property def native(self) -> algopy.BigUInt: - """Return the UInt64 representation of the value after ARC4 - decoding.""" + """Return the UInt64 representation of the value after ARC4 decoding.""" import algopy return algopy.BigUInt.from_bytes(self._value) @@ -439,9 +436,6 @@ class _UFixedNxM( _value: bytes # underlying 'bytes' value representing the UFixedNxM def __init__(self, value: str = "0.0", /) -> None: - """Construct an instance of UFixedNxM where value (v) is determined - from the original decimal value (d) by the formula v = round(d * - (10^M))""" value = as_string(value) with decimal.localcontext( decimal.Context( @@ -692,19 +686,9 @@ def arc4_name(self) -> str: class Address(StaticArray[Byte, typing.Literal[32]]): - """An alias for an array containing 32 bytes representing an Algorand - address.""" - type_info = _AddressTypeInfo() def __init__(self, value: Account | str | algopy.Bytes = algosdk.constants.ZERO_ADDRESS): - """If `value` is a string, it should be a 58 character base32 string, - - ie a base32 string-encoded 32 bytes public key + 4 bytes checksum. - If `value` is a Bytes, it's length checked to be 32 bytes - to avoid this - check, use `Address.from_bytes(...)` instead. - Defaults to the zero-address. - """ if isinstance(value, str): try: bytes_value = algosdk.encoding.decode_address(value) @@ -729,8 +713,8 @@ def __bool__(self) -> bool: return self.bytes != zero_bytes def __eq__(self, other: Address | Account | str) -> bool: # type: ignore[override] - """Address equality is determined by the address of another - `arc4.Address`, `Account` or `str`""" + """Address equality is determined by the address of another `arc4.Address`, + `Account` or `str`""" if isinstance(other, Address | Account): return self.bytes == other.bytes other_bytes: bytes = algosdk.encoding.decode_address(other) @@ -982,7 +966,6 @@ def __new__( return instance def __init__(self, _items: tuple[typing.Unpack[_TTuple]] = (), /): # type: ignore[assignment] - """Construct an ARC4 tuple from a python tuple.""" items = _check_is_arc4(_items) if items: for item, expected_type in zip(items, self.type_info.child_types, strict=True): @@ -1039,8 +1022,8 @@ def from_bytes(cls, value: algopy.Bytes | bytes, /) -> typing.Self: @classmethod def from_log(cls, log: algopy.Bytes, /) -> typing.Self: - """Load an ABI type from application logs, checking for the ABI return - prefix `0x151f7c75`""" + """Load an ABI type from application logs, checking for the ABI return prefix + `0x151f7c75`""" if log[:4] == ARC4_RETURN_PREFIX: return cls.from_bytes(log[4:]) raise ValueError("ABI return prefix not found") @@ -1091,35 +1074,6 @@ def __getitem__(self, return_type: type) -> typing.Any: def emit(event: str | Struct, /, *args: object) -> None: - """Emit an ARC-28 event for the provided event signature or name, and - provided args. - - :param event: Either an ARC4 Struct, an event name, or event signature. - * If event is an ARC4 Struct, the event signature will be determined from the Struct name and fields - * If event is a signature, then the following args will be typed checked to ensure they match. - * If event is just a name, the event signature will be inferred from the name and following arguments - - :param args: When event is a signature or name, args will be used as the event data. - They will all be encoded as single ARC4 Tuple - - Example: - ``` - from algopy import ARC4Contract, arc4 - - - class Swapped(arc4.Struct): - a: arc4.UInt64 - b: arc4.UInt64 - - - class EventEmitter(ARC4Contract): - @arc4.abimethod - def emit_swapped(self, a: arc4.UInt64, b: arc4.UInt64) -> None: - arc4.emit(Swapped(b, a)) - arc4.emit("Swapped(uint64,uint64)", b, a) - arc4.emit("Swapped", b, a) - ``` - """ # noqa: E501 from algopy_testing.utilities.log import log if isinstance(event, str): @@ -1184,8 +1138,7 @@ def _find_bool( index: int, delta: int, ) -> int: - """Helper function to find consecutive booleans from current index in a - tuple.""" + """Helper function to find consecutive booleans from current index in a tuple.""" until = 0 values_length = len(values) if isinstance(values, tuple | list) else values.length.value while True: @@ -1202,8 +1155,7 @@ def _find_bool( def _find_bool_types(values: typing.Sequence[_TypeInfo], index: int, delta: int) -> int: - """Helper function to find consecutive booleans from current index in a - tuple.""" + """Helper function to find consecutive booleans from current index in a tuple.""" until = 0 values_length = len(values) while True: diff --git a/src/algopy_testing/context.py b/src/algopy_testing/context.py index f78840e..1e29edb 100644 --- a/src/algopy_testing/context.py +++ b/src/algopy_testing/context.py @@ -14,14 +14,15 @@ class AlgopyTestContext: - """Manages the testing context for Algorand Python SDK (algopy) - applications. - - This class provides methods and properties to simulate various - aspects of the Algorand blockchain environment, including accounts, - assets, applications, transactions, and global state. It allows for - easy setup and manipulation of test scenarios for algopy-based smart - contracts and applications. + """Manages the testing context for Algorand Python SDK (algopy) applications. + + This class provides methods and properties to simulate various aspects of the + Algorand blockchain environment, including accounts, assets, applications, + transactions, and global state. It allows for easy setup and manipulation of test + scenarios for algopy-based smart contracts and applications. + + :param default_sender: The default sender account address, defaults to None + :param template_vars: Dictionary of template variables, defaults to None """ def __init__( @@ -30,15 +31,6 @@ def __init__( default_sender: str | None = None, template_vars: dict[str, typing.Any] | None = None, ) -> None: - """Initialize the AlgopyTestContext. - - :param default_sender: The default sender account address, - defaults to None - :type default_sender: str | None, optional - :param template_vars: Dictionary of template variables, defaults - to None - :type template_vars: dict[str, typing.Any] | None, optional - """ import algopy self._default_sender = algopy.Account( @@ -93,7 +85,6 @@ def get_app_for_contract( """Get the application for a given contract. :param contract: The contract to get the application for - :type contract: algopy.Contract | algopy.ARC4Contract :return: The application associated with the contract :rtype: algopy.Application """ @@ -103,22 +94,13 @@ def set_template_var(self, name: str, value: typing.Any) -> None: """Set a template variable for the current context. :param name: The name of the template variable - :type name: str :param value: The value to assign to the template variable - :type value: Any """ self._template_vars[name] = value def execute_logicsig(self, lsig: algopy.LogicSig, *args: algopy.Bytes) -> bool | algopy.UInt64: - """Execute a logic signature using provided args. - - :param lsig: The logic signature to execute - :type lsig: algopy.LogicSig - :param args: The logic signature arguments to use - :type args: algopy.Bytes - :return: The result of executing the logic signature function - :rtype: bool | algopy.UInt64 - """ + """Execute a logic signature using provided args.""" + self._active_lsig_args = args try: return lsig.func() @@ -130,8 +112,8 @@ def clear_transaction_context(self) -> None: self._txn_context = TransactionContext() def reset(self) -> None: - """Reset the test context to its initial state, clearing all data and - resetting ID counters.""" + """Reset the test context to its initial state, clearing all data and resetting + ID counters.""" self._template_vars.clear() self._txn_context = TransactionContext() self._ledger_context = LedgerContext() diff --git a/src/algopy_testing/decorators/arc4.py b/src/algopy_testing/decorators/arc4.py index bd74b48..eeed563 100644 --- a/src/algopy_testing/decorators/arc4.py +++ b/src/algopy_testing/decorators/arc4.py @@ -2,6 +2,7 @@ import dataclasses import functools +import inspect import types import typing @@ -62,10 +63,29 @@ def get_arc4_metadata(fn: object) -> MethodMetadata: def get_ordered_args( - _fn: Callable[..., typing.Any], app_args: list[typing.Any], kwargs: dict[str, typing.Any] + _fn: Callable[..., typing.Any], app_args: Sequence[typing.Any], kwargs: dict[str, typing.Any] ) -> list[typing.Any]: - # TODO: 1.0 order kwargs correctly based on fn signature - return [*app_args, *kwargs.values()] + sig = inspect.signature(_fn) + params = list(sig.parameters.values())[1:] # Skip 'self' + app_args_iter = iter(app_args) + + ordered_args = [ + ( + kwargs.get(p.name, next(app_args_iter, p.default)) + if p.default is not p.empty + else kwargs.get(p.name) or next(app_args_iter) + ) + for p in params + ] + + if list(app_args_iter): + raise TypeError("Too many positional arguments") + + if len(ordered_args) != len(params): + missing = [p.name for p in params if p.name not in kwargs and p.default is p.empty] + raise TypeError(f"Missing required argument(s): {', '.join(missing)}") + + return ordered_args def check_routing_conditions(app_id: int, metadata: MethodMetadata) -> None: @@ -163,7 +183,7 @@ def create_abimethod_txns( ) -> list[algopy.gtxn.TransactionBase]: method = algosdk.abi.Method.from_signature(arc4_signature) method_selector = Bytes(method.get_selector()) - txn_fields = lazy_context.get_txn_op_fields() + txn_fields = lazy_context.get_active_txn_fields() contract_app = lazy_context.ledger.get_app(app_id) txn_app = txn_fields.setdefault("app_id", contract_app) @@ -195,7 +215,7 @@ def create_abimethod_txns( def create_baremethod_txns(app_id: int) -> list[algopy.gtxn.TransactionBase]: - txn_fields = lazy_context.get_txn_op_fields() + txn_fields = lazy_context.get_active_txn_fields() contract_app = lazy_context.ledger.get_app(app_id) txn_fields.setdefault("app_id", contract_app) diff --git a/src/algopy_testing/itxn.py b/src/algopy_testing/itxn.py index c996983..c2877b4 100644 --- a/src/algopy_testing/itxn.py +++ b/src/algopy_testing/itxn.py @@ -155,10 +155,6 @@ class ApplicationCall(_BaseInnerTransactionFields): def submit_txns( *transactions: _BaseInnerTransactionFields, ) -> tuple[_BaseInnerTransactionResult, ...]: - """Submits a group of up to 16 inner transactions parameters. - - :returns: A tuple of the resulting inner transactions - """ if len(transactions) > algosdk.constants.TX_GROUP_LIMIT: raise ValueError("Cannot submit more than 16 inner transactions at once") diff --git a/src/algopy_testing/models/account.py b/src/algopy_testing/models/account.py index f6bbec3..a906e5a 100644 --- a/src/algopy_testing/models/account.py +++ b/src/algopy_testing/models/account.py @@ -131,11 +131,13 @@ def __repr__(self) -> str: return self.public_key def __eq__(self, other: object) -> bool: - if not isinstance(other, Account | str): - raise TypeError("Invalid value for Account") - if isinstance(other, Account): - return self._public_key == other._public_key - return self._public_key == as_bytes(other) + match other: + case Account() as other_acc: + return self._public_key == other_acc._public_key + case str() as other_str: + return self.public_key == other_str + case _: + return NotImplemented def __bool__(self) -> bool: return bool(self._public_key) and self._public_key != algosdk.encoding.decode_address( diff --git a/src/algopy_testing/models/asset.py b/src/algopy_testing/models/asset.py index c159cb8..77e22ce 100644 --- a/src/algopy_testing/models/asset.py +++ b/src/algopy_testing/models/asset.py @@ -51,7 +51,8 @@ def balance(self, account: algopy.Account) -> algopy.UInt64: if int(self.id) not in account_data.opted_asset_balances: raise ValueError( "The asset is not opted into the account! " - "Use `account.opt_in()` to opt the asset into the account." + "Use `ctx.any.account(opted_asset_balances={{ASSET_ID: VALUE}})` " + "to set emulated opted asset into the account." ) return account_data.opted_asset_balances[self.id] diff --git a/src/algopy_testing/models/contract.py b/src/algopy_testing/models/contract.py index d553319..3cc79f4 100644 --- a/src/algopy_testing/models/contract.py +++ b/src/algopy_testing/models/contract.py @@ -45,7 +45,7 @@ def __call__(cls, *args: typing.Any, **kwargs: dict[str, typing.Any]) -> object: app_data = lazy_context.get_app_data(app_id) app_data.is_creating = True - fields = lazy_context.get_txn_op_fields() + fields = lazy_context.get_active_txn_fields() fields["app_id"] = app_ref # TODO: 1.0 provide app_id during instantiation without requiring a txn diff --git a/src/algopy_testing/models/template_variable.py b/src/algopy_testing/models/template_variable.py index d8179ae..770ef18 100644 --- a/src/algopy_testing/models/template_variable.py +++ b/src/algopy_testing/models/template_variable.py @@ -21,5 +21,5 @@ def create_template_var(variable_name: str) -> typing.Any: TemplateVar: TemplateVarGeneric = TemplateVarGeneric() -"""Template variables can be used to represent a placeholder for a deploy-time -provided value.""" +"""Template variables can be used to represent a placeholder for a deploy-time provided +value.""" diff --git a/src/algopy_testing/models/txn_fields.py b/src/algopy_testing/models/txn_fields.py index 74d83ff..5a0f0c5 100644 --- a/src/algopy_testing/models/txn_fields.py +++ b/src/algopy_testing/models/txn_fields.py @@ -65,19 +65,22 @@ class AssetConfigFields(TransactionBaseFields, total=False): created_asset: algopy.Asset -class ApplicationCallFields(TransactionBaseFields, total=False): - app_id: algopy.Application +class ActiveTransactionFields(TransactionBaseFields, total=False): on_completion: algopy.OnCompleteAction + app_args: Sequence[algopy.Bytes] + accounts: Sequence[algopy.Account] + assets: Sequence[algopy.Asset] + apps: Sequence[algopy.Application] + + +class ApplicationCallFields(ActiveTransactionFields, total=False): + app_id: algopy.Application global_num_uint: algopy.UInt64 global_num_bytes: algopy.UInt64 local_num_uint: algopy.UInt64 local_num_bytes: algopy.UInt64 extra_program_pages: algopy.UInt64 logs: Sequence[algopy.Bytes] - app_args: Sequence[algopy.Bytes] - accounts: Sequence[algopy.Account] - assets: Sequence[algopy.Asset] - apps: Sequence[algopy.Application] approval_program: Sequence[algopy.Bytes] clear_state_program: Sequence[algopy.Bytes] created_app: algopy.Application diff --git a/src/algopy_testing/op/global_values.py b/src/algopy_testing/op/global_values.py index 4a7c43f..e7516b0 100644 --- a/src/algopy_testing/op/global_values.py +++ b/src/algopy_testing/op/global_values.py @@ -7,7 +7,7 @@ import algosdk from algopy_testing._context_helpers import lazy_context -from algopy_testing.models import Account, Application +from algopy_testing.models import Account from algopy_testing.primitives import UInt64 if typing.TYPE_CHECKING: @@ -47,11 +47,7 @@ def current_application_address(self) -> algopy.Account: @property def current_application_id(self) -> algopy.Application: - app = lazy_context.active_app - app_data = lazy_context.get_app_data(app) - if app_data.is_creating: - return Application(0) - return app + return lazy_context.active_app @property def creator_address(self) -> algopy.Account: diff --git a/src/algopy_testing/op/pure.py b/src/algopy_testing/op/pure.py index 99154ed..5a41aba 100644 --- a/src/algopy_testing/op/pure.py +++ b/src/algopy_testing/op/pure.py @@ -292,8 +292,8 @@ def _get_bit(v: int, index: int) -> int: def _set_bit(v: int, index: int, x: int) -> int: - """Set the index:th bit of v to 1 if x is truthy, else to 0, and return the - new value.""" + """Set the index:th bit of v to 1 if x is truthy, else to 0, and return the new + value.""" mask = 1 << index # Compute mask, an integer with just bit 'index' set. v &= ~mask # Clear the bit indicated by the mask (if x is False) if x: diff --git a/src/algopy_testing/primitives/biguint.py b/src/algopy_testing/primitives/biguint.py index c5f3add..e8195fa 100644 --- a/src/algopy_testing/primitives/biguint.py +++ b/src/algopy_testing/primitives/biguint.py @@ -14,8 +14,7 @@ @functools.total_ordering class BigUInt(BytesBacked): - """A python implementation of an TEAL bigint type represented by AVM []byte - type.""" + """A python implementation of an TEAL bigint type represented by AVM []byte type.""" __value: bytes # underlying 'bytes' value representing the BigUInt diff --git a/src/algopy_testing/primitives/bytes.py b/src/algopy_testing/primitives/bytes.py index 8b4d4c2..e7e82b1 100644 --- a/src/algopy_testing/primitives/bytes.py +++ b/src/algopy_testing/primitives/bytes.py @@ -37,8 +37,8 @@ def __bool__(self) -> bool: return bool(self.value) def __add__(self, other: Bytes | bytes) -> Bytes: - """Concatenate Bytes with another Bytes or bytes literal e.g. - `Bytes(b"Hello ") + b"World"`.""" + """Concatenate Bytes with another Bytes or bytes literal e.g. `Bytes(b"Hello ") + + b"World"`.""" if isinstance(other, Bytes): return _checked_result(self.value + other.value, "+") else: @@ -46,8 +46,8 @@ def __add__(self, other: Bytes | bytes) -> Bytes: return _checked_result(result, "+") def __radd__(self, other: bytes) -> Bytes: - """Concatenate Bytes with another Bytes or bytes literal e.g. `b"Hello - " + Bytes(b"World")`.""" + """Concatenate Bytes with another Bytes or bytes literal e.g. `b"Hello " + + Bytes(b"World")`.""" return _checked_result(other + self.value, "+") def __len__(self) -> int: @@ -58,15 +58,15 @@ def __iter__(self) -> Iterator[Bytes]: return _BytesIter(self, 1) def __reversed__(self) -> Iterator[Bytes]: - """Bytes can be iterated in reverse, yield each preceding byte starting - at the end.""" + """Bytes can be iterated in reverse, yield each preceding byte starting at the + end.""" return _BytesIter(self, -1) def __getitem__( self, index: UInt64 | int | slice ) -> Bytes: # maps to substring/substring3 if slice, extract/extract3 otherwise? - """Returns a Bytes containing a single byte if indexed with UInt64 or - int otherwise the substring o bytes described by the slice.""" + """Returns a Bytes containing a single byte if indexed with UInt64 or int + otherwise the substring o bytes described by the slice.""" if isinstance(index, slice): return Bytes(self.value[index]) else: @@ -143,8 +143,7 @@ def from_base64(value: str) -> Bytes: @staticmethod def from_hex(value: str) -> Bytes: - """Creates Bytes from a hex/octal encoded string e.g. - `Bytes.from_hex("FF")`""" + """Creates Bytes from a hex/octal encoded string e.g. `Bytes.from_hex("FF")`""" return Bytes(base64.b16decode(value)) diff --git a/src/algopy_testing/primitives/string.py b/src/algopy_testing/primitives/string.py index 2bd3927..1ca869f 100644 --- a/src/algopy_testing/primitives/string.py +++ b/src/algopy_testing/primitives/string.py @@ -6,12 +6,11 @@ class String(BytesBacked): - """Represents a UTF-8 encoded string backed by Bytes, accessible via - .bytes. + """Represents a UTF-8 encoded string backed by Bytes, accessible via .bytes. - Works with str literals instead of bytes literals. Due to lack of - AVM support for unicode, indexing and length operations are not - supported. Use .bytes.length for byte length. + Works with str literals instead of bytes literals. Due to lack of AVM support for + unicode, indexing and length operations are not supported. Use .bytes.length for + byte length. """ _value: bytes # underlying 'bytes' value representing the String diff --git a/src/algopy_testing/primitives/uint64.py b/src/algopy_testing/primitives/uint64.py index 37e40c5..b09834b 100644 --- a/src/algopy_testing/primitives/uint64.py +++ b/src/algopy_testing/primitives/uint64.py @@ -163,8 +163,8 @@ def __invert__(self) -> UInt64: return UInt64(~self.value & MAX_UINT64) def __index__(self) -> int: - """Return the internal integer value of the UInt64 for use in - indexing/slice expressions. + """Return the internal integer value of the UInt64 for use in indexing/slice + expressions. Returns: int: The internal integer value of the UInt64. diff --git a/src/algopy_testing/state/box.py b/src/algopy_testing/state/box.py index 55d1834..28dc42f 100644 --- a/src/algopy_testing/state/box.py +++ b/src/algopy_testing/state/box.py @@ -18,8 +18,8 @@ class Box(typing.Generic[_TValue]): """Box abstracts the reading and writing of a single value to a single box. - The box size will be reconfigured dynamically to fit the size of the - value being assigned to it. + The box size will be reconfigured dynamically to fit the size of the value being + assigned to it. """ def __init__( @@ -35,55 +35,34 @@ def __init__( self.app_id = lazy_context.active_app_id def __bool__(self) -> bool: - """Returns True if the box exists, regardless of the truthiness of the - contents of the box.""" return lazy_context.ledger.box_exists(self.app_id, self.key) @property def key(self) -> algopy.Bytes: - """Provides access to the raw storage key.""" if not self._key: raise RuntimeError("Box key is empty") return self._key @property def value(self) -> _TValue: - """Retrieve the contents of the box. - - Fails if the box has not been created. - """ if not lazy_context.ledger.box_exists(self.app_id, self.key): raise RuntimeError("Box has not been created") - # TODO: 1.0 will need to use a proxy here too for mutable types return cast_from_bytes(self._type, lazy_context.ledger.get_box(self.app_id, self.key)) @value.setter def value(self, value: _TValue) -> None: - """Write _value_ to the box. - - Creates the box if it does not exist. - """ bytes_value = cast_to_bytes(value) lazy_context.ledger.set_box(self.app_id, self.key, bytes_value) @value.deleter def value(self) -> None: - """Delete the box.""" lazy_context.ledger.delete_box(self.app_id, self.key) def get(self, *, default: _TValue) -> _TValue: - """Retrieve the contents of the box, or return the default value if the - box has not been created. - - :arg default: The default value to return if the box has not - been created - """ box_content, box_exists = self.maybe() return default if not box_exists else box_content def maybe(self) -> tuple[_TValue, bool]: - """Retrieve the contents of the box if it exists, and return a boolean - indicating if the box exists.""" box_exists = lazy_context.ledger.box_exists(self.app_id, self.key) box_content_bytes = lazy_context.ledger.get_box(self.app_id, self.key) box_content = cast_from_bytes(self._type, box_content_bytes) @@ -91,21 +70,16 @@ def maybe(self) -> tuple[_TValue, bool]: @property def length(self) -> algopy.UInt64: - """Get the length of this Box. - - Fails if the box does not exist - """ if not lazy_context.ledger.box_exists(self.app_id, self.key): raise RuntimeError("Box has not been created") return algopy_testing.UInt64(len(lazy_context.ledger.get_box(self.app_id, self.key))) class BoxRef: - """BoxRef abstracts the reading and writing of boxes containing raw binary - data. + """BoxRef abstracts the reading and writing of boxes containing raw binary data. - The size is configured manually, and can be set to values larger - than what the AVM can handle in a single value. + The size is configured manually, and can be set to values larger than what the AVM + can handle in a single value. """ def __init__(self, /, *, key: bytes | str | algopy.Bytes | algopy.String = "") -> None: @@ -117,26 +91,16 @@ def __init__(self, /, *, key: bytes | str | algopy.Bytes | algopy.String = "") - self.app_id = lazy_context.active_app_id def __bool__(self) -> bool: - """Returns True if the box has a value set, regardless of the - truthiness of that value.""" return lazy_context.ledger.box_exists(self.app_id, self.key) @property def key(self) -> algopy.Bytes: - """Provides access to the raw storage key.""" if not self._key: raise RuntimeError("Box key is empty") return self._key def create(self, *, size: algopy.UInt64 | int) -> bool: - """Creates a box with the specified size, setting all bits to zero. - Fails if the box already exists with a different size. Fails if the - specified size is greater than the max box size (32,768) - - Returns True if the box was created, False if the box already - existed - """ size_int = int(size) if size_int > MAX_BOX_SIZE: raise ValueError(f"Box size cannot exceed {MAX_BOX_SIZE}") @@ -150,21 +114,11 @@ def create(self, *, size: algopy.UInt64 | int) -> bool: return True def delete(self) -> bool: - """Deletes the box if it exists and returns a value indicating if the - box existed.""" return lazy_context.ledger.delete_box(self.app_id, self.key) def extract( self, start_index: algopy.UInt64 | int, length: algopy.UInt64 | int ) -> algopy.Bytes: - """Extract a slice of bytes from the box. - - Fails if the box does not exist, or if `start_index + length > - len(box)` - - :arg start_index: The offset to start extracting bytes from :arg - length: The number of bytes to extract - """ box_content, box_exists = self._maybe() start_int = int(start_index) length_int = int(length) @@ -176,11 +130,6 @@ def extract( return algopy_testing.Bytes(result) def resize(self, new_size: algopy.UInt64 | int) -> None: - """Resizes the box the specified `new_size`. Truncating existing data - if the new value is shorter or padding with zero bytes if it is longer. - - :arg new_size: The new size of the box - """ new_size_int = int(new_size) if new_size_int > MAX_BOX_SIZE: @@ -195,12 +144,6 @@ def resize(self, new_size: algopy.UInt64 | int) -> None: lazy_context.ledger.set_box(self.app_id, self.key, updated_content) def replace(self, start_index: algopy.UInt64 | int, value: algopy.Bytes | bytes) -> None: - """Write `value` to the box starting at `start_index`. Fails if the box - does not exist, or if `start_index + len(value) > len(box)` - - :arg start_index: The offset to start writing bytes from :arg - value: The bytes to be written - """ box_content, box_exists = self._maybe() if not box_exists: raise RuntimeError("Box has not been created") @@ -217,18 +160,6 @@ def splice( length: algopy.UInt64 | int, value: algopy.Bytes | bytes, ) -> None: - """Set box to contain its previous bytes up to index `start_index`, - followed by `bytes`, followed by the original bytes of the box that - began at index `start_index + length` - - **Important: This op does not resize the box** - If the new value is longer than the box size, it will be truncated. - If the new value is shorter than the box size, it will be padded with zero bytes - - :arg start_index: The index to start inserting `value` - :arg length: The number of bytes after `start_index` to omit from the new value - :arg value: The `value` to be inserted. - """ box_content, box_exists = self._maybe() start = int(start_index) @@ -241,31 +172,17 @@ def splice( if start > len(box_content): raise ValueError("Start index exceeds box size") - # Calculate the end index for deletion end = min(start + delete_count, len(box_content)) - - # Construct the new content new_content = box_content[:start] + insert_content + box_content[end:] - # Adjust the size if necessary if len(new_content) > len(box_content): - # Truncate if the new content is too long new_content = new_content[: len(box_content)] elif len(new_content) < len(box_content): - # Pad with zeros if the new content is too short new_content += b"\x00" * (len(box_content) - len(new_content)) - # Update the box with the new content lazy_context.ledger.set_box(self.app_id, self.key, new_content) def get(self, *, default: algopy.Bytes | bytes) -> algopy.Bytes: - """Retrieve the contents of the box, or return the default value if the - box has not been created. - - :arg default: The default value to return if the box has not - been created - """ - box_content, box_exists = self._maybe() default_bytes = ( default if isinstance(default, algopy_testing.Bytes) else algopy_testing.Bytes(default) @@ -273,11 +190,6 @@ def get(self, *, default: algopy.Bytes | bytes) -> algopy.Bytes: return default_bytes if not box_exists else algopy_testing.Bytes(box_content) def put(self, value: algopy.Bytes | bytes) -> None: - """Replaces the contents of box with value. Fails if box exists and - len(box) != len(value). Creates box if it does not exist. - - :arg value: The value to write to the box - """ box_content, box_exists = self._maybe() if box_exists and len(box_content) != len(value): raise ValueError("Box already exists with a different size") @@ -286,8 +198,6 @@ def put(self, value: algopy.Bytes | bytes) -> None: lazy_context.ledger.set_box(self.app_id, self.key, content) def maybe(self) -> tuple[algopy.Bytes, bool]: - """Retrieve the contents of the box if it exists, and return a boolean - indicating if the box exists.""" box_content, box_exists = self._maybe() return algopy_testing.Bytes(box_content), box_exists @@ -298,10 +208,6 @@ def _maybe(self) -> tuple[bytes, bool]: @property def length(self) -> algopy.UInt64: - """Get the length of this Box. - - Fails if the box does not exist - """ box_content, box_exists = self._maybe() if not box_exists: raise RuntimeError("Box has not been created") @@ -309,8 +215,8 @@ def length(self) -> algopy.UInt64: class BoxMap(typing.Generic[_TKey, _TValue]): - """BoxMap abstracts the reading and writing of a set of boxes using a - common key and content type. + """BoxMap abstracts the reading and writing of a set of boxes using a common key and + content type. Each composite key (prefix + key) still needs to be made available to the application via the `boxes` property of the Transaction. @@ -324,15 +230,6 @@ def __init__( *, key_prefix: bytes | str | algopy.Bytes | algopy.String | None = None, ) -> None: - """Declare a box map. - - :arg key_type: The type of the keys :arg value_type: The type of - the values :arg key_prefix: The value used as a prefix to key - data, can be empty. When the BoxMap is being - assigned to a member variable, this argument is - optional and defaults to the member variable name, and if a - custom value is supplied it must be static. - """ self._key_type = key_type self._value_type = value_type match key_prefix: @@ -348,58 +245,34 @@ def __init__( @property def key_prefix(self) -> algopy.Bytes: - """Provides access to the raw storage key-prefix.""" - # empty bytes is a valid key prefix, so check for None explicitly if self._key_prefix is None: raise RuntimeError("Box key prefix is not defined") return self._key_prefix def __getitem__(self, key: _TKey) -> _ProxyValue: - """Retrieve the contents of a keyed box. - - Fails if the box for the key has not been created. - """ box_content, box_exists = self.maybe(key) if not box_exists: raise RuntimeError("Box has not been created") return _ProxyValue(self, key, box_content) def __setitem__(self, key: _TKey, value: _TValue) -> None: - """Write _value_ to a keyed box. - - Creates the box if it does not exist - """ key_bytes = self._full_key(key) bytes_value = cast_to_bytes(value) lazy_context.ledger.set_box(self.app_id, key_bytes, bytes_value) def __delitem__(self, key: _TKey) -> None: - """Deletes a keyed box.""" key_bytes = self._full_key(key) lazy_context.ledger.delete_box(self.app_id, key_bytes) def __contains__(self, key: _TKey) -> bool: - """Returns True if a box with the specified key exists in the map, - regardless of the truthiness of the contents of the box.""" key_bytes = self._full_key(key) return lazy_context.ledger.box_exists(self.app_id, key_bytes) def get(self, key: _TKey, *, default: _TValue) -> _TValue: - """Retrieve the contents of a keyed box, or return the default value if - the box has not been created. - - :arg key: The key of the box to get :arg default: The default - value to return if the box has not been created. - """ box_content, box_exists = self.maybe(key) return default if not box_exists else box_content def maybe(self, key: _TKey) -> tuple[_TValue, bool]: - """Retrieve the contents of a keyed box if it exists, and return a - boolean indicating if the box exists. - - :arg key: The key of the box to get - """ key_bytes = self._full_key(key) box_exists = lazy_context.ledger.box_exists(self.app_id, key_bytes) if not box_exists: @@ -409,11 +282,6 @@ def maybe(self, key: _TKey) -> tuple[_TValue, bool]: return box_content, box_exists def length(self, key: _TKey) -> algopy.UInt64: - """Get the length of an item in this BoxMap. Fails if the box does not - exist. - - :arg key: The key of the box to get - """ key_bytes = self._full_key(key) box_exists = lazy_context.ledger.box_exists(self.app_id, key_bytes) if not box_exists: @@ -425,13 +293,6 @@ def _full_key(self, key: _TKey) -> algopy.Bytes: return self.key_prefix + cast_to_bytes(key) -# TODO: 1.0 using this proxy will mean other parts of the library that do isinstance will not be -# correct. To solve this need to do the following -# 1.) only use the proxy if the value is mutable, currently this means only -# ARC Arrays, Tuples and structs should need this proxy -# 2.) modify the metaclass of the above types to ensure they still pass the appropriate -# isinstance checks, when a ProxyValue is being used -# see https://docs.python.org/3.12/reference/datamodel.html#customizing-instance-and-subclass-checks class _ProxyValue: """Allows mutating attributes of objects retrieved from a BoxMap.""" diff --git a/src/algopy_testing/state/global_state.py b/src/algopy_testing/state/global_state.py index a9601b1..cd679d1 100644 --- a/src/algopy_testing/state/global_state.py +++ b/src/algopy_testing/state/global_state.py @@ -59,9 +59,8 @@ def __init__( def set_key(self, key: Bytes | String | bytes | str) -> None: """Set the key and apply any pending value. - Pending values are used for implicit keys in Contract - subclasses. They're stored until the 'Contract''s initialization - sets the key. + Pending values are used for implicit keys in Contract subclasses. They're stored + until the 'Contract''s initialization sets the key. """ match key: case bytes(bytes_key): @@ -73,7 +72,7 @@ def set_key(self, key: Bytes | String | bytes | str) -> None: case String() as key_str: self._key = key_str.bytes case _: - raise ValueError("Key must be bytes or str") + raise KeyError("Key must be bytes or str") if self._key and self._pending_value is not None: self.value = self._pending_value @@ -83,7 +82,7 @@ def set_key(self, key: Bytes | String | bytes | str) -> None: def key(self) -> algopy.Bytes: """Provides access to the raw storage key.""" if self._key is None: - raise ValueError("Key is not set") + raise KeyError("Key is not set") return self._key @property @@ -91,7 +90,7 @@ def value(self) -> _T: if self._key is None: if self._pending_value is not None: return self._pending_value - raise ValueError("Key is not set") + raise KeyError("Key is not set") try: native = lazy_context.ledger.get_global_state(self.app_id, self._key) except KeyError as e: diff --git a/tests/arc4/test_abi_call.py b/tests/arc4/test_abi_call.py index 5b4f8ad..2ba1e0e 100644 --- a/tests/arc4/test_abi_call.py +++ b/tests/arc4/test_abi_call.py @@ -18,7 +18,6 @@ def echo(self, value: arc4.String) -> arc4.String: def context() -> Generator[AlgopyTestContext, None, None]: with algopy_testing_context() as ctx: yield ctx - ctx.reset() def test_mocking_required_for_abi_call(context: AlgopyTestContext) -> None: diff --git a/tests/arc4/test_arc4_method_signature.py b/tests/arc4/test_arc4_method_signature.py index fd247fe..c7b522b 100644 --- a/tests/arc4/test_arc4_method_signature.py +++ b/tests/arc4/test_arc4_method_signature.py @@ -1,10 +1,15 @@ from collections.abc import Generator +from pathlib import Path +import algokit_utils import algopy import algopy_testing import algosdk import pytest +from algokit_utils.beta.algorand_client import AlgorandClient, AssetCreateParams, PayParams from algopy import arc4 +from algosdk.atomic_transaction_composer import TransactionWithSigner +from algosdk.v2client.algod import AlgodClient from tests.artifacts.Arc4ABIMethod.contract import ( AnotherStruct, @@ -12,23 +17,65 @@ SignaturesContract, UInt8Array, ) +from tests.common import AVMInvoker, create_avm_invoker -# TODO: 1.0 execute this on AVM too +ARTIFACTS_DIR = Path(__file__).parent / ".." / "artifacts" +APP_SPEC = ARTIFACTS_DIR / "Arc4ABIMethod" / "data" / "SignaturesContract.arc32.json" +_FUNDED_ACCOUNT_SPENDING = 1234 + + +@pytest.fixture() +def get_avm_result(algod_client: AlgodClient) -> AVMInvoker: + return create_avm_invoker(APP_SPEC, algod_client) @pytest.fixture() def context() -> Generator[algopy_testing.AlgopyTestContext, None, None]: with algopy_testing.algopy_testing_context() as ctx: yield ctx - ctx.reset() -def test_app_args_is_correct_with_simple_args(context: algopy_testing.AlgopyTestContext) -> None: +@pytest.fixture() +def funded_account(algod_client: AlgodClient, context: algopy_testing.AlgopyTestContext) -> str: + pk, address = algosdk.account.generate_account() + assert isinstance(address, str) + algokit_utils.ensure_funded( + algod_client, + algokit_utils.EnsureBalanceParameters( + account_to_fund=address, + min_spending_balance_micro_algos=_FUNDED_ACCOUNT_SPENDING, + ), + ) + + # ensure context has the same account with matching balance + context.any.account(address, balance=algopy.Global.min_balance + _FUNDED_ACCOUNT_SPENDING) + return address + + +@pytest.fixture() +def other_app_id(algod_client: AlgodClient, context: algopy_testing.AlgopyTestContext) -> int: + second_invoker = create_avm_invoker(APP_SPEC, algod_client) + client = second_invoker.client + app_id = client.app_id + + # ensure context also has app with this id + context.any.application(app_id) + return app_id + + +def test_app_args_is_correct_with_simple_args( + get_avm_result: AVMInvoker, + context: algopy_testing.AlgopyTestContext, +) -> None: # arrange contract = SignaturesContract() contract.create() # act + + # ensure same execution in AVM runs without errors + get_avm_result("sink", value="hello", arr=[1, 2]) + # then run inside emulator contract.sink(arc4.String("hello"), UInt8Array(arc4.UInt8(1), arc4.UInt8(2))) # assert @@ -41,12 +88,18 @@ def test_app_args_is_correct_with_simple_args(context: algopy_testing.AlgopyTest ] -def test_app_args_is_correct_with_alias(context: algopy_testing.AlgopyTestContext) -> None: +def test_app_args_is_correct_with_alias( + get_avm_result: AVMInvoker, + context: algopy_testing.AlgopyTestContext, +) -> None: # arrange contract = SignaturesContract() contract.create() # act + # ensure same execution in AVM runs without errors + get_avm_result("alias", value="hello", arr=[1, 2]) + # then run inside emulator contract.sink2(arc4.String("hello"), UInt8Array(arc4.UInt8(1), arc4.UInt8(2))) # assert @@ -59,15 +112,35 @@ def test_app_args_is_correct_with_alias(context: algopy_testing.AlgopyTestContex ] -def test_app_args_is_correct_with_txn(context: algopy_testing.AlgopyTestContext) -> None: +def test_app_args_is_correct_with_txn( + context: algopy_testing.AlgopyTestContext, + get_avm_result: AVMInvoker, + localnet_creator_address: str, + algorand: AlgorandClient, +) -> None: # arrange contract = SignaturesContract() contract.create() # act + get_avm_result( + "with_txn", + value="hello", + pay=TransactionWithSigner( + txn=algorand.transactions.payment( + PayParams( + sender=localnet_creator_address, + receiver=localnet_creator_address, + amount=123, + ) + ), + signer=algorand.account.get_signer("default"), + ), + arr=[1, 2], + ) contract.with_txn( arc4.String("hello"), - context.any.txn.asset_config(total=algopy.UInt64(123)), + context.any.txn.payment(amount=algopy.UInt64(123)), UInt8Array(arc4.UInt8(1), arc4.UInt8(2)), ) @@ -75,7 +148,7 @@ def test_app_args_is_correct_with_txn(context: algopy_testing.AlgopyTestContext) txn = context.txn.last_active app_args = [txn.app_args(i) for i in range(3)] assert app_args == [ - algosdk.abi.Method.from_signature("with_txn(string,acfg,uint8[])void").get_selector(), + algosdk.abi.Method.from_signature("with_txn(string,pay,uint8[])void").get_selector(), b"\x00\x05hello", b"\x00\x02\x01\x02", ] @@ -83,11 +156,23 @@ def test_app_args_is_correct_with_txn(context: algopy_testing.AlgopyTestContext) def test_app_args_is_correct_with_asset( context: algopy_testing.AlgopyTestContext, -) -> None: # arrange + localnet_creator_address: str, + algorand: AlgorandClient, + get_avm_result: AVMInvoker, +) -> None: + # arrange contract = SignaturesContract() contract.create() + asa_id = algorand.send.asset_create( + AssetCreateParams( + sender=localnet_creator_address, + total=123, + ) + )["confirmation"]["asset-index"] + # act + get_avm_result("with_asset", value="hello", asset=asa_id, arr=[1, 2]) contract.with_asset( arc4.String("hello"), context.any.asset(total=algopy.UInt64(123)), @@ -105,45 +190,93 @@ def test_app_args_is_correct_with_asset( ] -def test_app_args_is_correct_with_application(context: algopy_testing.AlgopyTestContext) -> None: +def test_app_args_is_correct_with_account( + context: algopy_testing.AlgopyTestContext, + funded_account: str, + get_avm_result: AVMInvoker, +) -> None: + # arrange + contract = SignaturesContract() + contract.create() + + # act + contract.with_acc( + arc4.String("hello"), + context.ledger.get_account(funded_account), + UInt8Array(arc4.UInt8(1), arc4.UInt8(2)), + ) + get_avm_result( + "with_acc", + value="hello", + acc=funded_account, + arr=[1, 2], + ) + + # assert + txn = context.txn.last_active + app_args = [txn.app_args(i) for i in range(int(txn.num_app_args))] + assert app_args == [ + algosdk.abi.Method.from_signature("with_acc(string,account,uint8[])void").get_selector(), + b"\x00\x05hello", + b"\x01", + b"\x00\x02\x01\x02", + ] + + +def test_app_args_is_correct_with_application( + context: algopy_testing.AlgopyTestContext, + other_app_id: int, + get_avm_result: AVMInvoker, +) -> None: # arrange contract = SignaturesContract() contract.create() self_app = context.get_app_for_contract(contract) - other_app = context.any.application(id=1234) # act + get_avm_result( + "with_app", + value="hello", + app=other_app_id, + app_id=other_app_id, + arr=[1, 2], + ) contract.with_app( arc4.String("hello"), - other_app, + context.ledger.get_app(other_app_id), + arc4.UInt64(other_app_id), UInt8Array(arc4.UInt8(1), arc4.UInt8(2)), ) # assert txn = context.txn.last_active app_args = [txn.app_args(i) for i in range(int(txn.num_app_args))] - app_foreign_apps = [txn.apps(i) for i in range(int(txn.num_apps))] + app_foreign_apps = [txn.apps(i).id for i in range(int(txn.num_apps))] assert app_args == [ algosdk.abi.Method.from_signature( - "with_app(string,application,uint8[])void" + "with_app(string,application,uint64,uint8[])void" ).get_selector(), b"\x00\x05hello", b"\x01", # 0th index is the app being called + other_app_id.to_bytes(length=8), # app id as bytes b"\x00\x02\x01\x02", ] assert app_foreign_apps == [ - self_app, - other_app, + self_app.id, + other_app_id, ] -def test_app_args_is_correct_with_complex(context: algopy_testing.AlgopyTestContext) -> None: +def test_app_args_is_correct_with_complex( + context: algopy_testing.AlgopyTestContext, + funded_account: str, +) -> None: # arrange contract = SignaturesContract() contract.create() - account = context.any.account(balance=algopy.UInt64(123)) + account = context.ledger.get_account(funded_account) txn = context.any.txn.transaction() struct = MyStruct( three=arc4.UInt128(3), @@ -171,12 +304,18 @@ def test_app_args_is_correct_with_complex(context: algopy_testing.AlgopyTestCont assert result[1].bytes == struct.bytes -def test_prepare_txns_with_complex(context: algopy_testing.AlgopyTestContext) -> None: +def test_prepare_txns_with_complex( + context: algopy_testing.AlgopyTestContext, + get_avm_result: AVMInvoker, + algorand: AlgorandClient, + localnet_creator_address: str, + funded_account: str, +) -> None: # arrange contract = SignaturesContract() contract.create() - account = context.any.account(balance=algopy.UInt64(123)) + account = context.ledger.get_account(funded_account) txn = context.any.txn.transaction() struct = MyStruct( three=arc4.UInt128(3), @@ -190,7 +329,25 @@ def test_prepare_txns_with_complex(context: algopy_testing.AlgopyTestContext) -> ) # act - with context.txn.create_group(gtxns=[deferred_app_call]): + get_avm_result( + "complex_sig", + struct1=((1, "2"), (1, "2"), 3, 4), + txn=TransactionWithSigner( + txn=algorand.transactions.payment( + PayParams( + sender=localnet_creator_address, + receiver=localnet_creator_address, + amount=123, + ) + ), + signer=algorand.account.get_signer("default"), + ), + acc=funded_account, + five=[5], + ) + with context.txn.create_group( + gtxns=[context.any.txn.payment(), deferred_app_call, context.any.txn.payment()] + ): result = deferred_app_call.submit() # assert diff --git a/tests/arc4/test_emit.py b/tests/arc4/test_emit.py index 0c7df77..e112198 100644 --- a/tests/arc4/test_emit.py +++ b/tests/arc4/test_emit.py @@ -56,7 +56,6 @@ class SwappedArc4(arc4.Struct): def context() -> Generator[AlgopyTestContext, None, None]: with algopy_testing_context() as ctx: yield ctx - ctx.reset() def test_emit(get_avm_result: AVMInvoker, context: AlgopyTestContext) -> None: diff --git a/tests/artifacts/Arc4ABIMethod/contract.py b/tests/artifacts/Arc4ABIMethod/contract.py index 2223a3e..a61848f 100644 --- a/tests/artifacts/Arc4ABIMethod/contract.py +++ b/tests/artifacts/Arc4ABIMethod/contract.py @@ -26,9 +26,12 @@ class SignaturesContract(ARC4Contract): @arc4.abimethod(create="require") def create(self) -> None: app_txn = gtxn.ApplicationCallTransaction(0) - assert op.Global.current_application_id == 0 - assert app_txn.app_id == 0 - assert Txn.application_id == 0 + assert op.Global.current_application_id != 0, "expected global to have app id" + assert ( + op.Global.current_application_address != op.Global.zero_address + ), "expected global to have app address" + assert app_txn.app_id == 0, "expected txn to have 0" + assert Txn.application_id == 0, "expected txn to have 0" @arc4.abimethod def sink(self, value: arc4.String, arr: UInt8Array) -> None: @@ -41,14 +44,12 @@ def sink2(self, value: arc4.String, arr: UInt8Array) -> None: assert arr @arc4.abimethod - def with_txn( - self, value: arc4.String, acfg: gtxn.AssetConfigTransaction, arr: UInt8Array - ) -> None: + def with_txn(self, value: arc4.String, pay: gtxn.PaymentTransaction, arr: UInt8Array) -> None: assert value assert arr - assert acfg.group_index == 0 + assert pay.group_index == 0 assert Txn.group_index == 1 - assert acfg.total == 123 + assert pay.amount == 123 @arc4.abimethod def with_asset(self, value: arc4.String, asset: Asset, arr: UInt8Array) -> None: @@ -58,10 +59,13 @@ def with_asset(self, value: arc4.String, asset: Asset, arr: UInt8Array) -> None: assert Txn.assets(0) == asset @arc4.abimethod - def with_app(self, value: arc4.String, app: Application, arr: UInt8Array) -> None: + def with_app( + self, value: arc4.String, app: Application, app_id: arc4.UInt64, arr: UInt8Array + ) -> None: assert value assert arr - assert app.id == 1234 + assert app.id == app_id, "expected app id to match provided app id" + assert app.creator == op.Global.creator_address, "expected other app to have same creator" app_txn = gtxn.ApplicationCallTransaction(0) assert app_txn.apps(0) == op.Global.current_application_id assert Txn.applications(0) == op.Global.current_application_id @@ -72,7 +76,7 @@ def with_app(self, value: arc4.String, app: Application, arr: UInt8Array) -> Non def with_acc(self, value: arc4.String, acc: Account, arr: UInt8Array) -> None: assert value assert arr - assert acc.total_apps_created == 123 + assert acc.balance == acc.min_balance + 1234 assert Txn.accounts(0) == Txn.sender assert Txn.accounts(1) == acc @@ -94,7 +98,7 @@ def complex_sig( # acc assert Txn.application_args(2) == arc4.UInt8(1).bytes # acc array ref - assert acc.balance == 123 + assert acc.balance == acc.min_balance + 1234 assert five[0] == 5 return struct1.another_struct.copy(), struct1.copy() diff --git a/tests/artifacts/Arc4ABIMethod/data/SignaturesContract.approval.teal b/tests/artifacts/Arc4ABIMethod/data/SignaturesContract.approval.teal index b4b0b18..9975148 100644 --- a/tests/artifacts/Arc4ABIMethod/data/SignaturesContract.approval.teal +++ b/tests/artifacts/Arc4ABIMethod/data/SignaturesContract.approval.teal @@ -6,9 +6,9 @@ tests.artifacts.Arc4ABIMethod.contract.SignaturesContract.approval_program: method "create()void" method "sink(string,uint8[])void" method "alias(string,uint8[])void" - method "with_txn(string,acfg,uint8[])void" + method "with_txn(string,pay,uint8[])void" method "with_asset(string,asset,uint8[])void" - method "with_app(string,application,uint8[])void" + method "with_app(string,application,uint64,uint8[])void" method "with_acc(string,account,uint8[])void" method "complex_sig(((uint64,string),(uint64,string),uint128,uint128),txn,account,uint8[])((uint64,string),((uint64,string),(uint64,string),uint128,uint128))" txna ApplicationArgs 0 @@ -29,7 +29,7 @@ main_create_route@1: return main_sink_route@2: - // tests/artifacts/Arc4ABIMethod/contract.py:33 + // tests/artifacts/Arc4ABIMethod/contract.py:36 // @arc4.abimethod txn OnCompletion ! @@ -40,14 +40,14 @@ main_sink_route@2: // class SignaturesContract(ARC4Contract): txna ApplicationArgs 1 txna ApplicationArgs 2 - // tests/artifacts/Arc4ABIMethod/contract.py:33 + // tests/artifacts/Arc4ABIMethod/contract.py:36 // @arc4.abimethod callsub sink int 1 return main_alias_route@3: - // tests/artifacts/Arc4ABIMethod/contract.py:38 + // tests/artifacts/Arc4ABIMethod/contract.py:41 // @arc4.abimethod(name="alias") txn OnCompletion ! @@ -58,14 +58,14 @@ main_alias_route@3: // class SignaturesContract(ARC4Contract): txna ApplicationArgs 1 txna ApplicationArgs 2 - // tests/artifacts/Arc4ABIMethod/contract.py:38 + // tests/artifacts/Arc4ABIMethod/contract.py:41 // @arc4.abimethod(name="alias") callsub sink2 int 1 return main_with_txn_route@4: - // tests/artifacts/Arc4ABIMethod/contract.py:43 + // tests/artifacts/Arc4ABIMethod/contract.py:46 // @arc4.abimethod txn OnCompletion ! @@ -80,18 +80,18 @@ main_with_txn_route@4: - dup gtxns TypeEnum - int acfg + int pay == - assert // transaction type is acfg + assert // transaction type is pay txna ApplicationArgs 2 - // tests/artifacts/Arc4ABIMethod/contract.py:43 + // tests/artifacts/Arc4ABIMethod/contract.py:46 // @arc4.abimethod callsub with_txn int 1 return main_with_asset_route@5: - // tests/artifacts/Arc4ABIMethod/contract.py:53 + // tests/artifacts/Arc4ABIMethod/contract.py:54 // @arc4.abimethod txn OnCompletion ! @@ -105,14 +105,14 @@ main_with_asset_route@5: btoi txnas Assets txna ApplicationArgs 3 - // tests/artifacts/Arc4ABIMethod/contract.py:53 + // tests/artifacts/Arc4ABIMethod/contract.py:54 // @arc4.abimethod callsub with_asset int 1 return main_with_app_route@6: - // tests/artifacts/Arc4ABIMethod/contract.py:60 + // tests/artifacts/Arc4ABIMethod/contract.py:61 // @arc4.abimethod txn OnCompletion ! @@ -126,14 +126,15 @@ main_with_app_route@6: btoi txnas Applications txna ApplicationArgs 3 - // tests/artifacts/Arc4ABIMethod/contract.py:60 + txna ApplicationArgs 4 + // tests/artifacts/Arc4ABIMethod/contract.py:61 // @arc4.abimethod callsub with_app int 1 return main_with_acc_route@7: - // tests/artifacts/Arc4ABIMethod/contract.py:71 + // tests/artifacts/Arc4ABIMethod/contract.py:75 // @arc4.abimethod txn OnCompletion ! @@ -147,14 +148,14 @@ main_with_acc_route@7: btoi txnas Accounts txna ApplicationArgs 3 - // tests/artifacts/Arc4ABIMethod/contract.py:71 + // tests/artifacts/Arc4ABIMethod/contract.py:75 // @arc4.abimethod callsub with_acc int 1 return main_complex_sig_route@8: - // tests/artifacts/Arc4ABIMethod/contract.py:79 + // tests/artifacts/Arc4ABIMethod/contract.py:83 // @arc4.abimethod txn OnCompletion ! @@ -171,7 +172,7 @@ main_complex_sig_route@8: btoi txnas Accounts txna ApplicationArgs 3 - // tests/artifacts/Arc4ABIMethod/contract.py:79 + // tests/artifacts/Arc4ABIMethod/contract.py:83 // @arc4.abimethod callsub complex_sig swap @@ -210,39 +211,48 @@ create: == assert // transaction type is appl // tests/artifacts/Arc4ABIMethod/contract.py:29 - // assert op.Global.current_application_id == 0 + // assert op.Global.current_application_id != 0, "expected global to have app id" global CurrentApplicationID - ! - assert + assert // expected global to have app id + // tests/artifacts/Arc4ABIMethod/contract.py:31 + // op.Global.current_application_address != op.Global.zero_address + global CurrentApplicationAddress + global ZeroAddress + != + // tests/artifacts/Arc4ABIMethod/contract.py:30-32 + // assert ( + // op.Global.current_application_address != op.Global.zero_address + // ), "expected global to have app address" + assert // expected global to have app address // tests/artifacts/Arc4ABIMethod/contract.py:28 // app_txn = gtxn.ApplicationCallTransaction(0) int 0 - // tests/artifacts/Arc4ABIMethod/contract.py:30 - // assert app_txn.app_id == 0 + // tests/artifacts/Arc4ABIMethod/contract.py:33 + // assert app_txn.app_id == 0, "expected txn to have 0" gtxns ApplicationID ! - assert - // tests/artifacts/Arc4ABIMethod/contract.py:31 - // assert Txn.application_id == 0 + assert // expected txn to have 0 + // tests/artifacts/Arc4ABIMethod/contract.py:34 + // assert Txn.application_id == 0, "expected txn to have 0" txn ApplicationID ! - assert + assert // expected txn to have 0 retsub // tests.artifacts.Arc4ABIMethod.contract.SignaturesContract.sink(value: bytes, arr: bytes) -> void: sink: - // tests/artifacts/Arc4ABIMethod/contract.py:33-34 + // tests/artifacts/Arc4ABIMethod/contract.py:36-37 // @arc4.abimethod // def sink(self, value: arc4.String, arr: UInt8Array) -> None: proto 2 0 - // tests/artifacts/Arc4ABIMethod/contract.py:35 + // tests/artifacts/Arc4ABIMethod/contract.py:38 // assert value frame_dig -2 byte 0x0000 != assert - // tests/artifacts/Arc4ABIMethod/contract.py:36 + // tests/artifacts/Arc4ABIMethod/contract.py:39 // assert arr frame_dig -1 byte 0x0000 @@ -253,17 +263,17 @@ sink: // tests.artifacts.Arc4ABIMethod.contract.SignaturesContract.sink2(value: bytes, arr: bytes) -> void: sink2: - // tests/artifacts/Arc4ABIMethod/contract.py:38-39 + // tests/artifacts/Arc4ABIMethod/contract.py:41-42 // @arc4.abimethod(name="alias") // def sink2(self, value: arc4.String, arr: UInt8Array) -> None: proto 2 0 - // tests/artifacts/Arc4ABIMethod/contract.py:40 + // tests/artifacts/Arc4ABIMethod/contract.py:43 // assert value frame_dig -2 byte 0x0000 != assert - // tests/artifacts/Arc4ABIMethod/contract.py:41 + // tests/artifacts/Arc4ABIMethod/contract.py:44 // assert arr frame_dig -1 byte 0x0000 @@ -272,42 +282,40 @@ sink2: retsub -// tests.artifacts.Arc4ABIMethod.contract.SignaturesContract.with_txn(value: bytes, acfg: uint64, arr: bytes) -> void: +// tests.artifacts.Arc4ABIMethod.contract.SignaturesContract.with_txn(value: bytes, pay: uint64, arr: bytes) -> void: with_txn: - // tests/artifacts/Arc4ABIMethod/contract.py:43-46 + // tests/artifacts/Arc4ABIMethod/contract.py:46-47 // @arc4.abimethod - // def with_txn( - // self, value: arc4.String, acfg: gtxn.AssetConfigTransaction, arr: UInt8Array - // ) -> None: + // def with_txn(self, value: arc4.String, pay: gtxn.PaymentTransaction, arr: UInt8Array) -> None: proto 3 0 - // tests/artifacts/Arc4ABIMethod/contract.py:47 + // tests/artifacts/Arc4ABIMethod/contract.py:48 // assert value frame_dig -3 byte 0x0000 != assert - // tests/artifacts/Arc4ABIMethod/contract.py:48 + // tests/artifacts/Arc4ABIMethod/contract.py:49 // assert arr frame_dig -1 byte 0x0000 != assert - // tests/artifacts/Arc4ABIMethod/contract.py:49 - // assert acfg.group_index == 0 + // tests/artifacts/Arc4ABIMethod/contract.py:50 + // assert pay.group_index == 0 frame_dig -2 gtxns GroupIndex ! assert - // tests/artifacts/Arc4ABIMethod/contract.py:50 + // tests/artifacts/Arc4ABIMethod/contract.py:51 // assert Txn.group_index == 1 txn GroupIndex int 1 == assert - // tests/artifacts/Arc4ABIMethod/contract.py:51 - // assert acfg.total == 123 + // tests/artifacts/Arc4ABIMethod/contract.py:52 + // assert pay.amount == 123 frame_dig -2 - gtxns ConfigAssetTotal + gtxns Amount int 123 == assert @@ -316,23 +324,23 @@ with_txn: // tests.artifacts.Arc4ABIMethod.contract.SignaturesContract.with_asset(value: bytes, asset: uint64, arr: bytes) -> void: with_asset: - // tests/artifacts/Arc4ABIMethod/contract.py:53-54 + // tests/artifacts/Arc4ABIMethod/contract.py:54-55 // @arc4.abimethod // def with_asset(self, value: arc4.String, asset: Asset, arr: UInt8Array) -> None: proto 3 0 - // tests/artifacts/Arc4ABIMethod/contract.py:55 + // tests/artifacts/Arc4ABIMethod/contract.py:56 // assert value frame_dig -3 byte 0x0000 != assert - // tests/artifacts/Arc4ABIMethod/contract.py:56 + // tests/artifacts/Arc4ABIMethod/contract.py:57 // assert arr frame_dig -1 byte 0x0000 != assert - // tests/artifacts/Arc4ABIMethod/contract.py:57 + // tests/artifacts/Arc4ABIMethod/contract.py:58 // assert asset.total == 123 frame_dig -2 asset_params_get AssetTotal @@ -340,7 +348,7 @@ with_asset: int 123 == assert - // tests/artifacts/Arc4ABIMethod/contract.py:58 + // tests/artifacts/Arc4ABIMethod/contract.py:59 // assert Txn.assets(0) == asset txna Assets 0 frame_dig -2 @@ -349,31 +357,42 @@ with_asset: retsub -// tests.artifacts.Arc4ABIMethod.contract.SignaturesContract.with_app(value: bytes, app: uint64, arr: bytes) -> void: +// tests.artifacts.Arc4ABIMethod.contract.SignaturesContract.with_app(value: bytes, app: uint64, app_id: bytes, arr: bytes) -> void: with_app: - // tests/artifacts/Arc4ABIMethod/contract.py:60-61 + // tests/artifacts/Arc4ABIMethod/contract.py:61-64 // @arc4.abimethod - // def with_app(self, value: arc4.String, app: Application, arr: UInt8Array) -> None: - proto 3 0 - // tests/artifacts/Arc4ABIMethod/contract.py:62 + // def with_app( + // self, value: arc4.String, app: Application, app_id: arc4.UInt64, arr: UInt8Array + // ) -> None: + proto 4 0 + // tests/artifacts/Arc4ABIMethod/contract.py:65 // assert value - frame_dig -3 + frame_dig -4 byte 0x0000 != assert - // tests/artifacts/Arc4ABIMethod/contract.py:63 + // tests/artifacts/Arc4ABIMethod/contract.py:66 // assert arr frame_dig -1 byte 0x0000 != assert - // tests/artifacts/Arc4ABIMethod/contract.py:64 - // assert app.id == 1234 + // tests/artifacts/Arc4ABIMethod/contract.py:67 + // assert app.id == app_id, "expected app id to match provided app id" + frame_dig -3 + itob frame_dig -2 - int 1234 + b== + assert // expected app id to match provided app id + // tests/artifacts/Arc4ABIMethod/contract.py:68 + // assert app.creator == op.Global.creator_address, "expected other app to have same creator" + frame_dig -3 + app_params_get AppCreator + assert // application exists + global CreatorAddress == - assert - // tests/artifacts/Arc4ABIMethod/contract.py:65 + assert // expected other app to have same creator + // tests/artifacts/Arc4ABIMethod/contract.py:69 // app_txn = gtxn.ApplicationCallTransaction(0) int 0 gtxns TypeEnum @@ -381,33 +400,33 @@ with_app: == assert // transaction type is appl int 0 - // tests/artifacts/Arc4ABIMethod/contract.py:66 + // tests/artifacts/Arc4ABIMethod/contract.py:70 // assert app_txn.apps(0) == op.Global.current_application_id dup gtxnsas Applications global CurrentApplicationID == assert - // tests/artifacts/Arc4ABIMethod/contract.py:67 + // tests/artifacts/Arc4ABIMethod/contract.py:71 // assert Txn.applications(0) == op.Global.current_application_id txna Applications 0 global CurrentApplicationID == assert - // tests/artifacts/Arc4ABIMethod/contract.py:65 + // tests/artifacts/Arc4ABIMethod/contract.py:69 // app_txn = gtxn.ApplicationCallTransaction(0) int 0 - // tests/artifacts/Arc4ABIMethod/contract.py:68 + // tests/artifacts/Arc4ABIMethod/contract.py:72 // assert app_txn.apps(1) == app int 1 gtxnsas Applications - frame_dig -2 + frame_dig -3 == assert - // tests/artifacts/Arc4ABIMethod/contract.py:69 + // tests/artifacts/Arc4ABIMethod/contract.py:73 // assert Txn.applications(1) == app txna Applications 1 - frame_dig -2 + frame_dig -3 == assert retsub @@ -415,37 +434,41 @@ with_app: // tests.artifacts.Arc4ABIMethod.contract.SignaturesContract.with_acc(value: bytes, acc: bytes, arr: bytes) -> void: with_acc: - // tests/artifacts/Arc4ABIMethod/contract.py:71-72 + // tests/artifacts/Arc4ABIMethod/contract.py:75-76 // @arc4.abimethod // def with_acc(self, value: arc4.String, acc: Account, arr: UInt8Array) -> None: proto 3 0 - // tests/artifacts/Arc4ABIMethod/contract.py:73 + // tests/artifacts/Arc4ABIMethod/contract.py:77 // assert value frame_dig -3 byte 0x0000 != assert - // tests/artifacts/Arc4ABIMethod/contract.py:74 + // tests/artifacts/Arc4ABIMethod/contract.py:78 // assert arr frame_dig -1 byte 0x0000 != assert - // tests/artifacts/Arc4ABIMethod/contract.py:75 - // assert acc.total_apps_created == 123 + // tests/artifacts/Arc4ABIMethod/contract.py:79 + // assert acc.balance == acc.min_balance + 1234 frame_dig -2 - acct_params_get AcctTotalAppsCreated + acct_params_get AcctBalance assert // account funded - int 123 + frame_dig -2 + acct_params_get AcctMinBalance + assert // account funded + int 1234 + + == assert - // tests/artifacts/Arc4ABIMethod/contract.py:76 + // tests/artifacts/Arc4ABIMethod/contract.py:80 // assert Txn.accounts(0) == Txn.sender txna Accounts 0 txn Sender == assert - // tests/artifacts/Arc4ABIMethod/contract.py:77 + // tests/artifacts/Arc4ABIMethod/contract.py:81 // assert Txn.accounts(1) == acc txna Accounts 1 frame_dig -2 @@ -456,19 +479,19 @@ with_acc: // tests.artifacts.Arc4ABIMethod.contract.SignaturesContract.complex_sig(struct1: bytes, txn: uint64, acc: bytes, five: bytes) -> bytes, bytes: complex_sig: - // tests/artifacts/Arc4ABIMethod/contract.py:79-82 + // tests/artifacts/Arc4ABIMethod/contract.py:83-86 // @arc4.abimethod // def complex_sig( // self, struct1: MyStruct, txn: algopy.gtxn.Transaction, acc: Account, five: UInt8Array // ) -> tuple[MyStructAlias, MyStruct]: proto 4 2 - // tests/artifacts/Arc4ABIMethod/contract.py:83 + // tests/artifacts/Arc4ABIMethod/contract.py:87 // assert Txn.num_app_args == 4 txn NumAppArgs int 4 == assert - // tests/artifacts/Arc4ABIMethod/contract.py:84-85 + // tests/artifacts/Arc4ABIMethod/contract.py:88-89 // # struct // assert struct1.another_struct.one == 1 frame_dig -4 @@ -486,7 +509,7 @@ complex_sig: byte 0x0000000000000001 b== assert - // tests/artifacts/Arc4ABIMethod/contract.py:86 + // tests/artifacts/Arc4ABIMethod/contract.py:90 // assert struct1.another_struct.two == "2" dup int 8 @@ -502,7 +525,7 @@ complex_sig: byte 0x000132 == assert - // tests/artifacts/Arc4ABIMethod/contract.py:87 + // tests/artifacts/Arc4ABIMethod/contract.py:91 // assert struct1.another_struct_alias.one == 1 frame_dig -4 len @@ -515,7 +538,7 @@ complex_sig: byte 0x0000000000000001 b== assert - // tests/artifacts/Arc4ABIMethod/contract.py:88 + // tests/artifacts/Arc4ABIMethod/contract.py:92 // assert struct1.another_struct_alias.two == "2" dup int 8 @@ -529,21 +552,21 @@ complex_sig: byte 0x000132 == assert - // tests/artifacts/Arc4ABIMethod/contract.py:89 + // tests/artifacts/Arc4ABIMethod/contract.py:93 // assert struct1.three == 3 frame_dig -4 extract 4 16 // on error: Index access is out of bounds byte 0x00000000000000000000000000000003 b== assert - // tests/artifacts/Arc4ABIMethod/contract.py:90 + // tests/artifacts/Arc4ABIMethod/contract.py:94 // assert struct1.four == 4 frame_dig -4 extract 20 16 // on error: Index access is out of bounds byte 0x00000000000000000000000000000004 b== assert - // tests/artifacts/Arc4ABIMethod/contract.py:92-93 + // tests/artifacts/Arc4ABIMethod/contract.py:96-97 // # txn // assert txn.group_index == Txn.group_index - 1 frame_dig -3 @@ -553,22 +576,26 @@ complex_sig: - == assert - // tests/artifacts/Arc4ABIMethod/contract.py:95-96 + // tests/artifacts/Arc4ABIMethod/contract.py:99-100 // # acc // assert Txn.application_args(2) == arc4.UInt8(1).bytes # acc array ref txna ApplicationArgs 2 byte 0x01 == assert - // tests/artifacts/Arc4ABIMethod/contract.py:97 - // assert acc.balance == 123 + // tests/artifacts/Arc4ABIMethod/contract.py:101 + // assert acc.balance == acc.min_balance + 1234 frame_dig -2 acct_params_get AcctBalance assert // account funded - int 123 + frame_dig -2 + acct_params_get AcctMinBalance + assert // account funded + int 1234 + + == assert - // tests/artifacts/Arc4ABIMethod/contract.py:98 + // tests/artifacts/Arc4ABIMethod/contract.py:102 // assert five[0] == 5 frame_dig -1 extract 2 0 @@ -576,7 +603,7 @@ complex_sig: byte 0x05 b== assert - // tests/artifacts/Arc4ABIMethod/contract.py:100 + // tests/artifacts/Arc4ABIMethod/contract.py:104 // return struct1.another_struct.copy(), struct1.copy() frame_dig -4 retsub diff --git a/tests/artifacts/Arc4ABIMethod/data/SignaturesContract.arc32.json b/tests/artifacts/Arc4ABIMethod/data/SignaturesContract.arc32.json index c946f10..e0a7cd9 100644 --- a/tests/artifacts/Arc4ABIMethod/data/SignaturesContract.arc32.json +++ b/tests/artifacts/Arc4ABIMethod/data/SignaturesContract.arc32.json @@ -15,7 +15,7 @@ "no_op": "CALL" } }, - "with_txn(string,acfg,uint8[])void": { + "with_txn(string,pay,uint8[])void": { "call_config": { "no_op": "CALL" } @@ -25,7 +25,7 @@ "no_op": "CALL" } }, - "with_app(string,application,uint8[])void": { + "with_app(string,application,uint64,uint8[])void": { "call_config": { "no_op": "CALL" } @@ -65,7 +65,7 @@ } }, "source": { - "approval": "I3ByYWdtYSB2ZXJzaW9uIDEwCgp0ZXN0cy5hcnRpZmFjdHMuQXJjNEFCSU1ldGhvZC5jb250cmFjdC5TaWduYXR1cmVzQ29udHJhY3QuYXBwcm92YWxfcHJvZ3JhbToKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9BcmM0QUJJTWV0aG9kL2NvbnRyYWN0LnB5OjI1CiAgICAvLyBjbGFzcyBTaWduYXR1cmVzQ29udHJhY3QoQVJDNENvbnRyYWN0KToKICAgIG1ldGhvZCAiY3JlYXRlKCl2b2lkIgogICAgbWV0aG9kICJzaW5rKHN0cmluZyx1aW50OFtdKXZvaWQiCiAgICBtZXRob2QgImFsaWFzKHN0cmluZyx1aW50OFtdKXZvaWQiCiAgICBtZXRob2QgIndpdGhfdHhuKHN0cmluZyxhY2ZnLHVpbnQ4W10pdm9pZCIKICAgIG1ldGhvZCAid2l0aF9hc3NldChzdHJpbmcsYXNzZXQsdWludDhbXSl2b2lkIgogICAgbWV0aG9kICJ3aXRoX2FwcChzdHJpbmcsYXBwbGljYXRpb24sdWludDhbXSl2b2lkIgogICAgbWV0aG9kICJ3aXRoX2FjYyhzdHJpbmcsYWNjb3VudCx1aW50OFtdKXZvaWQiCiAgICBtZXRob2QgImNvbXBsZXhfc2lnKCgodWludDY0LHN0cmluZyksKHVpbnQ2NCxzdHJpbmcpLHVpbnQxMjgsdWludDEyOCksdHhuLGFjY291bnQsdWludDhbXSkoKHVpbnQ2NCxzdHJpbmcpLCgodWludDY0LHN0cmluZyksKHVpbnQ2NCxzdHJpbmcpLHVpbnQxMjgsdWludDEyOCkpIgogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMAogICAgbWF0Y2ggbWFpbl9jcmVhdGVfcm91dGVAMSBtYWluX3Npbmtfcm91dGVAMiBtYWluX2FsaWFzX3JvdXRlQDMgbWFpbl93aXRoX3R4bl9yb3V0ZUA0IG1haW5fd2l0aF9hc3NldF9yb3V0ZUA1IG1haW5fd2l0aF9hcHBfcm91dGVANiBtYWluX3dpdGhfYWNjX3JvdXRlQDcgbWFpbl9jb21wbGV4X3NpZ19yb3V0ZUA4CiAgICBlcnIgLy8gcmVqZWN0IHRyYW5zYWN0aW9uCgptYWluX2NyZWF0ZV9yb3V0ZUAxOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL0FyYzRBQklNZXRob2QvY29udHJhY3QucHk6MjYKICAgIC8vIEBhcmM0LmFiaW1ldGhvZChjcmVhdGU9InJlcXVpcmUiKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgIQogICAgYXNzZXJ0IC8vIGlzIGNyZWF0aW5nCiAgICBjYWxsc3ViIGNyZWF0ZQogICAgaW50IDEKICAgIHJldHVybgoKbWFpbl9zaW5rX3JvdXRlQDI6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvQXJjNEFCSU1ldGhvZC9jb250cmFjdC5weTozMwogICAgLy8gQGFyYzQuYWJpbWV0aG9kCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gaXMgbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvQXJjNEFCSU1ldGhvZC9jb250cmFjdC5weToyNQogICAgLy8gY2xhc3MgU2lnbmF0dXJlc0NvbnRyYWN0KEFSQzRDb250cmFjdCk6CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAyCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvQXJjNEFCSU1ldGhvZC9jb250cmFjdC5weTozMwogICAgLy8gQGFyYzQuYWJpbWV0aG9kCiAgICBjYWxsc3ViIHNpbmsKICAgIGludCAxCiAgICByZXR1cm4KCm1haW5fYWxpYXNfcm91dGVAMzoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9BcmM0QUJJTWV0aG9kL2NvbnRyYWN0LnB5OjM4CiAgICAvLyBAYXJjNC5hYmltZXRob2QobmFtZT0iYWxpYXMiKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGlzIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL0FyYzRBQklNZXRob2QvY29udHJhY3QucHk6MjUKICAgIC8vIGNsYXNzIFNpZ25hdHVyZXNDb250cmFjdChBUkM0Q29udHJhY3QpOgogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL0FyYzRBQklNZXRob2QvY29udHJhY3QucHk6MzgKICAgIC8vIEBhcmM0LmFiaW1ldGhvZChuYW1lPSJhbGlhcyIpCiAgICBjYWxsc3ViIHNpbmsyCiAgICBpbnQgMQogICAgcmV0dXJuCgptYWluX3dpdGhfdHhuX3JvdXRlQDQ6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvQXJjNEFCSU1ldGhvZC9jb250cmFjdC5weTo0MwogICAgLy8gQGFyYzQuYWJpbWV0aG9kCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gaXMgbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvQXJjNEFCSU1ldGhvZC9jb250cmFjdC5weToyNQogICAgLy8gY2xhc3MgU2lnbmF0dXJlc0NvbnRyYWN0KEFSQzRDb250cmFjdCk6CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICB0eG4gR3JvdXBJbmRleAogICAgaW50IDEKICAgIC0KICAgIGR1cAogICAgZ3R4bnMgVHlwZUVudW0KICAgIGludCBhY2ZnCiAgICA9PQogICAgYXNzZXJ0IC8vIHRyYW5zYWN0aW9uIHR5cGUgaXMgYWNmZwogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL0FyYzRBQklNZXRob2QvY29udHJhY3QucHk6NDMKICAgIC8vIEBhcmM0LmFiaW1ldGhvZAogICAgY2FsbHN1YiB3aXRoX3R4bgogICAgaW50IDEKICAgIHJldHVybgoKbWFpbl93aXRoX2Fzc2V0X3JvdXRlQDU6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvQXJjNEFCSU1ldGhvZC9jb250cmFjdC5weTo1MwogICAgLy8gQGFyYzQuYWJpbWV0aG9kCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gaXMgbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvQXJjNEFCSU1ldGhvZC9jb250cmFjdC5weToyNQogICAgLy8gY2xhc3MgU2lnbmF0dXJlc0NvbnRyYWN0KEFSQzRDb250cmFjdCk6CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAyCiAgICBidG9pCiAgICB0eG5hcyBBc3NldHMKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDMKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9BcmM0QUJJTWV0aG9kL2NvbnRyYWN0LnB5OjUzCiAgICAvLyBAYXJjNC5hYmltZXRob2QKICAgIGNhbGxzdWIgd2l0aF9hc3NldAogICAgaW50IDEKICAgIHJldHVybgoKbWFpbl93aXRoX2FwcF9yb3V0ZUA2OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL0FyYzRBQklNZXRob2QvY29udHJhY3QucHk6NjAKICAgIC8vIEBhcmM0LmFiaW1ldGhvZAogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGlzIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL0FyYzRBQklNZXRob2QvY29udHJhY3QucHk6MjUKICAgIC8vIGNsYXNzIFNpZ25hdHVyZXNDb250cmFjdChBUkM0Q29udHJhY3QpOgogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMgogICAgYnRvaQogICAgdHhuYXMgQXBwbGljYXRpb25zCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAzCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvQXJjNEFCSU1ldGhvZC9jb250cmFjdC5weTo2MAogICAgLy8gQGFyYzQuYWJpbWV0aG9kCiAgICBjYWxsc3ViIHdpdGhfYXBwCiAgICBpbnQgMQogICAgcmV0dXJuCgptYWluX3dpdGhfYWNjX3JvdXRlQDc6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvQXJjNEFCSU1ldGhvZC9jb250cmFjdC5weTo3MQogICAgLy8gQGFyYzQuYWJpbWV0aG9kCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gaXMgbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvQXJjNEFCSU1ldGhvZC9jb250cmFjdC5weToyNQogICAgLy8gY2xhc3MgU2lnbmF0dXJlc0NvbnRyYWN0KEFSQzRDb250cmFjdCk6CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAyCiAgICBidG9pCiAgICB0eG5hcyBBY2NvdW50cwogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL0FyYzRBQklNZXRob2QvY29udHJhY3QucHk6NzEKICAgIC8vIEBhcmM0LmFiaW1ldGhvZAogICAgY2FsbHN1YiB3aXRoX2FjYwogICAgaW50IDEKICAgIHJldHVybgoKbWFpbl9jb21wbGV4X3NpZ19yb3V0ZUA4OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL0FyYzRBQklNZXRob2QvY29udHJhY3QucHk6NzkKICAgIC8vIEBhcmM0LmFiaW1ldGhvZAogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGlzIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL0FyYzRBQklNZXRob2QvY29udHJhY3QucHk6MjUKICAgIC8vIGNsYXNzIFNpZ25hdHVyZXNDb250cmFjdChBUkM0Q29udHJhY3QpOgogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgdHhuIEdyb3VwSW5kZXgKICAgIGludCAxCiAgICAtCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAyCiAgICBidG9pCiAgICB0eG5hcyBBY2NvdW50cwogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL0FyYzRBQklNZXRob2QvY29udHJhY3QucHk6NzkKICAgIC8vIEBhcmM0LmFiaW1ldGhvZAogICAgY2FsbHN1YiBjb21wbGV4X3NpZwogICAgc3dhcAogICAgZHVwCiAgICBsZW4KICAgIGludCA0CiAgICArCiAgICBpdG9iCiAgICBleHRyYWN0IDYgMgogICAgYnl0ZSAweDAwMDQKICAgIHN3YXAKICAgIGNvbmNhdAogICAgc3dhcAogICAgY29uY2F0CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGJ5dGUgMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludCAxCiAgICByZXR1cm4KCgovLyB0ZXN0cy5hcnRpZmFjdHMuQXJjNEFCSU1ldGhvZC5jb250cmFjdC5TaWduYXR1cmVzQ29udHJhY3QuY3JlYXRlKCkgLT4gdm9pZDoKY3JlYXRlOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL0FyYzRBQklNZXRob2QvY29udHJhY3QucHk6MjYtMjcKICAgIC8vIEBhcmM0LmFiaW1ldGhvZChjcmVhdGU9InJlcXVpcmUiKQogICAgLy8gZGVmIGNyZWF0ZShzZWxmKSAtPiBOb25lOgogICAgcHJvdG8gMCAwCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvQXJjNEFCSU1ldGhvZC9jb250cmFjdC5weToyOAogICAgLy8gYXBwX3R4biA9IGd0eG4uQXBwbGljYXRpb25DYWxsVHJhbnNhY3Rpb24oMCkKICAgIGludCAwCiAgICBndHhucyBUeXBlRW51bQogICAgaW50IGFwcGwKICAgID09CiAgICBhc3NlcnQgLy8gdHJhbnNhY3Rpb24gdHlwZSBpcyBhcHBsCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvQXJjNEFCSU1ldGhvZC9jb250cmFjdC5weToyOQogICAgLy8gYXNzZXJ0IG9wLkdsb2JhbC5jdXJyZW50X2FwcGxpY2F0aW9uX2lkID09IDAKICAgIGdsb2JhbCBDdXJyZW50QXBwbGljYXRpb25JRAogICAgIQogICAgYXNzZXJ0CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvQXJjNEFCSU1ldGhvZC9jb250cmFjdC5weToyOAogICAgLy8gYXBwX3R4biA9IGd0eG4uQXBwbGljYXRpb25DYWxsVHJhbnNhY3Rpb24oMCkKICAgIGludCAwCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvQXJjNEFCSU1ldGhvZC9jb250cmFjdC5weTozMAogICAgLy8gYXNzZXJ0IGFwcF90eG4uYXBwX2lkID09IDAKICAgIGd0eG5zIEFwcGxpY2F0aW9uSUQKICAgICEKICAgIGFzc2VydAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL0FyYzRBQklNZXRob2QvY29udHJhY3QucHk6MzEKICAgIC8vIGFzc2VydCBUeG4uYXBwbGljYXRpb25faWQgPT0gMAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgICEKICAgIGFzc2VydAogICAgcmV0c3ViCgoKLy8gdGVzdHMuYXJ0aWZhY3RzLkFyYzRBQklNZXRob2QuY29udHJhY3QuU2lnbmF0dXJlc0NvbnRyYWN0LnNpbmsodmFsdWU6IGJ5dGVzLCBhcnI6IGJ5dGVzKSAtPiB2b2lkOgpzaW5rOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL0FyYzRBQklNZXRob2QvY29udHJhY3QucHk6MzMtMzQKICAgIC8vIEBhcmM0LmFiaW1ldGhvZAogICAgLy8gZGVmIHNpbmsoc2VsZiwgdmFsdWU6IGFyYzQuU3RyaW5nLCBhcnI6IFVJbnQ4QXJyYXkpIC0+IE5vbmU6CiAgICBwcm90byAyIDAKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9BcmM0QUJJTWV0aG9kL2NvbnRyYWN0LnB5OjM1CiAgICAvLyBhc3NlcnQgdmFsdWUKICAgIGZyYW1lX2RpZyAtMgogICAgYnl0ZSAweDAwMDAKICAgICE9CiAgICBhc3NlcnQKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9BcmM0QUJJTWV0aG9kL2NvbnRyYWN0LnB5OjM2CiAgICAvLyBhc3NlcnQgYXJyCiAgICBmcmFtZV9kaWcgLTEKICAgIGJ5dGUgMHgwMDAwCiAgICAhPQogICAgYXNzZXJ0CiAgICByZXRzdWIKCgovLyB0ZXN0cy5hcnRpZmFjdHMuQXJjNEFCSU1ldGhvZC5jb250cmFjdC5TaWduYXR1cmVzQ29udHJhY3Quc2luazIodmFsdWU6IGJ5dGVzLCBhcnI6IGJ5dGVzKSAtPiB2b2lkOgpzaW5rMjoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9BcmM0QUJJTWV0aG9kL2NvbnRyYWN0LnB5OjM4LTM5CiAgICAvLyBAYXJjNC5hYmltZXRob2QobmFtZT0iYWxpYXMiKQogICAgLy8gZGVmIHNpbmsyKHNlbGYsIHZhbHVlOiBhcmM0LlN0cmluZywgYXJyOiBVSW50OEFycmF5KSAtPiBOb25lOgogICAgcHJvdG8gMiAwCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvQXJjNEFCSU1ldGhvZC9jb250cmFjdC5weTo0MAogICAgLy8gYXNzZXJ0IHZhbHVlCiAgICBmcmFtZV9kaWcgLTIKICAgIGJ5dGUgMHgwMDAwCiAgICAhPQogICAgYXNzZXJ0CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvQXJjNEFCSU1ldGhvZC9jb250cmFjdC5weTo0MQogICAgLy8gYXNzZXJ0IGFycgogICAgZnJhbWVfZGlnIC0xCiAgICBieXRlIDB4MDAwMAogICAgIT0KICAgIGFzc2VydAogICAgcmV0c3ViCgoKLy8gdGVzdHMuYXJ0aWZhY3RzLkFyYzRBQklNZXRob2QuY29udHJhY3QuU2lnbmF0dXJlc0NvbnRyYWN0LndpdGhfdHhuKHZhbHVlOiBieXRlcywgYWNmZzogdWludDY0LCBhcnI6IGJ5dGVzKSAtPiB2b2lkOgp3aXRoX3R4bjoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9BcmM0QUJJTWV0aG9kL2NvbnRyYWN0LnB5OjQzLTQ2CiAgICAvLyBAYXJjNC5hYmltZXRob2QKICAgIC8vIGRlZiB3aXRoX3R4bigKICAgIC8vICAgICBzZWxmLCB2YWx1ZTogYXJjNC5TdHJpbmcsIGFjZmc6IGd0eG4uQXNzZXRDb25maWdUcmFuc2FjdGlvbiwgYXJyOiBVSW50OEFycmF5CiAgICAvLyApIC0+IE5vbmU6CiAgICBwcm90byAzIDAKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9BcmM0QUJJTWV0aG9kL2NvbnRyYWN0LnB5OjQ3CiAgICAvLyBhc3NlcnQgdmFsdWUKICAgIGZyYW1lX2RpZyAtMwogICAgYnl0ZSAweDAwMDAKICAgICE9CiAgICBhc3NlcnQKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9BcmM0QUJJTWV0aG9kL2NvbnRyYWN0LnB5OjQ4CiAgICAvLyBhc3NlcnQgYXJyCiAgICBmcmFtZV9kaWcgLTEKICAgIGJ5dGUgMHgwMDAwCiAgICAhPQogICAgYXNzZXJ0CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvQXJjNEFCSU1ldGhvZC9jb250cmFjdC5weTo0OQogICAgLy8gYXNzZXJ0IGFjZmcuZ3JvdXBfaW5kZXggPT0gMAogICAgZnJhbWVfZGlnIC0yCiAgICBndHhucyBHcm91cEluZGV4CiAgICAhCiAgICBhc3NlcnQKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9BcmM0QUJJTWV0aG9kL2NvbnRyYWN0LnB5OjUwCiAgICAvLyBhc3NlcnQgVHhuLmdyb3VwX2luZGV4ID09IDEKICAgIHR4biBHcm91cEluZGV4CiAgICBpbnQgMQogICAgPT0KICAgIGFzc2VydAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL0FyYzRBQklNZXRob2QvY29udHJhY3QucHk6NTEKICAgIC8vIGFzc2VydCBhY2ZnLnRvdGFsID09IDEyMwogICAgZnJhbWVfZGlnIC0yCiAgICBndHhucyBDb25maWdBc3NldFRvdGFsCiAgICBpbnQgMTIzCiAgICA9PQogICAgYXNzZXJ0CiAgICByZXRzdWIKCgovLyB0ZXN0cy5hcnRpZmFjdHMuQXJjNEFCSU1ldGhvZC5jb250cmFjdC5TaWduYXR1cmVzQ29udHJhY3Qud2l0aF9hc3NldCh2YWx1ZTogYnl0ZXMsIGFzc2V0OiB1aW50NjQsIGFycjogYnl0ZXMpIC0+IHZvaWQ6CndpdGhfYXNzZXQ6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvQXJjNEFCSU1ldGhvZC9jb250cmFjdC5weTo1My01NAogICAgLy8gQGFyYzQuYWJpbWV0aG9kCiAgICAvLyBkZWYgd2l0aF9hc3NldChzZWxmLCB2YWx1ZTogYXJjNC5TdHJpbmcsIGFzc2V0OiBBc3NldCwgYXJyOiBVSW50OEFycmF5KSAtPiBOb25lOgogICAgcHJvdG8gMyAwCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvQXJjNEFCSU1ldGhvZC9jb250cmFjdC5weTo1NQogICAgLy8gYXNzZXJ0IHZhbHVlCiAgICBmcmFtZV9kaWcgLTMKICAgIGJ5dGUgMHgwMDAwCiAgICAhPQogICAgYXNzZXJ0CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvQXJjNEFCSU1ldGhvZC9jb250cmFjdC5weTo1NgogICAgLy8gYXNzZXJ0IGFycgogICAgZnJhbWVfZGlnIC0xCiAgICBieXRlIDB4MDAwMAogICAgIT0KICAgIGFzc2VydAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL0FyYzRBQklNZXRob2QvY29udHJhY3QucHk6NTcKICAgIC8vIGFzc2VydCBhc3NldC50b3RhbCA9PSAxMjMKICAgIGZyYW1lX2RpZyAtMgogICAgYXNzZXRfcGFyYW1zX2dldCBBc3NldFRvdGFsCiAgICBhc3NlcnQgLy8gYXNzZXQgZXhpc3RzCiAgICBpbnQgMTIzCiAgICA9PQogICAgYXNzZXJ0CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvQXJjNEFCSU1ldGhvZC9jb250cmFjdC5weTo1OAogICAgLy8gYXNzZXJ0IFR4bi5hc3NldHMoMCkgPT0gYXNzZXQKICAgIHR4bmEgQXNzZXRzIDAKICAgIGZyYW1lX2RpZyAtMgogICAgPT0KICAgIGFzc2VydAogICAgcmV0c3ViCgoKLy8gdGVzdHMuYXJ0aWZhY3RzLkFyYzRBQklNZXRob2QuY29udHJhY3QuU2lnbmF0dXJlc0NvbnRyYWN0LndpdGhfYXBwKHZhbHVlOiBieXRlcywgYXBwOiB1aW50NjQsIGFycjogYnl0ZXMpIC0+IHZvaWQ6CndpdGhfYXBwOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL0FyYzRBQklNZXRob2QvY29udHJhY3QucHk6NjAtNjEKICAgIC8vIEBhcmM0LmFiaW1ldGhvZAogICAgLy8gZGVmIHdpdGhfYXBwKHNlbGYsIHZhbHVlOiBhcmM0LlN0cmluZywgYXBwOiBBcHBsaWNhdGlvbiwgYXJyOiBVSW50OEFycmF5KSAtPiBOb25lOgogICAgcHJvdG8gMyAwCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvQXJjNEFCSU1ldGhvZC9jb250cmFjdC5weTo2MgogICAgLy8gYXNzZXJ0IHZhbHVlCiAgICBmcmFtZV9kaWcgLTMKICAgIGJ5dGUgMHgwMDAwCiAgICAhPQogICAgYXNzZXJ0CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvQXJjNEFCSU1ldGhvZC9jb250cmFjdC5weTo2MwogICAgLy8gYXNzZXJ0IGFycgogICAgZnJhbWVfZGlnIC0xCiAgICBieXRlIDB4MDAwMAogICAgIT0KICAgIGFzc2VydAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL0FyYzRBQklNZXRob2QvY29udHJhY3QucHk6NjQKICAgIC8vIGFzc2VydCBhcHAuaWQgPT0gMTIzNAogICAgZnJhbWVfZGlnIC0yCiAgICBpbnQgMTIzNAogICAgPT0KICAgIGFzc2VydAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL0FyYzRBQklNZXRob2QvY29udHJhY3QucHk6NjUKICAgIC8vIGFwcF90eG4gPSBndHhuLkFwcGxpY2F0aW9uQ2FsbFRyYW5zYWN0aW9uKDApCiAgICBpbnQgMAogICAgZ3R4bnMgVHlwZUVudW0KICAgIGludCBhcHBsCiAgICA9PQogICAgYXNzZXJ0IC8vIHRyYW5zYWN0aW9uIHR5cGUgaXMgYXBwbAogICAgaW50IDAKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9BcmM0QUJJTWV0aG9kL2NvbnRyYWN0LnB5OjY2CiAgICAvLyBhc3NlcnQgYXBwX3R4bi5hcHBzKDApID09IG9wLkdsb2JhbC5jdXJyZW50X2FwcGxpY2F0aW9uX2lkCiAgICBkdXAKICAgIGd0eG5zYXMgQXBwbGljYXRpb25zCiAgICBnbG9iYWwgQ3VycmVudEFwcGxpY2F0aW9uSUQKICAgID09CiAgICBhc3NlcnQKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9BcmM0QUJJTWV0aG9kL2NvbnRyYWN0LnB5OjY3CiAgICAvLyBhc3NlcnQgVHhuLmFwcGxpY2F0aW9ucygwKSA9PSBvcC5HbG9iYWwuY3VycmVudF9hcHBsaWNhdGlvbl9pZAogICAgdHhuYSBBcHBsaWNhdGlvbnMgMAogICAgZ2xvYmFsIEN1cnJlbnRBcHBsaWNhdGlvbklECiAgICA9PQogICAgYXNzZXJ0CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvQXJjNEFCSU1ldGhvZC9jb250cmFjdC5weTo2NQogICAgLy8gYXBwX3R4biA9IGd0eG4uQXBwbGljYXRpb25DYWxsVHJhbnNhY3Rpb24oMCkKICAgIGludCAwCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvQXJjNEFCSU1ldGhvZC9jb250cmFjdC5weTo2OAogICAgLy8gYXNzZXJ0IGFwcF90eG4uYXBwcygxKSA9PSBhcHAKICAgIGludCAxCiAgICBndHhuc2FzIEFwcGxpY2F0aW9ucwogICAgZnJhbWVfZGlnIC0yCiAgICA9PQogICAgYXNzZXJ0CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvQXJjNEFCSU1ldGhvZC9jb250cmFjdC5weTo2OQogICAgLy8gYXNzZXJ0IFR4bi5hcHBsaWNhdGlvbnMoMSkgPT0gYXBwCiAgICB0eG5hIEFwcGxpY2F0aW9ucyAxCiAgICBmcmFtZV9kaWcgLTIKICAgID09CiAgICBhc3NlcnQKICAgIHJldHN1YgoKCi8vIHRlc3RzLmFydGlmYWN0cy5BcmM0QUJJTWV0aG9kLmNvbnRyYWN0LlNpZ25hdHVyZXNDb250cmFjdC53aXRoX2FjYyh2YWx1ZTogYnl0ZXMsIGFjYzogYnl0ZXMsIGFycjogYnl0ZXMpIC0+IHZvaWQ6CndpdGhfYWNjOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL0FyYzRBQklNZXRob2QvY29udHJhY3QucHk6NzEtNzIKICAgIC8vIEBhcmM0LmFiaW1ldGhvZAogICAgLy8gZGVmIHdpdGhfYWNjKHNlbGYsIHZhbHVlOiBhcmM0LlN0cmluZywgYWNjOiBBY2NvdW50LCBhcnI6IFVJbnQ4QXJyYXkpIC0+IE5vbmU6CiAgICBwcm90byAzIDAKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9BcmM0QUJJTWV0aG9kL2NvbnRyYWN0LnB5OjczCiAgICAvLyBhc3NlcnQgdmFsdWUKICAgIGZyYW1lX2RpZyAtMwogICAgYnl0ZSAweDAwMDAKICAgICE9CiAgICBhc3NlcnQKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9BcmM0QUJJTWV0aG9kL2NvbnRyYWN0LnB5Ojc0CiAgICAvLyBhc3NlcnQgYXJyCiAgICBmcmFtZV9kaWcgLTEKICAgIGJ5dGUgMHgwMDAwCiAgICAhPQogICAgYXNzZXJ0CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvQXJjNEFCSU1ldGhvZC9jb250cmFjdC5weTo3NQogICAgLy8gYXNzZXJ0IGFjYy50b3RhbF9hcHBzX2NyZWF0ZWQgPT0gMTIzCiAgICBmcmFtZV9kaWcgLTIKICAgIGFjY3RfcGFyYW1zX2dldCBBY2N0VG90YWxBcHBzQ3JlYXRlZAogICAgYXNzZXJ0IC8vIGFjY291bnQgZnVuZGVkCiAgICBpbnQgMTIzCiAgICA9PQogICAgYXNzZXJ0CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvQXJjNEFCSU1ldGhvZC9jb250cmFjdC5weTo3NgogICAgLy8gYXNzZXJ0IFR4bi5hY2NvdW50cygwKSA9PSBUeG4uc2VuZGVyCiAgICB0eG5hIEFjY291bnRzIDAKICAgIHR4biBTZW5kZXIKICAgID09CiAgICBhc3NlcnQKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9BcmM0QUJJTWV0aG9kL2NvbnRyYWN0LnB5Ojc3CiAgICAvLyBhc3NlcnQgVHhuLmFjY291bnRzKDEpID09IGFjYwogICAgdHhuYSBBY2NvdW50cyAxCiAgICBmcmFtZV9kaWcgLTIKICAgID09CiAgICBhc3NlcnQKICAgIHJldHN1YgoKCi8vIHRlc3RzLmFydGlmYWN0cy5BcmM0QUJJTWV0aG9kLmNvbnRyYWN0LlNpZ25hdHVyZXNDb250cmFjdC5jb21wbGV4X3NpZyhzdHJ1Y3QxOiBieXRlcywgdHhuOiB1aW50NjQsIGFjYzogYnl0ZXMsIGZpdmU6IGJ5dGVzKSAtPiBieXRlcywgYnl0ZXM6CmNvbXBsZXhfc2lnOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL0FyYzRBQklNZXRob2QvY29udHJhY3QucHk6NzktODIKICAgIC8vIEBhcmM0LmFiaW1ldGhvZAogICAgLy8gZGVmIGNvbXBsZXhfc2lnKAogICAgLy8gICAgIHNlbGYsIHN0cnVjdDE6IE15U3RydWN0LCB0eG46IGFsZ29weS5ndHhuLlRyYW5zYWN0aW9uLCBhY2M6IEFjY291bnQsIGZpdmU6IFVJbnQ4QXJyYXkKICAgIC8vICkgLT4gdHVwbGVbTXlTdHJ1Y3RBbGlhcywgTXlTdHJ1Y3RdOgogICAgcHJvdG8gNCAyCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvQXJjNEFCSU1ldGhvZC9jb250cmFjdC5weTo4MwogICAgLy8gYXNzZXJ0IFR4bi5udW1fYXBwX2FyZ3MgPT0gNAogICAgdHhuIE51bUFwcEFyZ3MKICAgIGludCA0CiAgICA9PQogICAgYXNzZXJ0CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvQXJjNEFCSU1ldGhvZC9jb250cmFjdC5weTo4NC04NQogICAgLy8gIyBzdHJ1Y3QKICAgIC8vIGFzc2VydCBzdHJ1Y3QxLmFub3RoZXJfc3RydWN0Lm9uZSA9PSAxCiAgICBmcmFtZV9kaWcgLTQKICAgIGludCAwCiAgICBleHRyYWN0X3VpbnQxNgogICAgZnJhbWVfZGlnIC00CiAgICBpbnQgMgogICAgZXh0cmFjdF91aW50MTYKICAgIGZyYW1lX2RpZyAtNAogICAgdW5jb3ZlciAyCiAgICBkaWcgMgogICAgc3Vic3RyaW5nMwogICAgZHVwCiAgICBleHRyYWN0IDAgOCAvLyBvbiBlcnJvcjogSW5kZXggYWNjZXNzIGlzIG91dCBvZiBib3VuZHMKICAgIGJ5dGUgMHgwMDAwMDAwMDAwMDAwMDAxCiAgICBiPT0KICAgIGFzc2VydAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL0FyYzRBQklNZXRob2QvY29udHJhY3QucHk6ODYKICAgIC8vIGFzc2VydCBzdHJ1Y3QxLmFub3RoZXJfc3RydWN0LnR3byA9PSAiMiIKICAgIGR1cAogICAgaW50IDgKICAgIGV4dHJhY3RfdWludDE2CiAgICBzd2FwCiAgICBkdXAKICAgIGxlbgogICAgc3dhcAogICAgZHVwCiAgICB1bmNvdmVyIDMKICAgIHVuY292ZXIgMwogICAgc3Vic3RyaW5nMwogICAgYnl0ZSAweDAwMDEzMgogICAgPT0KICAgIGFzc2VydAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL0FyYzRBQklNZXRob2QvY29udHJhY3QucHk6ODcKICAgIC8vIGFzc2VydCBzdHJ1Y3QxLmFub3RoZXJfc3RydWN0X2FsaWFzLm9uZSA9PSAxCiAgICBmcmFtZV9kaWcgLTQKICAgIGxlbgogICAgZnJhbWVfZGlnIC00CiAgICB1bmNvdmVyIDMKICAgIHVuY292ZXIgMgogICAgc3Vic3RyaW5nMwogICAgZHVwCiAgICBleHRyYWN0IDAgOCAvLyBvbiBlcnJvcjogSW5kZXggYWNjZXNzIGlzIG91dCBvZiBib3VuZHMKICAgIGJ5dGUgMHgwMDAwMDAwMDAwMDAwMDAxCiAgICBiPT0KICAgIGFzc2VydAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL0FyYzRBQklNZXRob2QvY29udHJhY3QucHk6ODgKICAgIC8vIGFzc2VydCBzdHJ1Y3QxLmFub3RoZXJfc3RydWN0X2FsaWFzLnR3byA9PSAiMiIKICAgIGR1cAogICAgaW50IDgKICAgIGV4dHJhY3RfdWludDE2CiAgICBzd2FwCiAgICBkdXAKICAgIGxlbgogICAgc3dhcAogICAgY292ZXIgMgogICAgc3Vic3RyaW5nMwogICAgYnl0ZSAweDAwMDEzMgogICAgPT0KICAgIGFzc2VydAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL0FyYzRBQklNZXRob2QvY29udHJhY3QucHk6ODkKICAgIC8vIGFzc2VydCBzdHJ1Y3QxLnRocmVlID09IDMKICAgIGZyYW1lX2RpZyAtNAogICAgZXh0cmFjdCA0IDE2IC8vIG9uIGVycm9yOiBJbmRleCBhY2Nlc3MgaXMgb3V0IG9mIGJvdW5kcwogICAgYnl0ZSAweDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAzCiAgICBiPT0KICAgIGFzc2VydAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL0FyYzRBQklNZXRob2QvY29udHJhY3QucHk6OTAKICAgIC8vIGFzc2VydCBzdHJ1Y3QxLmZvdXIgPT0gNAogICAgZnJhbWVfZGlnIC00CiAgICBleHRyYWN0IDIwIDE2IC8vIG9uIGVycm9yOiBJbmRleCBhY2Nlc3MgaXMgb3V0IG9mIGJvdW5kcwogICAgYnl0ZSAweDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDA0CiAgICBiPT0KICAgIGFzc2VydAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL0FyYzRBQklNZXRob2QvY29udHJhY3QucHk6OTItOTMKICAgIC8vICMgdHhuCiAgICAvLyBhc3NlcnQgdHhuLmdyb3VwX2luZGV4ID09IFR4bi5ncm91cF9pbmRleCAtIDEKICAgIGZyYW1lX2RpZyAtMwogICAgZ3R4bnMgR3JvdXBJbmRleAogICAgdHhuIEdyb3VwSW5kZXgKICAgIGludCAxCiAgICAtCiAgICA9PQogICAgYXNzZXJ0CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvQXJjNEFCSU1ldGhvZC9jb250cmFjdC5weTo5NS05NgogICAgLy8gIyBhY2MKICAgIC8vIGFzc2VydCBUeG4uYXBwbGljYXRpb25fYXJncygyKSA9PSBhcmM0LlVJbnQ4KDEpLmJ5dGVzICAjIGFjYyBhcnJheSByZWYKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDIKICAgIGJ5dGUgMHgwMQogICAgPT0KICAgIGFzc2VydAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL0FyYzRBQklNZXRob2QvY29udHJhY3QucHk6OTcKICAgIC8vIGFzc2VydCBhY2MuYmFsYW5jZSA9PSAxMjMKICAgIGZyYW1lX2RpZyAtMgogICAgYWNjdF9wYXJhbXNfZ2V0IEFjY3RCYWxhbmNlCiAgICBhc3NlcnQgLy8gYWNjb3VudCBmdW5kZWQKICAgIGludCAxMjMKICAgID09CiAgICBhc3NlcnQKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9BcmM0QUJJTWV0aG9kL2NvbnRyYWN0LnB5Ojk4CiAgICAvLyBhc3NlcnQgZml2ZVswXSA9PSA1CiAgICBmcmFtZV9kaWcgLTEKICAgIGV4dHJhY3QgMiAwCiAgICBleHRyYWN0IDAgMSAvLyBvbiBlcnJvcjogSW5kZXggYWNjZXNzIGlzIG91dCBvZiBib3VuZHMKICAgIGJ5dGUgMHgwNQogICAgYj09CiAgICBhc3NlcnQKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9BcmM0QUJJTWV0aG9kL2NvbnRyYWN0LnB5OjEwMAogICAgLy8gcmV0dXJuIHN0cnVjdDEuYW5vdGhlcl9zdHJ1Y3QuY29weSgpLCBzdHJ1Y3QxLmNvcHkoKQogICAgZnJhbWVfZGlnIC00CiAgICByZXRzdWIK", + "approval": "I3ByYWdtYSB2ZXJzaW9uIDEwCgp0ZXN0cy5hcnRpZmFjdHMuQXJjNEFCSU1ldGhvZC5jb250cmFjdC5TaWduYXR1cmVzQ29udHJhY3QuYXBwcm92YWxfcHJvZ3JhbToKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9BcmM0QUJJTWV0aG9kL2NvbnRyYWN0LnB5OjI1CiAgICAvLyBjbGFzcyBTaWduYXR1cmVzQ29udHJhY3QoQVJDNENvbnRyYWN0KToKICAgIG1ldGhvZCAiY3JlYXRlKCl2b2lkIgogICAgbWV0aG9kICJzaW5rKHN0cmluZyx1aW50OFtdKXZvaWQiCiAgICBtZXRob2QgImFsaWFzKHN0cmluZyx1aW50OFtdKXZvaWQiCiAgICBtZXRob2QgIndpdGhfdHhuKHN0cmluZyxwYXksdWludDhbXSl2b2lkIgogICAgbWV0aG9kICJ3aXRoX2Fzc2V0KHN0cmluZyxhc3NldCx1aW50OFtdKXZvaWQiCiAgICBtZXRob2QgIndpdGhfYXBwKHN0cmluZyxhcHBsaWNhdGlvbix1aW50NjQsdWludDhbXSl2b2lkIgogICAgbWV0aG9kICJ3aXRoX2FjYyhzdHJpbmcsYWNjb3VudCx1aW50OFtdKXZvaWQiCiAgICBtZXRob2QgImNvbXBsZXhfc2lnKCgodWludDY0LHN0cmluZyksKHVpbnQ2NCxzdHJpbmcpLHVpbnQxMjgsdWludDEyOCksdHhuLGFjY291bnQsdWludDhbXSkoKHVpbnQ2NCxzdHJpbmcpLCgodWludDY0LHN0cmluZyksKHVpbnQ2NCxzdHJpbmcpLHVpbnQxMjgsdWludDEyOCkpIgogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMAogICAgbWF0Y2ggbWFpbl9jcmVhdGVfcm91dGVAMSBtYWluX3Npbmtfcm91dGVAMiBtYWluX2FsaWFzX3JvdXRlQDMgbWFpbl93aXRoX3R4bl9yb3V0ZUA0IG1haW5fd2l0aF9hc3NldF9yb3V0ZUA1IG1haW5fd2l0aF9hcHBfcm91dGVANiBtYWluX3dpdGhfYWNjX3JvdXRlQDcgbWFpbl9jb21wbGV4X3NpZ19yb3V0ZUA4CiAgICBlcnIgLy8gcmVqZWN0IHRyYW5zYWN0aW9uCgptYWluX2NyZWF0ZV9yb3V0ZUAxOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL0FyYzRBQklNZXRob2QvY29udHJhY3QucHk6MjYKICAgIC8vIEBhcmM0LmFiaW1ldGhvZChjcmVhdGU9InJlcXVpcmUiKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgIQogICAgYXNzZXJ0IC8vIGlzIGNyZWF0aW5nCiAgICBjYWxsc3ViIGNyZWF0ZQogICAgaW50IDEKICAgIHJldHVybgoKbWFpbl9zaW5rX3JvdXRlQDI6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvQXJjNEFCSU1ldGhvZC9jb250cmFjdC5weTozNgogICAgLy8gQGFyYzQuYWJpbWV0aG9kCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gaXMgbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvQXJjNEFCSU1ldGhvZC9jb250cmFjdC5weToyNQogICAgLy8gY2xhc3MgU2lnbmF0dXJlc0NvbnRyYWN0KEFSQzRDb250cmFjdCk6CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAyCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvQXJjNEFCSU1ldGhvZC9jb250cmFjdC5weTozNgogICAgLy8gQGFyYzQuYWJpbWV0aG9kCiAgICBjYWxsc3ViIHNpbmsKICAgIGludCAxCiAgICByZXR1cm4KCm1haW5fYWxpYXNfcm91dGVAMzoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9BcmM0QUJJTWV0aG9kL2NvbnRyYWN0LnB5OjQxCiAgICAvLyBAYXJjNC5hYmltZXRob2QobmFtZT0iYWxpYXMiKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGlzIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL0FyYzRBQklNZXRob2QvY29udHJhY3QucHk6MjUKICAgIC8vIGNsYXNzIFNpZ25hdHVyZXNDb250cmFjdChBUkM0Q29udHJhY3QpOgogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL0FyYzRBQklNZXRob2QvY29udHJhY3QucHk6NDEKICAgIC8vIEBhcmM0LmFiaW1ldGhvZChuYW1lPSJhbGlhcyIpCiAgICBjYWxsc3ViIHNpbmsyCiAgICBpbnQgMQogICAgcmV0dXJuCgptYWluX3dpdGhfdHhuX3JvdXRlQDQ6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvQXJjNEFCSU1ldGhvZC9jb250cmFjdC5weTo0NgogICAgLy8gQGFyYzQuYWJpbWV0aG9kCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gaXMgbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvQXJjNEFCSU1ldGhvZC9jb250cmFjdC5weToyNQogICAgLy8gY2xhc3MgU2lnbmF0dXJlc0NvbnRyYWN0KEFSQzRDb250cmFjdCk6CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICB0eG4gR3JvdXBJbmRleAogICAgaW50IDEKICAgIC0KICAgIGR1cAogICAgZ3R4bnMgVHlwZUVudW0KICAgIGludCBwYXkKICAgID09CiAgICBhc3NlcnQgLy8gdHJhbnNhY3Rpb24gdHlwZSBpcyBwYXkKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDIKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9BcmM0QUJJTWV0aG9kL2NvbnRyYWN0LnB5OjQ2CiAgICAvLyBAYXJjNC5hYmltZXRob2QKICAgIGNhbGxzdWIgd2l0aF90eG4KICAgIGludCAxCiAgICByZXR1cm4KCm1haW5fd2l0aF9hc3NldF9yb3V0ZUA1OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL0FyYzRBQklNZXRob2QvY29udHJhY3QucHk6NTQKICAgIC8vIEBhcmM0LmFiaW1ldGhvZAogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGlzIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL0FyYzRBQklNZXRob2QvY29udHJhY3QucHk6MjUKICAgIC8vIGNsYXNzIFNpZ25hdHVyZXNDb250cmFjdChBUkM0Q29udHJhY3QpOgogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMgogICAgYnRvaQogICAgdHhuYXMgQXNzZXRzCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAzCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvQXJjNEFCSU1ldGhvZC9jb250cmFjdC5weTo1NAogICAgLy8gQGFyYzQuYWJpbWV0aG9kCiAgICBjYWxsc3ViIHdpdGhfYXNzZXQKICAgIGludCAxCiAgICByZXR1cm4KCm1haW5fd2l0aF9hcHBfcm91dGVANjoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9BcmM0QUJJTWV0aG9kL2NvbnRyYWN0LnB5OjYxCiAgICAvLyBAYXJjNC5hYmltZXRob2QKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBpcyBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9BcmM0QUJJTWV0aG9kL2NvbnRyYWN0LnB5OjI1CiAgICAvLyBjbGFzcyBTaWduYXR1cmVzQ29udHJhY3QoQVJDNENvbnRyYWN0KToKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDIKICAgIGJ0b2kKICAgIHR4bmFzIEFwcGxpY2F0aW9ucwogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMwogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgNAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL0FyYzRBQklNZXRob2QvY29udHJhY3QucHk6NjEKICAgIC8vIEBhcmM0LmFiaW1ldGhvZAogICAgY2FsbHN1YiB3aXRoX2FwcAogICAgaW50IDEKICAgIHJldHVybgoKbWFpbl93aXRoX2FjY19yb3V0ZUA3OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL0FyYzRBQklNZXRob2QvY29udHJhY3QucHk6NzUKICAgIC8vIEBhcmM0LmFiaW1ldGhvZAogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGlzIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL0FyYzRBQklNZXRob2QvY29udHJhY3QucHk6MjUKICAgIC8vIGNsYXNzIFNpZ25hdHVyZXNDb250cmFjdChBUkM0Q29udHJhY3QpOgogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMgogICAgYnRvaQogICAgdHhuYXMgQWNjb3VudHMKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDMKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9BcmM0QUJJTWV0aG9kL2NvbnRyYWN0LnB5Ojc1CiAgICAvLyBAYXJjNC5hYmltZXRob2QKICAgIGNhbGxzdWIgd2l0aF9hY2MKICAgIGludCAxCiAgICByZXR1cm4KCm1haW5fY29tcGxleF9zaWdfcm91dGVAODoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9BcmM0QUJJTWV0aG9kL2NvbnRyYWN0LnB5OjgzCiAgICAvLyBAYXJjNC5hYmltZXRob2QKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBpcyBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9BcmM0QUJJTWV0aG9kL2NvbnRyYWN0LnB5OjI1CiAgICAvLyBjbGFzcyBTaWduYXR1cmVzQ29udHJhY3QoQVJDNENvbnRyYWN0KToKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIHR4biBHcm91cEluZGV4CiAgICBpbnQgMQogICAgLQogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMgogICAgYnRvaQogICAgdHhuYXMgQWNjb3VudHMKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDMKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9BcmM0QUJJTWV0aG9kL2NvbnRyYWN0LnB5OjgzCiAgICAvLyBAYXJjNC5hYmltZXRob2QKICAgIGNhbGxzdWIgY29tcGxleF9zaWcKICAgIHN3YXAKICAgIGR1cAogICAgbGVuCiAgICBpbnQgNAogICAgKwogICAgaXRvYgogICAgZXh0cmFjdCA2IDIKICAgIGJ5dGUgMHgwMDA0CiAgICBzd2FwCiAgICBjb25jYXQKICAgIHN3YXAKICAgIGNvbmNhdAogICAgc3dhcAogICAgY29uY2F0CiAgICBieXRlIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnQgMQogICAgcmV0dXJuCgoKLy8gdGVzdHMuYXJ0aWZhY3RzLkFyYzRBQklNZXRob2QuY29udHJhY3QuU2lnbmF0dXJlc0NvbnRyYWN0LmNyZWF0ZSgpIC0+IHZvaWQ6CmNyZWF0ZToKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9BcmM0QUJJTWV0aG9kL2NvbnRyYWN0LnB5OjI2LTI3CiAgICAvLyBAYXJjNC5hYmltZXRob2QoY3JlYXRlPSJyZXF1aXJlIikKICAgIC8vIGRlZiBjcmVhdGUoc2VsZikgLT4gTm9uZToKICAgIHByb3RvIDAgMAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL0FyYzRBQklNZXRob2QvY29udHJhY3QucHk6MjgKICAgIC8vIGFwcF90eG4gPSBndHhuLkFwcGxpY2F0aW9uQ2FsbFRyYW5zYWN0aW9uKDApCiAgICBpbnQgMAogICAgZ3R4bnMgVHlwZUVudW0KICAgIGludCBhcHBsCiAgICA9PQogICAgYXNzZXJ0IC8vIHRyYW5zYWN0aW9uIHR5cGUgaXMgYXBwbAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL0FyYzRBQklNZXRob2QvY29udHJhY3QucHk6MjkKICAgIC8vIGFzc2VydCBvcC5HbG9iYWwuY3VycmVudF9hcHBsaWNhdGlvbl9pZCAhPSAwLCAiZXhwZWN0ZWQgZ2xvYmFsIHRvIGhhdmUgYXBwIGlkIgogICAgZ2xvYmFsIEN1cnJlbnRBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gZXhwZWN0ZWQgZ2xvYmFsIHRvIGhhdmUgYXBwIGlkCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvQXJjNEFCSU1ldGhvZC9jb250cmFjdC5weTozMQogICAgLy8gb3AuR2xvYmFsLmN1cnJlbnRfYXBwbGljYXRpb25fYWRkcmVzcyAhPSBvcC5HbG9iYWwuemVyb19hZGRyZXNzCiAgICBnbG9iYWwgQ3VycmVudEFwcGxpY2F0aW9uQWRkcmVzcwogICAgZ2xvYmFsIFplcm9BZGRyZXNzCiAgICAhPQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL0FyYzRBQklNZXRob2QvY29udHJhY3QucHk6MzAtMzIKICAgIC8vIGFzc2VydCAoCiAgICAvLyAgICAgb3AuR2xvYmFsLmN1cnJlbnRfYXBwbGljYXRpb25fYWRkcmVzcyAhPSBvcC5HbG9iYWwuemVyb19hZGRyZXNzCiAgICAvLyApLCAiZXhwZWN0ZWQgZ2xvYmFsIHRvIGhhdmUgYXBwIGFkZHJlc3MiCiAgICBhc3NlcnQgLy8gZXhwZWN0ZWQgZ2xvYmFsIHRvIGhhdmUgYXBwIGFkZHJlc3MKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9BcmM0QUJJTWV0aG9kL2NvbnRyYWN0LnB5OjI4CiAgICAvLyBhcHBfdHhuID0gZ3R4bi5BcHBsaWNhdGlvbkNhbGxUcmFuc2FjdGlvbigwKQogICAgaW50IDAKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9BcmM0QUJJTWV0aG9kL2NvbnRyYWN0LnB5OjMzCiAgICAvLyBhc3NlcnQgYXBwX3R4bi5hcHBfaWQgPT0gMCwgImV4cGVjdGVkIHR4biB0byBoYXZlIDAiCiAgICBndHhucyBBcHBsaWNhdGlvbklECiAgICAhCiAgICBhc3NlcnQgLy8gZXhwZWN0ZWQgdHhuIHRvIGhhdmUgMAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL0FyYzRBQklNZXRob2QvY29udHJhY3QucHk6MzQKICAgIC8vIGFzc2VydCBUeG4uYXBwbGljYXRpb25faWQgPT0gMCwgImV4cGVjdGVkIHR4biB0byBoYXZlIDAiCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgIQogICAgYXNzZXJ0IC8vIGV4cGVjdGVkIHR4biB0byBoYXZlIDAKICAgIHJldHN1YgoKCi8vIHRlc3RzLmFydGlmYWN0cy5BcmM0QUJJTWV0aG9kLmNvbnRyYWN0LlNpZ25hdHVyZXNDb250cmFjdC5zaW5rKHZhbHVlOiBieXRlcywgYXJyOiBieXRlcykgLT4gdm9pZDoKc2luazoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9BcmM0QUJJTWV0aG9kL2NvbnRyYWN0LnB5OjM2LTM3CiAgICAvLyBAYXJjNC5hYmltZXRob2QKICAgIC8vIGRlZiBzaW5rKHNlbGYsIHZhbHVlOiBhcmM0LlN0cmluZywgYXJyOiBVSW50OEFycmF5KSAtPiBOb25lOgogICAgcHJvdG8gMiAwCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvQXJjNEFCSU1ldGhvZC9jb250cmFjdC5weTozOAogICAgLy8gYXNzZXJ0IHZhbHVlCiAgICBmcmFtZV9kaWcgLTIKICAgIGJ5dGUgMHgwMDAwCiAgICAhPQogICAgYXNzZXJ0CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvQXJjNEFCSU1ldGhvZC9jb250cmFjdC5weTozOQogICAgLy8gYXNzZXJ0IGFycgogICAgZnJhbWVfZGlnIC0xCiAgICBieXRlIDB4MDAwMAogICAgIT0KICAgIGFzc2VydAogICAgcmV0c3ViCgoKLy8gdGVzdHMuYXJ0aWZhY3RzLkFyYzRBQklNZXRob2QuY29udHJhY3QuU2lnbmF0dXJlc0NvbnRyYWN0LnNpbmsyKHZhbHVlOiBieXRlcywgYXJyOiBieXRlcykgLT4gdm9pZDoKc2luazI6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvQXJjNEFCSU1ldGhvZC9jb250cmFjdC5weTo0MS00MgogICAgLy8gQGFyYzQuYWJpbWV0aG9kKG5hbWU9ImFsaWFzIikKICAgIC8vIGRlZiBzaW5rMihzZWxmLCB2YWx1ZTogYXJjNC5TdHJpbmcsIGFycjogVUludDhBcnJheSkgLT4gTm9uZToKICAgIHByb3RvIDIgMAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL0FyYzRBQklNZXRob2QvY29udHJhY3QucHk6NDMKICAgIC8vIGFzc2VydCB2YWx1ZQogICAgZnJhbWVfZGlnIC0yCiAgICBieXRlIDB4MDAwMAogICAgIT0KICAgIGFzc2VydAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL0FyYzRBQklNZXRob2QvY29udHJhY3QucHk6NDQKICAgIC8vIGFzc2VydCBhcnIKICAgIGZyYW1lX2RpZyAtMQogICAgYnl0ZSAweDAwMDAKICAgICE9CiAgICBhc3NlcnQKICAgIHJldHN1YgoKCi8vIHRlc3RzLmFydGlmYWN0cy5BcmM0QUJJTWV0aG9kLmNvbnRyYWN0LlNpZ25hdHVyZXNDb250cmFjdC53aXRoX3R4bih2YWx1ZTogYnl0ZXMsIHBheTogdWludDY0LCBhcnI6IGJ5dGVzKSAtPiB2b2lkOgp3aXRoX3R4bjoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9BcmM0QUJJTWV0aG9kL2NvbnRyYWN0LnB5OjQ2LTQ3CiAgICAvLyBAYXJjNC5hYmltZXRob2QKICAgIC8vIGRlZiB3aXRoX3R4bihzZWxmLCB2YWx1ZTogYXJjNC5TdHJpbmcsIHBheTogZ3R4bi5QYXltZW50VHJhbnNhY3Rpb24sIGFycjogVUludDhBcnJheSkgLT4gTm9uZToKICAgIHByb3RvIDMgMAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL0FyYzRBQklNZXRob2QvY29udHJhY3QucHk6NDgKICAgIC8vIGFzc2VydCB2YWx1ZQogICAgZnJhbWVfZGlnIC0zCiAgICBieXRlIDB4MDAwMAogICAgIT0KICAgIGFzc2VydAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL0FyYzRBQklNZXRob2QvY29udHJhY3QucHk6NDkKICAgIC8vIGFzc2VydCBhcnIKICAgIGZyYW1lX2RpZyAtMQogICAgYnl0ZSAweDAwMDAKICAgICE9CiAgICBhc3NlcnQKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9BcmM0QUJJTWV0aG9kL2NvbnRyYWN0LnB5OjUwCiAgICAvLyBhc3NlcnQgcGF5Lmdyb3VwX2luZGV4ID09IDAKICAgIGZyYW1lX2RpZyAtMgogICAgZ3R4bnMgR3JvdXBJbmRleAogICAgIQogICAgYXNzZXJ0CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvQXJjNEFCSU1ldGhvZC9jb250cmFjdC5weTo1MQogICAgLy8gYXNzZXJ0IFR4bi5ncm91cF9pbmRleCA9PSAxCiAgICB0eG4gR3JvdXBJbmRleAogICAgaW50IDEKICAgID09CiAgICBhc3NlcnQKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9BcmM0QUJJTWV0aG9kL2NvbnRyYWN0LnB5OjUyCiAgICAvLyBhc3NlcnQgcGF5LmFtb3VudCA9PSAxMjMKICAgIGZyYW1lX2RpZyAtMgogICAgZ3R4bnMgQW1vdW50CiAgICBpbnQgMTIzCiAgICA9PQogICAgYXNzZXJ0CiAgICByZXRzdWIKCgovLyB0ZXN0cy5hcnRpZmFjdHMuQXJjNEFCSU1ldGhvZC5jb250cmFjdC5TaWduYXR1cmVzQ29udHJhY3Qud2l0aF9hc3NldCh2YWx1ZTogYnl0ZXMsIGFzc2V0OiB1aW50NjQsIGFycjogYnl0ZXMpIC0+IHZvaWQ6CndpdGhfYXNzZXQ6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvQXJjNEFCSU1ldGhvZC9jb250cmFjdC5weTo1NC01NQogICAgLy8gQGFyYzQuYWJpbWV0aG9kCiAgICAvLyBkZWYgd2l0aF9hc3NldChzZWxmLCB2YWx1ZTogYXJjNC5TdHJpbmcsIGFzc2V0OiBBc3NldCwgYXJyOiBVSW50OEFycmF5KSAtPiBOb25lOgogICAgcHJvdG8gMyAwCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvQXJjNEFCSU1ldGhvZC9jb250cmFjdC5weTo1NgogICAgLy8gYXNzZXJ0IHZhbHVlCiAgICBmcmFtZV9kaWcgLTMKICAgIGJ5dGUgMHgwMDAwCiAgICAhPQogICAgYXNzZXJ0CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvQXJjNEFCSU1ldGhvZC9jb250cmFjdC5weTo1NwogICAgLy8gYXNzZXJ0IGFycgogICAgZnJhbWVfZGlnIC0xCiAgICBieXRlIDB4MDAwMAogICAgIT0KICAgIGFzc2VydAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL0FyYzRBQklNZXRob2QvY29udHJhY3QucHk6NTgKICAgIC8vIGFzc2VydCBhc3NldC50b3RhbCA9PSAxMjMKICAgIGZyYW1lX2RpZyAtMgogICAgYXNzZXRfcGFyYW1zX2dldCBBc3NldFRvdGFsCiAgICBhc3NlcnQgLy8gYXNzZXQgZXhpc3RzCiAgICBpbnQgMTIzCiAgICA9PQogICAgYXNzZXJ0CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvQXJjNEFCSU1ldGhvZC9jb250cmFjdC5weTo1OQogICAgLy8gYXNzZXJ0IFR4bi5hc3NldHMoMCkgPT0gYXNzZXQKICAgIHR4bmEgQXNzZXRzIDAKICAgIGZyYW1lX2RpZyAtMgogICAgPT0KICAgIGFzc2VydAogICAgcmV0c3ViCgoKLy8gdGVzdHMuYXJ0aWZhY3RzLkFyYzRBQklNZXRob2QuY29udHJhY3QuU2lnbmF0dXJlc0NvbnRyYWN0LndpdGhfYXBwKHZhbHVlOiBieXRlcywgYXBwOiB1aW50NjQsIGFwcF9pZDogYnl0ZXMsIGFycjogYnl0ZXMpIC0+IHZvaWQ6CndpdGhfYXBwOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL0FyYzRBQklNZXRob2QvY29udHJhY3QucHk6NjEtNjQKICAgIC8vIEBhcmM0LmFiaW1ldGhvZAogICAgLy8gZGVmIHdpdGhfYXBwKAogICAgLy8gICAgIHNlbGYsIHZhbHVlOiBhcmM0LlN0cmluZywgYXBwOiBBcHBsaWNhdGlvbiwgYXBwX2lkOiBhcmM0LlVJbnQ2NCwgYXJyOiBVSW50OEFycmF5CiAgICAvLyApIC0+IE5vbmU6CiAgICBwcm90byA0IDAKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9BcmM0QUJJTWV0aG9kL2NvbnRyYWN0LnB5OjY1CiAgICAvLyBhc3NlcnQgdmFsdWUKICAgIGZyYW1lX2RpZyAtNAogICAgYnl0ZSAweDAwMDAKICAgICE9CiAgICBhc3NlcnQKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9BcmM0QUJJTWV0aG9kL2NvbnRyYWN0LnB5OjY2CiAgICAvLyBhc3NlcnQgYXJyCiAgICBmcmFtZV9kaWcgLTEKICAgIGJ5dGUgMHgwMDAwCiAgICAhPQogICAgYXNzZXJ0CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvQXJjNEFCSU1ldGhvZC9jb250cmFjdC5weTo2NwogICAgLy8gYXNzZXJ0IGFwcC5pZCA9PSBhcHBfaWQsICJleHBlY3RlZCBhcHAgaWQgdG8gbWF0Y2ggcHJvdmlkZWQgYXBwIGlkIgogICAgZnJhbWVfZGlnIC0zCiAgICBpdG9iCiAgICBmcmFtZV9kaWcgLTIKICAgIGI9PQogICAgYXNzZXJ0IC8vIGV4cGVjdGVkIGFwcCBpZCB0byBtYXRjaCBwcm92aWRlZCBhcHAgaWQKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9BcmM0QUJJTWV0aG9kL2NvbnRyYWN0LnB5OjY4CiAgICAvLyBhc3NlcnQgYXBwLmNyZWF0b3IgPT0gb3AuR2xvYmFsLmNyZWF0b3JfYWRkcmVzcywgImV4cGVjdGVkIG90aGVyIGFwcCB0byBoYXZlIHNhbWUgY3JlYXRvciIKICAgIGZyYW1lX2RpZyAtMwogICAgYXBwX3BhcmFtc19nZXQgQXBwQ3JlYXRvcgogICAgYXNzZXJ0IC8vIGFwcGxpY2F0aW9uIGV4aXN0cwogICAgZ2xvYmFsIENyZWF0b3JBZGRyZXNzCiAgICA9PQogICAgYXNzZXJ0IC8vIGV4cGVjdGVkIG90aGVyIGFwcCB0byBoYXZlIHNhbWUgY3JlYXRvcgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL0FyYzRBQklNZXRob2QvY29udHJhY3QucHk6NjkKICAgIC8vIGFwcF90eG4gPSBndHhuLkFwcGxpY2F0aW9uQ2FsbFRyYW5zYWN0aW9uKDApCiAgICBpbnQgMAogICAgZ3R4bnMgVHlwZUVudW0KICAgIGludCBhcHBsCiAgICA9PQogICAgYXNzZXJ0IC8vIHRyYW5zYWN0aW9uIHR5cGUgaXMgYXBwbAogICAgaW50IDAKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9BcmM0QUJJTWV0aG9kL2NvbnRyYWN0LnB5OjcwCiAgICAvLyBhc3NlcnQgYXBwX3R4bi5hcHBzKDApID09IG9wLkdsb2JhbC5jdXJyZW50X2FwcGxpY2F0aW9uX2lkCiAgICBkdXAKICAgIGd0eG5zYXMgQXBwbGljYXRpb25zCiAgICBnbG9iYWwgQ3VycmVudEFwcGxpY2F0aW9uSUQKICAgID09CiAgICBhc3NlcnQKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9BcmM0QUJJTWV0aG9kL2NvbnRyYWN0LnB5OjcxCiAgICAvLyBhc3NlcnQgVHhuLmFwcGxpY2F0aW9ucygwKSA9PSBvcC5HbG9iYWwuY3VycmVudF9hcHBsaWNhdGlvbl9pZAogICAgdHhuYSBBcHBsaWNhdGlvbnMgMAogICAgZ2xvYmFsIEN1cnJlbnRBcHBsaWNhdGlvbklECiAgICA9PQogICAgYXNzZXJ0CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvQXJjNEFCSU1ldGhvZC9jb250cmFjdC5weTo2OQogICAgLy8gYXBwX3R4biA9IGd0eG4uQXBwbGljYXRpb25DYWxsVHJhbnNhY3Rpb24oMCkKICAgIGludCAwCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvQXJjNEFCSU1ldGhvZC9jb250cmFjdC5weTo3MgogICAgLy8gYXNzZXJ0IGFwcF90eG4uYXBwcygxKSA9PSBhcHAKICAgIGludCAxCiAgICBndHhuc2FzIEFwcGxpY2F0aW9ucwogICAgZnJhbWVfZGlnIC0zCiAgICA9PQogICAgYXNzZXJ0CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvQXJjNEFCSU1ldGhvZC9jb250cmFjdC5weTo3MwogICAgLy8gYXNzZXJ0IFR4bi5hcHBsaWNhdGlvbnMoMSkgPT0gYXBwCiAgICB0eG5hIEFwcGxpY2F0aW9ucyAxCiAgICBmcmFtZV9kaWcgLTMKICAgID09CiAgICBhc3NlcnQKICAgIHJldHN1YgoKCi8vIHRlc3RzLmFydGlmYWN0cy5BcmM0QUJJTWV0aG9kLmNvbnRyYWN0LlNpZ25hdHVyZXNDb250cmFjdC53aXRoX2FjYyh2YWx1ZTogYnl0ZXMsIGFjYzogYnl0ZXMsIGFycjogYnl0ZXMpIC0+IHZvaWQ6CndpdGhfYWNjOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL0FyYzRBQklNZXRob2QvY29udHJhY3QucHk6NzUtNzYKICAgIC8vIEBhcmM0LmFiaW1ldGhvZAogICAgLy8gZGVmIHdpdGhfYWNjKHNlbGYsIHZhbHVlOiBhcmM0LlN0cmluZywgYWNjOiBBY2NvdW50LCBhcnI6IFVJbnQ4QXJyYXkpIC0+IE5vbmU6CiAgICBwcm90byAzIDAKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9BcmM0QUJJTWV0aG9kL2NvbnRyYWN0LnB5Ojc3CiAgICAvLyBhc3NlcnQgdmFsdWUKICAgIGZyYW1lX2RpZyAtMwogICAgYnl0ZSAweDAwMDAKICAgICE9CiAgICBhc3NlcnQKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9BcmM0QUJJTWV0aG9kL2NvbnRyYWN0LnB5Ojc4CiAgICAvLyBhc3NlcnQgYXJyCiAgICBmcmFtZV9kaWcgLTEKICAgIGJ5dGUgMHgwMDAwCiAgICAhPQogICAgYXNzZXJ0CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvQXJjNEFCSU1ldGhvZC9jb250cmFjdC5weTo3OQogICAgLy8gYXNzZXJ0IGFjYy5iYWxhbmNlID09IGFjYy5taW5fYmFsYW5jZSArIDEyMzQKICAgIGZyYW1lX2RpZyAtMgogICAgYWNjdF9wYXJhbXNfZ2V0IEFjY3RCYWxhbmNlCiAgICBhc3NlcnQgLy8gYWNjb3VudCBmdW5kZWQKICAgIGZyYW1lX2RpZyAtMgogICAgYWNjdF9wYXJhbXNfZ2V0IEFjY3RNaW5CYWxhbmNlCiAgICBhc3NlcnQgLy8gYWNjb3VudCBmdW5kZWQKICAgIGludCAxMjM0CiAgICArCiAgICA9PQogICAgYXNzZXJ0CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvQXJjNEFCSU1ldGhvZC9jb250cmFjdC5weTo4MAogICAgLy8gYXNzZXJ0IFR4bi5hY2NvdW50cygwKSA9PSBUeG4uc2VuZGVyCiAgICB0eG5hIEFjY291bnRzIDAKICAgIHR4biBTZW5kZXIKICAgID09CiAgICBhc3NlcnQKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9BcmM0QUJJTWV0aG9kL2NvbnRyYWN0LnB5OjgxCiAgICAvLyBhc3NlcnQgVHhuLmFjY291bnRzKDEpID09IGFjYwogICAgdHhuYSBBY2NvdW50cyAxCiAgICBmcmFtZV9kaWcgLTIKICAgID09CiAgICBhc3NlcnQKICAgIHJldHN1YgoKCi8vIHRlc3RzLmFydGlmYWN0cy5BcmM0QUJJTWV0aG9kLmNvbnRyYWN0LlNpZ25hdHVyZXNDb250cmFjdC5jb21wbGV4X3NpZyhzdHJ1Y3QxOiBieXRlcywgdHhuOiB1aW50NjQsIGFjYzogYnl0ZXMsIGZpdmU6IGJ5dGVzKSAtPiBieXRlcywgYnl0ZXM6CmNvbXBsZXhfc2lnOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL0FyYzRBQklNZXRob2QvY29udHJhY3QucHk6ODMtODYKICAgIC8vIEBhcmM0LmFiaW1ldGhvZAogICAgLy8gZGVmIGNvbXBsZXhfc2lnKAogICAgLy8gICAgIHNlbGYsIHN0cnVjdDE6IE15U3RydWN0LCB0eG46IGFsZ29weS5ndHhuLlRyYW5zYWN0aW9uLCBhY2M6IEFjY291bnQsIGZpdmU6IFVJbnQ4QXJyYXkKICAgIC8vICkgLT4gdHVwbGVbTXlTdHJ1Y3RBbGlhcywgTXlTdHJ1Y3RdOgogICAgcHJvdG8gNCAyCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvQXJjNEFCSU1ldGhvZC9jb250cmFjdC5weTo4NwogICAgLy8gYXNzZXJ0IFR4bi5udW1fYXBwX2FyZ3MgPT0gNAogICAgdHhuIE51bUFwcEFyZ3MKICAgIGludCA0CiAgICA9PQogICAgYXNzZXJ0CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvQXJjNEFCSU1ldGhvZC9jb250cmFjdC5weTo4OC04OQogICAgLy8gIyBzdHJ1Y3QKICAgIC8vIGFzc2VydCBzdHJ1Y3QxLmFub3RoZXJfc3RydWN0Lm9uZSA9PSAxCiAgICBmcmFtZV9kaWcgLTQKICAgIGludCAwCiAgICBleHRyYWN0X3VpbnQxNgogICAgZnJhbWVfZGlnIC00CiAgICBpbnQgMgogICAgZXh0cmFjdF91aW50MTYKICAgIGZyYW1lX2RpZyAtNAogICAgdW5jb3ZlciAyCiAgICBkaWcgMgogICAgc3Vic3RyaW5nMwogICAgZHVwCiAgICBleHRyYWN0IDAgOCAvLyBvbiBlcnJvcjogSW5kZXggYWNjZXNzIGlzIG91dCBvZiBib3VuZHMKICAgIGJ5dGUgMHgwMDAwMDAwMDAwMDAwMDAxCiAgICBiPT0KICAgIGFzc2VydAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL0FyYzRBQklNZXRob2QvY29udHJhY3QucHk6OTAKICAgIC8vIGFzc2VydCBzdHJ1Y3QxLmFub3RoZXJfc3RydWN0LnR3byA9PSAiMiIKICAgIGR1cAogICAgaW50IDgKICAgIGV4dHJhY3RfdWludDE2CiAgICBzd2FwCiAgICBkdXAKICAgIGxlbgogICAgc3dhcAogICAgZHVwCiAgICB1bmNvdmVyIDMKICAgIHVuY292ZXIgMwogICAgc3Vic3RyaW5nMwogICAgYnl0ZSAweDAwMDEzMgogICAgPT0KICAgIGFzc2VydAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL0FyYzRBQklNZXRob2QvY29udHJhY3QucHk6OTEKICAgIC8vIGFzc2VydCBzdHJ1Y3QxLmFub3RoZXJfc3RydWN0X2FsaWFzLm9uZSA9PSAxCiAgICBmcmFtZV9kaWcgLTQKICAgIGxlbgogICAgZnJhbWVfZGlnIC00CiAgICB1bmNvdmVyIDMKICAgIHVuY292ZXIgMgogICAgc3Vic3RyaW5nMwogICAgZHVwCiAgICBleHRyYWN0IDAgOCAvLyBvbiBlcnJvcjogSW5kZXggYWNjZXNzIGlzIG91dCBvZiBib3VuZHMKICAgIGJ5dGUgMHgwMDAwMDAwMDAwMDAwMDAxCiAgICBiPT0KICAgIGFzc2VydAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL0FyYzRBQklNZXRob2QvY29udHJhY3QucHk6OTIKICAgIC8vIGFzc2VydCBzdHJ1Y3QxLmFub3RoZXJfc3RydWN0X2FsaWFzLnR3byA9PSAiMiIKICAgIGR1cAogICAgaW50IDgKICAgIGV4dHJhY3RfdWludDE2CiAgICBzd2FwCiAgICBkdXAKICAgIGxlbgogICAgc3dhcAogICAgY292ZXIgMgogICAgc3Vic3RyaW5nMwogICAgYnl0ZSAweDAwMDEzMgogICAgPT0KICAgIGFzc2VydAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL0FyYzRBQklNZXRob2QvY29udHJhY3QucHk6OTMKICAgIC8vIGFzc2VydCBzdHJ1Y3QxLnRocmVlID09IDMKICAgIGZyYW1lX2RpZyAtNAogICAgZXh0cmFjdCA0IDE2IC8vIG9uIGVycm9yOiBJbmRleCBhY2Nlc3MgaXMgb3V0IG9mIGJvdW5kcwogICAgYnl0ZSAweDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAzCiAgICBiPT0KICAgIGFzc2VydAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL0FyYzRBQklNZXRob2QvY29udHJhY3QucHk6OTQKICAgIC8vIGFzc2VydCBzdHJ1Y3QxLmZvdXIgPT0gNAogICAgZnJhbWVfZGlnIC00CiAgICBleHRyYWN0IDIwIDE2IC8vIG9uIGVycm9yOiBJbmRleCBhY2Nlc3MgaXMgb3V0IG9mIGJvdW5kcwogICAgYnl0ZSAweDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDA0CiAgICBiPT0KICAgIGFzc2VydAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL0FyYzRBQklNZXRob2QvY29udHJhY3QucHk6OTYtOTcKICAgIC8vICMgdHhuCiAgICAvLyBhc3NlcnQgdHhuLmdyb3VwX2luZGV4ID09IFR4bi5ncm91cF9pbmRleCAtIDEKICAgIGZyYW1lX2RpZyAtMwogICAgZ3R4bnMgR3JvdXBJbmRleAogICAgdHhuIEdyb3VwSW5kZXgKICAgIGludCAxCiAgICAtCiAgICA9PQogICAgYXNzZXJ0CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvQXJjNEFCSU1ldGhvZC9jb250cmFjdC5weTo5OS0xMDAKICAgIC8vICMgYWNjCiAgICAvLyBhc3NlcnQgVHhuLmFwcGxpY2F0aW9uX2FyZ3MoMikgPT0gYXJjNC5VSW50OCgxKS5ieXRlcyAgIyBhY2MgYXJyYXkgcmVmCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAyCiAgICBieXRlIDB4MDEKICAgID09CiAgICBhc3NlcnQKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9BcmM0QUJJTWV0aG9kL2NvbnRyYWN0LnB5OjEwMQogICAgLy8gYXNzZXJ0IGFjYy5iYWxhbmNlID09IGFjYy5taW5fYmFsYW5jZSArIDEyMzQKICAgIGZyYW1lX2RpZyAtMgogICAgYWNjdF9wYXJhbXNfZ2V0IEFjY3RCYWxhbmNlCiAgICBhc3NlcnQgLy8gYWNjb3VudCBmdW5kZWQKICAgIGZyYW1lX2RpZyAtMgogICAgYWNjdF9wYXJhbXNfZ2V0IEFjY3RNaW5CYWxhbmNlCiAgICBhc3NlcnQgLy8gYWNjb3VudCBmdW5kZWQKICAgIGludCAxMjM0CiAgICArCiAgICA9PQogICAgYXNzZXJ0CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvQXJjNEFCSU1ldGhvZC9jb250cmFjdC5weToxMDIKICAgIC8vIGFzc2VydCBmaXZlWzBdID09IDUKICAgIGZyYW1lX2RpZyAtMQogICAgZXh0cmFjdCAyIDAKICAgIGV4dHJhY3QgMCAxIC8vIG9uIGVycm9yOiBJbmRleCBhY2Nlc3MgaXMgb3V0IG9mIGJvdW5kcwogICAgYnl0ZSAweDA1CiAgICBiPT0KICAgIGFzc2VydAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL0FyYzRBQklNZXRob2QvY29udHJhY3QucHk6MTA0CiAgICAvLyByZXR1cm4gc3RydWN0MS5hbm90aGVyX3N0cnVjdC5jb3B5KCksIHN0cnVjdDEuY29weSgpCiAgICBmcmFtZV9kaWcgLTQKICAgIHJldHN1Ygo=", "clear": "I3ByYWdtYSB2ZXJzaW9uIDEwCgp0ZXN0cy5hcnRpZmFjdHMuQXJjNEFCSU1ldGhvZC5jb250cmFjdC5TaWduYXR1cmVzQ29udHJhY3QuY2xlYXJfc3RhdGVfcHJvZ3JhbToKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9BcmM0QUJJTWV0aG9kL2NvbnRyYWN0LnB5OjI1CiAgICAvLyBjbGFzcyBTaWduYXR1cmVzQ29udHJhY3QoQVJDNENvbnRyYWN0KToKICAgIGludCAxCiAgICByZXR1cm4K" }, "state": { @@ -141,8 +141,8 @@ "name": "value" }, { - "type": "acfg", - "name": "acfg" + "type": "pay", + "name": "pay" }, { "type": "uint8[]", @@ -186,6 +186,10 @@ "type": "application", "name": "app" }, + { + "type": "uint64", + "name": "app_id" + }, { "type": "uint8[]", "name": "arr" diff --git a/examples/box/__init__.py b/tests/artifacts/BoxContract/__init__.py similarity index 100% rename from examples/box/__init__.py rename to tests/artifacts/BoxContract/__init__.py diff --git a/examples/box/contract.py b/tests/artifacts/BoxContract/contract.py similarity index 100% rename from examples/box/contract.py rename to tests/artifacts/BoxContract/contract.py diff --git a/tests/artifacts/BoxContract/data/BoxContract.approval.teal b/tests/artifacts/BoxContract/data/BoxContract.approval.teal new file mode 100644 index 0000000..ad0f79d --- /dev/null +++ b/tests/artifacts/BoxContract/data/BoxContract.approval.teal @@ -0,0 +1,151 @@ +#pragma version 10 + +tests.artifacts.BoxContract.contract.BoxContract.approval_program: + // tests/artifacts/BoxContract/contract.py:4 + // class BoxContract(ARC4Contract): + txn NumAppArgs + bz main_bare_routing@6 + method "store_enums()void" + method "read_enums()(uint64,uint64)" + txna ApplicationArgs 0 + match main_store_enums_route@2 main_read_enums_route@3 + err // reject transaction + +main_store_enums_route@2: + // tests/artifacts/BoxContract/contract.py:9 + // @arc4.abimethod() + txn OnCompletion + ! + assert // OnCompletion is NoOp + txn ApplicationID + assert // is not creating + callsub store_enums + int 1 + return + +main_read_enums_route@3: + // tests/artifacts/BoxContract/contract.py:14 + // @arc4.abimethod() + txn OnCompletion + ! + assert // OnCompletion is NoOp + txn ApplicationID + assert // is not creating + callsub read_enums + byte 0x151f7c75 + swap + concat + log + int 1 + return + +main_bare_routing@6: + // tests/artifacts/BoxContract/contract.py:4 + // class BoxContract(ARC4Contract): + txn OnCompletion + ! + assert // reject transaction + txn ApplicationID + ! + assert // is creating + int 1 + return + + +// tests.artifacts.BoxContract.contract.BoxContract.store_enums() -> void: +store_enums: + // tests/artifacts/BoxContract/contract.py:9-10 + // @arc4.abimethod() + // def store_enums(self) -> None: + proto 0 0 + // tests/artifacts/BoxContract/contract.py:11 + // self.oca.value = OnCompleteAction.OptIn + int OptIn + itob + // tests/artifacts/BoxContract/contract.py:6 + // self.oca = Box(OnCompleteAction) + byte "oca" + // tests/artifacts/BoxContract/contract.py:11 + // self.oca.value = OnCompleteAction.OptIn + swap + box_put + // tests/artifacts/BoxContract/contract.py:12 + // self.txn.value = TransactionType.ApplicationCall + int appl + itob + // tests/artifacts/BoxContract/contract.py:7 + // self.txn = Box(TransactionType) + byte "txn" + // tests/artifacts/BoxContract/contract.py:12 + // self.txn.value = TransactionType.ApplicationCall + swap + box_put + retsub + + +// tests.artifacts.BoxContract.contract.BoxContract.read_enums() -> bytes: +read_enums: + // tests/artifacts/BoxContract/contract.py:14-15 + // @arc4.abimethod() + // def read_enums(self) -> arc4.Tuple[arc4.UInt64, arc4.UInt64]: + proto 0 1 + // tests/artifacts/BoxContract/contract.py:16 + // assert op.Box.get(b"oca")[0] == op.itob(self.oca.value) + byte 0x6f6361 + box_get + pop + // tests/artifacts/BoxContract/contract.py:6 + // self.oca = Box(OnCompleteAction) + byte "oca" + // tests/artifacts/BoxContract/contract.py:16 + // assert op.Box.get(b"oca")[0] == op.itob(self.oca.value) + box_get + swap + btoi + swap + assert // check self.oca exists + itob + == + assert + // tests/artifacts/BoxContract/contract.py:17 + // assert op.Box.get(b"txn")[0] == op.itob(self.txn.value) + byte 0x74786e + box_get + pop + // tests/artifacts/BoxContract/contract.py:7 + // self.txn = Box(TransactionType) + byte "txn" + // tests/artifacts/BoxContract/contract.py:17 + // assert op.Box.get(b"txn")[0] == op.itob(self.txn.value) + box_get + swap + btoi + swap + assert // check self.txn exists + itob + == + assert + // tests/artifacts/BoxContract/contract.py:6 + // self.oca = Box(OnCompleteAction) + byte "oca" + // tests/artifacts/BoxContract/contract.py:19 + // return arc4.Tuple((arc4.UInt64(self.oca.value), arc4.UInt64(self.txn.value))) + box_get + swap + btoi + swap + assert // check self.oca exists + itob + // tests/artifacts/BoxContract/contract.py:7 + // self.txn = Box(TransactionType) + byte "txn" + // tests/artifacts/BoxContract/contract.py:19 + // return arc4.Tuple((arc4.UInt64(self.oca.value), arc4.UInt64(self.txn.value))) + box_get + swap + btoi + swap + assert // check self.txn exists + itob + concat + retsub diff --git a/tests/artifacts/BoxContract/data/BoxContract.arc32.json b/tests/artifacts/BoxContract/data/BoxContract.arc32.json new file mode 100644 index 0000000..4e43a17 --- /dev/null +++ b/tests/artifacts/BoxContract/data/BoxContract.arc32.json @@ -0,0 +1,63 @@ +{ + "hints": { + "store_enums()void": { + "call_config": { + "no_op": "CALL" + } + }, + "read_enums()(uint64,uint64)": { + "call_config": { + "no_op": "CALL" + } + } + }, + "source": { + "approval": "I3ByYWdtYSB2ZXJzaW9uIDEwCgp0ZXN0cy5hcnRpZmFjdHMuQm94Q29udHJhY3QuY29udHJhY3QuQm94Q29udHJhY3QuYXBwcm92YWxfcHJvZ3JhbToKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9Cb3hDb250cmFjdC9jb250cmFjdC5weTo0CiAgICAvLyBjbGFzcyBCb3hDb250cmFjdChBUkM0Q29udHJhY3QpOgogICAgdHhuIE51bUFwcEFyZ3MKICAgIGJ6IG1haW5fYmFyZV9yb3V0aW5nQDYKICAgIG1ldGhvZCAic3RvcmVfZW51bXMoKXZvaWQiCiAgICBtZXRob2QgInJlYWRfZW51bXMoKSh1aW50NjQsdWludDY0KSIKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDAKICAgIG1hdGNoIG1haW5fc3RvcmVfZW51bXNfcm91dGVAMiBtYWluX3JlYWRfZW51bXNfcm91dGVAMwogICAgZXJyIC8vIHJlamVjdCB0cmFuc2FjdGlvbgoKbWFpbl9zdG9yZV9lbnVtc19yb3V0ZUAyOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL0JveENvbnRyYWN0L2NvbnRyYWN0LnB5OjkKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gaXMgbm90IGNyZWF0aW5nCiAgICBjYWxsc3ViIHN0b3JlX2VudW1zCiAgICBpbnQgMQogICAgcmV0dXJuCgptYWluX3JlYWRfZW51bXNfcm91dGVAMzoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9Cb3hDb250cmFjdC9jb250cmFjdC5weToxNAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBpcyBub3QgY3JlYXRpbmcKICAgIGNhbGxzdWIgcmVhZF9lbnVtcwogICAgYnl0ZSAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50IDEKICAgIHJldHVybgoKbWFpbl9iYXJlX3JvdXRpbmdANjoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9Cb3hDb250cmFjdC9jb250cmFjdC5weTo0CiAgICAvLyBjbGFzcyBCb3hDb250cmFjdChBUkM0Q29udHJhY3QpOgogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIHJlamVjdCB0cmFuc2FjdGlvbgogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgICEKICAgIGFzc2VydCAvLyBpcyBjcmVhdGluZwogICAgaW50IDEKICAgIHJldHVybgoKCi8vIHRlc3RzLmFydGlmYWN0cy5Cb3hDb250cmFjdC5jb250cmFjdC5Cb3hDb250cmFjdC5zdG9yZV9lbnVtcygpIC0+IHZvaWQ6CnN0b3JlX2VudW1zOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL0JveENvbnRyYWN0L2NvbnRyYWN0LnB5OjktMTAKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBkZWYgc3RvcmVfZW51bXMoc2VsZikgLT4gTm9uZToKICAgIHByb3RvIDAgMAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL0JveENvbnRyYWN0L2NvbnRyYWN0LnB5OjExCiAgICAvLyBzZWxmLm9jYS52YWx1ZSA9IE9uQ29tcGxldGVBY3Rpb24uT3B0SW4KICAgIGludCBPcHRJbgogICAgaXRvYgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL0JveENvbnRyYWN0L2NvbnRyYWN0LnB5OjYKICAgIC8vIHNlbGYub2NhID0gQm94KE9uQ29tcGxldGVBY3Rpb24pCiAgICBieXRlICJvY2EiCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvQm94Q29udHJhY3QvY29udHJhY3QucHk6MTEKICAgIC8vIHNlbGYub2NhLnZhbHVlID0gT25Db21wbGV0ZUFjdGlvbi5PcHRJbgogICAgc3dhcAogICAgYm94X3B1dAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL0JveENvbnRyYWN0L2NvbnRyYWN0LnB5OjEyCiAgICAvLyBzZWxmLnR4bi52YWx1ZSA9IFRyYW5zYWN0aW9uVHlwZS5BcHBsaWNhdGlvbkNhbGwKICAgIGludCBhcHBsCiAgICBpdG9iCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvQm94Q29udHJhY3QvY29udHJhY3QucHk6NwogICAgLy8gc2VsZi50eG4gPSBCb3goVHJhbnNhY3Rpb25UeXBlKQogICAgYnl0ZSAidHhuIgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL0JveENvbnRyYWN0L2NvbnRyYWN0LnB5OjEyCiAgICAvLyBzZWxmLnR4bi52YWx1ZSA9IFRyYW5zYWN0aW9uVHlwZS5BcHBsaWNhdGlvbkNhbGwKICAgIHN3YXAKICAgIGJveF9wdXQKICAgIHJldHN1YgoKCi8vIHRlc3RzLmFydGlmYWN0cy5Cb3hDb250cmFjdC5jb250cmFjdC5Cb3hDb250cmFjdC5yZWFkX2VudW1zKCkgLT4gYnl0ZXM6CnJlYWRfZW51bXM6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvQm94Q29udHJhY3QvY29udHJhY3QucHk6MTQtMTUKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBkZWYgcmVhZF9lbnVtcyhzZWxmKSAtPiBhcmM0LlR1cGxlW2FyYzQuVUludDY0LCBhcmM0LlVJbnQ2NF06CiAgICBwcm90byAwIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9Cb3hDb250cmFjdC9jb250cmFjdC5weToxNgogICAgLy8gYXNzZXJ0IG9wLkJveC5nZXQoYiJvY2EiKVswXSA9PSBvcC5pdG9iKHNlbGYub2NhLnZhbHVlKQogICAgYnl0ZSAweDZmNjM2MQogICAgYm94X2dldAogICAgcG9wCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvQm94Q29udHJhY3QvY29udHJhY3QucHk6NgogICAgLy8gc2VsZi5vY2EgPSBCb3goT25Db21wbGV0ZUFjdGlvbikKICAgIGJ5dGUgIm9jYSIKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9Cb3hDb250cmFjdC9jb250cmFjdC5weToxNgogICAgLy8gYXNzZXJ0IG9wLkJveC5nZXQoYiJvY2EiKVswXSA9PSBvcC5pdG9iKHNlbGYub2NhLnZhbHVlKQogICAgYm94X2dldAogICAgc3dhcAogICAgYnRvaQogICAgc3dhcAogICAgYXNzZXJ0IC8vIGNoZWNrIHNlbGYub2NhIGV4aXN0cwogICAgaXRvYgogICAgPT0KICAgIGFzc2VydAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL0JveENvbnRyYWN0L2NvbnRyYWN0LnB5OjE3CiAgICAvLyBhc3NlcnQgb3AuQm94LmdldChiInR4biIpWzBdID09IG9wLml0b2Ioc2VsZi50eG4udmFsdWUpCiAgICBieXRlIDB4NzQ3ODZlCiAgICBib3hfZ2V0CiAgICBwb3AKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9Cb3hDb250cmFjdC9jb250cmFjdC5weTo3CiAgICAvLyBzZWxmLnR4biA9IEJveChUcmFuc2FjdGlvblR5cGUpCiAgICBieXRlICJ0eG4iCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvQm94Q29udHJhY3QvY29udHJhY3QucHk6MTcKICAgIC8vIGFzc2VydCBvcC5Cb3guZ2V0KGIidHhuIilbMF0gPT0gb3AuaXRvYihzZWxmLnR4bi52YWx1ZSkKICAgIGJveF9nZXQKICAgIHN3YXAKICAgIGJ0b2kKICAgIHN3YXAKICAgIGFzc2VydCAvLyBjaGVjayBzZWxmLnR4biBleGlzdHMKICAgIGl0b2IKICAgID09CiAgICBhc3NlcnQKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9Cb3hDb250cmFjdC9jb250cmFjdC5weTo2CiAgICAvLyBzZWxmLm9jYSA9IEJveChPbkNvbXBsZXRlQWN0aW9uKQogICAgYnl0ZSAib2NhIgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL0JveENvbnRyYWN0L2NvbnRyYWN0LnB5OjE5CiAgICAvLyByZXR1cm4gYXJjNC5UdXBsZSgoYXJjNC5VSW50NjQoc2VsZi5vY2EudmFsdWUpLCBhcmM0LlVJbnQ2NChzZWxmLnR4bi52YWx1ZSkpKQogICAgYm94X2dldAogICAgc3dhcAogICAgYnRvaQogICAgc3dhcAogICAgYXNzZXJ0IC8vIGNoZWNrIHNlbGYub2NhIGV4aXN0cwogICAgaXRvYgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL0JveENvbnRyYWN0L2NvbnRyYWN0LnB5OjcKICAgIC8vIHNlbGYudHhuID0gQm94KFRyYW5zYWN0aW9uVHlwZSkKICAgIGJ5dGUgInR4biIKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9Cb3hDb250cmFjdC9jb250cmFjdC5weToxOQogICAgLy8gcmV0dXJuIGFyYzQuVHVwbGUoKGFyYzQuVUludDY0KHNlbGYub2NhLnZhbHVlKSwgYXJjNC5VSW50NjQoc2VsZi50eG4udmFsdWUpKSkKICAgIGJveF9nZXQKICAgIHN3YXAKICAgIGJ0b2kKICAgIHN3YXAKICAgIGFzc2VydCAvLyBjaGVjayBzZWxmLnR4biBleGlzdHMKICAgIGl0b2IKICAgIGNvbmNhdAogICAgcmV0c3ViCg==", + "clear": "I3ByYWdtYSB2ZXJzaW9uIDEwCgp0ZXN0cy5hcnRpZmFjdHMuQm94Q29udHJhY3QuY29udHJhY3QuQm94Q29udHJhY3QuY2xlYXJfc3RhdGVfcHJvZ3JhbToKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9Cb3hDb250cmFjdC9jb250cmFjdC5weTo0CiAgICAvLyBjbGFzcyBCb3hDb250cmFjdChBUkM0Q29udHJhY3QpOgogICAgaW50IDEKICAgIHJldHVybgo=" + }, + "state": { + "global": { + "num_byte_slices": 0, + "num_uints": 0 + }, + "local": { + "num_byte_slices": 0, + "num_uints": 0 + } + }, + "schema": { + "global": { + "declared": {}, + "reserved": {} + }, + "local": { + "declared": {}, + "reserved": {} + } + }, + "contract": { + "name": "BoxContract", + "methods": [ + { + "name": "store_enums", + "args": [], + "readonly": false, + "returns": { + "type": "void" + } + }, + { + "name": "read_enums", + "args": [], + "readonly": false, + "returns": { + "type": "(uint64,uint64)" + } + } + ], + "networks": {} + }, + "bare_call_config": { + "no_op": "CREATE" + } +} \ No newline at end of file diff --git a/tests/artifacts/BoxContract/data/BoxContract.clear.teal b/tests/artifacts/BoxContract/data/BoxContract.clear.teal new file mode 100644 index 0000000..27c12e7 --- /dev/null +++ b/tests/artifacts/BoxContract/data/BoxContract.clear.teal @@ -0,0 +1,7 @@ +#pragma version 10 + +tests.artifacts.BoxContract.contract.BoxContract.clear_state_program: + // tests/artifacts/BoxContract/contract.py:4 + // class BoxContract(ARC4Contract): + int 1 + return diff --git a/tests/artifacts/StateOps/contract.py b/tests/artifacts/StateOps/contract.py index 012d812..71dcdce 100644 --- a/tests/artifacts/StateOps/contract.py +++ b/tests/artifacts/StateOps/contract.py @@ -8,72 +8,121 @@ Global, GlobalState, LocalState, + Txn, UInt64, arc4, op, + subroutine, ) +@subroutine +def _get_1st_ref_index() -> UInt64: + return op.btoi(Txn.application_args(1)) + + class StateAcctParamsGetContract(ARC4Contract): @arc4.abimethod() def verify_acct_balance(self, a: algopy.Account) -> algopy.UInt64: - balance, _val = op.AcctParamsGet.acct_balance(a) - return balance + value, funded = op.AcctParamsGet.acct_balance(a) + value_index, funded_index = op.AcctParamsGet.acct_balance(_get_1st_ref_index()) + assert value == value_index, "expected value by index to match" + assert funded == funded_index, "expected funded by index to match" + return value @arc4.abimethod() def verify_acct_min_balance(self, a: algopy.Account) -> algopy.UInt64: - min_balance, _val = op.AcctParamsGet.acct_min_balance(a) - return min_balance + value, funded = op.AcctParamsGet.acct_min_balance(a) + value_index, funded_index = op.AcctParamsGet.acct_min_balance(_get_1st_ref_index()) + assert value == value_index, "expected value by index to match" + assert funded == funded_index, "expected funded by index to match" + return value @arc4.abimethod() - def verify_acct_auth_addr(self, a: algopy.Account) -> algopy.Bytes: - auth_addr, _val = op.AcctParamsGet.acct_auth_addr(a) - return auth_addr.bytes + def verify_acct_auth_addr(self, a: algopy.Account) -> arc4.Address: + value, funded = op.AcctParamsGet.acct_auth_addr(a) + value_index, funded_index = op.AcctParamsGet.acct_auth_addr(_get_1st_ref_index()) + assert value == value_index, "expected value by index to match" + assert funded == funded_index, "expected funded by index to match" + return arc4.Address(value) @arc4.abimethod() def verify_acct_total_num_uint(self, a: algopy.Account) -> algopy.UInt64: - total_num_uint, _val = op.AcctParamsGet.acct_total_num_uint(a) - return total_num_uint + value, funded = op.AcctParamsGet.acct_total_num_uint(a) + value_index, funded_index = op.AcctParamsGet.acct_total_num_uint(_get_1st_ref_index()) + assert value == value_index, "expected value by index to match" + assert funded == funded_index, "expected funded by index to match" + return value @arc4.abimethod() def verify_acct_total_num_byte_slice(self, a: algopy.Account) -> algopy.UInt64: - total_num_byte_slice, _val = op.AcctParamsGet.acct_total_num_byte_slice(a) - return total_num_byte_slice + value, funded = op.AcctParamsGet.acct_total_num_byte_slice(a) + value_index, funded_index = op.AcctParamsGet.acct_total_num_byte_slice( + _get_1st_ref_index() + ) + assert value == value_index, "expected value by index to match" + assert funded == funded_index, "expected funded by index to match" + return value @arc4.abimethod() def verify_acct_total_extra_app_pages(self, a: algopy.Account) -> algopy.UInt64: - total_extra_app_pages, _val = op.AcctParamsGet.acct_total_extra_app_pages(a) - return total_extra_app_pages + value, funded = op.AcctParamsGet.acct_total_extra_app_pages(a) + value_index, funded_index = op.AcctParamsGet.acct_total_extra_app_pages( + _get_1st_ref_index() + ) + assert value == value_index, "expected value by index to match" + assert funded == funded_index, "expected funded by index to match" + return value @arc4.abimethod() def verify_acct_total_apps_created(self, a: algopy.Account) -> algopy.UInt64: - total_apps_created, _val = op.AcctParamsGet.acct_total_apps_created(a) - return total_apps_created + value, funded = op.AcctParamsGet.acct_total_apps_created(a) + value_index, funded_index = op.AcctParamsGet.acct_total_apps_created(_get_1st_ref_index()) + assert value == value_index, "expected value by index to match" + assert funded == funded_index, "expected funded by index to match" + return value @arc4.abimethod() def verify_acct_total_apps_opted_in(self, a: algopy.Account) -> algopy.UInt64: - total_apps_opted_in, _val = op.AcctParamsGet.acct_total_apps_opted_in(a) - return total_apps_opted_in + value, funded = op.AcctParamsGet.acct_total_apps_opted_in(a) + value_index, funded_index = op.AcctParamsGet.acct_total_apps_opted_in(_get_1st_ref_index()) + assert value == value_index, "expected value by index to match" + assert funded == funded_index, "expected funded by index to match" + return value @arc4.abimethod() def verify_acct_total_assets_created(self, a: algopy.Account) -> algopy.UInt64: - total_assets_created, _val = op.AcctParamsGet.acct_total_assets_created(a) - return total_assets_created + value, funded = op.AcctParamsGet.acct_total_assets_created(a) + value_index, funded_index = op.AcctParamsGet.acct_total_assets_created( + _get_1st_ref_index() + ) + assert value == value_index, "expected value by index to match" + assert funded == funded_index, "expected funded by index to match" + return value @arc4.abimethod() def verify_acct_total_assets(self, a: algopy.Account) -> algopy.UInt64: - total_assets, _val = op.AcctParamsGet.acct_total_assets(a) - return total_assets + value, funded = op.AcctParamsGet.acct_total_assets(a) + value_index, funded_index = op.AcctParamsGet.acct_total_assets(_get_1st_ref_index()) + assert value == value_index, "expected value by index to match" + assert funded == funded_index, "expected funded by index to match" + return value @arc4.abimethod() def verify_acct_total_boxes(self, a: algopy.Account) -> algopy.UInt64: - total_boxes, _val = op.AcctParamsGet.acct_total_boxes(a) - return total_boxes + value, funded = op.AcctParamsGet.acct_total_boxes(a) + value_index, funded_index = op.AcctParamsGet.acct_total_boxes(_get_1st_ref_index()) + assert value == value_index, "expected value by index to match" + assert funded == funded_index, "expected funded by index to match" + return value @arc4.abimethod() def verify_acct_total_box_bytes(self, a: algopy.Account) -> algopy.UInt64: - total_box_bytes, _val = op.AcctParamsGet.acct_total_box_bytes(a) - return total_box_bytes + value, funded = op.AcctParamsGet.acct_total_box_bytes(a) + value_index, funded_index = op.AcctParamsGet.acct_total_box_bytes(_get_1st_ref_index()) + assert value == value_index, "expected value by index to match" + assert funded == funded_index, "expected funded by index to match" + return value class StateAssetHoldingContract(ARC4Contract): @@ -91,110 +140,174 @@ def verify_asset_frozen_get(self, a: Account, b: Asset) -> bool: class StateAssetParamsContract(ARC4Contract): @arc4.abimethod() def verify_asset_params_get_total(self, a: Asset) -> UInt64: - total, _val = op.AssetParamsGet.asset_total(a) - return total + value, exists = op.AssetParamsGet.asset_total(a) + value_index, exists_index = op.AssetParamsGet.asset_total(_get_1st_ref_index()) + assert value == value_index, "expected value by index to match" + assert exists == exists_index, "expected exists by index to match" + return value @arc4.abimethod() def verify_asset_params_get_decimals(self, a: Asset) -> UInt64: - decimals, _val = op.AssetParamsGet.asset_decimals(a) - return decimals + value, exists = op.AssetParamsGet.asset_decimals(a) + value_index, exists_index = op.AssetParamsGet.asset_decimals(_get_1st_ref_index()) + assert value == value_index, "expected value by index to match" + assert exists == exists_index, "expected exists by index to match" + return value @arc4.abimethod() def verify_asset_params_get_default_frozen(self, a: Asset) -> bool: - default_frozen, _val = op.AssetParamsGet.asset_default_frozen(a) - return default_frozen + value, exists = op.AssetParamsGet.asset_default_frozen(a) + value_index, exists_index = op.AssetParamsGet.asset_default_frozen(_get_1st_ref_index()) + assert value == value_index, "expected value by index to match" + assert exists == exists_index, "expected exists by index to match" + return value @arc4.abimethod() def verify_asset_params_get_unit_name(self, a: Asset) -> Bytes: - unit_name, _val = op.AssetParamsGet.asset_unit_name(a) - return unit_name + value, exists = op.AssetParamsGet.asset_unit_name(a) + value_index, exists_index = op.AssetParamsGet.asset_unit_name(_get_1st_ref_index()) + assert value == value_index, "expected value by index to match" + assert exists == exists_index, "expected exists by index to match" + return value @arc4.abimethod() def verify_asset_params_get_name(self, a: Asset) -> Bytes: - name, _val = op.AssetParamsGet.asset_name(a) - return name + value, exists = op.AssetParamsGet.asset_name(a) + value_index, exists_index = op.AssetParamsGet.asset_name(_get_1st_ref_index()) + assert value == value_index, "expected value by index to match" + assert exists == exists_index, "expected exists by index to match" + return value @arc4.abimethod() def verify_asset_params_get_url(self, a: Asset) -> Bytes: - url, _val = op.AssetParamsGet.asset_url(a) - return url + value, exists = op.AssetParamsGet.asset_url(a) + value_index, exists_index = op.AssetParamsGet.asset_url(_get_1st_ref_index()) + assert value == value_index, "expected value by index to match" + assert exists == exists_index, "expected exists by index to match" + return value @arc4.abimethod() def verify_asset_params_get_metadata_hash(self, a: Asset) -> Bytes: - metadata_hash, _val = op.AssetParamsGet.asset_metadata_hash(a) - return metadata_hash + value, exists = op.AssetParamsGet.asset_metadata_hash(a) + value_index, exists_index = op.AssetParamsGet.asset_metadata_hash(_get_1st_ref_index()) + assert value == value_index, "expected value by index to match" + assert exists == exists_index, "expected exists by index to match" + return value @arc4.abimethod() - def verify_asset_params_get_manager(self, a: Asset) -> Bytes: - manager, _val = op.AssetParamsGet.asset_manager(a) - return manager.bytes + def verify_asset_params_get_manager(self, a: Asset) -> arc4.Address: + value, exists = op.AssetParamsGet.asset_manager(a) + value_index, exists_index = op.AssetParamsGet.asset_manager(_get_1st_ref_index()) + assert value == value_index, "expected value by index to match" + assert exists == exists_index, "expected exists by index to match" + return arc4.Address(value) @arc4.abimethod() - def verify_asset_params_get_reserve(self, a: Asset) -> Bytes: - reserve, _val = op.AssetParamsGet.asset_reserve(a) - return reserve.bytes + def verify_asset_params_get_reserve(self, a: Asset) -> arc4.Address: + value, exists = op.AssetParamsGet.asset_reserve(a) + value_index, exists_index = op.AssetParamsGet.asset_reserve(_get_1st_ref_index()) + assert value == value_index, "expected value by index to match" + assert exists == exists_index, "expected exists by index to match" + return arc4.Address(value) @arc4.abimethod() - def verify_asset_params_get_freeze(self, a: Asset) -> Bytes: - freeze, _val = op.AssetParamsGet.asset_freeze(a) - return freeze.bytes + def verify_asset_params_get_freeze(self, a: Asset) -> arc4.Address: + value, exists = op.AssetParamsGet.asset_freeze(a) + value_index, exists_index = op.AssetParamsGet.asset_freeze(_get_1st_ref_index()) + assert value == value_index, "expected value by index to match" + assert exists == exists_index, "expected exists by index to match" + return arc4.Address(value) @arc4.abimethod() - def verify_asset_params_get_clawback(self, a: Asset) -> Bytes: - clawback, _val = op.AssetParamsGet.asset_clawback(a) - return clawback.bytes + def verify_asset_params_get_clawback(self, a: Asset) -> arc4.Address: + value, exists = op.AssetParamsGet.asset_clawback(a) + value_index, exists_index = op.AssetParamsGet.asset_clawback(_get_1st_ref_index()) + assert value == value_index, "expected value by index to match" + assert exists == exists_index, "expected exists by index to match" + return arc4.Address(value) @arc4.abimethod() - def verify_asset_params_get_creator(self, a: Asset) -> Bytes: - creator, _val = op.AssetParamsGet.asset_creator(a) - return creator.bytes + def verify_asset_params_get_creator(self, a: Asset) -> arc4.Address: + value, exists = op.AssetParamsGet.asset_creator(a) + value_index, exists_index = op.AssetParamsGet.asset_creator(_get_1st_ref_index()) + assert value == value_index, "expected value by index to match" + assert exists == exists_index, "expected exists by index to match" + return arc4.Address(value) class StateAppParamsContract(ARC4Contract): + @arc4.abimethod() def verify_app_params_get_approval_program(self, a: Application) -> Bytes: - approval_program, _val = op.AppParamsGet.app_approval_program(a) - return approval_program + value, exists = op.AppParamsGet.app_approval_program(a) + value_index, exists_index = op.AppParamsGet.app_approval_program(_get_1st_ref_index()) + assert value == value_index, "expected value by index to match" + assert exists == exists_index, "expected exists by index to match" + return value @arc4.abimethod() def verify_app_params_get_clear_state_program(self, a: Application) -> Bytes: - clear_state_program, _val = op.AppParamsGet.app_clear_state_program(a) - return clear_state_program + value, exists = op.AppParamsGet.app_clear_state_program(a) + value_index, exists_index = op.AppParamsGet.app_clear_state_program(_get_1st_ref_index()) + assert value == value_index, "expected value by index to match" + assert exists == exists_index, "expected exists by index to match" + return value @arc4.abimethod() def verify_app_params_get_global_num_uint(self, a: Application) -> UInt64: - global_num_uint, _val = op.AppParamsGet.app_global_num_uint(a) - return global_num_uint + value, exists = op.AppParamsGet.app_global_num_uint(a) + value_index, exists_index = op.AppParamsGet.app_global_num_uint(_get_1st_ref_index()) + assert value == value_index, "expected value by index to match" + assert exists == exists_index, "expected exists by index to match" + return value @arc4.abimethod() def verify_app_params_get_global_num_byte_slice(self, a: Application) -> UInt64: - global_num_byte_slice, _val = op.AppParamsGet.app_global_num_byte_slice(a) - return global_num_byte_slice + value, exists = op.AppParamsGet.app_global_num_byte_slice(a) + value_index, exists_index = op.AppParamsGet.app_global_num_byte_slice(_get_1st_ref_index()) + assert value == value_index, "expected value by index to match" + assert exists == exists_index, "expected exists by index to match" + return value @arc4.abimethod() def verify_app_params_get_local_num_uint(self, a: Application) -> UInt64: - local_num_uint, _val = op.AppParamsGet.app_local_num_uint(a) - return local_num_uint + value, exists = op.AppParamsGet.app_local_num_uint(a) + value_index, exists_index = op.AppParamsGet.app_local_num_uint(_get_1st_ref_index()) + assert value == value_index, "expected value by index to match" + assert exists == exists_index, "expected exists by index to match" + return value @arc4.abimethod() def verify_app_params_get_local_num_byte_slice(self, a: Application) -> UInt64: - local_num_byte_slice, _val = op.AppParamsGet.app_local_num_byte_slice(a) - return local_num_byte_slice + value, exists = op.AppParamsGet.app_local_num_byte_slice(a) + value_index, exists_index = op.AppParamsGet.app_local_num_byte_slice(_get_1st_ref_index()) + assert value == value_index, "expected value by index to match" + assert exists == exists_index, "expected exists by index to match" + return value @arc4.abimethod() def verify_app_params_get_extra_program_pages(self, a: Application) -> UInt64: - extra_program_pages, _val = op.AppParamsGet.app_extra_program_pages(a) - return extra_program_pages + value, exists = op.AppParamsGet.app_extra_program_pages(a) + value_index, exists_index = op.AppParamsGet.app_extra_program_pages(_get_1st_ref_index()) + assert value == value_index, "expected value by index to match" + assert exists == exists_index, "expected exists by index to match" + return value @arc4.abimethod() - def verify_app_params_get_creator(self, a: Application) -> Bytes: - creator, _val = op.AppParamsGet.app_creator(a) - return creator.bytes + def verify_app_params_get_creator(self, a: Application) -> arc4.Address: + value, exists = op.AppParamsGet.app_creator(a) + value_index, exists_index = op.AppParamsGet.app_creator(_get_1st_ref_index()) + assert value == value_index, "expected value by index to match" + assert exists == exists_index, "expected exists by index to match" + return arc4.Address(value) @arc4.abimethod() - def verify_app_params_get_address(self, a: Application) -> Bytes: - address, _val = op.AppParamsGet.app_address(a) - return address.bytes + def verify_app_params_get_address(self, a: Application) -> arc4.Address: + value, exists = op.AppParamsGet.app_address(a) + value_index, exists_index = op.AppParamsGet.app_address(_get_1st_ref_index()) + assert value == value_index, "expected value by index to match" + assert exists == exists_index, "expected exists by index to match" + return arc4.Address(value) class StateAppLocalExContract(ARC4Contract): @@ -264,6 +377,11 @@ def verify_get_ex_uint64(self, a: Account, b: Application, c: Bytes) -> UInt64: def verify_delete(self, a: Account, b: Bytes) -> None: op.AppLocal.delete(a, b) + @arc4.abimethod() + def verify_exists(self, a: Account, b: Bytes) -> bool: + _value, exists = op.AppLocal.get_ex_uint64(a, 0, b) + return exists + @arc4.abimethod() def verify_put_uint64(self, a: Account, b: Bytes, c: UInt64) -> None: op.AppLocal.put(a, b, c) diff --git a/tests/artifacts/StateOps/data/GlobalStateContract.approval.teal b/tests/artifacts/StateOps/data/GlobalStateContract.approval.teal index 6b313e8..d25b864 100644 --- a/tests/artifacts/StateOps/data/GlobalStateContract.approval.teal +++ b/tests/artifacts/StateOps/data/GlobalStateContract.approval.teal @@ -6,7 +6,7 @@ tests.artifacts.StateOps.contract.GlobalStateContract.approval_program: callsub __init__ main_entrypoint@2: - // tests/artifacts/StateOps/contract.py:362 + // tests/artifacts/StateOps/contract.py:480 // class GlobalStateContract(ARC4Contract): txn NumAppArgs bz main_bare_routing@34 @@ -43,7 +43,7 @@ main_entrypoint@2: err // reject transaction main_get_implicit_key_arc4_uint_route@4: - // tests/artifacts/StateOps/contract.py:386-387 + // tests/artifacts/StateOps/contract.py:504-505 // # Getter methods for implicit key state variables // @arc4.abimethod() txn OnCompletion @@ -60,7 +60,7 @@ main_get_implicit_key_arc4_uint_route@4: return main_get_implicit_key_arc4_string_route@5: - // tests/artifacts/StateOps/contract.py:391 + // tests/artifacts/StateOps/contract.py:509 // @arc4.abimethod() txn OnCompletion ! @@ -76,7 +76,7 @@ main_get_implicit_key_arc4_string_route@5: return main_get_implicit_key_arc4_byte_route@6: - // tests/artifacts/StateOps/contract.py:395 + // tests/artifacts/StateOps/contract.py:513 // @arc4.abimethod() txn OnCompletion ! @@ -92,7 +92,7 @@ main_get_implicit_key_arc4_byte_route@6: return main_get_implicit_key_arc4_bool_route@7: - // tests/artifacts/StateOps/contract.py:399 + // tests/artifacts/StateOps/contract.py:517 // @arc4.abimethod() txn OnCompletion ! @@ -108,7 +108,7 @@ main_get_implicit_key_arc4_bool_route@7: return main_get_implicit_key_arc4_address_route@8: - // tests/artifacts/StateOps/contract.py:403 + // tests/artifacts/StateOps/contract.py:521 // @arc4.abimethod() txn OnCompletion ! @@ -124,7 +124,7 @@ main_get_implicit_key_arc4_address_route@8: return main_get_implicit_key_arc4_uint128_route@9: - // tests/artifacts/StateOps/contract.py:407 + // tests/artifacts/StateOps/contract.py:525 // @arc4.abimethod() txn OnCompletion ! @@ -140,7 +140,7 @@ main_get_implicit_key_arc4_uint128_route@9: return main_get_implicit_key_arc4_dynamic_bytes_route@10: - // tests/artifacts/StateOps/contract.py:411 + // tests/artifacts/StateOps/contract.py:529 // @arc4.abimethod() txn OnCompletion ! @@ -156,7 +156,7 @@ main_get_implicit_key_arc4_dynamic_bytes_route@10: return main_get_arc4_uint_route@11: - // tests/artifacts/StateOps/contract.py:415-416 + // tests/artifacts/StateOps/contract.py:533-534 // # Getter methods for explicit key state variables // @arc4.abimethod() txn OnCompletion @@ -173,7 +173,7 @@ main_get_arc4_uint_route@11: return main_get_arc4_string_route@12: - // tests/artifacts/StateOps/contract.py:420 + // tests/artifacts/StateOps/contract.py:538 // @arc4.abimethod() txn OnCompletion ! @@ -189,7 +189,7 @@ main_get_arc4_string_route@12: return main_get_arc4_byte_route@13: - // tests/artifacts/StateOps/contract.py:424 + // tests/artifacts/StateOps/contract.py:542 // @arc4.abimethod() txn OnCompletion ! @@ -205,7 +205,7 @@ main_get_arc4_byte_route@13: return main_get_arc4_bool_route@14: - // tests/artifacts/StateOps/contract.py:428 + // tests/artifacts/StateOps/contract.py:546 // @arc4.abimethod() txn OnCompletion ! @@ -221,7 +221,7 @@ main_get_arc4_bool_route@14: return main_get_arc4_address_route@15: - // tests/artifacts/StateOps/contract.py:432 + // tests/artifacts/StateOps/contract.py:550 // @arc4.abimethod() txn OnCompletion ! @@ -237,7 +237,7 @@ main_get_arc4_address_route@15: return main_get_arc4_uint128_route@16: - // tests/artifacts/StateOps/contract.py:436 + // tests/artifacts/StateOps/contract.py:554 // @arc4.abimethod() txn OnCompletion ! @@ -253,7 +253,7 @@ main_get_arc4_uint128_route@16: return main_get_arc4_dynamic_bytes_route@17: - // tests/artifacts/StateOps/contract.py:440 + // tests/artifacts/StateOps/contract.py:558 // @arc4.abimethod() txn OnCompletion ! @@ -269,7 +269,7 @@ main_get_arc4_dynamic_bytes_route@17: return main_set_implicit_key_arc4_uint_route@18: - // tests/artifacts/StateOps/contract.py:444-445 + // tests/artifacts/StateOps/contract.py:562-563 // # Setter methods for implicit key state variables // @arc4.abimethod() txn OnCompletion @@ -277,10 +277,10 @@ main_set_implicit_key_arc4_uint_route@18: assert // OnCompletion is NoOp txn ApplicationID assert // is not creating - // tests/artifacts/StateOps/contract.py:362 + // tests/artifacts/StateOps/contract.py:480 // class GlobalStateContract(ARC4Contract): txna ApplicationArgs 1 - // tests/artifacts/StateOps/contract.py:444-445 + // tests/artifacts/StateOps/contract.py:562-563 // # Setter methods for implicit key state variables // @arc4.abimethod() callsub set_implicit_key_arc4_uint @@ -288,109 +288,109 @@ main_set_implicit_key_arc4_uint_route@18: return main_set_implicit_key_arc4_string_route@19: - // tests/artifacts/StateOps/contract.py:449 + // tests/artifacts/StateOps/contract.py:567 // @arc4.abimethod() txn OnCompletion ! assert // OnCompletion is NoOp txn ApplicationID assert // is not creating - // tests/artifacts/StateOps/contract.py:362 + // tests/artifacts/StateOps/contract.py:480 // class GlobalStateContract(ARC4Contract): txna ApplicationArgs 1 - // tests/artifacts/StateOps/contract.py:449 + // tests/artifacts/StateOps/contract.py:567 // @arc4.abimethod() callsub set_implicit_key_arc4_string int 1 return main_set_implicit_key_arc4_byte_route@20: - // tests/artifacts/StateOps/contract.py:453 + // tests/artifacts/StateOps/contract.py:571 // @arc4.abimethod() txn OnCompletion ! assert // OnCompletion is NoOp txn ApplicationID assert // is not creating - // tests/artifacts/StateOps/contract.py:362 + // tests/artifacts/StateOps/contract.py:480 // class GlobalStateContract(ARC4Contract): txna ApplicationArgs 1 - // tests/artifacts/StateOps/contract.py:453 + // tests/artifacts/StateOps/contract.py:571 // @arc4.abimethod() callsub set_implicit_key_arc4_byte int 1 return main_set_implicit_key_arc4_bool_route@21: - // tests/artifacts/StateOps/contract.py:457 + // tests/artifacts/StateOps/contract.py:575 // @arc4.abimethod() txn OnCompletion ! assert // OnCompletion is NoOp txn ApplicationID assert // is not creating - // tests/artifacts/StateOps/contract.py:362 + // tests/artifacts/StateOps/contract.py:480 // class GlobalStateContract(ARC4Contract): txna ApplicationArgs 1 - // tests/artifacts/StateOps/contract.py:457 + // tests/artifacts/StateOps/contract.py:575 // @arc4.abimethod() callsub set_implicit_key_arc4_bool int 1 return main_set_implicit_key_arc4_address_route@22: - // tests/artifacts/StateOps/contract.py:461 + // tests/artifacts/StateOps/contract.py:579 // @arc4.abimethod() txn OnCompletion ! assert // OnCompletion is NoOp txn ApplicationID assert // is not creating - // tests/artifacts/StateOps/contract.py:362 + // tests/artifacts/StateOps/contract.py:480 // class GlobalStateContract(ARC4Contract): txna ApplicationArgs 1 - // tests/artifacts/StateOps/contract.py:461 + // tests/artifacts/StateOps/contract.py:579 // @arc4.abimethod() callsub set_implicit_key_arc4_address int 1 return main_set_implicit_key_arc4_uint128_route@23: - // tests/artifacts/StateOps/contract.py:465 + // tests/artifacts/StateOps/contract.py:583 // @arc4.abimethod() txn OnCompletion ! assert // OnCompletion is NoOp txn ApplicationID assert // is not creating - // tests/artifacts/StateOps/contract.py:362 + // tests/artifacts/StateOps/contract.py:480 // class GlobalStateContract(ARC4Contract): txna ApplicationArgs 1 - // tests/artifacts/StateOps/contract.py:465 + // tests/artifacts/StateOps/contract.py:583 // @arc4.abimethod() callsub set_implicit_key_arc4_uint128 int 1 return main_set_implicit_key_arc4_dynamic_bytes_route@24: - // tests/artifacts/StateOps/contract.py:469 + // tests/artifacts/StateOps/contract.py:587 // @arc4.abimethod() txn OnCompletion ! assert // OnCompletion is NoOp txn ApplicationID assert // is not creating - // tests/artifacts/StateOps/contract.py:362 + // tests/artifacts/StateOps/contract.py:480 // class GlobalStateContract(ARC4Contract): txna ApplicationArgs 1 - // tests/artifacts/StateOps/contract.py:469 + // tests/artifacts/StateOps/contract.py:587 // @arc4.abimethod() callsub set_implicit_key_arc4_dynamic_bytes int 1 return main_set_arc4_uint_route@25: - // tests/artifacts/StateOps/contract.py:473-474 + // tests/artifacts/StateOps/contract.py:591-592 // # Setter methods for explicit key state variables // @arc4.abimethod() txn OnCompletion @@ -398,10 +398,10 @@ main_set_arc4_uint_route@25: assert // OnCompletion is NoOp txn ApplicationID assert // is not creating - // tests/artifacts/StateOps/contract.py:362 + // tests/artifacts/StateOps/contract.py:480 // class GlobalStateContract(ARC4Contract): txna ApplicationArgs 1 - // tests/artifacts/StateOps/contract.py:473-474 + // tests/artifacts/StateOps/contract.py:591-592 // # Setter methods for explicit key state variables // @arc4.abimethod() callsub set_arc4_uint @@ -409,109 +409,109 @@ main_set_arc4_uint_route@25: return main_set_arc4_string_route@26: - // tests/artifacts/StateOps/contract.py:478 + // tests/artifacts/StateOps/contract.py:596 // @arc4.abimethod() txn OnCompletion ! assert // OnCompletion is NoOp txn ApplicationID assert // is not creating - // tests/artifacts/StateOps/contract.py:362 + // tests/artifacts/StateOps/contract.py:480 // class GlobalStateContract(ARC4Contract): txna ApplicationArgs 1 - // tests/artifacts/StateOps/contract.py:478 + // tests/artifacts/StateOps/contract.py:596 // @arc4.abimethod() callsub set_arc4_string int 1 return main_set_arc4_byte_route@27: - // tests/artifacts/StateOps/contract.py:482 + // tests/artifacts/StateOps/contract.py:600 // @arc4.abimethod() txn OnCompletion ! assert // OnCompletion is NoOp txn ApplicationID assert // is not creating - // tests/artifacts/StateOps/contract.py:362 + // tests/artifacts/StateOps/contract.py:480 // class GlobalStateContract(ARC4Contract): txna ApplicationArgs 1 - // tests/artifacts/StateOps/contract.py:482 + // tests/artifacts/StateOps/contract.py:600 // @arc4.abimethod() callsub set_arc4_byte int 1 return main_set_arc4_bool_route@28: - // tests/artifacts/StateOps/contract.py:486 + // tests/artifacts/StateOps/contract.py:604 // @arc4.abimethod() txn OnCompletion ! assert // OnCompletion is NoOp txn ApplicationID assert // is not creating - // tests/artifacts/StateOps/contract.py:362 + // tests/artifacts/StateOps/contract.py:480 // class GlobalStateContract(ARC4Contract): txna ApplicationArgs 1 - // tests/artifacts/StateOps/contract.py:486 + // tests/artifacts/StateOps/contract.py:604 // @arc4.abimethod() callsub set_arc4_bool int 1 return main_set_arc4_address_route@29: - // tests/artifacts/StateOps/contract.py:490 + // tests/artifacts/StateOps/contract.py:608 // @arc4.abimethod() txn OnCompletion ! assert // OnCompletion is NoOp txn ApplicationID assert // is not creating - // tests/artifacts/StateOps/contract.py:362 + // tests/artifacts/StateOps/contract.py:480 // class GlobalStateContract(ARC4Contract): txna ApplicationArgs 1 - // tests/artifacts/StateOps/contract.py:490 + // tests/artifacts/StateOps/contract.py:608 // @arc4.abimethod() callsub set_arc4_address int 1 return main_set_arc4_uint128_route@30: - // tests/artifacts/StateOps/contract.py:494 + // tests/artifacts/StateOps/contract.py:612 // @arc4.abimethod() txn OnCompletion ! assert // OnCompletion is NoOp txn ApplicationID assert // is not creating - // tests/artifacts/StateOps/contract.py:362 + // tests/artifacts/StateOps/contract.py:480 // class GlobalStateContract(ARC4Contract): txna ApplicationArgs 1 - // tests/artifacts/StateOps/contract.py:494 + // tests/artifacts/StateOps/contract.py:612 // @arc4.abimethod() callsub set_arc4_uint128 int 1 return main_set_arc4_dynamic_bytes_route@31: - // tests/artifacts/StateOps/contract.py:498 + // tests/artifacts/StateOps/contract.py:616 // @arc4.abimethod() txn OnCompletion ! assert // OnCompletion is NoOp txn ApplicationID assert // is not creating - // tests/artifacts/StateOps/contract.py:362 + // tests/artifacts/StateOps/contract.py:480 // class GlobalStateContract(ARC4Contract): txna ApplicationArgs 1 - // tests/artifacts/StateOps/contract.py:498 + // tests/artifacts/StateOps/contract.py:616 // @arc4.abimethod() callsub set_arc4_dynamic_bytes int 1 return main_bare_routing@34: - // tests/artifacts/StateOps/contract.py:362 + // tests/artifacts/StateOps/contract.py:480 // class GlobalStateContract(ARC4Contract): txn OnCompletion ! @@ -525,19 +525,19 @@ main_bare_routing@34: // tests.artifacts.StateOps.contract.GlobalStateContract.get_implicit_key_arc4_uint() -> bytes: get_implicit_key_arc4_uint: - // tests/artifacts/StateOps/contract.py:386-388 + // tests/artifacts/StateOps/contract.py:504-506 // # Getter methods for implicit key state variables // @arc4.abimethod() // def get_implicit_key_arc4_uint(self) -> arc4.UInt64: proto 0 1 - // tests/artifacts/StateOps/contract.py:389 + // tests/artifacts/StateOps/contract.py:507 // return self.implicit_key_arc4_uint.value int 0 - // tests/artifacts/StateOps/contract.py:364-365 + // tests/artifacts/StateOps/contract.py:482-483 // # Implicit key state variables // self.implicit_key_arc4_uint = GlobalState(arc4.UInt64(1337)) byte "implicit_key_arc4_uint" - // tests/artifacts/StateOps/contract.py:389 + // tests/artifacts/StateOps/contract.py:507 // return self.implicit_key_arc4_uint.value app_global_get_ex assert // check self.implicit_key_arc4_uint exists @@ -546,17 +546,17 @@ get_implicit_key_arc4_uint: // tests.artifacts.StateOps.contract.GlobalStateContract.get_implicit_key_arc4_string() -> bytes: get_implicit_key_arc4_string: - // tests/artifacts/StateOps/contract.py:391-392 + // tests/artifacts/StateOps/contract.py:509-510 // @arc4.abimethod() // def get_implicit_key_arc4_string(self) -> arc4.String: proto 0 1 - // tests/artifacts/StateOps/contract.py:393 + // tests/artifacts/StateOps/contract.py:511 // return self.implicit_key_arc4_string.value int 0 - // tests/artifacts/StateOps/contract.py:366 + // tests/artifacts/StateOps/contract.py:484 // self.implicit_key_arc4_string = GlobalState(arc4.String("Hello")) byte "implicit_key_arc4_string" - // tests/artifacts/StateOps/contract.py:393 + // tests/artifacts/StateOps/contract.py:511 // return self.implicit_key_arc4_string.value app_global_get_ex assert // check self.implicit_key_arc4_string exists @@ -565,17 +565,17 @@ get_implicit_key_arc4_string: // tests.artifacts.StateOps.contract.GlobalStateContract.get_implicit_key_arc4_byte() -> bytes: get_implicit_key_arc4_byte: - // tests/artifacts/StateOps/contract.py:395-396 + // tests/artifacts/StateOps/contract.py:513-514 // @arc4.abimethod() // def get_implicit_key_arc4_byte(self) -> arc4.Byte: proto 0 1 - // tests/artifacts/StateOps/contract.py:397 + // tests/artifacts/StateOps/contract.py:515 // return self.implicit_key_arc4_byte.value int 0 - // tests/artifacts/StateOps/contract.py:367 + // tests/artifacts/StateOps/contract.py:485 // self.implicit_key_arc4_byte = GlobalState(arc4.Byte(0)) byte "implicit_key_arc4_byte" - // tests/artifacts/StateOps/contract.py:397 + // tests/artifacts/StateOps/contract.py:515 // return self.implicit_key_arc4_byte.value app_global_get_ex assert // check self.implicit_key_arc4_byte exists @@ -584,17 +584,17 @@ get_implicit_key_arc4_byte: // tests.artifacts.StateOps.contract.GlobalStateContract.get_implicit_key_arc4_bool() -> bytes: get_implicit_key_arc4_bool: - // tests/artifacts/StateOps/contract.py:399-400 + // tests/artifacts/StateOps/contract.py:517-518 // @arc4.abimethod() // def get_implicit_key_arc4_bool(self) -> arc4.Bool: proto 0 1 - // tests/artifacts/StateOps/contract.py:401 + // tests/artifacts/StateOps/contract.py:519 // return self.implicit_key_arc4_bool.value int 0 - // tests/artifacts/StateOps/contract.py:368 + // tests/artifacts/StateOps/contract.py:486 // self.implicit_key_arc4_bool = GlobalState(arc4.Bool(True)) byte "implicit_key_arc4_bool" - // tests/artifacts/StateOps/contract.py:401 + // tests/artifacts/StateOps/contract.py:519 // return self.implicit_key_arc4_bool.value app_global_get_ex assert // check self.implicit_key_arc4_bool exists @@ -603,17 +603,17 @@ get_implicit_key_arc4_bool: // tests.artifacts.StateOps.contract.GlobalStateContract.get_implicit_key_arc4_address() -> bytes: get_implicit_key_arc4_address: - // tests/artifacts/StateOps/contract.py:403-404 + // tests/artifacts/StateOps/contract.py:521-522 // @arc4.abimethod() // def get_implicit_key_arc4_address(self) -> arc4.Address: proto 0 1 - // tests/artifacts/StateOps/contract.py:405 + // tests/artifacts/StateOps/contract.py:523 // return self.implicit_key_arc4_address.value int 0 - // tests/artifacts/StateOps/contract.py:369 + // tests/artifacts/StateOps/contract.py:487 // self.implicit_key_arc4_address = GlobalState(arc4.Address(Global.creator_address)) byte "implicit_key_arc4_address" - // tests/artifacts/StateOps/contract.py:405 + // tests/artifacts/StateOps/contract.py:523 // return self.implicit_key_arc4_address.value app_global_get_ex assert // check self.implicit_key_arc4_address exists @@ -622,17 +622,17 @@ get_implicit_key_arc4_address: // tests.artifacts.StateOps.contract.GlobalStateContract.get_implicit_key_arc4_uint128() -> bytes: get_implicit_key_arc4_uint128: - // tests/artifacts/StateOps/contract.py:407-408 + // tests/artifacts/StateOps/contract.py:525-526 // @arc4.abimethod() // def get_implicit_key_arc4_uint128(self) -> arc4.UInt128: proto 0 1 - // tests/artifacts/StateOps/contract.py:409 + // tests/artifacts/StateOps/contract.py:527 // return self.implicit_key_arc4_uint128.value int 0 - // tests/artifacts/StateOps/contract.py:370 + // tests/artifacts/StateOps/contract.py:488 // self.implicit_key_arc4_uint128 = GlobalState(arc4.UInt128(2**100)) byte "implicit_key_arc4_uint128" - // tests/artifacts/StateOps/contract.py:409 + // tests/artifacts/StateOps/contract.py:527 // return self.implicit_key_arc4_uint128.value app_global_get_ex assert // check self.implicit_key_arc4_uint128 exists @@ -641,17 +641,17 @@ get_implicit_key_arc4_uint128: // tests.artifacts.StateOps.contract.GlobalStateContract.get_implicit_key_arc4_dynamic_bytes() -> bytes: get_implicit_key_arc4_dynamic_bytes: - // tests/artifacts/StateOps/contract.py:411-412 + // tests/artifacts/StateOps/contract.py:529-530 // @arc4.abimethod() // def get_implicit_key_arc4_dynamic_bytes(self) -> arc4.DynamicBytes: proto 0 1 - // tests/artifacts/StateOps/contract.py:413 + // tests/artifacts/StateOps/contract.py:531 // return self.implicit_key_arc4_dynamic_bytes.value int 0 - // tests/artifacts/StateOps/contract.py:371 + // tests/artifacts/StateOps/contract.py:489 // self.implicit_key_arc4_dynamic_bytes = GlobalState(arc4.DynamicBytes(b"dynamic bytes")) byte "implicit_key_arc4_dynamic_bytes" - // tests/artifacts/StateOps/contract.py:413 + // tests/artifacts/StateOps/contract.py:531 // return self.implicit_key_arc4_dynamic_bytes.value app_global_get_ex assert // check self.implicit_key_arc4_dynamic_bytes exists @@ -660,19 +660,19 @@ get_implicit_key_arc4_dynamic_bytes: // tests.artifacts.StateOps.contract.GlobalStateContract.get_arc4_uint() -> bytes: get_arc4_uint: - // tests/artifacts/StateOps/contract.py:415-417 + // tests/artifacts/StateOps/contract.py:533-535 // # Getter methods for explicit key state variables // @arc4.abimethod() // def get_arc4_uint(self) -> arc4.UInt64: proto 0 1 - // tests/artifacts/StateOps/contract.py:418 + // tests/artifacts/StateOps/contract.py:536 // return self.arc4_uint.value int 0 - // tests/artifacts/StateOps/contract.py:373-374 + // tests/artifacts/StateOps/contract.py:491-492 // # Explicit key state variables // self.arc4_uint = GlobalState(arc4.UInt64(1337), key="explicit_key_arc4_uint") byte "explicit_key_arc4_uint" - // tests/artifacts/StateOps/contract.py:418 + // tests/artifacts/StateOps/contract.py:536 // return self.arc4_uint.value app_global_get_ex assert // check self.arc4_uint exists @@ -681,17 +681,17 @@ get_arc4_uint: // tests.artifacts.StateOps.contract.GlobalStateContract.get_arc4_string() -> bytes: get_arc4_string: - // tests/artifacts/StateOps/contract.py:420-421 + // tests/artifacts/StateOps/contract.py:538-539 // @arc4.abimethod() // def get_arc4_string(self) -> arc4.String: proto 0 1 - // tests/artifacts/StateOps/contract.py:422 + // tests/artifacts/StateOps/contract.py:540 // return self.arc4_string.value int 0 - // tests/artifacts/StateOps/contract.py:375 + // tests/artifacts/StateOps/contract.py:493 // self.arc4_string = GlobalState(arc4.String("Hello"), key="explicit_key_arc4_string") byte "explicit_key_arc4_string" - // tests/artifacts/StateOps/contract.py:422 + // tests/artifacts/StateOps/contract.py:540 // return self.arc4_string.value app_global_get_ex assert // check self.arc4_string exists @@ -700,17 +700,17 @@ get_arc4_string: // tests.artifacts.StateOps.contract.GlobalStateContract.get_arc4_byte() -> bytes: get_arc4_byte: - // tests/artifacts/StateOps/contract.py:424-425 + // tests/artifacts/StateOps/contract.py:542-543 // @arc4.abimethod() // def get_arc4_byte(self) -> arc4.Byte: proto 0 1 - // tests/artifacts/StateOps/contract.py:426 + // tests/artifacts/StateOps/contract.py:544 // return self.arc4_byte.value int 0 - // tests/artifacts/StateOps/contract.py:376 + // tests/artifacts/StateOps/contract.py:494 // self.arc4_byte = GlobalState(arc4.Byte(0), key="explicit_key_arc4_byte") byte "explicit_key_arc4_byte" - // tests/artifacts/StateOps/contract.py:426 + // tests/artifacts/StateOps/contract.py:544 // return self.arc4_byte.value app_global_get_ex assert // check self.arc4_byte exists @@ -719,17 +719,17 @@ get_arc4_byte: // tests.artifacts.StateOps.contract.GlobalStateContract.get_arc4_bool() -> bytes: get_arc4_bool: - // tests/artifacts/StateOps/contract.py:428-429 + // tests/artifacts/StateOps/contract.py:546-547 // @arc4.abimethod() // def get_arc4_bool(self) -> arc4.Bool: proto 0 1 - // tests/artifacts/StateOps/contract.py:430 + // tests/artifacts/StateOps/contract.py:548 // return self.arc4_bool.value int 0 - // tests/artifacts/StateOps/contract.py:377 + // tests/artifacts/StateOps/contract.py:495 // self.arc4_bool = GlobalState(arc4.Bool(True), key="explicit_key_arc4_bool") byte "explicit_key_arc4_bool" - // tests/artifacts/StateOps/contract.py:430 + // tests/artifacts/StateOps/contract.py:548 // return self.arc4_bool.value app_global_get_ex assert // check self.arc4_bool exists @@ -738,17 +738,17 @@ get_arc4_bool: // tests.artifacts.StateOps.contract.GlobalStateContract.get_arc4_address() -> bytes: get_arc4_address: - // tests/artifacts/StateOps/contract.py:432-433 + // tests/artifacts/StateOps/contract.py:550-551 // @arc4.abimethod() // def get_arc4_address(self) -> arc4.Address: proto 0 1 - // tests/artifacts/StateOps/contract.py:434 + // tests/artifacts/StateOps/contract.py:552 // return self.arc4_address.value int 0 - // tests/artifacts/StateOps/contract.py:379 + // tests/artifacts/StateOps/contract.py:497 // arc4.Address(Global.creator_address), key="explicit_key_arc4_address" byte "explicit_key_arc4_address" - // tests/artifacts/StateOps/contract.py:434 + // tests/artifacts/StateOps/contract.py:552 // return self.arc4_address.value app_global_get_ex assert // check self.arc4_address exists @@ -757,17 +757,17 @@ get_arc4_address: // tests.artifacts.StateOps.contract.GlobalStateContract.get_arc4_uint128() -> bytes: get_arc4_uint128: - // tests/artifacts/StateOps/contract.py:436-437 + // tests/artifacts/StateOps/contract.py:554-555 // @arc4.abimethod() // def get_arc4_uint128(self) -> arc4.UInt128: proto 0 1 - // tests/artifacts/StateOps/contract.py:438 + // tests/artifacts/StateOps/contract.py:556 // return self.arc4_uint128.value int 0 - // tests/artifacts/StateOps/contract.py:381 + // tests/artifacts/StateOps/contract.py:499 // self.arc4_uint128 = GlobalState(arc4.UInt128(2**100), key="explicit_key_arc4_uint128") byte "explicit_key_arc4_uint128" - // tests/artifacts/StateOps/contract.py:438 + // tests/artifacts/StateOps/contract.py:556 // return self.arc4_uint128.value app_global_get_ex assert // check self.arc4_uint128 exists @@ -776,17 +776,17 @@ get_arc4_uint128: // tests.artifacts.StateOps.contract.GlobalStateContract.get_arc4_dynamic_bytes() -> bytes: get_arc4_dynamic_bytes: - // tests/artifacts/StateOps/contract.py:440-441 + // tests/artifacts/StateOps/contract.py:558-559 // @arc4.abimethod() // def get_arc4_dynamic_bytes(self) -> arc4.DynamicBytes: proto 0 1 - // tests/artifacts/StateOps/contract.py:442 + // tests/artifacts/StateOps/contract.py:560 // return self.arc4_dynamic_bytes.value int 0 - // tests/artifacts/StateOps/contract.py:383 + // tests/artifacts/StateOps/contract.py:501 // arc4.DynamicBytes(b"dynamic bytes"), key="explicit_key_arc4_dynamic_bytes" byte "explicit_key_arc4_dynamic_bytes" - // tests/artifacts/StateOps/contract.py:442 + // tests/artifacts/StateOps/contract.py:560 // return self.arc4_dynamic_bytes.value app_global_get_ex assert // check self.arc4_dynamic_bytes exists @@ -795,16 +795,16 @@ get_arc4_dynamic_bytes: // tests.artifacts.StateOps.contract.GlobalStateContract.set_implicit_key_arc4_uint(value: bytes) -> void: set_implicit_key_arc4_uint: - // tests/artifacts/StateOps/contract.py:444-446 + // tests/artifacts/StateOps/contract.py:562-564 // # Setter methods for implicit key state variables // @arc4.abimethod() // def set_implicit_key_arc4_uint(self, value: arc4.UInt64) -> None: proto 1 0 - // tests/artifacts/StateOps/contract.py:364-365 + // tests/artifacts/StateOps/contract.py:482-483 // # Implicit key state variables // self.implicit_key_arc4_uint = GlobalState(arc4.UInt64(1337)) byte "implicit_key_arc4_uint" - // tests/artifacts/StateOps/contract.py:447 + // tests/artifacts/StateOps/contract.py:565 // self.implicit_key_arc4_uint.value = value frame_dig -1 app_global_put @@ -813,14 +813,14 @@ set_implicit_key_arc4_uint: // tests.artifacts.StateOps.contract.GlobalStateContract.set_implicit_key_arc4_string(value: bytes) -> void: set_implicit_key_arc4_string: - // tests/artifacts/StateOps/contract.py:449-450 + // tests/artifacts/StateOps/contract.py:567-568 // @arc4.abimethod() // def set_implicit_key_arc4_string(self, value: arc4.String) -> None: proto 1 0 - // tests/artifacts/StateOps/contract.py:366 + // tests/artifacts/StateOps/contract.py:484 // self.implicit_key_arc4_string = GlobalState(arc4.String("Hello")) byte "implicit_key_arc4_string" - // tests/artifacts/StateOps/contract.py:451 + // tests/artifacts/StateOps/contract.py:569 // self.implicit_key_arc4_string.value = value frame_dig -1 app_global_put @@ -829,14 +829,14 @@ set_implicit_key_arc4_string: // tests.artifacts.StateOps.contract.GlobalStateContract.set_implicit_key_arc4_byte(value: bytes) -> void: set_implicit_key_arc4_byte: - // tests/artifacts/StateOps/contract.py:453-454 + // tests/artifacts/StateOps/contract.py:571-572 // @arc4.abimethod() // def set_implicit_key_arc4_byte(self, value: arc4.Byte) -> None: proto 1 0 - // tests/artifacts/StateOps/contract.py:367 + // tests/artifacts/StateOps/contract.py:485 // self.implicit_key_arc4_byte = GlobalState(arc4.Byte(0)) byte "implicit_key_arc4_byte" - // tests/artifacts/StateOps/contract.py:455 + // tests/artifacts/StateOps/contract.py:573 // self.implicit_key_arc4_byte.value = value frame_dig -1 app_global_put @@ -845,14 +845,14 @@ set_implicit_key_arc4_byte: // tests.artifacts.StateOps.contract.GlobalStateContract.set_implicit_key_arc4_bool(value: bytes) -> void: set_implicit_key_arc4_bool: - // tests/artifacts/StateOps/contract.py:457-458 + // tests/artifacts/StateOps/contract.py:575-576 // @arc4.abimethod() // def set_implicit_key_arc4_bool(self, value: arc4.Bool) -> None: proto 1 0 - // tests/artifacts/StateOps/contract.py:368 + // tests/artifacts/StateOps/contract.py:486 // self.implicit_key_arc4_bool = GlobalState(arc4.Bool(True)) byte "implicit_key_arc4_bool" - // tests/artifacts/StateOps/contract.py:459 + // tests/artifacts/StateOps/contract.py:577 // self.implicit_key_arc4_bool.value = value frame_dig -1 app_global_put @@ -861,14 +861,14 @@ set_implicit_key_arc4_bool: // tests.artifacts.StateOps.contract.GlobalStateContract.set_implicit_key_arc4_address(value: bytes) -> void: set_implicit_key_arc4_address: - // tests/artifacts/StateOps/contract.py:461-462 + // tests/artifacts/StateOps/contract.py:579-580 // @arc4.abimethod() // def set_implicit_key_arc4_address(self, value: arc4.Address) -> None: proto 1 0 - // tests/artifacts/StateOps/contract.py:369 + // tests/artifacts/StateOps/contract.py:487 // self.implicit_key_arc4_address = GlobalState(arc4.Address(Global.creator_address)) byte "implicit_key_arc4_address" - // tests/artifacts/StateOps/contract.py:463 + // tests/artifacts/StateOps/contract.py:581 // self.implicit_key_arc4_address.value = value frame_dig -1 app_global_put @@ -877,14 +877,14 @@ set_implicit_key_arc4_address: // tests.artifacts.StateOps.contract.GlobalStateContract.set_implicit_key_arc4_uint128(value: bytes) -> void: set_implicit_key_arc4_uint128: - // tests/artifacts/StateOps/contract.py:465-466 + // tests/artifacts/StateOps/contract.py:583-584 // @arc4.abimethod() // def set_implicit_key_arc4_uint128(self, value: arc4.UInt128) -> None: proto 1 0 - // tests/artifacts/StateOps/contract.py:370 + // tests/artifacts/StateOps/contract.py:488 // self.implicit_key_arc4_uint128 = GlobalState(arc4.UInt128(2**100)) byte "implicit_key_arc4_uint128" - // tests/artifacts/StateOps/contract.py:467 + // tests/artifacts/StateOps/contract.py:585 // self.implicit_key_arc4_uint128.value = value frame_dig -1 app_global_put @@ -893,14 +893,14 @@ set_implicit_key_arc4_uint128: // tests.artifacts.StateOps.contract.GlobalStateContract.set_implicit_key_arc4_dynamic_bytes(value: bytes) -> void: set_implicit_key_arc4_dynamic_bytes: - // tests/artifacts/StateOps/contract.py:469-470 + // tests/artifacts/StateOps/contract.py:587-588 // @arc4.abimethod() // def set_implicit_key_arc4_dynamic_bytes(self, value: arc4.DynamicBytes) -> None: proto 1 0 - // tests/artifacts/StateOps/contract.py:371 + // tests/artifacts/StateOps/contract.py:489 // self.implicit_key_arc4_dynamic_bytes = GlobalState(arc4.DynamicBytes(b"dynamic bytes")) byte "implicit_key_arc4_dynamic_bytes" - // tests/artifacts/StateOps/contract.py:471 + // tests/artifacts/StateOps/contract.py:589 // self.implicit_key_arc4_dynamic_bytes.value = value.copy() frame_dig -1 app_global_put @@ -909,16 +909,16 @@ set_implicit_key_arc4_dynamic_bytes: // tests.artifacts.StateOps.contract.GlobalStateContract.set_arc4_uint(value: bytes) -> void: set_arc4_uint: - // tests/artifacts/StateOps/contract.py:473-475 + // tests/artifacts/StateOps/contract.py:591-593 // # Setter methods for explicit key state variables // @arc4.abimethod() // def set_arc4_uint(self, value: arc4.UInt64) -> None: proto 1 0 - // tests/artifacts/StateOps/contract.py:373-374 + // tests/artifacts/StateOps/contract.py:491-492 // # Explicit key state variables // self.arc4_uint = GlobalState(arc4.UInt64(1337), key="explicit_key_arc4_uint") byte "explicit_key_arc4_uint" - // tests/artifacts/StateOps/contract.py:476 + // tests/artifacts/StateOps/contract.py:594 // self.arc4_uint.value = value frame_dig -1 app_global_put @@ -927,14 +927,14 @@ set_arc4_uint: // tests.artifacts.StateOps.contract.GlobalStateContract.set_arc4_string(value: bytes) -> void: set_arc4_string: - // tests/artifacts/StateOps/contract.py:478-479 + // tests/artifacts/StateOps/contract.py:596-597 // @arc4.abimethod() // def set_arc4_string(self, value: arc4.String) -> None: proto 1 0 - // tests/artifacts/StateOps/contract.py:375 + // tests/artifacts/StateOps/contract.py:493 // self.arc4_string = GlobalState(arc4.String("Hello"), key="explicit_key_arc4_string") byte "explicit_key_arc4_string" - // tests/artifacts/StateOps/contract.py:480 + // tests/artifacts/StateOps/contract.py:598 // self.arc4_string.value = value frame_dig -1 app_global_put @@ -943,14 +943,14 @@ set_arc4_string: // tests.artifacts.StateOps.contract.GlobalStateContract.set_arc4_byte(value: bytes) -> void: set_arc4_byte: - // tests/artifacts/StateOps/contract.py:482-483 + // tests/artifacts/StateOps/contract.py:600-601 // @arc4.abimethod() // def set_arc4_byte(self, value: arc4.Byte) -> None: proto 1 0 - // tests/artifacts/StateOps/contract.py:376 + // tests/artifacts/StateOps/contract.py:494 // self.arc4_byte = GlobalState(arc4.Byte(0), key="explicit_key_arc4_byte") byte "explicit_key_arc4_byte" - // tests/artifacts/StateOps/contract.py:484 + // tests/artifacts/StateOps/contract.py:602 // self.arc4_byte.value = value frame_dig -1 app_global_put @@ -959,14 +959,14 @@ set_arc4_byte: // tests.artifacts.StateOps.contract.GlobalStateContract.set_arc4_bool(value: bytes) -> void: set_arc4_bool: - // tests/artifacts/StateOps/contract.py:486-487 + // tests/artifacts/StateOps/contract.py:604-605 // @arc4.abimethod() // def set_arc4_bool(self, value: arc4.Bool) -> None: proto 1 0 - // tests/artifacts/StateOps/contract.py:377 + // tests/artifacts/StateOps/contract.py:495 // self.arc4_bool = GlobalState(arc4.Bool(True), key="explicit_key_arc4_bool") byte "explicit_key_arc4_bool" - // tests/artifacts/StateOps/contract.py:488 + // tests/artifacts/StateOps/contract.py:606 // self.arc4_bool.value = value frame_dig -1 app_global_put @@ -975,14 +975,14 @@ set_arc4_bool: // tests.artifacts.StateOps.contract.GlobalStateContract.set_arc4_address(value: bytes) -> void: set_arc4_address: - // tests/artifacts/StateOps/contract.py:490-491 + // tests/artifacts/StateOps/contract.py:608-609 // @arc4.abimethod() // def set_arc4_address(self, value: arc4.Address) -> None: proto 1 0 - // tests/artifacts/StateOps/contract.py:379 + // tests/artifacts/StateOps/contract.py:497 // arc4.Address(Global.creator_address), key="explicit_key_arc4_address" byte "explicit_key_arc4_address" - // tests/artifacts/StateOps/contract.py:492 + // tests/artifacts/StateOps/contract.py:610 // self.arc4_address.value = value frame_dig -1 app_global_put @@ -991,14 +991,14 @@ set_arc4_address: // tests.artifacts.StateOps.contract.GlobalStateContract.set_arc4_uint128(value: bytes) -> void: set_arc4_uint128: - // tests/artifacts/StateOps/contract.py:494-495 + // tests/artifacts/StateOps/contract.py:612-613 // @arc4.abimethod() // def set_arc4_uint128(self, value: arc4.UInt128) -> None: proto 1 0 - // tests/artifacts/StateOps/contract.py:381 + // tests/artifacts/StateOps/contract.py:499 // self.arc4_uint128 = GlobalState(arc4.UInt128(2**100), key="explicit_key_arc4_uint128") byte "explicit_key_arc4_uint128" - // tests/artifacts/StateOps/contract.py:496 + // tests/artifacts/StateOps/contract.py:614 // self.arc4_uint128.value = value frame_dig -1 app_global_put @@ -1007,14 +1007,14 @@ set_arc4_uint128: // tests.artifacts.StateOps.contract.GlobalStateContract.set_arc4_dynamic_bytes(value: bytes) -> void: set_arc4_dynamic_bytes: - // tests/artifacts/StateOps/contract.py:498-499 + // tests/artifacts/StateOps/contract.py:616-617 // @arc4.abimethod() // def set_arc4_dynamic_bytes(self, value: arc4.DynamicBytes) -> None: proto 1 0 - // tests/artifacts/StateOps/contract.py:383 + // tests/artifacts/StateOps/contract.py:501 // arc4.DynamicBytes(b"dynamic bytes"), key="explicit_key_arc4_dynamic_bytes" byte "explicit_key_arc4_dynamic_bytes" - // tests/artifacts/StateOps/contract.py:500 + // tests/artifacts/StateOps/contract.py:618 // self.arc4_dynamic_bytes.value = value.copy() frame_dig -1 app_global_put @@ -1023,85 +1023,85 @@ set_arc4_dynamic_bytes: // tests.artifacts.StateOps.contract.GlobalStateContract.__init__() -> void: __init__: - // tests/artifacts/StateOps/contract.py:363 + // tests/artifacts/StateOps/contract.py:481 // def __init__(self) -> None: proto 0 0 - // tests/artifacts/StateOps/contract.py:364-365 + // tests/artifacts/StateOps/contract.py:482-483 // # Implicit key state variables // self.implicit_key_arc4_uint = GlobalState(arc4.UInt64(1337)) byte "implicit_key_arc4_uint" byte 0x0000000000000539 app_global_put - // tests/artifacts/StateOps/contract.py:366 + // tests/artifacts/StateOps/contract.py:484 // self.implicit_key_arc4_string = GlobalState(arc4.String("Hello")) byte "implicit_key_arc4_string" byte 0x000548656c6c6f app_global_put - // tests/artifacts/StateOps/contract.py:367 + // tests/artifacts/StateOps/contract.py:485 // self.implicit_key_arc4_byte = GlobalState(arc4.Byte(0)) byte "implicit_key_arc4_byte" byte 0x00 app_global_put - // tests/artifacts/StateOps/contract.py:368 + // tests/artifacts/StateOps/contract.py:486 // self.implicit_key_arc4_bool = GlobalState(arc4.Bool(True)) byte "implicit_key_arc4_bool" byte 0x80 app_global_put - // tests/artifacts/StateOps/contract.py:369 + // tests/artifacts/StateOps/contract.py:487 // self.implicit_key_arc4_address = GlobalState(arc4.Address(Global.creator_address)) byte "implicit_key_arc4_address" global CreatorAddress app_global_put - // tests/artifacts/StateOps/contract.py:370 + // tests/artifacts/StateOps/contract.py:488 // self.implicit_key_arc4_uint128 = GlobalState(arc4.UInt128(2**100)) byte "implicit_key_arc4_uint128" byte 0x00000010000000000000000000000000 app_global_put - // tests/artifacts/StateOps/contract.py:371 + // tests/artifacts/StateOps/contract.py:489 // self.implicit_key_arc4_dynamic_bytes = GlobalState(arc4.DynamicBytes(b"dynamic bytes")) byte "implicit_key_arc4_dynamic_bytes" byte 0x000d64796e616d6963206279746573 app_global_put - // tests/artifacts/StateOps/contract.py:373-374 + // tests/artifacts/StateOps/contract.py:491-492 // # Explicit key state variables // self.arc4_uint = GlobalState(arc4.UInt64(1337), key="explicit_key_arc4_uint") byte "explicit_key_arc4_uint" byte 0x0000000000000539 app_global_put - // tests/artifacts/StateOps/contract.py:375 + // tests/artifacts/StateOps/contract.py:493 // self.arc4_string = GlobalState(arc4.String("Hello"), key="explicit_key_arc4_string") byte "explicit_key_arc4_string" byte 0x000548656c6c6f app_global_put - // tests/artifacts/StateOps/contract.py:376 + // tests/artifacts/StateOps/contract.py:494 // self.arc4_byte = GlobalState(arc4.Byte(0), key="explicit_key_arc4_byte") byte "explicit_key_arc4_byte" byte 0x00 app_global_put - // tests/artifacts/StateOps/contract.py:377 + // tests/artifacts/StateOps/contract.py:495 // self.arc4_bool = GlobalState(arc4.Bool(True), key="explicit_key_arc4_bool") byte "explicit_key_arc4_bool" byte 0x80 app_global_put - // tests/artifacts/StateOps/contract.py:379 + // tests/artifacts/StateOps/contract.py:497 // arc4.Address(Global.creator_address), key="explicit_key_arc4_address" byte "explicit_key_arc4_address" global CreatorAddress - // tests/artifacts/StateOps/contract.py:378-380 + // tests/artifacts/StateOps/contract.py:496-498 // self.arc4_address = GlobalState( // arc4.Address(Global.creator_address), key="explicit_key_arc4_address" // ) app_global_put - // tests/artifacts/StateOps/contract.py:381 + // tests/artifacts/StateOps/contract.py:499 // self.arc4_uint128 = GlobalState(arc4.UInt128(2**100), key="explicit_key_arc4_uint128") byte "explicit_key_arc4_uint128" byte 0x00000010000000000000000000000000 app_global_put - // tests/artifacts/StateOps/contract.py:383 + // tests/artifacts/StateOps/contract.py:501 // arc4.DynamicBytes(b"dynamic bytes"), key="explicit_key_arc4_dynamic_bytes" byte "explicit_key_arc4_dynamic_bytes" byte 0x000d64796e616d6963206279746573 - // tests/artifacts/StateOps/contract.py:382-384 + // tests/artifacts/StateOps/contract.py:500-502 // self.arc4_dynamic_bytes = GlobalState( // arc4.DynamicBytes(b"dynamic bytes"), key="explicit_key_arc4_dynamic_bytes" // ) diff --git a/tests/artifacts/StateOps/data/GlobalStateContract.arc32.json b/tests/artifacts/StateOps/data/GlobalStateContract.arc32.json index a6880d7..b2dd0ce 100644 --- a/tests/artifacts/StateOps/data/GlobalStateContract.arc32.json +++ b/tests/artifacts/StateOps/data/GlobalStateContract.arc32.json @@ -142,8 +142,8 @@ } }, "source": { - "approval": "I3ByYWdtYSB2ZXJzaW9uIDEwCgp0ZXN0cy5hcnRpZmFjdHMuU3RhdGVPcHMuY29udHJhY3QuR2xvYmFsU3RhdGVDb250cmFjdC5hcHByb3ZhbF9wcm9ncmFtOgogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGJueiBtYWluX2VudHJ5cG9pbnRAMgogICAgY2FsbHN1YiBfX2luaXRfXwoKbWFpbl9lbnRyeXBvaW50QDI6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6MzYyCiAgICAvLyBjbGFzcyBHbG9iYWxTdGF0ZUNvbnRyYWN0KEFSQzRDb250cmFjdCk6CiAgICB0eG4gTnVtQXBwQXJncwogICAgYnogbWFpbl9iYXJlX3JvdXRpbmdAMzQKICAgIG1ldGhvZCAiZ2V0X2ltcGxpY2l0X2tleV9hcmM0X3VpbnQoKXVpbnQ2NCIKICAgIG1ldGhvZCAiZ2V0X2ltcGxpY2l0X2tleV9hcmM0X3N0cmluZygpc3RyaW5nIgogICAgbWV0aG9kICJnZXRfaW1wbGljaXRfa2V5X2FyYzRfYnl0ZSgpYnl0ZSIKICAgIG1ldGhvZCAiZ2V0X2ltcGxpY2l0X2tleV9hcmM0X2Jvb2woKWJvb2wiCiAgICBtZXRob2QgImdldF9pbXBsaWNpdF9rZXlfYXJjNF9hZGRyZXNzKClhZGRyZXNzIgogICAgbWV0aG9kICJnZXRfaW1wbGljaXRfa2V5X2FyYzRfdWludDEyOCgpdWludDEyOCIKICAgIG1ldGhvZCAiZ2V0X2ltcGxpY2l0X2tleV9hcmM0X2R5bmFtaWNfYnl0ZXMoKWJ5dGVbXSIKICAgIG1ldGhvZCAiZ2V0X2FyYzRfdWludCgpdWludDY0IgogICAgbWV0aG9kICJnZXRfYXJjNF9zdHJpbmcoKXN0cmluZyIKICAgIG1ldGhvZCAiZ2V0X2FyYzRfYnl0ZSgpYnl0ZSIKICAgIG1ldGhvZCAiZ2V0X2FyYzRfYm9vbCgpYm9vbCIKICAgIG1ldGhvZCAiZ2V0X2FyYzRfYWRkcmVzcygpYWRkcmVzcyIKICAgIG1ldGhvZCAiZ2V0X2FyYzRfdWludDEyOCgpdWludDEyOCIKICAgIG1ldGhvZCAiZ2V0X2FyYzRfZHluYW1pY19ieXRlcygpYnl0ZVtdIgogICAgbWV0aG9kICJzZXRfaW1wbGljaXRfa2V5X2FyYzRfdWludCh1aW50NjQpdm9pZCIKICAgIG1ldGhvZCAic2V0X2ltcGxpY2l0X2tleV9hcmM0X3N0cmluZyhzdHJpbmcpdm9pZCIKICAgIG1ldGhvZCAic2V0X2ltcGxpY2l0X2tleV9hcmM0X2J5dGUoYnl0ZSl2b2lkIgogICAgbWV0aG9kICJzZXRfaW1wbGljaXRfa2V5X2FyYzRfYm9vbChib29sKXZvaWQiCiAgICBtZXRob2QgInNldF9pbXBsaWNpdF9rZXlfYXJjNF9hZGRyZXNzKGFkZHJlc3Mpdm9pZCIKICAgIG1ldGhvZCAic2V0X2ltcGxpY2l0X2tleV9hcmM0X3VpbnQxMjgodWludDEyOCl2b2lkIgogICAgbWV0aG9kICJzZXRfaW1wbGljaXRfa2V5X2FyYzRfZHluYW1pY19ieXRlcyhieXRlW10pdm9pZCIKICAgIG1ldGhvZCAic2V0X2FyYzRfdWludCh1aW50NjQpdm9pZCIKICAgIG1ldGhvZCAic2V0X2FyYzRfc3RyaW5nKHN0cmluZyl2b2lkIgogICAgbWV0aG9kICJzZXRfYXJjNF9ieXRlKGJ5dGUpdm9pZCIKICAgIG1ldGhvZCAic2V0X2FyYzRfYm9vbChib29sKXZvaWQiCiAgICBtZXRob2QgInNldF9hcmM0X2FkZHJlc3MoYWRkcmVzcyl2b2lkIgogICAgbWV0aG9kICJzZXRfYXJjNF91aW50MTI4KHVpbnQxMjgpdm9pZCIKICAgIG1ldGhvZCAic2V0X2FyYzRfZHluYW1pY19ieXRlcyhieXRlW10pdm9pZCIKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDAKICAgIG1hdGNoIG1haW5fZ2V0X2ltcGxpY2l0X2tleV9hcmM0X3VpbnRfcm91dGVANCBtYWluX2dldF9pbXBsaWNpdF9rZXlfYXJjNF9zdHJpbmdfcm91dGVANSBtYWluX2dldF9pbXBsaWNpdF9rZXlfYXJjNF9ieXRlX3JvdXRlQDYgbWFpbl9nZXRfaW1wbGljaXRfa2V5X2FyYzRfYm9vbF9yb3V0ZUA3IG1haW5fZ2V0X2ltcGxpY2l0X2tleV9hcmM0X2FkZHJlc3Nfcm91dGVAOCBtYWluX2dldF9pbXBsaWNpdF9rZXlfYXJjNF91aW50MTI4X3JvdXRlQDkgbWFpbl9nZXRfaW1wbGljaXRfa2V5X2FyYzRfZHluYW1pY19ieXRlc19yb3V0ZUAxMCBtYWluX2dldF9hcmM0X3VpbnRfcm91dGVAMTEgbWFpbl9nZXRfYXJjNF9zdHJpbmdfcm91dGVAMTIgbWFpbl9nZXRfYXJjNF9ieXRlX3JvdXRlQDEzIG1haW5fZ2V0X2FyYzRfYm9vbF9yb3V0ZUAxNCBtYWluX2dldF9hcmM0X2FkZHJlc3Nfcm91dGVAMTUgbWFpbl9nZXRfYXJjNF91aW50MTI4X3JvdXRlQDE2IG1haW5fZ2V0X2FyYzRfZHluYW1pY19ieXRlc19yb3V0ZUAxNyBtYWluX3NldF9pbXBsaWNpdF9rZXlfYXJjNF91aW50X3JvdXRlQDE4IG1haW5fc2V0X2ltcGxpY2l0X2tleV9hcmM0X3N0cmluZ19yb3V0ZUAxOSBtYWluX3NldF9pbXBsaWNpdF9rZXlfYXJjNF9ieXRlX3JvdXRlQDIwIG1haW5fc2V0X2ltcGxpY2l0X2tleV9hcmM0X2Jvb2xfcm91dGVAMjEgbWFpbl9zZXRfaW1wbGljaXRfa2V5X2FyYzRfYWRkcmVzc19yb3V0ZUAyMiBtYWluX3NldF9pbXBsaWNpdF9rZXlfYXJjNF91aW50MTI4X3JvdXRlQDIzIG1haW5fc2V0X2ltcGxpY2l0X2tleV9hcmM0X2R5bmFtaWNfYnl0ZXNfcm91dGVAMjQgbWFpbl9zZXRfYXJjNF91aW50X3JvdXRlQDI1IG1haW5fc2V0X2FyYzRfc3RyaW5nX3JvdXRlQDI2IG1haW5fc2V0X2FyYzRfYnl0ZV9yb3V0ZUAyNyBtYWluX3NldF9hcmM0X2Jvb2xfcm91dGVAMjggbWFpbl9zZXRfYXJjNF9hZGRyZXNzX3JvdXRlQDI5IG1haW5fc2V0X2FyYzRfdWludDEyOF9yb3V0ZUAzMCBtYWluX3NldF9hcmM0X2R5bmFtaWNfYnl0ZXNfcm91dGVAMzEKICAgIGVyciAvLyByZWplY3QgdHJhbnNhY3Rpb24KCm1haW5fZ2V0X2ltcGxpY2l0X2tleV9hcmM0X3VpbnRfcm91dGVANDoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTozODYtMzg3CiAgICAvLyAjIEdldHRlciBtZXRob2RzIGZvciBpbXBsaWNpdCBrZXkgc3RhdGUgdmFyaWFibGVzCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGlzIG5vdCBjcmVhdGluZwogICAgY2FsbHN1YiBnZXRfaW1wbGljaXRfa2V5X2FyYzRfdWludAogICAgYnl0ZSAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50IDEKICAgIHJldHVybgoKbWFpbl9nZXRfaW1wbGljaXRfa2V5X2FyYzRfc3RyaW5nX3JvdXRlQDU6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6MzkxCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGlzIG5vdCBjcmVhdGluZwogICAgY2FsbHN1YiBnZXRfaW1wbGljaXRfa2V5X2FyYzRfc3RyaW5nCiAgICBieXRlIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnQgMQogICAgcmV0dXJuCgptYWluX2dldF9pbXBsaWNpdF9rZXlfYXJjNF9ieXRlX3JvdXRlQDY6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6Mzk1CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGlzIG5vdCBjcmVhdGluZwogICAgY2FsbHN1YiBnZXRfaW1wbGljaXRfa2V5X2FyYzRfYnl0ZQogICAgYnl0ZSAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50IDEKICAgIHJldHVybgoKbWFpbl9nZXRfaW1wbGljaXRfa2V5X2FyYzRfYm9vbF9yb3V0ZUA3OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjM5OQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBpcyBub3QgY3JlYXRpbmcKICAgIGNhbGxzdWIgZ2V0X2ltcGxpY2l0X2tleV9hcmM0X2Jvb2wKICAgIGJ5dGUgMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludCAxCiAgICByZXR1cm4KCm1haW5fZ2V0X2ltcGxpY2l0X2tleV9hcmM0X2FkZHJlc3Nfcm91dGVAODoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTo0MDMKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gaXMgbm90IGNyZWF0aW5nCiAgICBjYWxsc3ViIGdldF9pbXBsaWNpdF9rZXlfYXJjNF9hZGRyZXNzCiAgICBieXRlIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnQgMQogICAgcmV0dXJuCgptYWluX2dldF9pbXBsaWNpdF9rZXlfYXJjNF91aW50MTI4X3JvdXRlQDk6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6NDA3CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGlzIG5vdCBjcmVhdGluZwogICAgY2FsbHN1YiBnZXRfaW1wbGljaXRfa2V5X2FyYzRfdWludDEyOAogICAgYnl0ZSAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50IDEKICAgIHJldHVybgoKbWFpbl9nZXRfaW1wbGljaXRfa2V5X2FyYzRfZHluYW1pY19ieXRlc19yb3V0ZUAxMDoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTo0MTEKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gaXMgbm90IGNyZWF0aW5nCiAgICBjYWxsc3ViIGdldF9pbXBsaWNpdF9rZXlfYXJjNF9keW5hbWljX2J5dGVzCiAgICBieXRlIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnQgMQogICAgcmV0dXJuCgptYWluX2dldF9hcmM0X3VpbnRfcm91dGVAMTE6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6NDE1LTQxNgogICAgLy8gIyBHZXR0ZXIgbWV0aG9kcyBmb3IgZXhwbGljaXQga2V5IHN0YXRlIHZhcmlhYmxlcwogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBpcyBub3QgY3JlYXRpbmcKICAgIGNhbGxzdWIgZ2V0X2FyYzRfdWludAogICAgYnl0ZSAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50IDEKICAgIHJldHVybgoKbWFpbl9nZXRfYXJjNF9zdHJpbmdfcm91dGVAMTI6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6NDIwCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGlzIG5vdCBjcmVhdGluZwogICAgY2FsbHN1YiBnZXRfYXJjNF9zdHJpbmcKICAgIGJ5dGUgMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludCAxCiAgICByZXR1cm4KCm1haW5fZ2V0X2FyYzRfYnl0ZV9yb3V0ZUAxMzoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTo0MjQKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gaXMgbm90IGNyZWF0aW5nCiAgICBjYWxsc3ViIGdldF9hcmM0X2J5dGUKICAgIGJ5dGUgMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludCAxCiAgICByZXR1cm4KCm1haW5fZ2V0X2FyYzRfYm9vbF9yb3V0ZUAxNDoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTo0MjgKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gaXMgbm90IGNyZWF0aW5nCiAgICBjYWxsc3ViIGdldF9hcmM0X2Jvb2wKICAgIGJ5dGUgMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludCAxCiAgICByZXR1cm4KCm1haW5fZ2V0X2FyYzRfYWRkcmVzc19yb3V0ZUAxNToKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTo0MzIKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gaXMgbm90IGNyZWF0aW5nCiAgICBjYWxsc3ViIGdldF9hcmM0X2FkZHJlc3MKICAgIGJ5dGUgMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludCAxCiAgICByZXR1cm4KCm1haW5fZ2V0X2FyYzRfdWludDEyOF9yb3V0ZUAxNjoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTo0MzYKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gaXMgbm90IGNyZWF0aW5nCiAgICBjYWxsc3ViIGdldF9hcmM0X3VpbnQxMjgKICAgIGJ5dGUgMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludCAxCiAgICByZXR1cm4KCm1haW5fZ2V0X2FyYzRfZHluYW1pY19ieXRlc19yb3V0ZUAxNzoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTo0NDAKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gaXMgbm90IGNyZWF0aW5nCiAgICBjYWxsc3ViIGdldF9hcmM0X2R5bmFtaWNfYnl0ZXMKICAgIGJ5dGUgMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludCAxCiAgICByZXR1cm4KCm1haW5fc2V0X2ltcGxpY2l0X2tleV9hcmM0X3VpbnRfcm91dGVAMTg6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6NDQ0LTQ0NQogICAgLy8gIyBTZXR0ZXIgbWV0aG9kcyBmb3IgaW1wbGljaXQga2V5IHN0YXRlIHZhcmlhYmxlcwogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBpcyBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTozNjIKICAgIC8vIGNsYXNzIEdsb2JhbFN0YXRlQ29udHJhY3QoQVJDNENvbnRyYWN0KToKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTo0NDQtNDQ1CiAgICAvLyAjIFNldHRlciBtZXRob2RzIGZvciBpbXBsaWNpdCBrZXkgc3RhdGUgdmFyaWFibGVzCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiBzZXRfaW1wbGljaXRfa2V5X2FyYzRfdWludAogICAgaW50IDEKICAgIHJldHVybgoKbWFpbl9zZXRfaW1wbGljaXRfa2V5X2FyYzRfc3RyaW5nX3JvdXRlQDE5OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjQ0OQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBpcyBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTozNjIKICAgIC8vIGNsYXNzIEdsb2JhbFN0YXRlQ29udHJhY3QoQVJDNENvbnRyYWN0KToKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTo0NDkKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHNldF9pbXBsaWNpdF9rZXlfYXJjNF9zdHJpbmcKICAgIGludCAxCiAgICByZXR1cm4KCm1haW5fc2V0X2ltcGxpY2l0X2tleV9hcmM0X2J5dGVfcm91dGVAMjA6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6NDUzCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGlzIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjM2MgogICAgLy8gY2xhc3MgR2xvYmFsU3RhdGVDb250cmFjdChBUkM0Q29udHJhY3QpOgogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjQ1MwogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgc2V0X2ltcGxpY2l0X2tleV9hcmM0X2J5dGUKICAgIGludCAxCiAgICByZXR1cm4KCm1haW5fc2V0X2ltcGxpY2l0X2tleV9hcmM0X2Jvb2xfcm91dGVAMjE6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6NDU3CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGlzIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjM2MgogICAgLy8gY2xhc3MgR2xvYmFsU3RhdGVDb250cmFjdChBUkM0Q29udHJhY3QpOgogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjQ1NwogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgc2V0X2ltcGxpY2l0X2tleV9hcmM0X2Jvb2wKICAgIGludCAxCiAgICByZXR1cm4KCm1haW5fc2V0X2ltcGxpY2l0X2tleV9hcmM0X2FkZHJlc3Nfcm91dGVAMjI6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6NDYxCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGlzIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjM2MgogICAgLy8gY2xhc3MgR2xvYmFsU3RhdGVDb250cmFjdChBUkM0Q29udHJhY3QpOgogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjQ2MQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgc2V0X2ltcGxpY2l0X2tleV9hcmM0X2FkZHJlc3MKICAgIGludCAxCiAgICByZXR1cm4KCm1haW5fc2V0X2ltcGxpY2l0X2tleV9hcmM0X3VpbnQxMjhfcm91dGVAMjM6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6NDY1CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGlzIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjM2MgogICAgLy8gY2xhc3MgR2xvYmFsU3RhdGVDb250cmFjdChBUkM0Q29udHJhY3QpOgogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjQ2NQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgc2V0X2ltcGxpY2l0X2tleV9hcmM0X3VpbnQxMjgKICAgIGludCAxCiAgICByZXR1cm4KCm1haW5fc2V0X2ltcGxpY2l0X2tleV9hcmM0X2R5bmFtaWNfYnl0ZXNfcm91dGVAMjQ6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6NDY5CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGlzIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjM2MgogICAgLy8gY2xhc3MgR2xvYmFsU3RhdGVDb250cmFjdChBUkM0Q29udHJhY3QpOgogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjQ2OQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgc2V0X2ltcGxpY2l0X2tleV9hcmM0X2R5bmFtaWNfYnl0ZXMKICAgIGludCAxCiAgICByZXR1cm4KCm1haW5fc2V0X2FyYzRfdWludF9yb3V0ZUAyNToKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTo0NzMtNDc0CiAgICAvLyAjIFNldHRlciBtZXRob2RzIGZvciBleHBsaWNpdCBrZXkgc3RhdGUgdmFyaWFibGVzCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGlzIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjM2MgogICAgLy8gY2xhc3MgR2xvYmFsU3RhdGVDb250cmFjdChBUkM0Q29udHJhY3QpOgogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjQ3My00NzQKICAgIC8vICMgU2V0dGVyIG1ldGhvZHMgZm9yIGV4cGxpY2l0IGtleSBzdGF0ZSB2YXJpYWJsZXMKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHNldF9hcmM0X3VpbnQKICAgIGludCAxCiAgICByZXR1cm4KCm1haW5fc2V0X2FyYzRfc3RyaW5nX3JvdXRlQDI2OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjQ3OAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBpcyBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTozNjIKICAgIC8vIGNsYXNzIEdsb2JhbFN0YXRlQ29udHJhY3QoQVJDNENvbnRyYWN0KToKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTo0NzgKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHNldF9hcmM0X3N0cmluZwogICAgaW50IDEKICAgIHJldHVybgoKbWFpbl9zZXRfYXJjNF9ieXRlX3JvdXRlQDI3OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjQ4MgogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBpcyBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTozNjIKICAgIC8vIGNsYXNzIEdsb2JhbFN0YXRlQ29udHJhY3QoQVJDNENvbnRyYWN0KToKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTo0ODIKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHNldF9hcmM0X2J5dGUKICAgIGludCAxCiAgICByZXR1cm4KCm1haW5fc2V0X2FyYzRfYm9vbF9yb3V0ZUAyODoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTo0ODYKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gaXMgbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6MzYyCiAgICAvLyBjbGFzcyBHbG9iYWxTdGF0ZUNvbnRyYWN0KEFSQzRDb250cmFjdCk6CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6NDg2CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiBzZXRfYXJjNF9ib29sCiAgICBpbnQgMQogICAgcmV0dXJuCgptYWluX3NldF9hcmM0X2FkZHJlc3Nfcm91dGVAMjk6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6NDkwCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGlzIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjM2MgogICAgLy8gY2xhc3MgR2xvYmFsU3RhdGVDb250cmFjdChBUkM0Q29udHJhY3QpOgogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjQ5MAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgc2V0X2FyYzRfYWRkcmVzcwogICAgaW50IDEKICAgIHJldHVybgoKbWFpbl9zZXRfYXJjNF91aW50MTI4X3JvdXRlQDMwOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjQ5NAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBpcyBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTozNjIKICAgIC8vIGNsYXNzIEdsb2JhbFN0YXRlQ29udHJhY3QoQVJDNENvbnRyYWN0KToKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTo0OTQKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHNldF9hcmM0X3VpbnQxMjgKICAgIGludCAxCiAgICByZXR1cm4KCm1haW5fc2V0X2FyYzRfZHluYW1pY19ieXRlc19yb3V0ZUAzMToKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTo0OTgKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gaXMgbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6MzYyCiAgICAvLyBjbGFzcyBHbG9iYWxTdGF0ZUNvbnRyYWN0KEFSQzRDb250cmFjdCk6CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6NDk4CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiBzZXRfYXJjNF9keW5hbWljX2J5dGVzCiAgICBpbnQgMQogICAgcmV0dXJuCgptYWluX2JhcmVfcm91dGluZ0AzNDoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTozNjIKICAgIC8vIGNsYXNzIEdsb2JhbFN0YXRlQ29udHJhY3QoQVJDNENvbnRyYWN0KToKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyByZWplY3QgdHJhbnNhY3Rpb24KICAgIHR4biBBcHBsaWNhdGlvbklECiAgICAhCiAgICBhc3NlcnQgLy8gaXMgY3JlYXRpbmcKICAgIGludCAxCiAgICByZXR1cm4KCgovLyB0ZXN0cy5hcnRpZmFjdHMuU3RhdGVPcHMuY29udHJhY3QuR2xvYmFsU3RhdGVDb250cmFjdC5nZXRfaW1wbGljaXRfa2V5X2FyYzRfdWludCgpIC0+IGJ5dGVzOgpnZXRfaW1wbGljaXRfa2V5X2FyYzRfdWludDoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTozODYtMzg4CiAgICAvLyAjIEdldHRlciBtZXRob2RzIGZvciBpbXBsaWNpdCBrZXkgc3RhdGUgdmFyaWFibGVzCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gZGVmIGdldF9pbXBsaWNpdF9rZXlfYXJjNF91aW50KHNlbGYpIC0+IGFyYzQuVUludDY0OgogICAgcHJvdG8gMCAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6Mzg5CiAgICAvLyByZXR1cm4gc2VsZi5pbXBsaWNpdF9rZXlfYXJjNF91aW50LnZhbHVlCiAgICBpbnQgMAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjM2NC0zNjUKICAgIC8vICMgSW1wbGljaXQga2V5IHN0YXRlIHZhcmlhYmxlcwogICAgLy8gc2VsZi5pbXBsaWNpdF9rZXlfYXJjNF91aW50ID0gR2xvYmFsU3RhdGUoYXJjNC5VSW50NjQoMTMzNykpCiAgICBieXRlICJpbXBsaWNpdF9rZXlfYXJjNF91aW50IgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjM4OQogICAgLy8gcmV0dXJuIHNlbGYuaW1wbGljaXRfa2V5X2FyYzRfdWludC52YWx1ZQogICAgYXBwX2dsb2JhbF9nZXRfZXgKICAgIGFzc2VydCAvLyBjaGVjayBzZWxmLmltcGxpY2l0X2tleV9hcmM0X3VpbnQgZXhpc3RzCiAgICByZXRzdWIKCgovLyB0ZXN0cy5hcnRpZmFjdHMuU3RhdGVPcHMuY29udHJhY3QuR2xvYmFsU3RhdGVDb250cmFjdC5nZXRfaW1wbGljaXRfa2V5X2FyYzRfc3RyaW5nKCkgLT4gYnl0ZXM6CmdldF9pbXBsaWNpdF9rZXlfYXJjNF9zdHJpbmc6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6MzkxLTM5MgogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIGRlZiBnZXRfaW1wbGljaXRfa2V5X2FyYzRfc3RyaW5nKHNlbGYpIC0+IGFyYzQuU3RyaW5nOgogICAgcHJvdG8gMCAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6MzkzCiAgICAvLyByZXR1cm4gc2VsZi5pbXBsaWNpdF9rZXlfYXJjNF9zdHJpbmcudmFsdWUKICAgIGludCAwCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6MzY2CiAgICAvLyBzZWxmLmltcGxpY2l0X2tleV9hcmM0X3N0cmluZyA9IEdsb2JhbFN0YXRlKGFyYzQuU3RyaW5nKCJIZWxsbyIpKQogICAgYnl0ZSAiaW1wbGljaXRfa2V5X2FyYzRfc3RyaW5nIgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjM5MwogICAgLy8gcmV0dXJuIHNlbGYuaW1wbGljaXRfa2V5X2FyYzRfc3RyaW5nLnZhbHVlCiAgICBhcHBfZ2xvYmFsX2dldF9leAogICAgYXNzZXJ0IC8vIGNoZWNrIHNlbGYuaW1wbGljaXRfa2V5X2FyYzRfc3RyaW5nIGV4aXN0cwogICAgcmV0c3ViCgoKLy8gdGVzdHMuYXJ0aWZhY3RzLlN0YXRlT3BzLmNvbnRyYWN0Lkdsb2JhbFN0YXRlQ29udHJhY3QuZ2V0X2ltcGxpY2l0X2tleV9hcmM0X2J5dGUoKSAtPiBieXRlczoKZ2V0X2ltcGxpY2l0X2tleV9hcmM0X2J5dGU6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6Mzk1LTM5NgogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIGRlZiBnZXRfaW1wbGljaXRfa2V5X2FyYzRfYnl0ZShzZWxmKSAtPiBhcmM0LkJ5dGU6CiAgICBwcm90byAwIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTozOTcKICAgIC8vIHJldHVybiBzZWxmLmltcGxpY2l0X2tleV9hcmM0X2J5dGUudmFsdWUKICAgIGludCAwCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6MzY3CiAgICAvLyBzZWxmLmltcGxpY2l0X2tleV9hcmM0X2J5dGUgPSBHbG9iYWxTdGF0ZShhcmM0LkJ5dGUoMCkpCiAgICBieXRlICJpbXBsaWNpdF9rZXlfYXJjNF9ieXRlIgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjM5NwogICAgLy8gcmV0dXJuIHNlbGYuaW1wbGljaXRfa2V5X2FyYzRfYnl0ZS52YWx1ZQogICAgYXBwX2dsb2JhbF9nZXRfZXgKICAgIGFzc2VydCAvLyBjaGVjayBzZWxmLmltcGxpY2l0X2tleV9hcmM0X2J5dGUgZXhpc3RzCiAgICByZXRzdWIKCgovLyB0ZXN0cy5hcnRpZmFjdHMuU3RhdGVPcHMuY29udHJhY3QuR2xvYmFsU3RhdGVDb250cmFjdC5nZXRfaW1wbGljaXRfa2V5X2FyYzRfYm9vbCgpIC0+IGJ5dGVzOgpnZXRfaW1wbGljaXRfa2V5X2FyYzRfYm9vbDoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTozOTktNDAwCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gZGVmIGdldF9pbXBsaWNpdF9rZXlfYXJjNF9ib29sKHNlbGYpIC0+IGFyYzQuQm9vbDoKICAgIHByb3RvIDAgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjQwMQogICAgLy8gcmV0dXJuIHNlbGYuaW1wbGljaXRfa2V5X2FyYzRfYm9vbC52YWx1ZQogICAgaW50IDAKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTozNjgKICAgIC8vIHNlbGYuaW1wbGljaXRfa2V5X2FyYzRfYm9vbCA9IEdsb2JhbFN0YXRlKGFyYzQuQm9vbChUcnVlKSkKICAgIGJ5dGUgImltcGxpY2l0X2tleV9hcmM0X2Jvb2wiCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6NDAxCiAgICAvLyByZXR1cm4gc2VsZi5pbXBsaWNpdF9rZXlfYXJjNF9ib29sLnZhbHVlCiAgICBhcHBfZ2xvYmFsX2dldF9leAogICAgYXNzZXJ0IC8vIGNoZWNrIHNlbGYuaW1wbGljaXRfa2V5X2FyYzRfYm9vbCBleGlzdHMKICAgIHJldHN1YgoKCi8vIHRlc3RzLmFydGlmYWN0cy5TdGF0ZU9wcy5jb250cmFjdC5HbG9iYWxTdGF0ZUNvbnRyYWN0LmdldF9pbXBsaWNpdF9rZXlfYXJjNF9hZGRyZXNzKCkgLT4gYnl0ZXM6CmdldF9pbXBsaWNpdF9rZXlfYXJjNF9hZGRyZXNzOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjQwMy00MDQKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBkZWYgZ2V0X2ltcGxpY2l0X2tleV9hcmM0X2FkZHJlc3Moc2VsZikgLT4gYXJjNC5BZGRyZXNzOgogICAgcHJvdG8gMCAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6NDA1CiAgICAvLyByZXR1cm4gc2VsZi5pbXBsaWNpdF9rZXlfYXJjNF9hZGRyZXNzLnZhbHVlCiAgICBpbnQgMAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjM2OQogICAgLy8gc2VsZi5pbXBsaWNpdF9rZXlfYXJjNF9hZGRyZXNzID0gR2xvYmFsU3RhdGUoYXJjNC5BZGRyZXNzKEdsb2JhbC5jcmVhdG9yX2FkZHJlc3MpKQogICAgYnl0ZSAiaW1wbGljaXRfa2V5X2FyYzRfYWRkcmVzcyIKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTo0MDUKICAgIC8vIHJldHVybiBzZWxmLmltcGxpY2l0X2tleV9hcmM0X2FkZHJlc3MudmFsdWUKICAgIGFwcF9nbG9iYWxfZ2V0X2V4CiAgICBhc3NlcnQgLy8gY2hlY2sgc2VsZi5pbXBsaWNpdF9rZXlfYXJjNF9hZGRyZXNzIGV4aXN0cwogICAgcmV0c3ViCgoKLy8gdGVzdHMuYXJ0aWZhY3RzLlN0YXRlT3BzLmNvbnRyYWN0Lkdsb2JhbFN0YXRlQ29udHJhY3QuZ2V0X2ltcGxpY2l0X2tleV9hcmM0X3VpbnQxMjgoKSAtPiBieXRlczoKZ2V0X2ltcGxpY2l0X2tleV9hcmM0X3VpbnQxMjg6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6NDA3LTQwOAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIGRlZiBnZXRfaW1wbGljaXRfa2V5X2FyYzRfdWludDEyOChzZWxmKSAtPiBhcmM0LlVJbnQxMjg6CiAgICBwcm90byAwIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTo0MDkKICAgIC8vIHJldHVybiBzZWxmLmltcGxpY2l0X2tleV9hcmM0X3VpbnQxMjgudmFsdWUKICAgIGludCAwCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6MzcwCiAgICAvLyBzZWxmLmltcGxpY2l0X2tleV9hcmM0X3VpbnQxMjggPSBHbG9iYWxTdGF0ZShhcmM0LlVJbnQxMjgoMioqMTAwKSkKICAgIGJ5dGUgImltcGxpY2l0X2tleV9hcmM0X3VpbnQxMjgiCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6NDA5CiAgICAvLyByZXR1cm4gc2VsZi5pbXBsaWNpdF9rZXlfYXJjNF91aW50MTI4LnZhbHVlCiAgICBhcHBfZ2xvYmFsX2dldF9leAogICAgYXNzZXJ0IC8vIGNoZWNrIHNlbGYuaW1wbGljaXRfa2V5X2FyYzRfdWludDEyOCBleGlzdHMKICAgIHJldHN1YgoKCi8vIHRlc3RzLmFydGlmYWN0cy5TdGF0ZU9wcy5jb250cmFjdC5HbG9iYWxTdGF0ZUNvbnRyYWN0LmdldF9pbXBsaWNpdF9rZXlfYXJjNF9keW5hbWljX2J5dGVzKCkgLT4gYnl0ZXM6CmdldF9pbXBsaWNpdF9rZXlfYXJjNF9keW5hbWljX2J5dGVzOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjQxMS00MTIKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBkZWYgZ2V0X2ltcGxpY2l0X2tleV9hcmM0X2R5bmFtaWNfYnl0ZXMoc2VsZikgLT4gYXJjNC5EeW5hbWljQnl0ZXM6CiAgICBwcm90byAwIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTo0MTMKICAgIC8vIHJldHVybiBzZWxmLmltcGxpY2l0X2tleV9hcmM0X2R5bmFtaWNfYnl0ZXMudmFsdWUKICAgIGludCAwCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6MzcxCiAgICAvLyBzZWxmLmltcGxpY2l0X2tleV9hcmM0X2R5bmFtaWNfYnl0ZXMgPSBHbG9iYWxTdGF0ZShhcmM0LkR5bmFtaWNCeXRlcyhiImR5bmFtaWMgYnl0ZXMiKSkKICAgIGJ5dGUgImltcGxpY2l0X2tleV9hcmM0X2R5bmFtaWNfYnl0ZXMiCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6NDEzCiAgICAvLyByZXR1cm4gc2VsZi5pbXBsaWNpdF9rZXlfYXJjNF9keW5hbWljX2J5dGVzLnZhbHVlCiAgICBhcHBfZ2xvYmFsX2dldF9leAogICAgYXNzZXJ0IC8vIGNoZWNrIHNlbGYuaW1wbGljaXRfa2V5X2FyYzRfZHluYW1pY19ieXRlcyBleGlzdHMKICAgIHJldHN1YgoKCi8vIHRlc3RzLmFydGlmYWN0cy5TdGF0ZU9wcy5jb250cmFjdC5HbG9iYWxTdGF0ZUNvbnRyYWN0LmdldF9hcmM0X3VpbnQoKSAtPiBieXRlczoKZ2V0X2FyYzRfdWludDoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTo0MTUtNDE3CiAgICAvLyAjIEdldHRlciBtZXRob2RzIGZvciBleHBsaWNpdCBrZXkgc3RhdGUgdmFyaWFibGVzCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gZGVmIGdldF9hcmM0X3VpbnQoc2VsZikgLT4gYXJjNC5VSW50NjQ6CiAgICBwcm90byAwIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTo0MTgKICAgIC8vIHJldHVybiBzZWxmLmFyYzRfdWludC52YWx1ZQogICAgaW50IDAKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTozNzMtMzc0CiAgICAvLyAjIEV4cGxpY2l0IGtleSBzdGF0ZSB2YXJpYWJsZXMKICAgIC8vIHNlbGYuYXJjNF91aW50ID0gR2xvYmFsU3RhdGUoYXJjNC5VSW50NjQoMTMzNyksIGtleT0iZXhwbGljaXRfa2V5X2FyYzRfdWludCIpCiAgICBieXRlICJleHBsaWNpdF9rZXlfYXJjNF91aW50IgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjQxOAogICAgLy8gcmV0dXJuIHNlbGYuYXJjNF91aW50LnZhbHVlCiAgICBhcHBfZ2xvYmFsX2dldF9leAogICAgYXNzZXJ0IC8vIGNoZWNrIHNlbGYuYXJjNF91aW50IGV4aXN0cwogICAgcmV0c3ViCgoKLy8gdGVzdHMuYXJ0aWZhY3RzLlN0YXRlT3BzLmNvbnRyYWN0Lkdsb2JhbFN0YXRlQ29udHJhY3QuZ2V0X2FyYzRfc3RyaW5nKCkgLT4gYnl0ZXM6CmdldF9hcmM0X3N0cmluZzoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTo0MjAtNDIxCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gZGVmIGdldF9hcmM0X3N0cmluZyhzZWxmKSAtPiBhcmM0LlN0cmluZzoKICAgIHByb3RvIDAgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjQyMgogICAgLy8gcmV0dXJuIHNlbGYuYXJjNF9zdHJpbmcudmFsdWUKICAgIGludCAwCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6Mzc1CiAgICAvLyBzZWxmLmFyYzRfc3RyaW5nID0gR2xvYmFsU3RhdGUoYXJjNC5TdHJpbmcoIkhlbGxvIiksIGtleT0iZXhwbGljaXRfa2V5X2FyYzRfc3RyaW5nIikKICAgIGJ5dGUgImV4cGxpY2l0X2tleV9hcmM0X3N0cmluZyIKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTo0MjIKICAgIC8vIHJldHVybiBzZWxmLmFyYzRfc3RyaW5nLnZhbHVlCiAgICBhcHBfZ2xvYmFsX2dldF9leAogICAgYXNzZXJ0IC8vIGNoZWNrIHNlbGYuYXJjNF9zdHJpbmcgZXhpc3RzCiAgICByZXRzdWIKCgovLyB0ZXN0cy5hcnRpZmFjdHMuU3RhdGVPcHMuY29udHJhY3QuR2xvYmFsU3RhdGVDb250cmFjdC5nZXRfYXJjNF9ieXRlKCkgLT4gYnl0ZXM6CmdldF9hcmM0X2J5dGU6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6NDI0LTQyNQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIGRlZiBnZXRfYXJjNF9ieXRlKHNlbGYpIC0+IGFyYzQuQnl0ZToKICAgIHByb3RvIDAgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjQyNgogICAgLy8gcmV0dXJuIHNlbGYuYXJjNF9ieXRlLnZhbHVlCiAgICBpbnQgMAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjM3NgogICAgLy8gc2VsZi5hcmM0X2J5dGUgPSBHbG9iYWxTdGF0ZShhcmM0LkJ5dGUoMCksIGtleT0iZXhwbGljaXRfa2V5X2FyYzRfYnl0ZSIpCiAgICBieXRlICJleHBsaWNpdF9rZXlfYXJjNF9ieXRlIgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjQyNgogICAgLy8gcmV0dXJuIHNlbGYuYXJjNF9ieXRlLnZhbHVlCiAgICBhcHBfZ2xvYmFsX2dldF9leAogICAgYXNzZXJ0IC8vIGNoZWNrIHNlbGYuYXJjNF9ieXRlIGV4aXN0cwogICAgcmV0c3ViCgoKLy8gdGVzdHMuYXJ0aWZhY3RzLlN0YXRlT3BzLmNvbnRyYWN0Lkdsb2JhbFN0YXRlQ29udHJhY3QuZ2V0X2FyYzRfYm9vbCgpIC0+IGJ5dGVzOgpnZXRfYXJjNF9ib29sOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjQyOC00MjkKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBkZWYgZ2V0X2FyYzRfYm9vbChzZWxmKSAtPiBhcmM0LkJvb2w6CiAgICBwcm90byAwIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTo0MzAKICAgIC8vIHJldHVybiBzZWxmLmFyYzRfYm9vbC52YWx1ZQogICAgaW50IDAKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTozNzcKICAgIC8vIHNlbGYuYXJjNF9ib29sID0gR2xvYmFsU3RhdGUoYXJjNC5Cb29sKFRydWUpLCBrZXk9ImV4cGxpY2l0X2tleV9hcmM0X2Jvb2wiKQogICAgYnl0ZSAiZXhwbGljaXRfa2V5X2FyYzRfYm9vbCIKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTo0MzAKICAgIC8vIHJldHVybiBzZWxmLmFyYzRfYm9vbC52YWx1ZQogICAgYXBwX2dsb2JhbF9nZXRfZXgKICAgIGFzc2VydCAvLyBjaGVjayBzZWxmLmFyYzRfYm9vbCBleGlzdHMKICAgIHJldHN1YgoKCi8vIHRlc3RzLmFydGlmYWN0cy5TdGF0ZU9wcy5jb250cmFjdC5HbG9iYWxTdGF0ZUNvbnRyYWN0LmdldF9hcmM0X2FkZHJlc3MoKSAtPiBieXRlczoKZ2V0X2FyYzRfYWRkcmVzczoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTo0MzItNDMzCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gZGVmIGdldF9hcmM0X2FkZHJlc3Moc2VsZikgLT4gYXJjNC5BZGRyZXNzOgogICAgcHJvdG8gMCAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6NDM0CiAgICAvLyByZXR1cm4gc2VsZi5hcmM0X2FkZHJlc3MudmFsdWUKICAgIGludCAwCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6Mzc5CiAgICAvLyBhcmM0LkFkZHJlc3MoR2xvYmFsLmNyZWF0b3JfYWRkcmVzcyksIGtleT0iZXhwbGljaXRfa2V5X2FyYzRfYWRkcmVzcyIKICAgIGJ5dGUgImV4cGxpY2l0X2tleV9hcmM0X2FkZHJlc3MiCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6NDM0CiAgICAvLyByZXR1cm4gc2VsZi5hcmM0X2FkZHJlc3MudmFsdWUKICAgIGFwcF9nbG9iYWxfZ2V0X2V4CiAgICBhc3NlcnQgLy8gY2hlY2sgc2VsZi5hcmM0X2FkZHJlc3MgZXhpc3RzCiAgICByZXRzdWIKCgovLyB0ZXN0cy5hcnRpZmFjdHMuU3RhdGVPcHMuY29udHJhY3QuR2xvYmFsU3RhdGVDb250cmFjdC5nZXRfYXJjNF91aW50MTI4KCkgLT4gYnl0ZXM6CmdldF9hcmM0X3VpbnQxMjg6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6NDM2LTQzNwogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIGRlZiBnZXRfYXJjNF91aW50MTI4KHNlbGYpIC0+IGFyYzQuVUludDEyODoKICAgIHByb3RvIDAgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjQzOAogICAgLy8gcmV0dXJuIHNlbGYuYXJjNF91aW50MTI4LnZhbHVlCiAgICBpbnQgMAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjM4MQogICAgLy8gc2VsZi5hcmM0X3VpbnQxMjggPSBHbG9iYWxTdGF0ZShhcmM0LlVJbnQxMjgoMioqMTAwKSwga2V5PSJleHBsaWNpdF9rZXlfYXJjNF91aW50MTI4IikKICAgIGJ5dGUgImV4cGxpY2l0X2tleV9hcmM0X3VpbnQxMjgiCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6NDM4CiAgICAvLyByZXR1cm4gc2VsZi5hcmM0X3VpbnQxMjgudmFsdWUKICAgIGFwcF9nbG9iYWxfZ2V0X2V4CiAgICBhc3NlcnQgLy8gY2hlY2sgc2VsZi5hcmM0X3VpbnQxMjggZXhpc3RzCiAgICByZXRzdWIKCgovLyB0ZXN0cy5hcnRpZmFjdHMuU3RhdGVPcHMuY29udHJhY3QuR2xvYmFsU3RhdGVDb250cmFjdC5nZXRfYXJjNF9keW5hbWljX2J5dGVzKCkgLT4gYnl0ZXM6CmdldF9hcmM0X2R5bmFtaWNfYnl0ZXM6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6NDQwLTQ0MQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIGRlZiBnZXRfYXJjNF9keW5hbWljX2J5dGVzKHNlbGYpIC0+IGFyYzQuRHluYW1pY0J5dGVzOgogICAgcHJvdG8gMCAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6NDQyCiAgICAvLyByZXR1cm4gc2VsZi5hcmM0X2R5bmFtaWNfYnl0ZXMudmFsdWUKICAgIGludCAwCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6MzgzCiAgICAvLyBhcmM0LkR5bmFtaWNCeXRlcyhiImR5bmFtaWMgYnl0ZXMiKSwga2V5PSJleHBsaWNpdF9rZXlfYXJjNF9keW5hbWljX2J5dGVzIgogICAgYnl0ZSAiZXhwbGljaXRfa2V5X2FyYzRfZHluYW1pY19ieXRlcyIKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTo0NDIKICAgIC8vIHJldHVybiBzZWxmLmFyYzRfZHluYW1pY19ieXRlcy52YWx1ZQogICAgYXBwX2dsb2JhbF9nZXRfZXgKICAgIGFzc2VydCAvLyBjaGVjayBzZWxmLmFyYzRfZHluYW1pY19ieXRlcyBleGlzdHMKICAgIHJldHN1YgoKCi8vIHRlc3RzLmFydGlmYWN0cy5TdGF0ZU9wcy5jb250cmFjdC5HbG9iYWxTdGF0ZUNvbnRyYWN0LnNldF9pbXBsaWNpdF9rZXlfYXJjNF91aW50KHZhbHVlOiBieXRlcykgLT4gdm9pZDoKc2V0X2ltcGxpY2l0X2tleV9hcmM0X3VpbnQ6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6NDQ0LTQ0NgogICAgLy8gIyBTZXR0ZXIgbWV0aG9kcyBmb3IgaW1wbGljaXQga2V5IHN0YXRlIHZhcmlhYmxlcwogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIGRlZiBzZXRfaW1wbGljaXRfa2V5X2FyYzRfdWludChzZWxmLCB2YWx1ZTogYXJjNC5VSW50NjQpIC0+IE5vbmU6CiAgICBwcm90byAxIDAKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTozNjQtMzY1CiAgICAvLyAjIEltcGxpY2l0IGtleSBzdGF0ZSB2YXJpYWJsZXMKICAgIC8vIHNlbGYuaW1wbGljaXRfa2V5X2FyYzRfdWludCA9IEdsb2JhbFN0YXRlKGFyYzQuVUludDY0KDEzMzcpKQogICAgYnl0ZSAiaW1wbGljaXRfa2V5X2FyYzRfdWludCIKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTo0NDcKICAgIC8vIHNlbGYuaW1wbGljaXRfa2V5X2FyYzRfdWludC52YWx1ZSA9IHZhbHVlCiAgICBmcmFtZV9kaWcgLTEKICAgIGFwcF9nbG9iYWxfcHV0CiAgICByZXRzdWIKCgovLyB0ZXN0cy5hcnRpZmFjdHMuU3RhdGVPcHMuY29udHJhY3QuR2xvYmFsU3RhdGVDb250cmFjdC5zZXRfaW1wbGljaXRfa2V5X2FyYzRfc3RyaW5nKHZhbHVlOiBieXRlcykgLT4gdm9pZDoKc2V0X2ltcGxpY2l0X2tleV9hcmM0X3N0cmluZzoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTo0NDktNDUwCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gZGVmIHNldF9pbXBsaWNpdF9rZXlfYXJjNF9zdHJpbmcoc2VsZiwgdmFsdWU6IGFyYzQuU3RyaW5nKSAtPiBOb25lOgogICAgcHJvdG8gMSAwCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6MzY2CiAgICAvLyBzZWxmLmltcGxpY2l0X2tleV9hcmM0X3N0cmluZyA9IEdsb2JhbFN0YXRlKGFyYzQuU3RyaW5nKCJIZWxsbyIpKQogICAgYnl0ZSAiaW1wbGljaXRfa2V5X2FyYzRfc3RyaW5nIgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjQ1MQogICAgLy8gc2VsZi5pbXBsaWNpdF9rZXlfYXJjNF9zdHJpbmcudmFsdWUgPSB2YWx1ZQogICAgZnJhbWVfZGlnIC0xCiAgICBhcHBfZ2xvYmFsX3B1dAogICAgcmV0c3ViCgoKLy8gdGVzdHMuYXJ0aWZhY3RzLlN0YXRlT3BzLmNvbnRyYWN0Lkdsb2JhbFN0YXRlQ29udHJhY3Quc2V0X2ltcGxpY2l0X2tleV9hcmM0X2J5dGUodmFsdWU6IGJ5dGVzKSAtPiB2b2lkOgpzZXRfaW1wbGljaXRfa2V5X2FyYzRfYnl0ZToKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTo0NTMtNDU0CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gZGVmIHNldF9pbXBsaWNpdF9rZXlfYXJjNF9ieXRlKHNlbGYsIHZhbHVlOiBhcmM0LkJ5dGUpIC0+IE5vbmU6CiAgICBwcm90byAxIDAKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTozNjcKICAgIC8vIHNlbGYuaW1wbGljaXRfa2V5X2FyYzRfYnl0ZSA9IEdsb2JhbFN0YXRlKGFyYzQuQnl0ZSgwKSkKICAgIGJ5dGUgImltcGxpY2l0X2tleV9hcmM0X2J5dGUiCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6NDU1CiAgICAvLyBzZWxmLmltcGxpY2l0X2tleV9hcmM0X2J5dGUudmFsdWUgPSB2YWx1ZQogICAgZnJhbWVfZGlnIC0xCiAgICBhcHBfZ2xvYmFsX3B1dAogICAgcmV0c3ViCgoKLy8gdGVzdHMuYXJ0aWZhY3RzLlN0YXRlT3BzLmNvbnRyYWN0Lkdsb2JhbFN0YXRlQ29udHJhY3Quc2V0X2ltcGxpY2l0X2tleV9hcmM0X2Jvb2wodmFsdWU6IGJ5dGVzKSAtPiB2b2lkOgpzZXRfaW1wbGljaXRfa2V5X2FyYzRfYm9vbDoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTo0NTctNDU4CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gZGVmIHNldF9pbXBsaWNpdF9rZXlfYXJjNF9ib29sKHNlbGYsIHZhbHVlOiBhcmM0LkJvb2wpIC0+IE5vbmU6CiAgICBwcm90byAxIDAKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTozNjgKICAgIC8vIHNlbGYuaW1wbGljaXRfa2V5X2FyYzRfYm9vbCA9IEdsb2JhbFN0YXRlKGFyYzQuQm9vbChUcnVlKSkKICAgIGJ5dGUgImltcGxpY2l0X2tleV9hcmM0X2Jvb2wiCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6NDU5CiAgICAvLyBzZWxmLmltcGxpY2l0X2tleV9hcmM0X2Jvb2wudmFsdWUgPSB2YWx1ZQogICAgZnJhbWVfZGlnIC0xCiAgICBhcHBfZ2xvYmFsX3B1dAogICAgcmV0c3ViCgoKLy8gdGVzdHMuYXJ0aWZhY3RzLlN0YXRlT3BzLmNvbnRyYWN0Lkdsb2JhbFN0YXRlQ29udHJhY3Quc2V0X2ltcGxpY2l0X2tleV9hcmM0X2FkZHJlc3ModmFsdWU6IGJ5dGVzKSAtPiB2b2lkOgpzZXRfaW1wbGljaXRfa2V5X2FyYzRfYWRkcmVzczoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTo0NjEtNDYyCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gZGVmIHNldF9pbXBsaWNpdF9rZXlfYXJjNF9hZGRyZXNzKHNlbGYsIHZhbHVlOiBhcmM0LkFkZHJlc3MpIC0+IE5vbmU6CiAgICBwcm90byAxIDAKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTozNjkKICAgIC8vIHNlbGYuaW1wbGljaXRfa2V5X2FyYzRfYWRkcmVzcyA9IEdsb2JhbFN0YXRlKGFyYzQuQWRkcmVzcyhHbG9iYWwuY3JlYXRvcl9hZGRyZXNzKSkKICAgIGJ5dGUgImltcGxpY2l0X2tleV9hcmM0X2FkZHJlc3MiCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6NDYzCiAgICAvLyBzZWxmLmltcGxpY2l0X2tleV9hcmM0X2FkZHJlc3MudmFsdWUgPSB2YWx1ZQogICAgZnJhbWVfZGlnIC0xCiAgICBhcHBfZ2xvYmFsX3B1dAogICAgcmV0c3ViCgoKLy8gdGVzdHMuYXJ0aWZhY3RzLlN0YXRlT3BzLmNvbnRyYWN0Lkdsb2JhbFN0YXRlQ29udHJhY3Quc2V0X2ltcGxpY2l0X2tleV9hcmM0X3VpbnQxMjgodmFsdWU6IGJ5dGVzKSAtPiB2b2lkOgpzZXRfaW1wbGljaXRfa2V5X2FyYzRfdWludDEyODoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTo0NjUtNDY2CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gZGVmIHNldF9pbXBsaWNpdF9rZXlfYXJjNF91aW50MTI4KHNlbGYsIHZhbHVlOiBhcmM0LlVJbnQxMjgpIC0+IE5vbmU6CiAgICBwcm90byAxIDAKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTozNzAKICAgIC8vIHNlbGYuaW1wbGljaXRfa2V5X2FyYzRfdWludDEyOCA9IEdsb2JhbFN0YXRlKGFyYzQuVUludDEyOCgyKioxMDApKQogICAgYnl0ZSAiaW1wbGljaXRfa2V5X2FyYzRfdWludDEyOCIKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTo0NjcKICAgIC8vIHNlbGYuaW1wbGljaXRfa2V5X2FyYzRfdWludDEyOC52YWx1ZSA9IHZhbHVlCiAgICBmcmFtZV9kaWcgLTEKICAgIGFwcF9nbG9iYWxfcHV0CiAgICByZXRzdWIKCgovLyB0ZXN0cy5hcnRpZmFjdHMuU3RhdGVPcHMuY29udHJhY3QuR2xvYmFsU3RhdGVDb250cmFjdC5zZXRfaW1wbGljaXRfa2V5X2FyYzRfZHluYW1pY19ieXRlcyh2YWx1ZTogYnl0ZXMpIC0+IHZvaWQ6CnNldF9pbXBsaWNpdF9rZXlfYXJjNF9keW5hbWljX2J5dGVzOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjQ2OS00NzAKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBkZWYgc2V0X2ltcGxpY2l0X2tleV9hcmM0X2R5bmFtaWNfYnl0ZXMoc2VsZiwgdmFsdWU6IGFyYzQuRHluYW1pY0J5dGVzKSAtPiBOb25lOgogICAgcHJvdG8gMSAwCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6MzcxCiAgICAvLyBzZWxmLmltcGxpY2l0X2tleV9hcmM0X2R5bmFtaWNfYnl0ZXMgPSBHbG9iYWxTdGF0ZShhcmM0LkR5bmFtaWNCeXRlcyhiImR5bmFtaWMgYnl0ZXMiKSkKICAgIGJ5dGUgImltcGxpY2l0X2tleV9hcmM0X2R5bmFtaWNfYnl0ZXMiCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6NDcxCiAgICAvLyBzZWxmLmltcGxpY2l0X2tleV9hcmM0X2R5bmFtaWNfYnl0ZXMudmFsdWUgPSB2YWx1ZS5jb3B5KCkKICAgIGZyYW1lX2RpZyAtMQogICAgYXBwX2dsb2JhbF9wdXQKICAgIHJldHN1YgoKCi8vIHRlc3RzLmFydGlmYWN0cy5TdGF0ZU9wcy5jb250cmFjdC5HbG9iYWxTdGF0ZUNvbnRyYWN0LnNldF9hcmM0X3VpbnQodmFsdWU6IGJ5dGVzKSAtPiB2b2lkOgpzZXRfYXJjNF91aW50OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjQ3My00NzUKICAgIC8vICMgU2V0dGVyIG1ldGhvZHMgZm9yIGV4cGxpY2l0IGtleSBzdGF0ZSB2YXJpYWJsZXMKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBkZWYgc2V0X2FyYzRfdWludChzZWxmLCB2YWx1ZTogYXJjNC5VSW50NjQpIC0+IE5vbmU6CiAgICBwcm90byAxIDAKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTozNzMtMzc0CiAgICAvLyAjIEV4cGxpY2l0IGtleSBzdGF0ZSB2YXJpYWJsZXMKICAgIC8vIHNlbGYuYXJjNF91aW50ID0gR2xvYmFsU3RhdGUoYXJjNC5VSW50NjQoMTMzNyksIGtleT0iZXhwbGljaXRfa2V5X2FyYzRfdWludCIpCiAgICBieXRlICJleHBsaWNpdF9rZXlfYXJjNF91aW50IgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjQ3NgogICAgLy8gc2VsZi5hcmM0X3VpbnQudmFsdWUgPSB2YWx1ZQogICAgZnJhbWVfZGlnIC0xCiAgICBhcHBfZ2xvYmFsX3B1dAogICAgcmV0c3ViCgoKLy8gdGVzdHMuYXJ0aWZhY3RzLlN0YXRlT3BzLmNvbnRyYWN0Lkdsb2JhbFN0YXRlQ29udHJhY3Quc2V0X2FyYzRfc3RyaW5nKHZhbHVlOiBieXRlcykgLT4gdm9pZDoKc2V0X2FyYzRfc3RyaW5nOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjQ3OC00NzkKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBkZWYgc2V0X2FyYzRfc3RyaW5nKHNlbGYsIHZhbHVlOiBhcmM0LlN0cmluZykgLT4gTm9uZToKICAgIHByb3RvIDEgMAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjM3NQogICAgLy8gc2VsZi5hcmM0X3N0cmluZyA9IEdsb2JhbFN0YXRlKGFyYzQuU3RyaW5nKCJIZWxsbyIpLCBrZXk9ImV4cGxpY2l0X2tleV9hcmM0X3N0cmluZyIpCiAgICBieXRlICJleHBsaWNpdF9rZXlfYXJjNF9zdHJpbmciCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6NDgwCiAgICAvLyBzZWxmLmFyYzRfc3RyaW5nLnZhbHVlID0gdmFsdWUKICAgIGZyYW1lX2RpZyAtMQogICAgYXBwX2dsb2JhbF9wdXQKICAgIHJldHN1YgoKCi8vIHRlc3RzLmFydGlmYWN0cy5TdGF0ZU9wcy5jb250cmFjdC5HbG9iYWxTdGF0ZUNvbnRyYWN0LnNldF9hcmM0X2J5dGUodmFsdWU6IGJ5dGVzKSAtPiB2b2lkOgpzZXRfYXJjNF9ieXRlOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjQ4Mi00ODMKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBkZWYgc2V0X2FyYzRfYnl0ZShzZWxmLCB2YWx1ZTogYXJjNC5CeXRlKSAtPiBOb25lOgogICAgcHJvdG8gMSAwCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6Mzc2CiAgICAvLyBzZWxmLmFyYzRfYnl0ZSA9IEdsb2JhbFN0YXRlKGFyYzQuQnl0ZSgwKSwga2V5PSJleHBsaWNpdF9rZXlfYXJjNF9ieXRlIikKICAgIGJ5dGUgImV4cGxpY2l0X2tleV9hcmM0X2J5dGUiCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6NDg0CiAgICAvLyBzZWxmLmFyYzRfYnl0ZS52YWx1ZSA9IHZhbHVlCiAgICBmcmFtZV9kaWcgLTEKICAgIGFwcF9nbG9iYWxfcHV0CiAgICByZXRzdWIKCgovLyB0ZXN0cy5hcnRpZmFjdHMuU3RhdGVPcHMuY29udHJhY3QuR2xvYmFsU3RhdGVDb250cmFjdC5zZXRfYXJjNF9ib29sKHZhbHVlOiBieXRlcykgLT4gdm9pZDoKc2V0X2FyYzRfYm9vbDoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTo0ODYtNDg3CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gZGVmIHNldF9hcmM0X2Jvb2woc2VsZiwgdmFsdWU6IGFyYzQuQm9vbCkgLT4gTm9uZToKICAgIHByb3RvIDEgMAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjM3NwogICAgLy8gc2VsZi5hcmM0X2Jvb2wgPSBHbG9iYWxTdGF0ZShhcmM0LkJvb2woVHJ1ZSksIGtleT0iZXhwbGljaXRfa2V5X2FyYzRfYm9vbCIpCiAgICBieXRlICJleHBsaWNpdF9rZXlfYXJjNF9ib29sIgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjQ4OAogICAgLy8gc2VsZi5hcmM0X2Jvb2wudmFsdWUgPSB2YWx1ZQogICAgZnJhbWVfZGlnIC0xCiAgICBhcHBfZ2xvYmFsX3B1dAogICAgcmV0c3ViCgoKLy8gdGVzdHMuYXJ0aWZhY3RzLlN0YXRlT3BzLmNvbnRyYWN0Lkdsb2JhbFN0YXRlQ29udHJhY3Quc2V0X2FyYzRfYWRkcmVzcyh2YWx1ZTogYnl0ZXMpIC0+IHZvaWQ6CnNldF9hcmM0X2FkZHJlc3M6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6NDkwLTQ5MQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIGRlZiBzZXRfYXJjNF9hZGRyZXNzKHNlbGYsIHZhbHVlOiBhcmM0LkFkZHJlc3MpIC0+IE5vbmU6CiAgICBwcm90byAxIDAKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTozNzkKICAgIC8vIGFyYzQuQWRkcmVzcyhHbG9iYWwuY3JlYXRvcl9hZGRyZXNzKSwga2V5PSJleHBsaWNpdF9rZXlfYXJjNF9hZGRyZXNzIgogICAgYnl0ZSAiZXhwbGljaXRfa2V5X2FyYzRfYWRkcmVzcyIKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTo0OTIKICAgIC8vIHNlbGYuYXJjNF9hZGRyZXNzLnZhbHVlID0gdmFsdWUKICAgIGZyYW1lX2RpZyAtMQogICAgYXBwX2dsb2JhbF9wdXQKICAgIHJldHN1YgoKCi8vIHRlc3RzLmFydGlmYWN0cy5TdGF0ZU9wcy5jb250cmFjdC5HbG9iYWxTdGF0ZUNvbnRyYWN0LnNldF9hcmM0X3VpbnQxMjgodmFsdWU6IGJ5dGVzKSAtPiB2b2lkOgpzZXRfYXJjNF91aW50MTI4OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjQ5NC00OTUKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBkZWYgc2V0X2FyYzRfdWludDEyOChzZWxmLCB2YWx1ZTogYXJjNC5VSW50MTI4KSAtPiBOb25lOgogICAgcHJvdG8gMSAwCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6MzgxCiAgICAvLyBzZWxmLmFyYzRfdWludDEyOCA9IEdsb2JhbFN0YXRlKGFyYzQuVUludDEyOCgyKioxMDApLCBrZXk9ImV4cGxpY2l0X2tleV9hcmM0X3VpbnQxMjgiKQogICAgYnl0ZSAiZXhwbGljaXRfa2V5X2FyYzRfdWludDEyOCIKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTo0OTYKICAgIC8vIHNlbGYuYXJjNF91aW50MTI4LnZhbHVlID0gdmFsdWUKICAgIGZyYW1lX2RpZyAtMQogICAgYXBwX2dsb2JhbF9wdXQKICAgIHJldHN1YgoKCi8vIHRlc3RzLmFydGlmYWN0cy5TdGF0ZU9wcy5jb250cmFjdC5HbG9iYWxTdGF0ZUNvbnRyYWN0LnNldF9hcmM0X2R5bmFtaWNfYnl0ZXModmFsdWU6IGJ5dGVzKSAtPiB2b2lkOgpzZXRfYXJjNF9keW5hbWljX2J5dGVzOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjQ5OC00OTkKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBkZWYgc2V0X2FyYzRfZHluYW1pY19ieXRlcyhzZWxmLCB2YWx1ZTogYXJjNC5EeW5hbWljQnl0ZXMpIC0+IE5vbmU6CiAgICBwcm90byAxIDAKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTozODMKICAgIC8vIGFyYzQuRHluYW1pY0J5dGVzKGIiZHluYW1pYyBieXRlcyIpLCBrZXk9ImV4cGxpY2l0X2tleV9hcmM0X2R5bmFtaWNfYnl0ZXMiCiAgICBieXRlICJleHBsaWNpdF9rZXlfYXJjNF9keW5hbWljX2J5dGVzIgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjUwMAogICAgLy8gc2VsZi5hcmM0X2R5bmFtaWNfYnl0ZXMudmFsdWUgPSB2YWx1ZS5jb3B5KCkKICAgIGZyYW1lX2RpZyAtMQogICAgYXBwX2dsb2JhbF9wdXQKICAgIHJldHN1YgoKCi8vIHRlc3RzLmFydGlmYWN0cy5TdGF0ZU9wcy5jb250cmFjdC5HbG9iYWxTdGF0ZUNvbnRyYWN0Ll9faW5pdF9fKCkgLT4gdm9pZDoKX19pbml0X186CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6MzYzCiAgICAvLyBkZWYgX19pbml0X18oc2VsZikgLT4gTm9uZToKICAgIHByb3RvIDAgMAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjM2NC0zNjUKICAgIC8vICMgSW1wbGljaXQga2V5IHN0YXRlIHZhcmlhYmxlcwogICAgLy8gc2VsZi5pbXBsaWNpdF9rZXlfYXJjNF91aW50ID0gR2xvYmFsU3RhdGUoYXJjNC5VSW50NjQoMTMzNykpCiAgICBieXRlICJpbXBsaWNpdF9rZXlfYXJjNF91aW50IgogICAgYnl0ZSAweDAwMDAwMDAwMDAwMDA1MzkKICAgIGFwcF9nbG9iYWxfcHV0CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6MzY2CiAgICAvLyBzZWxmLmltcGxpY2l0X2tleV9hcmM0X3N0cmluZyA9IEdsb2JhbFN0YXRlKGFyYzQuU3RyaW5nKCJIZWxsbyIpKQogICAgYnl0ZSAiaW1wbGljaXRfa2V5X2FyYzRfc3RyaW5nIgogICAgYnl0ZSAweDAwMDU0ODY1NmM2YzZmCiAgICBhcHBfZ2xvYmFsX3B1dAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjM2NwogICAgLy8gc2VsZi5pbXBsaWNpdF9rZXlfYXJjNF9ieXRlID0gR2xvYmFsU3RhdGUoYXJjNC5CeXRlKDApKQogICAgYnl0ZSAiaW1wbGljaXRfa2V5X2FyYzRfYnl0ZSIKICAgIGJ5dGUgMHgwMAogICAgYXBwX2dsb2JhbF9wdXQKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTozNjgKICAgIC8vIHNlbGYuaW1wbGljaXRfa2V5X2FyYzRfYm9vbCA9IEdsb2JhbFN0YXRlKGFyYzQuQm9vbChUcnVlKSkKICAgIGJ5dGUgImltcGxpY2l0X2tleV9hcmM0X2Jvb2wiCiAgICBieXRlIDB4ODAKICAgIGFwcF9nbG9iYWxfcHV0CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6MzY5CiAgICAvLyBzZWxmLmltcGxpY2l0X2tleV9hcmM0X2FkZHJlc3MgPSBHbG9iYWxTdGF0ZShhcmM0LkFkZHJlc3MoR2xvYmFsLmNyZWF0b3JfYWRkcmVzcykpCiAgICBieXRlICJpbXBsaWNpdF9rZXlfYXJjNF9hZGRyZXNzIgogICAgZ2xvYmFsIENyZWF0b3JBZGRyZXNzCiAgICBhcHBfZ2xvYmFsX3B1dAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjM3MAogICAgLy8gc2VsZi5pbXBsaWNpdF9rZXlfYXJjNF91aW50MTI4ID0gR2xvYmFsU3RhdGUoYXJjNC5VSW50MTI4KDIqKjEwMCkpCiAgICBieXRlICJpbXBsaWNpdF9rZXlfYXJjNF91aW50MTI4IgogICAgYnl0ZSAweDAwMDAwMDEwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwCiAgICBhcHBfZ2xvYmFsX3B1dAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjM3MQogICAgLy8gc2VsZi5pbXBsaWNpdF9rZXlfYXJjNF9keW5hbWljX2J5dGVzID0gR2xvYmFsU3RhdGUoYXJjNC5EeW5hbWljQnl0ZXMoYiJkeW5hbWljIGJ5dGVzIikpCiAgICBieXRlICJpbXBsaWNpdF9rZXlfYXJjNF9keW5hbWljX2J5dGVzIgogICAgYnl0ZSAweDAwMGQ2NDc5NmU2MTZkNjk2MzIwNjI3OTc0NjU3MwogICAgYXBwX2dsb2JhbF9wdXQKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTozNzMtMzc0CiAgICAvLyAjIEV4cGxpY2l0IGtleSBzdGF0ZSB2YXJpYWJsZXMKICAgIC8vIHNlbGYuYXJjNF91aW50ID0gR2xvYmFsU3RhdGUoYXJjNC5VSW50NjQoMTMzNyksIGtleT0iZXhwbGljaXRfa2V5X2FyYzRfdWludCIpCiAgICBieXRlICJleHBsaWNpdF9rZXlfYXJjNF91aW50IgogICAgYnl0ZSAweDAwMDAwMDAwMDAwMDA1MzkKICAgIGFwcF9nbG9iYWxfcHV0CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6Mzc1CiAgICAvLyBzZWxmLmFyYzRfc3RyaW5nID0gR2xvYmFsU3RhdGUoYXJjNC5TdHJpbmcoIkhlbGxvIiksIGtleT0iZXhwbGljaXRfa2V5X2FyYzRfc3RyaW5nIikKICAgIGJ5dGUgImV4cGxpY2l0X2tleV9hcmM0X3N0cmluZyIKICAgIGJ5dGUgMHgwMDA1NDg2NTZjNmM2ZgogICAgYXBwX2dsb2JhbF9wdXQKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTozNzYKICAgIC8vIHNlbGYuYXJjNF9ieXRlID0gR2xvYmFsU3RhdGUoYXJjNC5CeXRlKDApLCBrZXk9ImV4cGxpY2l0X2tleV9hcmM0X2J5dGUiKQogICAgYnl0ZSAiZXhwbGljaXRfa2V5X2FyYzRfYnl0ZSIKICAgIGJ5dGUgMHgwMAogICAgYXBwX2dsb2JhbF9wdXQKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTozNzcKICAgIC8vIHNlbGYuYXJjNF9ib29sID0gR2xvYmFsU3RhdGUoYXJjNC5Cb29sKFRydWUpLCBrZXk9ImV4cGxpY2l0X2tleV9hcmM0X2Jvb2wiKQogICAgYnl0ZSAiZXhwbGljaXRfa2V5X2FyYzRfYm9vbCIKICAgIGJ5dGUgMHg4MAogICAgYXBwX2dsb2JhbF9wdXQKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTozNzkKICAgIC8vIGFyYzQuQWRkcmVzcyhHbG9iYWwuY3JlYXRvcl9hZGRyZXNzKSwga2V5PSJleHBsaWNpdF9rZXlfYXJjNF9hZGRyZXNzIgogICAgYnl0ZSAiZXhwbGljaXRfa2V5X2FyYzRfYWRkcmVzcyIKICAgIGdsb2JhbCBDcmVhdG9yQWRkcmVzcwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjM3OC0zODAKICAgIC8vIHNlbGYuYXJjNF9hZGRyZXNzID0gR2xvYmFsU3RhdGUoCiAgICAvLyAgICAgYXJjNC5BZGRyZXNzKEdsb2JhbC5jcmVhdG9yX2FkZHJlc3MpLCBrZXk9ImV4cGxpY2l0X2tleV9hcmM0X2FkZHJlc3MiCiAgICAvLyApCiAgICBhcHBfZ2xvYmFsX3B1dAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjM4MQogICAgLy8gc2VsZi5hcmM0X3VpbnQxMjggPSBHbG9iYWxTdGF0ZShhcmM0LlVJbnQxMjgoMioqMTAwKSwga2V5PSJleHBsaWNpdF9rZXlfYXJjNF91aW50MTI4IikKICAgIGJ5dGUgImV4cGxpY2l0X2tleV9hcmM0X3VpbnQxMjgiCiAgICBieXRlIDB4MDAwMDAwMTAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAKICAgIGFwcF9nbG9iYWxfcHV0CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6MzgzCiAgICAvLyBhcmM0LkR5bmFtaWNCeXRlcyhiImR5bmFtaWMgYnl0ZXMiKSwga2V5PSJleHBsaWNpdF9rZXlfYXJjNF9keW5hbWljX2J5dGVzIgogICAgYnl0ZSAiZXhwbGljaXRfa2V5X2FyYzRfZHluYW1pY19ieXRlcyIKICAgIGJ5dGUgMHgwMDBkNjQ3OTZlNjE2ZDY5NjMyMDYyNzk3NDY1NzMKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTozODItMzg0CiAgICAvLyBzZWxmLmFyYzRfZHluYW1pY19ieXRlcyA9IEdsb2JhbFN0YXRlKAogICAgLy8gICAgIGFyYzQuRHluYW1pY0J5dGVzKGIiZHluYW1pYyBieXRlcyIpLCBrZXk9ImV4cGxpY2l0X2tleV9hcmM0X2R5bmFtaWNfYnl0ZXMiCiAgICAvLyApCiAgICBhcHBfZ2xvYmFsX3B1dAogICAgcmV0c3ViCg==", - "clear": "I3ByYWdtYSB2ZXJzaW9uIDEwCgp0ZXN0cy5hcnRpZmFjdHMuU3RhdGVPcHMuY29udHJhY3QuR2xvYmFsU3RhdGVDb250cmFjdC5jbGVhcl9zdGF0ZV9wcm9ncmFtOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjM2MgogICAgLy8gY2xhc3MgR2xvYmFsU3RhdGVDb250cmFjdChBUkM0Q29udHJhY3QpOgogICAgaW50IDEKICAgIHJldHVybgo=" + "approval": "I3ByYWdtYSB2ZXJzaW9uIDEwCgp0ZXN0cy5hcnRpZmFjdHMuU3RhdGVPcHMuY29udHJhY3QuR2xvYmFsU3RhdGVDb250cmFjdC5hcHByb3ZhbF9wcm9ncmFtOgogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGJueiBtYWluX2VudHJ5cG9pbnRAMgogICAgY2FsbHN1YiBfX2luaXRfXwoKbWFpbl9lbnRyeXBvaW50QDI6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6NDgwCiAgICAvLyBjbGFzcyBHbG9iYWxTdGF0ZUNvbnRyYWN0KEFSQzRDb250cmFjdCk6CiAgICB0eG4gTnVtQXBwQXJncwogICAgYnogbWFpbl9iYXJlX3JvdXRpbmdAMzQKICAgIG1ldGhvZCAiZ2V0X2ltcGxpY2l0X2tleV9hcmM0X3VpbnQoKXVpbnQ2NCIKICAgIG1ldGhvZCAiZ2V0X2ltcGxpY2l0X2tleV9hcmM0X3N0cmluZygpc3RyaW5nIgogICAgbWV0aG9kICJnZXRfaW1wbGljaXRfa2V5X2FyYzRfYnl0ZSgpYnl0ZSIKICAgIG1ldGhvZCAiZ2V0X2ltcGxpY2l0X2tleV9hcmM0X2Jvb2woKWJvb2wiCiAgICBtZXRob2QgImdldF9pbXBsaWNpdF9rZXlfYXJjNF9hZGRyZXNzKClhZGRyZXNzIgogICAgbWV0aG9kICJnZXRfaW1wbGljaXRfa2V5X2FyYzRfdWludDEyOCgpdWludDEyOCIKICAgIG1ldGhvZCAiZ2V0X2ltcGxpY2l0X2tleV9hcmM0X2R5bmFtaWNfYnl0ZXMoKWJ5dGVbXSIKICAgIG1ldGhvZCAiZ2V0X2FyYzRfdWludCgpdWludDY0IgogICAgbWV0aG9kICJnZXRfYXJjNF9zdHJpbmcoKXN0cmluZyIKICAgIG1ldGhvZCAiZ2V0X2FyYzRfYnl0ZSgpYnl0ZSIKICAgIG1ldGhvZCAiZ2V0X2FyYzRfYm9vbCgpYm9vbCIKICAgIG1ldGhvZCAiZ2V0X2FyYzRfYWRkcmVzcygpYWRkcmVzcyIKICAgIG1ldGhvZCAiZ2V0X2FyYzRfdWludDEyOCgpdWludDEyOCIKICAgIG1ldGhvZCAiZ2V0X2FyYzRfZHluYW1pY19ieXRlcygpYnl0ZVtdIgogICAgbWV0aG9kICJzZXRfaW1wbGljaXRfa2V5X2FyYzRfdWludCh1aW50NjQpdm9pZCIKICAgIG1ldGhvZCAic2V0X2ltcGxpY2l0X2tleV9hcmM0X3N0cmluZyhzdHJpbmcpdm9pZCIKICAgIG1ldGhvZCAic2V0X2ltcGxpY2l0X2tleV9hcmM0X2J5dGUoYnl0ZSl2b2lkIgogICAgbWV0aG9kICJzZXRfaW1wbGljaXRfa2V5X2FyYzRfYm9vbChib29sKXZvaWQiCiAgICBtZXRob2QgInNldF9pbXBsaWNpdF9rZXlfYXJjNF9hZGRyZXNzKGFkZHJlc3Mpdm9pZCIKICAgIG1ldGhvZCAic2V0X2ltcGxpY2l0X2tleV9hcmM0X3VpbnQxMjgodWludDEyOCl2b2lkIgogICAgbWV0aG9kICJzZXRfaW1wbGljaXRfa2V5X2FyYzRfZHluYW1pY19ieXRlcyhieXRlW10pdm9pZCIKICAgIG1ldGhvZCAic2V0X2FyYzRfdWludCh1aW50NjQpdm9pZCIKICAgIG1ldGhvZCAic2V0X2FyYzRfc3RyaW5nKHN0cmluZyl2b2lkIgogICAgbWV0aG9kICJzZXRfYXJjNF9ieXRlKGJ5dGUpdm9pZCIKICAgIG1ldGhvZCAic2V0X2FyYzRfYm9vbChib29sKXZvaWQiCiAgICBtZXRob2QgInNldF9hcmM0X2FkZHJlc3MoYWRkcmVzcyl2b2lkIgogICAgbWV0aG9kICJzZXRfYXJjNF91aW50MTI4KHVpbnQxMjgpdm9pZCIKICAgIG1ldGhvZCAic2V0X2FyYzRfZHluYW1pY19ieXRlcyhieXRlW10pdm9pZCIKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDAKICAgIG1hdGNoIG1haW5fZ2V0X2ltcGxpY2l0X2tleV9hcmM0X3VpbnRfcm91dGVANCBtYWluX2dldF9pbXBsaWNpdF9rZXlfYXJjNF9zdHJpbmdfcm91dGVANSBtYWluX2dldF9pbXBsaWNpdF9rZXlfYXJjNF9ieXRlX3JvdXRlQDYgbWFpbl9nZXRfaW1wbGljaXRfa2V5X2FyYzRfYm9vbF9yb3V0ZUA3IG1haW5fZ2V0X2ltcGxpY2l0X2tleV9hcmM0X2FkZHJlc3Nfcm91dGVAOCBtYWluX2dldF9pbXBsaWNpdF9rZXlfYXJjNF91aW50MTI4X3JvdXRlQDkgbWFpbl9nZXRfaW1wbGljaXRfa2V5X2FyYzRfZHluYW1pY19ieXRlc19yb3V0ZUAxMCBtYWluX2dldF9hcmM0X3VpbnRfcm91dGVAMTEgbWFpbl9nZXRfYXJjNF9zdHJpbmdfcm91dGVAMTIgbWFpbl9nZXRfYXJjNF9ieXRlX3JvdXRlQDEzIG1haW5fZ2V0X2FyYzRfYm9vbF9yb3V0ZUAxNCBtYWluX2dldF9hcmM0X2FkZHJlc3Nfcm91dGVAMTUgbWFpbl9nZXRfYXJjNF91aW50MTI4X3JvdXRlQDE2IG1haW5fZ2V0X2FyYzRfZHluYW1pY19ieXRlc19yb3V0ZUAxNyBtYWluX3NldF9pbXBsaWNpdF9rZXlfYXJjNF91aW50X3JvdXRlQDE4IG1haW5fc2V0X2ltcGxpY2l0X2tleV9hcmM0X3N0cmluZ19yb3V0ZUAxOSBtYWluX3NldF9pbXBsaWNpdF9rZXlfYXJjNF9ieXRlX3JvdXRlQDIwIG1haW5fc2V0X2ltcGxpY2l0X2tleV9hcmM0X2Jvb2xfcm91dGVAMjEgbWFpbl9zZXRfaW1wbGljaXRfa2V5X2FyYzRfYWRkcmVzc19yb3V0ZUAyMiBtYWluX3NldF9pbXBsaWNpdF9rZXlfYXJjNF91aW50MTI4X3JvdXRlQDIzIG1haW5fc2V0X2ltcGxpY2l0X2tleV9hcmM0X2R5bmFtaWNfYnl0ZXNfcm91dGVAMjQgbWFpbl9zZXRfYXJjNF91aW50X3JvdXRlQDI1IG1haW5fc2V0X2FyYzRfc3RyaW5nX3JvdXRlQDI2IG1haW5fc2V0X2FyYzRfYnl0ZV9yb3V0ZUAyNyBtYWluX3NldF9hcmM0X2Jvb2xfcm91dGVAMjggbWFpbl9zZXRfYXJjNF9hZGRyZXNzX3JvdXRlQDI5IG1haW5fc2V0X2FyYzRfdWludDEyOF9yb3V0ZUAzMCBtYWluX3NldF9hcmM0X2R5bmFtaWNfYnl0ZXNfcm91dGVAMzEKICAgIGVyciAvLyByZWplY3QgdHJhbnNhY3Rpb24KCm1haW5fZ2V0X2ltcGxpY2l0X2tleV9hcmM0X3VpbnRfcm91dGVANDoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTo1MDQtNTA1CiAgICAvLyAjIEdldHRlciBtZXRob2RzIGZvciBpbXBsaWNpdCBrZXkgc3RhdGUgdmFyaWFibGVzCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGlzIG5vdCBjcmVhdGluZwogICAgY2FsbHN1YiBnZXRfaW1wbGljaXRfa2V5X2FyYzRfdWludAogICAgYnl0ZSAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50IDEKICAgIHJldHVybgoKbWFpbl9nZXRfaW1wbGljaXRfa2V5X2FyYzRfc3RyaW5nX3JvdXRlQDU6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6NTA5CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGlzIG5vdCBjcmVhdGluZwogICAgY2FsbHN1YiBnZXRfaW1wbGljaXRfa2V5X2FyYzRfc3RyaW5nCiAgICBieXRlIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnQgMQogICAgcmV0dXJuCgptYWluX2dldF9pbXBsaWNpdF9rZXlfYXJjNF9ieXRlX3JvdXRlQDY6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6NTEzCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGlzIG5vdCBjcmVhdGluZwogICAgY2FsbHN1YiBnZXRfaW1wbGljaXRfa2V5X2FyYzRfYnl0ZQogICAgYnl0ZSAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50IDEKICAgIHJldHVybgoKbWFpbl9nZXRfaW1wbGljaXRfa2V5X2FyYzRfYm9vbF9yb3V0ZUA3OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjUxNwogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBpcyBub3QgY3JlYXRpbmcKICAgIGNhbGxzdWIgZ2V0X2ltcGxpY2l0X2tleV9hcmM0X2Jvb2wKICAgIGJ5dGUgMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludCAxCiAgICByZXR1cm4KCm1haW5fZ2V0X2ltcGxpY2l0X2tleV9hcmM0X2FkZHJlc3Nfcm91dGVAODoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTo1MjEKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gaXMgbm90IGNyZWF0aW5nCiAgICBjYWxsc3ViIGdldF9pbXBsaWNpdF9rZXlfYXJjNF9hZGRyZXNzCiAgICBieXRlIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnQgMQogICAgcmV0dXJuCgptYWluX2dldF9pbXBsaWNpdF9rZXlfYXJjNF91aW50MTI4X3JvdXRlQDk6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6NTI1CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGlzIG5vdCBjcmVhdGluZwogICAgY2FsbHN1YiBnZXRfaW1wbGljaXRfa2V5X2FyYzRfdWludDEyOAogICAgYnl0ZSAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50IDEKICAgIHJldHVybgoKbWFpbl9nZXRfaW1wbGljaXRfa2V5X2FyYzRfZHluYW1pY19ieXRlc19yb3V0ZUAxMDoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTo1MjkKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gaXMgbm90IGNyZWF0aW5nCiAgICBjYWxsc3ViIGdldF9pbXBsaWNpdF9rZXlfYXJjNF9keW5hbWljX2J5dGVzCiAgICBieXRlIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnQgMQogICAgcmV0dXJuCgptYWluX2dldF9hcmM0X3VpbnRfcm91dGVAMTE6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6NTMzLTUzNAogICAgLy8gIyBHZXR0ZXIgbWV0aG9kcyBmb3IgZXhwbGljaXQga2V5IHN0YXRlIHZhcmlhYmxlcwogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBpcyBub3QgY3JlYXRpbmcKICAgIGNhbGxzdWIgZ2V0X2FyYzRfdWludAogICAgYnl0ZSAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50IDEKICAgIHJldHVybgoKbWFpbl9nZXRfYXJjNF9zdHJpbmdfcm91dGVAMTI6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6NTM4CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGlzIG5vdCBjcmVhdGluZwogICAgY2FsbHN1YiBnZXRfYXJjNF9zdHJpbmcKICAgIGJ5dGUgMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludCAxCiAgICByZXR1cm4KCm1haW5fZ2V0X2FyYzRfYnl0ZV9yb3V0ZUAxMzoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTo1NDIKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gaXMgbm90IGNyZWF0aW5nCiAgICBjYWxsc3ViIGdldF9hcmM0X2J5dGUKICAgIGJ5dGUgMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludCAxCiAgICByZXR1cm4KCm1haW5fZ2V0X2FyYzRfYm9vbF9yb3V0ZUAxNDoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTo1NDYKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gaXMgbm90IGNyZWF0aW5nCiAgICBjYWxsc3ViIGdldF9hcmM0X2Jvb2wKICAgIGJ5dGUgMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludCAxCiAgICByZXR1cm4KCm1haW5fZ2V0X2FyYzRfYWRkcmVzc19yb3V0ZUAxNToKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTo1NTAKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gaXMgbm90IGNyZWF0aW5nCiAgICBjYWxsc3ViIGdldF9hcmM0X2FkZHJlc3MKICAgIGJ5dGUgMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludCAxCiAgICByZXR1cm4KCm1haW5fZ2V0X2FyYzRfdWludDEyOF9yb3V0ZUAxNjoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTo1NTQKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gaXMgbm90IGNyZWF0aW5nCiAgICBjYWxsc3ViIGdldF9hcmM0X3VpbnQxMjgKICAgIGJ5dGUgMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludCAxCiAgICByZXR1cm4KCm1haW5fZ2V0X2FyYzRfZHluYW1pY19ieXRlc19yb3V0ZUAxNzoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTo1NTgKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gaXMgbm90IGNyZWF0aW5nCiAgICBjYWxsc3ViIGdldF9hcmM0X2R5bmFtaWNfYnl0ZXMKICAgIGJ5dGUgMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludCAxCiAgICByZXR1cm4KCm1haW5fc2V0X2ltcGxpY2l0X2tleV9hcmM0X3VpbnRfcm91dGVAMTg6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6NTYyLTU2MwogICAgLy8gIyBTZXR0ZXIgbWV0aG9kcyBmb3IgaW1wbGljaXQga2V5IHN0YXRlIHZhcmlhYmxlcwogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBpcyBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTo0ODAKICAgIC8vIGNsYXNzIEdsb2JhbFN0YXRlQ29udHJhY3QoQVJDNENvbnRyYWN0KToKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTo1NjItNTYzCiAgICAvLyAjIFNldHRlciBtZXRob2RzIGZvciBpbXBsaWNpdCBrZXkgc3RhdGUgdmFyaWFibGVzCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiBzZXRfaW1wbGljaXRfa2V5X2FyYzRfdWludAogICAgaW50IDEKICAgIHJldHVybgoKbWFpbl9zZXRfaW1wbGljaXRfa2V5X2FyYzRfc3RyaW5nX3JvdXRlQDE5OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjU2NwogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBpcyBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTo0ODAKICAgIC8vIGNsYXNzIEdsb2JhbFN0YXRlQ29udHJhY3QoQVJDNENvbnRyYWN0KToKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTo1NjcKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHNldF9pbXBsaWNpdF9rZXlfYXJjNF9zdHJpbmcKICAgIGludCAxCiAgICByZXR1cm4KCm1haW5fc2V0X2ltcGxpY2l0X2tleV9hcmM0X2J5dGVfcm91dGVAMjA6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6NTcxCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGlzIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjQ4MAogICAgLy8gY2xhc3MgR2xvYmFsU3RhdGVDb250cmFjdChBUkM0Q29udHJhY3QpOgogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjU3MQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgc2V0X2ltcGxpY2l0X2tleV9hcmM0X2J5dGUKICAgIGludCAxCiAgICByZXR1cm4KCm1haW5fc2V0X2ltcGxpY2l0X2tleV9hcmM0X2Jvb2xfcm91dGVAMjE6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6NTc1CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGlzIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjQ4MAogICAgLy8gY2xhc3MgR2xvYmFsU3RhdGVDb250cmFjdChBUkM0Q29udHJhY3QpOgogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjU3NQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgc2V0X2ltcGxpY2l0X2tleV9hcmM0X2Jvb2wKICAgIGludCAxCiAgICByZXR1cm4KCm1haW5fc2V0X2ltcGxpY2l0X2tleV9hcmM0X2FkZHJlc3Nfcm91dGVAMjI6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6NTc5CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGlzIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjQ4MAogICAgLy8gY2xhc3MgR2xvYmFsU3RhdGVDb250cmFjdChBUkM0Q29udHJhY3QpOgogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjU3OQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgc2V0X2ltcGxpY2l0X2tleV9hcmM0X2FkZHJlc3MKICAgIGludCAxCiAgICByZXR1cm4KCm1haW5fc2V0X2ltcGxpY2l0X2tleV9hcmM0X3VpbnQxMjhfcm91dGVAMjM6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6NTgzCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGlzIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjQ4MAogICAgLy8gY2xhc3MgR2xvYmFsU3RhdGVDb250cmFjdChBUkM0Q29udHJhY3QpOgogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjU4MwogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgc2V0X2ltcGxpY2l0X2tleV9hcmM0X3VpbnQxMjgKICAgIGludCAxCiAgICByZXR1cm4KCm1haW5fc2V0X2ltcGxpY2l0X2tleV9hcmM0X2R5bmFtaWNfYnl0ZXNfcm91dGVAMjQ6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6NTg3CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGlzIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjQ4MAogICAgLy8gY2xhc3MgR2xvYmFsU3RhdGVDb250cmFjdChBUkM0Q29udHJhY3QpOgogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjU4NwogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgc2V0X2ltcGxpY2l0X2tleV9hcmM0X2R5bmFtaWNfYnl0ZXMKICAgIGludCAxCiAgICByZXR1cm4KCm1haW5fc2V0X2FyYzRfdWludF9yb3V0ZUAyNToKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTo1OTEtNTkyCiAgICAvLyAjIFNldHRlciBtZXRob2RzIGZvciBleHBsaWNpdCBrZXkgc3RhdGUgdmFyaWFibGVzCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGlzIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjQ4MAogICAgLy8gY2xhc3MgR2xvYmFsU3RhdGVDb250cmFjdChBUkM0Q29udHJhY3QpOgogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjU5MS01OTIKICAgIC8vICMgU2V0dGVyIG1ldGhvZHMgZm9yIGV4cGxpY2l0IGtleSBzdGF0ZSB2YXJpYWJsZXMKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHNldF9hcmM0X3VpbnQKICAgIGludCAxCiAgICByZXR1cm4KCm1haW5fc2V0X2FyYzRfc3RyaW5nX3JvdXRlQDI2OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjU5NgogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBpcyBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTo0ODAKICAgIC8vIGNsYXNzIEdsb2JhbFN0YXRlQ29udHJhY3QoQVJDNENvbnRyYWN0KToKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTo1OTYKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHNldF9hcmM0X3N0cmluZwogICAgaW50IDEKICAgIHJldHVybgoKbWFpbl9zZXRfYXJjNF9ieXRlX3JvdXRlQDI3OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjYwMAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBpcyBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTo0ODAKICAgIC8vIGNsYXNzIEdsb2JhbFN0YXRlQ29udHJhY3QoQVJDNENvbnRyYWN0KToKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTo2MDAKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHNldF9hcmM0X2J5dGUKICAgIGludCAxCiAgICByZXR1cm4KCm1haW5fc2V0X2FyYzRfYm9vbF9yb3V0ZUAyODoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTo2MDQKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gaXMgbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6NDgwCiAgICAvLyBjbGFzcyBHbG9iYWxTdGF0ZUNvbnRyYWN0KEFSQzRDb250cmFjdCk6CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6NjA0CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiBzZXRfYXJjNF9ib29sCiAgICBpbnQgMQogICAgcmV0dXJuCgptYWluX3NldF9hcmM0X2FkZHJlc3Nfcm91dGVAMjk6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6NjA4CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGlzIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjQ4MAogICAgLy8gY2xhc3MgR2xvYmFsU3RhdGVDb250cmFjdChBUkM0Q29udHJhY3QpOgogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjYwOAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgc2V0X2FyYzRfYWRkcmVzcwogICAgaW50IDEKICAgIHJldHVybgoKbWFpbl9zZXRfYXJjNF91aW50MTI4X3JvdXRlQDMwOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjYxMgogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBpcyBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTo0ODAKICAgIC8vIGNsYXNzIEdsb2JhbFN0YXRlQ29udHJhY3QoQVJDNENvbnRyYWN0KToKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTo2MTIKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHNldF9hcmM0X3VpbnQxMjgKICAgIGludCAxCiAgICByZXR1cm4KCm1haW5fc2V0X2FyYzRfZHluYW1pY19ieXRlc19yb3V0ZUAzMToKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTo2MTYKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gaXMgbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6NDgwCiAgICAvLyBjbGFzcyBHbG9iYWxTdGF0ZUNvbnRyYWN0KEFSQzRDb250cmFjdCk6CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6NjE2CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiBzZXRfYXJjNF9keW5hbWljX2J5dGVzCiAgICBpbnQgMQogICAgcmV0dXJuCgptYWluX2JhcmVfcm91dGluZ0AzNDoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTo0ODAKICAgIC8vIGNsYXNzIEdsb2JhbFN0YXRlQ29udHJhY3QoQVJDNENvbnRyYWN0KToKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyByZWplY3QgdHJhbnNhY3Rpb24KICAgIHR4biBBcHBsaWNhdGlvbklECiAgICAhCiAgICBhc3NlcnQgLy8gaXMgY3JlYXRpbmcKICAgIGludCAxCiAgICByZXR1cm4KCgovLyB0ZXN0cy5hcnRpZmFjdHMuU3RhdGVPcHMuY29udHJhY3QuR2xvYmFsU3RhdGVDb250cmFjdC5nZXRfaW1wbGljaXRfa2V5X2FyYzRfdWludCgpIC0+IGJ5dGVzOgpnZXRfaW1wbGljaXRfa2V5X2FyYzRfdWludDoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTo1MDQtNTA2CiAgICAvLyAjIEdldHRlciBtZXRob2RzIGZvciBpbXBsaWNpdCBrZXkgc3RhdGUgdmFyaWFibGVzCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gZGVmIGdldF9pbXBsaWNpdF9rZXlfYXJjNF91aW50KHNlbGYpIC0+IGFyYzQuVUludDY0OgogICAgcHJvdG8gMCAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6NTA3CiAgICAvLyByZXR1cm4gc2VsZi5pbXBsaWNpdF9rZXlfYXJjNF91aW50LnZhbHVlCiAgICBpbnQgMAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjQ4Mi00ODMKICAgIC8vICMgSW1wbGljaXQga2V5IHN0YXRlIHZhcmlhYmxlcwogICAgLy8gc2VsZi5pbXBsaWNpdF9rZXlfYXJjNF91aW50ID0gR2xvYmFsU3RhdGUoYXJjNC5VSW50NjQoMTMzNykpCiAgICBieXRlICJpbXBsaWNpdF9rZXlfYXJjNF91aW50IgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjUwNwogICAgLy8gcmV0dXJuIHNlbGYuaW1wbGljaXRfa2V5X2FyYzRfdWludC52YWx1ZQogICAgYXBwX2dsb2JhbF9nZXRfZXgKICAgIGFzc2VydCAvLyBjaGVjayBzZWxmLmltcGxpY2l0X2tleV9hcmM0X3VpbnQgZXhpc3RzCiAgICByZXRzdWIKCgovLyB0ZXN0cy5hcnRpZmFjdHMuU3RhdGVPcHMuY29udHJhY3QuR2xvYmFsU3RhdGVDb250cmFjdC5nZXRfaW1wbGljaXRfa2V5X2FyYzRfc3RyaW5nKCkgLT4gYnl0ZXM6CmdldF9pbXBsaWNpdF9rZXlfYXJjNF9zdHJpbmc6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6NTA5LTUxMAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIGRlZiBnZXRfaW1wbGljaXRfa2V5X2FyYzRfc3RyaW5nKHNlbGYpIC0+IGFyYzQuU3RyaW5nOgogICAgcHJvdG8gMCAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6NTExCiAgICAvLyByZXR1cm4gc2VsZi5pbXBsaWNpdF9rZXlfYXJjNF9zdHJpbmcudmFsdWUKICAgIGludCAwCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6NDg0CiAgICAvLyBzZWxmLmltcGxpY2l0X2tleV9hcmM0X3N0cmluZyA9IEdsb2JhbFN0YXRlKGFyYzQuU3RyaW5nKCJIZWxsbyIpKQogICAgYnl0ZSAiaW1wbGljaXRfa2V5X2FyYzRfc3RyaW5nIgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjUxMQogICAgLy8gcmV0dXJuIHNlbGYuaW1wbGljaXRfa2V5X2FyYzRfc3RyaW5nLnZhbHVlCiAgICBhcHBfZ2xvYmFsX2dldF9leAogICAgYXNzZXJ0IC8vIGNoZWNrIHNlbGYuaW1wbGljaXRfa2V5X2FyYzRfc3RyaW5nIGV4aXN0cwogICAgcmV0c3ViCgoKLy8gdGVzdHMuYXJ0aWZhY3RzLlN0YXRlT3BzLmNvbnRyYWN0Lkdsb2JhbFN0YXRlQ29udHJhY3QuZ2V0X2ltcGxpY2l0X2tleV9hcmM0X2J5dGUoKSAtPiBieXRlczoKZ2V0X2ltcGxpY2l0X2tleV9hcmM0X2J5dGU6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6NTEzLTUxNAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIGRlZiBnZXRfaW1wbGljaXRfa2V5X2FyYzRfYnl0ZShzZWxmKSAtPiBhcmM0LkJ5dGU6CiAgICBwcm90byAwIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTo1MTUKICAgIC8vIHJldHVybiBzZWxmLmltcGxpY2l0X2tleV9hcmM0X2J5dGUudmFsdWUKICAgIGludCAwCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6NDg1CiAgICAvLyBzZWxmLmltcGxpY2l0X2tleV9hcmM0X2J5dGUgPSBHbG9iYWxTdGF0ZShhcmM0LkJ5dGUoMCkpCiAgICBieXRlICJpbXBsaWNpdF9rZXlfYXJjNF9ieXRlIgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjUxNQogICAgLy8gcmV0dXJuIHNlbGYuaW1wbGljaXRfa2V5X2FyYzRfYnl0ZS52YWx1ZQogICAgYXBwX2dsb2JhbF9nZXRfZXgKICAgIGFzc2VydCAvLyBjaGVjayBzZWxmLmltcGxpY2l0X2tleV9hcmM0X2J5dGUgZXhpc3RzCiAgICByZXRzdWIKCgovLyB0ZXN0cy5hcnRpZmFjdHMuU3RhdGVPcHMuY29udHJhY3QuR2xvYmFsU3RhdGVDb250cmFjdC5nZXRfaW1wbGljaXRfa2V5X2FyYzRfYm9vbCgpIC0+IGJ5dGVzOgpnZXRfaW1wbGljaXRfa2V5X2FyYzRfYm9vbDoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTo1MTctNTE4CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gZGVmIGdldF9pbXBsaWNpdF9rZXlfYXJjNF9ib29sKHNlbGYpIC0+IGFyYzQuQm9vbDoKICAgIHByb3RvIDAgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjUxOQogICAgLy8gcmV0dXJuIHNlbGYuaW1wbGljaXRfa2V5X2FyYzRfYm9vbC52YWx1ZQogICAgaW50IDAKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTo0ODYKICAgIC8vIHNlbGYuaW1wbGljaXRfa2V5X2FyYzRfYm9vbCA9IEdsb2JhbFN0YXRlKGFyYzQuQm9vbChUcnVlKSkKICAgIGJ5dGUgImltcGxpY2l0X2tleV9hcmM0X2Jvb2wiCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6NTE5CiAgICAvLyByZXR1cm4gc2VsZi5pbXBsaWNpdF9rZXlfYXJjNF9ib29sLnZhbHVlCiAgICBhcHBfZ2xvYmFsX2dldF9leAogICAgYXNzZXJ0IC8vIGNoZWNrIHNlbGYuaW1wbGljaXRfa2V5X2FyYzRfYm9vbCBleGlzdHMKICAgIHJldHN1YgoKCi8vIHRlc3RzLmFydGlmYWN0cy5TdGF0ZU9wcy5jb250cmFjdC5HbG9iYWxTdGF0ZUNvbnRyYWN0LmdldF9pbXBsaWNpdF9rZXlfYXJjNF9hZGRyZXNzKCkgLT4gYnl0ZXM6CmdldF9pbXBsaWNpdF9rZXlfYXJjNF9hZGRyZXNzOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjUyMS01MjIKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBkZWYgZ2V0X2ltcGxpY2l0X2tleV9hcmM0X2FkZHJlc3Moc2VsZikgLT4gYXJjNC5BZGRyZXNzOgogICAgcHJvdG8gMCAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6NTIzCiAgICAvLyByZXR1cm4gc2VsZi5pbXBsaWNpdF9rZXlfYXJjNF9hZGRyZXNzLnZhbHVlCiAgICBpbnQgMAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjQ4NwogICAgLy8gc2VsZi5pbXBsaWNpdF9rZXlfYXJjNF9hZGRyZXNzID0gR2xvYmFsU3RhdGUoYXJjNC5BZGRyZXNzKEdsb2JhbC5jcmVhdG9yX2FkZHJlc3MpKQogICAgYnl0ZSAiaW1wbGljaXRfa2V5X2FyYzRfYWRkcmVzcyIKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTo1MjMKICAgIC8vIHJldHVybiBzZWxmLmltcGxpY2l0X2tleV9hcmM0X2FkZHJlc3MudmFsdWUKICAgIGFwcF9nbG9iYWxfZ2V0X2V4CiAgICBhc3NlcnQgLy8gY2hlY2sgc2VsZi5pbXBsaWNpdF9rZXlfYXJjNF9hZGRyZXNzIGV4aXN0cwogICAgcmV0c3ViCgoKLy8gdGVzdHMuYXJ0aWZhY3RzLlN0YXRlT3BzLmNvbnRyYWN0Lkdsb2JhbFN0YXRlQ29udHJhY3QuZ2V0X2ltcGxpY2l0X2tleV9hcmM0X3VpbnQxMjgoKSAtPiBieXRlczoKZ2V0X2ltcGxpY2l0X2tleV9hcmM0X3VpbnQxMjg6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6NTI1LTUyNgogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIGRlZiBnZXRfaW1wbGljaXRfa2V5X2FyYzRfdWludDEyOChzZWxmKSAtPiBhcmM0LlVJbnQxMjg6CiAgICBwcm90byAwIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTo1MjcKICAgIC8vIHJldHVybiBzZWxmLmltcGxpY2l0X2tleV9hcmM0X3VpbnQxMjgudmFsdWUKICAgIGludCAwCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6NDg4CiAgICAvLyBzZWxmLmltcGxpY2l0X2tleV9hcmM0X3VpbnQxMjggPSBHbG9iYWxTdGF0ZShhcmM0LlVJbnQxMjgoMioqMTAwKSkKICAgIGJ5dGUgImltcGxpY2l0X2tleV9hcmM0X3VpbnQxMjgiCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6NTI3CiAgICAvLyByZXR1cm4gc2VsZi5pbXBsaWNpdF9rZXlfYXJjNF91aW50MTI4LnZhbHVlCiAgICBhcHBfZ2xvYmFsX2dldF9leAogICAgYXNzZXJ0IC8vIGNoZWNrIHNlbGYuaW1wbGljaXRfa2V5X2FyYzRfdWludDEyOCBleGlzdHMKICAgIHJldHN1YgoKCi8vIHRlc3RzLmFydGlmYWN0cy5TdGF0ZU9wcy5jb250cmFjdC5HbG9iYWxTdGF0ZUNvbnRyYWN0LmdldF9pbXBsaWNpdF9rZXlfYXJjNF9keW5hbWljX2J5dGVzKCkgLT4gYnl0ZXM6CmdldF9pbXBsaWNpdF9rZXlfYXJjNF9keW5hbWljX2J5dGVzOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjUyOS01MzAKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBkZWYgZ2V0X2ltcGxpY2l0X2tleV9hcmM0X2R5bmFtaWNfYnl0ZXMoc2VsZikgLT4gYXJjNC5EeW5hbWljQnl0ZXM6CiAgICBwcm90byAwIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTo1MzEKICAgIC8vIHJldHVybiBzZWxmLmltcGxpY2l0X2tleV9hcmM0X2R5bmFtaWNfYnl0ZXMudmFsdWUKICAgIGludCAwCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6NDg5CiAgICAvLyBzZWxmLmltcGxpY2l0X2tleV9hcmM0X2R5bmFtaWNfYnl0ZXMgPSBHbG9iYWxTdGF0ZShhcmM0LkR5bmFtaWNCeXRlcyhiImR5bmFtaWMgYnl0ZXMiKSkKICAgIGJ5dGUgImltcGxpY2l0X2tleV9hcmM0X2R5bmFtaWNfYnl0ZXMiCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6NTMxCiAgICAvLyByZXR1cm4gc2VsZi5pbXBsaWNpdF9rZXlfYXJjNF9keW5hbWljX2J5dGVzLnZhbHVlCiAgICBhcHBfZ2xvYmFsX2dldF9leAogICAgYXNzZXJ0IC8vIGNoZWNrIHNlbGYuaW1wbGljaXRfa2V5X2FyYzRfZHluYW1pY19ieXRlcyBleGlzdHMKICAgIHJldHN1YgoKCi8vIHRlc3RzLmFydGlmYWN0cy5TdGF0ZU9wcy5jb250cmFjdC5HbG9iYWxTdGF0ZUNvbnRyYWN0LmdldF9hcmM0X3VpbnQoKSAtPiBieXRlczoKZ2V0X2FyYzRfdWludDoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTo1MzMtNTM1CiAgICAvLyAjIEdldHRlciBtZXRob2RzIGZvciBleHBsaWNpdCBrZXkgc3RhdGUgdmFyaWFibGVzCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gZGVmIGdldF9hcmM0X3VpbnQoc2VsZikgLT4gYXJjNC5VSW50NjQ6CiAgICBwcm90byAwIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTo1MzYKICAgIC8vIHJldHVybiBzZWxmLmFyYzRfdWludC52YWx1ZQogICAgaW50IDAKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTo0OTEtNDkyCiAgICAvLyAjIEV4cGxpY2l0IGtleSBzdGF0ZSB2YXJpYWJsZXMKICAgIC8vIHNlbGYuYXJjNF91aW50ID0gR2xvYmFsU3RhdGUoYXJjNC5VSW50NjQoMTMzNyksIGtleT0iZXhwbGljaXRfa2V5X2FyYzRfdWludCIpCiAgICBieXRlICJleHBsaWNpdF9rZXlfYXJjNF91aW50IgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjUzNgogICAgLy8gcmV0dXJuIHNlbGYuYXJjNF91aW50LnZhbHVlCiAgICBhcHBfZ2xvYmFsX2dldF9leAogICAgYXNzZXJ0IC8vIGNoZWNrIHNlbGYuYXJjNF91aW50IGV4aXN0cwogICAgcmV0c3ViCgoKLy8gdGVzdHMuYXJ0aWZhY3RzLlN0YXRlT3BzLmNvbnRyYWN0Lkdsb2JhbFN0YXRlQ29udHJhY3QuZ2V0X2FyYzRfc3RyaW5nKCkgLT4gYnl0ZXM6CmdldF9hcmM0X3N0cmluZzoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTo1MzgtNTM5CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gZGVmIGdldF9hcmM0X3N0cmluZyhzZWxmKSAtPiBhcmM0LlN0cmluZzoKICAgIHByb3RvIDAgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjU0MAogICAgLy8gcmV0dXJuIHNlbGYuYXJjNF9zdHJpbmcudmFsdWUKICAgIGludCAwCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6NDkzCiAgICAvLyBzZWxmLmFyYzRfc3RyaW5nID0gR2xvYmFsU3RhdGUoYXJjNC5TdHJpbmcoIkhlbGxvIiksIGtleT0iZXhwbGljaXRfa2V5X2FyYzRfc3RyaW5nIikKICAgIGJ5dGUgImV4cGxpY2l0X2tleV9hcmM0X3N0cmluZyIKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTo1NDAKICAgIC8vIHJldHVybiBzZWxmLmFyYzRfc3RyaW5nLnZhbHVlCiAgICBhcHBfZ2xvYmFsX2dldF9leAogICAgYXNzZXJ0IC8vIGNoZWNrIHNlbGYuYXJjNF9zdHJpbmcgZXhpc3RzCiAgICByZXRzdWIKCgovLyB0ZXN0cy5hcnRpZmFjdHMuU3RhdGVPcHMuY29udHJhY3QuR2xvYmFsU3RhdGVDb250cmFjdC5nZXRfYXJjNF9ieXRlKCkgLT4gYnl0ZXM6CmdldF9hcmM0X2J5dGU6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6NTQyLTU0MwogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIGRlZiBnZXRfYXJjNF9ieXRlKHNlbGYpIC0+IGFyYzQuQnl0ZToKICAgIHByb3RvIDAgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjU0NAogICAgLy8gcmV0dXJuIHNlbGYuYXJjNF9ieXRlLnZhbHVlCiAgICBpbnQgMAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjQ5NAogICAgLy8gc2VsZi5hcmM0X2J5dGUgPSBHbG9iYWxTdGF0ZShhcmM0LkJ5dGUoMCksIGtleT0iZXhwbGljaXRfa2V5X2FyYzRfYnl0ZSIpCiAgICBieXRlICJleHBsaWNpdF9rZXlfYXJjNF9ieXRlIgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjU0NAogICAgLy8gcmV0dXJuIHNlbGYuYXJjNF9ieXRlLnZhbHVlCiAgICBhcHBfZ2xvYmFsX2dldF9leAogICAgYXNzZXJ0IC8vIGNoZWNrIHNlbGYuYXJjNF9ieXRlIGV4aXN0cwogICAgcmV0c3ViCgoKLy8gdGVzdHMuYXJ0aWZhY3RzLlN0YXRlT3BzLmNvbnRyYWN0Lkdsb2JhbFN0YXRlQ29udHJhY3QuZ2V0X2FyYzRfYm9vbCgpIC0+IGJ5dGVzOgpnZXRfYXJjNF9ib29sOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjU0Ni01NDcKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBkZWYgZ2V0X2FyYzRfYm9vbChzZWxmKSAtPiBhcmM0LkJvb2w6CiAgICBwcm90byAwIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTo1NDgKICAgIC8vIHJldHVybiBzZWxmLmFyYzRfYm9vbC52YWx1ZQogICAgaW50IDAKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTo0OTUKICAgIC8vIHNlbGYuYXJjNF9ib29sID0gR2xvYmFsU3RhdGUoYXJjNC5Cb29sKFRydWUpLCBrZXk9ImV4cGxpY2l0X2tleV9hcmM0X2Jvb2wiKQogICAgYnl0ZSAiZXhwbGljaXRfa2V5X2FyYzRfYm9vbCIKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTo1NDgKICAgIC8vIHJldHVybiBzZWxmLmFyYzRfYm9vbC52YWx1ZQogICAgYXBwX2dsb2JhbF9nZXRfZXgKICAgIGFzc2VydCAvLyBjaGVjayBzZWxmLmFyYzRfYm9vbCBleGlzdHMKICAgIHJldHN1YgoKCi8vIHRlc3RzLmFydGlmYWN0cy5TdGF0ZU9wcy5jb250cmFjdC5HbG9iYWxTdGF0ZUNvbnRyYWN0LmdldF9hcmM0X2FkZHJlc3MoKSAtPiBieXRlczoKZ2V0X2FyYzRfYWRkcmVzczoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTo1NTAtNTUxCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gZGVmIGdldF9hcmM0X2FkZHJlc3Moc2VsZikgLT4gYXJjNC5BZGRyZXNzOgogICAgcHJvdG8gMCAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6NTUyCiAgICAvLyByZXR1cm4gc2VsZi5hcmM0X2FkZHJlc3MudmFsdWUKICAgIGludCAwCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6NDk3CiAgICAvLyBhcmM0LkFkZHJlc3MoR2xvYmFsLmNyZWF0b3JfYWRkcmVzcyksIGtleT0iZXhwbGljaXRfa2V5X2FyYzRfYWRkcmVzcyIKICAgIGJ5dGUgImV4cGxpY2l0X2tleV9hcmM0X2FkZHJlc3MiCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6NTUyCiAgICAvLyByZXR1cm4gc2VsZi5hcmM0X2FkZHJlc3MudmFsdWUKICAgIGFwcF9nbG9iYWxfZ2V0X2V4CiAgICBhc3NlcnQgLy8gY2hlY2sgc2VsZi5hcmM0X2FkZHJlc3MgZXhpc3RzCiAgICByZXRzdWIKCgovLyB0ZXN0cy5hcnRpZmFjdHMuU3RhdGVPcHMuY29udHJhY3QuR2xvYmFsU3RhdGVDb250cmFjdC5nZXRfYXJjNF91aW50MTI4KCkgLT4gYnl0ZXM6CmdldF9hcmM0X3VpbnQxMjg6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6NTU0LTU1NQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIGRlZiBnZXRfYXJjNF91aW50MTI4KHNlbGYpIC0+IGFyYzQuVUludDEyODoKICAgIHByb3RvIDAgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjU1NgogICAgLy8gcmV0dXJuIHNlbGYuYXJjNF91aW50MTI4LnZhbHVlCiAgICBpbnQgMAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjQ5OQogICAgLy8gc2VsZi5hcmM0X3VpbnQxMjggPSBHbG9iYWxTdGF0ZShhcmM0LlVJbnQxMjgoMioqMTAwKSwga2V5PSJleHBsaWNpdF9rZXlfYXJjNF91aW50MTI4IikKICAgIGJ5dGUgImV4cGxpY2l0X2tleV9hcmM0X3VpbnQxMjgiCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6NTU2CiAgICAvLyByZXR1cm4gc2VsZi5hcmM0X3VpbnQxMjgudmFsdWUKICAgIGFwcF9nbG9iYWxfZ2V0X2V4CiAgICBhc3NlcnQgLy8gY2hlY2sgc2VsZi5hcmM0X3VpbnQxMjggZXhpc3RzCiAgICByZXRzdWIKCgovLyB0ZXN0cy5hcnRpZmFjdHMuU3RhdGVPcHMuY29udHJhY3QuR2xvYmFsU3RhdGVDb250cmFjdC5nZXRfYXJjNF9keW5hbWljX2J5dGVzKCkgLT4gYnl0ZXM6CmdldF9hcmM0X2R5bmFtaWNfYnl0ZXM6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6NTU4LTU1OQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIGRlZiBnZXRfYXJjNF9keW5hbWljX2J5dGVzKHNlbGYpIC0+IGFyYzQuRHluYW1pY0J5dGVzOgogICAgcHJvdG8gMCAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6NTYwCiAgICAvLyByZXR1cm4gc2VsZi5hcmM0X2R5bmFtaWNfYnl0ZXMudmFsdWUKICAgIGludCAwCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6NTAxCiAgICAvLyBhcmM0LkR5bmFtaWNCeXRlcyhiImR5bmFtaWMgYnl0ZXMiKSwga2V5PSJleHBsaWNpdF9rZXlfYXJjNF9keW5hbWljX2J5dGVzIgogICAgYnl0ZSAiZXhwbGljaXRfa2V5X2FyYzRfZHluYW1pY19ieXRlcyIKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTo1NjAKICAgIC8vIHJldHVybiBzZWxmLmFyYzRfZHluYW1pY19ieXRlcy52YWx1ZQogICAgYXBwX2dsb2JhbF9nZXRfZXgKICAgIGFzc2VydCAvLyBjaGVjayBzZWxmLmFyYzRfZHluYW1pY19ieXRlcyBleGlzdHMKICAgIHJldHN1YgoKCi8vIHRlc3RzLmFydGlmYWN0cy5TdGF0ZU9wcy5jb250cmFjdC5HbG9iYWxTdGF0ZUNvbnRyYWN0LnNldF9pbXBsaWNpdF9rZXlfYXJjNF91aW50KHZhbHVlOiBieXRlcykgLT4gdm9pZDoKc2V0X2ltcGxpY2l0X2tleV9hcmM0X3VpbnQ6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6NTYyLTU2NAogICAgLy8gIyBTZXR0ZXIgbWV0aG9kcyBmb3IgaW1wbGljaXQga2V5IHN0YXRlIHZhcmlhYmxlcwogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIGRlZiBzZXRfaW1wbGljaXRfa2V5X2FyYzRfdWludChzZWxmLCB2YWx1ZTogYXJjNC5VSW50NjQpIC0+IE5vbmU6CiAgICBwcm90byAxIDAKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTo0ODItNDgzCiAgICAvLyAjIEltcGxpY2l0IGtleSBzdGF0ZSB2YXJpYWJsZXMKICAgIC8vIHNlbGYuaW1wbGljaXRfa2V5X2FyYzRfdWludCA9IEdsb2JhbFN0YXRlKGFyYzQuVUludDY0KDEzMzcpKQogICAgYnl0ZSAiaW1wbGljaXRfa2V5X2FyYzRfdWludCIKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTo1NjUKICAgIC8vIHNlbGYuaW1wbGljaXRfa2V5X2FyYzRfdWludC52YWx1ZSA9IHZhbHVlCiAgICBmcmFtZV9kaWcgLTEKICAgIGFwcF9nbG9iYWxfcHV0CiAgICByZXRzdWIKCgovLyB0ZXN0cy5hcnRpZmFjdHMuU3RhdGVPcHMuY29udHJhY3QuR2xvYmFsU3RhdGVDb250cmFjdC5zZXRfaW1wbGljaXRfa2V5X2FyYzRfc3RyaW5nKHZhbHVlOiBieXRlcykgLT4gdm9pZDoKc2V0X2ltcGxpY2l0X2tleV9hcmM0X3N0cmluZzoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTo1NjctNTY4CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gZGVmIHNldF9pbXBsaWNpdF9rZXlfYXJjNF9zdHJpbmcoc2VsZiwgdmFsdWU6IGFyYzQuU3RyaW5nKSAtPiBOb25lOgogICAgcHJvdG8gMSAwCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6NDg0CiAgICAvLyBzZWxmLmltcGxpY2l0X2tleV9hcmM0X3N0cmluZyA9IEdsb2JhbFN0YXRlKGFyYzQuU3RyaW5nKCJIZWxsbyIpKQogICAgYnl0ZSAiaW1wbGljaXRfa2V5X2FyYzRfc3RyaW5nIgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjU2OQogICAgLy8gc2VsZi5pbXBsaWNpdF9rZXlfYXJjNF9zdHJpbmcudmFsdWUgPSB2YWx1ZQogICAgZnJhbWVfZGlnIC0xCiAgICBhcHBfZ2xvYmFsX3B1dAogICAgcmV0c3ViCgoKLy8gdGVzdHMuYXJ0aWZhY3RzLlN0YXRlT3BzLmNvbnRyYWN0Lkdsb2JhbFN0YXRlQ29udHJhY3Quc2V0X2ltcGxpY2l0X2tleV9hcmM0X2J5dGUodmFsdWU6IGJ5dGVzKSAtPiB2b2lkOgpzZXRfaW1wbGljaXRfa2V5X2FyYzRfYnl0ZToKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTo1NzEtNTcyCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gZGVmIHNldF9pbXBsaWNpdF9rZXlfYXJjNF9ieXRlKHNlbGYsIHZhbHVlOiBhcmM0LkJ5dGUpIC0+IE5vbmU6CiAgICBwcm90byAxIDAKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTo0ODUKICAgIC8vIHNlbGYuaW1wbGljaXRfa2V5X2FyYzRfYnl0ZSA9IEdsb2JhbFN0YXRlKGFyYzQuQnl0ZSgwKSkKICAgIGJ5dGUgImltcGxpY2l0X2tleV9hcmM0X2J5dGUiCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6NTczCiAgICAvLyBzZWxmLmltcGxpY2l0X2tleV9hcmM0X2J5dGUudmFsdWUgPSB2YWx1ZQogICAgZnJhbWVfZGlnIC0xCiAgICBhcHBfZ2xvYmFsX3B1dAogICAgcmV0c3ViCgoKLy8gdGVzdHMuYXJ0aWZhY3RzLlN0YXRlT3BzLmNvbnRyYWN0Lkdsb2JhbFN0YXRlQ29udHJhY3Quc2V0X2ltcGxpY2l0X2tleV9hcmM0X2Jvb2wodmFsdWU6IGJ5dGVzKSAtPiB2b2lkOgpzZXRfaW1wbGljaXRfa2V5X2FyYzRfYm9vbDoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTo1NzUtNTc2CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gZGVmIHNldF9pbXBsaWNpdF9rZXlfYXJjNF9ib29sKHNlbGYsIHZhbHVlOiBhcmM0LkJvb2wpIC0+IE5vbmU6CiAgICBwcm90byAxIDAKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTo0ODYKICAgIC8vIHNlbGYuaW1wbGljaXRfa2V5X2FyYzRfYm9vbCA9IEdsb2JhbFN0YXRlKGFyYzQuQm9vbChUcnVlKSkKICAgIGJ5dGUgImltcGxpY2l0X2tleV9hcmM0X2Jvb2wiCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6NTc3CiAgICAvLyBzZWxmLmltcGxpY2l0X2tleV9hcmM0X2Jvb2wudmFsdWUgPSB2YWx1ZQogICAgZnJhbWVfZGlnIC0xCiAgICBhcHBfZ2xvYmFsX3B1dAogICAgcmV0c3ViCgoKLy8gdGVzdHMuYXJ0aWZhY3RzLlN0YXRlT3BzLmNvbnRyYWN0Lkdsb2JhbFN0YXRlQ29udHJhY3Quc2V0X2ltcGxpY2l0X2tleV9hcmM0X2FkZHJlc3ModmFsdWU6IGJ5dGVzKSAtPiB2b2lkOgpzZXRfaW1wbGljaXRfa2V5X2FyYzRfYWRkcmVzczoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTo1NzktNTgwCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gZGVmIHNldF9pbXBsaWNpdF9rZXlfYXJjNF9hZGRyZXNzKHNlbGYsIHZhbHVlOiBhcmM0LkFkZHJlc3MpIC0+IE5vbmU6CiAgICBwcm90byAxIDAKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTo0ODcKICAgIC8vIHNlbGYuaW1wbGljaXRfa2V5X2FyYzRfYWRkcmVzcyA9IEdsb2JhbFN0YXRlKGFyYzQuQWRkcmVzcyhHbG9iYWwuY3JlYXRvcl9hZGRyZXNzKSkKICAgIGJ5dGUgImltcGxpY2l0X2tleV9hcmM0X2FkZHJlc3MiCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6NTgxCiAgICAvLyBzZWxmLmltcGxpY2l0X2tleV9hcmM0X2FkZHJlc3MudmFsdWUgPSB2YWx1ZQogICAgZnJhbWVfZGlnIC0xCiAgICBhcHBfZ2xvYmFsX3B1dAogICAgcmV0c3ViCgoKLy8gdGVzdHMuYXJ0aWZhY3RzLlN0YXRlT3BzLmNvbnRyYWN0Lkdsb2JhbFN0YXRlQ29udHJhY3Quc2V0X2ltcGxpY2l0X2tleV9hcmM0X3VpbnQxMjgodmFsdWU6IGJ5dGVzKSAtPiB2b2lkOgpzZXRfaW1wbGljaXRfa2V5X2FyYzRfdWludDEyODoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTo1ODMtNTg0CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gZGVmIHNldF9pbXBsaWNpdF9rZXlfYXJjNF91aW50MTI4KHNlbGYsIHZhbHVlOiBhcmM0LlVJbnQxMjgpIC0+IE5vbmU6CiAgICBwcm90byAxIDAKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTo0ODgKICAgIC8vIHNlbGYuaW1wbGljaXRfa2V5X2FyYzRfdWludDEyOCA9IEdsb2JhbFN0YXRlKGFyYzQuVUludDEyOCgyKioxMDApKQogICAgYnl0ZSAiaW1wbGljaXRfa2V5X2FyYzRfdWludDEyOCIKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTo1ODUKICAgIC8vIHNlbGYuaW1wbGljaXRfa2V5X2FyYzRfdWludDEyOC52YWx1ZSA9IHZhbHVlCiAgICBmcmFtZV9kaWcgLTEKICAgIGFwcF9nbG9iYWxfcHV0CiAgICByZXRzdWIKCgovLyB0ZXN0cy5hcnRpZmFjdHMuU3RhdGVPcHMuY29udHJhY3QuR2xvYmFsU3RhdGVDb250cmFjdC5zZXRfaW1wbGljaXRfa2V5X2FyYzRfZHluYW1pY19ieXRlcyh2YWx1ZTogYnl0ZXMpIC0+IHZvaWQ6CnNldF9pbXBsaWNpdF9rZXlfYXJjNF9keW5hbWljX2J5dGVzOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjU4Ny01ODgKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBkZWYgc2V0X2ltcGxpY2l0X2tleV9hcmM0X2R5bmFtaWNfYnl0ZXMoc2VsZiwgdmFsdWU6IGFyYzQuRHluYW1pY0J5dGVzKSAtPiBOb25lOgogICAgcHJvdG8gMSAwCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6NDg5CiAgICAvLyBzZWxmLmltcGxpY2l0X2tleV9hcmM0X2R5bmFtaWNfYnl0ZXMgPSBHbG9iYWxTdGF0ZShhcmM0LkR5bmFtaWNCeXRlcyhiImR5bmFtaWMgYnl0ZXMiKSkKICAgIGJ5dGUgImltcGxpY2l0X2tleV9hcmM0X2R5bmFtaWNfYnl0ZXMiCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6NTg5CiAgICAvLyBzZWxmLmltcGxpY2l0X2tleV9hcmM0X2R5bmFtaWNfYnl0ZXMudmFsdWUgPSB2YWx1ZS5jb3B5KCkKICAgIGZyYW1lX2RpZyAtMQogICAgYXBwX2dsb2JhbF9wdXQKICAgIHJldHN1YgoKCi8vIHRlc3RzLmFydGlmYWN0cy5TdGF0ZU9wcy5jb250cmFjdC5HbG9iYWxTdGF0ZUNvbnRyYWN0LnNldF9hcmM0X3VpbnQodmFsdWU6IGJ5dGVzKSAtPiB2b2lkOgpzZXRfYXJjNF91aW50OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjU5MS01OTMKICAgIC8vICMgU2V0dGVyIG1ldGhvZHMgZm9yIGV4cGxpY2l0IGtleSBzdGF0ZSB2YXJpYWJsZXMKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBkZWYgc2V0X2FyYzRfdWludChzZWxmLCB2YWx1ZTogYXJjNC5VSW50NjQpIC0+IE5vbmU6CiAgICBwcm90byAxIDAKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTo0OTEtNDkyCiAgICAvLyAjIEV4cGxpY2l0IGtleSBzdGF0ZSB2YXJpYWJsZXMKICAgIC8vIHNlbGYuYXJjNF91aW50ID0gR2xvYmFsU3RhdGUoYXJjNC5VSW50NjQoMTMzNyksIGtleT0iZXhwbGljaXRfa2V5X2FyYzRfdWludCIpCiAgICBieXRlICJleHBsaWNpdF9rZXlfYXJjNF91aW50IgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjU5NAogICAgLy8gc2VsZi5hcmM0X3VpbnQudmFsdWUgPSB2YWx1ZQogICAgZnJhbWVfZGlnIC0xCiAgICBhcHBfZ2xvYmFsX3B1dAogICAgcmV0c3ViCgoKLy8gdGVzdHMuYXJ0aWZhY3RzLlN0YXRlT3BzLmNvbnRyYWN0Lkdsb2JhbFN0YXRlQ29udHJhY3Quc2V0X2FyYzRfc3RyaW5nKHZhbHVlOiBieXRlcykgLT4gdm9pZDoKc2V0X2FyYzRfc3RyaW5nOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjU5Ni01OTcKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBkZWYgc2V0X2FyYzRfc3RyaW5nKHNlbGYsIHZhbHVlOiBhcmM0LlN0cmluZykgLT4gTm9uZToKICAgIHByb3RvIDEgMAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjQ5MwogICAgLy8gc2VsZi5hcmM0X3N0cmluZyA9IEdsb2JhbFN0YXRlKGFyYzQuU3RyaW5nKCJIZWxsbyIpLCBrZXk9ImV4cGxpY2l0X2tleV9hcmM0X3N0cmluZyIpCiAgICBieXRlICJleHBsaWNpdF9rZXlfYXJjNF9zdHJpbmciCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6NTk4CiAgICAvLyBzZWxmLmFyYzRfc3RyaW5nLnZhbHVlID0gdmFsdWUKICAgIGZyYW1lX2RpZyAtMQogICAgYXBwX2dsb2JhbF9wdXQKICAgIHJldHN1YgoKCi8vIHRlc3RzLmFydGlmYWN0cy5TdGF0ZU9wcy5jb250cmFjdC5HbG9iYWxTdGF0ZUNvbnRyYWN0LnNldF9hcmM0X2J5dGUodmFsdWU6IGJ5dGVzKSAtPiB2b2lkOgpzZXRfYXJjNF9ieXRlOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjYwMC02MDEKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBkZWYgc2V0X2FyYzRfYnl0ZShzZWxmLCB2YWx1ZTogYXJjNC5CeXRlKSAtPiBOb25lOgogICAgcHJvdG8gMSAwCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6NDk0CiAgICAvLyBzZWxmLmFyYzRfYnl0ZSA9IEdsb2JhbFN0YXRlKGFyYzQuQnl0ZSgwKSwga2V5PSJleHBsaWNpdF9rZXlfYXJjNF9ieXRlIikKICAgIGJ5dGUgImV4cGxpY2l0X2tleV9hcmM0X2J5dGUiCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6NjAyCiAgICAvLyBzZWxmLmFyYzRfYnl0ZS52YWx1ZSA9IHZhbHVlCiAgICBmcmFtZV9kaWcgLTEKICAgIGFwcF9nbG9iYWxfcHV0CiAgICByZXRzdWIKCgovLyB0ZXN0cy5hcnRpZmFjdHMuU3RhdGVPcHMuY29udHJhY3QuR2xvYmFsU3RhdGVDb250cmFjdC5zZXRfYXJjNF9ib29sKHZhbHVlOiBieXRlcykgLT4gdm9pZDoKc2V0X2FyYzRfYm9vbDoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTo2MDQtNjA1CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gZGVmIHNldF9hcmM0X2Jvb2woc2VsZiwgdmFsdWU6IGFyYzQuQm9vbCkgLT4gTm9uZToKICAgIHByb3RvIDEgMAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjQ5NQogICAgLy8gc2VsZi5hcmM0X2Jvb2wgPSBHbG9iYWxTdGF0ZShhcmM0LkJvb2woVHJ1ZSksIGtleT0iZXhwbGljaXRfa2V5X2FyYzRfYm9vbCIpCiAgICBieXRlICJleHBsaWNpdF9rZXlfYXJjNF9ib29sIgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjYwNgogICAgLy8gc2VsZi5hcmM0X2Jvb2wudmFsdWUgPSB2YWx1ZQogICAgZnJhbWVfZGlnIC0xCiAgICBhcHBfZ2xvYmFsX3B1dAogICAgcmV0c3ViCgoKLy8gdGVzdHMuYXJ0aWZhY3RzLlN0YXRlT3BzLmNvbnRyYWN0Lkdsb2JhbFN0YXRlQ29udHJhY3Quc2V0X2FyYzRfYWRkcmVzcyh2YWx1ZTogYnl0ZXMpIC0+IHZvaWQ6CnNldF9hcmM0X2FkZHJlc3M6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6NjA4LTYwOQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIGRlZiBzZXRfYXJjNF9hZGRyZXNzKHNlbGYsIHZhbHVlOiBhcmM0LkFkZHJlc3MpIC0+IE5vbmU6CiAgICBwcm90byAxIDAKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTo0OTcKICAgIC8vIGFyYzQuQWRkcmVzcyhHbG9iYWwuY3JlYXRvcl9hZGRyZXNzKSwga2V5PSJleHBsaWNpdF9rZXlfYXJjNF9hZGRyZXNzIgogICAgYnl0ZSAiZXhwbGljaXRfa2V5X2FyYzRfYWRkcmVzcyIKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTo2MTAKICAgIC8vIHNlbGYuYXJjNF9hZGRyZXNzLnZhbHVlID0gdmFsdWUKICAgIGZyYW1lX2RpZyAtMQogICAgYXBwX2dsb2JhbF9wdXQKICAgIHJldHN1YgoKCi8vIHRlc3RzLmFydGlmYWN0cy5TdGF0ZU9wcy5jb250cmFjdC5HbG9iYWxTdGF0ZUNvbnRyYWN0LnNldF9hcmM0X3VpbnQxMjgodmFsdWU6IGJ5dGVzKSAtPiB2b2lkOgpzZXRfYXJjNF91aW50MTI4OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjYxMi02MTMKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBkZWYgc2V0X2FyYzRfdWludDEyOChzZWxmLCB2YWx1ZTogYXJjNC5VSW50MTI4KSAtPiBOb25lOgogICAgcHJvdG8gMSAwCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6NDk5CiAgICAvLyBzZWxmLmFyYzRfdWludDEyOCA9IEdsb2JhbFN0YXRlKGFyYzQuVUludDEyOCgyKioxMDApLCBrZXk9ImV4cGxpY2l0X2tleV9hcmM0X3VpbnQxMjgiKQogICAgYnl0ZSAiZXhwbGljaXRfa2V5X2FyYzRfdWludDEyOCIKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTo2MTQKICAgIC8vIHNlbGYuYXJjNF91aW50MTI4LnZhbHVlID0gdmFsdWUKICAgIGZyYW1lX2RpZyAtMQogICAgYXBwX2dsb2JhbF9wdXQKICAgIHJldHN1YgoKCi8vIHRlc3RzLmFydGlmYWN0cy5TdGF0ZU9wcy5jb250cmFjdC5HbG9iYWxTdGF0ZUNvbnRyYWN0LnNldF9hcmM0X2R5bmFtaWNfYnl0ZXModmFsdWU6IGJ5dGVzKSAtPiB2b2lkOgpzZXRfYXJjNF9keW5hbWljX2J5dGVzOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjYxNi02MTcKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBkZWYgc2V0X2FyYzRfZHluYW1pY19ieXRlcyhzZWxmLCB2YWx1ZTogYXJjNC5EeW5hbWljQnl0ZXMpIC0+IE5vbmU6CiAgICBwcm90byAxIDAKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTo1MDEKICAgIC8vIGFyYzQuRHluYW1pY0J5dGVzKGIiZHluYW1pYyBieXRlcyIpLCBrZXk9ImV4cGxpY2l0X2tleV9hcmM0X2R5bmFtaWNfYnl0ZXMiCiAgICBieXRlICJleHBsaWNpdF9rZXlfYXJjNF9keW5hbWljX2J5dGVzIgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjYxOAogICAgLy8gc2VsZi5hcmM0X2R5bmFtaWNfYnl0ZXMudmFsdWUgPSB2YWx1ZS5jb3B5KCkKICAgIGZyYW1lX2RpZyAtMQogICAgYXBwX2dsb2JhbF9wdXQKICAgIHJldHN1YgoKCi8vIHRlc3RzLmFydGlmYWN0cy5TdGF0ZU9wcy5jb250cmFjdC5HbG9iYWxTdGF0ZUNvbnRyYWN0Ll9faW5pdF9fKCkgLT4gdm9pZDoKX19pbml0X186CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6NDgxCiAgICAvLyBkZWYgX19pbml0X18oc2VsZikgLT4gTm9uZToKICAgIHByb3RvIDAgMAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjQ4Mi00ODMKICAgIC8vICMgSW1wbGljaXQga2V5IHN0YXRlIHZhcmlhYmxlcwogICAgLy8gc2VsZi5pbXBsaWNpdF9rZXlfYXJjNF91aW50ID0gR2xvYmFsU3RhdGUoYXJjNC5VSW50NjQoMTMzNykpCiAgICBieXRlICJpbXBsaWNpdF9rZXlfYXJjNF91aW50IgogICAgYnl0ZSAweDAwMDAwMDAwMDAwMDA1MzkKICAgIGFwcF9nbG9iYWxfcHV0CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6NDg0CiAgICAvLyBzZWxmLmltcGxpY2l0X2tleV9hcmM0X3N0cmluZyA9IEdsb2JhbFN0YXRlKGFyYzQuU3RyaW5nKCJIZWxsbyIpKQogICAgYnl0ZSAiaW1wbGljaXRfa2V5X2FyYzRfc3RyaW5nIgogICAgYnl0ZSAweDAwMDU0ODY1NmM2YzZmCiAgICBhcHBfZ2xvYmFsX3B1dAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjQ4NQogICAgLy8gc2VsZi5pbXBsaWNpdF9rZXlfYXJjNF9ieXRlID0gR2xvYmFsU3RhdGUoYXJjNC5CeXRlKDApKQogICAgYnl0ZSAiaW1wbGljaXRfa2V5X2FyYzRfYnl0ZSIKICAgIGJ5dGUgMHgwMAogICAgYXBwX2dsb2JhbF9wdXQKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTo0ODYKICAgIC8vIHNlbGYuaW1wbGljaXRfa2V5X2FyYzRfYm9vbCA9IEdsb2JhbFN0YXRlKGFyYzQuQm9vbChUcnVlKSkKICAgIGJ5dGUgImltcGxpY2l0X2tleV9hcmM0X2Jvb2wiCiAgICBieXRlIDB4ODAKICAgIGFwcF9nbG9iYWxfcHV0CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6NDg3CiAgICAvLyBzZWxmLmltcGxpY2l0X2tleV9hcmM0X2FkZHJlc3MgPSBHbG9iYWxTdGF0ZShhcmM0LkFkZHJlc3MoR2xvYmFsLmNyZWF0b3JfYWRkcmVzcykpCiAgICBieXRlICJpbXBsaWNpdF9rZXlfYXJjNF9hZGRyZXNzIgogICAgZ2xvYmFsIENyZWF0b3JBZGRyZXNzCiAgICBhcHBfZ2xvYmFsX3B1dAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjQ4OAogICAgLy8gc2VsZi5pbXBsaWNpdF9rZXlfYXJjNF91aW50MTI4ID0gR2xvYmFsU3RhdGUoYXJjNC5VSW50MTI4KDIqKjEwMCkpCiAgICBieXRlICJpbXBsaWNpdF9rZXlfYXJjNF91aW50MTI4IgogICAgYnl0ZSAweDAwMDAwMDEwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwCiAgICBhcHBfZ2xvYmFsX3B1dAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjQ4OQogICAgLy8gc2VsZi5pbXBsaWNpdF9rZXlfYXJjNF9keW5hbWljX2J5dGVzID0gR2xvYmFsU3RhdGUoYXJjNC5EeW5hbWljQnl0ZXMoYiJkeW5hbWljIGJ5dGVzIikpCiAgICBieXRlICJpbXBsaWNpdF9rZXlfYXJjNF9keW5hbWljX2J5dGVzIgogICAgYnl0ZSAweDAwMGQ2NDc5NmU2MTZkNjk2MzIwNjI3OTc0NjU3MwogICAgYXBwX2dsb2JhbF9wdXQKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTo0OTEtNDkyCiAgICAvLyAjIEV4cGxpY2l0IGtleSBzdGF0ZSB2YXJpYWJsZXMKICAgIC8vIHNlbGYuYXJjNF91aW50ID0gR2xvYmFsU3RhdGUoYXJjNC5VSW50NjQoMTMzNyksIGtleT0iZXhwbGljaXRfa2V5X2FyYzRfdWludCIpCiAgICBieXRlICJleHBsaWNpdF9rZXlfYXJjNF91aW50IgogICAgYnl0ZSAweDAwMDAwMDAwMDAwMDA1MzkKICAgIGFwcF9nbG9iYWxfcHV0CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6NDkzCiAgICAvLyBzZWxmLmFyYzRfc3RyaW5nID0gR2xvYmFsU3RhdGUoYXJjNC5TdHJpbmcoIkhlbGxvIiksIGtleT0iZXhwbGljaXRfa2V5X2FyYzRfc3RyaW5nIikKICAgIGJ5dGUgImV4cGxpY2l0X2tleV9hcmM0X3N0cmluZyIKICAgIGJ5dGUgMHgwMDA1NDg2NTZjNmM2ZgogICAgYXBwX2dsb2JhbF9wdXQKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTo0OTQKICAgIC8vIHNlbGYuYXJjNF9ieXRlID0gR2xvYmFsU3RhdGUoYXJjNC5CeXRlKDApLCBrZXk9ImV4cGxpY2l0X2tleV9hcmM0X2J5dGUiKQogICAgYnl0ZSAiZXhwbGljaXRfa2V5X2FyYzRfYnl0ZSIKICAgIGJ5dGUgMHgwMAogICAgYXBwX2dsb2JhbF9wdXQKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTo0OTUKICAgIC8vIHNlbGYuYXJjNF9ib29sID0gR2xvYmFsU3RhdGUoYXJjNC5Cb29sKFRydWUpLCBrZXk9ImV4cGxpY2l0X2tleV9hcmM0X2Jvb2wiKQogICAgYnl0ZSAiZXhwbGljaXRfa2V5X2FyYzRfYm9vbCIKICAgIGJ5dGUgMHg4MAogICAgYXBwX2dsb2JhbF9wdXQKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTo0OTcKICAgIC8vIGFyYzQuQWRkcmVzcyhHbG9iYWwuY3JlYXRvcl9hZGRyZXNzKSwga2V5PSJleHBsaWNpdF9rZXlfYXJjNF9hZGRyZXNzIgogICAgYnl0ZSAiZXhwbGljaXRfa2V5X2FyYzRfYWRkcmVzcyIKICAgIGdsb2JhbCBDcmVhdG9yQWRkcmVzcwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjQ5Ni00OTgKICAgIC8vIHNlbGYuYXJjNF9hZGRyZXNzID0gR2xvYmFsU3RhdGUoCiAgICAvLyAgICAgYXJjNC5BZGRyZXNzKEdsb2JhbC5jcmVhdG9yX2FkZHJlc3MpLCBrZXk9ImV4cGxpY2l0X2tleV9hcmM0X2FkZHJlc3MiCiAgICAvLyApCiAgICBhcHBfZ2xvYmFsX3B1dAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjQ5OQogICAgLy8gc2VsZi5hcmM0X3VpbnQxMjggPSBHbG9iYWxTdGF0ZShhcmM0LlVJbnQxMjgoMioqMTAwKSwga2V5PSJleHBsaWNpdF9rZXlfYXJjNF91aW50MTI4IikKICAgIGJ5dGUgImV4cGxpY2l0X2tleV9hcmM0X3VpbnQxMjgiCiAgICBieXRlIDB4MDAwMDAwMTAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAKICAgIGFwcF9nbG9iYWxfcHV0CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6NTAxCiAgICAvLyBhcmM0LkR5bmFtaWNCeXRlcyhiImR5bmFtaWMgYnl0ZXMiKSwga2V5PSJleHBsaWNpdF9rZXlfYXJjNF9keW5hbWljX2J5dGVzIgogICAgYnl0ZSAiZXhwbGljaXRfa2V5X2FyYzRfZHluYW1pY19ieXRlcyIKICAgIGJ5dGUgMHgwMDBkNjQ3OTZlNjE2ZDY5NjMyMDYyNzk3NDY1NzMKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTo1MDAtNTAyCiAgICAvLyBzZWxmLmFyYzRfZHluYW1pY19ieXRlcyA9IEdsb2JhbFN0YXRlKAogICAgLy8gICAgIGFyYzQuRHluYW1pY0J5dGVzKGIiZHluYW1pYyBieXRlcyIpLCBrZXk9ImV4cGxpY2l0X2tleV9hcmM0X2R5bmFtaWNfYnl0ZXMiCiAgICAvLyApCiAgICBhcHBfZ2xvYmFsX3B1dAogICAgcmV0c3ViCg==", + "clear": "I3ByYWdtYSB2ZXJzaW9uIDEwCgp0ZXN0cy5hcnRpZmFjdHMuU3RhdGVPcHMuY29udHJhY3QuR2xvYmFsU3RhdGVDb250cmFjdC5jbGVhcl9zdGF0ZV9wcm9ncmFtOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjQ4MAogICAgLy8gY2xhc3MgR2xvYmFsU3RhdGVDb250cmFjdChBUkM0Q29udHJhY3QpOgogICAgaW50IDEKICAgIHJldHVybgo=" }, "state": { "global": { diff --git a/tests/artifacts/StateOps/data/GlobalStateContract.clear.teal b/tests/artifacts/StateOps/data/GlobalStateContract.clear.teal index f23bd82..73daaa8 100644 --- a/tests/artifacts/StateOps/data/GlobalStateContract.clear.teal +++ b/tests/artifacts/StateOps/data/GlobalStateContract.clear.teal @@ -1,7 +1,7 @@ #pragma version 10 tests.artifacts.StateOps.contract.GlobalStateContract.clear_state_program: - // tests/artifacts/StateOps/contract.py:362 + // tests/artifacts/StateOps/contract.py:480 // class GlobalStateContract(ARC4Contract): int 1 return diff --git a/tests/artifacts/StateOps/data/ITxnOpsContract.approval.teal b/tests/artifacts/StateOps/data/ITxnOpsContract.approval.teal index 999ef11..8f03030 100644 --- a/tests/artifacts/StateOps/data/ITxnOpsContract.approval.teal +++ b/tests/artifacts/StateOps/data/ITxnOpsContract.approval.teal @@ -1,7 +1,7 @@ #pragma version 10 tests.artifacts.StateOps.contract.ITxnOpsContract.approval_program: - // tests/artifacts/StateOps/contract.py:337 + // tests/artifacts/StateOps/contract.py:455 // class ITxnOpsContract(ARC4Contract): txn NumAppArgs bz main_bare_routing@5 @@ -11,7 +11,7 @@ tests.artifacts.StateOps.contract.ITxnOpsContract.approval_program: err // reject transaction main_verify_itxn_ops_route@2: - // tests/artifacts/StateOps/contract.py:338 + // tests/artifacts/StateOps/contract.py:456 // @arc4.abimethod() txn OnCompletion ! @@ -23,7 +23,7 @@ main_verify_itxn_ops_route@2: return main_bare_routing@5: - // tests/artifacts/StateOps/contract.py:337 + // tests/artifacts/StateOps/contract.py:455 // class ITxnOpsContract(ARC4Contract): txn OnCompletion ! @@ -37,81 +37,81 @@ main_bare_routing@5: // tests.artifacts.StateOps.contract.ITxnOpsContract.verify_itxn_ops() -> void: verify_itxn_ops: - // tests/artifacts/StateOps/contract.py:338-339 + // tests/artifacts/StateOps/contract.py:456-457 // @arc4.abimethod() // def verify_itxn_ops(self) -> None: proto 0 0 - // tests/artifacts/StateOps/contract.py:340 + // tests/artifacts/StateOps/contract.py:458 // algopy.op.ITxnCreate.begin() itxn_begin - // tests/artifacts/StateOps/contract.py:341 + // tests/artifacts/StateOps/contract.py:459 // algopy.op.ITxnCreate.set_type_enum(algopy.TransactionType.ApplicationCall) int appl itxn_field TypeEnum - // tests/artifacts/StateOps/contract.py:342 + // tests/artifacts/StateOps/contract.py:460 // algopy.op.ITxnCreate.set_on_completion(algopy.OnCompleteAction.DeleteApplication) int DeleteApplication itxn_field OnCompletion - // tests/artifacts/StateOps/contract.py:343 + // tests/artifacts/StateOps/contract.py:461 // algopy.op.ITxnCreate.set_approval_program(Bytes.from_hex("068101")) byte 0x068101 itxn_field ApprovalProgram - // tests/artifacts/StateOps/contract.py:344-345 + // tests/artifacts/StateOps/contract.py:462-463 // # pages essentially appends // algopy.op.ITxnCreate.set_approval_program_pages(Bytes.from_hex("068101")) byte 0x068101 itxn_field ApprovalProgramPages - // tests/artifacts/StateOps/contract.py:346 + // tests/artifacts/StateOps/contract.py:464 // algopy.op.ITxnCreate.set_clear_state_program(Bytes.from_hex("068101")) byte 0x068101 itxn_field ClearStateProgram - // tests/artifacts/StateOps/contract.py:347 + // tests/artifacts/StateOps/contract.py:465 // algopy.op.ITxnCreate.set_fee(algopy.op.Global.min_txn_fee) global MinTxnFee itxn_field Fee - // tests/artifacts/StateOps/contract.py:348 + // tests/artifacts/StateOps/contract.py:466 // algopy.op.ITxnCreate.next() itxn_next - // tests/artifacts/StateOps/contract.py:349 + // tests/artifacts/StateOps/contract.py:467 // algopy.op.ITxnCreate.set_type_enum(algopy.TransactionType.Payment) int pay itxn_field TypeEnum - // tests/artifacts/StateOps/contract.py:350 + // tests/artifacts/StateOps/contract.py:468 // algopy.op.ITxnCreate.set_receiver(algopy.op.Global.creator_address) global CreatorAddress itxn_field Receiver - // tests/artifacts/StateOps/contract.py:351 + // tests/artifacts/StateOps/contract.py:469 // algopy.op.ITxnCreate.set_amount(algopy.UInt64(1000)) int 1000 itxn_field Amount - // tests/artifacts/StateOps/contract.py:352 + // tests/artifacts/StateOps/contract.py:470 // algopy.op.ITxnCreate.submit() itxn_submit - // tests/artifacts/StateOps/contract.py:354 + // tests/artifacts/StateOps/contract.py:472 // assert algopy.op.ITxn.receiver() == algopy.op.Global.creator_address itxn Receiver global CreatorAddress == assert - // tests/artifacts/StateOps/contract.py:355 + // tests/artifacts/StateOps/contract.py:473 // assert algopy.op.ITxn.amount() == algopy.UInt64(1000) itxn Amount int 1000 == assert - // tests/artifacts/StateOps/contract.py:356 + // tests/artifacts/StateOps/contract.py:474 // assert algopy.op.ITxn.type_enum() == algopy.TransactionType.Payment itxn TypeEnum int pay == assert - // tests/artifacts/StateOps/contract.py:358 + // tests/artifacts/StateOps/contract.py:476 // assert algopy.op.GITxn.type_enum(0) == algopy.TransactionType.ApplicationCall gitxn 0 TypeEnum int appl == assert - // tests/artifacts/StateOps/contract.py:359 + // tests/artifacts/StateOps/contract.py:477 // assert algopy.op.GITxn.type_enum(1) == algopy.TransactionType.Payment gitxn 1 TypeEnum int pay diff --git a/tests/artifacts/StateOps/data/ITxnOpsContract.arc32.json b/tests/artifacts/StateOps/data/ITxnOpsContract.arc32.json index 492b88a..ef512c9 100644 --- a/tests/artifacts/StateOps/data/ITxnOpsContract.arc32.json +++ b/tests/artifacts/StateOps/data/ITxnOpsContract.arc32.json @@ -7,8 +7,8 @@ } }, "source": { - "approval": "I3ByYWdtYSB2ZXJzaW9uIDEwCgp0ZXN0cy5hcnRpZmFjdHMuU3RhdGVPcHMuY29udHJhY3QuSVR4bk9wc0NvbnRyYWN0LmFwcHJvdmFsX3Byb2dyYW06CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6MzM3CiAgICAvLyBjbGFzcyBJVHhuT3BzQ29udHJhY3QoQVJDNENvbnRyYWN0KToKICAgIHR4biBOdW1BcHBBcmdzCiAgICBieiBtYWluX2JhcmVfcm91dGluZ0A1CiAgICBtZXRob2QgInZlcmlmeV9pdHhuX29wcygpdm9pZCIKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDAKICAgIG1hdGNoIG1haW5fdmVyaWZ5X2l0eG5fb3BzX3JvdXRlQDIKICAgIGVyciAvLyByZWplY3QgdHJhbnNhY3Rpb24KCm1haW5fdmVyaWZ5X2l0eG5fb3BzX3JvdXRlQDI6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6MzM4CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGlzIG5vdCBjcmVhdGluZwogICAgY2FsbHN1YiB2ZXJpZnlfaXR4bl9vcHMKICAgIGludCAxCiAgICByZXR1cm4KCm1haW5fYmFyZV9yb3V0aW5nQDU6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6MzM3CiAgICAvLyBjbGFzcyBJVHhuT3BzQ29udHJhY3QoQVJDNENvbnRyYWN0KToKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyByZWplY3QgdHJhbnNhY3Rpb24KICAgIHR4biBBcHBsaWNhdGlvbklECiAgICAhCiAgICBhc3NlcnQgLy8gaXMgY3JlYXRpbmcKICAgIGludCAxCiAgICByZXR1cm4KCgovLyB0ZXN0cy5hcnRpZmFjdHMuU3RhdGVPcHMuY29udHJhY3QuSVR4bk9wc0NvbnRyYWN0LnZlcmlmeV9pdHhuX29wcygpIC0+IHZvaWQ6CnZlcmlmeV9pdHhuX29wczoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTozMzgtMzM5CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gZGVmIHZlcmlmeV9pdHhuX29wcyhzZWxmKSAtPiBOb25lOgogICAgcHJvdG8gMCAwCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6MzQwCiAgICAvLyBhbGdvcHkub3AuSVR4bkNyZWF0ZS5iZWdpbigpCiAgICBpdHhuX2JlZ2luCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6MzQxCiAgICAvLyBhbGdvcHkub3AuSVR4bkNyZWF0ZS5zZXRfdHlwZV9lbnVtKGFsZ29weS5UcmFuc2FjdGlvblR5cGUuQXBwbGljYXRpb25DYWxsKQogICAgaW50IGFwcGwKICAgIGl0eG5fZmllbGQgVHlwZUVudW0KICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTozNDIKICAgIC8vIGFsZ29weS5vcC5JVHhuQ3JlYXRlLnNldF9vbl9jb21wbGV0aW9uKGFsZ29weS5PbkNvbXBsZXRlQWN0aW9uLkRlbGV0ZUFwcGxpY2F0aW9uKQogICAgaW50IERlbGV0ZUFwcGxpY2F0aW9uCiAgICBpdHhuX2ZpZWxkIE9uQ29tcGxldGlvbgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjM0MwogICAgLy8gYWxnb3B5Lm9wLklUeG5DcmVhdGUuc2V0X2FwcHJvdmFsX3Byb2dyYW0oQnl0ZXMuZnJvbV9oZXgoIjA2ODEwMSIpKQogICAgYnl0ZSAweDA2ODEwMQogICAgaXR4bl9maWVsZCBBcHByb3ZhbFByb2dyYW0KICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTozNDQtMzQ1CiAgICAvLyAjIHBhZ2VzIGVzc2VudGlhbGx5IGFwcGVuZHMKICAgIC8vIGFsZ29weS5vcC5JVHhuQ3JlYXRlLnNldF9hcHByb3ZhbF9wcm9ncmFtX3BhZ2VzKEJ5dGVzLmZyb21faGV4KCIwNjgxMDEiKSkKICAgIGJ5dGUgMHgwNjgxMDEKICAgIGl0eG5fZmllbGQgQXBwcm92YWxQcm9ncmFtUGFnZXMKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTozNDYKICAgIC8vIGFsZ29weS5vcC5JVHhuQ3JlYXRlLnNldF9jbGVhcl9zdGF0ZV9wcm9ncmFtKEJ5dGVzLmZyb21faGV4KCIwNjgxMDEiKSkKICAgIGJ5dGUgMHgwNjgxMDEKICAgIGl0eG5fZmllbGQgQ2xlYXJTdGF0ZVByb2dyYW0KICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTozNDcKICAgIC8vIGFsZ29weS5vcC5JVHhuQ3JlYXRlLnNldF9mZWUoYWxnb3B5Lm9wLkdsb2JhbC5taW5fdHhuX2ZlZSkKICAgIGdsb2JhbCBNaW5UeG5GZWUKICAgIGl0eG5fZmllbGQgRmVlCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6MzQ4CiAgICAvLyBhbGdvcHkub3AuSVR4bkNyZWF0ZS5uZXh0KCkKICAgIGl0eG5fbmV4dAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjM0OQogICAgLy8gYWxnb3B5Lm9wLklUeG5DcmVhdGUuc2V0X3R5cGVfZW51bShhbGdvcHkuVHJhbnNhY3Rpb25UeXBlLlBheW1lbnQpCiAgICBpbnQgcGF5CiAgICBpdHhuX2ZpZWxkIFR5cGVFbnVtCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6MzUwCiAgICAvLyBhbGdvcHkub3AuSVR4bkNyZWF0ZS5zZXRfcmVjZWl2ZXIoYWxnb3B5Lm9wLkdsb2JhbC5jcmVhdG9yX2FkZHJlc3MpCiAgICBnbG9iYWwgQ3JlYXRvckFkZHJlc3MKICAgIGl0eG5fZmllbGQgUmVjZWl2ZXIKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTozNTEKICAgIC8vIGFsZ29weS5vcC5JVHhuQ3JlYXRlLnNldF9hbW91bnQoYWxnb3B5LlVJbnQ2NCgxMDAwKSkKICAgIGludCAxMDAwCiAgICBpdHhuX2ZpZWxkIEFtb3VudAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjM1MgogICAgLy8gYWxnb3B5Lm9wLklUeG5DcmVhdGUuc3VibWl0KCkKICAgIGl0eG5fc3VibWl0CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6MzU0CiAgICAvLyBhc3NlcnQgYWxnb3B5Lm9wLklUeG4ucmVjZWl2ZXIoKSA9PSBhbGdvcHkub3AuR2xvYmFsLmNyZWF0b3JfYWRkcmVzcwogICAgaXR4biBSZWNlaXZlcgogICAgZ2xvYmFsIENyZWF0b3JBZGRyZXNzCiAgICA9PQogICAgYXNzZXJ0CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6MzU1CiAgICAvLyBhc3NlcnQgYWxnb3B5Lm9wLklUeG4uYW1vdW50KCkgPT0gYWxnb3B5LlVJbnQ2NCgxMDAwKQogICAgaXR4biBBbW91bnQKICAgIGludCAxMDAwCiAgICA9PQogICAgYXNzZXJ0CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6MzU2CiAgICAvLyBhc3NlcnQgYWxnb3B5Lm9wLklUeG4udHlwZV9lbnVtKCkgPT0gYWxnb3B5LlRyYW5zYWN0aW9uVHlwZS5QYXltZW50CiAgICBpdHhuIFR5cGVFbnVtCiAgICBpbnQgcGF5CiAgICA9PQogICAgYXNzZXJ0CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6MzU4CiAgICAvLyBhc3NlcnQgYWxnb3B5Lm9wLkdJVHhuLnR5cGVfZW51bSgwKSA9PSBhbGdvcHkuVHJhbnNhY3Rpb25UeXBlLkFwcGxpY2F0aW9uQ2FsbAogICAgZ2l0eG4gMCBUeXBlRW51bQogICAgaW50IGFwcGwKICAgID09CiAgICBhc3NlcnQKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTozNTkKICAgIC8vIGFzc2VydCBhbGdvcHkub3AuR0lUeG4udHlwZV9lbnVtKDEpID09IGFsZ29weS5UcmFuc2FjdGlvblR5cGUuUGF5bWVudAogICAgZ2l0eG4gMSBUeXBlRW51bQogICAgaW50IHBheQogICAgPT0KICAgIGFzc2VydAogICAgcmV0c3ViCg==", - "clear": "I3ByYWdtYSB2ZXJzaW9uIDEwCgp0ZXN0cy5hcnRpZmFjdHMuU3RhdGVPcHMuY29udHJhY3QuSVR4bk9wc0NvbnRyYWN0LmNsZWFyX3N0YXRlX3Byb2dyYW06CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6MzM3CiAgICAvLyBjbGFzcyBJVHhuT3BzQ29udHJhY3QoQVJDNENvbnRyYWN0KToKICAgIGludCAxCiAgICByZXR1cm4K" + "approval": "I3ByYWdtYSB2ZXJzaW9uIDEwCgp0ZXN0cy5hcnRpZmFjdHMuU3RhdGVPcHMuY29udHJhY3QuSVR4bk9wc0NvbnRyYWN0LmFwcHJvdmFsX3Byb2dyYW06CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6NDU1CiAgICAvLyBjbGFzcyBJVHhuT3BzQ29udHJhY3QoQVJDNENvbnRyYWN0KToKICAgIHR4biBOdW1BcHBBcmdzCiAgICBieiBtYWluX2JhcmVfcm91dGluZ0A1CiAgICBtZXRob2QgInZlcmlmeV9pdHhuX29wcygpdm9pZCIKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDAKICAgIG1hdGNoIG1haW5fdmVyaWZ5X2l0eG5fb3BzX3JvdXRlQDIKICAgIGVyciAvLyByZWplY3QgdHJhbnNhY3Rpb24KCm1haW5fdmVyaWZ5X2l0eG5fb3BzX3JvdXRlQDI6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6NDU2CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGlzIG5vdCBjcmVhdGluZwogICAgY2FsbHN1YiB2ZXJpZnlfaXR4bl9vcHMKICAgIGludCAxCiAgICByZXR1cm4KCm1haW5fYmFyZV9yb3V0aW5nQDU6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6NDU1CiAgICAvLyBjbGFzcyBJVHhuT3BzQ29udHJhY3QoQVJDNENvbnRyYWN0KToKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyByZWplY3QgdHJhbnNhY3Rpb24KICAgIHR4biBBcHBsaWNhdGlvbklECiAgICAhCiAgICBhc3NlcnQgLy8gaXMgY3JlYXRpbmcKICAgIGludCAxCiAgICByZXR1cm4KCgovLyB0ZXN0cy5hcnRpZmFjdHMuU3RhdGVPcHMuY29udHJhY3QuSVR4bk9wc0NvbnRyYWN0LnZlcmlmeV9pdHhuX29wcygpIC0+IHZvaWQ6CnZlcmlmeV9pdHhuX29wczoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTo0NTYtNDU3CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gZGVmIHZlcmlmeV9pdHhuX29wcyhzZWxmKSAtPiBOb25lOgogICAgcHJvdG8gMCAwCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6NDU4CiAgICAvLyBhbGdvcHkub3AuSVR4bkNyZWF0ZS5iZWdpbigpCiAgICBpdHhuX2JlZ2luCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6NDU5CiAgICAvLyBhbGdvcHkub3AuSVR4bkNyZWF0ZS5zZXRfdHlwZV9lbnVtKGFsZ29weS5UcmFuc2FjdGlvblR5cGUuQXBwbGljYXRpb25DYWxsKQogICAgaW50IGFwcGwKICAgIGl0eG5fZmllbGQgVHlwZUVudW0KICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTo0NjAKICAgIC8vIGFsZ29weS5vcC5JVHhuQ3JlYXRlLnNldF9vbl9jb21wbGV0aW9uKGFsZ29weS5PbkNvbXBsZXRlQWN0aW9uLkRlbGV0ZUFwcGxpY2F0aW9uKQogICAgaW50IERlbGV0ZUFwcGxpY2F0aW9uCiAgICBpdHhuX2ZpZWxkIE9uQ29tcGxldGlvbgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjQ2MQogICAgLy8gYWxnb3B5Lm9wLklUeG5DcmVhdGUuc2V0X2FwcHJvdmFsX3Byb2dyYW0oQnl0ZXMuZnJvbV9oZXgoIjA2ODEwMSIpKQogICAgYnl0ZSAweDA2ODEwMQogICAgaXR4bl9maWVsZCBBcHByb3ZhbFByb2dyYW0KICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTo0NjItNDYzCiAgICAvLyAjIHBhZ2VzIGVzc2VudGlhbGx5IGFwcGVuZHMKICAgIC8vIGFsZ29weS5vcC5JVHhuQ3JlYXRlLnNldF9hcHByb3ZhbF9wcm9ncmFtX3BhZ2VzKEJ5dGVzLmZyb21faGV4KCIwNjgxMDEiKSkKICAgIGJ5dGUgMHgwNjgxMDEKICAgIGl0eG5fZmllbGQgQXBwcm92YWxQcm9ncmFtUGFnZXMKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTo0NjQKICAgIC8vIGFsZ29weS5vcC5JVHhuQ3JlYXRlLnNldF9jbGVhcl9zdGF0ZV9wcm9ncmFtKEJ5dGVzLmZyb21faGV4KCIwNjgxMDEiKSkKICAgIGJ5dGUgMHgwNjgxMDEKICAgIGl0eG5fZmllbGQgQ2xlYXJTdGF0ZVByb2dyYW0KICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTo0NjUKICAgIC8vIGFsZ29weS5vcC5JVHhuQ3JlYXRlLnNldF9mZWUoYWxnb3B5Lm9wLkdsb2JhbC5taW5fdHhuX2ZlZSkKICAgIGdsb2JhbCBNaW5UeG5GZWUKICAgIGl0eG5fZmllbGQgRmVlCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6NDY2CiAgICAvLyBhbGdvcHkub3AuSVR4bkNyZWF0ZS5uZXh0KCkKICAgIGl0eG5fbmV4dAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjQ2NwogICAgLy8gYWxnb3B5Lm9wLklUeG5DcmVhdGUuc2V0X3R5cGVfZW51bShhbGdvcHkuVHJhbnNhY3Rpb25UeXBlLlBheW1lbnQpCiAgICBpbnQgcGF5CiAgICBpdHhuX2ZpZWxkIFR5cGVFbnVtCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6NDY4CiAgICAvLyBhbGdvcHkub3AuSVR4bkNyZWF0ZS5zZXRfcmVjZWl2ZXIoYWxnb3B5Lm9wLkdsb2JhbC5jcmVhdG9yX2FkZHJlc3MpCiAgICBnbG9iYWwgQ3JlYXRvckFkZHJlc3MKICAgIGl0eG5fZmllbGQgUmVjZWl2ZXIKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTo0NjkKICAgIC8vIGFsZ29weS5vcC5JVHhuQ3JlYXRlLnNldF9hbW91bnQoYWxnb3B5LlVJbnQ2NCgxMDAwKSkKICAgIGludCAxMDAwCiAgICBpdHhuX2ZpZWxkIEFtb3VudAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjQ3MAogICAgLy8gYWxnb3B5Lm9wLklUeG5DcmVhdGUuc3VibWl0KCkKICAgIGl0eG5fc3VibWl0CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6NDcyCiAgICAvLyBhc3NlcnQgYWxnb3B5Lm9wLklUeG4ucmVjZWl2ZXIoKSA9PSBhbGdvcHkub3AuR2xvYmFsLmNyZWF0b3JfYWRkcmVzcwogICAgaXR4biBSZWNlaXZlcgogICAgZ2xvYmFsIENyZWF0b3JBZGRyZXNzCiAgICA9PQogICAgYXNzZXJ0CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6NDczCiAgICAvLyBhc3NlcnQgYWxnb3B5Lm9wLklUeG4uYW1vdW50KCkgPT0gYWxnb3B5LlVJbnQ2NCgxMDAwKQogICAgaXR4biBBbW91bnQKICAgIGludCAxMDAwCiAgICA9PQogICAgYXNzZXJ0CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6NDc0CiAgICAvLyBhc3NlcnQgYWxnb3B5Lm9wLklUeG4udHlwZV9lbnVtKCkgPT0gYWxnb3B5LlRyYW5zYWN0aW9uVHlwZS5QYXltZW50CiAgICBpdHhuIFR5cGVFbnVtCiAgICBpbnQgcGF5CiAgICA9PQogICAgYXNzZXJ0CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6NDc2CiAgICAvLyBhc3NlcnQgYWxnb3B5Lm9wLkdJVHhuLnR5cGVfZW51bSgwKSA9PSBhbGdvcHkuVHJhbnNhY3Rpb25UeXBlLkFwcGxpY2F0aW9uQ2FsbAogICAgZ2l0eG4gMCBUeXBlRW51bQogICAgaW50IGFwcGwKICAgID09CiAgICBhc3NlcnQKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTo0NzcKICAgIC8vIGFzc2VydCBhbGdvcHkub3AuR0lUeG4udHlwZV9lbnVtKDEpID09IGFsZ29weS5UcmFuc2FjdGlvblR5cGUuUGF5bWVudAogICAgZ2l0eG4gMSBUeXBlRW51bQogICAgaW50IHBheQogICAgPT0KICAgIGFzc2VydAogICAgcmV0c3ViCg==", + "clear": "I3ByYWdtYSB2ZXJzaW9uIDEwCgp0ZXN0cy5hcnRpZmFjdHMuU3RhdGVPcHMuY29udHJhY3QuSVR4bk9wc0NvbnRyYWN0LmNsZWFyX3N0YXRlX3Byb2dyYW06CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6NDU1CiAgICAvLyBjbGFzcyBJVHhuT3BzQ29udHJhY3QoQVJDNENvbnRyYWN0KToKICAgIGludCAxCiAgICByZXR1cm4K" }, "state": { "global": { diff --git a/tests/artifacts/StateOps/data/ITxnOpsContract.clear.teal b/tests/artifacts/StateOps/data/ITxnOpsContract.clear.teal index cd2e0fc..61ef575 100644 --- a/tests/artifacts/StateOps/data/ITxnOpsContract.clear.teal +++ b/tests/artifacts/StateOps/data/ITxnOpsContract.clear.teal @@ -1,7 +1,7 @@ #pragma version 10 tests.artifacts.StateOps.contract.ITxnOpsContract.clear_state_program: - // tests/artifacts/StateOps/contract.py:337 + // tests/artifacts/StateOps/contract.py:455 // class ITxnOpsContract(ARC4Contract): int 1 return diff --git a/tests/artifacts/StateOps/data/LocalStateContract.approval.teal b/tests/artifacts/StateOps/data/LocalStateContract.approval.teal index ca1764e..a989637 100644 --- a/tests/artifacts/StateOps/data/LocalStateContract.approval.teal +++ b/tests/artifacts/StateOps/data/LocalStateContract.approval.teal @@ -1,7 +1,7 @@ #pragma version 10 tests.artifacts.StateOps.contract.LocalStateContract.approval_program: - // tests/artifacts/StateOps/contract.py:503 + // tests/artifacts/StateOps/contract.py:621 // class LocalStateContract(ARC4Contract): txn NumAppArgs bz main_bare_routing@19 @@ -25,7 +25,7 @@ tests.artifacts.StateOps.contract.LocalStateContract.approval_program: err // reject transaction main_opt_in_route@2: - // tests/artifacts/StateOps/contract.py:525 + // tests/artifacts/StateOps/contract.py:643 // @arc4.abimethod(allow_actions=["OptIn"]) txn OnCompletion int OptIn @@ -38,7 +38,7 @@ main_opt_in_route@2: return main_get_implicit_key_arc4_uint_route@3: - // tests/artifacts/StateOps/contract.py:547-548 + // tests/artifacts/StateOps/contract.py:665-666 // # Getter methods for implicit key state variables // @arc4.abimethod() txn OnCompletion @@ -46,12 +46,12 @@ main_get_implicit_key_arc4_uint_route@3: assert // OnCompletion is NoOp txn ApplicationID assert // is not creating - // tests/artifacts/StateOps/contract.py:503 + // tests/artifacts/StateOps/contract.py:621 // class LocalStateContract(ARC4Contract): txna ApplicationArgs 1 btoi txnas Accounts - // tests/artifacts/StateOps/contract.py:547-548 + // tests/artifacts/StateOps/contract.py:665-666 // # Getter methods for implicit key state variables // @arc4.abimethod() callsub get_implicit_key_arc4_uint @@ -63,19 +63,19 @@ main_get_implicit_key_arc4_uint_route@3: return main_get_implicit_key_arc4_string_route@4: - // tests/artifacts/StateOps/contract.py:552 + // tests/artifacts/StateOps/contract.py:670 // @arc4.abimethod() txn OnCompletion ! assert // OnCompletion is NoOp txn ApplicationID assert // is not creating - // tests/artifacts/StateOps/contract.py:503 + // tests/artifacts/StateOps/contract.py:621 // class LocalStateContract(ARC4Contract): txna ApplicationArgs 1 btoi txnas Accounts - // tests/artifacts/StateOps/contract.py:552 + // tests/artifacts/StateOps/contract.py:670 // @arc4.abimethod() callsub get_implicit_key_arc4_string byte 0x151f7c75 @@ -86,19 +86,19 @@ main_get_implicit_key_arc4_string_route@4: return main_get_implicit_key_arc4_byte_route@5: - // tests/artifacts/StateOps/contract.py:556 + // tests/artifacts/StateOps/contract.py:674 // @arc4.abimethod() txn OnCompletion ! assert // OnCompletion is NoOp txn ApplicationID assert // is not creating - // tests/artifacts/StateOps/contract.py:503 + // tests/artifacts/StateOps/contract.py:621 // class LocalStateContract(ARC4Contract): txna ApplicationArgs 1 btoi txnas Accounts - // tests/artifacts/StateOps/contract.py:556 + // tests/artifacts/StateOps/contract.py:674 // @arc4.abimethod() callsub get_implicit_key_arc4_byte byte 0x151f7c75 @@ -109,19 +109,19 @@ main_get_implicit_key_arc4_byte_route@5: return main_get_implicit_key_arc4_bool_route@6: - // tests/artifacts/StateOps/contract.py:560 + // tests/artifacts/StateOps/contract.py:678 // @arc4.abimethod() txn OnCompletion ! assert // OnCompletion is NoOp txn ApplicationID assert // is not creating - // tests/artifacts/StateOps/contract.py:503 + // tests/artifacts/StateOps/contract.py:621 // class LocalStateContract(ARC4Contract): txna ApplicationArgs 1 btoi txnas Accounts - // tests/artifacts/StateOps/contract.py:560 + // tests/artifacts/StateOps/contract.py:678 // @arc4.abimethod() callsub get_implicit_key_arc4_bool byte 0x151f7c75 @@ -132,19 +132,19 @@ main_get_implicit_key_arc4_bool_route@6: return main_get_implicit_key_arc4_address_route@7: - // tests/artifacts/StateOps/contract.py:564 + // tests/artifacts/StateOps/contract.py:682 // @arc4.abimethod() txn OnCompletion ! assert // OnCompletion is NoOp txn ApplicationID assert // is not creating - // tests/artifacts/StateOps/contract.py:503 + // tests/artifacts/StateOps/contract.py:621 // class LocalStateContract(ARC4Contract): txna ApplicationArgs 1 btoi txnas Accounts - // tests/artifacts/StateOps/contract.py:564 + // tests/artifacts/StateOps/contract.py:682 // @arc4.abimethod() callsub get_implicit_key_arc4_address byte 0x151f7c75 @@ -155,19 +155,19 @@ main_get_implicit_key_arc4_address_route@7: return main_get_implicit_key_arc4_uint128_route@8: - // tests/artifacts/StateOps/contract.py:568 + // tests/artifacts/StateOps/contract.py:686 // @arc4.abimethod() txn OnCompletion ! assert // OnCompletion is NoOp txn ApplicationID assert // is not creating - // tests/artifacts/StateOps/contract.py:503 + // tests/artifacts/StateOps/contract.py:621 // class LocalStateContract(ARC4Contract): txna ApplicationArgs 1 btoi txnas Accounts - // tests/artifacts/StateOps/contract.py:568 + // tests/artifacts/StateOps/contract.py:686 // @arc4.abimethod() callsub get_implicit_key_arc4_uint128 byte 0x151f7c75 @@ -178,19 +178,19 @@ main_get_implicit_key_arc4_uint128_route@8: return main_get_implicit_key_arc4_dynamic_bytes_route@9: - // tests/artifacts/StateOps/contract.py:572 + // tests/artifacts/StateOps/contract.py:690 // @arc4.abimethod() txn OnCompletion ! assert // OnCompletion is NoOp txn ApplicationID assert // is not creating - // tests/artifacts/StateOps/contract.py:503 + // tests/artifacts/StateOps/contract.py:621 // class LocalStateContract(ARC4Contract): txna ApplicationArgs 1 btoi txnas Accounts - // tests/artifacts/StateOps/contract.py:572 + // tests/artifacts/StateOps/contract.py:690 // @arc4.abimethod() callsub get_implicit_key_arc4_dynamic_bytes byte 0x151f7c75 @@ -201,7 +201,7 @@ main_get_implicit_key_arc4_dynamic_bytes_route@9: return main_get_arc4_uint_route@10: - // tests/artifacts/StateOps/contract.py:576-577 + // tests/artifacts/StateOps/contract.py:694-695 // # Getter methods for explicit key state variables // @arc4.abimethod() txn OnCompletion @@ -209,12 +209,12 @@ main_get_arc4_uint_route@10: assert // OnCompletion is NoOp txn ApplicationID assert // is not creating - // tests/artifacts/StateOps/contract.py:503 + // tests/artifacts/StateOps/contract.py:621 // class LocalStateContract(ARC4Contract): txna ApplicationArgs 1 btoi txnas Accounts - // tests/artifacts/StateOps/contract.py:576-577 + // tests/artifacts/StateOps/contract.py:694-695 // # Getter methods for explicit key state variables // @arc4.abimethod() callsub get_arc4_uint @@ -226,19 +226,19 @@ main_get_arc4_uint_route@10: return main_get_arc4_string_route@11: - // tests/artifacts/StateOps/contract.py:581 + // tests/artifacts/StateOps/contract.py:699 // @arc4.abimethod() txn OnCompletion ! assert // OnCompletion is NoOp txn ApplicationID assert // is not creating - // tests/artifacts/StateOps/contract.py:503 + // tests/artifacts/StateOps/contract.py:621 // class LocalStateContract(ARC4Contract): txna ApplicationArgs 1 btoi txnas Accounts - // tests/artifacts/StateOps/contract.py:581 + // tests/artifacts/StateOps/contract.py:699 // @arc4.abimethod() callsub get_arc4_string byte 0x151f7c75 @@ -249,19 +249,19 @@ main_get_arc4_string_route@11: return main_get_arc4_byte_route@12: - // tests/artifacts/StateOps/contract.py:585 + // tests/artifacts/StateOps/contract.py:703 // @arc4.abimethod() txn OnCompletion ! assert // OnCompletion is NoOp txn ApplicationID assert // is not creating - // tests/artifacts/StateOps/contract.py:503 + // tests/artifacts/StateOps/contract.py:621 // class LocalStateContract(ARC4Contract): txna ApplicationArgs 1 btoi txnas Accounts - // tests/artifacts/StateOps/contract.py:585 + // tests/artifacts/StateOps/contract.py:703 // @arc4.abimethod() callsub get_arc4_byte byte 0x151f7c75 @@ -272,19 +272,19 @@ main_get_arc4_byte_route@12: return main_get_arc4_bool_route@13: - // tests/artifacts/StateOps/contract.py:589 + // tests/artifacts/StateOps/contract.py:707 // @arc4.abimethod() txn OnCompletion ! assert // OnCompletion is NoOp txn ApplicationID assert // is not creating - // tests/artifacts/StateOps/contract.py:503 + // tests/artifacts/StateOps/contract.py:621 // class LocalStateContract(ARC4Contract): txna ApplicationArgs 1 btoi txnas Accounts - // tests/artifacts/StateOps/contract.py:589 + // tests/artifacts/StateOps/contract.py:707 // @arc4.abimethod() callsub get_arc4_bool byte 0x151f7c75 @@ -295,19 +295,19 @@ main_get_arc4_bool_route@13: return main_get_arc4_address_route@14: - // tests/artifacts/StateOps/contract.py:593 + // tests/artifacts/StateOps/contract.py:711 // @arc4.abimethod() txn OnCompletion ! assert // OnCompletion is NoOp txn ApplicationID assert // is not creating - // tests/artifacts/StateOps/contract.py:503 + // tests/artifacts/StateOps/contract.py:621 // class LocalStateContract(ARC4Contract): txna ApplicationArgs 1 btoi txnas Accounts - // tests/artifacts/StateOps/contract.py:593 + // tests/artifacts/StateOps/contract.py:711 // @arc4.abimethod() callsub get_arc4_address byte 0x151f7c75 @@ -318,19 +318,19 @@ main_get_arc4_address_route@14: return main_get_arc4_uint128_route@15: - // tests/artifacts/StateOps/contract.py:597 + // tests/artifacts/StateOps/contract.py:715 // @arc4.abimethod() txn OnCompletion ! assert // OnCompletion is NoOp txn ApplicationID assert // is not creating - // tests/artifacts/StateOps/contract.py:503 + // tests/artifacts/StateOps/contract.py:621 // class LocalStateContract(ARC4Contract): txna ApplicationArgs 1 btoi txnas Accounts - // tests/artifacts/StateOps/contract.py:597 + // tests/artifacts/StateOps/contract.py:715 // @arc4.abimethod() callsub get_arc4_uint128 byte 0x151f7c75 @@ -341,19 +341,19 @@ main_get_arc4_uint128_route@15: return main_get_arc4_dynamic_bytes_route@16: - // tests/artifacts/StateOps/contract.py:601 + // tests/artifacts/StateOps/contract.py:719 // @arc4.abimethod() txn OnCompletion ! assert // OnCompletion is NoOp txn ApplicationID assert // is not creating - // tests/artifacts/StateOps/contract.py:503 + // tests/artifacts/StateOps/contract.py:621 // class LocalStateContract(ARC4Contract): txna ApplicationArgs 1 btoi txnas Accounts - // tests/artifacts/StateOps/contract.py:601 + // tests/artifacts/StateOps/contract.py:719 // @arc4.abimethod() callsub get_arc4_dynamic_bytes byte 0x151f7c75 @@ -364,7 +364,7 @@ main_get_arc4_dynamic_bytes_route@16: return main_bare_routing@19: - // tests/artifacts/StateOps/contract.py:503 + // tests/artifacts/StateOps/contract.py:621 // class LocalStateContract(ARC4Contract): txn OnCompletion ! @@ -378,155 +378,155 @@ main_bare_routing@19: // tests.artifacts.StateOps.contract.LocalStateContract.opt_in() -> void: opt_in: - // tests/artifacts/StateOps/contract.py:525-526 + // tests/artifacts/StateOps/contract.py:643-644 // @arc4.abimethod(allow_actions=["OptIn"]) // def opt_in(self) -> None: proto 0 0 - // tests/artifacts/StateOps/contract.py:527 + // tests/artifacts/StateOps/contract.py:645 // self.implicit_key_arc4_uint[Global.creator_address] = arc4.UInt64(1337) global CreatorAddress - // tests/artifacts/StateOps/contract.py:505-506 + // tests/artifacts/StateOps/contract.py:623-624 // # Implicit key state variables // self.implicit_key_arc4_uint = LocalState(arc4.UInt64) byte "implicit_key_arc4_uint" - // tests/artifacts/StateOps/contract.py:527 + // tests/artifacts/StateOps/contract.py:645 // self.implicit_key_arc4_uint[Global.creator_address] = arc4.UInt64(1337) byte 0x0000000000000539 app_local_put - // tests/artifacts/StateOps/contract.py:528 + // tests/artifacts/StateOps/contract.py:646 // self.implicit_key_arc4_string[Global.creator_address] = arc4.String("Hello") global CreatorAddress - // tests/artifacts/StateOps/contract.py:507 + // tests/artifacts/StateOps/contract.py:625 // self.implicit_key_arc4_string = LocalState(arc4.String) byte "implicit_key_arc4_string" - // tests/artifacts/StateOps/contract.py:528 + // tests/artifacts/StateOps/contract.py:646 // self.implicit_key_arc4_string[Global.creator_address] = arc4.String("Hello") byte 0x000548656c6c6f app_local_put - // tests/artifacts/StateOps/contract.py:529 + // tests/artifacts/StateOps/contract.py:647 // self.implicit_key_arc4_byte[Global.creator_address] = arc4.Byte(0) global CreatorAddress - // tests/artifacts/StateOps/contract.py:508 + // tests/artifacts/StateOps/contract.py:626 // self.implicit_key_arc4_byte = LocalState(arc4.Byte) byte "implicit_key_arc4_byte" - // tests/artifacts/StateOps/contract.py:529 + // tests/artifacts/StateOps/contract.py:647 // self.implicit_key_arc4_byte[Global.creator_address] = arc4.Byte(0) byte 0x00 app_local_put - // tests/artifacts/StateOps/contract.py:530 + // tests/artifacts/StateOps/contract.py:648 // self.implicit_key_arc4_bool[Global.creator_address] = arc4.Bool(True) global CreatorAddress - // tests/artifacts/StateOps/contract.py:509 + // tests/artifacts/StateOps/contract.py:627 // self.implicit_key_arc4_bool = LocalState(arc4.Bool) byte "implicit_key_arc4_bool" - // tests/artifacts/StateOps/contract.py:530 + // tests/artifacts/StateOps/contract.py:648 // self.implicit_key_arc4_bool[Global.creator_address] = arc4.Bool(True) byte 0x80 app_local_put - // tests/artifacts/StateOps/contract.py:531 + // tests/artifacts/StateOps/contract.py:649 // self.implicit_key_arc4_address[Global.creator_address] = arc4.Address( global CreatorAddress - // tests/artifacts/StateOps/contract.py:510 + // tests/artifacts/StateOps/contract.py:628 // self.implicit_key_arc4_address = LocalState(arc4.Address) byte "implicit_key_arc4_address" - // tests/artifacts/StateOps/contract.py:532 + // tests/artifacts/StateOps/contract.py:650 // Global.creator_address global CreatorAddress - // tests/artifacts/StateOps/contract.py:531-533 + // tests/artifacts/StateOps/contract.py:649-651 // self.implicit_key_arc4_address[Global.creator_address] = arc4.Address( // Global.creator_address // ) app_local_put - // tests/artifacts/StateOps/contract.py:534 + // tests/artifacts/StateOps/contract.py:652 // self.implicit_key_arc4_uint128[Global.creator_address] = arc4.UInt128(2**100) global CreatorAddress - // tests/artifacts/StateOps/contract.py:511 + // tests/artifacts/StateOps/contract.py:629 // self.implicit_key_arc4_uint128 = LocalState(arc4.UInt128) byte "implicit_key_arc4_uint128" - // tests/artifacts/StateOps/contract.py:534 + // tests/artifacts/StateOps/contract.py:652 // self.implicit_key_arc4_uint128[Global.creator_address] = arc4.UInt128(2**100) byte 0x00000010000000000000000000000000 app_local_put - // tests/artifacts/StateOps/contract.py:535 + // tests/artifacts/StateOps/contract.py:653 // self.implicit_key_arc4_dynamic_bytes[Global.creator_address] = arc4.DynamicBytes( global CreatorAddress - // tests/artifacts/StateOps/contract.py:512 + // tests/artifacts/StateOps/contract.py:630 // self.implicit_key_arc4_dynamic_bytes = LocalState(arc4.DynamicBytes) byte "implicit_key_arc4_dynamic_bytes" - // tests/artifacts/StateOps/contract.py:535-537 + // tests/artifacts/StateOps/contract.py:653-655 // self.implicit_key_arc4_dynamic_bytes[Global.creator_address] = arc4.DynamicBytes( // b"dynamic bytes" // ) byte 0x000d64796e616d6963206279746573 app_local_put - // tests/artifacts/StateOps/contract.py:539 + // tests/artifacts/StateOps/contract.py:657 // self.arc4_uint[Global.creator_address] = arc4.UInt64(1337) global CreatorAddress - // tests/artifacts/StateOps/contract.py:514-515 + // tests/artifacts/StateOps/contract.py:632-633 // # Explicit key state variables // self.arc4_uint = LocalState(arc4.UInt64, key="explicit_key_arc4_uint") byte "explicit_key_arc4_uint" - // tests/artifacts/StateOps/contract.py:539 + // tests/artifacts/StateOps/contract.py:657 // self.arc4_uint[Global.creator_address] = arc4.UInt64(1337) byte 0x0000000000000539 app_local_put - // tests/artifacts/StateOps/contract.py:540 + // tests/artifacts/StateOps/contract.py:658 // self.arc4_string[Global.creator_address] = arc4.String("Hello") global CreatorAddress - // tests/artifacts/StateOps/contract.py:516 + // tests/artifacts/StateOps/contract.py:634 // self.arc4_string = LocalState(arc4.String, key="explicit_key_arc4_string") byte "explicit_key_arc4_string" - // tests/artifacts/StateOps/contract.py:540 + // tests/artifacts/StateOps/contract.py:658 // self.arc4_string[Global.creator_address] = arc4.String("Hello") byte 0x000548656c6c6f app_local_put - // tests/artifacts/StateOps/contract.py:541 + // tests/artifacts/StateOps/contract.py:659 // self.arc4_byte[Global.creator_address] = arc4.Byte(0) global CreatorAddress - // tests/artifacts/StateOps/contract.py:517 + // tests/artifacts/StateOps/contract.py:635 // self.arc4_byte = LocalState(arc4.Byte, key="explicit_key_arc4_byte") byte "explicit_key_arc4_byte" - // tests/artifacts/StateOps/contract.py:541 + // tests/artifacts/StateOps/contract.py:659 // self.arc4_byte[Global.creator_address] = arc4.Byte(0) byte 0x00 app_local_put - // tests/artifacts/StateOps/contract.py:542 + // tests/artifacts/StateOps/contract.py:660 // self.arc4_bool[Global.creator_address] = arc4.Bool(True) global CreatorAddress - // tests/artifacts/StateOps/contract.py:518 + // tests/artifacts/StateOps/contract.py:636 // self.arc4_bool = LocalState(arc4.Bool, key="explicit_key_arc4_bool") byte "explicit_key_arc4_bool" - // tests/artifacts/StateOps/contract.py:542 + // tests/artifacts/StateOps/contract.py:660 // self.arc4_bool[Global.creator_address] = arc4.Bool(True) byte 0x80 app_local_put - // tests/artifacts/StateOps/contract.py:543 + // tests/artifacts/StateOps/contract.py:661 // self.arc4_address[Global.creator_address] = arc4.Address(Global.creator_address) global CreatorAddress - // tests/artifacts/StateOps/contract.py:519 + // tests/artifacts/StateOps/contract.py:637 // self.arc4_address = LocalState(arc4.Address, key="explicit_key_arc4_address") byte "explicit_key_arc4_address" - // tests/artifacts/StateOps/contract.py:543 + // tests/artifacts/StateOps/contract.py:661 // self.arc4_address[Global.creator_address] = arc4.Address(Global.creator_address) global CreatorAddress app_local_put - // tests/artifacts/StateOps/contract.py:544 + // tests/artifacts/StateOps/contract.py:662 // self.arc4_uint128[Global.creator_address] = arc4.UInt128(2**100) global CreatorAddress - // tests/artifacts/StateOps/contract.py:520 + // tests/artifacts/StateOps/contract.py:638 // self.arc4_uint128 = LocalState(arc4.UInt128, key="explicit_key_arc4_uint128") byte "explicit_key_arc4_uint128" - // tests/artifacts/StateOps/contract.py:544 + // tests/artifacts/StateOps/contract.py:662 // self.arc4_uint128[Global.creator_address] = arc4.UInt128(2**100) byte 0x00000010000000000000000000000000 app_local_put - // tests/artifacts/StateOps/contract.py:545 + // tests/artifacts/StateOps/contract.py:663 // self.arc4_dynamic_bytes[Global.creator_address] = arc4.DynamicBytes(b"dynamic bytes") global CreatorAddress - // tests/artifacts/StateOps/contract.py:522 + // tests/artifacts/StateOps/contract.py:640 // arc4.DynamicBytes, key="explicit_key_arc4_dynamic_bytes" byte "explicit_key_arc4_dynamic_bytes" - // tests/artifacts/StateOps/contract.py:545 + // tests/artifacts/StateOps/contract.py:663 // self.arc4_dynamic_bytes[Global.creator_address] = arc4.DynamicBytes(b"dynamic bytes") byte 0x000d64796e616d6963206279746573 app_local_put @@ -535,20 +535,20 @@ opt_in: // tests.artifacts.StateOps.contract.LocalStateContract.get_implicit_key_arc4_uint(a: bytes) -> bytes: get_implicit_key_arc4_uint: - // tests/artifacts/StateOps/contract.py:547-549 + // tests/artifacts/StateOps/contract.py:665-667 // # Getter methods for implicit key state variables // @arc4.abimethod() // def get_implicit_key_arc4_uint(self, a: Account) -> arc4.UInt64: proto 1 1 - // tests/artifacts/StateOps/contract.py:550 + // tests/artifacts/StateOps/contract.py:668 // return self.implicit_key_arc4_uint[a] frame_dig -1 int 0 - // tests/artifacts/StateOps/contract.py:505-506 + // tests/artifacts/StateOps/contract.py:623-624 // # Implicit key state variables // self.implicit_key_arc4_uint = LocalState(arc4.UInt64) byte "implicit_key_arc4_uint" - // tests/artifacts/StateOps/contract.py:550 + // tests/artifacts/StateOps/contract.py:668 // return self.implicit_key_arc4_uint[a] app_local_get_ex assert // check self.implicit_key_arc4_uint exists for account @@ -557,18 +557,18 @@ get_implicit_key_arc4_uint: // tests.artifacts.StateOps.contract.LocalStateContract.get_implicit_key_arc4_string(a: bytes) -> bytes: get_implicit_key_arc4_string: - // tests/artifacts/StateOps/contract.py:552-553 + // tests/artifacts/StateOps/contract.py:670-671 // @arc4.abimethod() // def get_implicit_key_arc4_string(self, a: Account) -> arc4.String: proto 1 1 - // tests/artifacts/StateOps/contract.py:554 + // tests/artifacts/StateOps/contract.py:672 // return self.implicit_key_arc4_string[a] frame_dig -1 int 0 - // tests/artifacts/StateOps/contract.py:507 + // tests/artifacts/StateOps/contract.py:625 // self.implicit_key_arc4_string = LocalState(arc4.String) byte "implicit_key_arc4_string" - // tests/artifacts/StateOps/contract.py:554 + // tests/artifacts/StateOps/contract.py:672 // return self.implicit_key_arc4_string[a] app_local_get_ex assert // check self.implicit_key_arc4_string exists for account @@ -577,18 +577,18 @@ get_implicit_key_arc4_string: // tests.artifacts.StateOps.contract.LocalStateContract.get_implicit_key_arc4_byte(a: bytes) -> bytes: get_implicit_key_arc4_byte: - // tests/artifacts/StateOps/contract.py:556-557 + // tests/artifacts/StateOps/contract.py:674-675 // @arc4.abimethod() // def get_implicit_key_arc4_byte(self, a: Account) -> arc4.Byte: proto 1 1 - // tests/artifacts/StateOps/contract.py:558 + // tests/artifacts/StateOps/contract.py:676 // return self.implicit_key_arc4_byte[a] frame_dig -1 int 0 - // tests/artifacts/StateOps/contract.py:508 + // tests/artifacts/StateOps/contract.py:626 // self.implicit_key_arc4_byte = LocalState(arc4.Byte) byte "implicit_key_arc4_byte" - // tests/artifacts/StateOps/contract.py:558 + // tests/artifacts/StateOps/contract.py:676 // return self.implicit_key_arc4_byte[a] app_local_get_ex assert // check self.implicit_key_arc4_byte exists for account @@ -597,18 +597,18 @@ get_implicit_key_arc4_byte: // tests.artifacts.StateOps.contract.LocalStateContract.get_implicit_key_arc4_bool(a: bytes) -> bytes: get_implicit_key_arc4_bool: - // tests/artifacts/StateOps/contract.py:560-561 + // tests/artifacts/StateOps/contract.py:678-679 // @arc4.abimethod() // def get_implicit_key_arc4_bool(self, a: Account) -> arc4.Bool: proto 1 1 - // tests/artifacts/StateOps/contract.py:562 + // tests/artifacts/StateOps/contract.py:680 // return self.implicit_key_arc4_bool[a] frame_dig -1 int 0 - // tests/artifacts/StateOps/contract.py:509 + // tests/artifacts/StateOps/contract.py:627 // self.implicit_key_arc4_bool = LocalState(arc4.Bool) byte "implicit_key_arc4_bool" - // tests/artifacts/StateOps/contract.py:562 + // tests/artifacts/StateOps/contract.py:680 // return self.implicit_key_arc4_bool[a] app_local_get_ex assert // check self.implicit_key_arc4_bool exists for account @@ -617,18 +617,18 @@ get_implicit_key_arc4_bool: // tests.artifacts.StateOps.contract.LocalStateContract.get_implicit_key_arc4_address(a: bytes) -> bytes: get_implicit_key_arc4_address: - // tests/artifacts/StateOps/contract.py:564-565 + // tests/artifacts/StateOps/contract.py:682-683 // @arc4.abimethod() // def get_implicit_key_arc4_address(self, a: Account) -> arc4.Address: proto 1 1 - // tests/artifacts/StateOps/contract.py:566 + // tests/artifacts/StateOps/contract.py:684 // return self.implicit_key_arc4_address[a] frame_dig -1 int 0 - // tests/artifacts/StateOps/contract.py:510 + // tests/artifacts/StateOps/contract.py:628 // self.implicit_key_arc4_address = LocalState(arc4.Address) byte "implicit_key_arc4_address" - // tests/artifacts/StateOps/contract.py:566 + // tests/artifacts/StateOps/contract.py:684 // return self.implicit_key_arc4_address[a] app_local_get_ex assert // check self.implicit_key_arc4_address exists for account @@ -637,18 +637,18 @@ get_implicit_key_arc4_address: // tests.artifacts.StateOps.contract.LocalStateContract.get_implicit_key_arc4_uint128(a: bytes) -> bytes: get_implicit_key_arc4_uint128: - // tests/artifacts/StateOps/contract.py:568-569 + // tests/artifacts/StateOps/contract.py:686-687 // @arc4.abimethod() // def get_implicit_key_arc4_uint128(self, a: Account) -> arc4.UInt128: proto 1 1 - // tests/artifacts/StateOps/contract.py:570 + // tests/artifacts/StateOps/contract.py:688 // return self.implicit_key_arc4_uint128[a] frame_dig -1 int 0 - // tests/artifacts/StateOps/contract.py:511 + // tests/artifacts/StateOps/contract.py:629 // self.implicit_key_arc4_uint128 = LocalState(arc4.UInt128) byte "implicit_key_arc4_uint128" - // tests/artifacts/StateOps/contract.py:570 + // tests/artifacts/StateOps/contract.py:688 // return self.implicit_key_arc4_uint128[a] app_local_get_ex assert // check self.implicit_key_arc4_uint128 exists for account @@ -657,18 +657,18 @@ get_implicit_key_arc4_uint128: // tests.artifacts.StateOps.contract.LocalStateContract.get_implicit_key_arc4_dynamic_bytes(a: bytes) -> bytes: get_implicit_key_arc4_dynamic_bytes: - // tests/artifacts/StateOps/contract.py:572-573 + // tests/artifacts/StateOps/contract.py:690-691 // @arc4.abimethod() // def get_implicit_key_arc4_dynamic_bytes(self, a: Account) -> arc4.DynamicBytes: proto 1 1 - // tests/artifacts/StateOps/contract.py:574 + // tests/artifacts/StateOps/contract.py:692 // return self.implicit_key_arc4_dynamic_bytes[a] frame_dig -1 int 0 - // tests/artifacts/StateOps/contract.py:512 + // tests/artifacts/StateOps/contract.py:630 // self.implicit_key_arc4_dynamic_bytes = LocalState(arc4.DynamicBytes) byte "implicit_key_arc4_dynamic_bytes" - // tests/artifacts/StateOps/contract.py:574 + // tests/artifacts/StateOps/contract.py:692 // return self.implicit_key_arc4_dynamic_bytes[a] app_local_get_ex assert // check self.implicit_key_arc4_dynamic_bytes exists for account @@ -677,20 +677,20 @@ get_implicit_key_arc4_dynamic_bytes: // tests.artifacts.StateOps.contract.LocalStateContract.get_arc4_uint(a: bytes) -> bytes: get_arc4_uint: - // tests/artifacts/StateOps/contract.py:576-578 + // tests/artifacts/StateOps/contract.py:694-696 // # Getter methods for explicit key state variables // @arc4.abimethod() // def get_arc4_uint(self, a: Account) -> arc4.UInt64: proto 1 1 - // tests/artifacts/StateOps/contract.py:579 + // tests/artifacts/StateOps/contract.py:697 // return self.arc4_uint[a] frame_dig -1 int 0 - // tests/artifacts/StateOps/contract.py:514-515 + // tests/artifacts/StateOps/contract.py:632-633 // # Explicit key state variables // self.arc4_uint = LocalState(arc4.UInt64, key="explicit_key_arc4_uint") byte "explicit_key_arc4_uint" - // tests/artifacts/StateOps/contract.py:579 + // tests/artifacts/StateOps/contract.py:697 // return self.arc4_uint[a] app_local_get_ex assert // check self.arc4_uint exists for account @@ -699,18 +699,18 @@ get_arc4_uint: // tests.artifacts.StateOps.contract.LocalStateContract.get_arc4_string(a: bytes) -> bytes: get_arc4_string: - // tests/artifacts/StateOps/contract.py:581-582 + // tests/artifacts/StateOps/contract.py:699-700 // @arc4.abimethod() // def get_arc4_string(self, a: Account) -> arc4.String: proto 1 1 - // tests/artifacts/StateOps/contract.py:583 + // tests/artifacts/StateOps/contract.py:701 // return self.arc4_string[a] frame_dig -1 int 0 - // tests/artifacts/StateOps/contract.py:516 + // tests/artifacts/StateOps/contract.py:634 // self.arc4_string = LocalState(arc4.String, key="explicit_key_arc4_string") byte "explicit_key_arc4_string" - // tests/artifacts/StateOps/contract.py:583 + // tests/artifacts/StateOps/contract.py:701 // return self.arc4_string[a] app_local_get_ex assert // check self.arc4_string exists for account @@ -719,18 +719,18 @@ get_arc4_string: // tests.artifacts.StateOps.contract.LocalStateContract.get_arc4_byte(a: bytes) -> bytes: get_arc4_byte: - // tests/artifacts/StateOps/contract.py:585-586 + // tests/artifacts/StateOps/contract.py:703-704 // @arc4.abimethod() // def get_arc4_byte(self, a: Account) -> arc4.Byte: proto 1 1 - // tests/artifacts/StateOps/contract.py:587 + // tests/artifacts/StateOps/contract.py:705 // return self.arc4_byte[a] frame_dig -1 int 0 - // tests/artifacts/StateOps/contract.py:517 + // tests/artifacts/StateOps/contract.py:635 // self.arc4_byte = LocalState(arc4.Byte, key="explicit_key_arc4_byte") byte "explicit_key_arc4_byte" - // tests/artifacts/StateOps/contract.py:587 + // tests/artifacts/StateOps/contract.py:705 // return self.arc4_byte[a] app_local_get_ex assert // check self.arc4_byte exists for account @@ -739,18 +739,18 @@ get_arc4_byte: // tests.artifacts.StateOps.contract.LocalStateContract.get_arc4_bool(a: bytes) -> bytes: get_arc4_bool: - // tests/artifacts/StateOps/contract.py:589-590 + // tests/artifacts/StateOps/contract.py:707-708 // @arc4.abimethod() // def get_arc4_bool(self, a: Account) -> arc4.Bool: proto 1 1 - // tests/artifacts/StateOps/contract.py:591 + // tests/artifacts/StateOps/contract.py:709 // return self.arc4_bool[a] frame_dig -1 int 0 - // tests/artifacts/StateOps/contract.py:518 + // tests/artifacts/StateOps/contract.py:636 // self.arc4_bool = LocalState(arc4.Bool, key="explicit_key_arc4_bool") byte "explicit_key_arc4_bool" - // tests/artifacts/StateOps/contract.py:591 + // tests/artifacts/StateOps/contract.py:709 // return self.arc4_bool[a] app_local_get_ex assert // check self.arc4_bool exists for account @@ -759,18 +759,18 @@ get_arc4_bool: // tests.artifacts.StateOps.contract.LocalStateContract.get_arc4_address(a: bytes) -> bytes: get_arc4_address: - // tests/artifacts/StateOps/contract.py:593-594 + // tests/artifacts/StateOps/contract.py:711-712 // @arc4.abimethod() // def get_arc4_address(self, a: Account) -> arc4.Address: proto 1 1 - // tests/artifacts/StateOps/contract.py:595 + // tests/artifacts/StateOps/contract.py:713 // return self.arc4_address[a] frame_dig -1 int 0 - // tests/artifacts/StateOps/contract.py:519 + // tests/artifacts/StateOps/contract.py:637 // self.arc4_address = LocalState(arc4.Address, key="explicit_key_arc4_address") byte "explicit_key_arc4_address" - // tests/artifacts/StateOps/contract.py:595 + // tests/artifacts/StateOps/contract.py:713 // return self.arc4_address[a] app_local_get_ex assert // check self.arc4_address exists for account @@ -779,18 +779,18 @@ get_arc4_address: // tests.artifacts.StateOps.contract.LocalStateContract.get_arc4_uint128(a: bytes) -> bytes: get_arc4_uint128: - // tests/artifacts/StateOps/contract.py:597-598 + // tests/artifacts/StateOps/contract.py:715-716 // @arc4.abimethod() // def get_arc4_uint128(self, a: Account) -> arc4.UInt128: proto 1 1 - // tests/artifacts/StateOps/contract.py:599 + // tests/artifacts/StateOps/contract.py:717 // return self.arc4_uint128[a] frame_dig -1 int 0 - // tests/artifacts/StateOps/contract.py:520 + // tests/artifacts/StateOps/contract.py:638 // self.arc4_uint128 = LocalState(arc4.UInt128, key="explicit_key_arc4_uint128") byte "explicit_key_arc4_uint128" - // tests/artifacts/StateOps/contract.py:599 + // tests/artifacts/StateOps/contract.py:717 // return self.arc4_uint128[a] app_local_get_ex assert // check self.arc4_uint128 exists for account @@ -799,18 +799,18 @@ get_arc4_uint128: // tests.artifacts.StateOps.contract.LocalStateContract.get_arc4_dynamic_bytes(a: bytes) -> bytes: get_arc4_dynamic_bytes: - // tests/artifacts/StateOps/contract.py:601-602 + // tests/artifacts/StateOps/contract.py:719-720 // @arc4.abimethod() // def get_arc4_dynamic_bytes(self, a: Account) -> arc4.DynamicBytes: proto 1 1 - // tests/artifacts/StateOps/contract.py:603 + // tests/artifacts/StateOps/contract.py:721 // return self.arc4_dynamic_bytes[a] frame_dig -1 int 0 - // tests/artifacts/StateOps/contract.py:522 + // tests/artifacts/StateOps/contract.py:640 // arc4.DynamicBytes, key="explicit_key_arc4_dynamic_bytes" byte "explicit_key_arc4_dynamic_bytes" - // tests/artifacts/StateOps/contract.py:603 + // tests/artifacts/StateOps/contract.py:721 // return self.arc4_dynamic_bytes[a] app_local_get_ex assert // check self.arc4_dynamic_bytes exists for account diff --git a/tests/artifacts/StateOps/data/LocalStateContract.arc32.json b/tests/artifacts/StateOps/data/LocalStateContract.arc32.json index ec169de..a03812d 100644 --- a/tests/artifacts/StateOps/data/LocalStateContract.arc32.json +++ b/tests/artifacts/StateOps/data/LocalStateContract.arc32.json @@ -77,8 +77,8 @@ } }, "source": { - "approval": "I3ByYWdtYSB2ZXJzaW9uIDEwCgp0ZXN0cy5hcnRpZmFjdHMuU3RhdGVPcHMuY29udHJhY3QuTG9jYWxTdGF0ZUNvbnRyYWN0LmFwcHJvdmFsX3Byb2dyYW06CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6NTAzCiAgICAvLyBjbGFzcyBMb2NhbFN0YXRlQ29udHJhY3QoQVJDNENvbnRyYWN0KToKICAgIHR4biBOdW1BcHBBcmdzCiAgICBieiBtYWluX2JhcmVfcm91dGluZ0AxOQogICAgbWV0aG9kICJvcHRfaW4oKXZvaWQiCiAgICBtZXRob2QgImdldF9pbXBsaWNpdF9rZXlfYXJjNF91aW50KGFjY291bnQpdWludDY0IgogICAgbWV0aG9kICJnZXRfaW1wbGljaXRfa2V5X2FyYzRfc3RyaW5nKGFjY291bnQpc3RyaW5nIgogICAgbWV0aG9kICJnZXRfaW1wbGljaXRfa2V5X2FyYzRfYnl0ZShhY2NvdW50KWJ5dGUiCiAgICBtZXRob2QgImdldF9pbXBsaWNpdF9rZXlfYXJjNF9ib29sKGFjY291bnQpYm9vbCIKICAgIG1ldGhvZCAiZ2V0X2ltcGxpY2l0X2tleV9hcmM0X2FkZHJlc3MoYWNjb3VudClhZGRyZXNzIgogICAgbWV0aG9kICJnZXRfaW1wbGljaXRfa2V5X2FyYzRfdWludDEyOChhY2NvdW50KXVpbnQxMjgiCiAgICBtZXRob2QgImdldF9pbXBsaWNpdF9rZXlfYXJjNF9keW5hbWljX2J5dGVzKGFjY291bnQpYnl0ZVtdIgogICAgbWV0aG9kICJnZXRfYXJjNF91aW50KGFjY291bnQpdWludDY0IgogICAgbWV0aG9kICJnZXRfYXJjNF9zdHJpbmcoYWNjb3VudClzdHJpbmciCiAgICBtZXRob2QgImdldF9hcmM0X2J5dGUoYWNjb3VudClieXRlIgogICAgbWV0aG9kICJnZXRfYXJjNF9ib29sKGFjY291bnQpYm9vbCIKICAgIG1ldGhvZCAiZ2V0X2FyYzRfYWRkcmVzcyhhY2NvdW50KWFkZHJlc3MiCiAgICBtZXRob2QgImdldF9hcmM0X3VpbnQxMjgoYWNjb3VudCl1aW50MTI4IgogICAgbWV0aG9kICJnZXRfYXJjNF9keW5hbWljX2J5dGVzKGFjY291bnQpYnl0ZVtdIgogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMAogICAgbWF0Y2ggbWFpbl9vcHRfaW5fcm91dGVAMiBtYWluX2dldF9pbXBsaWNpdF9rZXlfYXJjNF91aW50X3JvdXRlQDMgbWFpbl9nZXRfaW1wbGljaXRfa2V5X2FyYzRfc3RyaW5nX3JvdXRlQDQgbWFpbl9nZXRfaW1wbGljaXRfa2V5X2FyYzRfYnl0ZV9yb3V0ZUA1IG1haW5fZ2V0X2ltcGxpY2l0X2tleV9hcmM0X2Jvb2xfcm91dGVANiBtYWluX2dldF9pbXBsaWNpdF9rZXlfYXJjNF9hZGRyZXNzX3JvdXRlQDcgbWFpbl9nZXRfaW1wbGljaXRfa2V5X2FyYzRfdWludDEyOF9yb3V0ZUA4IG1haW5fZ2V0X2ltcGxpY2l0X2tleV9hcmM0X2R5bmFtaWNfYnl0ZXNfcm91dGVAOSBtYWluX2dldF9hcmM0X3VpbnRfcm91dGVAMTAgbWFpbl9nZXRfYXJjNF9zdHJpbmdfcm91dGVAMTEgbWFpbl9nZXRfYXJjNF9ieXRlX3JvdXRlQDEyIG1haW5fZ2V0X2FyYzRfYm9vbF9yb3V0ZUAxMyBtYWluX2dldF9hcmM0X2FkZHJlc3Nfcm91dGVAMTQgbWFpbl9nZXRfYXJjNF91aW50MTI4X3JvdXRlQDE1IG1haW5fZ2V0X2FyYzRfZHluYW1pY19ieXRlc19yb3V0ZUAxNgogICAgZXJyIC8vIHJlamVjdCB0cmFuc2FjdGlvbgoKbWFpbl9vcHRfaW5fcm91dGVAMjoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTo1MjUKICAgIC8vIEBhcmM0LmFiaW1ldGhvZChhbGxvd19hY3Rpb25zPVsiT3B0SW4iXSkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgIGludCBPcHRJbgogICAgPT0KICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgT3B0SW4KICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gaXMgbm90IGNyZWF0aW5nCiAgICBjYWxsc3ViIG9wdF9pbgogICAgaW50IDEKICAgIHJldHVybgoKbWFpbl9nZXRfaW1wbGljaXRfa2V5X2FyYzRfdWludF9yb3V0ZUAzOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjU0Ny01NDgKICAgIC8vICMgR2V0dGVyIG1ldGhvZHMgZm9yIGltcGxpY2l0IGtleSBzdGF0ZSB2YXJpYWJsZXMKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gaXMgbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6NTAzCiAgICAvLyBjbGFzcyBMb2NhbFN0YXRlQ29udHJhY3QoQVJDNENvbnRyYWN0KToKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGJ0b2kKICAgIHR4bmFzIEFjY291bnRzCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6NTQ3LTU0OAogICAgLy8gIyBHZXR0ZXIgbWV0aG9kcyBmb3IgaW1wbGljaXQga2V5IHN0YXRlIHZhcmlhYmxlcwogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgZ2V0X2ltcGxpY2l0X2tleV9hcmM0X3VpbnQKICAgIGJ5dGUgMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludCAxCiAgICByZXR1cm4KCm1haW5fZ2V0X2ltcGxpY2l0X2tleV9hcmM0X3N0cmluZ19yb3V0ZUA0OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjU1MgogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBpcyBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTo1MDMKICAgIC8vIGNsYXNzIExvY2FsU3RhdGVDb250cmFjdChBUkM0Q29udHJhY3QpOgogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgYnRvaQogICAgdHhuYXMgQWNjb3VudHMKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTo1NTIKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIGdldF9pbXBsaWNpdF9rZXlfYXJjNF9zdHJpbmcKICAgIGJ5dGUgMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludCAxCiAgICByZXR1cm4KCm1haW5fZ2V0X2ltcGxpY2l0X2tleV9hcmM0X2J5dGVfcm91dGVANToKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTo1NTYKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gaXMgbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6NTAzCiAgICAvLyBjbGFzcyBMb2NhbFN0YXRlQ29udHJhY3QoQVJDNENvbnRyYWN0KToKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGJ0b2kKICAgIHR4bmFzIEFjY291bnRzCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6NTU2CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiBnZXRfaW1wbGljaXRfa2V5X2FyYzRfYnl0ZQogICAgYnl0ZSAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50IDEKICAgIHJldHVybgoKbWFpbl9nZXRfaW1wbGljaXRfa2V5X2FyYzRfYm9vbF9yb3V0ZUA2OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjU2MAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBpcyBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTo1MDMKICAgIC8vIGNsYXNzIExvY2FsU3RhdGVDb250cmFjdChBUkM0Q29udHJhY3QpOgogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgYnRvaQogICAgdHhuYXMgQWNjb3VudHMKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTo1NjAKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIGdldF9pbXBsaWNpdF9rZXlfYXJjNF9ib29sCiAgICBieXRlIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnQgMQogICAgcmV0dXJuCgptYWluX2dldF9pbXBsaWNpdF9rZXlfYXJjNF9hZGRyZXNzX3JvdXRlQDc6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6NTY0CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGlzIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjUwMwogICAgLy8gY2xhc3MgTG9jYWxTdGF0ZUNvbnRyYWN0KEFSQzRDb250cmFjdCk6CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBidG9pCiAgICB0eG5hcyBBY2NvdW50cwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjU2NAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgZ2V0X2ltcGxpY2l0X2tleV9hcmM0X2FkZHJlc3MKICAgIGJ5dGUgMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludCAxCiAgICByZXR1cm4KCm1haW5fZ2V0X2ltcGxpY2l0X2tleV9hcmM0X3VpbnQxMjhfcm91dGVAODoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTo1NjgKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gaXMgbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6NTAzCiAgICAvLyBjbGFzcyBMb2NhbFN0YXRlQ29udHJhY3QoQVJDNENvbnRyYWN0KToKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGJ0b2kKICAgIHR4bmFzIEFjY291bnRzCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6NTY4CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiBnZXRfaW1wbGljaXRfa2V5X2FyYzRfdWludDEyOAogICAgYnl0ZSAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50IDEKICAgIHJldHVybgoKbWFpbl9nZXRfaW1wbGljaXRfa2V5X2FyYzRfZHluYW1pY19ieXRlc19yb3V0ZUA5OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjU3MgogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBpcyBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTo1MDMKICAgIC8vIGNsYXNzIExvY2FsU3RhdGVDb250cmFjdChBUkM0Q29udHJhY3QpOgogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgYnRvaQogICAgdHhuYXMgQWNjb3VudHMKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTo1NzIKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIGdldF9pbXBsaWNpdF9rZXlfYXJjNF9keW5hbWljX2J5dGVzCiAgICBieXRlIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnQgMQogICAgcmV0dXJuCgptYWluX2dldF9hcmM0X3VpbnRfcm91dGVAMTA6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6NTc2LTU3NwogICAgLy8gIyBHZXR0ZXIgbWV0aG9kcyBmb3IgZXhwbGljaXQga2V5IHN0YXRlIHZhcmlhYmxlcwogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBpcyBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTo1MDMKICAgIC8vIGNsYXNzIExvY2FsU3RhdGVDb250cmFjdChBUkM0Q29udHJhY3QpOgogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgYnRvaQogICAgdHhuYXMgQWNjb3VudHMKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTo1NzYtNTc3CiAgICAvLyAjIEdldHRlciBtZXRob2RzIGZvciBleHBsaWNpdCBrZXkgc3RhdGUgdmFyaWFibGVzCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiBnZXRfYXJjNF91aW50CiAgICBieXRlIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnQgMQogICAgcmV0dXJuCgptYWluX2dldF9hcmM0X3N0cmluZ19yb3V0ZUAxMToKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTo1ODEKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gaXMgbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6NTAzCiAgICAvLyBjbGFzcyBMb2NhbFN0YXRlQ29udHJhY3QoQVJDNENvbnRyYWN0KToKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGJ0b2kKICAgIHR4bmFzIEFjY291bnRzCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6NTgxCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiBnZXRfYXJjNF9zdHJpbmcKICAgIGJ5dGUgMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludCAxCiAgICByZXR1cm4KCm1haW5fZ2V0X2FyYzRfYnl0ZV9yb3V0ZUAxMjoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTo1ODUKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gaXMgbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6NTAzCiAgICAvLyBjbGFzcyBMb2NhbFN0YXRlQ29udHJhY3QoQVJDNENvbnRyYWN0KToKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGJ0b2kKICAgIHR4bmFzIEFjY291bnRzCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6NTg1CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiBnZXRfYXJjNF9ieXRlCiAgICBieXRlIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnQgMQogICAgcmV0dXJuCgptYWluX2dldF9hcmM0X2Jvb2xfcm91dGVAMTM6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6NTg5CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGlzIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjUwMwogICAgLy8gY2xhc3MgTG9jYWxTdGF0ZUNvbnRyYWN0KEFSQzRDb250cmFjdCk6CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBidG9pCiAgICB0eG5hcyBBY2NvdW50cwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjU4OQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgZ2V0X2FyYzRfYm9vbAogICAgYnl0ZSAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50IDEKICAgIHJldHVybgoKbWFpbl9nZXRfYXJjNF9hZGRyZXNzX3JvdXRlQDE0OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjU5MwogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBpcyBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTo1MDMKICAgIC8vIGNsYXNzIExvY2FsU3RhdGVDb250cmFjdChBUkM0Q29udHJhY3QpOgogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgYnRvaQogICAgdHhuYXMgQWNjb3VudHMKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTo1OTMKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIGdldF9hcmM0X2FkZHJlc3MKICAgIGJ5dGUgMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludCAxCiAgICByZXR1cm4KCm1haW5fZ2V0X2FyYzRfdWludDEyOF9yb3V0ZUAxNToKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTo1OTcKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gaXMgbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6NTAzCiAgICAvLyBjbGFzcyBMb2NhbFN0YXRlQ29udHJhY3QoQVJDNENvbnRyYWN0KToKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGJ0b2kKICAgIHR4bmFzIEFjY291bnRzCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6NTk3CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiBnZXRfYXJjNF91aW50MTI4CiAgICBieXRlIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnQgMQogICAgcmV0dXJuCgptYWluX2dldF9hcmM0X2R5bmFtaWNfYnl0ZXNfcm91dGVAMTY6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6NjAxCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGlzIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjUwMwogICAgLy8gY2xhc3MgTG9jYWxTdGF0ZUNvbnRyYWN0KEFSQzRDb250cmFjdCk6CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBidG9pCiAgICB0eG5hcyBBY2NvdW50cwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjYwMQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgZ2V0X2FyYzRfZHluYW1pY19ieXRlcwogICAgYnl0ZSAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50IDEKICAgIHJldHVybgoKbWFpbl9iYXJlX3JvdXRpbmdAMTk6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6NTAzCiAgICAvLyBjbGFzcyBMb2NhbFN0YXRlQ29udHJhY3QoQVJDNENvbnRyYWN0KToKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyByZWplY3QgdHJhbnNhY3Rpb24KICAgIHR4biBBcHBsaWNhdGlvbklECiAgICAhCiAgICBhc3NlcnQgLy8gaXMgY3JlYXRpbmcKICAgIGludCAxCiAgICByZXR1cm4KCgovLyB0ZXN0cy5hcnRpZmFjdHMuU3RhdGVPcHMuY29udHJhY3QuTG9jYWxTdGF0ZUNvbnRyYWN0Lm9wdF9pbigpIC0+IHZvaWQ6Cm9wdF9pbjoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTo1MjUtNTI2CiAgICAvLyBAYXJjNC5hYmltZXRob2QoYWxsb3dfYWN0aW9ucz1bIk9wdEluIl0pCiAgICAvLyBkZWYgb3B0X2luKHNlbGYpIC0+IE5vbmU6CiAgICBwcm90byAwIDAKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTo1MjcKICAgIC8vIHNlbGYuaW1wbGljaXRfa2V5X2FyYzRfdWludFtHbG9iYWwuY3JlYXRvcl9hZGRyZXNzXSA9IGFyYzQuVUludDY0KDEzMzcpCiAgICBnbG9iYWwgQ3JlYXRvckFkZHJlc3MKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTo1MDUtNTA2CiAgICAvLyAjIEltcGxpY2l0IGtleSBzdGF0ZSB2YXJpYWJsZXMKICAgIC8vIHNlbGYuaW1wbGljaXRfa2V5X2FyYzRfdWludCA9IExvY2FsU3RhdGUoYXJjNC5VSW50NjQpCiAgICBieXRlICJpbXBsaWNpdF9rZXlfYXJjNF91aW50IgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjUyNwogICAgLy8gc2VsZi5pbXBsaWNpdF9rZXlfYXJjNF91aW50W0dsb2JhbC5jcmVhdG9yX2FkZHJlc3NdID0gYXJjNC5VSW50NjQoMTMzNykKICAgIGJ5dGUgMHgwMDAwMDAwMDAwMDAwNTM5CiAgICBhcHBfbG9jYWxfcHV0CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6NTI4CiAgICAvLyBzZWxmLmltcGxpY2l0X2tleV9hcmM0X3N0cmluZ1tHbG9iYWwuY3JlYXRvcl9hZGRyZXNzXSA9IGFyYzQuU3RyaW5nKCJIZWxsbyIpCiAgICBnbG9iYWwgQ3JlYXRvckFkZHJlc3MKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTo1MDcKICAgIC8vIHNlbGYuaW1wbGljaXRfa2V5X2FyYzRfc3RyaW5nID0gTG9jYWxTdGF0ZShhcmM0LlN0cmluZykKICAgIGJ5dGUgImltcGxpY2l0X2tleV9hcmM0X3N0cmluZyIKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTo1MjgKICAgIC8vIHNlbGYuaW1wbGljaXRfa2V5X2FyYzRfc3RyaW5nW0dsb2JhbC5jcmVhdG9yX2FkZHJlc3NdID0gYXJjNC5TdHJpbmcoIkhlbGxvIikKICAgIGJ5dGUgMHgwMDA1NDg2NTZjNmM2ZgogICAgYXBwX2xvY2FsX3B1dAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjUyOQogICAgLy8gc2VsZi5pbXBsaWNpdF9rZXlfYXJjNF9ieXRlW0dsb2JhbC5jcmVhdG9yX2FkZHJlc3NdID0gYXJjNC5CeXRlKDApCiAgICBnbG9iYWwgQ3JlYXRvckFkZHJlc3MKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTo1MDgKICAgIC8vIHNlbGYuaW1wbGljaXRfa2V5X2FyYzRfYnl0ZSA9IExvY2FsU3RhdGUoYXJjNC5CeXRlKQogICAgYnl0ZSAiaW1wbGljaXRfa2V5X2FyYzRfYnl0ZSIKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTo1MjkKICAgIC8vIHNlbGYuaW1wbGljaXRfa2V5X2FyYzRfYnl0ZVtHbG9iYWwuY3JlYXRvcl9hZGRyZXNzXSA9IGFyYzQuQnl0ZSgwKQogICAgYnl0ZSAweDAwCiAgICBhcHBfbG9jYWxfcHV0CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6NTMwCiAgICAvLyBzZWxmLmltcGxpY2l0X2tleV9hcmM0X2Jvb2xbR2xvYmFsLmNyZWF0b3JfYWRkcmVzc10gPSBhcmM0LkJvb2woVHJ1ZSkKICAgIGdsb2JhbCBDcmVhdG9yQWRkcmVzcwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjUwOQogICAgLy8gc2VsZi5pbXBsaWNpdF9rZXlfYXJjNF9ib29sID0gTG9jYWxTdGF0ZShhcmM0LkJvb2wpCiAgICBieXRlICJpbXBsaWNpdF9rZXlfYXJjNF9ib29sIgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjUzMAogICAgLy8gc2VsZi5pbXBsaWNpdF9rZXlfYXJjNF9ib29sW0dsb2JhbC5jcmVhdG9yX2FkZHJlc3NdID0gYXJjNC5Cb29sKFRydWUpCiAgICBieXRlIDB4ODAKICAgIGFwcF9sb2NhbF9wdXQKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTo1MzEKICAgIC8vIHNlbGYuaW1wbGljaXRfa2V5X2FyYzRfYWRkcmVzc1tHbG9iYWwuY3JlYXRvcl9hZGRyZXNzXSA9IGFyYzQuQWRkcmVzcygKICAgIGdsb2JhbCBDcmVhdG9yQWRkcmVzcwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjUxMAogICAgLy8gc2VsZi5pbXBsaWNpdF9rZXlfYXJjNF9hZGRyZXNzID0gTG9jYWxTdGF0ZShhcmM0LkFkZHJlc3MpCiAgICBieXRlICJpbXBsaWNpdF9rZXlfYXJjNF9hZGRyZXNzIgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjUzMgogICAgLy8gR2xvYmFsLmNyZWF0b3JfYWRkcmVzcwogICAgZ2xvYmFsIENyZWF0b3JBZGRyZXNzCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6NTMxLTUzMwogICAgLy8gc2VsZi5pbXBsaWNpdF9rZXlfYXJjNF9hZGRyZXNzW0dsb2JhbC5jcmVhdG9yX2FkZHJlc3NdID0gYXJjNC5BZGRyZXNzKAogICAgLy8gICAgIEdsb2JhbC5jcmVhdG9yX2FkZHJlc3MKICAgIC8vICkKICAgIGFwcF9sb2NhbF9wdXQKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTo1MzQKICAgIC8vIHNlbGYuaW1wbGljaXRfa2V5X2FyYzRfdWludDEyOFtHbG9iYWwuY3JlYXRvcl9hZGRyZXNzXSA9IGFyYzQuVUludDEyOCgyKioxMDApCiAgICBnbG9iYWwgQ3JlYXRvckFkZHJlc3MKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTo1MTEKICAgIC8vIHNlbGYuaW1wbGljaXRfa2V5X2FyYzRfdWludDEyOCA9IExvY2FsU3RhdGUoYXJjNC5VSW50MTI4KQogICAgYnl0ZSAiaW1wbGljaXRfa2V5X2FyYzRfdWludDEyOCIKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTo1MzQKICAgIC8vIHNlbGYuaW1wbGljaXRfa2V5X2FyYzRfdWludDEyOFtHbG9iYWwuY3JlYXRvcl9hZGRyZXNzXSA9IGFyYzQuVUludDEyOCgyKioxMDApCiAgICBieXRlIDB4MDAwMDAwMTAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAKICAgIGFwcF9sb2NhbF9wdXQKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTo1MzUKICAgIC8vIHNlbGYuaW1wbGljaXRfa2V5X2FyYzRfZHluYW1pY19ieXRlc1tHbG9iYWwuY3JlYXRvcl9hZGRyZXNzXSA9IGFyYzQuRHluYW1pY0J5dGVzKAogICAgZ2xvYmFsIENyZWF0b3JBZGRyZXNzCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6NTEyCiAgICAvLyBzZWxmLmltcGxpY2l0X2tleV9hcmM0X2R5bmFtaWNfYnl0ZXMgPSBMb2NhbFN0YXRlKGFyYzQuRHluYW1pY0J5dGVzKQogICAgYnl0ZSAiaW1wbGljaXRfa2V5X2FyYzRfZHluYW1pY19ieXRlcyIKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTo1MzUtNTM3CiAgICAvLyBzZWxmLmltcGxpY2l0X2tleV9hcmM0X2R5bmFtaWNfYnl0ZXNbR2xvYmFsLmNyZWF0b3JfYWRkcmVzc10gPSBhcmM0LkR5bmFtaWNCeXRlcygKICAgIC8vICAgICBiImR5bmFtaWMgYnl0ZXMiCiAgICAvLyApCiAgICBieXRlIDB4MDAwZDY0Nzk2ZTYxNmQ2OTYzMjA2Mjc5NzQ2NTczCiAgICBhcHBfbG9jYWxfcHV0CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6NTM5CiAgICAvLyBzZWxmLmFyYzRfdWludFtHbG9iYWwuY3JlYXRvcl9hZGRyZXNzXSA9IGFyYzQuVUludDY0KDEzMzcpCiAgICBnbG9iYWwgQ3JlYXRvckFkZHJlc3MKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTo1MTQtNTE1CiAgICAvLyAjIEV4cGxpY2l0IGtleSBzdGF0ZSB2YXJpYWJsZXMKICAgIC8vIHNlbGYuYXJjNF91aW50ID0gTG9jYWxTdGF0ZShhcmM0LlVJbnQ2NCwga2V5PSJleHBsaWNpdF9rZXlfYXJjNF91aW50IikKICAgIGJ5dGUgImV4cGxpY2l0X2tleV9hcmM0X3VpbnQiCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6NTM5CiAgICAvLyBzZWxmLmFyYzRfdWludFtHbG9iYWwuY3JlYXRvcl9hZGRyZXNzXSA9IGFyYzQuVUludDY0KDEzMzcpCiAgICBieXRlIDB4MDAwMDAwMDAwMDAwMDUzOQogICAgYXBwX2xvY2FsX3B1dAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjU0MAogICAgLy8gc2VsZi5hcmM0X3N0cmluZ1tHbG9iYWwuY3JlYXRvcl9hZGRyZXNzXSA9IGFyYzQuU3RyaW5nKCJIZWxsbyIpCiAgICBnbG9iYWwgQ3JlYXRvckFkZHJlc3MKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTo1MTYKICAgIC8vIHNlbGYuYXJjNF9zdHJpbmcgPSBMb2NhbFN0YXRlKGFyYzQuU3RyaW5nLCBrZXk9ImV4cGxpY2l0X2tleV9hcmM0X3N0cmluZyIpCiAgICBieXRlICJleHBsaWNpdF9rZXlfYXJjNF9zdHJpbmciCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6NTQwCiAgICAvLyBzZWxmLmFyYzRfc3RyaW5nW0dsb2JhbC5jcmVhdG9yX2FkZHJlc3NdID0gYXJjNC5TdHJpbmcoIkhlbGxvIikKICAgIGJ5dGUgMHgwMDA1NDg2NTZjNmM2ZgogICAgYXBwX2xvY2FsX3B1dAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjU0MQogICAgLy8gc2VsZi5hcmM0X2J5dGVbR2xvYmFsLmNyZWF0b3JfYWRkcmVzc10gPSBhcmM0LkJ5dGUoMCkKICAgIGdsb2JhbCBDcmVhdG9yQWRkcmVzcwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjUxNwogICAgLy8gc2VsZi5hcmM0X2J5dGUgPSBMb2NhbFN0YXRlKGFyYzQuQnl0ZSwga2V5PSJleHBsaWNpdF9rZXlfYXJjNF9ieXRlIikKICAgIGJ5dGUgImV4cGxpY2l0X2tleV9hcmM0X2J5dGUiCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6NTQxCiAgICAvLyBzZWxmLmFyYzRfYnl0ZVtHbG9iYWwuY3JlYXRvcl9hZGRyZXNzXSA9IGFyYzQuQnl0ZSgwKQogICAgYnl0ZSAweDAwCiAgICBhcHBfbG9jYWxfcHV0CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6NTQyCiAgICAvLyBzZWxmLmFyYzRfYm9vbFtHbG9iYWwuY3JlYXRvcl9hZGRyZXNzXSA9IGFyYzQuQm9vbChUcnVlKQogICAgZ2xvYmFsIENyZWF0b3JBZGRyZXNzCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6NTE4CiAgICAvLyBzZWxmLmFyYzRfYm9vbCA9IExvY2FsU3RhdGUoYXJjNC5Cb29sLCBrZXk9ImV4cGxpY2l0X2tleV9hcmM0X2Jvb2wiKQogICAgYnl0ZSAiZXhwbGljaXRfa2V5X2FyYzRfYm9vbCIKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTo1NDIKICAgIC8vIHNlbGYuYXJjNF9ib29sW0dsb2JhbC5jcmVhdG9yX2FkZHJlc3NdID0gYXJjNC5Cb29sKFRydWUpCiAgICBieXRlIDB4ODAKICAgIGFwcF9sb2NhbF9wdXQKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTo1NDMKICAgIC8vIHNlbGYuYXJjNF9hZGRyZXNzW0dsb2JhbC5jcmVhdG9yX2FkZHJlc3NdID0gYXJjNC5BZGRyZXNzKEdsb2JhbC5jcmVhdG9yX2FkZHJlc3MpCiAgICBnbG9iYWwgQ3JlYXRvckFkZHJlc3MKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTo1MTkKICAgIC8vIHNlbGYuYXJjNF9hZGRyZXNzID0gTG9jYWxTdGF0ZShhcmM0LkFkZHJlc3MsIGtleT0iZXhwbGljaXRfa2V5X2FyYzRfYWRkcmVzcyIpCiAgICBieXRlICJleHBsaWNpdF9rZXlfYXJjNF9hZGRyZXNzIgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjU0MwogICAgLy8gc2VsZi5hcmM0X2FkZHJlc3NbR2xvYmFsLmNyZWF0b3JfYWRkcmVzc10gPSBhcmM0LkFkZHJlc3MoR2xvYmFsLmNyZWF0b3JfYWRkcmVzcykKICAgIGdsb2JhbCBDcmVhdG9yQWRkcmVzcwogICAgYXBwX2xvY2FsX3B1dAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjU0NAogICAgLy8gc2VsZi5hcmM0X3VpbnQxMjhbR2xvYmFsLmNyZWF0b3JfYWRkcmVzc10gPSBhcmM0LlVJbnQxMjgoMioqMTAwKQogICAgZ2xvYmFsIENyZWF0b3JBZGRyZXNzCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6NTIwCiAgICAvLyBzZWxmLmFyYzRfdWludDEyOCA9IExvY2FsU3RhdGUoYXJjNC5VSW50MTI4LCBrZXk9ImV4cGxpY2l0X2tleV9hcmM0X3VpbnQxMjgiKQogICAgYnl0ZSAiZXhwbGljaXRfa2V5X2FyYzRfdWludDEyOCIKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTo1NDQKICAgIC8vIHNlbGYuYXJjNF91aW50MTI4W0dsb2JhbC5jcmVhdG9yX2FkZHJlc3NdID0gYXJjNC5VSW50MTI4KDIqKjEwMCkKICAgIGJ5dGUgMHgwMDAwMDAxMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMAogICAgYXBwX2xvY2FsX3B1dAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjU0NQogICAgLy8gc2VsZi5hcmM0X2R5bmFtaWNfYnl0ZXNbR2xvYmFsLmNyZWF0b3JfYWRkcmVzc10gPSBhcmM0LkR5bmFtaWNCeXRlcyhiImR5bmFtaWMgYnl0ZXMiKQogICAgZ2xvYmFsIENyZWF0b3JBZGRyZXNzCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6NTIyCiAgICAvLyBhcmM0LkR5bmFtaWNCeXRlcywga2V5PSJleHBsaWNpdF9rZXlfYXJjNF9keW5hbWljX2J5dGVzIgogICAgYnl0ZSAiZXhwbGljaXRfa2V5X2FyYzRfZHluYW1pY19ieXRlcyIKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTo1NDUKICAgIC8vIHNlbGYuYXJjNF9keW5hbWljX2J5dGVzW0dsb2JhbC5jcmVhdG9yX2FkZHJlc3NdID0gYXJjNC5EeW5hbWljQnl0ZXMoYiJkeW5hbWljIGJ5dGVzIikKICAgIGJ5dGUgMHgwMDBkNjQ3OTZlNjE2ZDY5NjMyMDYyNzk3NDY1NzMKICAgIGFwcF9sb2NhbF9wdXQKICAgIHJldHN1YgoKCi8vIHRlc3RzLmFydGlmYWN0cy5TdGF0ZU9wcy5jb250cmFjdC5Mb2NhbFN0YXRlQ29udHJhY3QuZ2V0X2ltcGxpY2l0X2tleV9hcmM0X3VpbnQoYTogYnl0ZXMpIC0+IGJ5dGVzOgpnZXRfaW1wbGljaXRfa2V5X2FyYzRfdWludDoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTo1NDctNTQ5CiAgICAvLyAjIEdldHRlciBtZXRob2RzIGZvciBpbXBsaWNpdCBrZXkgc3RhdGUgdmFyaWFibGVzCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gZGVmIGdldF9pbXBsaWNpdF9rZXlfYXJjNF91aW50KHNlbGYsIGE6IEFjY291bnQpIC0+IGFyYzQuVUludDY0OgogICAgcHJvdG8gMSAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6NTUwCiAgICAvLyByZXR1cm4gc2VsZi5pbXBsaWNpdF9rZXlfYXJjNF91aW50W2FdCiAgICBmcmFtZV9kaWcgLTEKICAgIGludCAwCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6NTA1LTUwNgogICAgLy8gIyBJbXBsaWNpdCBrZXkgc3RhdGUgdmFyaWFibGVzCiAgICAvLyBzZWxmLmltcGxpY2l0X2tleV9hcmM0X3VpbnQgPSBMb2NhbFN0YXRlKGFyYzQuVUludDY0KQogICAgYnl0ZSAiaW1wbGljaXRfa2V5X2FyYzRfdWludCIKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTo1NTAKICAgIC8vIHJldHVybiBzZWxmLmltcGxpY2l0X2tleV9hcmM0X3VpbnRbYV0KICAgIGFwcF9sb2NhbF9nZXRfZXgKICAgIGFzc2VydCAvLyBjaGVjayBzZWxmLmltcGxpY2l0X2tleV9hcmM0X3VpbnQgZXhpc3RzIGZvciBhY2NvdW50CiAgICByZXRzdWIKCgovLyB0ZXN0cy5hcnRpZmFjdHMuU3RhdGVPcHMuY29udHJhY3QuTG9jYWxTdGF0ZUNvbnRyYWN0LmdldF9pbXBsaWNpdF9rZXlfYXJjNF9zdHJpbmcoYTogYnl0ZXMpIC0+IGJ5dGVzOgpnZXRfaW1wbGljaXRfa2V5X2FyYzRfc3RyaW5nOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjU1Mi01NTMKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBkZWYgZ2V0X2ltcGxpY2l0X2tleV9hcmM0X3N0cmluZyhzZWxmLCBhOiBBY2NvdW50KSAtPiBhcmM0LlN0cmluZzoKICAgIHByb3RvIDEgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjU1NAogICAgLy8gcmV0dXJuIHNlbGYuaW1wbGljaXRfa2V5X2FyYzRfc3RyaW5nW2FdCiAgICBmcmFtZV9kaWcgLTEKICAgIGludCAwCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6NTA3CiAgICAvLyBzZWxmLmltcGxpY2l0X2tleV9hcmM0X3N0cmluZyA9IExvY2FsU3RhdGUoYXJjNC5TdHJpbmcpCiAgICBieXRlICJpbXBsaWNpdF9rZXlfYXJjNF9zdHJpbmciCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6NTU0CiAgICAvLyByZXR1cm4gc2VsZi5pbXBsaWNpdF9rZXlfYXJjNF9zdHJpbmdbYV0KICAgIGFwcF9sb2NhbF9nZXRfZXgKICAgIGFzc2VydCAvLyBjaGVjayBzZWxmLmltcGxpY2l0X2tleV9hcmM0X3N0cmluZyBleGlzdHMgZm9yIGFjY291bnQKICAgIHJldHN1YgoKCi8vIHRlc3RzLmFydGlmYWN0cy5TdGF0ZU9wcy5jb250cmFjdC5Mb2NhbFN0YXRlQ29udHJhY3QuZ2V0X2ltcGxpY2l0X2tleV9hcmM0X2J5dGUoYTogYnl0ZXMpIC0+IGJ5dGVzOgpnZXRfaW1wbGljaXRfa2V5X2FyYzRfYnl0ZToKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTo1NTYtNTU3CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gZGVmIGdldF9pbXBsaWNpdF9rZXlfYXJjNF9ieXRlKHNlbGYsIGE6IEFjY291bnQpIC0+IGFyYzQuQnl0ZToKICAgIHByb3RvIDEgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjU1OAogICAgLy8gcmV0dXJuIHNlbGYuaW1wbGljaXRfa2V5X2FyYzRfYnl0ZVthXQogICAgZnJhbWVfZGlnIC0xCiAgICBpbnQgMAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjUwOAogICAgLy8gc2VsZi5pbXBsaWNpdF9rZXlfYXJjNF9ieXRlID0gTG9jYWxTdGF0ZShhcmM0LkJ5dGUpCiAgICBieXRlICJpbXBsaWNpdF9rZXlfYXJjNF9ieXRlIgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjU1OAogICAgLy8gcmV0dXJuIHNlbGYuaW1wbGljaXRfa2V5X2FyYzRfYnl0ZVthXQogICAgYXBwX2xvY2FsX2dldF9leAogICAgYXNzZXJ0IC8vIGNoZWNrIHNlbGYuaW1wbGljaXRfa2V5X2FyYzRfYnl0ZSBleGlzdHMgZm9yIGFjY291bnQKICAgIHJldHN1YgoKCi8vIHRlc3RzLmFydGlmYWN0cy5TdGF0ZU9wcy5jb250cmFjdC5Mb2NhbFN0YXRlQ29udHJhY3QuZ2V0X2ltcGxpY2l0X2tleV9hcmM0X2Jvb2woYTogYnl0ZXMpIC0+IGJ5dGVzOgpnZXRfaW1wbGljaXRfa2V5X2FyYzRfYm9vbDoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTo1NjAtNTYxCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gZGVmIGdldF9pbXBsaWNpdF9rZXlfYXJjNF9ib29sKHNlbGYsIGE6IEFjY291bnQpIC0+IGFyYzQuQm9vbDoKICAgIHByb3RvIDEgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjU2MgogICAgLy8gcmV0dXJuIHNlbGYuaW1wbGljaXRfa2V5X2FyYzRfYm9vbFthXQogICAgZnJhbWVfZGlnIC0xCiAgICBpbnQgMAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjUwOQogICAgLy8gc2VsZi5pbXBsaWNpdF9rZXlfYXJjNF9ib29sID0gTG9jYWxTdGF0ZShhcmM0LkJvb2wpCiAgICBieXRlICJpbXBsaWNpdF9rZXlfYXJjNF9ib29sIgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjU2MgogICAgLy8gcmV0dXJuIHNlbGYuaW1wbGljaXRfa2V5X2FyYzRfYm9vbFthXQogICAgYXBwX2xvY2FsX2dldF9leAogICAgYXNzZXJ0IC8vIGNoZWNrIHNlbGYuaW1wbGljaXRfa2V5X2FyYzRfYm9vbCBleGlzdHMgZm9yIGFjY291bnQKICAgIHJldHN1YgoKCi8vIHRlc3RzLmFydGlmYWN0cy5TdGF0ZU9wcy5jb250cmFjdC5Mb2NhbFN0YXRlQ29udHJhY3QuZ2V0X2ltcGxpY2l0X2tleV9hcmM0X2FkZHJlc3MoYTogYnl0ZXMpIC0+IGJ5dGVzOgpnZXRfaW1wbGljaXRfa2V5X2FyYzRfYWRkcmVzczoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTo1NjQtNTY1CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gZGVmIGdldF9pbXBsaWNpdF9rZXlfYXJjNF9hZGRyZXNzKHNlbGYsIGE6IEFjY291bnQpIC0+IGFyYzQuQWRkcmVzczoKICAgIHByb3RvIDEgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjU2NgogICAgLy8gcmV0dXJuIHNlbGYuaW1wbGljaXRfa2V5X2FyYzRfYWRkcmVzc1thXQogICAgZnJhbWVfZGlnIC0xCiAgICBpbnQgMAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjUxMAogICAgLy8gc2VsZi5pbXBsaWNpdF9rZXlfYXJjNF9hZGRyZXNzID0gTG9jYWxTdGF0ZShhcmM0LkFkZHJlc3MpCiAgICBieXRlICJpbXBsaWNpdF9rZXlfYXJjNF9hZGRyZXNzIgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjU2NgogICAgLy8gcmV0dXJuIHNlbGYuaW1wbGljaXRfa2V5X2FyYzRfYWRkcmVzc1thXQogICAgYXBwX2xvY2FsX2dldF9leAogICAgYXNzZXJ0IC8vIGNoZWNrIHNlbGYuaW1wbGljaXRfa2V5X2FyYzRfYWRkcmVzcyBleGlzdHMgZm9yIGFjY291bnQKICAgIHJldHN1YgoKCi8vIHRlc3RzLmFydGlmYWN0cy5TdGF0ZU9wcy5jb250cmFjdC5Mb2NhbFN0YXRlQ29udHJhY3QuZ2V0X2ltcGxpY2l0X2tleV9hcmM0X3VpbnQxMjgoYTogYnl0ZXMpIC0+IGJ5dGVzOgpnZXRfaW1wbGljaXRfa2V5X2FyYzRfdWludDEyODoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTo1NjgtNTY5CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gZGVmIGdldF9pbXBsaWNpdF9rZXlfYXJjNF91aW50MTI4KHNlbGYsIGE6IEFjY291bnQpIC0+IGFyYzQuVUludDEyODoKICAgIHByb3RvIDEgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjU3MAogICAgLy8gcmV0dXJuIHNlbGYuaW1wbGljaXRfa2V5X2FyYzRfdWludDEyOFthXQogICAgZnJhbWVfZGlnIC0xCiAgICBpbnQgMAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjUxMQogICAgLy8gc2VsZi5pbXBsaWNpdF9rZXlfYXJjNF91aW50MTI4ID0gTG9jYWxTdGF0ZShhcmM0LlVJbnQxMjgpCiAgICBieXRlICJpbXBsaWNpdF9rZXlfYXJjNF91aW50MTI4IgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjU3MAogICAgLy8gcmV0dXJuIHNlbGYuaW1wbGljaXRfa2V5X2FyYzRfdWludDEyOFthXQogICAgYXBwX2xvY2FsX2dldF9leAogICAgYXNzZXJ0IC8vIGNoZWNrIHNlbGYuaW1wbGljaXRfa2V5X2FyYzRfdWludDEyOCBleGlzdHMgZm9yIGFjY291bnQKICAgIHJldHN1YgoKCi8vIHRlc3RzLmFydGlmYWN0cy5TdGF0ZU9wcy5jb250cmFjdC5Mb2NhbFN0YXRlQ29udHJhY3QuZ2V0X2ltcGxpY2l0X2tleV9hcmM0X2R5bmFtaWNfYnl0ZXMoYTogYnl0ZXMpIC0+IGJ5dGVzOgpnZXRfaW1wbGljaXRfa2V5X2FyYzRfZHluYW1pY19ieXRlczoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTo1NzItNTczCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gZGVmIGdldF9pbXBsaWNpdF9rZXlfYXJjNF9keW5hbWljX2J5dGVzKHNlbGYsIGE6IEFjY291bnQpIC0+IGFyYzQuRHluYW1pY0J5dGVzOgogICAgcHJvdG8gMSAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6NTc0CiAgICAvLyByZXR1cm4gc2VsZi5pbXBsaWNpdF9rZXlfYXJjNF9keW5hbWljX2J5dGVzW2FdCiAgICBmcmFtZV9kaWcgLTEKICAgIGludCAwCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6NTEyCiAgICAvLyBzZWxmLmltcGxpY2l0X2tleV9hcmM0X2R5bmFtaWNfYnl0ZXMgPSBMb2NhbFN0YXRlKGFyYzQuRHluYW1pY0J5dGVzKQogICAgYnl0ZSAiaW1wbGljaXRfa2V5X2FyYzRfZHluYW1pY19ieXRlcyIKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTo1NzQKICAgIC8vIHJldHVybiBzZWxmLmltcGxpY2l0X2tleV9hcmM0X2R5bmFtaWNfYnl0ZXNbYV0KICAgIGFwcF9sb2NhbF9nZXRfZXgKICAgIGFzc2VydCAvLyBjaGVjayBzZWxmLmltcGxpY2l0X2tleV9hcmM0X2R5bmFtaWNfYnl0ZXMgZXhpc3RzIGZvciBhY2NvdW50CiAgICByZXRzdWIKCgovLyB0ZXN0cy5hcnRpZmFjdHMuU3RhdGVPcHMuY29udHJhY3QuTG9jYWxTdGF0ZUNvbnRyYWN0LmdldF9hcmM0X3VpbnQoYTogYnl0ZXMpIC0+IGJ5dGVzOgpnZXRfYXJjNF91aW50OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjU3Ni01NzgKICAgIC8vICMgR2V0dGVyIG1ldGhvZHMgZm9yIGV4cGxpY2l0IGtleSBzdGF0ZSB2YXJpYWJsZXMKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBkZWYgZ2V0X2FyYzRfdWludChzZWxmLCBhOiBBY2NvdW50KSAtPiBhcmM0LlVJbnQ2NDoKICAgIHByb3RvIDEgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjU3OQogICAgLy8gcmV0dXJuIHNlbGYuYXJjNF91aW50W2FdCiAgICBmcmFtZV9kaWcgLTEKICAgIGludCAwCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6NTE0LTUxNQogICAgLy8gIyBFeHBsaWNpdCBrZXkgc3RhdGUgdmFyaWFibGVzCiAgICAvLyBzZWxmLmFyYzRfdWludCA9IExvY2FsU3RhdGUoYXJjNC5VSW50NjQsIGtleT0iZXhwbGljaXRfa2V5X2FyYzRfdWludCIpCiAgICBieXRlICJleHBsaWNpdF9rZXlfYXJjNF91aW50IgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjU3OQogICAgLy8gcmV0dXJuIHNlbGYuYXJjNF91aW50W2FdCiAgICBhcHBfbG9jYWxfZ2V0X2V4CiAgICBhc3NlcnQgLy8gY2hlY2sgc2VsZi5hcmM0X3VpbnQgZXhpc3RzIGZvciBhY2NvdW50CiAgICByZXRzdWIKCgovLyB0ZXN0cy5hcnRpZmFjdHMuU3RhdGVPcHMuY29udHJhY3QuTG9jYWxTdGF0ZUNvbnRyYWN0LmdldF9hcmM0X3N0cmluZyhhOiBieXRlcykgLT4gYnl0ZXM6CmdldF9hcmM0X3N0cmluZzoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTo1ODEtNTgyCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gZGVmIGdldF9hcmM0X3N0cmluZyhzZWxmLCBhOiBBY2NvdW50KSAtPiBhcmM0LlN0cmluZzoKICAgIHByb3RvIDEgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjU4MwogICAgLy8gcmV0dXJuIHNlbGYuYXJjNF9zdHJpbmdbYV0KICAgIGZyYW1lX2RpZyAtMQogICAgaW50IDAKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTo1MTYKICAgIC8vIHNlbGYuYXJjNF9zdHJpbmcgPSBMb2NhbFN0YXRlKGFyYzQuU3RyaW5nLCBrZXk9ImV4cGxpY2l0X2tleV9hcmM0X3N0cmluZyIpCiAgICBieXRlICJleHBsaWNpdF9rZXlfYXJjNF9zdHJpbmciCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6NTgzCiAgICAvLyByZXR1cm4gc2VsZi5hcmM0X3N0cmluZ1thXQogICAgYXBwX2xvY2FsX2dldF9leAogICAgYXNzZXJ0IC8vIGNoZWNrIHNlbGYuYXJjNF9zdHJpbmcgZXhpc3RzIGZvciBhY2NvdW50CiAgICByZXRzdWIKCgovLyB0ZXN0cy5hcnRpZmFjdHMuU3RhdGVPcHMuY29udHJhY3QuTG9jYWxTdGF0ZUNvbnRyYWN0LmdldF9hcmM0X2J5dGUoYTogYnl0ZXMpIC0+IGJ5dGVzOgpnZXRfYXJjNF9ieXRlOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjU4NS01ODYKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBkZWYgZ2V0X2FyYzRfYnl0ZShzZWxmLCBhOiBBY2NvdW50KSAtPiBhcmM0LkJ5dGU6CiAgICBwcm90byAxIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTo1ODcKICAgIC8vIHJldHVybiBzZWxmLmFyYzRfYnl0ZVthXQogICAgZnJhbWVfZGlnIC0xCiAgICBpbnQgMAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjUxNwogICAgLy8gc2VsZi5hcmM0X2J5dGUgPSBMb2NhbFN0YXRlKGFyYzQuQnl0ZSwga2V5PSJleHBsaWNpdF9rZXlfYXJjNF9ieXRlIikKICAgIGJ5dGUgImV4cGxpY2l0X2tleV9hcmM0X2J5dGUiCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6NTg3CiAgICAvLyByZXR1cm4gc2VsZi5hcmM0X2J5dGVbYV0KICAgIGFwcF9sb2NhbF9nZXRfZXgKICAgIGFzc2VydCAvLyBjaGVjayBzZWxmLmFyYzRfYnl0ZSBleGlzdHMgZm9yIGFjY291bnQKICAgIHJldHN1YgoKCi8vIHRlc3RzLmFydGlmYWN0cy5TdGF0ZU9wcy5jb250cmFjdC5Mb2NhbFN0YXRlQ29udHJhY3QuZ2V0X2FyYzRfYm9vbChhOiBieXRlcykgLT4gYnl0ZXM6CmdldF9hcmM0X2Jvb2w6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6NTg5LTU5MAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIGRlZiBnZXRfYXJjNF9ib29sKHNlbGYsIGE6IEFjY291bnQpIC0+IGFyYzQuQm9vbDoKICAgIHByb3RvIDEgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjU5MQogICAgLy8gcmV0dXJuIHNlbGYuYXJjNF9ib29sW2FdCiAgICBmcmFtZV9kaWcgLTEKICAgIGludCAwCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6NTE4CiAgICAvLyBzZWxmLmFyYzRfYm9vbCA9IExvY2FsU3RhdGUoYXJjNC5Cb29sLCBrZXk9ImV4cGxpY2l0X2tleV9hcmM0X2Jvb2wiKQogICAgYnl0ZSAiZXhwbGljaXRfa2V5X2FyYzRfYm9vbCIKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTo1OTEKICAgIC8vIHJldHVybiBzZWxmLmFyYzRfYm9vbFthXQogICAgYXBwX2xvY2FsX2dldF9leAogICAgYXNzZXJ0IC8vIGNoZWNrIHNlbGYuYXJjNF9ib29sIGV4aXN0cyBmb3IgYWNjb3VudAogICAgcmV0c3ViCgoKLy8gdGVzdHMuYXJ0aWZhY3RzLlN0YXRlT3BzLmNvbnRyYWN0LkxvY2FsU3RhdGVDb250cmFjdC5nZXRfYXJjNF9hZGRyZXNzKGE6IGJ5dGVzKSAtPiBieXRlczoKZ2V0X2FyYzRfYWRkcmVzczoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTo1OTMtNTk0CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gZGVmIGdldF9hcmM0X2FkZHJlc3Moc2VsZiwgYTogQWNjb3VudCkgLT4gYXJjNC5BZGRyZXNzOgogICAgcHJvdG8gMSAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6NTk1CiAgICAvLyByZXR1cm4gc2VsZi5hcmM0X2FkZHJlc3NbYV0KICAgIGZyYW1lX2RpZyAtMQogICAgaW50IDAKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTo1MTkKICAgIC8vIHNlbGYuYXJjNF9hZGRyZXNzID0gTG9jYWxTdGF0ZShhcmM0LkFkZHJlc3MsIGtleT0iZXhwbGljaXRfa2V5X2FyYzRfYWRkcmVzcyIpCiAgICBieXRlICJleHBsaWNpdF9rZXlfYXJjNF9hZGRyZXNzIgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjU5NQogICAgLy8gcmV0dXJuIHNlbGYuYXJjNF9hZGRyZXNzW2FdCiAgICBhcHBfbG9jYWxfZ2V0X2V4CiAgICBhc3NlcnQgLy8gY2hlY2sgc2VsZi5hcmM0X2FkZHJlc3MgZXhpc3RzIGZvciBhY2NvdW50CiAgICByZXRzdWIKCgovLyB0ZXN0cy5hcnRpZmFjdHMuU3RhdGVPcHMuY29udHJhY3QuTG9jYWxTdGF0ZUNvbnRyYWN0LmdldF9hcmM0X3VpbnQxMjgoYTogYnl0ZXMpIC0+IGJ5dGVzOgpnZXRfYXJjNF91aW50MTI4OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjU5Ny01OTgKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBkZWYgZ2V0X2FyYzRfdWludDEyOChzZWxmLCBhOiBBY2NvdW50KSAtPiBhcmM0LlVJbnQxMjg6CiAgICBwcm90byAxIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTo1OTkKICAgIC8vIHJldHVybiBzZWxmLmFyYzRfdWludDEyOFthXQogICAgZnJhbWVfZGlnIC0xCiAgICBpbnQgMAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjUyMAogICAgLy8gc2VsZi5hcmM0X3VpbnQxMjggPSBMb2NhbFN0YXRlKGFyYzQuVUludDEyOCwga2V5PSJleHBsaWNpdF9rZXlfYXJjNF91aW50MTI4IikKICAgIGJ5dGUgImV4cGxpY2l0X2tleV9hcmM0X3VpbnQxMjgiCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6NTk5CiAgICAvLyByZXR1cm4gc2VsZi5hcmM0X3VpbnQxMjhbYV0KICAgIGFwcF9sb2NhbF9nZXRfZXgKICAgIGFzc2VydCAvLyBjaGVjayBzZWxmLmFyYzRfdWludDEyOCBleGlzdHMgZm9yIGFjY291bnQKICAgIHJldHN1YgoKCi8vIHRlc3RzLmFydGlmYWN0cy5TdGF0ZU9wcy5jb250cmFjdC5Mb2NhbFN0YXRlQ29udHJhY3QuZ2V0X2FyYzRfZHluYW1pY19ieXRlcyhhOiBieXRlcykgLT4gYnl0ZXM6CmdldF9hcmM0X2R5bmFtaWNfYnl0ZXM6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6NjAxLTYwMgogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIGRlZiBnZXRfYXJjNF9keW5hbWljX2J5dGVzKHNlbGYsIGE6IEFjY291bnQpIC0+IGFyYzQuRHluYW1pY0J5dGVzOgogICAgcHJvdG8gMSAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6NjAzCiAgICAvLyByZXR1cm4gc2VsZi5hcmM0X2R5bmFtaWNfYnl0ZXNbYV0KICAgIGZyYW1lX2RpZyAtMQogICAgaW50IDAKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTo1MjIKICAgIC8vIGFyYzQuRHluYW1pY0J5dGVzLCBrZXk9ImV4cGxpY2l0X2tleV9hcmM0X2R5bmFtaWNfYnl0ZXMiCiAgICBieXRlICJleHBsaWNpdF9rZXlfYXJjNF9keW5hbWljX2J5dGVzIgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjYwMwogICAgLy8gcmV0dXJuIHNlbGYuYXJjNF9keW5hbWljX2J5dGVzW2FdCiAgICBhcHBfbG9jYWxfZ2V0X2V4CiAgICBhc3NlcnQgLy8gY2hlY2sgc2VsZi5hcmM0X2R5bmFtaWNfYnl0ZXMgZXhpc3RzIGZvciBhY2NvdW50CiAgICByZXRzdWIK", - "clear": "I3ByYWdtYSB2ZXJzaW9uIDEwCgp0ZXN0cy5hcnRpZmFjdHMuU3RhdGVPcHMuY29udHJhY3QuTG9jYWxTdGF0ZUNvbnRyYWN0LmNsZWFyX3N0YXRlX3Byb2dyYW06CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6NTAzCiAgICAvLyBjbGFzcyBMb2NhbFN0YXRlQ29udHJhY3QoQVJDNENvbnRyYWN0KToKICAgIGludCAxCiAgICByZXR1cm4K" + "approval": "I3ByYWdtYSB2ZXJzaW9uIDEwCgp0ZXN0cy5hcnRpZmFjdHMuU3RhdGVPcHMuY29udHJhY3QuTG9jYWxTdGF0ZUNvbnRyYWN0LmFwcHJvdmFsX3Byb2dyYW06CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6NjIxCiAgICAvLyBjbGFzcyBMb2NhbFN0YXRlQ29udHJhY3QoQVJDNENvbnRyYWN0KToKICAgIHR4biBOdW1BcHBBcmdzCiAgICBieiBtYWluX2JhcmVfcm91dGluZ0AxOQogICAgbWV0aG9kICJvcHRfaW4oKXZvaWQiCiAgICBtZXRob2QgImdldF9pbXBsaWNpdF9rZXlfYXJjNF91aW50KGFjY291bnQpdWludDY0IgogICAgbWV0aG9kICJnZXRfaW1wbGljaXRfa2V5X2FyYzRfc3RyaW5nKGFjY291bnQpc3RyaW5nIgogICAgbWV0aG9kICJnZXRfaW1wbGljaXRfa2V5X2FyYzRfYnl0ZShhY2NvdW50KWJ5dGUiCiAgICBtZXRob2QgImdldF9pbXBsaWNpdF9rZXlfYXJjNF9ib29sKGFjY291bnQpYm9vbCIKICAgIG1ldGhvZCAiZ2V0X2ltcGxpY2l0X2tleV9hcmM0X2FkZHJlc3MoYWNjb3VudClhZGRyZXNzIgogICAgbWV0aG9kICJnZXRfaW1wbGljaXRfa2V5X2FyYzRfdWludDEyOChhY2NvdW50KXVpbnQxMjgiCiAgICBtZXRob2QgImdldF9pbXBsaWNpdF9rZXlfYXJjNF9keW5hbWljX2J5dGVzKGFjY291bnQpYnl0ZVtdIgogICAgbWV0aG9kICJnZXRfYXJjNF91aW50KGFjY291bnQpdWludDY0IgogICAgbWV0aG9kICJnZXRfYXJjNF9zdHJpbmcoYWNjb3VudClzdHJpbmciCiAgICBtZXRob2QgImdldF9hcmM0X2J5dGUoYWNjb3VudClieXRlIgogICAgbWV0aG9kICJnZXRfYXJjNF9ib29sKGFjY291bnQpYm9vbCIKICAgIG1ldGhvZCAiZ2V0X2FyYzRfYWRkcmVzcyhhY2NvdW50KWFkZHJlc3MiCiAgICBtZXRob2QgImdldF9hcmM0X3VpbnQxMjgoYWNjb3VudCl1aW50MTI4IgogICAgbWV0aG9kICJnZXRfYXJjNF9keW5hbWljX2J5dGVzKGFjY291bnQpYnl0ZVtdIgogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMAogICAgbWF0Y2ggbWFpbl9vcHRfaW5fcm91dGVAMiBtYWluX2dldF9pbXBsaWNpdF9rZXlfYXJjNF91aW50X3JvdXRlQDMgbWFpbl9nZXRfaW1wbGljaXRfa2V5X2FyYzRfc3RyaW5nX3JvdXRlQDQgbWFpbl9nZXRfaW1wbGljaXRfa2V5X2FyYzRfYnl0ZV9yb3V0ZUA1IG1haW5fZ2V0X2ltcGxpY2l0X2tleV9hcmM0X2Jvb2xfcm91dGVANiBtYWluX2dldF9pbXBsaWNpdF9rZXlfYXJjNF9hZGRyZXNzX3JvdXRlQDcgbWFpbl9nZXRfaW1wbGljaXRfa2V5X2FyYzRfdWludDEyOF9yb3V0ZUA4IG1haW5fZ2V0X2ltcGxpY2l0X2tleV9hcmM0X2R5bmFtaWNfYnl0ZXNfcm91dGVAOSBtYWluX2dldF9hcmM0X3VpbnRfcm91dGVAMTAgbWFpbl9nZXRfYXJjNF9zdHJpbmdfcm91dGVAMTEgbWFpbl9nZXRfYXJjNF9ieXRlX3JvdXRlQDEyIG1haW5fZ2V0X2FyYzRfYm9vbF9yb3V0ZUAxMyBtYWluX2dldF9hcmM0X2FkZHJlc3Nfcm91dGVAMTQgbWFpbl9nZXRfYXJjNF91aW50MTI4X3JvdXRlQDE1IG1haW5fZ2V0X2FyYzRfZHluYW1pY19ieXRlc19yb3V0ZUAxNgogICAgZXJyIC8vIHJlamVjdCB0cmFuc2FjdGlvbgoKbWFpbl9vcHRfaW5fcm91dGVAMjoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTo2NDMKICAgIC8vIEBhcmM0LmFiaW1ldGhvZChhbGxvd19hY3Rpb25zPVsiT3B0SW4iXSkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgIGludCBPcHRJbgogICAgPT0KICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgT3B0SW4KICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gaXMgbm90IGNyZWF0aW5nCiAgICBjYWxsc3ViIG9wdF9pbgogICAgaW50IDEKICAgIHJldHVybgoKbWFpbl9nZXRfaW1wbGljaXRfa2V5X2FyYzRfdWludF9yb3V0ZUAzOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjY2NS02NjYKICAgIC8vICMgR2V0dGVyIG1ldGhvZHMgZm9yIGltcGxpY2l0IGtleSBzdGF0ZSB2YXJpYWJsZXMKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gaXMgbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6NjIxCiAgICAvLyBjbGFzcyBMb2NhbFN0YXRlQ29udHJhY3QoQVJDNENvbnRyYWN0KToKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGJ0b2kKICAgIHR4bmFzIEFjY291bnRzCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6NjY1LTY2NgogICAgLy8gIyBHZXR0ZXIgbWV0aG9kcyBmb3IgaW1wbGljaXQga2V5IHN0YXRlIHZhcmlhYmxlcwogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgZ2V0X2ltcGxpY2l0X2tleV9hcmM0X3VpbnQKICAgIGJ5dGUgMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludCAxCiAgICByZXR1cm4KCm1haW5fZ2V0X2ltcGxpY2l0X2tleV9hcmM0X3N0cmluZ19yb3V0ZUA0OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjY3MAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBpcyBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTo2MjEKICAgIC8vIGNsYXNzIExvY2FsU3RhdGVDb250cmFjdChBUkM0Q29udHJhY3QpOgogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgYnRvaQogICAgdHhuYXMgQWNjb3VudHMKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTo2NzAKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIGdldF9pbXBsaWNpdF9rZXlfYXJjNF9zdHJpbmcKICAgIGJ5dGUgMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludCAxCiAgICByZXR1cm4KCm1haW5fZ2V0X2ltcGxpY2l0X2tleV9hcmM0X2J5dGVfcm91dGVANToKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTo2NzQKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gaXMgbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6NjIxCiAgICAvLyBjbGFzcyBMb2NhbFN0YXRlQ29udHJhY3QoQVJDNENvbnRyYWN0KToKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGJ0b2kKICAgIHR4bmFzIEFjY291bnRzCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6Njc0CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiBnZXRfaW1wbGljaXRfa2V5X2FyYzRfYnl0ZQogICAgYnl0ZSAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50IDEKICAgIHJldHVybgoKbWFpbl9nZXRfaW1wbGljaXRfa2V5X2FyYzRfYm9vbF9yb3V0ZUA2OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjY3OAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBpcyBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTo2MjEKICAgIC8vIGNsYXNzIExvY2FsU3RhdGVDb250cmFjdChBUkM0Q29udHJhY3QpOgogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgYnRvaQogICAgdHhuYXMgQWNjb3VudHMKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTo2NzgKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIGdldF9pbXBsaWNpdF9rZXlfYXJjNF9ib29sCiAgICBieXRlIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnQgMQogICAgcmV0dXJuCgptYWluX2dldF9pbXBsaWNpdF9rZXlfYXJjNF9hZGRyZXNzX3JvdXRlQDc6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6NjgyCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGlzIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjYyMQogICAgLy8gY2xhc3MgTG9jYWxTdGF0ZUNvbnRyYWN0KEFSQzRDb250cmFjdCk6CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBidG9pCiAgICB0eG5hcyBBY2NvdW50cwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjY4MgogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgZ2V0X2ltcGxpY2l0X2tleV9hcmM0X2FkZHJlc3MKICAgIGJ5dGUgMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludCAxCiAgICByZXR1cm4KCm1haW5fZ2V0X2ltcGxpY2l0X2tleV9hcmM0X3VpbnQxMjhfcm91dGVAODoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTo2ODYKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gaXMgbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6NjIxCiAgICAvLyBjbGFzcyBMb2NhbFN0YXRlQ29udHJhY3QoQVJDNENvbnRyYWN0KToKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGJ0b2kKICAgIHR4bmFzIEFjY291bnRzCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6Njg2CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiBnZXRfaW1wbGljaXRfa2V5X2FyYzRfdWludDEyOAogICAgYnl0ZSAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50IDEKICAgIHJldHVybgoKbWFpbl9nZXRfaW1wbGljaXRfa2V5X2FyYzRfZHluYW1pY19ieXRlc19yb3V0ZUA5OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjY5MAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBpcyBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTo2MjEKICAgIC8vIGNsYXNzIExvY2FsU3RhdGVDb250cmFjdChBUkM0Q29udHJhY3QpOgogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgYnRvaQogICAgdHhuYXMgQWNjb3VudHMKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTo2OTAKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIGdldF9pbXBsaWNpdF9rZXlfYXJjNF9keW5hbWljX2J5dGVzCiAgICBieXRlIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnQgMQogICAgcmV0dXJuCgptYWluX2dldF9hcmM0X3VpbnRfcm91dGVAMTA6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6Njk0LTY5NQogICAgLy8gIyBHZXR0ZXIgbWV0aG9kcyBmb3IgZXhwbGljaXQga2V5IHN0YXRlIHZhcmlhYmxlcwogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBpcyBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTo2MjEKICAgIC8vIGNsYXNzIExvY2FsU3RhdGVDb250cmFjdChBUkM0Q29udHJhY3QpOgogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgYnRvaQogICAgdHhuYXMgQWNjb3VudHMKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTo2OTQtNjk1CiAgICAvLyAjIEdldHRlciBtZXRob2RzIGZvciBleHBsaWNpdCBrZXkgc3RhdGUgdmFyaWFibGVzCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiBnZXRfYXJjNF91aW50CiAgICBieXRlIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnQgMQogICAgcmV0dXJuCgptYWluX2dldF9hcmM0X3N0cmluZ19yb3V0ZUAxMToKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTo2OTkKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gaXMgbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6NjIxCiAgICAvLyBjbGFzcyBMb2NhbFN0YXRlQ29udHJhY3QoQVJDNENvbnRyYWN0KToKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGJ0b2kKICAgIHR4bmFzIEFjY291bnRzCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6Njk5CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiBnZXRfYXJjNF9zdHJpbmcKICAgIGJ5dGUgMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludCAxCiAgICByZXR1cm4KCm1haW5fZ2V0X2FyYzRfYnl0ZV9yb3V0ZUAxMjoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTo3MDMKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gaXMgbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6NjIxCiAgICAvLyBjbGFzcyBMb2NhbFN0YXRlQ29udHJhY3QoQVJDNENvbnRyYWN0KToKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGJ0b2kKICAgIHR4bmFzIEFjY291bnRzCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6NzAzCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiBnZXRfYXJjNF9ieXRlCiAgICBieXRlIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnQgMQogICAgcmV0dXJuCgptYWluX2dldF9hcmM0X2Jvb2xfcm91dGVAMTM6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6NzA3CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGlzIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjYyMQogICAgLy8gY2xhc3MgTG9jYWxTdGF0ZUNvbnRyYWN0KEFSQzRDb250cmFjdCk6CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBidG9pCiAgICB0eG5hcyBBY2NvdW50cwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjcwNwogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgZ2V0X2FyYzRfYm9vbAogICAgYnl0ZSAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50IDEKICAgIHJldHVybgoKbWFpbl9nZXRfYXJjNF9hZGRyZXNzX3JvdXRlQDE0OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjcxMQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBpcyBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTo2MjEKICAgIC8vIGNsYXNzIExvY2FsU3RhdGVDb250cmFjdChBUkM0Q29udHJhY3QpOgogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgYnRvaQogICAgdHhuYXMgQWNjb3VudHMKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTo3MTEKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIGdldF9hcmM0X2FkZHJlc3MKICAgIGJ5dGUgMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludCAxCiAgICByZXR1cm4KCm1haW5fZ2V0X2FyYzRfdWludDEyOF9yb3V0ZUAxNToKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTo3MTUKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gaXMgbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6NjIxCiAgICAvLyBjbGFzcyBMb2NhbFN0YXRlQ29udHJhY3QoQVJDNENvbnRyYWN0KToKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGJ0b2kKICAgIHR4bmFzIEFjY291bnRzCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6NzE1CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiBnZXRfYXJjNF91aW50MTI4CiAgICBieXRlIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnQgMQogICAgcmV0dXJuCgptYWluX2dldF9hcmM0X2R5bmFtaWNfYnl0ZXNfcm91dGVAMTY6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6NzE5CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGlzIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjYyMQogICAgLy8gY2xhc3MgTG9jYWxTdGF0ZUNvbnRyYWN0KEFSQzRDb250cmFjdCk6CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBidG9pCiAgICB0eG5hcyBBY2NvdW50cwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjcxOQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgZ2V0X2FyYzRfZHluYW1pY19ieXRlcwogICAgYnl0ZSAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50IDEKICAgIHJldHVybgoKbWFpbl9iYXJlX3JvdXRpbmdAMTk6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6NjIxCiAgICAvLyBjbGFzcyBMb2NhbFN0YXRlQ29udHJhY3QoQVJDNENvbnRyYWN0KToKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyByZWplY3QgdHJhbnNhY3Rpb24KICAgIHR4biBBcHBsaWNhdGlvbklECiAgICAhCiAgICBhc3NlcnQgLy8gaXMgY3JlYXRpbmcKICAgIGludCAxCiAgICByZXR1cm4KCgovLyB0ZXN0cy5hcnRpZmFjdHMuU3RhdGVPcHMuY29udHJhY3QuTG9jYWxTdGF0ZUNvbnRyYWN0Lm9wdF9pbigpIC0+IHZvaWQ6Cm9wdF9pbjoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTo2NDMtNjQ0CiAgICAvLyBAYXJjNC5hYmltZXRob2QoYWxsb3dfYWN0aW9ucz1bIk9wdEluIl0pCiAgICAvLyBkZWYgb3B0X2luKHNlbGYpIC0+IE5vbmU6CiAgICBwcm90byAwIDAKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTo2NDUKICAgIC8vIHNlbGYuaW1wbGljaXRfa2V5X2FyYzRfdWludFtHbG9iYWwuY3JlYXRvcl9hZGRyZXNzXSA9IGFyYzQuVUludDY0KDEzMzcpCiAgICBnbG9iYWwgQ3JlYXRvckFkZHJlc3MKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTo2MjMtNjI0CiAgICAvLyAjIEltcGxpY2l0IGtleSBzdGF0ZSB2YXJpYWJsZXMKICAgIC8vIHNlbGYuaW1wbGljaXRfa2V5X2FyYzRfdWludCA9IExvY2FsU3RhdGUoYXJjNC5VSW50NjQpCiAgICBieXRlICJpbXBsaWNpdF9rZXlfYXJjNF91aW50IgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjY0NQogICAgLy8gc2VsZi5pbXBsaWNpdF9rZXlfYXJjNF91aW50W0dsb2JhbC5jcmVhdG9yX2FkZHJlc3NdID0gYXJjNC5VSW50NjQoMTMzNykKICAgIGJ5dGUgMHgwMDAwMDAwMDAwMDAwNTM5CiAgICBhcHBfbG9jYWxfcHV0CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6NjQ2CiAgICAvLyBzZWxmLmltcGxpY2l0X2tleV9hcmM0X3N0cmluZ1tHbG9iYWwuY3JlYXRvcl9hZGRyZXNzXSA9IGFyYzQuU3RyaW5nKCJIZWxsbyIpCiAgICBnbG9iYWwgQ3JlYXRvckFkZHJlc3MKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTo2MjUKICAgIC8vIHNlbGYuaW1wbGljaXRfa2V5X2FyYzRfc3RyaW5nID0gTG9jYWxTdGF0ZShhcmM0LlN0cmluZykKICAgIGJ5dGUgImltcGxpY2l0X2tleV9hcmM0X3N0cmluZyIKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTo2NDYKICAgIC8vIHNlbGYuaW1wbGljaXRfa2V5X2FyYzRfc3RyaW5nW0dsb2JhbC5jcmVhdG9yX2FkZHJlc3NdID0gYXJjNC5TdHJpbmcoIkhlbGxvIikKICAgIGJ5dGUgMHgwMDA1NDg2NTZjNmM2ZgogICAgYXBwX2xvY2FsX3B1dAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjY0NwogICAgLy8gc2VsZi5pbXBsaWNpdF9rZXlfYXJjNF9ieXRlW0dsb2JhbC5jcmVhdG9yX2FkZHJlc3NdID0gYXJjNC5CeXRlKDApCiAgICBnbG9iYWwgQ3JlYXRvckFkZHJlc3MKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTo2MjYKICAgIC8vIHNlbGYuaW1wbGljaXRfa2V5X2FyYzRfYnl0ZSA9IExvY2FsU3RhdGUoYXJjNC5CeXRlKQogICAgYnl0ZSAiaW1wbGljaXRfa2V5X2FyYzRfYnl0ZSIKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTo2NDcKICAgIC8vIHNlbGYuaW1wbGljaXRfa2V5X2FyYzRfYnl0ZVtHbG9iYWwuY3JlYXRvcl9hZGRyZXNzXSA9IGFyYzQuQnl0ZSgwKQogICAgYnl0ZSAweDAwCiAgICBhcHBfbG9jYWxfcHV0CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6NjQ4CiAgICAvLyBzZWxmLmltcGxpY2l0X2tleV9hcmM0X2Jvb2xbR2xvYmFsLmNyZWF0b3JfYWRkcmVzc10gPSBhcmM0LkJvb2woVHJ1ZSkKICAgIGdsb2JhbCBDcmVhdG9yQWRkcmVzcwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjYyNwogICAgLy8gc2VsZi5pbXBsaWNpdF9rZXlfYXJjNF9ib29sID0gTG9jYWxTdGF0ZShhcmM0LkJvb2wpCiAgICBieXRlICJpbXBsaWNpdF9rZXlfYXJjNF9ib29sIgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjY0OAogICAgLy8gc2VsZi5pbXBsaWNpdF9rZXlfYXJjNF9ib29sW0dsb2JhbC5jcmVhdG9yX2FkZHJlc3NdID0gYXJjNC5Cb29sKFRydWUpCiAgICBieXRlIDB4ODAKICAgIGFwcF9sb2NhbF9wdXQKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTo2NDkKICAgIC8vIHNlbGYuaW1wbGljaXRfa2V5X2FyYzRfYWRkcmVzc1tHbG9iYWwuY3JlYXRvcl9hZGRyZXNzXSA9IGFyYzQuQWRkcmVzcygKICAgIGdsb2JhbCBDcmVhdG9yQWRkcmVzcwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjYyOAogICAgLy8gc2VsZi5pbXBsaWNpdF9rZXlfYXJjNF9hZGRyZXNzID0gTG9jYWxTdGF0ZShhcmM0LkFkZHJlc3MpCiAgICBieXRlICJpbXBsaWNpdF9rZXlfYXJjNF9hZGRyZXNzIgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjY1MAogICAgLy8gR2xvYmFsLmNyZWF0b3JfYWRkcmVzcwogICAgZ2xvYmFsIENyZWF0b3JBZGRyZXNzCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6NjQ5LTY1MQogICAgLy8gc2VsZi5pbXBsaWNpdF9rZXlfYXJjNF9hZGRyZXNzW0dsb2JhbC5jcmVhdG9yX2FkZHJlc3NdID0gYXJjNC5BZGRyZXNzKAogICAgLy8gICAgIEdsb2JhbC5jcmVhdG9yX2FkZHJlc3MKICAgIC8vICkKICAgIGFwcF9sb2NhbF9wdXQKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTo2NTIKICAgIC8vIHNlbGYuaW1wbGljaXRfa2V5X2FyYzRfdWludDEyOFtHbG9iYWwuY3JlYXRvcl9hZGRyZXNzXSA9IGFyYzQuVUludDEyOCgyKioxMDApCiAgICBnbG9iYWwgQ3JlYXRvckFkZHJlc3MKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTo2MjkKICAgIC8vIHNlbGYuaW1wbGljaXRfa2V5X2FyYzRfdWludDEyOCA9IExvY2FsU3RhdGUoYXJjNC5VSW50MTI4KQogICAgYnl0ZSAiaW1wbGljaXRfa2V5X2FyYzRfdWludDEyOCIKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTo2NTIKICAgIC8vIHNlbGYuaW1wbGljaXRfa2V5X2FyYzRfdWludDEyOFtHbG9iYWwuY3JlYXRvcl9hZGRyZXNzXSA9IGFyYzQuVUludDEyOCgyKioxMDApCiAgICBieXRlIDB4MDAwMDAwMTAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAKICAgIGFwcF9sb2NhbF9wdXQKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTo2NTMKICAgIC8vIHNlbGYuaW1wbGljaXRfa2V5X2FyYzRfZHluYW1pY19ieXRlc1tHbG9iYWwuY3JlYXRvcl9hZGRyZXNzXSA9IGFyYzQuRHluYW1pY0J5dGVzKAogICAgZ2xvYmFsIENyZWF0b3JBZGRyZXNzCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6NjMwCiAgICAvLyBzZWxmLmltcGxpY2l0X2tleV9hcmM0X2R5bmFtaWNfYnl0ZXMgPSBMb2NhbFN0YXRlKGFyYzQuRHluYW1pY0J5dGVzKQogICAgYnl0ZSAiaW1wbGljaXRfa2V5X2FyYzRfZHluYW1pY19ieXRlcyIKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTo2NTMtNjU1CiAgICAvLyBzZWxmLmltcGxpY2l0X2tleV9hcmM0X2R5bmFtaWNfYnl0ZXNbR2xvYmFsLmNyZWF0b3JfYWRkcmVzc10gPSBhcmM0LkR5bmFtaWNCeXRlcygKICAgIC8vICAgICBiImR5bmFtaWMgYnl0ZXMiCiAgICAvLyApCiAgICBieXRlIDB4MDAwZDY0Nzk2ZTYxNmQ2OTYzMjA2Mjc5NzQ2NTczCiAgICBhcHBfbG9jYWxfcHV0CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6NjU3CiAgICAvLyBzZWxmLmFyYzRfdWludFtHbG9iYWwuY3JlYXRvcl9hZGRyZXNzXSA9IGFyYzQuVUludDY0KDEzMzcpCiAgICBnbG9iYWwgQ3JlYXRvckFkZHJlc3MKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTo2MzItNjMzCiAgICAvLyAjIEV4cGxpY2l0IGtleSBzdGF0ZSB2YXJpYWJsZXMKICAgIC8vIHNlbGYuYXJjNF91aW50ID0gTG9jYWxTdGF0ZShhcmM0LlVJbnQ2NCwga2V5PSJleHBsaWNpdF9rZXlfYXJjNF91aW50IikKICAgIGJ5dGUgImV4cGxpY2l0X2tleV9hcmM0X3VpbnQiCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6NjU3CiAgICAvLyBzZWxmLmFyYzRfdWludFtHbG9iYWwuY3JlYXRvcl9hZGRyZXNzXSA9IGFyYzQuVUludDY0KDEzMzcpCiAgICBieXRlIDB4MDAwMDAwMDAwMDAwMDUzOQogICAgYXBwX2xvY2FsX3B1dAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjY1OAogICAgLy8gc2VsZi5hcmM0X3N0cmluZ1tHbG9iYWwuY3JlYXRvcl9hZGRyZXNzXSA9IGFyYzQuU3RyaW5nKCJIZWxsbyIpCiAgICBnbG9iYWwgQ3JlYXRvckFkZHJlc3MKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTo2MzQKICAgIC8vIHNlbGYuYXJjNF9zdHJpbmcgPSBMb2NhbFN0YXRlKGFyYzQuU3RyaW5nLCBrZXk9ImV4cGxpY2l0X2tleV9hcmM0X3N0cmluZyIpCiAgICBieXRlICJleHBsaWNpdF9rZXlfYXJjNF9zdHJpbmciCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6NjU4CiAgICAvLyBzZWxmLmFyYzRfc3RyaW5nW0dsb2JhbC5jcmVhdG9yX2FkZHJlc3NdID0gYXJjNC5TdHJpbmcoIkhlbGxvIikKICAgIGJ5dGUgMHgwMDA1NDg2NTZjNmM2ZgogICAgYXBwX2xvY2FsX3B1dAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjY1OQogICAgLy8gc2VsZi5hcmM0X2J5dGVbR2xvYmFsLmNyZWF0b3JfYWRkcmVzc10gPSBhcmM0LkJ5dGUoMCkKICAgIGdsb2JhbCBDcmVhdG9yQWRkcmVzcwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjYzNQogICAgLy8gc2VsZi5hcmM0X2J5dGUgPSBMb2NhbFN0YXRlKGFyYzQuQnl0ZSwga2V5PSJleHBsaWNpdF9rZXlfYXJjNF9ieXRlIikKICAgIGJ5dGUgImV4cGxpY2l0X2tleV9hcmM0X2J5dGUiCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6NjU5CiAgICAvLyBzZWxmLmFyYzRfYnl0ZVtHbG9iYWwuY3JlYXRvcl9hZGRyZXNzXSA9IGFyYzQuQnl0ZSgwKQogICAgYnl0ZSAweDAwCiAgICBhcHBfbG9jYWxfcHV0CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6NjYwCiAgICAvLyBzZWxmLmFyYzRfYm9vbFtHbG9iYWwuY3JlYXRvcl9hZGRyZXNzXSA9IGFyYzQuQm9vbChUcnVlKQogICAgZ2xvYmFsIENyZWF0b3JBZGRyZXNzCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6NjM2CiAgICAvLyBzZWxmLmFyYzRfYm9vbCA9IExvY2FsU3RhdGUoYXJjNC5Cb29sLCBrZXk9ImV4cGxpY2l0X2tleV9hcmM0X2Jvb2wiKQogICAgYnl0ZSAiZXhwbGljaXRfa2V5X2FyYzRfYm9vbCIKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTo2NjAKICAgIC8vIHNlbGYuYXJjNF9ib29sW0dsb2JhbC5jcmVhdG9yX2FkZHJlc3NdID0gYXJjNC5Cb29sKFRydWUpCiAgICBieXRlIDB4ODAKICAgIGFwcF9sb2NhbF9wdXQKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTo2NjEKICAgIC8vIHNlbGYuYXJjNF9hZGRyZXNzW0dsb2JhbC5jcmVhdG9yX2FkZHJlc3NdID0gYXJjNC5BZGRyZXNzKEdsb2JhbC5jcmVhdG9yX2FkZHJlc3MpCiAgICBnbG9iYWwgQ3JlYXRvckFkZHJlc3MKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTo2MzcKICAgIC8vIHNlbGYuYXJjNF9hZGRyZXNzID0gTG9jYWxTdGF0ZShhcmM0LkFkZHJlc3MsIGtleT0iZXhwbGljaXRfa2V5X2FyYzRfYWRkcmVzcyIpCiAgICBieXRlICJleHBsaWNpdF9rZXlfYXJjNF9hZGRyZXNzIgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjY2MQogICAgLy8gc2VsZi5hcmM0X2FkZHJlc3NbR2xvYmFsLmNyZWF0b3JfYWRkcmVzc10gPSBhcmM0LkFkZHJlc3MoR2xvYmFsLmNyZWF0b3JfYWRkcmVzcykKICAgIGdsb2JhbCBDcmVhdG9yQWRkcmVzcwogICAgYXBwX2xvY2FsX3B1dAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjY2MgogICAgLy8gc2VsZi5hcmM0X3VpbnQxMjhbR2xvYmFsLmNyZWF0b3JfYWRkcmVzc10gPSBhcmM0LlVJbnQxMjgoMioqMTAwKQogICAgZ2xvYmFsIENyZWF0b3JBZGRyZXNzCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6NjM4CiAgICAvLyBzZWxmLmFyYzRfdWludDEyOCA9IExvY2FsU3RhdGUoYXJjNC5VSW50MTI4LCBrZXk9ImV4cGxpY2l0X2tleV9hcmM0X3VpbnQxMjgiKQogICAgYnl0ZSAiZXhwbGljaXRfa2V5X2FyYzRfdWludDEyOCIKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTo2NjIKICAgIC8vIHNlbGYuYXJjNF91aW50MTI4W0dsb2JhbC5jcmVhdG9yX2FkZHJlc3NdID0gYXJjNC5VSW50MTI4KDIqKjEwMCkKICAgIGJ5dGUgMHgwMDAwMDAxMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMAogICAgYXBwX2xvY2FsX3B1dAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjY2MwogICAgLy8gc2VsZi5hcmM0X2R5bmFtaWNfYnl0ZXNbR2xvYmFsLmNyZWF0b3JfYWRkcmVzc10gPSBhcmM0LkR5bmFtaWNCeXRlcyhiImR5bmFtaWMgYnl0ZXMiKQogICAgZ2xvYmFsIENyZWF0b3JBZGRyZXNzCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6NjQwCiAgICAvLyBhcmM0LkR5bmFtaWNCeXRlcywga2V5PSJleHBsaWNpdF9rZXlfYXJjNF9keW5hbWljX2J5dGVzIgogICAgYnl0ZSAiZXhwbGljaXRfa2V5X2FyYzRfZHluYW1pY19ieXRlcyIKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTo2NjMKICAgIC8vIHNlbGYuYXJjNF9keW5hbWljX2J5dGVzW0dsb2JhbC5jcmVhdG9yX2FkZHJlc3NdID0gYXJjNC5EeW5hbWljQnl0ZXMoYiJkeW5hbWljIGJ5dGVzIikKICAgIGJ5dGUgMHgwMDBkNjQ3OTZlNjE2ZDY5NjMyMDYyNzk3NDY1NzMKICAgIGFwcF9sb2NhbF9wdXQKICAgIHJldHN1YgoKCi8vIHRlc3RzLmFydGlmYWN0cy5TdGF0ZU9wcy5jb250cmFjdC5Mb2NhbFN0YXRlQ29udHJhY3QuZ2V0X2ltcGxpY2l0X2tleV9hcmM0X3VpbnQoYTogYnl0ZXMpIC0+IGJ5dGVzOgpnZXRfaW1wbGljaXRfa2V5X2FyYzRfdWludDoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTo2NjUtNjY3CiAgICAvLyAjIEdldHRlciBtZXRob2RzIGZvciBpbXBsaWNpdCBrZXkgc3RhdGUgdmFyaWFibGVzCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gZGVmIGdldF9pbXBsaWNpdF9rZXlfYXJjNF91aW50KHNlbGYsIGE6IEFjY291bnQpIC0+IGFyYzQuVUludDY0OgogICAgcHJvdG8gMSAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6NjY4CiAgICAvLyByZXR1cm4gc2VsZi5pbXBsaWNpdF9rZXlfYXJjNF91aW50W2FdCiAgICBmcmFtZV9kaWcgLTEKICAgIGludCAwCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6NjIzLTYyNAogICAgLy8gIyBJbXBsaWNpdCBrZXkgc3RhdGUgdmFyaWFibGVzCiAgICAvLyBzZWxmLmltcGxpY2l0X2tleV9hcmM0X3VpbnQgPSBMb2NhbFN0YXRlKGFyYzQuVUludDY0KQogICAgYnl0ZSAiaW1wbGljaXRfa2V5X2FyYzRfdWludCIKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTo2NjgKICAgIC8vIHJldHVybiBzZWxmLmltcGxpY2l0X2tleV9hcmM0X3VpbnRbYV0KICAgIGFwcF9sb2NhbF9nZXRfZXgKICAgIGFzc2VydCAvLyBjaGVjayBzZWxmLmltcGxpY2l0X2tleV9hcmM0X3VpbnQgZXhpc3RzIGZvciBhY2NvdW50CiAgICByZXRzdWIKCgovLyB0ZXN0cy5hcnRpZmFjdHMuU3RhdGVPcHMuY29udHJhY3QuTG9jYWxTdGF0ZUNvbnRyYWN0LmdldF9pbXBsaWNpdF9rZXlfYXJjNF9zdHJpbmcoYTogYnl0ZXMpIC0+IGJ5dGVzOgpnZXRfaW1wbGljaXRfa2V5X2FyYzRfc3RyaW5nOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjY3MC02NzEKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBkZWYgZ2V0X2ltcGxpY2l0X2tleV9hcmM0X3N0cmluZyhzZWxmLCBhOiBBY2NvdW50KSAtPiBhcmM0LlN0cmluZzoKICAgIHByb3RvIDEgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjY3MgogICAgLy8gcmV0dXJuIHNlbGYuaW1wbGljaXRfa2V5X2FyYzRfc3RyaW5nW2FdCiAgICBmcmFtZV9kaWcgLTEKICAgIGludCAwCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6NjI1CiAgICAvLyBzZWxmLmltcGxpY2l0X2tleV9hcmM0X3N0cmluZyA9IExvY2FsU3RhdGUoYXJjNC5TdHJpbmcpCiAgICBieXRlICJpbXBsaWNpdF9rZXlfYXJjNF9zdHJpbmciCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6NjcyCiAgICAvLyByZXR1cm4gc2VsZi5pbXBsaWNpdF9rZXlfYXJjNF9zdHJpbmdbYV0KICAgIGFwcF9sb2NhbF9nZXRfZXgKICAgIGFzc2VydCAvLyBjaGVjayBzZWxmLmltcGxpY2l0X2tleV9hcmM0X3N0cmluZyBleGlzdHMgZm9yIGFjY291bnQKICAgIHJldHN1YgoKCi8vIHRlc3RzLmFydGlmYWN0cy5TdGF0ZU9wcy5jb250cmFjdC5Mb2NhbFN0YXRlQ29udHJhY3QuZ2V0X2ltcGxpY2l0X2tleV9hcmM0X2J5dGUoYTogYnl0ZXMpIC0+IGJ5dGVzOgpnZXRfaW1wbGljaXRfa2V5X2FyYzRfYnl0ZToKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTo2NzQtNjc1CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gZGVmIGdldF9pbXBsaWNpdF9rZXlfYXJjNF9ieXRlKHNlbGYsIGE6IEFjY291bnQpIC0+IGFyYzQuQnl0ZToKICAgIHByb3RvIDEgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjY3NgogICAgLy8gcmV0dXJuIHNlbGYuaW1wbGljaXRfa2V5X2FyYzRfYnl0ZVthXQogICAgZnJhbWVfZGlnIC0xCiAgICBpbnQgMAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjYyNgogICAgLy8gc2VsZi5pbXBsaWNpdF9rZXlfYXJjNF9ieXRlID0gTG9jYWxTdGF0ZShhcmM0LkJ5dGUpCiAgICBieXRlICJpbXBsaWNpdF9rZXlfYXJjNF9ieXRlIgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjY3NgogICAgLy8gcmV0dXJuIHNlbGYuaW1wbGljaXRfa2V5X2FyYzRfYnl0ZVthXQogICAgYXBwX2xvY2FsX2dldF9leAogICAgYXNzZXJ0IC8vIGNoZWNrIHNlbGYuaW1wbGljaXRfa2V5X2FyYzRfYnl0ZSBleGlzdHMgZm9yIGFjY291bnQKICAgIHJldHN1YgoKCi8vIHRlc3RzLmFydGlmYWN0cy5TdGF0ZU9wcy5jb250cmFjdC5Mb2NhbFN0YXRlQ29udHJhY3QuZ2V0X2ltcGxpY2l0X2tleV9hcmM0X2Jvb2woYTogYnl0ZXMpIC0+IGJ5dGVzOgpnZXRfaW1wbGljaXRfa2V5X2FyYzRfYm9vbDoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTo2NzgtNjc5CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gZGVmIGdldF9pbXBsaWNpdF9rZXlfYXJjNF9ib29sKHNlbGYsIGE6IEFjY291bnQpIC0+IGFyYzQuQm9vbDoKICAgIHByb3RvIDEgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjY4MAogICAgLy8gcmV0dXJuIHNlbGYuaW1wbGljaXRfa2V5X2FyYzRfYm9vbFthXQogICAgZnJhbWVfZGlnIC0xCiAgICBpbnQgMAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjYyNwogICAgLy8gc2VsZi5pbXBsaWNpdF9rZXlfYXJjNF9ib29sID0gTG9jYWxTdGF0ZShhcmM0LkJvb2wpCiAgICBieXRlICJpbXBsaWNpdF9rZXlfYXJjNF9ib29sIgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjY4MAogICAgLy8gcmV0dXJuIHNlbGYuaW1wbGljaXRfa2V5X2FyYzRfYm9vbFthXQogICAgYXBwX2xvY2FsX2dldF9leAogICAgYXNzZXJ0IC8vIGNoZWNrIHNlbGYuaW1wbGljaXRfa2V5X2FyYzRfYm9vbCBleGlzdHMgZm9yIGFjY291bnQKICAgIHJldHN1YgoKCi8vIHRlc3RzLmFydGlmYWN0cy5TdGF0ZU9wcy5jb250cmFjdC5Mb2NhbFN0YXRlQ29udHJhY3QuZ2V0X2ltcGxpY2l0X2tleV9hcmM0X2FkZHJlc3MoYTogYnl0ZXMpIC0+IGJ5dGVzOgpnZXRfaW1wbGljaXRfa2V5X2FyYzRfYWRkcmVzczoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTo2ODItNjgzCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gZGVmIGdldF9pbXBsaWNpdF9rZXlfYXJjNF9hZGRyZXNzKHNlbGYsIGE6IEFjY291bnQpIC0+IGFyYzQuQWRkcmVzczoKICAgIHByb3RvIDEgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjY4NAogICAgLy8gcmV0dXJuIHNlbGYuaW1wbGljaXRfa2V5X2FyYzRfYWRkcmVzc1thXQogICAgZnJhbWVfZGlnIC0xCiAgICBpbnQgMAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjYyOAogICAgLy8gc2VsZi5pbXBsaWNpdF9rZXlfYXJjNF9hZGRyZXNzID0gTG9jYWxTdGF0ZShhcmM0LkFkZHJlc3MpCiAgICBieXRlICJpbXBsaWNpdF9rZXlfYXJjNF9hZGRyZXNzIgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjY4NAogICAgLy8gcmV0dXJuIHNlbGYuaW1wbGljaXRfa2V5X2FyYzRfYWRkcmVzc1thXQogICAgYXBwX2xvY2FsX2dldF9leAogICAgYXNzZXJ0IC8vIGNoZWNrIHNlbGYuaW1wbGljaXRfa2V5X2FyYzRfYWRkcmVzcyBleGlzdHMgZm9yIGFjY291bnQKICAgIHJldHN1YgoKCi8vIHRlc3RzLmFydGlmYWN0cy5TdGF0ZU9wcy5jb250cmFjdC5Mb2NhbFN0YXRlQ29udHJhY3QuZ2V0X2ltcGxpY2l0X2tleV9hcmM0X3VpbnQxMjgoYTogYnl0ZXMpIC0+IGJ5dGVzOgpnZXRfaW1wbGljaXRfa2V5X2FyYzRfdWludDEyODoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTo2ODYtNjg3CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gZGVmIGdldF9pbXBsaWNpdF9rZXlfYXJjNF91aW50MTI4KHNlbGYsIGE6IEFjY291bnQpIC0+IGFyYzQuVUludDEyODoKICAgIHByb3RvIDEgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjY4OAogICAgLy8gcmV0dXJuIHNlbGYuaW1wbGljaXRfa2V5X2FyYzRfdWludDEyOFthXQogICAgZnJhbWVfZGlnIC0xCiAgICBpbnQgMAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjYyOQogICAgLy8gc2VsZi5pbXBsaWNpdF9rZXlfYXJjNF91aW50MTI4ID0gTG9jYWxTdGF0ZShhcmM0LlVJbnQxMjgpCiAgICBieXRlICJpbXBsaWNpdF9rZXlfYXJjNF91aW50MTI4IgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjY4OAogICAgLy8gcmV0dXJuIHNlbGYuaW1wbGljaXRfa2V5X2FyYzRfdWludDEyOFthXQogICAgYXBwX2xvY2FsX2dldF9leAogICAgYXNzZXJ0IC8vIGNoZWNrIHNlbGYuaW1wbGljaXRfa2V5X2FyYzRfdWludDEyOCBleGlzdHMgZm9yIGFjY291bnQKICAgIHJldHN1YgoKCi8vIHRlc3RzLmFydGlmYWN0cy5TdGF0ZU9wcy5jb250cmFjdC5Mb2NhbFN0YXRlQ29udHJhY3QuZ2V0X2ltcGxpY2l0X2tleV9hcmM0X2R5bmFtaWNfYnl0ZXMoYTogYnl0ZXMpIC0+IGJ5dGVzOgpnZXRfaW1wbGljaXRfa2V5X2FyYzRfZHluYW1pY19ieXRlczoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTo2OTAtNjkxCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gZGVmIGdldF9pbXBsaWNpdF9rZXlfYXJjNF9keW5hbWljX2J5dGVzKHNlbGYsIGE6IEFjY291bnQpIC0+IGFyYzQuRHluYW1pY0J5dGVzOgogICAgcHJvdG8gMSAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6NjkyCiAgICAvLyByZXR1cm4gc2VsZi5pbXBsaWNpdF9rZXlfYXJjNF9keW5hbWljX2J5dGVzW2FdCiAgICBmcmFtZV9kaWcgLTEKICAgIGludCAwCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6NjMwCiAgICAvLyBzZWxmLmltcGxpY2l0X2tleV9hcmM0X2R5bmFtaWNfYnl0ZXMgPSBMb2NhbFN0YXRlKGFyYzQuRHluYW1pY0J5dGVzKQogICAgYnl0ZSAiaW1wbGljaXRfa2V5X2FyYzRfZHluYW1pY19ieXRlcyIKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTo2OTIKICAgIC8vIHJldHVybiBzZWxmLmltcGxpY2l0X2tleV9hcmM0X2R5bmFtaWNfYnl0ZXNbYV0KICAgIGFwcF9sb2NhbF9nZXRfZXgKICAgIGFzc2VydCAvLyBjaGVjayBzZWxmLmltcGxpY2l0X2tleV9hcmM0X2R5bmFtaWNfYnl0ZXMgZXhpc3RzIGZvciBhY2NvdW50CiAgICByZXRzdWIKCgovLyB0ZXN0cy5hcnRpZmFjdHMuU3RhdGVPcHMuY29udHJhY3QuTG9jYWxTdGF0ZUNvbnRyYWN0LmdldF9hcmM0X3VpbnQoYTogYnl0ZXMpIC0+IGJ5dGVzOgpnZXRfYXJjNF91aW50OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjY5NC02OTYKICAgIC8vICMgR2V0dGVyIG1ldGhvZHMgZm9yIGV4cGxpY2l0IGtleSBzdGF0ZSB2YXJpYWJsZXMKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBkZWYgZ2V0X2FyYzRfdWludChzZWxmLCBhOiBBY2NvdW50KSAtPiBhcmM0LlVJbnQ2NDoKICAgIHByb3RvIDEgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjY5NwogICAgLy8gcmV0dXJuIHNlbGYuYXJjNF91aW50W2FdCiAgICBmcmFtZV9kaWcgLTEKICAgIGludCAwCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6NjMyLTYzMwogICAgLy8gIyBFeHBsaWNpdCBrZXkgc3RhdGUgdmFyaWFibGVzCiAgICAvLyBzZWxmLmFyYzRfdWludCA9IExvY2FsU3RhdGUoYXJjNC5VSW50NjQsIGtleT0iZXhwbGljaXRfa2V5X2FyYzRfdWludCIpCiAgICBieXRlICJleHBsaWNpdF9rZXlfYXJjNF91aW50IgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjY5NwogICAgLy8gcmV0dXJuIHNlbGYuYXJjNF91aW50W2FdCiAgICBhcHBfbG9jYWxfZ2V0X2V4CiAgICBhc3NlcnQgLy8gY2hlY2sgc2VsZi5hcmM0X3VpbnQgZXhpc3RzIGZvciBhY2NvdW50CiAgICByZXRzdWIKCgovLyB0ZXN0cy5hcnRpZmFjdHMuU3RhdGVPcHMuY29udHJhY3QuTG9jYWxTdGF0ZUNvbnRyYWN0LmdldF9hcmM0X3N0cmluZyhhOiBieXRlcykgLT4gYnl0ZXM6CmdldF9hcmM0X3N0cmluZzoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTo2OTktNzAwCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gZGVmIGdldF9hcmM0X3N0cmluZyhzZWxmLCBhOiBBY2NvdW50KSAtPiBhcmM0LlN0cmluZzoKICAgIHByb3RvIDEgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjcwMQogICAgLy8gcmV0dXJuIHNlbGYuYXJjNF9zdHJpbmdbYV0KICAgIGZyYW1lX2RpZyAtMQogICAgaW50IDAKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTo2MzQKICAgIC8vIHNlbGYuYXJjNF9zdHJpbmcgPSBMb2NhbFN0YXRlKGFyYzQuU3RyaW5nLCBrZXk9ImV4cGxpY2l0X2tleV9hcmM0X3N0cmluZyIpCiAgICBieXRlICJleHBsaWNpdF9rZXlfYXJjNF9zdHJpbmciCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6NzAxCiAgICAvLyByZXR1cm4gc2VsZi5hcmM0X3N0cmluZ1thXQogICAgYXBwX2xvY2FsX2dldF9leAogICAgYXNzZXJ0IC8vIGNoZWNrIHNlbGYuYXJjNF9zdHJpbmcgZXhpc3RzIGZvciBhY2NvdW50CiAgICByZXRzdWIKCgovLyB0ZXN0cy5hcnRpZmFjdHMuU3RhdGVPcHMuY29udHJhY3QuTG9jYWxTdGF0ZUNvbnRyYWN0LmdldF9hcmM0X2J5dGUoYTogYnl0ZXMpIC0+IGJ5dGVzOgpnZXRfYXJjNF9ieXRlOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjcwMy03MDQKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBkZWYgZ2V0X2FyYzRfYnl0ZShzZWxmLCBhOiBBY2NvdW50KSAtPiBhcmM0LkJ5dGU6CiAgICBwcm90byAxIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTo3MDUKICAgIC8vIHJldHVybiBzZWxmLmFyYzRfYnl0ZVthXQogICAgZnJhbWVfZGlnIC0xCiAgICBpbnQgMAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjYzNQogICAgLy8gc2VsZi5hcmM0X2J5dGUgPSBMb2NhbFN0YXRlKGFyYzQuQnl0ZSwga2V5PSJleHBsaWNpdF9rZXlfYXJjNF9ieXRlIikKICAgIGJ5dGUgImV4cGxpY2l0X2tleV9hcmM0X2J5dGUiCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6NzA1CiAgICAvLyByZXR1cm4gc2VsZi5hcmM0X2J5dGVbYV0KICAgIGFwcF9sb2NhbF9nZXRfZXgKICAgIGFzc2VydCAvLyBjaGVjayBzZWxmLmFyYzRfYnl0ZSBleGlzdHMgZm9yIGFjY291bnQKICAgIHJldHN1YgoKCi8vIHRlc3RzLmFydGlmYWN0cy5TdGF0ZU9wcy5jb250cmFjdC5Mb2NhbFN0YXRlQ29udHJhY3QuZ2V0X2FyYzRfYm9vbChhOiBieXRlcykgLT4gYnl0ZXM6CmdldF9hcmM0X2Jvb2w6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6NzA3LTcwOAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIGRlZiBnZXRfYXJjNF9ib29sKHNlbGYsIGE6IEFjY291bnQpIC0+IGFyYzQuQm9vbDoKICAgIHByb3RvIDEgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjcwOQogICAgLy8gcmV0dXJuIHNlbGYuYXJjNF9ib29sW2FdCiAgICBmcmFtZV9kaWcgLTEKICAgIGludCAwCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6NjM2CiAgICAvLyBzZWxmLmFyYzRfYm9vbCA9IExvY2FsU3RhdGUoYXJjNC5Cb29sLCBrZXk9ImV4cGxpY2l0X2tleV9hcmM0X2Jvb2wiKQogICAgYnl0ZSAiZXhwbGljaXRfa2V5X2FyYzRfYm9vbCIKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTo3MDkKICAgIC8vIHJldHVybiBzZWxmLmFyYzRfYm9vbFthXQogICAgYXBwX2xvY2FsX2dldF9leAogICAgYXNzZXJ0IC8vIGNoZWNrIHNlbGYuYXJjNF9ib29sIGV4aXN0cyBmb3IgYWNjb3VudAogICAgcmV0c3ViCgoKLy8gdGVzdHMuYXJ0aWZhY3RzLlN0YXRlT3BzLmNvbnRyYWN0LkxvY2FsU3RhdGVDb250cmFjdC5nZXRfYXJjNF9hZGRyZXNzKGE6IGJ5dGVzKSAtPiBieXRlczoKZ2V0X2FyYzRfYWRkcmVzczoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTo3MTEtNzEyCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gZGVmIGdldF9hcmM0X2FkZHJlc3Moc2VsZiwgYTogQWNjb3VudCkgLT4gYXJjNC5BZGRyZXNzOgogICAgcHJvdG8gMSAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6NzEzCiAgICAvLyByZXR1cm4gc2VsZi5hcmM0X2FkZHJlc3NbYV0KICAgIGZyYW1lX2RpZyAtMQogICAgaW50IDAKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTo2MzcKICAgIC8vIHNlbGYuYXJjNF9hZGRyZXNzID0gTG9jYWxTdGF0ZShhcmM0LkFkZHJlc3MsIGtleT0iZXhwbGljaXRfa2V5X2FyYzRfYWRkcmVzcyIpCiAgICBieXRlICJleHBsaWNpdF9rZXlfYXJjNF9hZGRyZXNzIgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjcxMwogICAgLy8gcmV0dXJuIHNlbGYuYXJjNF9hZGRyZXNzW2FdCiAgICBhcHBfbG9jYWxfZ2V0X2V4CiAgICBhc3NlcnQgLy8gY2hlY2sgc2VsZi5hcmM0X2FkZHJlc3MgZXhpc3RzIGZvciBhY2NvdW50CiAgICByZXRzdWIKCgovLyB0ZXN0cy5hcnRpZmFjdHMuU3RhdGVPcHMuY29udHJhY3QuTG9jYWxTdGF0ZUNvbnRyYWN0LmdldF9hcmM0X3VpbnQxMjgoYTogYnl0ZXMpIC0+IGJ5dGVzOgpnZXRfYXJjNF91aW50MTI4OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjcxNS03MTYKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBkZWYgZ2V0X2FyYzRfdWludDEyOChzZWxmLCBhOiBBY2NvdW50KSAtPiBhcmM0LlVJbnQxMjg6CiAgICBwcm90byAxIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTo3MTcKICAgIC8vIHJldHVybiBzZWxmLmFyYzRfdWludDEyOFthXQogICAgZnJhbWVfZGlnIC0xCiAgICBpbnQgMAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjYzOAogICAgLy8gc2VsZi5hcmM0X3VpbnQxMjggPSBMb2NhbFN0YXRlKGFyYzQuVUludDEyOCwga2V5PSJleHBsaWNpdF9rZXlfYXJjNF91aW50MTI4IikKICAgIGJ5dGUgImV4cGxpY2l0X2tleV9hcmM0X3VpbnQxMjgiCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6NzE3CiAgICAvLyByZXR1cm4gc2VsZi5hcmM0X3VpbnQxMjhbYV0KICAgIGFwcF9sb2NhbF9nZXRfZXgKICAgIGFzc2VydCAvLyBjaGVjayBzZWxmLmFyYzRfdWludDEyOCBleGlzdHMgZm9yIGFjY291bnQKICAgIHJldHN1YgoKCi8vIHRlc3RzLmFydGlmYWN0cy5TdGF0ZU9wcy5jb250cmFjdC5Mb2NhbFN0YXRlQ29udHJhY3QuZ2V0X2FyYzRfZHluYW1pY19ieXRlcyhhOiBieXRlcykgLT4gYnl0ZXM6CmdldF9hcmM0X2R5bmFtaWNfYnl0ZXM6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6NzE5LTcyMAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIGRlZiBnZXRfYXJjNF9keW5hbWljX2J5dGVzKHNlbGYsIGE6IEFjY291bnQpIC0+IGFyYzQuRHluYW1pY0J5dGVzOgogICAgcHJvdG8gMSAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6NzIxCiAgICAvLyByZXR1cm4gc2VsZi5hcmM0X2R5bmFtaWNfYnl0ZXNbYV0KICAgIGZyYW1lX2RpZyAtMQogICAgaW50IDAKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTo2NDAKICAgIC8vIGFyYzQuRHluYW1pY0J5dGVzLCBrZXk9ImV4cGxpY2l0X2tleV9hcmM0X2R5bmFtaWNfYnl0ZXMiCiAgICBieXRlICJleHBsaWNpdF9rZXlfYXJjNF9keW5hbWljX2J5dGVzIgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjcyMQogICAgLy8gcmV0dXJuIHNlbGYuYXJjNF9keW5hbWljX2J5dGVzW2FdCiAgICBhcHBfbG9jYWxfZ2V0X2V4CiAgICBhc3NlcnQgLy8gY2hlY2sgc2VsZi5hcmM0X2R5bmFtaWNfYnl0ZXMgZXhpc3RzIGZvciBhY2NvdW50CiAgICByZXRzdWIK", + "clear": "I3ByYWdtYSB2ZXJzaW9uIDEwCgp0ZXN0cy5hcnRpZmFjdHMuU3RhdGVPcHMuY29udHJhY3QuTG9jYWxTdGF0ZUNvbnRyYWN0LmNsZWFyX3N0YXRlX3Byb2dyYW06CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6NjIxCiAgICAvLyBjbGFzcyBMb2NhbFN0YXRlQ29udHJhY3QoQVJDNENvbnRyYWN0KToKICAgIGludCAxCiAgICByZXR1cm4K" }, "state": { "global": { diff --git a/tests/artifacts/StateOps/data/LocalStateContract.clear.teal b/tests/artifacts/StateOps/data/LocalStateContract.clear.teal index 3006ab4..8035798 100644 --- a/tests/artifacts/StateOps/data/LocalStateContract.clear.teal +++ b/tests/artifacts/StateOps/data/LocalStateContract.clear.teal @@ -1,7 +1,7 @@ #pragma version 10 tests.artifacts.StateOps.contract.LocalStateContract.clear_state_program: - // tests/artifacts/StateOps/contract.py:503 + // tests/artifacts/StateOps/contract.py:621 // class LocalStateContract(ARC4Contract): int 1 return diff --git a/tests/artifacts/StateOps/data/StateAcctParamsGetContract.approval.teal b/tests/artifacts/StateOps/data/StateAcctParamsGetContract.approval.teal index a2aae16..0dba141 100644 --- a/tests/artifacts/StateOps/data/StateAcctParamsGetContract.approval.teal +++ b/tests/artifacts/StateOps/data/StateAcctParamsGetContract.approval.teal @@ -1,13 +1,13 @@ #pragma version 10 tests.artifacts.StateOps.contract.StateAcctParamsGetContract.approval_program: - // tests/artifacts/StateOps/contract.py:17 + // tests/artifacts/StateOps/contract.py:24 // class StateAcctParamsGetContract(ARC4Contract): txn NumAppArgs bz main_bare_routing@16 method "verify_acct_balance(account)uint64" method "verify_acct_min_balance(account)uint64" - method "verify_acct_auth_addr(account)byte[]" + method "verify_acct_auth_addr(account)address" method "verify_acct_total_num_uint(account)uint64" method "verify_acct_total_num_byte_slice(account)uint64" method "verify_acct_total_extra_app_pages(account)uint64" @@ -22,19 +22,19 @@ tests.artifacts.StateOps.contract.StateAcctParamsGetContract.approval_program: err // reject transaction main_verify_acct_balance_route@2: - // tests/artifacts/StateOps/contract.py:18 + // tests/artifacts/StateOps/contract.py:25 // @arc4.abimethod() txn OnCompletion ! assert // OnCompletion is NoOp txn ApplicationID assert // is not creating - // tests/artifacts/StateOps/contract.py:17 + // tests/artifacts/StateOps/contract.py:24 // class StateAcctParamsGetContract(ARC4Contract): txna ApplicationArgs 1 btoi txnas Accounts - // tests/artifacts/StateOps/contract.py:18 + // tests/artifacts/StateOps/contract.py:25 // @arc4.abimethod() callsub verify_acct_balance itob @@ -46,19 +46,19 @@ main_verify_acct_balance_route@2: return main_verify_acct_min_balance_route@3: - // tests/artifacts/StateOps/contract.py:23 + // tests/artifacts/StateOps/contract.py:33 // @arc4.abimethod() txn OnCompletion ! assert // OnCompletion is NoOp txn ApplicationID assert // is not creating - // tests/artifacts/StateOps/contract.py:17 + // tests/artifacts/StateOps/contract.py:24 // class StateAcctParamsGetContract(ARC4Contract): txna ApplicationArgs 1 btoi txnas Accounts - // tests/artifacts/StateOps/contract.py:23 + // tests/artifacts/StateOps/contract.py:33 // @arc4.abimethod() callsub verify_acct_min_balance itob @@ -70,27 +70,21 @@ main_verify_acct_min_balance_route@3: return main_verify_acct_auth_addr_route@4: - // tests/artifacts/StateOps/contract.py:28 + // tests/artifacts/StateOps/contract.py:41 // @arc4.abimethod() txn OnCompletion ! assert // OnCompletion is NoOp txn ApplicationID assert // is not creating - // tests/artifacts/StateOps/contract.py:17 + // tests/artifacts/StateOps/contract.py:24 // class StateAcctParamsGetContract(ARC4Contract): txna ApplicationArgs 1 btoi txnas Accounts - // tests/artifacts/StateOps/contract.py:28 + // tests/artifacts/StateOps/contract.py:41 // @arc4.abimethod() callsub verify_acct_auth_addr - dup - len - itob - extract 6 2 - swap - concat byte 0x151f7c75 swap concat @@ -99,19 +93,19 @@ main_verify_acct_auth_addr_route@4: return main_verify_acct_total_num_uint_route@5: - // tests/artifacts/StateOps/contract.py:33 + // tests/artifacts/StateOps/contract.py:49 // @arc4.abimethod() txn OnCompletion ! assert // OnCompletion is NoOp txn ApplicationID assert // is not creating - // tests/artifacts/StateOps/contract.py:17 + // tests/artifacts/StateOps/contract.py:24 // class StateAcctParamsGetContract(ARC4Contract): txna ApplicationArgs 1 btoi txnas Accounts - // tests/artifacts/StateOps/contract.py:33 + // tests/artifacts/StateOps/contract.py:49 // @arc4.abimethod() callsub verify_acct_total_num_uint itob @@ -123,19 +117,19 @@ main_verify_acct_total_num_uint_route@5: return main_verify_acct_total_num_byte_slice_route@6: - // tests/artifacts/StateOps/contract.py:38 + // tests/artifacts/StateOps/contract.py:57 // @arc4.abimethod() txn OnCompletion ! assert // OnCompletion is NoOp txn ApplicationID assert // is not creating - // tests/artifacts/StateOps/contract.py:17 + // tests/artifacts/StateOps/contract.py:24 // class StateAcctParamsGetContract(ARC4Contract): txna ApplicationArgs 1 btoi txnas Accounts - // tests/artifacts/StateOps/contract.py:38 + // tests/artifacts/StateOps/contract.py:57 // @arc4.abimethod() callsub verify_acct_total_num_byte_slice itob @@ -147,19 +141,19 @@ main_verify_acct_total_num_byte_slice_route@6: return main_verify_acct_total_extra_app_pages_route@7: - // tests/artifacts/StateOps/contract.py:43 + // tests/artifacts/StateOps/contract.py:67 // @arc4.abimethod() txn OnCompletion ! assert // OnCompletion is NoOp txn ApplicationID assert // is not creating - // tests/artifacts/StateOps/contract.py:17 + // tests/artifacts/StateOps/contract.py:24 // class StateAcctParamsGetContract(ARC4Contract): txna ApplicationArgs 1 btoi txnas Accounts - // tests/artifacts/StateOps/contract.py:43 + // tests/artifacts/StateOps/contract.py:67 // @arc4.abimethod() callsub verify_acct_total_extra_app_pages itob @@ -171,19 +165,19 @@ main_verify_acct_total_extra_app_pages_route@7: return main_verify_acct_total_apps_created_route@8: - // tests/artifacts/StateOps/contract.py:48 + // tests/artifacts/StateOps/contract.py:77 // @arc4.abimethod() txn OnCompletion ! assert // OnCompletion is NoOp txn ApplicationID assert // is not creating - // tests/artifacts/StateOps/contract.py:17 + // tests/artifacts/StateOps/contract.py:24 // class StateAcctParamsGetContract(ARC4Contract): txna ApplicationArgs 1 btoi txnas Accounts - // tests/artifacts/StateOps/contract.py:48 + // tests/artifacts/StateOps/contract.py:77 // @arc4.abimethod() callsub verify_acct_total_apps_created itob @@ -195,19 +189,19 @@ main_verify_acct_total_apps_created_route@8: return main_verify_acct_total_apps_opted_in_route@9: - // tests/artifacts/StateOps/contract.py:53 + // tests/artifacts/StateOps/contract.py:85 // @arc4.abimethod() txn OnCompletion ! assert // OnCompletion is NoOp txn ApplicationID assert // is not creating - // tests/artifacts/StateOps/contract.py:17 + // tests/artifacts/StateOps/contract.py:24 // class StateAcctParamsGetContract(ARC4Contract): txna ApplicationArgs 1 btoi txnas Accounts - // tests/artifacts/StateOps/contract.py:53 + // tests/artifacts/StateOps/contract.py:85 // @arc4.abimethod() callsub verify_acct_total_apps_opted_in itob @@ -219,19 +213,19 @@ main_verify_acct_total_apps_opted_in_route@9: return main_verify_acct_total_assets_created_route@10: - // tests/artifacts/StateOps/contract.py:58 + // tests/artifacts/StateOps/contract.py:93 // @arc4.abimethod() txn OnCompletion ! assert // OnCompletion is NoOp txn ApplicationID assert // is not creating - // tests/artifacts/StateOps/contract.py:17 + // tests/artifacts/StateOps/contract.py:24 // class StateAcctParamsGetContract(ARC4Contract): txna ApplicationArgs 1 btoi txnas Accounts - // tests/artifacts/StateOps/contract.py:58 + // tests/artifacts/StateOps/contract.py:93 // @arc4.abimethod() callsub verify_acct_total_assets_created itob @@ -243,19 +237,19 @@ main_verify_acct_total_assets_created_route@10: return main_verify_acct_total_assets_route@11: - // tests/artifacts/StateOps/contract.py:63 + // tests/artifacts/StateOps/contract.py:103 // @arc4.abimethod() txn OnCompletion ! assert // OnCompletion is NoOp txn ApplicationID assert // is not creating - // tests/artifacts/StateOps/contract.py:17 + // tests/artifacts/StateOps/contract.py:24 // class StateAcctParamsGetContract(ARC4Contract): txna ApplicationArgs 1 btoi txnas Accounts - // tests/artifacts/StateOps/contract.py:63 + // tests/artifacts/StateOps/contract.py:103 // @arc4.abimethod() callsub verify_acct_total_assets itob @@ -267,19 +261,19 @@ main_verify_acct_total_assets_route@11: return main_verify_acct_total_boxes_route@12: - // tests/artifacts/StateOps/contract.py:68 + // tests/artifacts/StateOps/contract.py:111 // @arc4.abimethod() txn OnCompletion ! assert // OnCompletion is NoOp txn ApplicationID assert // is not creating - // tests/artifacts/StateOps/contract.py:17 + // tests/artifacts/StateOps/contract.py:24 // class StateAcctParamsGetContract(ARC4Contract): txna ApplicationArgs 1 btoi txnas Accounts - // tests/artifacts/StateOps/contract.py:68 + // tests/artifacts/StateOps/contract.py:111 // @arc4.abimethod() callsub verify_acct_total_boxes itob @@ -291,19 +285,19 @@ main_verify_acct_total_boxes_route@12: return main_verify_acct_total_box_bytes_route@13: - // tests/artifacts/StateOps/contract.py:73 + // tests/artifacts/StateOps/contract.py:119 // @arc4.abimethod() txn OnCompletion ! assert // OnCompletion is NoOp txn ApplicationID assert // is not creating - // tests/artifacts/StateOps/contract.py:17 + // tests/artifacts/StateOps/contract.py:24 // class StateAcctParamsGetContract(ARC4Contract): txna ApplicationArgs 1 btoi txnas Accounts - // tests/artifacts/StateOps/contract.py:73 + // tests/artifacts/StateOps/contract.py:119 // @arc4.abimethod() callsub verify_acct_total_box_bytes itob @@ -315,7 +309,7 @@ main_verify_acct_total_box_bytes_route@13: return main_bare_routing@16: - // tests/artifacts/StateOps/contract.py:17 + // tests/artifacts/StateOps/contract.py:24 // class StateAcctParamsGetContract(ARC4Contract): txn OnCompletion ! @@ -329,191 +323,396 @@ main_bare_routing@16: // tests.artifacts.StateOps.contract.StateAcctParamsGetContract.verify_acct_balance(a: bytes) -> uint64: verify_acct_balance: - // tests/artifacts/StateOps/contract.py:18-19 + // tests/artifacts/StateOps/contract.py:25-26 // @arc4.abimethod() // def verify_acct_balance(self, a: algopy.Account) -> algopy.UInt64: proto 1 1 - // tests/artifacts/StateOps/contract.py:20 - // balance, _val = op.AcctParamsGet.acct_balance(a) + // tests/artifacts/StateOps/contract.py:27 + // value, funded = op.AcctParamsGet.acct_balance(a) frame_dig -1 acct_params_get AcctBalance - pop + swap + // tests/artifacts/StateOps/contract.py:28 + // value_index, funded_index = op.AcctParamsGet.acct_balance(_get_1st_ref_index()) + callsub _get_1st_ref_index + acct_params_get AcctBalance + cover 2 + // tests/artifacts/StateOps/contract.py:29 + // assert value == value_index, "expected value by index to match" + dig 1 + == + assert // expected value by index to match + // tests/artifacts/StateOps/contract.py:30 + // assert funded == funded_index, "expected funded by index to match" + cover 2 + == + assert // expected funded by index to match + // tests/artifacts/StateOps/contract.py:31 + // return value + retsub + + +// tests.artifacts.StateOps.contract._get_1st_ref_index() -> uint64: +_get_1st_ref_index: + // tests/artifacts/StateOps/contract.py:19-20 + // @subroutine + // def _get_1st_ref_index() -> UInt64: + proto 0 1 // tests/artifacts/StateOps/contract.py:21 - // return balance + // return op.btoi(Txn.application_args(1)) + txna ApplicationArgs 1 + btoi retsub // tests.artifacts.StateOps.contract.StateAcctParamsGetContract.verify_acct_min_balance(a: bytes) -> uint64: verify_acct_min_balance: - // tests/artifacts/StateOps/contract.py:23-24 + // tests/artifacts/StateOps/contract.py:33-34 // @arc4.abimethod() // def verify_acct_min_balance(self, a: algopy.Account) -> algopy.UInt64: proto 1 1 - // tests/artifacts/StateOps/contract.py:25 - // min_balance, _val = op.AcctParamsGet.acct_min_balance(a) + // tests/artifacts/StateOps/contract.py:35 + // value, funded = op.AcctParamsGet.acct_min_balance(a) frame_dig -1 acct_params_get AcctMinBalance - pop - // tests/artifacts/StateOps/contract.py:26 - // return min_balance + swap + // tests/artifacts/StateOps/contract.py:36 + // value_index, funded_index = op.AcctParamsGet.acct_min_balance(_get_1st_ref_index()) + callsub _get_1st_ref_index + acct_params_get AcctMinBalance + cover 2 + // tests/artifacts/StateOps/contract.py:37 + // assert value == value_index, "expected value by index to match" + dig 1 + == + assert // expected value by index to match + // tests/artifacts/StateOps/contract.py:38 + // assert funded == funded_index, "expected funded by index to match" + cover 2 + == + assert // expected funded by index to match + // tests/artifacts/StateOps/contract.py:39 + // return value retsub // tests.artifacts.StateOps.contract.StateAcctParamsGetContract.verify_acct_auth_addr(a: bytes) -> bytes: verify_acct_auth_addr: - // tests/artifacts/StateOps/contract.py:28-29 + // tests/artifacts/StateOps/contract.py:41-42 // @arc4.abimethod() - // def verify_acct_auth_addr(self, a: algopy.Account) -> algopy.Bytes: + // def verify_acct_auth_addr(self, a: algopy.Account) -> arc4.Address: proto 1 1 - // tests/artifacts/StateOps/contract.py:30 - // auth_addr, _val = op.AcctParamsGet.acct_auth_addr(a) + // tests/artifacts/StateOps/contract.py:43 + // value, funded = op.AcctParamsGet.acct_auth_addr(a) frame_dig -1 acct_params_get AcctAuthAddr - pop - // tests/artifacts/StateOps/contract.py:31 - // return auth_addr.bytes + swap + // tests/artifacts/StateOps/contract.py:44 + // value_index, funded_index = op.AcctParamsGet.acct_auth_addr(_get_1st_ref_index()) + callsub _get_1st_ref_index + acct_params_get AcctAuthAddr + cover 2 + // tests/artifacts/StateOps/contract.py:45 + // assert value == value_index, "expected value by index to match" + dig 1 + == + assert // expected value by index to match + // tests/artifacts/StateOps/contract.py:46 + // assert funded == funded_index, "expected funded by index to match" + cover 2 + == + assert // expected funded by index to match + // tests/artifacts/StateOps/contract.py:47 + // return arc4.Address(value) retsub // tests.artifacts.StateOps.contract.StateAcctParamsGetContract.verify_acct_total_num_uint(a: bytes) -> uint64: verify_acct_total_num_uint: - // tests/artifacts/StateOps/contract.py:33-34 + // tests/artifacts/StateOps/contract.py:49-50 // @arc4.abimethod() // def verify_acct_total_num_uint(self, a: algopy.Account) -> algopy.UInt64: proto 1 1 - // tests/artifacts/StateOps/contract.py:35 - // total_num_uint, _val = op.AcctParamsGet.acct_total_num_uint(a) + // tests/artifacts/StateOps/contract.py:51 + // value, funded = op.AcctParamsGet.acct_total_num_uint(a) frame_dig -1 acct_params_get AcctTotalNumUint - pop - // tests/artifacts/StateOps/contract.py:36 - // return total_num_uint + swap + // tests/artifacts/StateOps/contract.py:52 + // value_index, funded_index = op.AcctParamsGet.acct_total_num_uint(_get_1st_ref_index()) + callsub _get_1st_ref_index + acct_params_get AcctTotalNumUint + cover 2 + // tests/artifacts/StateOps/contract.py:53 + // assert value == value_index, "expected value by index to match" + dig 1 + == + assert // expected value by index to match + // tests/artifacts/StateOps/contract.py:54 + // assert funded == funded_index, "expected funded by index to match" + cover 2 + == + assert // expected funded by index to match + // tests/artifacts/StateOps/contract.py:55 + // return value retsub // tests.artifacts.StateOps.contract.StateAcctParamsGetContract.verify_acct_total_num_byte_slice(a: bytes) -> uint64: verify_acct_total_num_byte_slice: - // tests/artifacts/StateOps/contract.py:38-39 + // tests/artifacts/StateOps/contract.py:57-58 // @arc4.abimethod() // def verify_acct_total_num_byte_slice(self, a: algopy.Account) -> algopy.UInt64: proto 1 1 - // tests/artifacts/StateOps/contract.py:40 - // total_num_byte_slice, _val = op.AcctParamsGet.acct_total_num_byte_slice(a) + // tests/artifacts/StateOps/contract.py:59 + // value, funded = op.AcctParamsGet.acct_total_num_byte_slice(a) frame_dig -1 acct_params_get AcctTotalNumByteSlice - pop - // tests/artifacts/StateOps/contract.py:41 - // return total_num_byte_slice + swap + // tests/artifacts/StateOps/contract.py:61 + // _get_1st_ref_index() + callsub _get_1st_ref_index + // tests/artifacts/StateOps/contract.py:60-62 + // value_index, funded_index = op.AcctParamsGet.acct_total_num_byte_slice( + // _get_1st_ref_index() + // ) + acct_params_get AcctTotalNumByteSlice + cover 2 + // tests/artifacts/StateOps/contract.py:63 + // assert value == value_index, "expected value by index to match" + dig 1 + == + assert // expected value by index to match + // tests/artifacts/StateOps/contract.py:64 + // assert funded == funded_index, "expected funded by index to match" + cover 2 + == + assert // expected funded by index to match + // tests/artifacts/StateOps/contract.py:65 + // return value retsub // tests.artifacts.StateOps.contract.StateAcctParamsGetContract.verify_acct_total_extra_app_pages(a: bytes) -> uint64: verify_acct_total_extra_app_pages: - // tests/artifacts/StateOps/contract.py:43-44 + // tests/artifacts/StateOps/contract.py:67-68 // @arc4.abimethod() // def verify_acct_total_extra_app_pages(self, a: algopy.Account) -> algopy.UInt64: proto 1 1 - // tests/artifacts/StateOps/contract.py:45 - // total_extra_app_pages, _val = op.AcctParamsGet.acct_total_extra_app_pages(a) + // tests/artifacts/StateOps/contract.py:69 + // value, funded = op.AcctParamsGet.acct_total_extra_app_pages(a) frame_dig -1 acct_params_get AcctTotalExtraAppPages - pop - // tests/artifacts/StateOps/contract.py:46 - // return total_extra_app_pages + swap + // tests/artifacts/StateOps/contract.py:71 + // _get_1st_ref_index() + callsub _get_1st_ref_index + // tests/artifacts/StateOps/contract.py:70-72 + // value_index, funded_index = op.AcctParamsGet.acct_total_extra_app_pages( + // _get_1st_ref_index() + // ) + acct_params_get AcctTotalExtraAppPages + cover 2 + // tests/artifacts/StateOps/contract.py:73 + // assert value == value_index, "expected value by index to match" + dig 1 + == + assert // expected value by index to match + // tests/artifacts/StateOps/contract.py:74 + // assert funded == funded_index, "expected funded by index to match" + cover 2 + == + assert // expected funded by index to match + // tests/artifacts/StateOps/contract.py:75 + // return value retsub // tests.artifacts.StateOps.contract.StateAcctParamsGetContract.verify_acct_total_apps_created(a: bytes) -> uint64: verify_acct_total_apps_created: - // tests/artifacts/StateOps/contract.py:48-49 + // tests/artifacts/StateOps/contract.py:77-78 // @arc4.abimethod() // def verify_acct_total_apps_created(self, a: algopy.Account) -> algopy.UInt64: proto 1 1 - // tests/artifacts/StateOps/contract.py:50 - // total_apps_created, _val = op.AcctParamsGet.acct_total_apps_created(a) + // tests/artifacts/StateOps/contract.py:79 + // value, funded = op.AcctParamsGet.acct_total_apps_created(a) frame_dig -1 acct_params_get AcctTotalAppsCreated - pop - // tests/artifacts/StateOps/contract.py:51 - // return total_apps_created + swap + // tests/artifacts/StateOps/contract.py:80 + // value_index, funded_index = op.AcctParamsGet.acct_total_apps_created(_get_1st_ref_index()) + callsub _get_1st_ref_index + acct_params_get AcctTotalAppsCreated + cover 2 + // tests/artifacts/StateOps/contract.py:81 + // assert value == value_index, "expected value by index to match" + dig 1 + == + assert // expected value by index to match + // tests/artifacts/StateOps/contract.py:82 + // assert funded == funded_index, "expected funded by index to match" + cover 2 + == + assert // expected funded by index to match + // tests/artifacts/StateOps/contract.py:83 + // return value retsub // tests.artifacts.StateOps.contract.StateAcctParamsGetContract.verify_acct_total_apps_opted_in(a: bytes) -> uint64: verify_acct_total_apps_opted_in: - // tests/artifacts/StateOps/contract.py:53-54 + // tests/artifacts/StateOps/contract.py:85-86 // @arc4.abimethod() // def verify_acct_total_apps_opted_in(self, a: algopy.Account) -> algopy.UInt64: proto 1 1 - // tests/artifacts/StateOps/contract.py:55 - // total_apps_opted_in, _val = op.AcctParamsGet.acct_total_apps_opted_in(a) + // tests/artifacts/StateOps/contract.py:87 + // value, funded = op.AcctParamsGet.acct_total_apps_opted_in(a) frame_dig -1 acct_params_get AcctTotalAppsOptedIn - pop - // tests/artifacts/StateOps/contract.py:56 - // return total_apps_opted_in + swap + // tests/artifacts/StateOps/contract.py:88 + // value_index, funded_index = op.AcctParamsGet.acct_total_apps_opted_in(_get_1st_ref_index()) + callsub _get_1st_ref_index + acct_params_get AcctTotalAppsOptedIn + cover 2 + // tests/artifacts/StateOps/contract.py:89 + // assert value == value_index, "expected value by index to match" + dig 1 + == + assert // expected value by index to match + // tests/artifacts/StateOps/contract.py:90 + // assert funded == funded_index, "expected funded by index to match" + cover 2 + == + assert // expected funded by index to match + // tests/artifacts/StateOps/contract.py:91 + // return value retsub // tests.artifacts.StateOps.contract.StateAcctParamsGetContract.verify_acct_total_assets_created(a: bytes) -> uint64: verify_acct_total_assets_created: - // tests/artifacts/StateOps/contract.py:58-59 + // tests/artifacts/StateOps/contract.py:93-94 // @arc4.abimethod() // def verify_acct_total_assets_created(self, a: algopy.Account) -> algopy.UInt64: proto 1 1 - // tests/artifacts/StateOps/contract.py:60 - // total_assets_created, _val = op.AcctParamsGet.acct_total_assets_created(a) + // tests/artifacts/StateOps/contract.py:95 + // value, funded = op.AcctParamsGet.acct_total_assets_created(a) frame_dig -1 acct_params_get AcctTotalAssetsCreated - pop - // tests/artifacts/StateOps/contract.py:61 - // return total_assets_created + swap + // tests/artifacts/StateOps/contract.py:97 + // _get_1st_ref_index() + callsub _get_1st_ref_index + // tests/artifacts/StateOps/contract.py:96-98 + // value_index, funded_index = op.AcctParamsGet.acct_total_assets_created( + // _get_1st_ref_index() + // ) + acct_params_get AcctTotalAssetsCreated + cover 2 + // tests/artifacts/StateOps/contract.py:99 + // assert value == value_index, "expected value by index to match" + dig 1 + == + assert // expected value by index to match + // tests/artifacts/StateOps/contract.py:100 + // assert funded == funded_index, "expected funded by index to match" + cover 2 + == + assert // expected funded by index to match + // tests/artifacts/StateOps/contract.py:101 + // return value retsub // tests.artifacts.StateOps.contract.StateAcctParamsGetContract.verify_acct_total_assets(a: bytes) -> uint64: verify_acct_total_assets: - // tests/artifacts/StateOps/contract.py:63-64 + // tests/artifacts/StateOps/contract.py:103-104 // @arc4.abimethod() // def verify_acct_total_assets(self, a: algopy.Account) -> algopy.UInt64: proto 1 1 - // tests/artifacts/StateOps/contract.py:65 - // total_assets, _val = op.AcctParamsGet.acct_total_assets(a) + // tests/artifacts/StateOps/contract.py:105 + // value, funded = op.AcctParamsGet.acct_total_assets(a) frame_dig -1 acct_params_get AcctTotalAssets - pop - // tests/artifacts/StateOps/contract.py:66 - // return total_assets + swap + // tests/artifacts/StateOps/contract.py:106 + // value_index, funded_index = op.AcctParamsGet.acct_total_assets(_get_1st_ref_index()) + callsub _get_1st_ref_index + acct_params_get AcctTotalAssets + cover 2 + // tests/artifacts/StateOps/contract.py:107 + // assert value == value_index, "expected value by index to match" + dig 1 + == + assert // expected value by index to match + // tests/artifacts/StateOps/contract.py:108 + // assert funded == funded_index, "expected funded by index to match" + cover 2 + == + assert // expected funded by index to match + // tests/artifacts/StateOps/contract.py:109 + // return value retsub // tests.artifacts.StateOps.contract.StateAcctParamsGetContract.verify_acct_total_boxes(a: bytes) -> uint64: verify_acct_total_boxes: - // tests/artifacts/StateOps/contract.py:68-69 + // tests/artifacts/StateOps/contract.py:111-112 // @arc4.abimethod() // def verify_acct_total_boxes(self, a: algopy.Account) -> algopy.UInt64: proto 1 1 - // tests/artifacts/StateOps/contract.py:70 - // total_boxes, _val = op.AcctParamsGet.acct_total_boxes(a) + // tests/artifacts/StateOps/contract.py:113 + // value, funded = op.AcctParamsGet.acct_total_boxes(a) frame_dig -1 acct_params_get AcctTotalBoxes - pop - // tests/artifacts/StateOps/contract.py:71 - // return total_boxes + swap + // tests/artifacts/StateOps/contract.py:114 + // value_index, funded_index = op.AcctParamsGet.acct_total_boxes(_get_1st_ref_index()) + callsub _get_1st_ref_index + acct_params_get AcctTotalBoxes + cover 2 + // tests/artifacts/StateOps/contract.py:115 + // assert value == value_index, "expected value by index to match" + dig 1 + == + assert // expected value by index to match + // tests/artifacts/StateOps/contract.py:116 + // assert funded == funded_index, "expected funded by index to match" + cover 2 + == + assert // expected funded by index to match + // tests/artifacts/StateOps/contract.py:117 + // return value retsub // tests.artifacts.StateOps.contract.StateAcctParamsGetContract.verify_acct_total_box_bytes(a: bytes) -> uint64: verify_acct_total_box_bytes: - // tests/artifacts/StateOps/contract.py:73-74 + // tests/artifacts/StateOps/contract.py:119-120 // @arc4.abimethod() // def verify_acct_total_box_bytes(self, a: algopy.Account) -> algopy.UInt64: proto 1 1 - // tests/artifacts/StateOps/contract.py:75 - // total_box_bytes, _val = op.AcctParamsGet.acct_total_box_bytes(a) + // tests/artifacts/StateOps/contract.py:121 + // value, funded = op.AcctParamsGet.acct_total_box_bytes(a) frame_dig -1 acct_params_get AcctTotalBoxBytes - pop - // tests/artifacts/StateOps/contract.py:76 - // return total_box_bytes + swap + // tests/artifacts/StateOps/contract.py:122 + // value_index, funded_index = op.AcctParamsGet.acct_total_box_bytes(_get_1st_ref_index()) + callsub _get_1st_ref_index + acct_params_get AcctTotalBoxBytes + cover 2 + // tests/artifacts/StateOps/contract.py:123 + // assert value == value_index, "expected value by index to match" + dig 1 + == + assert // expected value by index to match + // tests/artifacts/StateOps/contract.py:124 + // assert funded == funded_index, "expected funded by index to match" + cover 2 + == + assert // expected funded by index to match + // tests/artifacts/StateOps/contract.py:125 + // return value retsub diff --git a/tests/artifacts/StateOps/data/StateAcctParamsGetContract.arc32.json b/tests/artifacts/StateOps/data/StateAcctParamsGetContract.arc32.json index 32028ac..78380b6 100644 --- a/tests/artifacts/StateOps/data/StateAcctParamsGetContract.arc32.json +++ b/tests/artifacts/StateOps/data/StateAcctParamsGetContract.arc32.json @@ -10,7 +10,7 @@ "no_op": "CALL" } }, - "verify_acct_auth_addr(account)byte[]": { + "verify_acct_auth_addr(account)address": { "call_config": { "no_op": "CALL" } @@ -62,8 +62,8 @@ } }, "source": { - "approval": "I3ByYWdtYSB2ZXJzaW9uIDEwCgp0ZXN0cy5hcnRpZmFjdHMuU3RhdGVPcHMuY29udHJhY3QuU3RhdGVBY2N0UGFyYW1zR2V0Q29udHJhY3QuYXBwcm92YWxfcHJvZ3JhbToKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weToxNwogICAgLy8gY2xhc3MgU3RhdGVBY2N0UGFyYW1zR2V0Q29udHJhY3QoQVJDNENvbnRyYWN0KToKICAgIHR4biBOdW1BcHBBcmdzCiAgICBieiBtYWluX2JhcmVfcm91dGluZ0AxNgogICAgbWV0aG9kICJ2ZXJpZnlfYWNjdF9iYWxhbmNlKGFjY291bnQpdWludDY0IgogICAgbWV0aG9kICJ2ZXJpZnlfYWNjdF9taW5fYmFsYW5jZShhY2NvdW50KXVpbnQ2NCIKICAgIG1ldGhvZCAidmVyaWZ5X2FjY3RfYXV0aF9hZGRyKGFjY291bnQpYnl0ZVtdIgogICAgbWV0aG9kICJ2ZXJpZnlfYWNjdF90b3RhbF9udW1fdWludChhY2NvdW50KXVpbnQ2NCIKICAgIG1ldGhvZCAidmVyaWZ5X2FjY3RfdG90YWxfbnVtX2J5dGVfc2xpY2UoYWNjb3VudCl1aW50NjQiCiAgICBtZXRob2QgInZlcmlmeV9hY2N0X3RvdGFsX2V4dHJhX2FwcF9wYWdlcyhhY2NvdW50KXVpbnQ2NCIKICAgIG1ldGhvZCAidmVyaWZ5X2FjY3RfdG90YWxfYXBwc19jcmVhdGVkKGFjY291bnQpdWludDY0IgogICAgbWV0aG9kICJ2ZXJpZnlfYWNjdF90b3RhbF9hcHBzX29wdGVkX2luKGFjY291bnQpdWludDY0IgogICAgbWV0aG9kICJ2ZXJpZnlfYWNjdF90b3RhbF9hc3NldHNfY3JlYXRlZChhY2NvdW50KXVpbnQ2NCIKICAgIG1ldGhvZCAidmVyaWZ5X2FjY3RfdG90YWxfYXNzZXRzKGFjY291bnQpdWludDY0IgogICAgbWV0aG9kICJ2ZXJpZnlfYWNjdF90b3RhbF9ib3hlcyhhY2NvdW50KXVpbnQ2NCIKICAgIG1ldGhvZCAidmVyaWZ5X2FjY3RfdG90YWxfYm94X2J5dGVzKGFjY291bnQpdWludDY0IgogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMAogICAgbWF0Y2ggbWFpbl92ZXJpZnlfYWNjdF9iYWxhbmNlX3JvdXRlQDIgbWFpbl92ZXJpZnlfYWNjdF9taW5fYmFsYW5jZV9yb3V0ZUAzIG1haW5fdmVyaWZ5X2FjY3RfYXV0aF9hZGRyX3JvdXRlQDQgbWFpbl92ZXJpZnlfYWNjdF90b3RhbF9udW1fdWludF9yb3V0ZUA1IG1haW5fdmVyaWZ5X2FjY3RfdG90YWxfbnVtX2J5dGVfc2xpY2Vfcm91dGVANiBtYWluX3ZlcmlmeV9hY2N0X3RvdGFsX2V4dHJhX2FwcF9wYWdlc19yb3V0ZUA3IG1haW5fdmVyaWZ5X2FjY3RfdG90YWxfYXBwc19jcmVhdGVkX3JvdXRlQDggbWFpbl92ZXJpZnlfYWNjdF90b3RhbF9hcHBzX29wdGVkX2luX3JvdXRlQDkgbWFpbl92ZXJpZnlfYWNjdF90b3RhbF9hc3NldHNfY3JlYXRlZF9yb3V0ZUAxMCBtYWluX3ZlcmlmeV9hY2N0X3RvdGFsX2Fzc2V0c19yb3V0ZUAxMSBtYWluX3ZlcmlmeV9hY2N0X3RvdGFsX2JveGVzX3JvdXRlQDEyIG1haW5fdmVyaWZ5X2FjY3RfdG90YWxfYm94X2J5dGVzX3JvdXRlQDEzCiAgICBlcnIgLy8gcmVqZWN0IHRyYW5zYWN0aW9uCgptYWluX3ZlcmlmeV9hY2N0X2JhbGFuY2Vfcm91dGVAMjoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weToxOAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBpcyBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weToxNwogICAgLy8gY2xhc3MgU3RhdGVBY2N0UGFyYW1zR2V0Q29udHJhY3QoQVJDNENvbnRyYWN0KToKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGJ0b2kKICAgIHR4bmFzIEFjY291bnRzCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6MTgKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV9hY2N0X2JhbGFuY2UKICAgIGl0b2IKICAgIGJ5dGUgMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludCAxCiAgICByZXR1cm4KCm1haW5fdmVyaWZ5X2FjY3RfbWluX2JhbGFuY2Vfcm91dGVAMzoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weToyMwogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBpcyBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weToxNwogICAgLy8gY2xhc3MgU3RhdGVBY2N0UGFyYW1zR2V0Q29udHJhY3QoQVJDNENvbnRyYWN0KToKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGJ0b2kKICAgIHR4bmFzIEFjY291bnRzCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6MjMKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV9hY2N0X21pbl9iYWxhbmNlCiAgICBpdG9iCiAgICBieXRlIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnQgMQogICAgcmV0dXJuCgptYWluX3ZlcmlmeV9hY2N0X2F1dGhfYWRkcl9yb3V0ZUA0OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjI4CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGlzIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjE3CiAgICAvLyBjbGFzcyBTdGF0ZUFjY3RQYXJhbXNHZXRDb250cmFjdChBUkM0Q29udHJhY3QpOgogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgYnRvaQogICAgdHhuYXMgQWNjb3VudHMKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weToyOAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X2FjY3RfYXV0aF9hZGRyCiAgICBkdXAKICAgIGxlbgogICAgaXRvYgogICAgZXh0cmFjdCA2IDIKICAgIHN3YXAKICAgIGNvbmNhdAogICAgYnl0ZSAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50IDEKICAgIHJldHVybgoKbWFpbl92ZXJpZnlfYWNjdF90b3RhbF9udW1fdWludF9yb3V0ZUA1OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjMzCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGlzIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjE3CiAgICAvLyBjbGFzcyBTdGF0ZUFjY3RQYXJhbXNHZXRDb250cmFjdChBUkM0Q29udHJhY3QpOgogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgYnRvaQogICAgdHhuYXMgQWNjb3VudHMKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTozMwogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X2FjY3RfdG90YWxfbnVtX3VpbnQKICAgIGl0b2IKICAgIGJ5dGUgMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludCAxCiAgICByZXR1cm4KCm1haW5fdmVyaWZ5X2FjY3RfdG90YWxfbnVtX2J5dGVfc2xpY2Vfcm91dGVANjoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTozOAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBpcyBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weToxNwogICAgLy8gY2xhc3MgU3RhdGVBY2N0UGFyYW1zR2V0Q29udHJhY3QoQVJDNENvbnRyYWN0KToKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGJ0b2kKICAgIHR4bmFzIEFjY291bnRzCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6MzgKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV9hY2N0X3RvdGFsX251bV9ieXRlX3NsaWNlCiAgICBpdG9iCiAgICBieXRlIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnQgMQogICAgcmV0dXJuCgptYWluX3ZlcmlmeV9hY2N0X3RvdGFsX2V4dHJhX2FwcF9wYWdlc19yb3V0ZUA3OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjQzCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGlzIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjE3CiAgICAvLyBjbGFzcyBTdGF0ZUFjY3RQYXJhbXNHZXRDb250cmFjdChBUkM0Q29udHJhY3QpOgogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgYnRvaQogICAgdHhuYXMgQWNjb3VudHMKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTo0MwogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X2FjY3RfdG90YWxfZXh0cmFfYXBwX3BhZ2VzCiAgICBpdG9iCiAgICBieXRlIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnQgMQogICAgcmV0dXJuCgptYWluX3ZlcmlmeV9hY2N0X3RvdGFsX2FwcHNfY3JlYXRlZF9yb3V0ZUA4OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjQ4CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGlzIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjE3CiAgICAvLyBjbGFzcyBTdGF0ZUFjY3RQYXJhbXNHZXRDb250cmFjdChBUkM0Q29udHJhY3QpOgogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgYnRvaQogICAgdHhuYXMgQWNjb3VudHMKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTo0OAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X2FjY3RfdG90YWxfYXBwc19jcmVhdGVkCiAgICBpdG9iCiAgICBieXRlIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnQgMQogICAgcmV0dXJuCgptYWluX3ZlcmlmeV9hY2N0X3RvdGFsX2FwcHNfb3B0ZWRfaW5fcm91dGVAOToKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTo1MwogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBpcyBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weToxNwogICAgLy8gY2xhc3MgU3RhdGVBY2N0UGFyYW1zR2V0Q29udHJhY3QoQVJDNENvbnRyYWN0KToKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGJ0b2kKICAgIHR4bmFzIEFjY291bnRzCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6NTMKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV9hY2N0X3RvdGFsX2FwcHNfb3B0ZWRfaW4KICAgIGl0b2IKICAgIGJ5dGUgMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludCAxCiAgICByZXR1cm4KCm1haW5fdmVyaWZ5X2FjY3RfdG90YWxfYXNzZXRzX2NyZWF0ZWRfcm91dGVAMTA6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6NTgKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gaXMgbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6MTcKICAgIC8vIGNsYXNzIFN0YXRlQWNjdFBhcmFtc0dldENvbnRyYWN0KEFSQzRDb250cmFjdCk6CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBidG9pCiAgICB0eG5hcyBBY2NvdW50cwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjU4CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfYWNjdF90b3RhbF9hc3NldHNfY3JlYXRlZAogICAgaXRvYgogICAgYnl0ZSAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50IDEKICAgIHJldHVybgoKbWFpbl92ZXJpZnlfYWNjdF90b3RhbF9hc3NldHNfcm91dGVAMTE6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6NjMKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gaXMgbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6MTcKICAgIC8vIGNsYXNzIFN0YXRlQWNjdFBhcmFtc0dldENvbnRyYWN0KEFSQzRDb250cmFjdCk6CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBidG9pCiAgICB0eG5hcyBBY2NvdW50cwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjYzCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfYWNjdF90b3RhbF9hc3NldHMKICAgIGl0b2IKICAgIGJ5dGUgMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludCAxCiAgICByZXR1cm4KCm1haW5fdmVyaWZ5X2FjY3RfdG90YWxfYm94ZXNfcm91dGVAMTI6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6NjgKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gaXMgbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6MTcKICAgIC8vIGNsYXNzIFN0YXRlQWNjdFBhcmFtc0dldENvbnRyYWN0KEFSQzRDb250cmFjdCk6CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBidG9pCiAgICB0eG5hcyBBY2NvdW50cwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjY4CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfYWNjdF90b3RhbF9ib3hlcwogICAgaXRvYgogICAgYnl0ZSAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50IDEKICAgIHJldHVybgoKbWFpbl92ZXJpZnlfYWNjdF90b3RhbF9ib3hfYnl0ZXNfcm91dGVAMTM6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6NzMKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gaXMgbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6MTcKICAgIC8vIGNsYXNzIFN0YXRlQWNjdFBhcmFtc0dldENvbnRyYWN0KEFSQzRDb250cmFjdCk6CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBidG9pCiAgICB0eG5hcyBBY2NvdW50cwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjczCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfYWNjdF90b3RhbF9ib3hfYnl0ZXMKICAgIGl0b2IKICAgIGJ5dGUgMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludCAxCiAgICByZXR1cm4KCm1haW5fYmFyZV9yb3V0aW5nQDE2OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjE3CiAgICAvLyBjbGFzcyBTdGF0ZUFjY3RQYXJhbXNHZXRDb250cmFjdChBUkM0Q29udHJhY3QpOgogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIHJlamVjdCB0cmFuc2FjdGlvbgogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgICEKICAgIGFzc2VydCAvLyBpcyBjcmVhdGluZwogICAgaW50IDEKICAgIHJldHVybgoKCi8vIHRlc3RzLmFydGlmYWN0cy5TdGF0ZU9wcy5jb250cmFjdC5TdGF0ZUFjY3RQYXJhbXNHZXRDb250cmFjdC52ZXJpZnlfYWNjdF9iYWxhbmNlKGE6IGJ5dGVzKSAtPiB1aW50NjQ6CnZlcmlmeV9hY2N0X2JhbGFuY2U6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6MTgtMTkKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBkZWYgdmVyaWZ5X2FjY3RfYmFsYW5jZShzZWxmLCBhOiBhbGdvcHkuQWNjb3VudCkgLT4gYWxnb3B5LlVJbnQ2NDoKICAgIHByb3RvIDEgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjIwCiAgICAvLyBiYWxhbmNlLCBfdmFsID0gb3AuQWNjdFBhcmFtc0dldC5hY2N0X2JhbGFuY2UoYSkKICAgIGZyYW1lX2RpZyAtMQogICAgYWNjdF9wYXJhbXNfZ2V0IEFjY3RCYWxhbmNlCiAgICBwb3AKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weToyMQogICAgLy8gcmV0dXJuIGJhbGFuY2UKICAgIHJldHN1YgoKCi8vIHRlc3RzLmFydGlmYWN0cy5TdGF0ZU9wcy5jb250cmFjdC5TdGF0ZUFjY3RQYXJhbXNHZXRDb250cmFjdC52ZXJpZnlfYWNjdF9taW5fYmFsYW5jZShhOiBieXRlcykgLT4gdWludDY0Ogp2ZXJpZnlfYWNjdF9taW5fYmFsYW5jZToKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weToyMy0yNAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIGRlZiB2ZXJpZnlfYWNjdF9taW5fYmFsYW5jZShzZWxmLCBhOiBhbGdvcHkuQWNjb3VudCkgLT4gYWxnb3B5LlVJbnQ2NDoKICAgIHByb3RvIDEgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjI1CiAgICAvLyBtaW5fYmFsYW5jZSwgX3ZhbCA9IG9wLkFjY3RQYXJhbXNHZXQuYWNjdF9taW5fYmFsYW5jZShhKQogICAgZnJhbWVfZGlnIC0xCiAgICBhY2N0X3BhcmFtc19nZXQgQWNjdE1pbkJhbGFuY2UKICAgIHBvcAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjI2CiAgICAvLyByZXR1cm4gbWluX2JhbGFuY2UKICAgIHJldHN1YgoKCi8vIHRlc3RzLmFydGlmYWN0cy5TdGF0ZU9wcy5jb250cmFjdC5TdGF0ZUFjY3RQYXJhbXNHZXRDb250cmFjdC52ZXJpZnlfYWNjdF9hdXRoX2FkZHIoYTogYnl0ZXMpIC0+IGJ5dGVzOgp2ZXJpZnlfYWNjdF9hdXRoX2FkZHI6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6MjgtMjkKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBkZWYgdmVyaWZ5X2FjY3RfYXV0aF9hZGRyKHNlbGYsIGE6IGFsZ29weS5BY2NvdW50KSAtPiBhbGdvcHkuQnl0ZXM6CiAgICBwcm90byAxIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTozMAogICAgLy8gYXV0aF9hZGRyLCBfdmFsID0gb3AuQWNjdFBhcmFtc0dldC5hY2N0X2F1dGhfYWRkcihhKQogICAgZnJhbWVfZGlnIC0xCiAgICBhY2N0X3BhcmFtc19nZXQgQWNjdEF1dGhBZGRyCiAgICBwb3AKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTozMQogICAgLy8gcmV0dXJuIGF1dGhfYWRkci5ieXRlcwogICAgcmV0c3ViCgoKLy8gdGVzdHMuYXJ0aWZhY3RzLlN0YXRlT3BzLmNvbnRyYWN0LlN0YXRlQWNjdFBhcmFtc0dldENvbnRyYWN0LnZlcmlmeV9hY2N0X3RvdGFsX251bV91aW50KGE6IGJ5dGVzKSAtPiB1aW50NjQ6CnZlcmlmeV9hY2N0X3RvdGFsX251bV91aW50OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjMzLTM0CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gZGVmIHZlcmlmeV9hY2N0X3RvdGFsX251bV91aW50KHNlbGYsIGE6IGFsZ29weS5BY2NvdW50KSAtPiBhbGdvcHkuVUludDY0OgogICAgcHJvdG8gMSAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6MzUKICAgIC8vIHRvdGFsX251bV91aW50LCBfdmFsID0gb3AuQWNjdFBhcmFtc0dldC5hY2N0X3RvdGFsX251bV91aW50KGEpCiAgICBmcmFtZV9kaWcgLTEKICAgIGFjY3RfcGFyYW1zX2dldCBBY2N0VG90YWxOdW1VaW50CiAgICBwb3AKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTozNgogICAgLy8gcmV0dXJuIHRvdGFsX251bV91aW50CiAgICByZXRzdWIKCgovLyB0ZXN0cy5hcnRpZmFjdHMuU3RhdGVPcHMuY29udHJhY3QuU3RhdGVBY2N0UGFyYW1zR2V0Q29udHJhY3QudmVyaWZ5X2FjY3RfdG90YWxfbnVtX2J5dGVfc2xpY2UoYTogYnl0ZXMpIC0+IHVpbnQ2NDoKdmVyaWZ5X2FjY3RfdG90YWxfbnVtX2J5dGVfc2xpY2U6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6MzgtMzkKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBkZWYgdmVyaWZ5X2FjY3RfdG90YWxfbnVtX2J5dGVfc2xpY2Uoc2VsZiwgYTogYWxnb3B5LkFjY291bnQpIC0+IGFsZ29weS5VSW50NjQ6CiAgICBwcm90byAxIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTo0MAogICAgLy8gdG90YWxfbnVtX2J5dGVfc2xpY2UsIF92YWwgPSBvcC5BY2N0UGFyYW1zR2V0LmFjY3RfdG90YWxfbnVtX2J5dGVfc2xpY2UoYSkKICAgIGZyYW1lX2RpZyAtMQogICAgYWNjdF9wYXJhbXNfZ2V0IEFjY3RUb3RhbE51bUJ5dGVTbGljZQogICAgcG9wCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6NDEKICAgIC8vIHJldHVybiB0b3RhbF9udW1fYnl0ZV9zbGljZQogICAgcmV0c3ViCgoKLy8gdGVzdHMuYXJ0aWZhY3RzLlN0YXRlT3BzLmNvbnRyYWN0LlN0YXRlQWNjdFBhcmFtc0dldENvbnRyYWN0LnZlcmlmeV9hY2N0X3RvdGFsX2V4dHJhX2FwcF9wYWdlcyhhOiBieXRlcykgLT4gdWludDY0Ogp2ZXJpZnlfYWNjdF90b3RhbF9leHRyYV9hcHBfcGFnZXM6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6NDMtNDQKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBkZWYgdmVyaWZ5X2FjY3RfdG90YWxfZXh0cmFfYXBwX3BhZ2VzKHNlbGYsIGE6IGFsZ29weS5BY2NvdW50KSAtPiBhbGdvcHkuVUludDY0OgogICAgcHJvdG8gMSAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6NDUKICAgIC8vIHRvdGFsX2V4dHJhX2FwcF9wYWdlcywgX3ZhbCA9IG9wLkFjY3RQYXJhbXNHZXQuYWNjdF90b3RhbF9leHRyYV9hcHBfcGFnZXMoYSkKICAgIGZyYW1lX2RpZyAtMQogICAgYWNjdF9wYXJhbXNfZ2V0IEFjY3RUb3RhbEV4dHJhQXBwUGFnZXMKICAgIHBvcAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjQ2CiAgICAvLyByZXR1cm4gdG90YWxfZXh0cmFfYXBwX3BhZ2VzCiAgICByZXRzdWIKCgovLyB0ZXN0cy5hcnRpZmFjdHMuU3RhdGVPcHMuY29udHJhY3QuU3RhdGVBY2N0UGFyYW1zR2V0Q29udHJhY3QudmVyaWZ5X2FjY3RfdG90YWxfYXBwc19jcmVhdGVkKGE6IGJ5dGVzKSAtPiB1aW50NjQ6CnZlcmlmeV9hY2N0X3RvdGFsX2FwcHNfY3JlYXRlZDoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTo0OC00OQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIGRlZiB2ZXJpZnlfYWNjdF90b3RhbF9hcHBzX2NyZWF0ZWQoc2VsZiwgYTogYWxnb3B5LkFjY291bnQpIC0+IGFsZ29weS5VSW50NjQ6CiAgICBwcm90byAxIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTo1MAogICAgLy8gdG90YWxfYXBwc19jcmVhdGVkLCBfdmFsID0gb3AuQWNjdFBhcmFtc0dldC5hY2N0X3RvdGFsX2FwcHNfY3JlYXRlZChhKQogICAgZnJhbWVfZGlnIC0xCiAgICBhY2N0X3BhcmFtc19nZXQgQWNjdFRvdGFsQXBwc0NyZWF0ZWQKICAgIHBvcAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjUxCiAgICAvLyByZXR1cm4gdG90YWxfYXBwc19jcmVhdGVkCiAgICByZXRzdWIKCgovLyB0ZXN0cy5hcnRpZmFjdHMuU3RhdGVPcHMuY29udHJhY3QuU3RhdGVBY2N0UGFyYW1zR2V0Q29udHJhY3QudmVyaWZ5X2FjY3RfdG90YWxfYXBwc19vcHRlZF9pbihhOiBieXRlcykgLT4gdWludDY0Ogp2ZXJpZnlfYWNjdF90b3RhbF9hcHBzX29wdGVkX2luOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjUzLTU0CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gZGVmIHZlcmlmeV9hY2N0X3RvdGFsX2FwcHNfb3B0ZWRfaW4oc2VsZiwgYTogYWxnb3B5LkFjY291bnQpIC0+IGFsZ29weS5VSW50NjQ6CiAgICBwcm90byAxIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTo1NQogICAgLy8gdG90YWxfYXBwc19vcHRlZF9pbiwgX3ZhbCA9IG9wLkFjY3RQYXJhbXNHZXQuYWNjdF90b3RhbF9hcHBzX29wdGVkX2luKGEpCiAgICBmcmFtZV9kaWcgLTEKICAgIGFjY3RfcGFyYW1zX2dldCBBY2N0VG90YWxBcHBzT3B0ZWRJbgogICAgcG9wCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6NTYKICAgIC8vIHJldHVybiB0b3RhbF9hcHBzX29wdGVkX2luCiAgICByZXRzdWIKCgovLyB0ZXN0cy5hcnRpZmFjdHMuU3RhdGVPcHMuY29udHJhY3QuU3RhdGVBY2N0UGFyYW1zR2V0Q29udHJhY3QudmVyaWZ5X2FjY3RfdG90YWxfYXNzZXRzX2NyZWF0ZWQoYTogYnl0ZXMpIC0+IHVpbnQ2NDoKdmVyaWZ5X2FjY3RfdG90YWxfYXNzZXRzX2NyZWF0ZWQ6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6NTgtNTkKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBkZWYgdmVyaWZ5X2FjY3RfdG90YWxfYXNzZXRzX2NyZWF0ZWQoc2VsZiwgYTogYWxnb3B5LkFjY291bnQpIC0+IGFsZ29weS5VSW50NjQ6CiAgICBwcm90byAxIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTo2MAogICAgLy8gdG90YWxfYXNzZXRzX2NyZWF0ZWQsIF92YWwgPSBvcC5BY2N0UGFyYW1zR2V0LmFjY3RfdG90YWxfYXNzZXRzX2NyZWF0ZWQoYSkKICAgIGZyYW1lX2RpZyAtMQogICAgYWNjdF9wYXJhbXNfZ2V0IEFjY3RUb3RhbEFzc2V0c0NyZWF0ZWQKICAgIHBvcAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjYxCiAgICAvLyByZXR1cm4gdG90YWxfYXNzZXRzX2NyZWF0ZWQKICAgIHJldHN1YgoKCi8vIHRlc3RzLmFydGlmYWN0cy5TdGF0ZU9wcy5jb250cmFjdC5TdGF0ZUFjY3RQYXJhbXNHZXRDb250cmFjdC52ZXJpZnlfYWNjdF90b3RhbF9hc3NldHMoYTogYnl0ZXMpIC0+IHVpbnQ2NDoKdmVyaWZ5X2FjY3RfdG90YWxfYXNzZXRzOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjYzLTY0CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gZGVmIHZlcmlmeV9hY2N0X3RvdGFsX2Fzc2V0cyhzZWxmLCBhOiBhbGdvcHkuQWNjb3VudCkgLT4gYWxnb3B5LlVJbnQ2NDoKICAgIHByb3RvIDEgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjY1CiAgICAvLyB0b3RhbF9hc3NldHMsIF92YWwgPSBvcC5BY2N0UGFyYW1zR2V0LmFjY3RfdG90YWxfYXNzZXRzKGEpCiAgICBmcmFtZV9kaWcgLTEKICAgIGFjY3RfcGFyYW1zX2dldCBBY2N0VG90YWxBc3NldHMKICAgIHBvcAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjY2CiAgICAvLyByZXR1cm4gdG90YWxfYXNzZXRzCiAgICByZXRzdWIKCgovLyB0ZXN0cy5hcnRpZmFjdHMuU3RhdGVPcHMuY29udHJhY3QuU3RhdGVBY2N0UGFyYW1zR2V0Q29udHJhY3QudmVyaWZ5X2FjY3RfdG90YWxfYm94ZXMoYTogYnl0ZXMpIC0+IHVpbnQ2NDoKdmVyaWZ5X2FjY3RfdG90YWxfYm94ZXM6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6NjgtNjkKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBkZWYgdmVyaWZ5X2FjY3RfdG90YWxfYm94ZXMoc2VsZiwgYTogYWxnb3B5LkFjY291bnQpIC0+IGFsZ29weS5VSW50NjQ6CiAgICBwcm90byAxIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTo3MAogICAgLy8gdG90YWxfYm94ZXMsIF92YWwgPSBvcC5BY2N0UGFyYW1zR2V0LmFjY3RfdG90YWxfYm94ZXMoYSkKICAgIGZyYW1lX2RpZyAtMQogICAgYWNjdF9wYXJhbXNfZ2V0IEFjY3RUb3RhbEJveGVzCiAgICBwb3AKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTo3MQogICAgLy8gcmV0dXJuIHRvdGFsX2JveGVzCiAgICByZXRzdWIKCgovLyB0ZXN0cy5hcnRpZmFjdHMuU3RhdGVPcHMuY29udHJhY3QuU3RhdGVBY2N0UGFyYW1zR2V0Q29udHJhY3QudmVyaWZ5X2FjY3RfdG90YWxfYm94X2J5dGVzKGE6IGJ5dGVzKSAtPiB1aW50NjQ6CnZlcmlmeV9hY2N0X3RvdGFsX2JveF9ieXRlczoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTo3My03NAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIGRlZiB2ZXJpZnlfYWNjdF90b3RhbF9ib3hfYnl0ZXMoc2VsZiwgYTogYWxnb3B5LkFjY291bnQpIC0+IGFsZ29weS5VSW50NjQ6CiAgICBwcm90byAxIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTo3NQogICAgLy8gdG90YWxfYm94X2J5dGVzLCBfdmFsID0gb3AuQWNjdFBhcmFtc0dldC5hY2N0X3RvdGFsX2JveF9ieXRlcyhhKQogICAgZnJhbWVfZGlnIC0xCiAgICBhY2N0X3BhcmFtc19nZXQgQWNjdFRvdGFsQm94Qnl0ZXMKICAgIHBvcAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5Ojc2CiAgICAvLyByZXR1cm4gdG90YWxfYm94X2J5dGVzCiAgICByZXRzdWIK", - "clear": "I3ByYWdtYSB2ZXJzaW9uIDEwCgp0ZXN0cy5hcnRpZmFjdHMuU3RhdGVPcHMuY29udHJhY3QuU3RhdGVBY2N0UGFyYW1zR2V0Q29udHJhY3QuY2xlYXJfc3RhdGVfcHJvZ3JhbToKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weToxNwogICAgLy8gY2xhc3MgU3RhdGVBY2N0UGFyYW1zR2V0Q29udHJhY3QoQVJDNENvbnRyYWN0KToKICAgIGludCAxCiAgICByZXR1cm4K" + "approval": "I3ByYWdtYSB2ZXJzaW9uIDEwCgp0ZXN0cy5hcnRpZmFjdHMuU3RhdGVPcHMuY29udHJhY3QuU3RhdGVBY2N0UGFyYW1zR2V0Q29udHJhY3QuYXBwcm92YWxfcHJvZ3JhbToKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weToyNAogICAgLy8gY2xhc3MgU3RhdGVBY2N0UGFyYW1zR2V0Q29udHJhY3QoQVJDNENvbnRyYWN0KToKICAgIHR4biBOdW1BcHBBcmdzCiAgICBieiBtYWluX2JhcmVfcm91dGluZ0AxNgogICAgbWV0aG9kICJ2ZXJpZnlfYWNjdF9iYWxhbmNlKGFjY291bnQpdWludDY0IgogICAgbWV0aG9kICJ2ZXJpZnlfYWNjdF9taW5fYmFsYW5jZShhY2NvdW50KXVpbnQ2NCIKICAgIG1ldGhvZCAidmVyaWZ5X2FjY3RfYXV0aF9hZGRyKGFjY291bnQpYWRkcmVzcyIKICAgIG1ldGhvZCAidmVyaWZ5X2FjY3RfdG90YWxfbnVtX3VpbnQoYWNjb3VudCl1aW50NjQiCiAgICBtZXRob2QgInZlcmlmeV9hY2N0X3RvdGFsX251bV9ieXRlX3NsaWNlKGFjY291bnQpdWludDY0IgogICAgbWV0aG9kICJ2ZXJpZnlfYWNjdF90b3RhbF9leHRyYV9hcHBfcGFnZXMoYWNjb3VudCl1aW50NjQiCiAgICBtZXRob2QgInZlcmlmeV9hY2N0X3RvdGFsX2FwcHNfY3JlYXRlZChhY2NvdW50KXVpbnQ2NCIKICAgIG1ldGhvZCAidmVyaWZ5X2FjY3RfdG90YWxfYXBwc19vcHRlZF9pbihhY2NvdW50KXVpbnQ2NCIKICAgIG1ldGhvZCAidmVyaWZ5X2FjY3RfdG90YWxfYXNzZXRzX2NyZWF0ZWQoYWNjb3VudCl1aW50NjQiCiAgICBtZXRob2QgInZlcmlmeV9hY2N0X3RvdGFsX2Fzc2V0cyhhY2NvdW50KXVpbnQ2NCIKICAgIG1ldGhvZCAidmVyaWZ5X2FjY3RfdG90YWxfYm94ZXMoYWNjb3VudCl1aW50NjQiCiAgICBtZXRob2QgInZlcmlmeV9hY2N0X3RvdGFsX2JveF9ieXRlcyhhY2NvdW50KXVpbnQ2NCIKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDAKICAgIG1hdGNoIG1haW5fdmVyaWZ5X2FjY3RfYmFsYW5jZV9yb3V0ZUAyIG1haW5fdmVyaWZ5X2FjY3RfbWluX2JhbGFuY2Vfcm91dGVAMyBtYWluX3ZlcmlmeV9hY2N0X2F1dGhfYWRkcl9yb3V0ZUA0IG1haW5fdmVyaWZ5X2FjY3RfdG90YWxfbnVtX3VpbnRfcm91dGVANSBtYWluX3ZlcmlmeV9hY2N0X3RvdGFsX251bV9ieXRlX3NsaWNlX3JvdXRlQDYgbWFpbl92ZXJpZnlfYWNjdF90b3RhbF9leHRyYV9hcHBfcGFnZXNfcm91dGVANyBtYWluX3ZlcmlmeV9hY2N0X3RvdGFsX2FwcHNfY3JlYXRlZF9yb3V0ZUA4IG1haW5fdmVyaWZ5X2FjY3RfdG90YWxfYXBwc19vcHRlZF9pbl9yb3V0ZUA5IG1haW5fdmVyaWZ5X2FjY3RfdG90YWxfYXNzZXRzX2NyZWF0ZWRfcm91dGVAMTAgbWFpbl92ZXJpZnlfYWNjdF90b3RhbF9hc3NldHNfcm91dGVAMTEgbWFpbl92ZXJpZnlfYWNjdF90b3RhbF9ib3hlc19yb3V0ZUAxMiBtYWluX3ZlcmlmeV9hY2N0X3RvdGFsX2JveF9ieXRlc19yb3V0ZUAxMwogICAgZXJyIC8vIHJlamVjdCB0cmFuc2FjdGlvbgoKbWFpbl92ZXJpZnlfYWNjdF9iYWxhbmNlX3JvdXRlQDI6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6MjUKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gaXMgbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6MjQKICAgIC8vIGNsYXNzIFN0YXRlQWNjdFBhcmFtc0dldENvbnRyYWN0KEFSQzRDb250cmFjdCk6CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBidG9pCiAgICB0eG5hcyBBY2NvdW50cwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjI1CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfYWNjdF9iYWxhbmNlCiAgICBpdG9iCiAgICBieXRlIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnQgMQogICAgcmV0dXJuCgptYWluX3ZlcmlmeV9hY2N0X21pbl9iYWxhbmNlX3JvdXRlQDM6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6MzMKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gaXMgbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6MjQKICAgIC8vIGNsYXNzIFN0YXRlQWNjdFBhcmFtc0dldENvbnRyYWN0KEFSQzRDb250cmFjdCk6CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBidG9pCiAgICB0eG5hcyBBY2NvdW50cwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjMzCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfYWNjdF9taW5fYmFsYW5jZQogICAgaXRvYgogICAgYnl0ZSAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50IDEKICAgIHJldHVybgoKbWFpbl92ZXJpZnlfYWNjdF9hdXRoX2FkZHJfcm91dGVANDoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTo0MQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBpcyBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weToyNAogICAgLy8gY2xhc3MgU3RhdGVBY2N0UGFyYW1zR2V0Q29udHJhY3QoQVJDNENvbnRyYWN0KToKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGJ0b2kKICAgIHR4bmFzIEFjY291bnRzCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6NDEKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV9hY2N0X2F1dGhfYWRkcgogICAgYnl0ZSAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50IDEKICAgIHJldHVybgoKbWFpbl92ZXJpZnlfYWNjdF90b3RhbF9udW1fdWludF9yb3V0ZUA1OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjQ5CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGlzIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjI0CiAgICAvLyBjbGFzcyBTdGF0ZUFjY3RQYXJhbXNHZXRDb250cmFjdChBUkM0Q29udHJhY3QpOgogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgYnRvaQogICAgdHhuYXMgQWNjb3VudHMKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTo0OQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X2FjY3RfdG90YWxfbnVtX3VpbnQKICAgIGl0b2IKICAgIGJ5dGUgMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludCAxCiAgICByZXR1cm4KCm1haW5fdmVyaWZ5X2FjY3RfdG90YWxfbnVtX2J5dGVfc2xpY2Vfcm91dGVANjoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTo1NwogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBpcyBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weToyNAogICAgLy8gY2xhc3MgU3RhdGVBY2N0UGFyYW1zR2V0Q29udHJhY3QoQVJDNENvbnRyYWN0KToKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGJ0b2kKICAgIHR4bmFzIEFjY291bnRzCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6NTcKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV9hY2N0X3RvdGFsX251bV9ieXRlX3NsaWNlCiAgICBpdG9iCiAgICBieXRlIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnQgMQogICAgcmV0dXJuCgptYWluX3ZlcmlmeV9hY2N0X3RvdGFsX2V4dHJhX2FwcF9wYWdlc19yb3V0ZUA3OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjY3CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGlzIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjI0CiAgICAvLyBjbGFzcyBTdGF0ZUFjY3RQYXJhbXNHZXRDb250cmFjdChBUkM0Q29udHJhY3QpOgogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgYnRvaQogICAgdHhuYXMgQWNjb3VudHMKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTo2NwogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X2FjY3RfdG90YWxfZXh0cmFfYXBwX3BhZ2VzCiAgICBpdG9iCiAgICBieXRlIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnQgMQogICAgcmV0dXJuCgptYWluX3ZlcmlmeV9hY2N0X3RvdGFsX2FwcHNfY3JlYXRlZF9yb3V0ZUA4OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5Ojc3CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGlzIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjI0CiAgICAvLyBjbGFzcyBTdGF0ZUFjY3RQYXJhbXNHZXRDb250cmFjdChBUkM0Q29udHJhY3QpOgogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgYnRvaQogICAgdHhuYXMgQWNjb3VudHMKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTo3NwogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X2FjY3RfdG90YWxfYXBwc19jcmVhdGVkCiAgICBpdG9iCiAgICBieXRlIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnQgMQogICAgcmV0dXJuCgptYWluX3ZlcmlmeV9hY2N0X3RvdGFsX2FwcHNfb3B0ZWRfaW5fcm91dGVAOToKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTo4NQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBpcyBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weToyNAogICAgLy8gY2xhc3MgU3RhdGVBY2N0UGFyYW1zR2V0Q29udHJhY3QoQVJDNENvbnRyYWN0KToKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGJ0b2kKICAgIHR4bmFzIEFjY291bnRzCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6ODUKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV9hY2N0X3RvdGFsX2FwcHNfb3B0ZWRfaW4KICAgIGl0b2IKICAgIGJ5dGUgMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludCAxCiAgICByZXR1cm4KCm1haW5fdmVyaWZ5X2FjY3RfdG90YWxfYXNzZXRzX2NyZWF0ZWRfcm91dGVAMTA6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6OTMKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gaXMgbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6MjQKICAgIC8vIGNsYXNzIFN0YXRlQWNjdFBhcmFtc0dldENvbnRyYWN0KEFSQzRDb250cmFjdCk6CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBidG9pCiAgICB0eG5hcyBBY2NvdW50cwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjkzCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfYWNjdF90b3RhbF9hc3NldHNfY3JlYXRlZAogICAgaXRvYgogICAgYnl0ZSAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50IDEKICAgIHJldHVybgoKbWFpbl92ZXJpZnlfYWNjdF90b3RhbF9hc3NldHNfcm91dGVAMTE6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6MTAzCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGlzIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjI0CiAgICAvLyBjbGFzcyBTdGF0ZUFjY3RQYXJhbXNHZXRDb250cmFjdChBUkM0Q29udHJhY3QpOgogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgYnRvaQogICAgdHhuYXMgQWNjb3VudHMKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weToxMDMKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV9hY2N0X3RvdGFsX2Fzc2V0cwogICAgaXRvYgogICAgYnl0ZSAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50IDEKICAgIHJldHVybgoKbWFpbl92ZXJpZnlfYWNjdF90b3RhbF9ib3hlc19yb3V0ZUAxMjoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weToxMTEKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gaXMgbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6MjQKICAgIC8vIGNsYXNzIFN0YXRlQWNjdFBhcmFtc0dldENvbnRyYWN0KEFSQzRDb250cmFjdCk6CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBidG9pCiAgICB0eG5hcyBBY2NvdW50cwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjExMQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X2FjY3RfdG90YWxfYm94ZXMKICAgIGl0b2IKICAgIGJ5dGUgMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludCAxCiAgICByZXR1cm4KCm1haW5fdmVyaWZ5X2FjY3RfdG90YWxfYm94X2J5dGVzX3JvdXRlQDEzOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjExOQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBpcyBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weToyNAogICAgLy8gY2xhc3MgU3RhdGVBY2N0UGFyYW1zR2V0Q29udHJhY3QoQVJDNENvbnRyYWN0KToKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGJ0b2kKICAgIHR4bmFzIEFjY291bnRzCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6MTE5CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfYWNjdF90b3RhbF9ib3hfYnl0ZXMKICAgIGl0b2IKICAgIGJ5dGUgMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludCAxCiAgICByZXR1cm4KCm1haW5fYmFyZV9yb3V0aW5nQDE2OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjI0CiAgICAvLyBjbGFzcyBTdGF0ZUFjY3RQYXJhbXNHZXRDb250cmFjdChBUkM0Q29udHJhY3QpOgogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIHJlamVjdCB0cmFuc2FjdGlvbgogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgICEKICAgIGFzc2VydCAvLyBpcyBjcmVhdGluZwogICAgaW50IDEKICAgIHJldHVybgoKCi8vIHRlc3RzLmFydGlmYWN0cy5TdGF0ZU9wcy5jb250cmFjdC5TdGF0ZUFjY3RQYXJhbXNHZXRDb250cmFjdC52ZXJpZnlfYWNjdF9iYWxhbmNlKGE6IGJ5dGVzKSAtPiB1aW50NjQ6CnZlcmlmeV9hY2N0X2JhbGFuY2U6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6MjUtMjYKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBkZWYgdmVyaWZ5X2FjY3RfYmFsYW5jZShzZWxmLCBhOiBhbGdvcHkuQWNjb3VudCkgLT4gYWxnb3B5LlVJbnQ2NDoKICAgIHByb3RvIDEgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjI3CiAgICAvLyB2YWx1ZSwgZnVuZGVkID0gb3AuQWNjdFBhcmFtc0dldC5hY2N0X2JhbGFuY2UoYSkKICAgIGZyYW1lX2RpZyAtMQogICAgYWNjdF9wYXJhbXNfZ2V0IEFjY3RCYWxhbmNlCiAgICBzd2FwCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6MjgKICAgIC8vIHZhbHVlX2luZGV4LCBmdW5kZWRfaW5kZXggPSBvcC5BY2N0UGFyYW1zR2V0LmFjY3RfYmFsYW5jZShfZ2V0XzFzdF9yZWZfaW5kZXgoKSkKICAgIGNhbGxzdWIgX2dldF8xc3RfcmVmX2luZGV4CiAgICBhY2N0X3BhcmFtc19nZXQgQWNjdEJhbGFuY2UKICAgIGNvdmVyIDIKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weToyOQogICAgLy8gYXNzZXJ0IHZhbHVlID09IHZhbHVlX2luZGV4LCAiZXhwZWN0ZWQgdmFsdWUgYnkgaW5kZXggdG8gbWF0Y2giCiAgICBkaWcgMQogICAgPT0KICAgIGFzc2VydCAvLyBleHBlY3RlZCB2YWx1ZSBieSBpbmRleCB0byBtYXRjaAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjMwCiAgICAvLyBhc3NlcnQgZnVuZGVkID09IGZ1bmRlZF9pbmRleCwgImV4cGVjdGVkIGZ1bmRlZCBieSBpbmRleCB0byBtYXRjaCIKICAgIGNvdmVyIDIKICAgID09CiAgICBhc3NlcnQgLy8gZXhwZWN0ZWQgZnVuZGVkIGJ5IGluZGV4IHRvIG1hdGNoCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6MzEKICAgIC8vIHJldHVybiB2YWx1ZQogICAgcmV0c3ViCgoKLy8gdGVzdHMuYXJ0aWZhY3RzLlN0YXRlT3BzLmNvbnRyYWN0Ll9nZXRfMXN0X3JlZl9pbmRleCgpIC0+IHVpbnQ2NDoKX2dldF8xc3RfcmVmX2luZGV4OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjE5LTIwCiAgICAvLyBAc3Vicm91dGluZQogICAgLy8gZGVmIF9nZXRfMXN0X3JlZl9pbmRleCgpIC0+IFVJbnQ2NDoKICAgIHByb3RvIDAgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjIxCiAgICAvLyByZXR1cm4gb3AuYnRvaShUeG4uYXBwbGljYXRpb25fYXJncygxKSkKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGJ0b2kKICAgIHJldHN1YgoKCi8vIHRlc3RzLmFydGlmYWN0cy5TdGF0ZU9wcy5jb250cmFjdC5TdGF0ZUFjY3RQYXJhbXNHZXRDb250cmFjdC52ZXJpZnlfYWNjdF9taW5fYmFsYW5jZShhOiBieXRlcykgLT4gdWludDY0Ogp2ZXJpZnlfYWNjdF9taW5fYmFsYW5jZToKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTozMy0zNAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIGRlZiB2ZXJpZnlfYWNjdF9taW5fYmFsYW5jZShzZWxmLCBhOiBhbGdvcHkuQWNjb3VudCkgLT4gYWxnb3B5LlVJbnQ2NDoKICAgIHByb3RvIDEgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjM1CiAgICAvLyB2YWx1ZSwgZnVuZGVkID0gb3AuQWNjdFBhcmFtc0dldC5hY2N0X21pbl9iYWxhbmNlKGEpCiAgICBmcmFtZV9kaWcgLTEKICAgIGFjY3RfcGFyYW1zX2dldCBBY2N0TWluQmFsYW5jZQogICAgc3dhcAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjM2CiAgICAvLyB2YWx1ZV9pbmRleCwgZnVuZGVkX2luZGV4ID0gb3AuQWNjdFBhcmFtc0dldC5hY2N0X21pbl9iYWxhbmNlKF9nZXRfMXN0X3JlZl9pbmRleCgpKQogICAgY2FsbHN1YiBfZ2V0XzFzdF9yZWZfaW5kZXgKICAgIGFjY3RfcGFyYW1zX2dldCBBY2N0TWluQmFsYW5jZQogICAgY292ZXIgMgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjM3CiAgICAvLyBhc3NlcnQgdmFsdWUgPT0gdmFsdWVfaW5kZXgsICJleHBlY3RlZCB2YWx1ZSBieSBpbmRleCB0byBtYXRjaCIKICAgIGRpZyAxCiAgICA9PQogICAgYXNzZXJ0IC8vIGV4cGVjdGVkIHZhbHVlIGJ5IGluZGV4IHRvIG1hdGNoCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6MzgKICAgIC8vIGFzc2VydCBmdW5kZWQgPT0gZnVuZGVkX2luZGV4LCAiZXhwZWN0ZWQgZnVuZGVkIGJ5IGluZGV4IHRvIG1hdGNoIgogICAgY292ZXIgMgogICAgPT0KICAgIGFzc2VydCAvLyBleHBlY3RlZCBmdW5kZWQgYnkgaW5kZXggdG8gbWF0Y2gKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTozOQogICAgLy8gcmV0dXJuIHZhbHVlCiAgICByZXRzdWIKCgovLyB0ZXN0cy5hcnRpZmFjdHMuU3RhdGVPcHMuY29udHJhY3QuU3RhdGVBY2N0UGFyYW1zR2V0Q29udHJhY3QudmVyaWZ5X2FjY3RfYXV0aF9hZGRyKGE6IGJ5dGVzKSAtPiBieXRlczoKdmVyaWZ5X2FjY3RfYXV0aF9hZGRyOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjQxLTQyCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gZGVmIHZlcmlmeV9hY2N0X2F1dGhfYWRkcihzZWxmLCBhOiBhbGdvcHkuQWNjb3VudCkgLT4gYXJjNC5BZGRyZXNzOgogICAgcHJvdG8gMSAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6NDMKICAgIC8vIHZhbHVlLCBmdW5kZWQgPSBvcC5BY2N0UGFyYW1zR2V0LmFjY3RfYXV0aF9hZGRyKGEpCiAgICBmcmFtZV9kaWcgLTEKICAgIGFjY3RfcGFyYW1zX2dldCBBY2N0QXV0aEFkZHIKICAgIHN3YXAKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTo0NAogICAgLy8gdmFsdWVfaW5kZXgsIGZ1bmRlZF9pbmRleCA9IG9wLkFjY3RQYXJhbXNHZXQuYWNjdF9hdXRoX2FkZHIoX2dldF8xc3RfcmVmX2luZGV4KCkpCiAgICBjYWxsc3ViIF9nZXRfMXN0X3JlZl9pbmRleAogICAgYWNjdF9wYXJhbXNfZ2V0IEFjY3RBdXRoQWRkcgogICAgY292ZXIgMgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjQ1CiAgICAvLyBhc3NlcnQgdmFsdWUgPT0gdmFsdWVfaW5kZXgsICJleHBlY3RlZCB2YWx1ZSBieSBpbmRleCB0byBtYXRjaCIKICAgIGRpZyAxCiAgICA9PQogICAgYXNzZXJ0IC8vIGV4cGVjdGVkIHZhbHVlIGJ5IGluZGV4IHRvIG1hdGNoCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6NDYKICAgIC8vIGFzc2VydCBmdW5kZWQgPT0gZnVuZGVkX2luZGV4LCAiZXhwZWN0ZWQgZnVuZGVkIGJ5IGluZGV4IHRvIG1hdGNoIgogICAgY292ZXIgMgogICAgPT0KICAgIGFzc2VydCAvLyBleHBlY3RlZCBmdW5kZWQgYnkgaW5kZXggdG8gbWF0Y2gKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTo0NwogICAgLy8gcmV0dXJuIGFyYzQuQWRkcmVzcyh2YWx1ZSkKICAgIHJldHN1YgoKCi8vIHRlc3RzLmFydGlmYWN0cy5TdGF0ZU9wcy5jb250cmFjdC5TdGF0ZUFjY3RQYXJhbXNHZXRDb250cmFjdC52ZXJpZnlfYWNjdF90b3RhbF9udW1fdWludChhOiBieXRlcykgLT4gdWludDY0Ogp2ZXJpZnlfYWNjdF90b3RhbF9udW1fdWludDoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTo0OS01MAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIGRlZiB2ZXJpZnlfYWNjdF90b3RhbF9udW1fdWludChzZWxmLCBhOiBhbGdvcHkuQWNjb3VudCkgLT4gYWxnb3B5LlVJbnQ2NDoKICAgIHByb3RvIDEgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjUxCiAgICAvLyB2YWx1ZSwgZnVuZGVkID0gb3AuQWNjdFBhcmFtc0dldC5hY2N0X3RvdGFsX251bV91aW50KGEpCiAgICBmcmFtZV9kaWcgLTEKICAgIGFjY3RfcGFyYW1zX2dldCBBY2N0VG90YWxOdW1VaW50CiAgICBzd2FwCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6NTIKICAgIC8vIHZhbHVlX2luZGV4LCBmdW5kZWRfaW5kZXggPSBvcC5BY2N0UGFyYW1zR2V0LmFjY3RfdG90YWxfbnVtX3VpbnQoX2dldF8xc3RfcmVmX2luZGV4KCkpCiAgICBjYWxsc3ViIF9nZXRfMXN0X3JlZl9pbmRleAogICAgYWNjdF9wYXJhbXNfZ2V0IEFjY3RUb3RhbE51bVVpbnQKICAgIGNvdmVyIDIKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTo1MwogICAgLy8gYXNzZXJ0IHZhbHVlID09IHZhbHVlX2luZGV4LCAiZXhwZWN0ZWQgdmFsdWUgYnkgaW5kZXggdG8gbWF0Y2giCiAgICBkaWcgMQogICAgPT0KICAgIGFzc2VydCAvLyBleHBlY3RlZCB2YWx1ZSBieSBpbmRleCB0byBtYXRjaAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjU0CiAgICAvLyBhc3NlcnQgZnVuZGVkID09IGZ1bmRlZF9pbmRleCwgImV4cGVjdGVkIGZ1bmRlZCBieSBpbmRleCB0byBtYXRjaCIKICAgIGNvdmVyIDIKICAgID09CiAgICBhc3NlcnQgLy8gZXhwZWN0ZWQgZnVuZGVkIGJ5IGluZGV4IHRvIG1hdGNoCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6NTUKICAgIC8vIHJldHVybiB2YWx1ZQogICAgcmV0c3ViCgoKLy8gdGVzdHMuYXJ0aWZhY3RzLlN0YXRlT3BzLmNvbnRyYWN0LlN0YXRlQWNjdFBhcmFtc0dldENvbnRyYWN0LnZlcmlmeV9hY2N0X3RvdGFsX251bV9ieXRlX3NsaWNlKGE6IGJ5dGVzKSAtPiB1aW50NjQ6CnZlcmlmeV9hY2N0X3RvdGFsX251bV9ieXRlX3NsaWNlOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjU3LTU4CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gZGVmIHZlcmlmeV9hY2N0X3RvdGFsX251bV9ieXRlX3NsaWNlKHNlbGYsIGE6IGFsZ29weS5BY2NvdW50KSAtPiBhbGdvcHkuVUludDY0OgogICAgcHJvdG8gMSAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6NTkKICAgIC8vIHZhbHVlLCBmdW5kZWQgPSBvcC5BY2N0UGFyYW1zR2V0LmFjY3RfdG90YWxfbnVtX2J5dGVfc2xpY2UoYSkKICAgIGZyYW1lX2RpZyAtMQogICAgYWNjdF9wYXJhbXNfZ2V0IEFjY3RUb3RhbE51bUJ5dGVTbGljZQogICAgc3dhcAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjYxCiAgICAvLyBfZ2V0XzFzdF9yZWZfaW5kZXgoKQogICAgY2FsbHN1YiBfZ2V0XzFzdF9yZWZfaW5kZXgKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTo2MC02MgogICAgLy8gdmFsdWVfaW5kZXgsIGZ1bmRlZF9pbmRleCA9IG9wLkFjY3RQYXJhbXNHZXQuYWNjdF90b3RhbF9udW1fYnl0ZV9zbGljZSgKICAgIC8vICAgICBfZ2V0XzFzdF9yZWZfaW5kZXgoKQogICAgLy8gKQogICAgYWNjdF9wYXJhbXNfZ2V0IEFjY3RUb3RhbE51bUJ5dGVTbGljZQogICAgY292ZXIgMgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjYzCiAgICAvLyBhc3NlcnQgdmFsdWUgPT0gdmFsdWVfaW5kZXgsICJleHBlY3RlZCB2YWx1ZSBieSBpbmRleCB0byBtYXRjaCIKICAgIGRpZyAxCiAgICA9PQogICAgYXNzZXJ0IC8vIGV4cGVjdGVkIHZhbHVlIGJ5IGluZGV4IHRvIG1hdGNoCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6NjQKICAgIC8vIGFzc2VydCBmdW5kZWQgPT0gZnVuZGVkX2luZGV4LCAiZXhwZWN0ZWQgZnVuZGVkIGJ5IGluZGV4IHRvIG1hdGNoIgogICAgY292ZXIgMgogICAgPT0KICAgIGFzc2VydCAvLyBleHBlY3RlZCBmdW5kZWQgYnkgaW5kZXggdG8gbWF0Y2gKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTo2NQogICAgLy8gcmV0dXJuIHZhbHVlCiAgICByZXRzdWIKCgovLyB0ZXN0cy5hcnRpZmFjdHMuU3RhdGVPcHMuY29udHJhY3QuU3RhdGVBY2N0UGFyYW1zR2V0Q29udHJhY3QudmVyaWZ5X2FjY3RfdG90YWxfZXh0cmFfYXBwX3BhZ2VzKGE6IGJ5dGVzKSAtPiB1aW50NjQ6CnZlcmlmeV9hY2N0X3RvdGFsX2V4dHJhX2FwcF9wYWdlczoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTo2Ny02OAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIGRlZiB2ZXJpZnlfYWNjdF90b3RhbF9leHRyYV9hcHBfcGFnZXMoc2VsZiwgYTogYWxnb3B5LkFjY291bnQpIC0+IGFsZ29weS5VSW50NjQ6CiAgICBwcm90byAxIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTo2OQogICAgLy8gdmFsdWUsIGZ1bmRlZCA9IG9wLkFjY3RQYXJhbXNHZXQuYWNjdF90b3RhbF9leHRyYV9hcHBfcGFnZXMoYSkKICAgIGZyYW1lX2RpZyAtMQogICAgYWNjdF9wYXJhbXNfZ2V0IEFjY3RUb3RhbEV4dHJhQXBwUGFnZXMKICAgIHN3YXAKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTo3MQogICAgLy8gX2dldF8xc3RfcmVmX2luZGV4KCkKICAgIGNhbGxzdWIgX2dldF8xc3RfcmVmX2luZGV4CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6NzAtNzIKICAgIC8vIHZhbHVlX2luZGV4LCBmdW5kZWRfaW5kZXggPSBvcC5BY2N0UGFyYW1zR2V0LmFjY3RfdG90YWxfZXh0cmFfYXBwX3BhZ2VzKAogICAgLy8gICAgIF9nZXRfMXN0X3JlZl9pbmRleCgpCiAgICAvLyApCiAgICBhY2N0X3BhcmFtc19nZXQgQWNjdFRvdGFsRXh0cmFBcHBQYWdlcwogICAgY292ZXIgMgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjczCiAgICAvLyBhc3NlcnQgdmFsdWUgPT0gdmFsdWVfaW5kZXgsICJleHBlY3RlZCB2YWx1ZSBieSBpbmRleCB0byBtYXRjaCIKICAgIGRpZyAxCiAgICA9PQogICAgYXNzZXJ0IC8vIGV4cGVjdGVkIHZhbHVlIGJ5IGluZGV4IHRvIG1hdGNoCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6NzQKICAgIC8vIGFzc2VydCBmdW5kZWQgPT0gZnVuZGVkX2luZGV4LCAiZXhwZWN0ZWQgZnVuZGVkIGJ5IGluZGV4IHRvIG1hdGNoIgogICAgY292ZXIgMgogICAgPT0KICAgIGFzc2VydCAvLyBleHBlY3RlZCBmdW5kZWQgYnkgaW5kZXggdG8gbWF0Y2gKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTo3NQogICAgLy8gcmV0dXJuIHZhbHVlCiAgICByZXRzdWIKCgovLyB0ZXN0cy5hcnRpZmFjdHMuU3RhdGVPcHMuY29udHJhY3QuU3RhdGVBY2N0UGFyYW1zR2V0Q29udHJhY3QudmVyaWZ5X2FjY3RfdG90YWxfYXBwc19jcmVhdGVkKGE6IGJ5dGVzKSAtPiB1aW50NjQ6CnZlcmlmeV9hY2N0X3RvdGFsX2FwcHNfY3JlYXRlZDoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTo3Ny03OAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIGRlZiB2ZXJpZnlfYWNjdF90b3RhbF9hcHBzX2NyZWF0ZWQoc2VsZiwgYTogYWxnb3B5LkFjY291bnQpIC0+IGFsZ29weS5VSW50NjQ6CiAgICBwcm90byAxIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTo3OQogICAgLy8gdmFsdWUsIGZ1bmRlZCA9IG9wLkFjY3RQYXJhbXNHZXQuYWNjdF90b3RhbF9hcHBzX2NyZWF0ZWQoYSkKICAgIGZyYW1lX2RpZyAtMQogICAgYWNjdF9wYXJhbXNfZ2V0IEFjY3RUb3RhbEFwcHNDcmVhdGVkCiAgICBzd2FwCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6ODAKICAgIC8vIHZhbHVlX2luZGV4LCBmdW5kZWRfaW5kZXggPSBvcC5BY2N0UGFyYW1zR2V0LmFjY3RfdG90YWxfYXBwc19jcmVhdGVkKF9nZXRfMXN0X3JlZl9pbmRleCgpKQogICAgY2FsbHN1YiBfZ2V0XzFzdF9yZWZfaW5kZXgKICAgIGFjY3RfcGFyYW1zX2dldCBBY2N0VG90YWxBcHBzQ3JlYXRlZAogICAgY292ZXIgMgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjgxCiAgICAvLyBhc3NlcnQgdmFsdWUgPT0gdmFsdWVfaW5kZXgsICJleHBlY3RlZCB2YWx1ZSBieSBpbmRleCB0byBtYXRjaCIKICAgIGRpZyAxCiAgICA9PQogICAgYXNzZXJ0IC8vIGV4cGVjdGVkIHZhbHVlIGJ5IGluZGV4IHRvIG1hdGNoCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6ODIKICAgIC8vIGFzc2VydCBmdW5kZWQgPT0gZnVuZGVkX2luZGV4LCAiZXhwZWN0ZWQgZnVuZGVkIGJ5IGluZGV4IHRvIG1hdGNoIgogICAgY292ZXIgMgogICAgPT0KICAgIGFzc2VydCAvLyBleHBlY3RlZCBmdW5kZWQgYnkgaW5kZXggdG8gbWF0Y2gKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTo4MwogICAgLy8gcmV0dXJuIHZhbHVlCiAgICByZXRzdWIKCgovLyB0ZXN0cy5hcnRpZmFjdHMuU3RhdGVPcHMuY29udHJhY3QuU3RhdGVBY2N0UGFyYW1zR2V0Q29udHJhY3QudmVyaWZ5X2FjY3RfdG90YWxfYXBwc19vcHRlZF9pbihhOiBieXRlcykgLT4gdWludDY0Ogp2ZXJpZnlfYWNjdF90b3RhbF9hcHBzX29wdGVkX2luOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5Ojg1LTg2CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gZGVmIHZlcmlmeV9hY2N0X3RvdGFsX2FwcHNfb3B0ZWRfaW4oc2VsZiwgYTogYWxnb3B5LkFjY291bnQpIC0+IGFsZ29weS5VSW50NjQ6CiAgICBwcm90byAxIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTo4NwogICAgLy8gdmFsdWUsIGZ1bmRlZCA9IG9wLkFjY3RQYXJhbXNHZXQuYWNjdF90b3RhbF9hcHBzX29wdGVkX2luKGEpCiAgICBmcmFtZV9kaWcgLTEKICAgIGFjY3RfcGFyYW1zX2dldCBBY2N0VG90YWxBcHBzT3B0ZWRJbgogICAgc3dhcAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5Ojg4CiAgICAvLyB2YWx1ZV9pbmRleCwgZnVuZGVkX2luZGV4ID0gb3AuQWNjdFBhcmFtc0dldC5hY2N0X3RvdGFsX2FwcHNfb3B0ZWRfaW4oX2dldF8xc3RfcmVmX2luZGV4KCkpCiAgICBjYWxsc3ViIF9nZXRfMXN0X3JlZl9pbmRleAogICAgYWNjdF9wYXJhbXNfZ2V0IEFjY3RUb3RhbEFwcHNPcHRlZEluCiAgICBjb3ZlciAyCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6ODkKICAgIC8vIGFzc2VydCB2YWx1ZSA9PSB2YWx1ZV9pbmRleCwgImV4cGVjdGVkIHZhbHVlIGJ5IGluZGV4IHRvIG1hdGNoIgogICAgZGlnIDEKICAgID09CiAgICBhc3NlcnQgLy8gZXhwZWN0ZWQgdmFsdWUgYnkgaW5kZXggdG8gbWF0Y2gKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTo5MAogICAgLy8gYXNzZXJ0IGZ1bmRlZCA9PSBmdW5kZWRfaW5kZXgsICJleHBlY3RlZCBmdW5kZWQgYnkgaW5kZXggdG8gbWF0Y2giCiAgICBjb3ZlciAyCiAgICA9PQogICAgYXNzZXJ0IC8vIGV4cGVjdGVkIGZ1bmRlZCBieSBpbmRleCB0byBtYXRjaAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjkxCiAgICAvLyByZXR1cm4gdmFsdWUKICAgIHJldHN1YgoKCi8vIHRlc3RzLmFydGlmYWN0cy5TdGF0ZU9wcy5jb250cmFjdC5TdGF0ZUFjY3RQYXJhbXNHZXRDb250cmFjdC52ZXJpZnlfYWNjdF90b3RhbF9hc3NldHNfY3JlYXRlZChhOiBieXRlcykgLT4gdWludDY0Ogp2ZXJpZnlfYWNjdF90b3RhbF9hc3NldHNfY3JlYXRlZDoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTo5My05NAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIGRlZiB2ZXJpZnlfYWNjdF90b3RhbF9hc3NldHNfY3JlYXRlZChzZWxmLCBhOiBhbGdvcHkuQWNjb3VudCkgLT4gYWxnb3B5LlVJbnQ2NDoKICAgIHByb3RvIDEgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5Ojk1CiAgICAvLyB2YWx1ZSwgZnVuZGVkID0gb3AuQWNjdFBhcmFtc0dldC5hY2N0X3RvdGFsX2Fzc2V0c19jcmVhdGVkKGEpCiAgICBmcmFtZV9kaWcgLTEKICAgIGFjY3RfcGFyYW1zX2dldCBBY2N0VG90YWxBc3NldHNDcmVhdGVkCiAgICBzd2FwCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6OTcKICAgIC8vIF9nZXRfMXN0X3JlZl9pbmRleCgpCiAgICBjYWxsc3ViIF9nZXRfMXN0X3JlZl9pbmRleAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5Ojk2LTk4CiAgICAvLyB2YWx1ZV9pbmRleCwgZnVuZGVkX2luZGV4ID0gb3AuQWNjdFBhcmFtc0dldC5hY2N0X3RvdGFsX2Fzc2V0c19jcmVhdGVkKAogICAgLy8gICAgIF9nZXRfMXN0X3JlZl9pbmRleCgpCiAgICAvLyApCiAgICBhY2N0X3BhcmFtc19nZXQgQWNjdFRvdGFsQXNzZXRzQ3JlYXRlZAogICAgY292ZXIgMgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5Ojk5CiAgICAvLyBhc3NlcnQgdmFsdWUgPT0gdmFsdWVfaW5kZXgsICJleHBlY3RlZCB2YWx1ZSBieSBpbmRleCB0byBtYXRjaCIKICAgIGRpZyAxCiAgICA9PQogICAgYXNzZXJ0IC8vIGV4cGVjdGVkIHZhbHVlIGJ5IGluZGV4IHRvIG1hdGNoCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6MTAwCiAgICAvLyBhc3NlcnQgZnVuZGVkID09IGZ1bmRlZF9pbmRleCwgImV4cGVjdGVkIGZ1bmRlZCBieSBpbmRleCB0byBtYXRjaCIKICAgIGNvdmVyIDIKICAgID09CiAgICBhc3NlcnQgLy8gZXhwZWN0ZWQgZnVuZGVkIGJ5IGluZGV4IHRvIG1hdGNoCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6MTAxCiAgICAvLyByZXR1cm4gdmFsdWUKICAgIHJldHN1YgoKCi8vIHRlc3RzLmFydGlmYWN0cy5TdGF0ZU9wcy5jb250cmFjdC5TdGF0ZUFjY3RQYXJhbXNHZXRDb250cmFjdC52ZXJpZnlfYWNjdF90b3RhbF9hc3NldHMoYTogYnl0ZXMpIC0+IHVpbnQ2NDoKdmVyaWZ5X2FjY3RfdG90YWxfYXNzZXRzOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjEwMy0xMDQKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBkZWYgdmVyaWZ5X2FjY3RfdG90YWxfYXNzZXRzKHNlbGYsIGE6IGFsZ29weS5BY2NvdW50KSAtPiBhbGdvcHkuVUludDY0OgogICAgcHJvdG8gMSAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6MTA1CiAgICAvLyB2YWx1ZSwgZnVuZGVkID0gb3AuQWNjdFBhcmFtc0dldC5hY2N0X3RvdGFsX2Fzc2V0cyhhKQogICAgZnJhbWVfZGlnIC0xCiAgICBhY2N0X3BhcmFtc19nZXQgQWNjdFRvdGFsQXNzZXRzCiAgICBzd2FwCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6MTA2CiAgICAvLyB2YWx1ZV9pbmRleCwgZnVuZGVkX2luZGV4ID0gb3AuQWNjdFBhcmFtc0dldC5hY2N0X3RvdGFsX2Fzc2V0cyhfZ2V0XzFzdF9yZWZfaW5kZXgoKSkKICAgIGNhbGxzdWIgX2dldF8xc3RfcmVmX2luZGV4CiAgICBhY2N0X3BhcmFtc19nZXQgQWNjdFRvdGFsQXNzZXRzCiAgICBjb3ZlciAyCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6MTA3CiAgICAvLyBhc3NlcnQgdmFsdWUgPT0gdmFsdWVfaW5kZXgsICJleHBlY3RlZCB2YWx1ZSBieSBpbmRleCB0byBtYXRjaCIKICAgIGRpZyAxCiAgICA9PQogICAgYXNzZXJ0IC8vIGV4cGVjdGVkIHZhbHVlIGJ5IGluZGV4IHRvIG1hdGNoCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6MTA4CiAgICAvLyBhc3NlcnQgZnVuZGVkID09IGZ1bmRlZF9pbmRleCwgImV4cGVjdGVkIGZ1bmRlZCBieSBpbmRleCB0byBtYXRjaCIKICAgIGNvdmVyIDIKICAgID09CiAgICBhc3NlcnQgLy8gZXhwZWN0ZWQgZnVuZGVkIGJ5IGluZGV4IHRvIG1hdGNoCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6MTA5CiAgICAvLyByZXR1cm4gdmFsdWUKICAgIHJldHN1YgoKCi8vIHRlc3RzLmFydGlmYWN0cy5TdGF0ZU9wcy5jb250cmFjdC5TdGF0ZUFjY3RQYXJhbXNHZXRDb250cmFjdC52ZXJpZnlfYWNjdF90b3RhbF9ib3hlcyhhOiBieXRlcykgLT4gdWludDY0Ogp2ZXJpZnlfYWNjdF90b3RhbF9ib3hlczoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weToxMTEtMTEyCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gZGVmIHZlcmlmeV9hY2N0X3RvdGFsX2JveGVzKHNlbGYsIGE6IGFsZ29weS5BY2NvdW50KSAtPiBhbGdvcHkuVUludDY0OgogICAgcHJvdG8gMSAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6MTEzCiAgICAvLyB2YWx1ZSwgZnVuZGVkID0gb3AuQWNjdFBhcmFtc0dldC5hY2N0X3RvdGFsX2JveGVzKGEpCiAgICBmcmFtZV9kaWcgLTEKICAgIGFjY3RfcGFyYW1zX2dldCBBY2N0VG90YWxCb3hlcwogICAgc3dhcAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjExNAogICAgLy8gdmFsdWVfaW5kZXgsIGZ1bmRlZF9pbmRleCA9IG9wLkFjY3RQYXJhbXNHZXQuYWNjdF90b3RhbF9ib3hlcyhfZ2V0XzFzdF9yZWZfaW5kZXgoKSkKICAgIGNhbGxzdWIgX2dldF8xc3RfcmVmX2luZGV4CiAgICBhY2N0X3BhcmFtc19nZXQgQWNjdFRvdGFsQm94ZXMKICAgIGNvdmVyIDIKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weToxMTUKICAgIC8vIGFzc2VydCB2YWx1ZSA9PSB2YWx1ZV9pbmRleCwgImV4cGVjdGVkIHZhbHVlIGJ5IGluZGV4IHRvIG1hdGNoIgogICAgZGlnIDEKICAgID09CiAgICBhc3NlcnQgLy8gZXhwZWN0ZWQgdmFsdWUgYnkgaW5kZXggdG8gbWF0Y2gKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weToxMTYKICAgIC8vIGFzc2VydCBmdW5kZWQgPT0gZnVuZGVkX2luZGV4LCAiZXhwZWN0ZWQgZnVuZGVkIGJ5IGluZGV4IHRvIG1hdGNoIgogICAgY292ZXIgMgogICAgPT0KICAgIGFzc2VydCAvLyBleHBlY3RlZCBmdW5kZWQgYnkgaW5kZXggdG8gbWF0Y2gKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weToxMTcKICAgIC8vIHJldHVybiB2YWx1ZQogICAgcmV0c3ViCgoKLy8gdGVzdHMuYXJ0aWZhY3RzLlN0YXRlT3BzLmNvbnRyYWN0LlN0YXRlQWNjdFBhcmFtc0dldENvbnRyYWN0LnZlcmlmeV9hY2N0X3RvdGFsX2JveF9ieXRlcyhhOiBieXRlcykgLT4gdWludDY0Ogp2ZXJpZnlfYWNjdF90b3RhbF9ib3hfYnl0ZXM6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6MTE5LTEyMAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIGRlZiB2ZXJpZnlfYWNjdF90b3RhbF9ib3hfYnl0ZXMoc2VsZiwgYTogYWxnb3B5LkFjY291bnQpIC0+IGFsZ29weS5VSW50NjQ6CiAgICBwcm90byAxIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weToxMjEKICAgIC8vIHZhbHVlLCBmdW5kZWQgPSBvcC5BY2N0UGFyYW1zR2V0LmFjY3RfdG90YWxfYm94X2J5dGVzKGEpCiAgICBmcmFtZV9kaWcgLTEKICAgIGFjY3RfcGFyYW1zX2dldCBBY2N0VG90YWxCb3hCeXRlcwogICAgc3dhcAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjEyMgogICAgLy8gdmFsdWVfaW5kZXgsIGZ1bmRlZF9pbmRleCA9IG9wLkFjY3RQYXJhbXNHZXQuYWNjdF90b3RhbF9ib3hfYnl0ZXMoX2dldF8xc3RfcmVmX2luZGV4KCkpCiAgICBjYWxsc3ViIF9nZXRfMXN0X3JlZl9pbmRleAogICAgYWNjdF9wYXJhbXNfZ2V0IEFjY3RUb3RhbEJveEJ5dGVzCiAgICBjb3ZlciAyCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6MTIzCiAgICAvLyBhc3NlcnQgdmFsdWUgPT0gdmFsdWVfaW5kZXgsICJleHBlY3RlZCB2YWx1ZSBieSBpbmRleCB0byBtYXRjaCIKICAgIGRpZyAxCiAgICA9PQogICAgYXNzZXJ0IC8vIGV4cGVjdGVkIHZhbHVlIGJ5IGluZGV4IHRvIG1hdGNoCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6MTI0CiAgICAvLyBhc3NlcnQgZnVuZGVkID09IGZ1bmRlZF9pbmRleCwgImV4cGVjdGVkIGZ1bmRlZCBieSBpbmRleCB0byBtYXRjaCIKICAgIGNvdmVyIDIKICAgID09CiAgICBhc3NlcnQgLy8gZXhwZWN0ZWQgZnVuZGVkIGJ5IGluZGV4IHRvIG1hdGNoCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6MTI1CiAgICAvLyByZXR1cm4gdmFsdWUKICAgIHJldHN1Ygo=", + "clear": "I3ByYWdtYSB2ZXJzaW9uIDEwCgp0ZXN0cy5hcnRpZmFjdHMuU3RhdGVPcHMuY29udHJhY3QuU3RhdGVBY2N0UGFyYW1zR2V0Q29udHJhY3QuY2xlYXJfc3RhdGVfcHJvZ3JhbToKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weToyNAogICAgLy8gY2xhc3MgU3RhdGVBY2N0UGFyYW1zR2V0Q29udHJhY3QoQVJDNENvbnRyYWN0KToKICAgIGludCAxCiAgICByZXR1cm4K" }, "state": { "global": { @@ -124,7 +124,7 @@ ], "readonly": false, "returns": { - "type": "byte[]" + "type": "address" } }, { diff --git a/tests/artifacts/StateOps/data/StateAcctParamsGetContract.clear.teal b/tests/artifacts/StateOps/data/StateAcctParamsGetContract.clear.teal index 62dcc16..d07d34f 100644 --- a/tests/artifacts/StateOps/data/StateAcctParamsGetContract.clear.teal +++ b/tests/artifacts/StateOps/data/StateAcctParamsGetContract.clear.teal @@ -1,7 +1,7 @@ #pragma version 10 tests.artifacts.StateOps.contract.StateAcctParamsGetContract.clear_state_program: - // tests/artifacts/StateOps/contract.py:17 + // tests/artifacts/StateOps/contract.py:24 // class StateAcctParamsGetContract(ARC4Contract): int 1 return diff --git a/tests/artifacts/StateOps/data/StateAppGlobalContract.approval.teal b/tests/artifacts/StateOps/data/StateAppGlobalContract.approval.teal index e69dc09..6f12033 100644 --- a/tests/artifacts/StateOps/data/StateAppGlobalContract.approval.teal +++ b/tests/artifacts/StateOps/data/StateAppGlobalContract.approval.teal @@ -1,7 +1,7 @@ #pragma version 10 tests.artifacts.StateOps.contract.StateAppGlobalContract.approval_program: - // tests/artifacts/StateOps/contract.py:294 + // tests/artifacts/StateOps/contract.py:412 // class StateAppGlobalContract(ARC4Contract): txn NumAppArgs bz main_bare_routing@11 @@ -17,18 +17,18 @@ tests.artifacts.StateOps.contract.StateAppGlobalContract.approval_program: err // reject transaction main_verify_get_bytes_route@2: - // tests/artifacts/StateOps/contract.py:306 + // tests/artifacts/StateOps/contract.py:424 // @arc4.abimethod() txn OnCompletion ! assert // OnCompletion is NoOp txn ApplicationID assert // is not creating - // tests/artifacts/StateOps/contract.py:294 + // tests/artifacts/StateOps/contract.py:412 // class StateAppGlobalContract(ARC4Contract): txna ApplicationArgs 1 extract 2 0 - // tests/artifacts/StateOps/contract.py:306 + // tests/artifacts/StateOps/contract.py:424 // @arc4.abimethod() callsub verify_get_bytes dup @@ -45,18 +45,18 @@ main_verify_get_bytes_route@2: return main_verify_get_uint64_route@3: - // tests/artifacts/StateOps/contract.py:311 + // tests/artifacts/StateOps/contract.py:429 // @arc4.abimethod() txn OnCompletion ! assert // OnCompletion is NoOp txn ApplicationID assert // is not creating - // tests/artifacts/StateOps/contract.py:294 + // tests/artifacts/StateOps/contract.py:412 // class StateAppGlobalContract(ARC4Contract): txna ApplicationArgs 1 extract 2 0 - // tests/artifacts/StateOps/contract.py:311 + // tests/artifacts/StateOps/contract.py:429 // @arc4.abimethod() callsub verify_get_uint64 itob @@ -68,21 +68,21 @@ main_verify_get_uint64_route@3: return main_verify_get_ex_bytes_route@4: - // tests/artifacts/StateOps/contract.py:316 + // tests/artifacts/StateOps/contract.py:434 // @arc4.abimethod() txn OnCompletion ! assert // OnCompletion is NoOp txn ApplicationID assert // is not creating - // tests/artifacts/StateOps/contract.py:294 + // tests/artifacts/StateOps/contract.py:412 // class StateAppGlobalContract(ARC4Contract): txna ApplicationArgs 1 btoi txnas Applications txna ApplicationArgs 2 extract 2 0 - // tests/artifacts/StateOps/contract.py:316 + // tests/artifacts/StateOps/contract.py:434 // @arc4.abimethod() callsub verify_get_ex_bytes swap @@ -109,21 +109,21 @@ main_verify_get_ex_bytes_route@4: return main_verify_get_ex_uint64_route@5: - // tests/artifacts/StateOps/contract.py:320 + // tests/artifacts/StateOps/contract.py:438 // @arc4.abimethod() txn OnCompletion ! assert // OnCompletion is NoOp txn ApplicationID assert // is not creating - // tests/artifacts/StateOps/contract.py:294 + // tests/artifacts/StateOps/contract.py:412 // class StateAppGlobalContract(ARC4Contract): txna ApplicationArgs 1 btoi txnas Applications txna ApplicationArgs 2 extract 2 0 - // tests/artifacts/StateOps/contract.py:320 + // tests/artifacts/StateOps/contract.py:438 // @arc4.abimethod() callsub verify_get_ex_uint64 swap @@ -141,65 +141,65 @@ main_verify_get_ex_uint64_route@5: return main_verify_delete_route@6: - // tests/artifacts/StateOps/contract.py:324 + // tests/artifacts/StateOps/contract.py:442 // @arc4.abimethod() txn OnCompletion ! assert // OnCompletion is NoOp txn ApplicationID assert // is not creating - // tests/artifacts/StateOps/contract.py:294 + // tests/artifacts/StateOps/contract.py:412 // class StateAppGlobalContract(ARC4Contract): txna ApplicationArgs 1 extract 2 0 - // tests/artifacts/StateOps/contract.py:324 + // tests/artifacts/StateOps/contract.py:442 // @arc4.abimethod() callsub verify_delete int 1 return main_verify_put_uint64_route@7: - // tests/artifacts/StateOps/contract.py:328 + // tests/artifacts/StateOps/contract.py:446 // @arc4.abimethod() txn OnCompletion ! assert // OnCompletion is NoOp txn ApplicationID assert // is not creating - // tests/artifacts/StateOps/contract.py:294 + // tests/artifacts/StateOps/contract.py:412 // class StateAppGlobalContract(ARC4Contract): txna ApplicationArgs 1 extract 2 0 txna ApplicationArgs 2 btoi - // tests/artifacts/StateOps/contract.py:328 + // tests/artifacts/StateOps/contract.py:446 // @arc4.abimethod() callsub verify_put_uint64 int 1 return main_verify_put_bytes_route@8: - // tests/artifacts/StateOps/contract.py:332 + // tests/artifacts/StateOps/contract.py:450 // @arc4.abimethod() txn OnCompletion ! assert // OnCompletion is NoOp txn ApplicationID assert // is not creating - // tests/artifacts/StateOps/contract.py:294 + // tests/artifacts/StateOps/contract.py:412 // class StateAppGlobalContract(ARC4Contract): txna ApplicationArgs 1 extract 2 0 txna ApplicationArgs 2 extract 2 0 - // tests/artifacts/StateOps/contract.py:332 + // tests/artifacts/StateOps/contract.py:450 // @arc4.abimethod() callsub verify_put_bytes int 1 return main_bare_routing@11: - // tests/artifacts/StateOps/contract.py:294 + // tests/artifacts/StateOps/contract.py:412 // class StateAppGlobalContract(ARC4Contract): txn OnCompletion ! @@ -213,41 +213,41 @@ main_bare_routing@11: // tests.artifacts.StateOps.contract.StateAppGlobalContract.verify_get_bytes(a: bytes) -> bytes: verify_get_bytes: - // tests/artifacts/StateOps/contract.py:306-307 + // tests/artifacts/StateOps/contract.py:424-425 // @arc4.abimethod() // def verify_get_bytes(self, a: Bytes) -> Bytes: proto 1 1 - // tests/artifacts/StateOps/contract.py:308 + // tests/artifacts/StateOps/contract.py:426 // value = op.AppGlobal.get_bytes(a) frame_dig -1 app_global_get - // tests/artifacts/StateOps/contract.py:309 + // tests/artifacts/StateOps/contract.py:427 // return value retsub // tests.artifacts.StateOps.contract.StateAppGlobalContract.verify_get_uint64(a: bytes) -> uint64: verify_get_uint64: - // tests/artifacts/StateOps/contract.py:311-312 + // tests/artifacts/StateOps/contract.py:429-430 // @arc4.abimethod() // def verify_get_uint64(self, a: Bytes) -> UInt64: proto 1 1 - // tests/artifacts/StateOps/contract.py:313 + // tests/artifacts/StateOps/contract.py:431 // value = op.AppGlobal.get_uint64(a) frame_dig -1 app_global_get - // tests/artifacts/StateOps/contract.py:314 + // tests/artifacts/StateOps/contract.py:432 // return value retsub // tests.artifacts.StateOps.contract.StateAppGlobalContract.verify_get_ex_bytes(a: uint64, b: bytes) -> bytes, uint64: verify_get_ex_bytes: - // tests/artifacts/StateOps/contract.py:316-317 + // tests/artifacts/StateOps/contract.py:434-435 // @arc4.abimethod() // def verify_get_ex_bytes(self, a: Application, b: Bytes) -> tuple[Bytes, bool]: proto 2 2 - // tests/artifacts/StateOps/contract.py:318 + // tests/artifacts/StateOps/contract.py:436 // return op.AppGlobal.get_ex_bytes(a, b) frame_dig -2 frame_dig -1 @@ -257,11 +257,11 @@ verify_get_ex_bytes: // tests.artifacts.StateOps.contract.StateAppGlobalContract.verify_get_ex_uint64(a: uint64, b: bytes) -> uint64, uint64: verify_get_ex_uint64: - // tests/artifacts/StateOps/contract.py:320-321 + // tests/artifacts/StateOps/contract.py:438-439 // @arc4.abimethod() // def verify_get_ex_uint64(self, a: Application, b: Bytes) -> tuple[UInt64, bool]: proto 2 2 - // tests/artifacts/StateOps/contract.py:322 + // tests/artifacts/StateOps/contract.py:440 // return op.AppGlobal.get_ex_uint64(a, b) frame_dig -2 frame_dig -1 @@ -271,11 +271,11 @@ verify_get_ex_uint64: // tests.artifacts.StateOps.contract.StateAppGlobalContract.verify_delete(a: bytes) -> void: verify_delete: - // tests/artifacts/StateOps/contract.py:324-325 + // tests/artifacts/StateOps/contract.py:442-443 // @arc4.abimethod() // def verify_delete(self, a: Bytes) -> None: proto 1 0 - // tests/artifacts/StateOps/contract.py:326 + // tests/artifacts/StateOps/contract.py:444 // op.AppGlobal.delete(a) frame_dig -1 app_global_del @@ -284,11 +284,11 @@ verify_delete: // tests.artifacts.StateOps.contract.StateAppGlobalContract.verify_put_uint64(a: bytes, b: uint64) -> void: verify_put_uint64: - // tests/artifacts/StateOps/contract.py:328-329 + // tests/artifacts/StateOps/contract.py:446-447 // @arc4.abimethod() // def verify_put_uint64(self, a: Bytes, b: UInt64) -> None: proto 2 0 - // tests/artifacts/StateOps/contract.py:330 + // tests/artifacts/StateOps/contract.py:448 // op.AppGlobal.put(a, b) frame_dig -2 frame_dig -1 @@ -298,11 +298,11 @@ verify_put_uint64: // tests.artifacts.StateOps.contract.StateAppGlobalContract.verify_put_bytes(a: bytes, b: bytes) -> void: verify_put_bytes: - // tests/artifacts/StateOps/contract.py:332-333 + // tests/artifacts/StateOps/contract.py:450-451 // @arc4.abimethod() // def verify_put_bytes(self, a: Bytes, b: Bytes) -> None: proto 2 0 - // tests/artifacts/StateOps/contract.py:334 + // tests/artifacts/StateOps/contract.py:452 // op.AppGlobal.put(a, b) frame_dig -2 frame_dig -1 diff --git a/tests/artifacts/StateOps/data/StateAppGlobalContract.arc32.json b/tests/artifacts/StateOps/data/StateAppGlobalContract.arc32.json index d60c817..811b4f1 100644 --- a/tests/artifacts/StateOps/data/StateAppGlobalContract.arc32.json +++ b/tests/artifacts/StateOps/data/StateAppGlobalContract.arc32.json @@ -37,8 +37,8 @@ } }, "source": { - "approval": "I3ByYWdtYSB2ZXJzaW9uIDEwCgp0ZXN0cy5hcnRpZmFjdHMuU3RhdGVPcHMuY29udHJhY3QuU3RhdGVBcHBHbG9iYWxDb250cmFjdC5hcHByb3ZhbF9wcm9ncmFtOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjI5NAogICAgLy8gY2xhc3MgU3RhdGVBcHBHbG9iYWxDb250cmFjdChBUkM0Q29udHJhY3QpOgogICAgdHhuIE51bUFwcEFyZ3MKICAgIGJ6IG1haW5fYmFyZV9yb3V0aW5nQDExCiAgICBtZXRob2QgInZlcmlmeV9nZXRfYnl0ZXMoYnl0ZVtdKWJ5dGVbXSIKICAgIG1ldGhvZCAidmVyaWZ5X2dldF91aW50NjQoYnl0ZVtdKXVpbnQ2NCIKICAgIG1ldGhvZCAidmVyaWZ5X2dldF9leF9ieXRlcyhhcHBsaWNhdGlvbixieXRlW10pKGJ5dGVbXSxib29sKSIKICAgIG1ldGhvZCAidmVyaWZ5X2dldF9leF91aW50NjQoYXBwbGljYXRpb24sYnl0ZVtdKSh1aW50NjQsYm9vbCkiCiAgICBtZXRob2QgInZlcmlmeV9kZWxldGUoYnl0ZVtdKXZvaWQiCiAgICBtZXRob2QgInZlcmlmeV9wdXRfdWludDY0KGJ5dGVbXSx1aW50NjQpdm9pZCIKICAgIG1ldGhvZCAidmVyaWZ5X3B1dF9ieXRlcyhieXRlW10sYnl0ZVtdKXZvaWQiCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAwCiAgICBtYXRjaCBtYWluX3ZlcmlmeV9nZXRfYnl0ZXNfcm91dGVAMiBtYWluX3ZlcmlmeV9nZXRfdWludDY0X3JvdXRlQDMgbWFpbl92ZXJpZnlfZ2V0X2V4X2J5dGVzX3JvdXRlQDQgbWFpbl92ZXJpZnlfZ2V0X2V4X3VpbnQ2NF9yb3V0ZUA1IG1haW5fdmVyaWZ5X2RlbGV0ZV9yb3V0ZUA2IG1haW5fdmVyaWZ5X3B1dF91aW50NjRfcm91dGVANyBtYWluX3ZlcmlmeV9wdXRfYnl0ZXNfcm91dGVAOAogICAgZXJyIC8vIHJlamVjdCB0cmFuc2FjdGlvbgoKbWFpbl92ZXJpZnlfZ2V0X2J5dGVzX3JvdXRlQDI6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6MzA2CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGlzIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjI5NAogICAgLy8gY2xhc3MgU3RhdGVBcHBHbG9iYWxDb250cmFjdChBUkM0Q29udHJhY3QpOgogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgZXh0cmFjdCAyIDAKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTozMDYKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV9nZXRfYnl0ZXMKICAgIGR1cAogICAgbGVuCiAgICBpdG9iCiAgICBleHRyYWN0IDYgMgogICAgc3dhcAogICAgY29uY2F0CiAgICBieXRlIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnQgMQogICAgcmV0dXJuCgptYWluX3ZlcmlmeV9nZXRfdWludDY0X3JvdXRlQDM6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6MzExCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGlzIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjI5NAogICAgLy8gY2xhc3MgU3RhdGVBcHBHbG9iYWxDb250cmFjdChBUkM0Q29udHJhY3QpOgogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgZXh0cmFjdCAyIDAKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTozMTEKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV9nZXRfdWludDY0CiAgICBpdG9iCiAgICBieXRlIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnQgMQogICAgcmV0dXJuCgptYWluX3ZlcmlmeV9nZXRfZXhfYnl0ZXNfcm91dGVANDoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTozMTYKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gaXMgbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6Mjk0CiAgICAvLyBjbGFzcyBTdGF0ZUFwcEdsb2JhbENvbnRyYWN0KEFSQzRDb250cmFjdCk6CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBidG9pCiAgICB0eG5hcyBBcHBsaWNhdGlvbnMKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDIKICAgIGV4dHJhY3QgMiAwCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6MzE2CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfZ2V0X2V4X2J5dGVzCiAgICBzd2FwCiAgICBkdXAKICAgIGxlbgogICAgaXRvYgogICAgZXh0cmFjdCA2IDIKICAgIHN3YXAKICAgIGNvbmNhdAogICAgYnl0ZSAweDAwCiAgICBpbnQgMAogICAgdW5jb3ZlciAzCiAgICBzZXRiaXQKICAgIGJ5dGUgMHgwMDAzCiAgICBzd2FwCiAgICBjb25jYXQKICAgIHN3YXAKICAgIGNvbmNhdAogICAgYnl0ZSAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50IDEKICAgIHJldHVybgoKbWFpbl92ZXJpZnlfZ2V0X2V4X3VpbnQ2NF9yb3V0ZUA1OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjMyMAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBpcyBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weToyOTQKICAgIC8vIGNsYXNzIFN0YXRlQXBwR2xvYmFsQ29udHJhY3QoQVJDNENvbnRyYWN0KToKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGJ0b2kKICAgIHR4bmFzIEFwcGxpY2F0aW9ucwogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMgogICAgZXh0cmFjdCAyIDAKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTozMjAKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV9nZXRfZXhfdWludDY0CiAgICBzd2FwCiAgICBpdG9iCiAgICBieXRlIDB4MDAKICAgIGludCAwCiAgICB1bmNvdmVyIDMKICAgIHNldGJpdAogICAgY29uY2F0CiAgICBieXRlIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnQgMQogICAgcmV0dXJuCgptYWluX3ZlcmlmeV9kZWxldGVfcm91dGVANjoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTozMjQKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gaXMgbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6Mjk0CiAgICAvLyBjbGFzcyBTdGF0ZUFwcEdsb2JhbENvbnRyYWN0KEFSQzRDb250cmFjdCk6CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBleHRyYWN0IDIgMAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjMyNAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X2RlbGV0ZQogICAgaW50IDEKICAgIHJldHVybgoKbWFpbl92ZXJpZnlfcHV0X3VpbnQ2NF9yb3V0ZUA3OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjMyOAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBpcyBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weToyOTQKICAgIC8vIGNsYXNzIFN0YXRlQXBwR2xvYmFsQ29udHJhY3QoQVJDNENvbnRyYWN0KToKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGV4dHJhY3QgMiAwCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAyCiAgICBidG9pCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6MzI4CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfcHV0X3VpbnQ2NAogICAgaW50IDEKICAgIHJldHVybgoKbWFpbl92ZXJpZnlfcHV0X2J5dGVzX3JvdXRlQDg6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6MzMyCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGlzIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjI5NAogICAgLy8gY2xhc3MgU3RhdGVBcHBHbG9iYWxDb250cmFjdChBUkM0Q29udHJhY3QpOgogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgZXh0cmFjdCAyIDAKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDIKICAgIGV4dHJhY3QgMiAwCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6MzMyCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfcHV0X2J5dGVzCiAgICBpbnQgMQogICAgcmV0dXJuCgptYWluX2JhcmVfcm91dGluZ0AxMToKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weToyOTQKICAgIC8vIGNsYXNzIFN0YXRlQXBwR2xvYmFsQ29udHJhY3QoQVJDNENvbnRyYWN0KToKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyByZWplY3QgdHJhbnNhY3Rpb24KICAgIHR4biBBcHBsaWNhdGlvbklECiAgICAhCiAgICBhc3NlcnQgLy8gaXMgY3JlYXRpbmcKICAgIGludCAxCiAgICByZXR1cm4KCgovLyB0ZXN0cy5hcnRpZmFjdHMuU3RhdGVPcHMuY29udHJhY3QuU3RhdGVBcHBHbG9iYWxDb250cmFjdC52ZXJpZnlfZ2V0X2J5dGVzKGE6IGJ5dGVzKSAtPiBieXRlczoKdmVyaWZ5X2dldF9ieXRlczoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTozMDYtMzA3CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gZGVmIHZlcmlmeV9nZXRfYnl0ZXMoc2VsZiwgYTogQnl0ZXMpIC0+IEJ5dGVzOgogICAgcHJvdG8gMSAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6MzA4CiAgICAvLyB2YWx1ZSA9IG9wLkFwcEdsb2JhbC5nZXRfYnl0ZXMoYSkKICAgIGZyYW1lX2RpZyAtMQogICAgYXBwX2dsb2JhbF9nZXQKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTozMDkKICAgIC8vIHJldHVybiB2YWx1ZQogICAgcmV0c3ViCgoKLy8gdGVzdHMuYXJ0aWZhY3RzLlN0YXRlT3BzLmNvbnRyYWN0LlN0YXRlQXBwR2xvYmFsQ29udHJhY3QudmVyaWZ5X2dldF91aW50NjQoYTogYnl0ZXMpIC0+IHVpbnQ2NDoKdmVyaWZ5X2dldF91aW50NjQ6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6MzExLTMxMgogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIGRlZiB2ZXJpZnlfZ2V0X3VpbnQ2NChzZWxmLCBhOiBCeXRlcykgLT4gVUludDY0OgogICAgcHJvdG8gMSAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6MzEzCiAgICAvLyB2YWx1ZSA9IG9wLkFwcEdsb2JhbC5nZXRfdWludDY0KGEpCiAgICBmcmFtZV9kaWcgLTEKICAgIGFwcF9nbG9iYWxfZ2V0CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6MzE0CiAgICAvLyByZXR1cm4gdmFsdWUKICAgIHJldHN1YgoKCi8vIHRlc3RzLmFydGlmYWN0cy5TdGF0ZU9wcy5jb250cmFjdC5TdGF0ZUFwcEdsb2JhbENvbnRyYWN0LnZlcmlmeV9nZXRfZXhfYnl0ZXMoYTogdWludDY0LCBiOiBieXRlcykgLT4gYnl0ZXMsIHVpbnQ2NDoKdmVyaWZ5X2dldF9leF9ieXRlczoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTozMTYtMzE3CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gZGVmIHZlcmlmeV9nZXRfZXhfYnl0ZXMoc2VsZiwgYTogQXBwbGljYXRpb24sIGI6IEJ5dGVzKSAtPiB0dXBsZVtCeXRlcywgYm9vbF06CiAgICBwcm90byAyIDIKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTozMTgKICAgIC8vIHJldHVybiBvcC5BcHBHbG9iYWwuZ2V0X2V4X2J5dGVzKGEsIGIpCiAgICBmcmFtZV9kaWcgLTIKICAgIGZyYW1lX2RpZyAtMQogICAgYXBwX2dsb2JhbF9nZXRfZXgKICAgIHJldHN1YgoKCi8vIHRlc3RzLmFydGlmYWN0cy5TdGF0ZU9wcy5jb250cmFjdC5TdGF0ZUFwcEdsb2JhbENvbnRyYWN0LnZlcmlmeV9nZXRfZXhfdWludDY0KGE6IHVpbnQ2NCwgYjogYnl0ZXMpIC0+IHVpbnQ2NCwgdWludDY0Ogp2ZXJpZnlfZ2V0X2V4X3VpbnQ2NDoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTozMjAtMzIxCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gZGVmIHZlcmlmeV9nZXRfZXhfdWludDY0KHNlbGYsIGE6IEFwcGxpY2F0aW9uLCBiOiBCeXRlcykgLT4gdHVwbGVbVUludDY0LCBib29sXToKICAgIHByb3RvIDIgMgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjMyMgogICAgLy8gcmV0dXJuIG9wLkFwcEdsb2JhbC5nZXRfZXhfdWludDY0KGEsIGIpCiAgICBmcmFtZV9kaWcgLTIKICAgIGZyYW1lX2RpZyAtMQogICAgYXBwX2dsb2JhbF9nZXRfZXgKICAgIHJldHN1YgoKCi8vIHRlc3RzLmFydGlmYWN0cy5TdGF0ZU9wcy5jb250cmFjdC5TdGF0ZUFwcEdsb2JhbENvbnRyYWN0LnZlcmlmeV9kZWxldGUoYTogYnl0ZXMpIC0+IHZvaWQ6CnZlcmlmeV9kZWxldGU6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6MzI0LTMyNQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIGRlZiB2ZXJpZnlfZGVsZXRlKHNlbGYsIGE6IEJ5dGVzKSAtPiBOb25lOgogICAgcHJvdG8gMSAwCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6MzI2CiAgICAvLyBvcC5BcHBHbG9iYWwuZGVsZXRlKGEpCiAgICBmcmFtZV9kaWcgLTEKICAgIGFwcF9nbG9iYWxfZGVsCiAgICByZXRzdWIKCgovLyB0ZXN0cy5hcnRpZmFjdHMuU3RhdGVPcHMuY29udHJhY3QuU3RhdGVBcHBHbG9iYWxDb250cmFjdC52ZXJpZnlfcHV0X3VpbnQ2NChhOiBieXRlcywgYjogdWludDY0KSAtPiB2b2lkOgp2ZXJpZnlfcHV0X3VpbnQ2NDoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTozMjgtMzI5CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gZGVmIHZlcmlmeV9wdXRfdWludDY0KHNlbGYsIGE6IEJ5dGVzLCBiOiBVSW50NjQpIC0+IE5vbmU6CiAgICBwcm90byAyIDAKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTozMzAKICAgIC8vIG9wLkFwcEdsb2JhbC5wdXQoYSwgYikKICAgIGZyYW1lX2RpZyAtMgogICAgZnJhbWVfZGlnIC0xCiAgICBhcHBfZ2xvYmFsX3B1dAogICAgcmV0c3ViCgoKLy8gdGVzdHMuYXJ0aWZhY3RzLlN0YXRlT3BzLmNvbnRyYWN0LlN0YXRlQXBwR2xvYmFsQ29udHJhY3QudmVyaWZ5X3B1dF9ieXRlcyhhOiBieXRlcywgYjogYnl0ZXMpIC0+IHZvaWQ6CnZlcmlmeV9wdXRfYnl0ZXM6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6MzMyLTMzMwogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIGRlZiB2ZXJpZnlfcHV0X2J5dGVzKHNlbGYsIGE6IEJ5dGVzLCBiOiBCeXRlcykgLT4gTm9uZToKICAgIHByb3RvIDIgMAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjMzNAogICAgLy8gb3AuQXBwR2xvYmFsLnB1dChhLCBiKQogICAgZnJhbWVfZGlnIC0yCiAgICBmcmFtZV9kaWcgLTEKICAgIGFwcF9nbG9iYWxfcHV0CiAgICByZXRzdWIK", - "clear": "I3ByYWdtYSB2ZXJzaW9uIDEwCgp0ZXN0cy5hcnRpZmFjdHMuU3RhdGVPcHMuY29udHJhY3QuU3RhdGVBcHBHbG9iYWxDb250cmFjdC5jbGVhcl9zdGF0ZV9wcm9ncmFtOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjI5NAogICAgLy8gY2xhc3MgU3RhdGVBcHBHbG9iYWxDb250cmFjdChBUkM0Q29udHJhY3QpOgogICAgaW50IDEKICAgIHJldHVybgo=" + "approval": "I3ByYWdtYSB2ZXJzaW9uIDEwCgp0ZXN0cy5hcnRpZmFjdHMuU3RhdGVPcHMuY29udHJhY3QuU3RhdGVBcHBHbG9iYWxDb250cmFjdC5hcHByb3ZhbF9wcm9ncmFtOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjQxMgogICAgLy8gY2xhc3MgU3RhdGVBcHBHbG9iYWxDb250cmFjdChBUkM0Q29udHJhY3QpOgogICAgdHhuIE51bUFwcEFyZ3MKICAgIGJ6IG1haW5fYmFyZV9yb3V0aW5nQDExCiAgICBtZXRob2QgInZlcmlmeV9nZXRfYnl0ZXMoYnl0ZVtdKWJ5dGVbXSIKICAgIG1ldGhvZCAidmVyaWZ5X2dldF91aW50NjQoYnl0ZVtdKXVpbnQ2NCIKICAgIG1ldGhvZCAidmVyaWZ5X2dldF9leF9ieXRlcyhhcHBsaWNhdGlvbixieXRlW10pKGJ5dGVbXSxib29sKSIKICAgIG1ldGhvZCAidmVyaWZ5X2dldF9leF91aW50NjQoYXBwbGljYXRpb24sYnl0ZVtdKSh1aW50NjQsYm9vbCkiCiAgICBtZXRob2QgInZlcmlmeV9kZWxldGUoYnl0ZVtdKXZvaWQiCiAgICBtZXRob2QgInZlcmlmeV9wdXRfdWludDY0KGJ5dGVbXSx1aW50NjQpdm9pZCIKICAgIG1ldGhvZCAidmVyaWZ5X3B1dF9ieXRlcyhieXRlW10sYnl0ZVtdKXZvaWQiCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAwCiAgICBtYXRjaCBtYWluX3ZlcmlmeV9nZXRfYnl0ZXNfcm91dGVAMiBtYWluX3ZlcmlmeV9nZXRfdWludDY0X3JvdXRlQDMgbWFpbl92ZXJpZnlfZ2V0X2V4X2J5dGVzX3JvdXRlQDQgbWFpbl92ZXJpZnlfZ2V0X2V4X3VpbnQ2NF9yb3V0ZUA1IG1haW5fdmVyaWZ5X2RlbGV0ZV9yb3V0ZUA2IG1haW5fdmVyaWZ5X3B1dF91aW50NjRfcm91dGVANyBtYWluX3ZlcmlmeV9wdXRfYnl0ZXNfcm91dGVAOAogICAgZXJyIC8vIHJlamVjdCB0cmFuc2FjdGlvbgoKbWFpbl92ZXJpZnlfZ2V0X2J5dGVzX3JvdXRlQDI6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6NDI0CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGlzIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjQxMgogICAgLy8gY2xhc3MgU3RhdGVBcHBHbG9iYWxDb250cmFjdChBUkM0Q29udHJhY3QpOgogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgZXh0cmFjdCAyIDAKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTo0MjQKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV9nZXRfYnl0ZXMKICAgIGR1cAogICAgbGVuCiAgICBpdG9iCiAgICBleHRyYWN0IDYgMgogICAgc3dhcAogICAgY29uY2F0CiAgICBieXRlIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnQgMQogICAgcmV0dXJuCgptYWluX3ZlcmlmeV9nZXRfdWludDY0X3JvdXRlQDM6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6NDI5CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGlzIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjQxMgogICAgLy8gY2xhc3MgU3RhdGVBcHBHbG9iYWxDb250cmFjdChBUkM0Q29udHJhY3QpOgogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgZXh0cmFjdCAyIDAKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTo0MjkKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV9nZXRfdWludDY0CiAgICBpdG9iCiAgICBieXRlIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnQgMQogICAgcmV0dXJuCgptYWluX3ZlcmlmeV9nZXRfZXhfYnl0ZXNfcm91dGVANDoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTo0MzQKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gaXMgbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6NDEyCiAgICAvLyBjbGFzcyBTdGF0ZUFwcEdsb2JhbENvbnRyYWN0KEFSQzRDb250cmFjdCk6CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBidG9pCiAgICB0eG5hcyBBcHBsaWNhdGlvbnMKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDIKICAgIGV4dHJhY3QgMiAwCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6NDM0CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfZ2V0X2V4X2J5dGVzCiAgICBzd2FwCiAgICBkdXAKICAgIGxlbgogICAgaXRvYgogICAgZXh0cmFjdCA2IDIKICAgIHN3YXAKICAgIGNvbmNhdAogICAgYnl0ZSAweDAwCiAgICBpbnQgMAogICAgdW5jb3ZlciAzCiAgICBzZXRiaXQKICAgIGJ5dGUgMHgwMDAzCiAgICBzd2FwCiAgICBjb25jYXQKICAgIHN3YXAKICAgIGNvbmNhdAogICAgYnl0ZSAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50IDEKICAgIHJldHVybgoKbWFpbl92ZXJpZnlfZ2V0X2V4X3VpbnQ2NF9yb3V0ZUA1OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjQzOAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBpcyBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTo0MTIKICAgIC8vIGNsYXNzIFN0YXRlQXBwR2xvYmFsQ29udHJhY3QoQVJDNENvbnRyYWN0KToKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGJ0b2kKICAgIHR4bmFzIEFwcGxpY2F0aW9ucwogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMgogICAgZXh0cmFjdCAyIDAKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTo0MzgKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV9nZXRfZXhfdWludDY0CiAgICBzd2FwCiAgICBpdG9iCiAgICBieXRlIDB4MDAKICAgIGludCAwCiAgICB1bmNvdmVyIDMKICAgIHNldGJpdAogICAgY29uY2F0CiAgICBieXRlIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnQgMQogICAgcmV0dXJuCgptYWluX3ZlcmlmeV9kZWxldGVfcm91dGVANjoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTo0NDIKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gaXMgbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6NDEyCiAgICAvLyBjbGFzcyBTdGF0ZUFwcEdsb2JhbENvbnRyYWN0KEFSQzRDb250cmFjdCk6CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBleHRyYWN0IDIgMAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjQ0MgogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X2RlbGV0ZQogICAgaW50IDEKICAgIHJldHVybgoKbWFpbl92ZXJpZnlfcHV0X3VpbnQ2NF9yb3V0ZUA3OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjQ0NgogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBpcyBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTo0MTIKICAgIC8vIGNsYXNzIFN0YXRlQXBwR2xvYmFsQ29udHJhY3QoQVJDNENvbnRyYWN0KToKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGV4dHJhY3QgMiAwCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAyCiAgICBidG9pCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6NDQ2CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfcHV0X3VpbnQ2NAogICAgaW50IDEKICAgIHJldHVybgoKbWFpbl92ZXJpZnlfcHV0X2J5dGVzX3JvdXRlQDg6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6NDUwCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGlzIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjQxMgogICAgLy8gY2xhc3MgU3RhdGVBcHBHbG9iYWxDb250cmFjdChBUkM0Q29udHJhY3QpOgogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgZXh0cmFjdCAyIDAKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDIKICAgIGV4dHJhY3QgMiAwCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6NDUwCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfcHV0X2J5dGVzCiAgICBpbnQgMQogICAgcmV0dXJuCgptYWluX2JhcmVfcm91dGluZ0AxMToKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTo0MTIKICAgIC8vIGNsYXNzIFN0YXRlQXBwR2xvYmFsQ29udHJhY3QoQVJDNENvbnRyYWN0KToKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyByZWplY3QgdHJhbnNhY3Rpb24KICAgIHR4biBBcHBsaWNhdGlvbklECiAgICAhCiAgICBhc3NlcnQgLy8gaXMgY3JlYXRpbmcKICAgIGludCAxCiAgICByZXR1cm4KCgovLyB0ZXN0cy5hcnRpZmFjdHMuU3RhdGVPcHMuY29udHJhY3QuU3RhdGVBcHBHbG9iYWxDb250cmFjdC52ZXJpZnlfZ2V0X2J5dGVzKGE6IGJ5dGVzKSAtPiBieXRlczoKdmVyaWZ5X2dldF9ieXRlczoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTo0MjQtNDI1CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gZGVmIHZlcmlmeV9nZXRfYnl0ZXMoc2VsZiwgYTogQnl0ZXMpIC0+IEJ5dGVzOgogICAgcHJvdG8gMSAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6NDI2CiAgICAvLyB2YWx1ZSA9IG9wLkFwcEdsb2JhbC5nZXRfYnl0ZXMoYSkKICAgIGZyYW1lX2RpZyAtMQogICAgYXBwX2dsb2JhbF9nZXQKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTo0MjcKICAgIC8vIHJldHVybiB2YWx1ZQogICAgcmV0c3ViCgoKLy8gdGVzdHMuYXJ0aWZhY3RzLlN0YXRlT3BzLmNvbnRyYWN0LlN0YXRlQXBwR2xvYmFsQ29udHJhY3QudmVyaWZ5X2dldF91aW50NjQoYTogYnl0ZXMpIC0+IHVpbnQ2NDoKdmVyaWZ5X2dldF91aW50NjQ6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6NDI5LTQzMAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIGRlZiB2ZXJpZnlfZ2V0X3VpbnQ2NChzZWxmLCBhOiBCeXRlcykgLT4gVUludDY0OgogICAgcHJvdG8gMSAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6NDMxCiAgICAvLyB2YWx1ZSA9IG9wLkFwcEdsb2JhbC5nZXRfdWludDY0KGEpCiAgICBmcmFtZV9kaWcgLTEKICAgIGFwcF9nbG9iYWxfZ2V0CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6NDMyCiAgICAvLyByZXR1cm4gdmFsdWUKICAgIHJldHN1YgoKCi8vIHRlc3RzLmFydGlmYWN0cy5TdGF0ZU9wcy5jb250cmFjdC5TdGF0ZUFwcEdsb2JhbENvbnRyYWN0LnZlcmlmeV9nZXRfZXhfYnl0ZXMoYTogdWludDY0LCBiOiBieXRlcykgLT4gYnl0ZXMsIHVpbnQ2NDoKdmVyaWZ5X2dldF9leF9ieXRlczoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTo0MzQtNDM1CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gZGVmIHZlcmlmeV9nZXRfZXhfYnl0ZXMoc2VsZiwgYTogQXBwbGljYXRpb24sIGI6IEJ5dGVzKSAtPiB0dXBsZVtCeXRlcywgYm9vbF06CiAgICBwcm90byAyIDIKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTo0MzYKICAgIC8vIHJldHVybiBvcC5BcHBHbG9iYWwuZ2V0X2V4X2J5dGVzKGEsIGIpCiAgICBmcmFtZV9kaWcgLTIKICAgIGZyYW1lX2RpZyAtMQogICAgYXBwX2dsb2JhbF9nZXRfZXgKICAgIHJldHN1YgoKCi8vIHRlc3RzLmFydGlmYWN0cy5TdGF0ZU9wcy5jb250cmFjdC5TdGF0ZUFwcEdsb2JhbENvbnRyYWN0LnZlcmlmeV9nZXRfZXhfdWludDY0KGE6IHVpbnQ2NCwgYjogYnl0ZXMpIC0+IHVpbnQ2NCwgdWludDY0Ogp2ZXJpZnlfZ2V0X2V4X3VpbnQ2NDoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTo0MzgtNDM5CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gZGVmIHZlcmlmeV9nZXRfZXhfdWludDY0KHNlbGYsIGE6IEFwcGxpY2F0aW9uLCBiOiBCeXRlcykgLT4gdHVwbGVbVUludDY0LCBib29sXToKICAgIHByb3RvIDIgMgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjQ0MAogICAgLy8gcmV0dXJuIG9wLkFwcEdsb2JhbC5nZXRfZXhfdWludDY0KGEsIGIpCiAgICBmcmFtZV9kaWcgLTIKICAgIGZyYW1lX2RpZyAtMQogICAgYXBwX2dsb2JhbF9nZXRfZXgKICAgIHJldHN1YgoKCi8vIHRlc3RzLmFydGlmYWN0cy5TdGF0ZU9wcy5jb250cmFjdC5TdGF0ZUFwcEdsb2JhbENvbnRyYWN0LnZlcmlmeV9kZWxldGUoYTogYnl0ZXMpIC0+IHZvaWQ6CnZlcmlmeV9kZWxldGU6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6NDQyLTQ0MwogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIGRlZiB2ZXJpZnlfZGVsZXRlKHNlbGYsIGE6IEJ5dGVzKSAtPiBOb25lOgogICAgcHJvdG8gMSAwCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6NDQ0CiAgICAvLyBvcC5BcHBHbG9iYWwuZGVsZXRlKGEpCiAgICBmcmFtZV9kaWcgLTEKICAgIGFwcF9nbG9iYWxfZGVsCiAgICByZXRzdWIKCgovLyB0ZXN0cy5hcnRpZmFjdHMuU3RhdGVPcHMuY29udHJhY3QuU3RhdGVBcHBHbG9iYWxDb250cmFjdC52ZXJpZnlfcHV0X3VpbnQ2NChhOiBieXRlcywgYjogdWludDY0KSAtPiB2b2lkOgp2ZXJpZnlfcHV0X3VpbnQ2NDoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTo0NDYtNDQ3CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gZGVmIHZlcmlmeV9wdXRfdWludDY0KHNlbGYsIGE6IEJ5dGVzLCBiOiBVSW50NjQpIC0+IE5vbmU6CiAgICBwcm90byAyIDAKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTo0NDgKICAgIC8vIG9wLkFwcEdsb2JhbC5wdXQoYSwgYikKICAgIGZyYW1lX2RpZyAtMgogICAgZnJhbWVfZGlnIC0xCiAgICBhcHBfZ2xvYmFsX3B1dAogICAgcmV0c3ViCgoKLy8gdGVzdHMuYXJ0aWZhY3RzLlN0YXRlT3BzLmNvbnRyYWN0LlN0YXRlQXBwR2xvYmFsQ29udHJhY3QudmVyaWZ5X3B1dF9ieXRlcyhhOiBieXRlcywgYjogYnl0ZXMpIC0+IHZvaWQ6CnZlcmlmeV9wdXRfYnl0ZXM6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6NDUwLTQ1MQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIGRlZiB2ZXJpZnlfcHV0X2J5dGVzKHNlbGYsIGE6IEJ5dGVzLCBiOiBCeXRlcykgLT4gTm9uZToKICAgIHByb3RvIDIgMAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjQ1MgogICAgLy8gb3AuQXBwR2xvYmFsLnB1dChhLCBiKQogICAgZnJhbWVfZGlnIC0yCiAgICBmcmFtZV9kaWcgLTEKICAgIGFwcF9nbG9iYWxfcHV0CiAgICByZXRzdWIK", + "clear": "I3ByYWdtYSB2ZXJzaW9uIDEwCgp0ZXN0cy5hcnRpZmFjdHMuU3RhdGVPcHMuY29udHJhY3QuU3RhdGVBcHBHbG9iYWxDb250cmFjdC5jbGVhcl9zdGF0ZV9wcm9ncmFtOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjQxMgogICAgLy8gY2xhc3MgU3RhdGVBcHBHbG9iYWxDb250cmFjdChBUkM0Q29udHJhY3QpOgogICAgaW50IDEKICAgIHJldHVybgo=" }, "state": { "global": { diff --git a/tests/artifacts/StateOps/data/StateAppGlobalContract.clear.teal b/tests/artifacts/StateOps/data/StateAppGlobalContract.clear.teal index 10b08e3..c48f7ac 100644 --- a/tests/artifacts/StateOps/data/StateAppGlobalContract.clear.teal +++ b/tests/artifacts/StateOps/data/StateAppGlobalContract.clear.teal @@ -1,7 +1,7 @@ #pragma version 10 tests.artifacts.StateOps.contract.StateAppGlobalContract.clear_state_program: - // tests/artifacts/StateOps/contract.py:294 + // tests/artifacts/StateOps/contract.py:412 // class StateAppGlobalContract(ARC4Contract): int 1 return diff --git a/tests/artifacts/StateOps/data/StateAppGlobalExContract.approval.teal b/tests/artifacts/StateOps/data/StateAppGlobalExContract.approval.teal index 6266646..b24e9e8 100644 --- a/tests/artifacts/StateOps/data/StateAppGlobalExContract.approval.teal +++ b/tests/artifacts/StateOps/data/StateAppGlobalExContract.approval.teal @@ -6,7 +6,7 @@ tests.artifacts.StateOps.contract.StateAppGlobalExContract.approval_program: callsub __init__ main_entrypoint@2: - // tests/artifacts/StateOps/contract.py:276 + // tests/artifacts/StateOps/contract.py:394 // class StateAppGlobalExContract(ARC4Contract): txn NumAppArgs ! @@ -23,53 +23,53 @@ main_entrypoint@2: // tests.artifacts.StateOps.contract.StateAppGlobalExContract.__init__() -> void: __init__: - // tests/artifacts/StateOps/contract.py:277 + // tests/artifacts/StateOps/contract.py:395 // def __init__(self) -> None: proto 0 0 - // tests/artifacts/StateOps/contract.py:280 + // tests/artifacts/StateOps/contract.py:398 // key="global_uint64", byte "global_uint64" - // tests/artifacts/StateOps/contract.py:279 + // tests/artifacts/StateOps/contract.py:397 // UInt64(2), int 2 - // tests/artifacts/StateOps/contract.py:278-281 + // tests/artifacts/StateOps/contract.py:396-399 // self.global_uint64 = GlobalState( // UInt64(2), // key="global_uint64", // ) app_global_put - // tests/artifacts/StateOps/contract.py:284 + // tests/artifacts/StateOps/contract.py:402 // key="global_bytes", byte "global_bytes" - // tests/artifacts/StateOps/contract.py:283 + // tests/artifacts/StateOps/contract.py:401 // Bytes(b"dummy_bytes"), byte 0x64756d6d795f6279746573 - // tests/artifacts/StateOps/contract.py:282-285 + // tests/artifacts/StateOps/contract.py:400-403 // self.global_bytes = GlobalState( // Bytes(b"dummy_bytes"), // key="global_bytes", // ) app_global_put - // tests/artifacts/StateOps/contract.py:286 + // tests/artifacts/StateOps/contract.py:404 // self.global_uint64_explicit = algopy.UInt64(2) byte "global_uint64_explicit" int 2 app_global_put - // tests/artifacts/StateOps/contract.py:287 + // tests/artifacts/StateOps/contract.py:405 // self.global_bytes_explicit = algopy.Bytes(b"dummy_bytes") byte "global_bytes_explicit" byte 0x64756d6d795f6279746573 app_global_put - // tests/artifacts/StateOps/contract.py:289 + // tests/artifacts/StateOps/contract.py:407 // algopy.arc4.DynamicBytes(b"dummy_arc4_bytes"), key="global_arc4_bytes" byte "global_arc4_bytes" byte 0x001064756d6d795f617263345f6279746573 - // tests/artifacts/StateOps/contract.py:288-290 + // tests/artifacts/StateOps/contract.py:406-408 // self.global_arc4_bytes = GlobalState( // algopy.arc4.DynamicBytes(b"dummy_arc4_bytes"), key="global_arc4_bytes" // ) app_global_put - // tests/artifacts/StateOps/contract.py:291 + // tests/artifacts/StateOps/contract.py:409 // self.global_arc4_bytes_explicit = algopy.arc4.DynamicBytes(b"dummy_arc4_bytes") byte "global_arc4_bytes_explicit" byte 0x001064756d6d795f617263345f6279746573 diff --git a/tests/artifacts/StateOps/data/StateAppGlobalExContract.arc32.json b/tests/artifacts/StateOps/data/StateAppGlobalExContract.arc32.json index 61f0a69..2c98652 100644 --- a/tests/artifacts/StateOps/data/StateAppGlobalExContract.arc32.json +++ b/tests/artifacts/StateOps/data/StateAppGlobalExContract.arc32.json @@ -1,8 +1,8 @@ { "hints": {}, "source": { - "approval": "I3ByYWdtYSB2ZXJzaW9uIDEwCgp0ZXN0cy5hcnRpZmFjdHMuU3RhdGVPcHMuY29udHJhY3QuU3RhdGVBcHBHbG9iYWxFeENvbnRyYWN0LmFwcHJvdmFsX3Byb2dyYW06CiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYm56IG1haW5fZW50cnlwb2ludEAyCiAgICBjYWxsc3ViIF9faW5pdF9fCgptYWluX2VudHJ5cG9pbnRAMjoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weToyNzYKICAgIC8vIGNsYXNzIFN0YXRlQXBwR2xvYmFsRXhDb250cmFjdChBUkM0Q29udHJhY3QpOgogICAgdHhuIE51bUFwcEFyZ3MKICAgICEKICAgIGFzc2VydCAvLyByZWplY3QgdHJhbnNhY3Rpb24KICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyByZWplY3QgdHJhbnNhY3Rpb24KICAgIHR4biBBcHBsaWNhdGlvbklECiAgICAhCiAgICBhc3NlcnQgLy8gaXMgY3JlYXRpbmcKICAgIGludCAxCiAgICByZXR1cm4KCgovLyB0ZXN0cy5hcnRpZmFjdHMuU3RhdGVPcHMuY29udHJhY3QuU3RhdGVBcHBHbG9iYWxFeENvbnRyYWN0Ll9faW5pdF9fKCkgLT4gdm9pZDoKX19pbml0X186CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6Mjc3CiAgICAvLyBkZWYgX19pbml0X18oc2VsZikgLT4gTm9uZToKICAgIHByb3RvIDAgMAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjI4MAogICAgLy8ga2V5PSJnbG9iYWxfdWludDY0IiwKICAgIGJ5dGUgImdsb2JhbF91aW50NjQiCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6Mjc5CiAgICAvLyBVSW50NjQoMiksCiAgICBpbnQgMgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjI3OC0yODEKICAgIC8vIHNlbGYuZ2xvYmFsX3VpbnQ2NCA9IEdsb2JhbFN0YXRlKAogICAgLy8gICAgIFVJbnQ2NCgyKSwKICAgIC8vICAgICBrZXk9Imdsb2JhbF91aW50NjQiLAogICAgLy8gKQogICAgYXBwX2dsb2JhbF9wdXQKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weToyODQKICAgIC8vIGtleT0iZ2xvYmFsX2J5dGVzIiwKICAgIGJ5dGUgImdsb2JhbF9ieXRlcyIKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weToyODMKICAgIC8vIEJ5dGVzKGIiZHVtbXlfYnl0ZXMiKSwKICAgIGJ5dGUgMHg2NDc1NmQ2ZDc5NWY2Mjc5NzQ2NTczCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6MjgyLTI4NQogICAgLy8gc2VsZi5nbG9iYWxfYnl0ZXMgPSBHbG9iYWxTdGF0ZSgKICAgIC8vICAgICBCeXRlcyhiImR1bW15X2J5dGVzIiksCiAgICAvLyAgICAga2V5PSJnbG9iYWxfYnl0ZXMiLAogICAgLy8gKQogICAgYXBwX2dsb2JhbF9wdXQKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weToyODYKICAgIC8vIHNlbGYuZ2xvYmFsX3VpbnQ2NF9leHBsaWNpdCA9IGFsZ29weS5VSW50NjQoMikKICAgIGJ5dGUgImdsb2JhbF91aW50NjRfZXhwbGljaXQiCiAgICBpbnQgMgogICAgYXBwX2dsb2JhbF9wdXQKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weToyODcKICAgIC8vIHNlbGYuZ2xvYmFsX2J5dGVzX2V4cGxpY2l0ID0gYWxnb3B5LkJ5dGVzKGIiZHVtbXlfYnl0ZXMiKQogICAgYnl0ZSAiZ2xvYmFsX2J5dGVzX2V4cGxpY2l0IgogICAgYnl0ZSAweDY0NzU2ZDZkNzk1ZjYyNzk3NDY1NzMKICAgIGFwcF9nbG9iYWxfcHV0CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6Mjg5CiAgICAvLyBhbGdvcHkuYXJjNC5EeW5hbWljQnl0ZXMoYiJkdW1teV9hcmM0X2J5dGVzIiksIGtleT0iZ2xvYmFsX2FyYzRfYnl0ZXMiCiAgICBieXRlICJnbG9iYWxfYXJjNF9ieXRlcyIKICAgIGJ5dGUgMHgwMDEwNjQ3NTZkNmQ3OTVmNjE3MjYzMzQ1ZjYyNzk3NDY1NzMKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weToyODgtMjkwCiAgICAvLyBzZWxmLmdsb2JhbF9hcmM0X2J5dGVzID0gR2xvYmFsU3RhdGUoCiAgICAvLyAgICAgYWxnb3B5LmFyYzQuRHluYW1pY0J5dGVzKGIiZHVtbXlfYXJjNF9ieXRlcyIpLCBrZXk9Imdsb2JhbF9hcmM0X2J5dGVzIgogICAgLy8gKQogICAgYXBwX2dsb2JhbF9wdXQKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weToyOTEKICAgIC8vIHNlbGYuZ2xvYmFsX2FyYzRfYnl0ZXNfZXhwbGljaXQgPSBhbGdvcHkuYXJjNC5EeW5hbWljQnl0ZXMoYiJkdW1teV9hcmM0X2J5dGVzIikKICAgIGJ5dGUgImdsb2JhbF9hcmM0X2J5dGVzX2V4cGxpY2l0IgogICAgYnl0ZSAweDAwMTA2NDc1NmQ2ZDc5NWY2MTcyNjMzNDVmNjI3OTc0NjU3MwogICAgYXBwX2dsb2JhbF9wdXQKICAgIHJldHN1Ygo=", - "clear": "I3ByYWdtYSB2ZXJzaW9uIDEwCgp0ZXN0cy5hcnRpZmFjdHMuU3RhdGVPcHMuY29udHJhY3QuU3RhdGVBcHBHbG9iYWxFeENvbnRyYWN0LmNsZWFyX3N0YXRlX3Byb2dyYW06CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6Mjc2CiAgICAvLyBjbGFzcyBTdGF0ZUFwcEdsb2JhbEV4Q29udHJhY3QoQVJDNENvbnRyYWN0KToKICAgIGludCAxCiAgICByZXR1cm4K" + "approval": "I3ByYWdtYSB2ZXJzaW9uIDEwCgp0ZXN0cy5hcnRpZmFjdHMuU3RhdGVPcHMuY29udHJhY3QuU3RhdGVBcHBHbG9iYWxFeENvbnRyYWN0LmFwcHJvdmFsX3Byb2dyYW06CiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYm56IG1haW5fZW50cnlwb2ludEAyCiAgICBjYWxsc3ViIF9faW5pdF9fCgptYWluX2VudHJ5cG9pbnRAMjoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTozOTQKICAgIC8vIGNsYXNzIFN0YXRlQXBwR2xvYmFsRXhDb250cmFjdChBUkM0Q29udHJhY3QpOgogICAgdHhuIE51bUFwcEFyZ3MKICAgICEKICAgIGFzc2VydCAvLyByZWplY3QgdHJhbnNhY3Rpb24KICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyByZWplY3QgdHJhbnNhY3Rpb24KICAgIHR4biBBcHBsaWNhdGlvbklECiAgICAhCiAgICBhc3NlcnQgLy8gaXMgY3JlYXRpbmcKICAgIGludCAxCiAgICByZXR1cm4KCgovLyB0ZXN0cy5hcnRpZmFjdHMuU3RhdGVPcHMuY29udHJhY3QuU3RhdGVBcHBHbG9iYWxFeENvbnRyYWN0Ll9faW5pdF9fKCkgLT4gdm9pZDoKX19pbml0X186CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6Mzk1CiAgICAvLyBkZWYgX19pbml0X18oc2VsZikgLT4gTm9uZToKICAgIHByb3RvIDAgMAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjM5OAogICAgLy8ga2V5PSJnbG9iYWxfdWludDY0IiwKICAgIGJ5dGUgImdsb2JhbF91aW50NjQiCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6Mzk3CiAgICAvLyBVSW50NjQoMiksCiAgICBpbnQgMgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjM5Ni0zOTkKICAgIC8vIHNlbGYuZ2xvYmFsX3VpbnQ2NCA9IEdsb2JhbFN0YXRlKAogICAgLy8gICAgIFVJbnQ2NCgyKSwKICAgIC8vICAgICBrZXk9Imdsb2JhbF91aW50NjQiLAogICAgLy8gKQogICAgYXBwX2dsb2JhbF9wdXQKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTo0MDIKICAgIC8vIGtleT0iZ2xvYmFsX2J5dGVzIiwKICAgIGJ5dGUgImdsb2JhbF9ieXRlcyIKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTo0MDEKICAgIC8vIEJ5dGVzKGIiZHVtbXlfYnl0ZXMiKSwKICAgIGJ5dGUgMHg2NDc1NmQ2ZDc5NWY2Mjc5NzQ2NTczCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6NDAwLTQwMwogICAgLy8gc2VsZi5nbG9iYWxfYnl0ZXMgPSBHbG9iYWxTdGF0ZSgKICAgIC8vICAgICBCeXRlcyhiImR1bW15X2J5dGVzIiksCiAgICAvLyAgICAga2V5PSJnbG9iYWxfYnl0ZXMiLAogICAgLy8gKQogICAgYXBwX2dsb2JhbF9wdXQKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTo0MDQKICAgIC8vIHNlbGYuZ2xvYmFsX3VpbnQ2NF9leHBsaWNpdCA9IGFsZ29weS5VSW50NjQoMikKICAgIGJ5dGUgImdsb2JhbF91aW50NjRfZXhwbGljaXQiCiAgICBpbnQgMgogICAgYXBwX2dsb2JhbF9wdXQKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTo0MDUKICAgIC8vIHNlbGYuZ2xvYmFsX2J5dGVzX2V4cGxpY2l0ID0gYWxnb3B5LkJ5dGVzKGIiZHVtbXlfYnl0ZXMiKQogICAgYnl0ZSAiZ2xvYmFsX2J5dGVzX2V4cGxpY2l0IgogICAgYnl0ZSAweDY0NzU2ZDZkNzk1ZjYyNzk3NDY1NzMKICAgIGFwcF9nbG9iYWxfcHV0CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6NDA3CiAgICAvLyBhbGdvcHkuYXJjNC5EeW5hbWljQnl0ZXMoYiJkdW1teV9hcmM0X2J5dGVzIiksIGtleT0iZ2xvYmFsX2FyYzRfYnl0ZXMiCiAgICBieXRlICJnbG9iYWxfYXJjNF9ieXRlcyIKICAgIGJ5dGUgMHgwMDEwNjQ3NTZkNmQ3OTVmNjE3MjYzMzQ1ZjYyNzk3NDY1NzMKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTo0MDYtNDA4CiAgICAvLyBzZWxmLmdsb2JhbF9hcmM0X2J5dGVzID0gR2xvYmFsU3RhdGUoCiAgICAvLyAgICAgYWxnb3B5LmFyYzQuRHluYW1pY0J5dGVzKGIiZHVtbXlfYXJjNF9ieXRlcyIpLCBrZXk9Imdsb2JhbF9hcmM0X2J5dGVzIgogICAgLy8gKQogICAgYXBwX2dsb2JhbF9wdXQKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTo0MDkKICAgIC8vIHNlbGYuZ2xvYmFsX2FyYzRfYnl0ZXNfZXhwbGljaXQgPSBhbGdvcHkuYXJjNC5EeW5hbWljQnl0ZXMoYiJkdW1teV9hcmM0X2J5dGVzIikKICAgIGJ5dGUgImdsb2JhbF9hcmM0X2J5dGVzX2V4cGxpY2l0IgogICAgYnl0ZSAweDAwMTA2NDc1NmQ2ZDc5NWY2MTcyNjMzNDVmNjI3OTc0NjU3MwogICAgYXBwX2dsb2JhbF9wdXQKICAgIHJldHN1Ygo=", + "clear": "I3ByYWdtYSB2ZXJzaW9uIDEwCgp0ZXN0cy5hcnRpZmFjdHMuU3RhdGVPcHMuY29udHJhY3QuU3RhdGVBcHBHbG9iYWxFeENvbnRyYWN0LmNsZWFyX3N0YXRlX3Byb2dyYW06CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6Mzk0CiAgICAvLyBjbGFzcyBTdGF0ZUFwcEdsb2JhbEV4Q29udHJhY3QoQVJDNENvbnRyYWN0KToKICAgIGludCAxCiAgICByZXR1cm4K" }, "state": { "global": { diff --git a/tests/artifacts/StateOps/data/StateAppGlobalExContract.clear.teal b/tests/artifacts/StateOps/data/StateAppGlobalExContract.clear.teal index 6cfa0ba..72a52b0 100644 --- a/tests/artifacts/StateOps/data/StateAppGlobalExContract.clear.teal +++ b/tests/artifacts/StateOps/data/StateAppGlobalExContract.clear.teal @@ -1,7 +1,7 @@ #pragma version 10 tests.artifacts.StateOps.contract.StateAppGlobalExContract.clear_state_program: - // tests/artifacts/StateOps/contract.py:276 + // tests/artifacts/StateOps/contract.py:394 // class StateAppGlobalExContract(ARC4Contract): int 1 return diff --git a/tests/artifacts/StateOps/data/StateAppLocalContract.approval.teal b/tests/artifacts/StateOps/data/StateAppLocalContract.approval.teal index 67c2a57..0f43da7 100644 --- a/tests/artifacts/StateOps/data/StateAppLocalContract.approval.teal +++ b/tests/artifacts/StateOps/data/StateAppLocalContract.approval.teal @@ -1,24 +1,25 @@ #pragma version 10 tests.artifacts.StateOps.contract.StateAppLocalContract.approval_program: - // tests/artifacts/StateOps/contract.py:226 + // tests/artifacts/StateOps/contract.py:339 // class StateAppLocalContract(ARC4Contract): txn NumAppArgs - bz main_bare_routing@12 + bz main_bare_routing@13 method "opt_in()void" method "verify_get_bytes(account,byte[])byte[]" method "verify_get_uint64(account,byte[])uint64" method "verify_get_ex_bytes(account,application,byte[])byte[]" method "verify_get_ex_uint64(account,application,byte[])uint64" method "verify_delete(account,byte[])void" + method "verify_exists(account,byte[])bool" method "verify_put_uint64(account,byte[],uint64)void" method "verify_put_bytes(account,byte[],byte[])void" txna ApplicationArgs 0 - match main_opt_in_route@2 main_verify_get_bytes_route@3 main_verify_get_uint64_route@4 main_verify_get_ex_bytes_route@5 main_verify_get_ex_uint64_route@6 main_verify_delete_route@7 main_verify_put_uint64_route@8 main_verify_put_bytes_route@9 + match main_opt_in_route@2 main_verify_get_bytes_route@3 main_verify_get_uint64_route@4 main_verify_get_ex_bytes_route@5 main_verify_get_ex_uint64_route@6 main_verify_delete_route@7 main_verify_exists_route@8 main_verify_put_uint64_route@9 main_verify_put_bytes_route@10 err // reject transaction main_opt_in_route@2: - // tests/artifacts/StateOps/contract.py:238 + // tests/artifacts/StateOps/contract.py:351 // @arc4.abimethod(allow_actions=["OptIn"]) txn OnCompletion int OptIn @@ -31,21 +32,21 @@ main_opt_in_route@2: return main_verify_get_bytes_route@3: - // tests/artifacts/StateOps/contract.py:243 + // tests/artifacts/StateOps/contract.py:356 // @arc4.abimethod() txn OnCompletion ! assert // OnCompletion is NoOp txn ApplicationID assert // is not creating - // tests/artifacts/StateOps/contract.py:226 + // tests/artifacts/StateOps/contract.py:339 // class StateAppLocalContract(ARC4Contract): txna ApplicationArgs 1 btoi txnas Accounts txna ApplicationArgs 2 extract 2 0 - // tests/artifacts/StateOps/contract.py:243 + // tests/artifacts/StateOps/contract.py:356 // @arc4.abimethod() callsub verify_get_bytes dup @@ -62,21 +63,21 @@ main_verify_get_bytes_route@3: return main_verify_get_uint64_route@4: - // tests/artifacts/StateOps/contract.py:248 + // tests/artifacts/StateOps/contract.py:361 // @arc4.abimethod() txn OnCompletion ! assert // OnCompletion is NoOp txn ApplicationID assert // is not creating - // tests/artifacts/StateOps/contract.py:226 + // tests/artifacts/StateOps/contract.py:339 // class StateAppLocalContract(ARC4Contract): txna ApplicationArgs 1 btoi txnas Accounts txna ApplicationArgs 2 extract 2 0 - // tests/artifacts/StateOps/contract.py:248 + // tests/artifacts/StateOps/contract.py:361 // @arc4.abimethod() callsub verify_get_uint64 itob @@ -88,14 +89,14 @@ main_verify_get_uint64_route@4: return main_verify_get_ex_bytes_route@5: - // tests/artifacts/StateOps/contract.py:253 + // tests/artifacts/StateOps/contract.py:366 // @arc4.abimethod() txn OnCompletion ! assert // OnCompletion is NoOp txn ApplicationID assert // is not creating - // tests/artifacts/StateOps/contract.py:226 + // tests/artifacts/StateOps/contract.py:339 // class StateAppLocalContract(ARC4Contract): txna ApplicationArgs 1 btoi @@ -105,7 +106,7 @@ main_verify_get_ex_bytes_route@5: txnas Applications txna ApplicationArgs 3 extract 2 0 - // tests/artifacts/StateOps/contract.py:253 + // tests/artifacts/StateOps/contract.py:366 // @arc4.abimethod() callsub verify_get_ex_bytes dup @@ -122,14 +123,14 @@ main_verify_get_ex_bytes_route@5: return main_verify_get_ex_uint64_route@6: - // tests/artifacts/StateOps/contract.py:258 + // tests/artifacts/StateOps/contract.py:371 // @arc4.abimethod() txn OnCompletion ! assert // OnCompletion is NoOp txn ApplicationID assert // is not creating - // tests/artifacts/StateOps/contract.py:226 + // tests/artifacts/StateOps/contract.py:339 // class StateAppLocalContract(ARC4Contract): txna ApplicationArgs 1 btoi @@ -139,7 +140,7 @@ main_verify_get_ex_uint64_route@6: txnas Applications txna ApplicationArgs 3 extract 2 0 - // tests/artifacts/StateOps/contract.py:258 + // tests/artifacts/StateOps/contract.py:371 // @arc4.abimethod() callsub verify_get_ex_uint64 itob @@ -151,35 +152,64 @@ main_verify_get_ex_uint64_route@6: return main_verify_delete_route@7: - // tests/artifacts/StateOps/contract.py:263 + // tests/artifacts/StateOps/contract.py:376 // @arc4.abimethod() txn OnCompletion ! assert // OnCompletion is NoOp txn ApplicationID assert // is not creating - // tests/artifacts/StateOps/contract.py:226 + // tests/artifacts/StateOps/contract.py:339 // class StateAppLocalContract(ARC4Contract): txna ApplicationArgs 1 btoi txnas Accounts txna ApplicationArgs 2 extract 2 0 - // tests/artifacts/StateOps/contract.py:263 + // tests/artifacts/StateOps/contract.py:376 // @arc4.abimethod() callsub verify_delete int 1 return -main_verify_put_uint64_route@8: - // tests/artifacts/StateOps/contract.py:267 +main_verify_exists_route@8: + // tests/artifacts/StateOps/contract.py:380 // @arc4.abimethod() txn OnCompletion ! assert // OnCompletion is NoOp txn ApplicationID assert // is not creating - // tests/artifacts/StateOps/contract.py:226 + // tests/artifacts/StateOps/contract.py:339 + // class StateAppLocalContract(ARC4Contract): + txna ApplicationArgs 1 + btoi + txnas Accounts + txna ApplicationArgs 2 + extract 2 0 + // tests/artifacts/StateOps/contract.py:380 + // @arc4.abimethod() + callsub verify_exists + byte 0x00 + int 0 + uncover 2 + setbit + byte 0x151f7c75 + swap + concat + log + int 1 + return + +main_verify_put_uint64_route@9: + // tests/artifacts/StateOps/contract.py:385 + // @arc4.abimethod() + txn OnCompletion + ! + assert // OnCompletion is NoOp + txn ApplicationID + assert // is not creating + // tests/artifacts/StateOps/contract.py:339 // class StateAppLocalContract(ARC4Contract): txna ApplicationArgs 1 btoi @@ -188,21 +218,21 @@ main_verify_put_uint64_route@8: extract 2 0 txna ApplicationArgs 3 btoi - // tests/artifacts/StateOps/contract.py:267 + // tests/artifacts/StateOps/contract.py:385 // @arc4.abimethod() callsub verify_put_uint64 int 1 return -main_verify_put_bytes_route@9: - // tests/artifacts/StateOps/contract.py:271 +main_verify_put_bytes_route@10: + // tests/artifacts/StateOps/contract.py:389 // @arc4.abimethod() txn OnCompletion ! assert // OnCompletion is NoOp txn ApplicationID assert // is not creating - // tests/artifacts/StateOps/contract.py:226 + // tests/artifacts/StateOps/contract.py:339 // class StateAppLocalContract(ARC4Contract): txna ApplicationArgs 1 btoi @@ -211,14 +241,14 @@ main_verify_put_bytes_route@9: extract 2 0 txna ApplicationArgs 3 extract 2 0 - // tests/artifacts/StateOps/contract.py:271 + // tests/artifacts/StateOps/contract.py:389 // @arc4.abimethod() callsub verify_put_bytes int 1 return -main_bare_routing@12: - // tests/artifacts/StateOps/contract.py:226 +main_bare_routing@13: + // tests/artifacts/StateOps/contract.py:339 // class StateAppLocalContract(ARC4Contract): txn OnCompletion ! @@ -232,27 +262,27 @@ main_bare_routing@12: // tests.artifacts.StateOps.contract.StateAppLocalContract.opt_in() -> void: opt_in: - // tests/artifacts/StateOps/contract.py:238-239 + // tests/artifacts/StateOps/contract.py:351-352 // @arc4.abimethod(allow_actions=["OptIn"]) // def opt_in(self) -> None: proto 0 0 - // tests/artifacts/StateOps/contract.py:240 + // tests/artifacts/StateOps/contract.py:353 // self.local_bytes[Global.creator_address] = Bytes(b"dummy_bytes") global CreatorAddress - // tests/artifacts/StateOps/contract.py:235 + // tests/artifacts/StateOps/contract.py:348 // key="local_bytes", byte "local_bytes" - // tests/artifacts/StateOps/contract.py:240 + // tests/artifacts/StateOps/contract.py:353 // self.local_bytes[Global.creator_address] = Bytes(b"dummy_bytes") byte 0x64756d6d795f6279746573 app_local_put - // tests/artifacts/StateOps/contract.py:241 + // tests/artifacts/StateOps/contract.py:354 // self.local_uint64[Global.creator_address] = UInt64(999) global CreatorAddress - // tests/artifacts/StateOps/contract.py:230 + // tests/artifacts/StateOps/contract.py:343 // key="local_uint64", byte "local_uint64" - // tests/artifacts/StateOps/contract.py:241 + // tests/artifacts/StateOps/contract.py:354 // self.local_uint64[Global.creator_address] = UInt64(999) int 999 app_local_put @@ -261,79 +291,79 @@ opt_in: // tests.artifacts.StateOps.contract.StateAppLocalContract.verify_get_bytes(a: bytes, b: bytes) -> bytes: verify_get_bytes: - // tests/artifacts/StateOps/contract.py:243-244 + // tests/artifacts/StateOps/contract.py:356-357 // @arc4.abimethod() // def verify_get_bytes(self, a: Account, b: Bytes) -> Bytes: proto 2 1 - // tests/artifacts/StateOps/contract.py:245 + // tests/artifacts/StateOps/contract.py:358 // value = op.AppLocal.get_bytes(a, b) frame_dig -2 frame_dig -1 app_local_get - // tests/artifacts/StateOps/contract.py:246 + // tests/artifacts/StateOps/contract.py:359 // return value retsub // tests.artifacts.StateOps.contract.StateAppLocalContract.verify_get_uint64(a: bytes, b: bytes) -> uint64: verify_get_uint64: - // tests/artifacts/StateOps/contract.py:248-249 + // tests/artifacts/StateOps/contract.py:361-362 // @arc4.abimethod() // def verify_get_uint64(self, a: Account, b: Bytes) -> UInt64: proto 2 1 - // tests/artifacts/StateOps/contract.py:250 + // tests/artifacts/StateOps/contract.py:363 // value = op.AppLocal.get_uint64(a, b) frame_dig -2 frame_dig -1 app_local_get - // tests/artifacts/StateOps/contract.py:251 + // tests/artifacts/StateOps/contract.py:364 // return value retsub // tests.artifacts.StateOps.contract.StateAppLocalContract.verify_get_ex_bytes(a: bytes, b: uint64, c: bytes) -> bytes: verify_get_ex_bytes: - // tests/artifacts/StateOps/contract.py:253-254 + // tests/artifacts/StateOps/contract.py:366-367 // @arc4.abimethod() // def verify_get_ex_bytes(self, a: Account, b: Application, c: Bytes) -> Bytes: proto 3 1 - // tests/artifacts/StateOps/contract.py:255 + // tests/artifacts/StateOps/contract.py:368 // value, _val = op.AppLocal.get_ex_bytes(a, b, c) frame_dig -3 frame_dig -2 frame_dig -1 app_local_get_ex pop - // tests/artifacts/StateOps/contract.py:256 + // tests/artifacts/StateOps/contract.py:369 // return value retsub // tests.artifacts.StateOps.contract.StateAppLocalContract.verify_get_ex_uint64(a: bytes, b: uint64, c: bytes) -> uint64: verify_get_ex_uint64: - // tests/artifacts/StateOps/contract.py:258-259 + // tests/artifacts/StateOps/contract.py:371-372 // @arc4.abimethod() // def verify_get_ex_uint64(self, a: Account, b: Application, c: Bytes) -> UInt64: proto 3 1 - // tests/artifacts/StateOps/contract.py:260 + // tests/artifacts/StateOps/contract.py:373 // value, _val = op.AppLocal.get_ex_uint64(a, b, c) frame_dig -3 frame_dig -2 frame_dig -1 app_local_get_ex pop - // tests/artifacts/StateOps/contract.py:261 + // tests/artifacts/StateOps/contract.py:374 // return value retsub // tests.artifacts.StateOps.contract.StateAppLocalContract.verify_delete(a: bytes, b: bytes) -> void: verify_delete: - // tests/artifacts/StateOps/contract.py:263-264 + // tests/artifacts/StateOps/contract.py:376-377 // @arc4.abimethod() // def verify_delete(self, a: Account, b: Bytes) -> None: proto 2 0 - // tests/artifacts/StateOps/contract.py:265 + // tests/artifacts/StateOps/contract.py:378 // op.AppLocal.delete(a, b) frame_dig -2 frame_dig -1 @@ -341,13 +371,31 @@ verify_delete: retsub +// tests.artifacts.StateOps.contract.StateAppLocalContract.verify_exists(a: bytes, b: bytes) -> uint64: +verify_exists: + // tests/artifacts/StateOps/contract.py:380-381 + // @arc4.abimethod() + // def verify_exists(self, a: Account, b: Bytes) -> bool: + proto 2 1 + // tests/artifacts/StateOps/contract.py:382 + // _value, exists = op.AppLocal.get_ex_uint64(a, 0, b) + frame_dig -2 + int 0 + frame_dig -1 + app_local_get_ex + bury 1 + // tests/artifacts/StateOps/contract.py:383 + // return exists + retsub + + // tests.artifacts.StateOps.contract.StateAppLocalContract.verify_put_uint64(a: bytes, b: bytes, c: uint64) -> void: verify_put_uint64: - // tests/artifacts/StateOps/contract.py:267-268 + // tests/artifacts/StateOps/contract.py:385-386 // @arc4.abimethod() // def verify_put_uint64(self, a: Account, b: Bytes, c: UInt64) -> None: proto 3 0 - // tests/artifacts/StateOps/contract.py:269 + // tests/artifacts/StateOps/contract.py:387 // op.AppLocal.put(a, b, c) frame_dig -3 frame_dig -2 @@ -358,11 +406,11 @@ verify_put_uint64: // tests.artifacts.StateOps.contract.StateAppLocalContract.verify_put_bytes(a: bytes, b: bytes, c: bytes) -> void: verify_put_bytes: - // tests/artifacts/StateOps/contract.py:271-272 + // tests/artifacts/StateOps/contract.py:389-390 // @arc4.abimethod() // def verify_put_bytes(self, a: Account, b: Bytes, c: Bytes) -> None: proto 3 0 - // tests/artifacts/StateOps/contract.py:273 + // tests/artifacts/StateOps/contract.py:391 // op.AppLocal.put(a, b, c) frame_dig -3 frame_dig -2 diff --git a/tests/artifacts/StateOps/data/StateAppLocalContract.arc32.json b/tests/artifacts/StateOps/data/StateAppLocalContract.arc32.json index 39a31ec..3446b18 100644 --- a/tests/artifacts/StateOps/data/StateAppLocalContract.arc32.json +++ b/tests/artifacts/StateOps/data/StateAppLocalContract.arc32.json @@ -30,6 +30,11 @@ "no_op": "CALL" } }, + "verify_exists(account,byte[])bool": { + "call_config": { + "no_op": "CALL" + } + }, "verify_put_uint64(account,byte[],uint64)void": { "call_config": { "no_op": "CALL" @@ -42,8 +47,8 @@ } }, "source": { - "approval": "I3ByYWdtYSB2ZXJzaW9uIDEwCgp0ZXN0cy5hcnRpZmFjdHMuU3RhdGVPcHMuY29udHJhY3QuU3RhdGVBcHBMb2NhbENvbnRyYWN0LmFwcHJvdmFsX3Byb2dyYW06CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6MjI2CiAgICAvLyBjbGFzcyBTdGF0ZUFwcExvY2FsQ29udHJhY3QoQVJDNENvbnRyYWN0KToKICAgIHR4biBOdW1BcHBBcmdzCiAgICBieiBtYWluX2JhcmVfcm91dGluZ0AxMgogICAgbWV0aG9kICJvcHRfaW4oKXZvaWQiCiAgICBtZXRob2QgInZlcmlmeV9nZXRfYnl0ZXMoYWNjb3VudCxieXRlW10pYnl0ZVtdIgogICAgbWV0aG9kICJ2ZXJpZnlfZ2V0X3VpbnQ2NChhY2NvdW50LGJ5dGVbXSl1aW50NjQiCiAgICBtZXRob2QgInZlcmlmeV9nZXRfZXhfYnl0ZXMoYWNjb3VudCxhcHBsaWNhdGlvbixieXRlW10pYnl0ZVtdIgogICAgbWV0aG9kICJ2ZXJpZnlfZ2V0X2V4X3VpbnQ2NChhY2NvdW50LGFwcGxpY2F0aW9uLGJ5dGVbXSl1aW50NjQiCiAgICBtZXRob2QgInZlcmlmeV9kZWxldGUoYWNjb3VudCxieXRlW10pdm9pZCIKICAgIG1ldGhvZCAidmVyaWZ5X3B1dF91aW50NjQoYWNjb3VudCxieXRlW10sdWludDY0KXZvaWQiCiAgICBtZXRob2QgInZlcmlmeV9wdXRfYnl0ZXMoYWNjb3VudCxieXRlW10sYnl0ZVtdKXZvaWQiCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAwCiAgICBtYXRjaCBtYWluX29wdF9pbl9yb3V0ZUAyIG1haW5fdmVyaWZ5X2dldF9ieXRlc19yb3V0ZUAzIG1haW5fdmVyaWZ5X2dldF91aW50NjRfcm91dGVANCBtYWluX3ZlcmlmeV9nZXRfZXhfYnl0ZXNfcm91dGVANSBtYWluX3ZlcmlmeV9nZXRfZXhfdWludDY0X3JvdXRlQDYgbWFpbl92ZXJpZnlfZGVsZXRlX3JvdXRlQDcgbWFpbl92ZXJpZnlfcHV0X3VpbnQ2NF9yb3V0ZUA4IG1haW5fdmVyaWZ5X3B1dF9ieXRlc19yb3V0ZUA5CiAgICBlcnIgLy8gcmVqZWN0IHRyYW5zYWN0aW9uCgptYWluX29wdF9pbl9yb3V0ZUAyOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjIzOAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKGFsbG93X2FjdGlvbnM9WyJPcHRJbiJdKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgaW50IE9wdEluCiAgICA9PQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBPcHRJbgogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBpcyBub3QgY3JlYXRpbmcKICAgIGNhbGxzdWIgb3B0X2luCiAgICBpbnQgMQogICAgcmV0dXJuCgptYWluX3ZlcmlmeV9nZXRfYnl0ZXNfcm91dGVAMzoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weToyNDMKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gaXMgbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6MjI2CiAgICAvLyBjbGFzcyBTdGF0ZUFwcExvY2FsQ29udHJhY3QoQVJDNENvbnRyYWN0KToKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGJ0b2kKICAgIHR4bmFzIEFjY291bnRzCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAyCiAgICBleHRyYWN0IDIgMAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjI0MwogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X2dldF9ieXRlcwogICAgZHVwCiAgICBsZW4KICAgIGl0b2IKICAgIGV4dHJhY3QgNiAyCiAgICBzd2FwCiAgICBjb25jYXQKICAgIGJ5dGUgMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludCAxCiAgICByZXR1cm4KCm1haW5fdmVyaWZ5X2dldF91aW50NjRfcm91dGVANDoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weToyNDgKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gaXMgbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6MjI2CiAgICAvLyBjbGFzcyBTdGF0ZUFwcExvY2FsQ29udHJhY3QoQVJDNENvbnRyYWN0KToKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGJ0b2kKICAgIHR4bmFzIEFjY291bnRzCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAyCiAgICBleHRyYWN0IDIgMAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjI0OAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X2dldF91aW50NjQKICAgIGl0b2IKICAgIGJ5dGUgMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludCAxCiAgICByZXR1cm4KCm1haW5fdmVyaWZ5X2dldF9leF9ieXRlc19yb3V0ZUA1OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjI1MwogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBpcyBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weToyMjYKICAgIC8vIGNsYXNzIFN0YXRlQXBwTG9jYWxDb250cmFjdChBUkM0Q29udHJhY3QpOgogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgYnRvaQogICAgdHhuYXMgQWNjb3VudHMKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDIKICAgIGJ0b2kKICAgIHR4bmFzIEFwcGxpY2F0aW9ucwogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMwogICAgZXh0cmFjdCAyIDAKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weToyNTMKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV9nZXRfZXhfYnl0ZXMKICAgIGR1cAogICAgbGVuCiAgICBpdG9iCiAgICBleHRyYWN0IDYgMgogICAgc3dhcAogICAgY29uY2F0CiAgICBieXRlIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnQgMQogICAgcmV0dXJuCgptYWluX3ZlcmlmeV9nZXRfZXhfdWludDY0X3JvdXRlQDY6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6MjU4CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGlzIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjIyNgogICAgLy8gY2xhc3MgU3RhdGVBcHBMb2NhbENvbnRyYWN0KEFSQzRDb250cmFjdCk6CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBidG9pCiAgICB0eG5hcyBBY2NvdW50cwogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMgogICAgYnRvaQogICAgdHhuYXMgQXBwbGljYXRpb25zCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAzCiAgICBleHRyYWN0IDIgMAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjI1OAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X2dldF9leF91aW50NjQKICAgIGl0b2IKICAgIGJ5dGUgMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludCAxCiAgICByZXR1cm4KCm1haW5fdmVyaWZ5X2RlbGV0ZV9yb3V0ZUA3OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjI2MwogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBpcyBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weToyMjYKICAgIC8vIGNsYXNzIFN0YXRlQXBwTG9jYWxDb250cmFjdChBUkM0Q29udHJhY3QpOgogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgYnRvaQogICAgdHhuYXMgQWNjb3VudHMKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDIKICAgIGV4dHJhY3QgMiAwCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6MjYzCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfZGVsZXRlCiAgICBpbnQgMQogICAgcmV0dXJuCgptYWluX3ZlcmlmeV9wdXRfdWludDY0X3JvdXRlQDg6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6MjY3CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGlzIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjIyNgogICAgLy8gY2xhc3MgU3RhdGVBcHBMb2NhbENvbnRyYWN0KEFSQzRDb250cmFjdCk6CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBidG9pCiAgICB0eG5hcyBBY2NvdW50cwogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMgogICAgZXh0cmFjdCAyIDAKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDMKICAgIGJ0b2kKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weToyNjcKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV9wdXRfdWludDY0CiAgICBpbnQgMQogICAgcmV0dXJuCgptYWluX3ZlcmlmeV9wdXRfYnl0ZXNfcm91dGVAOToKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weToyNzEKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gaXMgbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6MjI2CiAgICAvLyBjbGFzcyBTdGF0ZUFwcExvY2FsQ29udHJhY3QoQVJDNENvbnRyYWN0KToKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGJ0b2kKICAgIHR4bmFzIEFjY291bnRzCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAyCiAgICBleHRyYWN0IDIgMAogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMwogICAgZXh0cmFjdCAyIDAKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weToyNzEKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV9wdXRfYnl0ZXMKICAgIGludCAxCiAgICByZXR1cm4KCm1haW5fYmFyZV9yb3V0aW5nQDEyOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjIyNgogICAgLy8gY2xhc3MgU3RhdGVBcHBMb2NhbENvbnRyYWN0KEFSQzRDb250cmFjdCk6CiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gcmVqZWN0IHRyYW5zYWN0aW9uCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgIQogICAgYXNzZXJ0IC8vIGlzIGNyZWF0aW5nCiAgICBpbnQgMQogICAgcmV0dXJuCgoKLy8gdGVzdHMuYXJ0aWZhY3RzLlN0YXRlT3BzLmNvbnRyYWN0LlN0YXRlQXBwTG9jYWxDb250cmFjdC5vcHRfaW4oKSAtPiB2b2lkOgpvcHRfaW46CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6MjM4LTIzOQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKGFsbG93X2FjdGlvbnM9WyJPcHRJbiJdKQogICAgLy8gZGVmIG9wdF9pbihzZWxmKSAtPiBOb25lOgogICAgcHJvdG8gMCAwCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6MjQwCiAgICAvLyBzZWxmLmxvY2FsX2J5dGVzW0dsb2JhbC5jcmVhdG9yX2FkZHJlc3NdID0gQnl0ZXMoYiJkdW1teV9ieXRlcyIpCiAgICBnbG9iYWwgQ3JlYXRvckFkZHJlc3MKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weToyMzUKICAgIC8vIGtleT0ibG9jYWxfYnl0ZXMiLAogICAgYnl0ZSAibG9jYWxfYnl0ZXMiCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6MjQwCiAgICAvLyBzZWxmLmxvY2FsX2J5dGVzW0dsb2JhbC5jcmVhdG9yX2FkZHJlc3NdID0gQnl0ZXMoYiJkdW1teV9ieXRlcyIpCiAgICBieXRlIDB4NjQ3NTZkNmQ3OTVmNjI3OTc0NjU3MwogICAgYXBwX2xvY2FsX3B1dAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjI0MQogICAgLy8gc2VsZi5sb2NhbF91aW50NjRbR2xvYmFsLmNyZWF0b3JfYWRkcmVzc10gPSBVSW50NjQoOTk5KQogICAgZ2xvYmFsIENyZWF0b3JBZGRyZXNzCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6MjMwCiAgICAvLyBrZXk9ImxvY2FsX3VpbnQ2NCIsCiAgICBieXRlICJsb2NhbF91aW50NjQiCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6MjQxCiAgICAvLyBzZWxmLmxvY2FsX3VpbnQ2NFtHbG9iYWwuY3JlYXRvcl9hZGRyZXNzXSA9IFVJbnQ2NCg5OTkpCiAgICBpbnQgOTk5CiAgICBhcHBfbG9jYWxfcHV0CiAgICByZXRzdWIKCgovLyB0ZXN0cy5hcnRpZmFjdHMuU3RhdGVPcHMuY29udHJhY3QuU3RhdGVBcHBMb2NhbENvbnRyYWN0LnZlcmlmeV9nZXRfYnl0ZXMoYTogYnl0ZXMsIGI6IGJ5dGVzKSAtPiBieXRlczoKdmVyaWZ5X2dldF9ieXRlczoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weToyNDMtMjQ0CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gZGVmIHZlcmlmeV9nZXRfYnl0ZXMoc2VsZiwgYTogQWNjb3VudCwgYjogQnl0ZXMpIC0+IEJ5dGVzOgogICAgcHJvdG8gMiAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6MjQ1CiAgICAvLyB2YWx1ZSA9IG9wLkFwcExvY2FsLmdldF9ieXRlcyhhLCBiKQogICAgZnJhbWVfZGlnIC0yCiAgICBmcmFtZV9kaWcgLTEKICAgIGFwcF9sb2NhbF9nZXQKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weToyNDYKICAgIC8vIHJldHVybiB2YWx1ZQogICAgcmV0c3ViCgoKLy8gdGVzdHMuYXJ0aWZhY3RzLlN0YXRlT3BzLmNvbnRyYWN0LlN0YXRlQXBwTG9jYWxDb250cmFjdC52ZXJpZnlfZ2V0X3VpbnQ2NChhOiBieXRlcywgYjogYnl0ZXMpIC0+IHVpbnQ2NDoKdmVyaWZ5X2dldF91aW50NjQ6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6MjQ4LTI0OQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIGRlZiB2ZXJpZnlfZ2V0X3VpbnQ2NChzZWxmLCBhOiBBY2NvdW50LCBiOiBCeXRlcykgLT4gVUludDY0OgogICAgcHJvdG8gMiAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6MjUwCiAgICAvLyB2YWx1ZSA9IG9wLkFwcExvY2FsLmdldF91aW50NjQoYSwgYikKICAgIGZyYW1lX2RpZyAtMgogICAgZnJhbWVfZGlnIC0xCiAgICBhcHBfbG9jYWxfZ2V0CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6MjUxCiAgICAvLyByZXR1cm4gdmFsdWUKICAgIHJldHN1YgoKCi8vIHRlc3RzLmFydGlmYWN0cy5TdGF0ZU9wcy5jb250cmFjdC5TdGF0ZUFwcExvY2FsQ29udHJhY3QudmVyaWZ5X2dldF9leF9ieXRlcyhhOiBieXRlcywgYjogdWludDY0LCBjOiBieXRlcykgLT4gYnl0ZXM6CnZlcmlmeV9nZXRfZXhfYnl0ZXM6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6MjUzLTI1NAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIGRlZiB2ZXJpZnlfZ2V0X2V4X2J5dGVzKHNlbGYsIGE6IEFjY291bnQsIGI6IEFwcGxpY2F0aW9uLCBjOiBCeXRlcykgLT4gQnl0ZXM6CiAgICBwcm90byAzIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weToyNTUKICAgIC8vIHZhbHVlLCBfdmFsID0gb3AuQXBwTG9jYWwuZ2V0X2V4X2J5dGVzKGEsIGIsIGMpCiAgICBmcmFtZV9kaWcgLTMKICAgIGZyYW1lX2RpZyAtMgogICAgZnJhbWVfZGlnIC0xCiAgICBhcHBfbG9jYWxfZ2V0X2V4CiAgICBwb3AKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weToyNTYKICAgIC8vIHJldHVybiB2YWx1ZQogICAgcmV0c3ViCgoKLy8gdGVzdHMuYXJ0aWZhY3RzLlN0YXRlT3BzLmNvbnRyYWN0LlN0YXRlQXBwTG9jYWxDb250cmFjdC52ZXJpZnlfZ2V0X2V4X3VpbnQ2NChhOiBieXRlcywgYjogdWludDY0LCBjOiBieXRlcykgLT4gdWludDY0Ogp2ZXJpZnlfZ2V0X2V4X3VpbnQ2NDoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weToyNTgtMjU5CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gZGVmIHZlcmlmeV9nZXRfZXhfdWludDY0KHNlbGYsIGE6IEFjY291bnQsIGI6IEFwcGxpY2F0aW9uLCBjOiBCeXRlcykgLT4gVUludDY0OgogICAgcHJvdG8gMyAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6MjYwCiAgICAvLyB2YWx1ZSwgX3ZhbCA9IG9wLkFwcExvY2FsLmdldF9leF91aW50NjQoYSwgYiwgYykKICAgIGZyYW1lX2RpZyAtMwogICAgZnJhbWVfZGlnIC0yCiAgICBmcmFtZV9kaWcgLTEKICAgIGFwcF9sb2NhbF9nZXRfZXgKICAgIHBvcAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjI2MQogICAgLy8gcmV0dXJuIHZhbHVlCiAgICByZXRzdWIKCgovLyB0ZXN0cy5hcnRpZmFjdHMuU3RhdGVPcHMuY29udHJhY3QuU3RhdGVBcHBMb2NhbENvbnRyYWN0LnZlcmlmeV9kZWxldGUoYTogYnl0ZXMsIGI6IGJ5dGVzKSAtPiB2b2lkOgp2ZXJpZnlfZGVsZXRlOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjI2My0yNjQKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBkZWYgdmVyaWZ5X2RlbGV0ZShzZWxmLCBhOiBBY2NvdW50LCBiOiBCeXRlcykgLT4gTm9uZToKICAgIHByb3RvIDIgMAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjI2NQogICAgLy8gb3AuQXBwTG9jYWwuZGVsZXRlKGEsIGIpCiAgICBmcmFtZV9kaWcgLTIKICAgIGZyYW1lX2RpZyAtMQogICAgYXBwX2xvY2FsX2RlbAogICAgcmV0c3ViCgoKLy8gdGVzdHMuYXJ0aWZhY3RzLlN0YXRlT3BzLmNvbnRyYWN0LlN0YXRlQXBwTG9jYWxDb250cmFjdC52ZXJpZnlfcHV0X3VpbnQ2NChhOiBieXRlcywgYjogYnl0ZXMsIGM6IHVpbnQ2NCkgLT4gdm9pZDoKdmVyaWZ5X3B1dF91aW50NjQ6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6MjY3LTI2OAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIGRlZiB2ZXJpZnlfcHV0X3VpbnQ2NChzZWxmLCBhOiBBY2NvdW50LCBiOiBCeXRlcywgYzogVUludDY0KSAtPiBOb25lOgogICAgcHJvdG8gMyAwCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6MjY5CiAgICAvLyBvcC5BcHBMb2NhbC5wdXQoYSwgYiwgYykKICAgIGZyYW1lX2RpZyAtMwogICAgZnJhbWVfZGlnIC0yCiAgICBmcmFtZV9kaWcgLTEKICAgIGFwcF9sb2NhbF9wdXQKICAgIHJldHN1YgoKCi8vIHRlc3RzLmFydGlmYWN0cy5TdGF0ZU9wcy5jb250cmFjdC5TdGF0ZUFwcExvY2FsQ29udHJhY3QudmVyaWZ5X3B1dF9ieXRlcyhhOiBieXRlcywgYjogYnl0ZXMsIGM6IGJ5dGVzKSAtPiB2b2lkOgp2ZXJpZnlfcHV0X2J5dGVzOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjI3MS0yNzIKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBkZWYgdmVyaWZ5X3B1dF9ieXRlcyhzZWxmLCBhOiBBY2NvdW50LCBiOiBCeXRlcywgYzogQnl0ZXMpIC0+IE5vbmU6CiAgICBwcm90byAzIDAKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weToyNzMKICAgIC8vIG9wLkFwcExvY2FsLnB1dChhLCBiLCBjKQogICAgZnJhbWVfZGlnIC0zCiAgICBmcmFtZV9kaWcgLTIKICAgIGZyYW1lX2RpZyAtMQogICAgYXBwX2xvY2FsX3B1dAogICAgcmV0c3ViCg==", - "clear": "I3ByYWdtYSB2ZXJzaW9uIDEwCgp0ZXN0cy5hcnRpZmFjdHMuU3RhdGVPcHMuY29udHJhY3QuU3RhdGVBcHBMb2NhbENvbnRyYWN0LmNsZWFyX3N0YXRlX3Byb2dyYW06CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6MjI2CiAgICAvLyBjbGFzcyBTdGF0ZUFwcExvY2FsQ29udHJhY3QoQVJDNENvbnRyYWN0KToKICAgIGludCAxCiAgICByZXR1cm4K" + "approval": "I3ByYWdtYSB2ZXJzaW9uIDEwCgp0ZXN0cy5hcnRpZmFjdHMuU3RhdGVPcHMuY29udHJhY3QuU3RhdGVBcHBMb2NhbENvbnRyYWN0LmFwcHJvdmFsX3Byb2dyYW06CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6MzM5CiAgICAvLyBjbGFzcyBTdGF0ZUFwcExvY2FsQ29udHJhY3QoQVJDNENvbnRyYWN0KToKICAgIHR4biBOdW1BcHBBcmdzCiAgICBieiBtYWluX2JhcmVfcm91dGluZ0AxMwogICAgbWV0aG9kICJvcHRfaW4oKXZvaWQiCiAgICBtZXRob2QgInZlcmlmeV9nZXRfYnl0ZXMoYWNjb3VudCxieXRlW10pYnl0ZVtdIgogICAgbWV0aG9kICJ2ZXJpZnlfZ2V0X3VpbnQ2NChhY2NvdW50LGJ5dGVbXSl1aW50NjQiCiAgICBtZXRob2QgInZlcmlmeV9nZXRfZXhfYnl0ZXMoYWNjb3VudCxhcHBsaWNhdGlvbixieXRlW10pYnl0ZVtdIgogICAgbWV0aG9kICJ2ZXJpZnlfZ2V0X2V4X3VpbnQ2NChhY2NvdW50LGFwcGxpY2F0aW9uLGJ5dGVbXSl1aW50NjQiCiAgICBtZXRob2QgInZlcmlmeV9kZWxldGUoYWNjb3VudCxieXRlW10pdm9pZCIKICAgIG1ldGhvZCAidmVyaWZ5X2V4aXN0cyhhY2NvdW50LGJ5dGVbXSlib29sIgogICAgbWV0aG9kICJ2ZXJpZnlfcHV0X3VpbnQ2NChhY2NvdW50LGJ5dGVbXSx1aW50NjQpdm9pZCIKICAgIG1ldGhvZCAidmVyaWZ5X3B1dF9ieXRlcyhhY2NvdW50LGJ5dGVbXSxieXRlW10pdm9pZCIKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDAKICAgIG1hdGNoIG1haW5fb3B0X2luX3JvdXRlQDIgbWFpbl92ZXJpZnlfZ2V0X2J5dGVzX3JvdXRlQDMgbWFpbl92ZXJpZnlfZ2V0X3VpbnQ2NF9yb3V0ZUA0IG1haW5fdmVyaWZ5X2dldF9leF9ieXRlc19yb3V0ZUA1IG1haW5fdmVyaWZ5X2dldF9leF91aW50NjRfcm91dGVANiBtYWluX3ZlcmlmeV9kZWxldGVfcm91dGVANyBtYWluX3ZlcmlmeV9leGlzdHNfcm91dGVAOCBtYWluX3ZlcmlmeV9wdXRfdWludDY0X3JvdXRlQDkgbWFpbl92ZXJpZnlfcHV0X2J5dGVzX3JvdXRlQDEwCiAgICBlcnIgLy8gcmVqZWN0IHRyYW5zYWN0aW9uCgptYWluX29wdF9pbl9yb3V0ZUAyOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjM1MQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKGFsbG93X2FjdGlvbnM9WyJPcHRJbiJdKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgaW50IE9wdEluCiAgICA9PQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBPcHRJbgogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBpcyBub3QgY3JlYXRpbmcKICAgIGNhbGxzdWIgb3B0X2luCiAgICBpbnQgMQogICAgcmV0dXJuCgptYWluX3ZlcmlmeV9nZXRfYnl0ZXNfcm91dGVAMzoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTozNTYKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gaXMgbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6MzM5CiAgICAvLyBjbGFzcyBTdGF0ZUFwcExvY2FsQ29udHJhY3QoQVJDNENvbnRyYWN0KToKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGJ0b2kKICAgIHR4bmFzIEFjY291bnRzCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAyCiAgICBleHRyYWN0IDIgMAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjM1NgogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X2dldF9ieXRlcwogICAgZHVwCiAgICBsZW4KICAgIGl0b2IKICAgIGV4dHJhY3QgNiAyCiAgICBzd2FwCiAgICBjb25jYXQKICAgIGJ5dGUgMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludCAxCiAgICByZXR1cm4KCm1haW5fdmVyaWZ5X2dldF91aW50NjRfcm91dGVANDoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTozNjEKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gaXMgbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6MzM5CiAgICAvLyBjbGFzcyBTdGF0ZUFwcExvY2FsQ29udHJhY3QoQVJDNENvbnRyYWN0KToKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGJ0b2kKICAgIHR4bmFzIEFjY291bnRzCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAyCiAgICBleHRyYWN0IDIgMAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjM2MQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X2dldF91aW50NjQKICAgIGl0b2IKICAgIGJ5dGUgMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludCAxCiAgICByZXR1cm4KCm1haW5fdmVyaWZ5X2dldF9leF9ieXRlc19yb3V0ZUA1OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjM2NgogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBpcyBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTozMzkKICAgIC8vIGNsYXNzIFN0YXRlQXBwTG9jYWxDb250cmFjdChBUkM0Q29udHJhY3QpOgogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgYnRvaQogICAgdHhuYXMgQWNjb3VudHMKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDIKICAgIGJ0b2kKICAgIHR4bmFzIEFwcGxpY2F0aW9ucwogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMwogICAgZXh0cmFjdCAyIDAKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTozNjYKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV9nZXRfZXhfYnl0ZXMKICAgIGR1cAogICAgbGVuCiAgICBpdG9iCiAgICBleHRyYWN0IDYgMgogICAgc3dhcAogICAgY29uY2F0CiAgICBieXRlIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnQgMQogICAgcmV0dXJuCgptYWluX3ZlcmlmeV9nZXRfZXhfdWludDY0X3JvdXRlQDY6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6MzcxCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGlzIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjMzOQogICAgLy8gY2xhc3MgU3RhdGVBcHBMb2NhbENvbnRyYWN0KEFSQzRDb250cmFjdCk6CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBidG9pCiAgICB0eG5hcyBBY2NvdW50cwogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMgogICAgYnRvaQogICAgdHhuYXMgQXBwbGljYXRpb25zCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAzCiAgICBleHRyYWN0IDIgMAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjM3MQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X2dldF9leF91aW50NjQKICAgIGl0b2IKICAgIGJ5dGUgMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludCAxCiAgICByZXR1cm4KCm1haW5fdmVyaWZ5X2RlbGV0ZV9yb3V0ZUA3OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjM3NgogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBpcyBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTozMzkKICAgIC8vIGNsYXNzIFN0YXRlQXBwTG9jYWxDb250cmFjdChBUkM0Q29udHJhY3QpOgogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgYnRvaQogICAgdHhuYXMgQWNjb3VudHMKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDIKICAgIGV4dHJhY3QgMiAwCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6Mzc2CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfZGVsZXRlCiAgICBpbnQgMQogICAgcmV0dXJuCgptYWluX3ZlcmlmeV9leGlzdHNfcm91dGVAODoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTozODAKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gaXMgbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6MzM5CiAgICAvLyBjbGFzcyBTdGF0ZUFwcExvY2FsQ29udHJhY3QoQVJDNENvbnRyYWN0KToKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGJ0b2kKICAgIHR4bmFzIEFjY291bnRzCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAyCiAgICBleHRyYWN0IDIgMAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjM4MAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X2V4aXN0cwogICAgYnl0ZSAweDAwCiAgICBpbnQgMAogICAgdW5jb3ZlciAyCiAgICBzZXRiaXQKICAgIGJ5dGUgMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludCAxCiAgICByZXR1cm4KCm1haW5fdmVyaWZ5X3B1dF91aW50NjRfcm91dGVAOToKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTozODUKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gaXMgbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6MzM5CiAgICAvLyBjbGFzcyBTdGF0ZUFwcExvY2FsQ29udHJhY3QoQVJDNENvbnRyYWN0KToKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGJ0b2kKICAgIHR4bmFzIEFjY291bnRzCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAyCiAgICBleHRyYWN0IDIgMAogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMwogICAgYnRvaQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjM4NQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X3B1dF91aW50NjQKICAgIGludCAxCiAgICByZXR1cm4KCm1haW5fdmVyaWZ5X3B1dF9ieXRlc19yb3V0ZUAxMDoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTozODkKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gaXMgbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6MzM5CiAgICAvLyBjbGFzcyBTdGF0ZUFwcExvY2FsQ29udHJhY3QoQVJDNENvbnRyYWN0KToKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGJ0b2kKICAgIHR4bmFzIEFjY291bnRzCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAyCiAgICBleHRyYWN0IDIgMAogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMwogICAgZXh0cmFjdCAyIDAKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTozODkKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV9wdXRfYnl0ZXMKICAgIGludCAxCiAgICByZXR1cm4KCm1haW5fYmFyZV9yb3V0aW5nQDEzOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjMzOQogICAgLy8gY2xhc3MgU3RhdGVBcHBMb2NhbENvbnRyYWN0KEFSQzRDb250cmFjdCk6CiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gcmVqZWN0IHRyYW5zYWN0aW9uCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgIQogICAgYXNzZXJ0IC8vIGlzIGNyZWF0aW5nCiAgICBpbnQgMQogICAgcmV0dXJuCgoKLy8gdGVzdHMuYXJ0aWZhY3RzLlN0YXRlT3BzLmNvbnRyYWN0LlN0YXRlQXBwTG9jYWxDb250cmFjdC5vcHRfaW4oKSAtPiB2b2lkOgpvcHRfaW46CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6MzUxLTM1MgogICAgLy8gQGFyYzQuYWJpbWV0aG9kKGFsbG93X2FjdGlvbnM9WyJPcHRJbiJdKQogICAgLy8gZGVmIG9wdF9pbihzZWxmKSAtPiBOb25lOgogICAgcHJvdG8gMCAwCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6MzUzCiAgICAvLyBzZWxmLmxvY2FsX2J5dGVzW0dsb2JhbC5jcmVhdG9yX2FkZHJlc3NdID0gQnl0ZXMoYiJkdW1teV9ieXRlcyIpCiAgICBnbG9iYWwgQ3JlYXRvckFkZHJlc3MKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTozNDgKICAgIC8vIGtleT0ibG9jYWxfYnl0ZXMiLAogICAgYnl0ZSAibG9jYWxfYnl0ZXMiCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6MzUzCiAgICAvLyBzZWxmLmxvY2FsX2J5dGVzW0dsb2JhbC5jcmVhdG9yX2FkZHJlc3NdID0gQnl0ZXMoYiJkdW1teV9ieXRlcyIpCiAgICBieXRlIDB4NjQ3NTZkNmQ3OTVmNjI3OTc0NjU3MwogICAgYXBwX2xvY2FsX3B1dAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjM1NAogICAgLy8gc2VsZi5sb2NhbF91aW50NjRbR2xvYmFsLmNyZWF0b3JfYWRkcmVzc10gPSBVSW50NjQoOTk5KQogICAgZ2xvYmFsIENyZWF0b3JBZGRyZXNzCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6MzQzCiAgICAvLyBrZXk9ImxvY2FsX3VpbnQ2NCIsCiAgICBieXRlICJsb2NhbF91aW50NjQiCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6MzU0CiAgICAvLyBzZWxmLmxvY2FsX3VpbnQ2NFtHbG9iYWwuY3JlYXRvcl9hZGRyZXNzXSA9IFVJbnQ2NCg5OTkpCiAgICBpbnQgOTk5CiAgICBhcHBfbG9jYWxfcHV0CiAgICByZXRzdWIKCgovLyB0ZXN0cy5hcnRpZmFjdHMuU3RhdGVPcHMuY29udHJhY3QuU3RhdGVBcHBMb2NhbENvbnRyYWN0LnZlcmlmeV9nZXRfYnl0ZXMoYTogYnl0ZXMsIGI6IGJ5dGVzKSAtPiBieXRlczoKdmVyaWZ5X2dldF9ieXRlczoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTozNTYtMzU3CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gZGVmIHZlcmlmeV9nZXRfYnl0ZXMoc2VsZiwgYTogQWNjb3VudCwgYjogQnl0ZXMpIC0+IEJ5dGVzOgogICAgcHJvdG8gMiAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6MzU4CiAgICAvLyB2YWx1ZSA9IG9wLkFwcExvY2FsLmdldF9ieXRlcyhhLCBiKQogICAgZnJhbWVfZGlnIC0yCiAgICBmcmFtZV9kaWcgLTEKICAgIGFwcF9sb2NhbF9nZXQKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTozNTkKICAgIC8vIHJldHVybiB2YWx1ZQogICAgcmV0c3ViCgoKLy8gdGVzdHMuYXJ0aWZhY3RzLlN0YXRlT3BzLmNvbnRyYWN0LlN0YXRlQXBwTG9jYWxDb250cmFjdC52ZXJpZnlfZ2V0X3VpbnQ2NChhOiBieXRlcywgYjogYnl0ZXMpIC0+IHVpbnQ2NDoKdmVyaWZ5X2dldF91aW50NjQ6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6MzYxLTM2MgogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIGRlZiB2ZXJpZnlfZ2V0X3VpbnQ2NChzZWxmLCBhOiBBY2NvdW50LCBiOiBCeXRlcykgLT4gVUludDY0OgogICAgcHJvdG8gMiAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6MzYzCiAgICAvLyB2YWx1ZSA9IG9wLkFwcExvY2FsLmdldF91aW50NjQoYSwgYikKICAgIGZyYW1lX2RpZyAtMgogICAgZnJhbWVfZGlnIC0xCiAgICBhcHBfbG9jYWxfZ2V0CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6MzY0CiAgICAvLyByZXR1cm4gdmFsdWUKICAgIHJldHN1YgoKCi8vIHRlc3RzLmFydGlmYWN0cy5TdGF0ZU9wcy5jb250cmFjdC5TdGF0ZUFwcExvY2FsQ29udHJhY3QudmVyaWZ5X2dldF9leF9ieXRlcyhhOiBieXRlcywgYjogdWludDY0LCBjOiBieXRlcykgLT4gYnl0ZXM6CnZlcmlmeV9nZXRfZXhfYnl0ZXM6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6MzY2LTM2NwogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIGRlZiB2ZXJpZnlfZ2V0X2V4X2J5dGVzKHNlbGYsIGE6IEFjY291bnQsIGI6IEFwcGxpY2F0aW9uLCBjOiBCeXRlcykgLT4gQnl0ZXM6CiAgICBwcm90byAzIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTozNjgKICAgIC8vIHZhbHVlLCBfdmFsID0gb3AuQXBwTG9jYWwuZ2V0X2V4X2J5dGVzKGEsIGIsIGMpCiAgICBmcmFtZV9kaWcgLTMKICAgIGZyYW1lX2RpZyAtMgogICAgZnJhbWVfZGlnIC0xCiAgICBhcHBfbG9jYWxfZ2V0X2V4CiAgICBwb3AKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTozNjkKICAgIC8vIHJldHVybiB2YWx1ZQogICAgcmV0c3ViCgoKLy8gdGVzdHMuYXJ0aWZhY3RzLlN0YXRlT3BzLmNvbnRyYWN0LlN0YXRlQXBwTG9jYWxDb250cmFjdC52ZXJpZnlfZ2V0X2V4X3VpbnQ2NChhOiBieXRlcywgYjogdWludDY0LCBjOiBieXRlcykgLT4gdWludDY0Ogp2ZXJpZnlfZ2V0X2V4X3VpbnQ2NDoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTozNzEtMzcyCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gZGVmIHZlcmlmeV9nZXRfZXhfdWludDY0KHNlbGYsIGE6IEFjY291bnQsIGI6IEFwcGxpY2F0aW9uLCBjOiBCeXRlcykgLT4gVUludDY0OgogICAgcHJvdG8gMyAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6MzczCiAgICAvLyB2YWx1ZSwgX3ZhbCA9IG9wLkFwcExvY2FsLmdldF9leF91aW50NjQoYSwgYiwgYykKICAgIGZyYW1lX2RpZyAtMwogICAgZnJhbWVfZGlnIC0yCiAgICBmcmFtZV9kaWcgLTEKICAgIGFwcF9sb2NhbF9nZXRfZXgKICAgIHBvcAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjM3NAogICAgLy8gcmV0dXJuIHZhbHVlCiAgICByZXRzdWIKCgovLyB0ZXN0cy5hcnRpZmFjdHMuU3RhdGVPcHMuY29udHJhY3QuU3RhdGVBcHBMb2NhbENvbnRyYWN0LnZlcmlmeV9kZWxldGUoYTogYnl0ZXMsIGI6IGJ5dGVzKSAtPiB2b2lkOgp2ZXJpZnlfZGVsZXRlOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjM3Ni0zNzcKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBkZWYgdmVyaWZ5X2RlbGV0ZShzZWxmLCBhOiBBY2NvdW50LCBiOiBCeXRlcykgLT4gTm9uZToKICAgIHByb3RvIDIgMAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjM3OAogICAgLy8gb3AuQXBwTG9jYWwuZGVsZXRlKGEsIGIpCiAgICBmcmFtZV9kaWcgLTIKICAgIGZyYW1lX2RpZyAtMQogICAgYXBwX2xvY2FsX2RlbAogICAgcmV0c3ViCgoKLy8gdGVzdHMuYXJ0aWZhY3RzLlN0YXRlT3BzLmNvbnRyYWN0LlN0YXRlQXBwTG9jYWxDb250cmFjdC52ZXJpZnlfZXhpc3RzKGE6IGJ5dGVzLCBiOiBieXRlcykgLT4gdWludDY0Ogp2ZXJpZnlfZXhpc3RzOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjM4MC0zODEKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBkZWYgdmVyaWZ5X2V4aXN0cyhzZWxmLCBhOiBBY2NvdW50LCBiOiBCeXRlcykgLT4gYm9vbDoKICAgIHByb3RvIDIgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjM4MgogICAgLy8gX3ZhbHVlLCBleGlzdHMgPSBvcC5BcHBMb2NhbC5nZXRfZXhfdWludDY0KGEsIDAsIGIpCiAgICBmcmFtZV9kaWcgLTIKICAgIGludCAwCiAgICBmcmFtZV9kaWcgLTEKICAgIGFwcF9sb2NhbF9nZXRfZXgKICAgIGJ1cnkgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjM4MwogICAgLy8gcmV0dXJuIGV4aXN0cwogICAgcmV0c3ViCgoKLy8gdGVzdHMuYXJ0aWZhY3RzLlN0YXRlT3BzLmNvbnRyYWN0LlN0YXRlQXBwTG9jYWxDb250cmFjdC52ZXJpZnlfcHV0X3VpbnQ2NChhOiBieXRlcywgYjogYnl0ZXMsIGM6IHVpbnQ2NCkgLT4gdm9pZDoKdmVyaWZ5X3B1dF91aW50NjQ6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6Mzg1LTM4NgogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIGRlZiB2ZXJpZnlfcHV0X3VpbnQ2NChzZWxmLCBhOiBBY2NvdW50LCBiOiBCeXRlcywgYzogVUludDY0KSAtPiBOb25lOgogICAgcHJvdG8gMyAwCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6Mzg3CiAgICAvLyBvcC5BcHBMb2NhbC5wdXQoYSwgYiwgYykKICAgIGZyYW1lX2RpZyAtMwogICAgZnJhbWVfZGlnIC0yCiAgICBmcmFtZV9kaWcgLTEKICAgIGFwcF9sb2NhbF9wdXQKICAgIHJldHN1YgoKCi8vIHRlc3RzLmFydGlmYWN0cy5TdGF0ZU9wcy5jb250cmFjdC5TdGF0ZUFwcExvY2FsQ29udHJhY3QudmVyaWZ5X3B1dF9ieXRlcyhhOiBieXRlcywgYjogYnl0ZXMsIGM6IGJ5dGVzKSAtPiB2b2lkOgp2ZXJpZnlfcHV0X2J5dGVzOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjM4OS0zOTAKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBkZWYgdmVyaWZ5X3B1dF9ieXRlcyhzZWxmLCBhOiBBY2NvdW50LCBiOiBCeXRlcywgYzogQnl0ZXMpIC0+IE5vbmU6CiAgICBwcm90byAzIDAKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTozOTEKICAgIC8vIG9wLkFwcExvY2FsLnB1dChhLCBiLCBjKQogICAgZnJhbWVfZGlnIC0zCiAgICBmcmFtZV9kaWcgLTIKICAgIGZyYW1lX2RpZyAtMQogICAgYXBwX2xvY2FsX3B1dAogICAgcmV0c3ViCg==", + "clear": "I3ByYWdtYSB2ZXJzaW9uIDEwCgp0ZXN0cy5hcnRpZmFjdHMuU3RhdGVPcHMuY29udHJhY3QuU3RhdGVBcHBMb2NhbENvbnRyYWN0LmNsZWFyX3N0YXRlX3Byb2dyYW06CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6MzM5CiAgICAvLyBjbGFzcyBTdGF0ZUFwcExvY2FsQ29udHJhY3QoQVJDNENvbnRyYWN0KToKICAgIGludCAxCiAgICByZXR1cm4K" }, "state": { "global": { @@ -178,6 +183,23 @@ "type": "void" } }, + { + "name": "verify_exists", + "args": [ + { + "type": "account", + "name": "a" + }, + { + "type": "byte[]", + "name": "b" + } + ], + "readonly": false, + "returns": { + "type": "bool" + } + }, { "name": "verify_put_uint64", "args": [ diff --git a/tests/artifacts/StateOps/data/StateAppLocalContract.clear.teal b/tests/artifacts/StateOps/data/StateAppLocalContract.clear.teal index d66ae21..68fd175 100644 --- a/tests/artifacts/StateOps/data/StateAppLocalContract.clear.teal +++ b/tests/artifacts/StateOps/data/StateAppLocalContract.clear.teal @@ -1,7 +1,7 @@ #pragma version 10 tests.artifacts.StateOps.contract.StateAppLocalContract.clear_state_program: - // tests/artifacts/StateOps/contract.py:226 + // tests/artifacts/StateOps/contract.py:339 // class StateAppLocalContract(ARC4Contract): int 1 return diff --git a/tests/artifacts/StateOps/data/StateAppLocalExContract.approval.teal b/tests/artifacts/StateOps/data/StateAppLocalExContract.approval.teal index f2e8fad..989781a 100644 --- a/tests/artifacts/StateOps/data/StateAppLocalExContract.approval.teal +++ b/tests/artifacts/StateOps/data/StateAppLocalExContract.approval.teal @@ -1,7 +1,7 @@ #pragma version 10 tests.artifacts.StateOps.contract.StateAppLocalExContract.approval_program: - // tests/artifacts/StateOps/contract.py:200 + // tests/artifacts/StateOps/contract.py:313 // class StateAppLocalExContract(ARC4Contract): txn NumAppArgs bz main_bare_routing@5 @@ -11,7 +11,7 @@ tests.artifacts.StateOps.contract.StateAppLocalExContract.approval_program: err // reject transaction main_opt_in_route@2: - // tests/artifacts/StateOps/contract.py:217 + // tests/artifacts/StateOps/contract.py:330 // @arc4.abimethod(allow_actions=["OptIn"]) txn OnCompletion int OptIn @@ -24,7 +24,7 @@ main_opt_in_route@2: return main_bare_routing@5: - // tests/artifacts/StateOps/contract.py:200 + // tests/artifacts/StateOps/contract.py:313 // class StateAppLocalExContract(ARC4Contract): txn OnCompletion ! @@ -38,37 +38,37 @@ main_bare_routing@5: // tests.artifacts.StateOps.contract.StateAppLocalExContract.opt_in() -> void: opt_in: - // tests/artifacts/StateOps/contract.py:217-218 + // tests/artifacts/StateOps/contract.py:330-331 // @arc4.abimethod(allow_actions=["OptIn"]) // def opt_in(self) -> None: proto 0 0 - // tests/artifacts/StateOps/contract.py:219 + // tests/artifacts/StateOps/contract.py:332 // self.local_bytes[Global.creator_address] = Bytes(b"dummy_bytes_from_external_contract") global CreatorAddress - // tests/artifacts/StateOps/contract.py:209 + // tests/artifacts/StateOps/contract.py:322 // key="local_bytes", byte "local_bytes" - // tests/artifacts/StateOps/contract.py:219 + // tests/artifacts/StateOps/contract.py:332 // self.local_bytes[Global.creator_address] = Bytes(b"dummy_bytes_from_external_contract") byte 0x64756d6d795f62797465735f66726f6d5f65787465726e616c5f636f6e7472616374 app_local_put - // tests/artifacts/StateOps/contract.py:220 + // tests/artifacts/StateOps/contract.py:333 // self.local_uint64[Global.creator_address] = UInt64(99) global CreatorAddress - // tests/artifacts/StateOps/contract.py:204 + // tests/artifacts/StateOps/contract.py:317 // key="local_uint64", byte "local_uint64" - // tests/artifacts/StateOps/contract.py:220 + // tests/artifacts/StateOps/contract.py:333 // self.local_uint64[Global.creator_address] = UInt64(99) int 99 app_local_put - // tests/artifacts/StateOps/contract.py:221 + // tests/artifacts/StateOps/contract.py:334 // self.local_arc4_bytes[Global.creator_address] = algopy.arc4.DynamicBytes( global CreatorAddress - // tests/artifacts/StateOps/contract.py:214 + // tests/artifacts/StateOps/contract.py:327 // key="local_arc4_bytes", byte "local_arc4_bytes" - // tests/artifacts/StateOps/contract.py:221-223 + // tests/artifacts/StateOps/contract.py:334-336 // self.local_arc4_bytes[Global.creator_address] = algopy.arc4.DynamicBytes( // b"dummy_arc4_bytes" // ) diff --git a/tests/artifacts/StateOps/data/StateAppLocalExContract.arc32.json b/tests/artifacts/StateOps/data/StateAppLocalExContract.arc32.json index e54d4f8..9654b8a 100644 --- a/tests/artifacts/StateOps/data/StateAppLocalExContract.arc32.json +++ b/tests/artifacts/StateOps/data/StateAppLocalExContract.arc32.json @@ -7,8 +7,8 @@ } }, "source": { - "approval": "I3ByYWdtYSB2ZXJzaW9uIDEwCgp0ZXN0cy5hcnRpZmFjdHMuU3RhdGVPcHMuY29udHJhY3QuU3RhdGVBcHBMb2NhbEV4Q29udHJhY3QuYXBwcm92YWxfcHJvZ3JhbToKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weToyMDAKICAgIC8vIGNsYXNzIFN0YXRlQXBwTG9jYWxFeENvbnRyYWN0KEFSQzRDb250cmFjdCk6CiAgICB0eG4gTnVtQXBwQXJncwogICAgYnogbWFpbl9iYXJlX3JvdXRpbmdANQogICAgbWV0aG9kICJvcHRfaW4oKXZvaWQiCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAwCiAgICBtYXRjaCBtYWluX29wdF9pbl9yb3V0ZUAyCiAgICBlcnIgLy8gcmVqZWN0IHRyYW5zYWN0aW9uCgptYWluX29wdF9pbl9yb3V0ZUAyOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjIxNwogICAgLy8gQGFyYzQuYWJpbWV0aG9kKGFsbG93X2FjdGlvbnM9WyJPcHRJbiJdKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgaW50IE9wdEluCiAgICA9PQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBPcHRJbgogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBpcyBub3QgY3JlYXRpbmcKICAgIGNhbGxzdWIgb3B0X2luCiAgICBpbnQgMQogICAgcmV0dXJuCgptYWluX2JhcmVfcm91dGluZ0A1OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjIwMAogICAgLy8gY2xhc3MgU3RhdGVBcHBMb2NhbEV4Q29udHJhY3QoQVJDNENvbnRyYWN0KToKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyByZWplY3QgdHJhbnNhY3Rpb24KICAgIHR4biBBcHBsaWNhdGlvbklECiAgICAhCiAgICBhc3NlcnQgLy8gaXMgY3JlYXRpbmcKICAgIGludCAxCiAgICByZXR1cm4KCgovLyB0ZXN0cy5hcnRpZmFjdHMuU3RhdGVPcHMuY29udHJhY3QuU3RhdGVBcHBMb2NhbEV4Q29udHJhY3Qub3B0X2luKCkgLT4gdm9pZDoKb3B0X2luOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjIxNy0yMTgKICAgIC8vIEBhcmM0LmFiaW1ldGhvZChhbGxvd19hY3Rpb25zPVsiT3B0SW4iXSkKICAgIC8vIGRlZiBvcHRfaW4oc2VsZikgLT4gTm9uZToKICAgIHByb3RvIDAgMAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjIxOQogICAgLy8gc2VsZi5sb2NhbF9ieXRlc1tHbG9iYWwuY3JlYXRvcl9hZGRyZXNzXSA9IEJ5dGVzKGIiZHVtbXlfYnl0ZXNfZnJvbV9leHRlcm5hbF9jb250cmFjdCIpCiAgICBnbG9iYWwgQ3JlYXRvckFkZHJlc3MKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weToyMDkKICAgIC8vIGtleT0ibG9jYWxfYnl0ZXMiLAogICAgYnl0ZSAibG9jYWxfYnl0ZXMiCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6MjE5CiAgICAvLyBzZWxmLmxvY2FsX2J5dGVzW0dsb2JhbC5jcmVhdG9yX2FkZHJlc3NdID0gQnl0ZXMoYiJkdW1teV9ieXRlc19mcm9tX2V4dGVybmFsX2NvbnRyYWN0IikKICAgIGJ5dGUgMHg2NDc1NmQ2ZDc5NWY2Mjc5NzQ2NTczNWY2NjcyNmY2ZDVmNjU3ODc0NjU3MjZlNjE2YzVmNjM2ZjZlNzQ3MjYxNjM3NAogICAgYXBwX2xvY2FsX3B1dAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjIyMAogICAgLy8gc2VsZi5sb2NhbF91aW50NjRbR2xvYmFsLmNyZWF0b3JfYWRkcmVzc10gPSBVSW50NjQoOTkpCiAgICBnbG9iYWwgQ3JlYXRvckFkZHJlc3MKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weToyMDQKICAgIC8vIGtleT0ibG9jYWxfdWludDY0IiwKICAgIGJ5dGUgImxvY2FsX3VpbnQ2NCIKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weToyMjAKICAgIC8vIHNlbGYubG9jYWxfdWludDY0W0dsb2JhbC5jcmVhdG9yX2FkZHJlc3NdID0gVUludDY0KDk5KQogICAgaW50IDk5CiAgICBhcHBfbG9jYWxfcHV0CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6MjIxCiAgICAvLyBzZWxmLmxvY2FsX2FyYzRfYnl0ZXNbR2xvYmFsLmNyZWF0b3JfYWRkcmVzc10gPSBhbGdvcHkuYXJjNC5EeW5hbWljQnl0ZXMoCiAgICBnbG9iYWwgQ3JlYXRvckFkZHJlc3MKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weToyMTQKICAgIC8vIGtleT0ibG9jYWxfYXJjNF9ieXRlcyIsCiAgICBieXRlICJsb2NhbF9hcmM0X2J5dGVzIgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjIyMS0yMjMKICAgIC8vIHNlbGYubG9jYWxfYXJjNF9ieXRlc1tHbG9iYWwuY3JlYXRvcl9hZGRyZXNzXSA9IGFsZ29weS5hcmM0LkR5bmFtaWNCeXRlcygKICAgIC8vICAgICBiImR1bW15X2FyYzRfYnl0ZXMiCiAgICAvLyApCiAgICBieXRlIDB4MDAxMDY0NzU2ZDZkNzk1ZjYxNzI2MzM0NWY2Mjc5NzQ2NTczCiAgICBhcHBfbG9jYWxfcHV0CiAgICByZXRzdWIK", - "clear": "I3ByYWdtYSB2ZXJzaW9uIDEwCgp0ZXN0cy5hcnRpZmFjdHMuU3RhdGVPcHMuY29udHJhY3QuU3RhdGVBcHBMb2NhbEV4Q29udHJhY3QuY2xlYXJfc3RhdGVfcHJvZ3JhbToKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weToyMDAKICAgIC8vIGNsYXNzIFN0YXRlQXBwTG9jYWxFeENvbnRyYWN0KEFSQzRDb250cmFjdCk6CiAgICBpbnQgMQogICAgcmV0dXJuCg==" + "approval": "I3ByYWdtYSB2ZXJzaW9uIDEwCgp0ZXN0cy5hcnRpZmFjdHMuU3RhdGVPcHMuY29udHJhY3QuU3RhdGVBcHBMb2NhbEV4Q29udHJhY3QuYXBwcm92YWxfcHJvZ3JhbToKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTozMTMKICAgIC8vIGNsYXNzIFN0YXRlQXBwTG9jYWxFeENvbnRyYWN0KEFSQzRDb250cmFjdCk6CiAgICB0eG4gTnVtQXBwQXJncwogICAgYnogbWFpbl9iYXJlX3JvdXRpbmdANQogICAgbWV0aG9kICJvcHRfaW4oKXZvaWQiCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAwCiAgICBtYXRjaCBtYWluX29wdF9pbl9yb3V0ZUAyCiAgICBlcnIgLy8gcmVqZWN0IHRyYW5zYWN0aW9uCgptYWluX29wdF9pbl9yb3V0ZUAyOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjMzMAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKGFsbG93X2FjdGlvbnM9WyJPcHRJbiJdKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgaW50IE9wdEluCiAgICA9PQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBPcHRJbgogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBpcyBub3QgY3JlYXRpbmcKICAgIGNhbGxzdWIgb3B0X2luCiAgICBpbnQgMQogICAgcmV0dXJuCgptYWluX2JhcmVfcm91dGluZ0A1OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjMxMwogICAgLy8gY2xhc3MgU3RhdGVBcHBMb2NhbEV4Q29udHJhY3QoQVJDNENvbnRyYWN0KToKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyByZWplY3QgdHJhbnNhY3Rpb24KICAgIHR4biBBcHBsaWNhdGlvbklECiAgICAhCiAgICBhc3NlcnQgLy8gaXMgY3JlYXRpbmcKICAgIGludCAxCiAgICByZXR1cm4KCgovLyB0ZXN0cy5hcnRpZmFjdHMuU3RhdGVPcHMuY29udHJhY3QuU3RhdGVBcHBMb2NhbEV4Q29udHJhY3Qub3B0X2luKCkgLT4gdm9pZDoKb3B0X2luOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjMzMC0zMzEKICAgIC8vIEBhcmM0LmFiaW1ldGhvZChhbGxvd19hY3Rpb25zPVsiT3B0SW4iXSkKICAgIC8vIGRlZiBvcHRfaW4oc2VsZikgLT4gTm9uZToKICAgIHByb3RvIDAgMAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjMzMgogICAgLy8gc2VsZi5sb2NhbF9ieXRlc1tHbG9iYWwuY3JlYXRvcl9hZGRyZXNzXSA9IEJ5dGVzKGIiZHVtbXlfYnl0ZXNfZnJvbV9leHRlcm5hbF9jb250cmFjdCIpCiAgICBnbG9iYWwgQ3JlYXRvckFkZHJlc3MKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTozMjIKICAgIC8vIGtleT0ibG9jYWxfYnl0ZXMiLAogICAgYnl0ZSAibG9jYWxfYnl0ZXMiCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6MzMyCiAgICAvLyBzZWxmLmxvY2FsX2J5dGVzW0dsb2JhbC5jcmVhdG9yX2FkZHJlc3NdID0gQnl0ZXMoYiJkdW1teV9ieXRlc19mcm9tX2V4dGVybmFsX2NvbnRyYWN0IikKICAgIGJ5dGUgMHg2NDc1NmQ2ZDc5NWY2Mjc5NzQ2NTczNWY2NjcyNmY2ZDVmNjU3ODc0NjU3MjZlNjE2YzVmNjM2ZjZlNzQ3MjYxNjM3NAogICAgYXBwX2xvY2FsX3B1dAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjMzMwogICAgLy8gc2VsZi5sb2NhbF91aW50NjRbR2xvYmFsLmNyZWF0b3JfYWRkcmVzc10gPSBVSW50NjQoOTkpCiAgICBnbG9iYWwgQ3JlYXRvckFkZHJlc3MKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTozMTcKICAgIC8vIGtleT0ibG9jYWxfdWludDY0IiwKICAgIGJ5dGUgImxvY2FsX3VpbnQ2NCIKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTozMzMKICAgIC8vIHNlbGYubG9jYWxfdWludDY0W0dsb2JhbC5jcmVhdG9yX2FkZHJlc3NdID0gVUludDY0KDk5KQogICAgaW50IDk5CiAgICBhcHBfbG9jYWxfcHV0CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6MzM0CiAgICAvLyBzZWxmLmxvY2FsX2FyYzRfYnl0ZXNbR2xvYmFsLmNyZWF0b3JfYWRkcmVzc10gPSBhbGdvcHkuYXJjNC5EeW5hbWljQnl0ZXMoCiAgICBnbG9iYWwgQ3JlYXRvckFkZHJlc3MKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTozMjcKICAgIC8vIGtleT0ibG9jYWxfYXJjNF9ieXRlcyIsCiAgICBieXRlICJsb2NhbF9hcmM0X2J5dGVzIgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjMzNC0zMzYKICAgIC8vIHNlbGYubG9jYWxfYXJjNF9ieXRlc1tHbG9iYWwuY3JlYXRvcl9hZGRyZXNzXSA9IGFsZ29weS5hcmM0LkR5bmFtaWNCeXRlcygKICAgIC8vICAgICBiImR1bW15X2FyYzRfYnl0ZXMiCiAgICAvLyApCiAgICBieXRlIDB4MDAxMDY0NzU2ZDZkNzk1ZjYxNzI2MzM0NWY2Mjc5NzQ2NTczCiAgICBhcHBfbG9jYWxfcHV0CiAgICByZXRzdWIK", + "clear": "I3ByYWdtYSB2ZXJzaW9uIDEwCgp0ZXN0cy5hcnRpZmFjdHMuU3RhdGVPcHMuY29udHJhY3QuU3RhdGVBcHBMb2NhbEV4Q29udHJhY3QuY2xlYXJfc3RhdGVfcHJvZ3JhbToKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTozMTMKICAgIC8vIGNsYXNzIFN0YXRlQXBwTG9jYWxFeENvbnRyYWN0KEFSQzRDb250cmFjdCk6CiAgICBpbnQgMQogICAgcmV0dXJuCg==" }, "state": { "global": { diff --git a/tests/artifacts/StateOps/data/StateAppLocalExContract.clear.teal b/tests/artifacts/StateOps/data/StateAppLocalExContract.clear.teal index 01b9c30..a633cb8 100644 --- a/tests/artifacts/StateOps/data/StateAppLocalExContract.clear.teal +++ b/tests/artifacts/StateOps/data/StateAppLocalExContract.clear.teal @@ -1,7 +1,7 @@ #pragma version 10 tests.artifacts.StateOps.contract.StateAppLocalExContract.clear_state_program: - // tests/artifacts/StateOps/contract.py:200 + // tests/artifacts/StateOps/contract.py:313 // class StateAppLocalExContract(ARC4Contract): int 1 return diff --git a/tests/artifacts/StateOps/data/StateAppParamsContract.approval.teal b/tests/artifacts/StateOps/data/StateAppParamsContract.approval.teal index 594b967..d0740bd 100644 --- a/tests/artifacts/StateOps/data/StateAppParamsContract.approval.teal +++ b/tests/artifacts/StateOps/data/StateAppParamsContract.approval.teal @@ -1,7 +1,7 @@ #pragma version 10 tests.artifacts.StateOps.contract.StateAppParamsContract.approval_program: - // tests/artifacts/StateOps/contract.py:153 + // tests/artifacts/StateOps/contract.py:238 // class StateAppParamsContract(ARC4Contract): txn NumAppArgs bz main_bare_routing@13 @@ -12,26 +12,26 @@ tests.artifacts.StateOps.contract.StateAppParamsContract.approval_program: method "verify_app_params_get_local_num_uint(application)uint64" method "verify_app_params_get_local_num_byte_slice(application)uint64" method "verify_app_params_get_extra_program_pages(application)uint64" - method "verify_app_params_get_creator(application)byte[]" - method "verify_app_params_get_address(application)byte[]" + method "verify_app_params_get_creator(application)address" + method "verify_app_params_get_address(application)address" txna ApplicationArgs 0 match main_verify_app_params_get_approval_program_route@2 main_verify_app_params_get_clear_state_program_route@3 main_verify_app_params_get_global_num_uint_route@4 main_verify_app_params_get_global_num_byte_slice_route@5 main_verify_app_params_get_local_num_uint_route@6 main_verify_app_params_get_local_num_byte_slice_route@7 main_verify_app_params_get_extra_program_pages_route@8 main_verify_app_params_get_creator_route@9 main_verify_app_params_get_address_route@10 err // reject transaction main_verify_app_params_get_approval_program_route@2: - // tests/artifacts/StateOps/contract.py:154 + // tests/artifacts/StateOps/contract.py:240 // @arc4.abimethod() txn OnCompletion ! assert // OnCompletion is NoOp txn ApplicationID assert // is not creating - // tests/artifacts/StateOps/contract.py:153 + // tests/artifacts/StateOps/contract.py:238 // class StateAppParamsContract(ARC4Contract): txna ApplicationArgs 1 btoi txnas Applications - // tests/artifacts/StateOps/contract.py:154 + // tests/artifacts/StateOps/contract.py:240 // @arc4.abimethod() callsub verify_app_params_get_approval_program dup @@ -48,19 +48,19 @@ main_verify_app_params_get_approval_program_route@2: return main_verify_app_params_get_clear_state_program_route@3: - // tests/artifacts/StateOps/contract.py:159 + // tests/artifacts/StateOps/contract.py:248 // @arc4.abimethod() txn OnCompletion ! assert // OnCompletion is NoOp txn ApplicationID assert // is not creating - // tests/artifacts/StateOps/contract.py:153 + // tests/artifacts/StateOps/contract.py:238 // class StateAppParamsContract(ARC4Contract): txna ApplicationArgs 1 btoi txnas Applications - // tests/artifacts/StateOps/contract.py:159 + // tests/artifacts/StateOps/contract.py:248 // @arc4.abimethod() callsub verify_app_params_get_clear_state_program dup @@ -77,19 +77,19 @@ main_verify_app_params_get_clear_state_program_route@3: return main_verify_app_params_get_global_num_uint_route@4: - // tests/artifacts/StateOps/contract.py:164 + // tests/artifacts/StateOps/contract.py:256 // @arc4.abimethod() txn OnCompletion ! assert // OnCompletion is NoOp txn ApplicationID assert // is not creating - // tests/artifacts/StateOps/contract.py:153 + // tests/artifacts/StateOps/contract.py:238 // class StateAppParamsContract(ARC4Contract): txna ApplicationArgs 1 btoi txnas Applications - // tests/artifacts/StateOps/contract.py:164 + // tests/artifacts/StateOps/contract.py:256 // @arc4.abimethod() callsub verify_app_params_get_global_num_uint itob @@ -101,19 +101,19 @@ main_verify_app_params_get_global_num_uint_route@4: return main_verify_app_params_get_global_num_byte_slice_route@5: - // tests/artifacts/StateOps/contract.py:169 + // tests/artifacts/StateOps/contract.py:264 // @arc4.abimethod() txn OnCompletion ! assert // OnCompletion is NoOp txn ApplicationID assert // is not creating - // tests/artifacts/StateOps/contract.py:153 + // tests/artifacts/StateOps/contract.py:238 // class StateAppParamsContract(ARC4Contract): txna ApplicationArgs 1 btoi txnas Applications - // tests/artifacts/StateOps/contract.py:169 + // tests/artifacts/StateOps/contract.py:264 // @arc4.abimethod() callsub verify_app_params_get_global_num_byte_slice itob @@ -125,19 +125,19 @@ main_verify_app_params_get_global_num_byte_slice_route@5: return main_verify_app_params_get_local_num_uint_route@6: - // tests/artifacts/StateOps/contract.py:174 + // tests/artifacts/StateOps/contract.py:272 // @arc4.abimethod() txn OnCompletion ! assert // OnCompletion is NoOp txn ApplicationID assert // is not creating - // tests/artifacts/StateOps/contract.py:153 + // tests/artifacts/StateOps/contract.py:238 // class StateAppParamsContract(ARC4Contract): txna ApplicationArgs 1 btoi txnas Applications - // tests/artifacts/StateOps/contract.py:174 + // tests/artifacts/StateOps/contract.py:272 // @arc4.abimethod() callsub verify_app_params_get_local_num_uint itob @@ -149,19 +149,19 @@ main_verify_app_params_get_local_num_uint_route@6: return main_verify_app_params_get_local_num_byte_slice_route@7: - // tests/artifacts/StateOps/contract.py:179 + // tests/artifacts/StateOps/contract.py:280 // @arc4.abimethod() txn OnCompletion ! assert // OnCompletion is NoOp txn ApplicationID assert // is not creating - // tests/artifacts/StateOps/contract.py:153 + // tests/artifacts/StateOps/contract.py:238 // class StateAppParamsContract(ARC4Contract): txna ApplicationArgs 1 btoi txnas Applications - // tests/artifacts/StateOps/contract.py:179 + // tests/artifacts/StateOps/contract.py:280 // @arc4.abimethod() callsub verify_app_params_get_local_num_byte_slice itob @@ -173,19 +173,19 @@ main_verify_app_params_get_local_num_byte_slice_route@7: return main_verify_app_params_get_extra_program_pages_route@8: - // tests/artifacts/StateOps/contract.py:184 + // tests/artifacts/StateOps/contract.py:288 // @arc4.abimethod() txn OnCompletion ! assert // OnCompletion is NoOp txn ApplicationID assert // is not creating - // tests/artifacts/StateOps/contract.py:153 + // tests/artifacts/StateOps/contract.py:238 // class StateAppParamsContract(ARC4Contract): txna ApplicationArgs 1 btoi txnas Applications - // tests/artifacts/StateOps/contract.py:184 + // tests/artifacts/StateOps/contract.py:288 // @arc4.abimethod() callsub verify_app_params_get_extra_program_pages itob @@ -197,27 +197,21 @@ main_verify_app_params_get_extra_program_pages_route@8: return main_verify_app_params_get_creator_route@9: - // tests/artifacts/StateOps/contract.py:189 + // tests/artifacts/StateOps/contract.py:296 // @arc4.abimethod() txn OnCompletion ! assert // OnCompletion is NoOp txn ApplicationID assert // is not creating - // tests/artifacts/StateOps/contract.py:153 + // tests/artifacts/StateOps/contract.py:238 // class StateAppParamsContract(ARC4Contract): txna ApplicationArgs 1 btoi txnas Applications - // tests/artifacts/StateOps/contract.py:189 + // tests/artifacts/StateOps/contract.py:296 // @arc4.abimethod() callsub verify_app_params_get_creator - dup - len - itob - extract 6 2 - swap - concat byte 0x151f7c75 swap concat @@ -226,27 +220,21 @@ main_verify_app_params_get_creator_route@9: return main_verify_app_params_get_address_route@10: - // tests/artifacts/StateOps/contract.py:194 + // tests/artifacts/StateOps/contract.py:304 // @arc4.abimethod() txn OnCompletion ! assert // OnCompletion is NoOp txn ApplicationID assert // is not creating - // tests/artifacts/StateOps/contract.py:153 + // tests/artifacts/StateOps/contract.py:238 // class StateAppParamsContract(ARC4Contract): txna ApplicationArgs 1 btoi txnas Applications - // tests/artifacts/StateOps/contract.py:194 + // tests/artifacts/StateOps/contract.py:304 // @arc4.abimethod() callsub verify_app_params_get_address - dup - len - itob - extract 6 2 - swap - concat byte 0x151f7c75 swap concat @@ -255,7 +243,7 @@ main_verify_app_params_get_address_route@10: return main_bare_routing@13: - // tests/artifacts/StateOps/contract.py:153 + // tests/artifacts/StateOps/contract.py:238 // class StateAppParamsContract(ARC4Contract): txn OnCompletion ! @@ -269,143 +257,291 @@ main_bare_routing@13: // tests.artifacts.StateOps.contract.StateAppParamsContract.verify_app_params_get_approval_program(a: uint64) -> bytes: verify_app_params_get_approval_program: - // tests/artifacts/StateOps/contract.py:154-155 + // tests/artifacts/StateOps/contract.py:240-241 // @arc4.abimethod() // def verify_app_params_get_approval_program(self, a: Application) -> Bytes: proto 1 1 - // tests/artifacts/StateOps/contract.py:156 - // approval_program, _val = op.AppParamsGet.app_approval_program(a) + // tests/artifacts/StateOps/contract.py:242 + // value, exists = op.AppParamsGet.app_approval_program(a) frame_dig -1 app_params_get AppApprovalProgram - pop - // tests/artifacts/StateOps/contract.py:157 - // return approval_program + swap + // tests/artifacts/StateOps/contract.py:243 + // value_index, exists_index = op.AppParamsGet.app_approval_program(_get_1st_ref_index()) + callsub _get_1st_ref_index + app_params_get AppApprovalProgram + cover 2 + // tests/artifacts/StateOps/contract.py:244 + // assert value == value_index, "expected value by index to match" + dig 1 + == + assert // expected value by index to match + // tests/artifacts/StateOps/contract.py:245 + // assert exists == exists_index, "expected exists by index to match" + cover 2 + == + assert // expected exists by index to match + // tests/artifacts/StateOps/contract.py:246 + // return value + retsub + + +// tests.artifacts.StateOps.contract._get_1st_ref_index() -> uint64: +_get_1st_ref_index: + // tests/artifacts/StateOps/contract.py:19-20 + // @subroutine + // def _get_1st_ref_index() -> UInt64: + proto 0 1 + // tests/artifacts/StateOps/contract.py:21 + // return op.btoi(Txn.application_args(1)) + txna ApplicationArgs 1 + btoi retsub // tests.artifacts.StateOps.contract.StateAppParamsContract.verify_app_params_get_clear_state_program(a: uint64) -> bytes: verify_app_params_get_clear_state_program: - // tests/artifacts/StateOps/contract.py:159-160 + // tests/artifacts/StateOps/contract.py:248-249 // @arc4.abimethod() // def verify_app_params_get_clear_state_program(self, a: Application) -> Bytes: proto 1 1 - // tests/artifacts/StateOps/contract.py:161 - // clear_state_program, _val = op.AppParamsGet.app_clear_state_program(a) + // tests/artifacts/StateOps/contract.py:250 + // value, exists = op.AppParamsGet.app_clear_state_program(a) frame_dig -1 app_params_get AppClearStateProgram - pop - // tests/artifacts/StateOps/contract.py:162 - // return clear_state_program + swap + // tests/artifacts/StateOps/contract.py:251 + // value_index, exists_index = op.AppParamsGet.app_clear_state_program(_get_1st_ref_index()) + callsub _get_1st_ref_index + app_params_get AppClearStateProgram + cover 2 + // tests/artifacts/StateOps/contract.py:252 + // assert value == value_index, "expected value by index to match" + dig 1 + == + assert // expected value by index to match + // tests/artifacts/StateOps/contract.py:253 + // assert exists == exists_index, "expected exists by index to match" + cover 2 + == + assert // expected exists by index to match + // tests/artifacts/StateOps/contract.py:254 + // return value retsub // tests.artifacts.StateOps.contract.StateAppParamsContract.verify_app_params_get_global_num_uint(a: uint64) -> uint64: verify_app_params_get_global_num_uint: - // tests/artifacts/StateOps/contract.py:164-165 + // tests/artifacts/StateOps/contract.py:256-257 // @arc4.abimethod() // def verify_app_params_get_global_num_uint(self, a: Application) -> UInt64: proto 1 1 - // tests/artifacts/StateOps/contract.py:166 - // global_num_uint, _val = op.AppParamsGet.app_global_num_uint(a) + // tests/artifacts/StateOps/contract.py:258 + // value, exists = op.AppParamsGet.app_global_num_uint(a) frame_dig -1 app_params_get AppGlobalNumUint - pop - // tests/artifacts/StateOps/contract.py:167 - // return global_num_uint + swap + // tests/artifacts/StateOps/contract.py:259 + // value_index, exists_index = op.AppParamsGet.app_global_num_uint(_get_1st_ref_index()) + callsub _get_1st_ref_index + app_params_get AppGlobalNumUint + cover 2 + // tests/artifacts/StateOps/contract.py:260 + // assert value == value_index, "expected value by index to match" + dig 1 + == + assert // expected value by index to match + // tests/artifacts/StateOps/contract.py:261 + // assert exists == exists_index, "expected exists by index to match" + cover 2 + == + assert // expected exists by index to match + // tests/artifacts/StateOps/contract.py:262 + // return value retsub // tests.artifacts.StateOps.contract.StateAppParamsContract.verify_app_params_get_global_num_byte_slice(a: uint64) -> uint64: verify_app_params_get_global_num_byte_slice: - // tests/artifacts/StateOps/contract.py:169-170 + // tests/artifacts/StateOps/contract.py:264-265 // @arc4.abimethod() // def verify_app_params_get_global_num_byte_slice(self, a: Application) -> UInt64: proto 1 1 - // tests/artifacts/StateOps/contract.py:171 - // global_num_byte_slice, _val = op.AppParamsGet.app_global_num_byte_slice(a) + // tests/artifacts/StateOps/contract.py:266 + // value, exists = op.AppParamsGet.app_global_num_byte_slice(a) frame_dig -1 app_params_get AppGlobalNumByteSlice - pop - // tests/artifacts/StateOps/contract.py:172 - // return global_num_byte_slice + swap + // tests/artifacts/StateOps/contract.py:267 + // value_index, exists_index = op.AppParamsGet.app_global_num_byte_slice(_get_1st_ref_index()) + callsub _get_1st_ref_index + app_params_get AppGlobalNumByteSlice + cover 2 + // tests/artifacts/StateOps/contract.py:268 + // assert value == value_index, "expected value by index to match" + dig 1 + == + assert // expected value by index to match + // tests/artifacts/StateOps/contract.py:269 + // assert exists == exists_index, "expected exists by index to match" + cover 2 + == + assert // expected exists by index to match + // tests/artifacts/StateOps/contract.py:270 + // return value retsub // tests.artifacts.StateOps.contract.StateAppParamsContract.verify_app_params_get_local_num_uint(a: uint64) -> uint64: verify_app_params_get_local_num_uint: - // tests/artifacts/StateOps/contract.py:174-175 + // tests/artifacts/StateOps/contract.py:272-273 // @arc4.abimethod() // def verify_app_params_get_local_num_uint(self, a: Application) -> UInt64: proto 1 1 - // tests/artifacts/StateOps/contract.py:176 - // local_num_uint, _val = op.AppParamsGet.app_local_num_uint(a) + // tests/artifacts/StateOps/contract.py:274 + // value, exists = op.AppParamsGet.app_local_num_uint(a) frame_dig -1 app_params_get AppLocalNumUint - pop - // tests/artifacts/StateOps/contract.py:177 - // return local_num_uint + swap + // tests/artifacts/StateOps/contract.py:275 + // value_index, exists_index = op.AppParamsGet.app_local_num_uint(_get_1st_ref_index()) + callsub _get_1st_ref_index + app_params_get AppLocalNumUint + cover 2 + // tests/artifacts/StateOps/contract.py:276 + // assert value == value_index, "expected value by index to match" + dig 1 + == + assert // expected value by index to match + // tests/artifacts/StateOps/contract.py:277 + // assert exists == exists_index, "expected exists by index to match" + cover 2 + == + assert // expected exists by index to match + // tests/artifacts/StateOps/contract.py:278 + // return value retsub // tests.artifacts.StateOps.contract.StateAppParamsContract.verify_app_params_get_local_num_byte_slice(a: uint64) -> uint64: verify_app_params_get_local_num_byte_slice: - // tests/artifacts/StateOps/contract.py:179-180 + // tests/artifacts/StateOps/contract.py:280-281 // @arc4.abimethod() // def verify_app_params_get_local_num_byte_slice(self, a: Application) -> UInt64: proto 1 1 - // tests/artifacts/StateOps/contract.py:181 - // local_num_byte_slice, _val = op.AppParamsGet.app_local_num_byte_slice(a) + // tests/artifacts/StateOps/contract.py:282 + // value, exists = op.AppParamsGet.app_local_num_byte_slice(a) frame_dig -1 app_params_get AppLocalNumByteSlice - pop - // tests/artifacts/StateOps/contract.py:182 - // return local_num_byte_slice + swap + // tests/artifacts/StateOps/contract.py:283 + // value_index, exists_index = op.AppParamsGet.app_local_num_byte_slice(_get_1st_ref_index()) + callsub _get_1st_ref_index + app_params_get AppLocalNumByteSlice + cover 2 + // tests/artifacts/StateOps/contract.py:284 + // assert value == value_index, "expected value by index to match" + dig 1 + == + assert // expected value by index to match + // tests/artifacts/StateOps/contract.py:285 + // assert exists == exists_index, "expected exists by index to match" + cover 2 + == + assert // expected exists by index to match + // tests/artifacts/StateOps/contract.py:286 + // return value retsub // tests.artifacts.StateOps.contract.StateAppParamsContract.verify_app_params_get_extra_program_pages(a: uint64) -> uint64: verify_app_params_get_extra_program_pages: - // tests/artifacts/StateOps/contract.py:184-185 + // tests/artifacts/StateOps/contract.py:288-289 // @arc4.abimethod() // def verify_app_params_get_extra_program_pages(self, a: Application) -> UInt64: proto 1 1 - // tests/artifacts/StateOps/contract.py:186 - // extra_program_pages, _val = op.AppParamsGet.app_extra_program_pages(a) + // tests/artifacts/StateOps/contract.py:290 + // value, exists = op.AppParamsGet.app_extra_program_pages(a) frame_dig -1 app_params_get AppExtraProgramPages - pop - // tests/artifacts/StateOps/contract.py:187 - // return extra_program_pages + swap + // tests/artifacts/StateOps/contract.py:291 + // value_index, exists_index = op.AppParamsGet.app_extra_program_pages(_get_1st_ref_index()) + callsub _get_1st_ref_index + app_params_get AppExtraProgramPages + cover 2 + // tests/artifacts/StateOps/contract.py:292 + // assert value == value_index, "expected value by index to match" + dig 1 + == + assert // expected value by index to match + // tests/artifacts/StateOps/contract.py:293 + // assert exists == exists_index, "expected exists by index to match" + cover 2 + == + assert // expected exists by index to match + // tests/artifacts/StateOps/contract.py:294 + // return value retsub // tests.artifacts.StateOps.contract.StateAppParamsContract.verify_app_params_get_creator(a: uint64) -> bytes: verify_app_params_get_creator: - // tests/artifacts/StateOps/contract.py:189-190 + // tests/artifacts/StateOps/contract.py:296-297 // @arc4.abimethod() - // def verify_app_params_get_creator(self, a: Application) -> Bytes: + // def verify_app_params_get_creator(self, a: Application) -> arc4.Address: proto 1 1 - // tests/artifacts/StateOps/contract.py:191 - // creator, _val = op.AppParamsGet.app_creator(a) + // tests/artifacts/StateOps/contract.py:298 + // value, exists = op.AppParamsGet.app_creator(a) frame_dig -1 app_params_get AppCreator - pop - // tests/artifacts/StateOps/contract.py:192 - // return creator.bytes + swap + // tests/artifacts/StateOps/contract.py:299 + // value_index, exists_index = op.AppParamsGet.app_creator(_get_1st_ref_index()) + callsub _get_1st_ref_index + app_params_get AppCreator + cover 2 + // tests/artifacts/StateOps/contract.py:300 + // assert value == value_index, "expected value by index to match" + dig 1 + == + assert // expected value by index to match + // tests/artifacts/StateOps/contract.py:301 + // assert exists == exists_index, "expected exists by index to match" + cover 2 + == + assert // expected exists by index to match + // tests/artifacts/StateOps/contract.py:302 + // return arc4.Address(value) retsub // tests.artifacts.StateOps.contract.StateAppParamsContract.verify_app_params_get_address(a: uint64) -> bytes: verify_app_params_get_address: - // tests/artifacts/StateOps/contract.py:194-195 + // tests/artifacts/StateOps/contract.py:304-305 // @arc4.abimethod() - // def verify_app_params_get_address(self, a: Application) -> Bytes: + // def verify_app_params_get_address(self, a: Application) -> arc4.Address: proto 1 1 - // tests/artifacts/StateOps/contract.py:196 - // address, _val = op.AppParamsGet.app_address(a) + // tests/artifacts/StateOps/contract.py:306 + // value, exists = op.AppParamsGet.app_address(a) frame_dig -1 app_params_get AppAddress - pop - // tests/artifacts/StateOps/contract.py:197 - // return address.bytes + swap + // tests/artifacts/StateOps/contract.py:307 + // value_index, exists_index = op.AppParamsGet.app_address(_get_1st_ref_index()) + callsub _get_1st_ref_index + app_params_get AppAddress + cover 2 + // tests/artifacts/StateOps/contract.py:308 + // assert value == value_index, "expected value by index to match" + dig 1 + == + assert // expected value by index to match + // tests/artifacts/StateOps/contract.py:309 + // assert exists == exists_index, "expected exists by index to match" + cover 2 + == + assert // expected exists by index to match + // tests/artifacts/StateOps/contract.py:310 + // return arc4.Address(value) retsub diff --git a/tests/artifacts/StateOps/data/StateAppParamsContract.arc32.json b/tests/artifacts/StateOps/data/StateAppParamsContract.arc32.json index eff143f..0a4509e 100644 --- a/tests/artifacts/StateOps/data/StateAppParamsContract.arc32.json +++ b/tests/artifacts/StateOps/data/StateAppParamsContract.arc32.json @@ -35,20 +35,20 @@ "no_op": "CALL" } }, - "verify_app_params_get_creator(application)byte[]": { + "verify_app_params_get_creator(application)address": { "call_config": { "no_op": "CALL" } }, - "verify_app_params_get_address(application)byte[]": { + "verify_app_params_get_address(application)address": { "call_config": { "no_op": "CALL" } } }, "source": { - "approval": "I3ByYWdtYSB2ZXJzaW9uIDEwCgp0ZXN0cy5hcnRpZmFjdHMuU3RhdGVPcHMuY29udHJhY3QuU3RhdGVBcHBQYXJhbXNDb250cmFjdC5hcHByb3ZhbF9wcm9ncmFtOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjE1MwogICAgLy8gY2xhc3MgU3RhdGVBcHBQYXJhbXNDb250cmFjdChBUkM0Q29udHJhY3QpOgogICAgdHhuIE51bUFwcEFyZ3MKICAgIGJ6IG1haW5fYmFyZV9yb3V0aW5nQDEzCiAgICBtZXRob2QgInZlcmlmeV9hcHBfcGFyYW1zX2dldF9hcHByb3ZhbF9wcm9ncmFtKGFwcGxpY2F0aW9uKWJ5dGVbXSIKICAgIG1ldGhvZCAidmVyaWZ5X2FwcF9wYXJhbXNfZ2V0X2NsZWFyX3N0YXRlX3Byb2dyYW0oYXBwbGljYXRpb24pYnl0ZVtdIgogICAgbWV0aG9kICJ2ZXJpZnlfYXBwX3BhcmFtc19nZXRfZ2xvYmFsX251bV91aW50KGFwcGxpY2F0aW9uKXVpbnQ2NCIKICAgIG1ldGhvZCAidmVyaWZ5X2FwcF9wYXJhbXNfZ2V0X2dsb2JhbF9udW1fYnl0ZV9zbGljZShhcHBsaWNhdGlvbil1aW50NjQiCiAgICBtZXRob2QgInZlcmlmeV9hcHBfcGFyYW1zX2dldF9sb2NhbF9udW1fdWludChhcHBsaWNhdGlvbil1aW50NjQiCiAgICBtZXRob2QgInZlcmlmeV9hcHBfcGFyYW1zX2dldF9sb2NhbF9udW1fYnl0ZV9zbGljZShhcHBsaWNhdGlvbil1aW50NjQiCiAgICBtZXRob2QgInZlcmlmeV9hcHBfcGFyYW1zX2dldF9leHRyYV9wcm9ncmFtX3BhZ2VzKGFwcGxpY2F0aW9uKXVpbnQ2NCIKICAgIG1ldGhvZCAidmVyaWZ5X2FwcF9wYXJhbXNfZ2V0X2NyZWF0b3IoYXBwbGljYXRpb24pYnl0ZVtdIgogICAgbWV0aG9kICJ2ZXJpZnlfYXBwX3BhcmFtc19nZXRfYWRkcmVzcyhhcHBsaWNhdGlvbilieXRlW10iCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAwCiAgICBtYXRjaCBtYWluX3ZlcmlmeV9hcHBfcGFyYW1zX2dldF9hcHByb3ZhbF9wcm9ncmFtX3JvdXRlQDIgbWFpbl92ZXJpZnlfYXBwX3BhcmFtc19nZXRfY2xlYXJfc3RhdGVfcHJvZ3JhbV9yb3V0ZUAzIG1haW5fdmVyaWZ5X2FwcF9wYXJhbXNfZ2V0X2dsb2JhbF9udW1fdWludF9yb3V0ZUA0IG1haW5fdmVyaWZ5X2FwcF9wYXJhbXNfZ2V0X2dsb2JhbF9udW1fYnl0ZV9zbGljZV9yb3V0ZUA1IG1haW5fdmVyaWZ5X2FwcF9wYXJhbXNfZ2V0X2xvY2FsX251bV91aW50X3JvdXRlQDYgbWFpbl92ZXJpZnlfYXBwX3BhcmFtc19nZXRfbG9jYWxfbnVtX2J5dGVfc2xpY2Vfcm91dGVANyBtYWluX3ZlcmlmeV9hcHBfcGFyYW1zX2dldF9leHRyYV9wcm9ncmFtX3BhZ2VzX3JvdXRlQDggbWFpbl92ZXJpZnlfYXBwX3BhcmFtc19nZXRfY3JlYXRvcl9yb3V0ZUA5IG1haW5fdmVyaWZ5X2FwcF9wYXJhbXNfZ2V0X2FkZHJlc3Nfcm91dGVAMTAKICAgIGVyciAvLyByZWplY3QgdHJhbnNhY3Rpb24KCm1haW5fdmVyaWZ5X2FwcF9wYXJhbXNfZ2V0X2FwcHJvdmFsX3Byb2dyYW1fcm91dGVAMjoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weToxNTQKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gaXMgbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6MTUzCiAgICAvLyBjbGFzcyBTdGF0ZUFwcFBhcmFtc0NvbnRyYWN0KEFSQzRDb250cmFjdCk6CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBidG9pCiAgICB0eG5hcyBBcHBsaWNhdGlvbnMKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weToxNTQKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV9hcHBfcGFyYW1zX2dldF9hcHByb3ZhbF9wcm9ncmFtCiAgICBkdXAKICAgIGxlbgogICAgaXRvYgogICAgZXh0cmFjdCA2IDIKICAgIHN3YXAKICAgIGNvbmNhdAogICAgYnl0ZSAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50IDEKICAgIHJldHVybgoKbWFpbl92ZXJpZnlfYXBwX3BhcmFtc19nZXRfY2xlYXJfc3RhdGVfcHJvZ3JhbV9yb3V0ZUAzOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjE1OQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBpcyBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weToxNTMKICAgIC8vIGNsYXNzIFN0YXRlQXBwUGFyYW1zQ29udHJhY3QoQVJDNENvbnRyYWN0KToKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGJ0b2kKICAgIHR4bmFzIEFwcGxpY2F0aW9ucwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjE1OQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X2FwcF9wYXJhbXNfZ2V0X2NsZWFyX3N0YXRlX3Byb2dyYW0KICAgIGR1cAogICAgbGVuCiAgICBpdG9iCiAgICBleHRyYWN0IDYgMgogICAgc3dhcAogICAgY29uY2F0CiAgICBieXRlIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnQgMQogICAgcmV0dXJuCgptYWluX3ZlcmlmeV9hcHBfcGFyYW1zX2dldF9nbG9iYWxfbnVtX3VpbnRfcm91dGVANDoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weToxNjQKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gaXMgbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6MTUzCiAgICAvLyBjbGFzcyBTdGF0ZUFwcFBhcmFtc0NvbnRyYWN0KEFSQzRDb250cmFjdCk6CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBidG9pCiAgICB0eG5hcyBBcHBsaWNhdGlvbnMKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weToxNjQKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV9hcHBfcGFyYW1zX2dldF9nbG9iYWxfbnVtX3VpbnQKICAgIGl0b2IKICAgIGJ5dGUgMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludCAxCiAgICByZXR1cm4KCm1haW5fdmVyaWZ5X2FwcF9wYXJhbXNfZ2V0X2dsb2JhbF9udW1fYnl0ZV9zbGljZV9yb3V0ZUA1OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjE2OQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBpcyBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weToxNTMKICAgIC8vIGNsYXNzIFN0YXRlQXBwUGFyYW1zQ29udHJhY3QoQVJDNENvbnRyYWN0KToKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGJ0b2kKICAgIHR4bmFzIEFwcGxpY2F0aW9ucwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjE2OQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X2FwcF9wYXJhbXNfZ2V0X2dsb2JhbF9udW1fYnl0ZV9zbGljZQogICAgaXRvYgogICAgYnl0ZSAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50IDEKICAgIHJldHVybgoKbWFpbl92ZXJpZnlfYXBwX3BhcmFtc19nZXRfbG9jYWxfbnVtX3VpbnRfcm91dGVANjoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weToxNzQKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gaXMgbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6MTUzCiAgICAvLyBjbGFzcyBTdGF0ZUFwcFBhcmFtc0NvbnRyYWN0KEFSQzRDb250cmFjdCk6CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBidG9pCiAgICB0eG5hcyBBcHBsaWNhdGlvbnMKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weToxNzQKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV9hcHBfcGFyYW1zX2dldF9sb2NhbF9udW1fdWludAogICAgaXRvYgogICAgYnl0ZSAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50IDEKICAgIHJldHVybgoKbWFpbl92ZXJpZnlfYXBwX3BhcmFtc19nZXRfbG9jYWxfbnVtX2J5dGVfc2xpY2Vfcm91dGVANzoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weToxNzkKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gaXMgbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6MTUzCiAgICAvLyBjbGFzcyBTdGF0ZUFwcFBhcmFtc0NvbnRyYWN0KEFSQzRDb250cmFjdCk6CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBidG9pCiAgICB0eG5hcyBBcHBsaWNhdGlvbnMKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weToxNzkKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV9hcHBfcGFyYW1zX2dldF9sb2NhbF9udW1fYnl0ZV9zbGljZQogICAgaXRvYgogICAgYnl0ZSAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50IDEKICAgIHJldHVybgoKbWFpbl92ZXJpZnlfYXBwX3BhcmFtc19nZXRfZXh0cmFfcHJvZ3JhbV9wYWdlc19yb3V0ZUA4OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjE4NAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBpcyBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weToxNTMKICAgIC8vIGNsYXNzIFN0YXRlQXBwUGFyYW1zQ29udHJhY3QoQVJDNENvbnRyYWN0KToKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGJ0b2kKICAgIHR4bmFzIEFwcGxpY2F0aW9ucwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjE4NAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X2FwcF9wYXJhbXNfZ2V0X2V4dHJhX3Byb2dyYW1fcGFnZXMKICAgIGl0b2IKICAgIGJ5dGUgMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludCAxCiAgICByZXR1cm4KCm1haW5fdmVyaWZ5X2FwcF9wYXJhbXNfZ2V0X2NyZWF0b3Jfcm91dGVAOToKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weToxODkKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gaXMgbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6MTUzCiAgICAvLyBjbGFzcyBTdGF0ZUFwcFBhcmFtc0NvbnRyYWN0KEFSQzRDb250cmFjdCk6CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBidG9pCiAgICB0eG5hcyBBcHBsaWNhdGlvbnMKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weToxODkKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV9hcHBfcGFyYW1zX2dldF9jcmVhdG9yCiAgICBkdXAKICAgIGxlbgogICAgaXRvYgogICAgZXh0cmFjdCA2IDIKICAgIHN3YXAKICAgIGNvbmNhdAogICAgYnl0ZSAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50IDEKICAgIHJldHVybgoKbWFpbl92ZXJpZnlfYXBwX3BhcmFtc19nZXRfYWRkcmVzc19yb3V0ZUAxMDoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weToxOTQKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gaXMgbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6MTUzCiAgICAvLyBjbGFzcyBTdGF0ZUFwcFBhcmFtc0NvbnRyYWN0KEFSQzRDb250cmFjdCk6CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBidG9pCiAgICB0eG5hcyBBcHBsaWNhdGlvbnMKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weToxOTQKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV9hcHBfcGFyYW1zX2dldF9hZGRyZXNzCiAgICBkdXAKICAgIGxlbgogICAgaXRvYgogICAgZXh0cmFjdCA2IDIKICAgIHN3YXAKICAgIGNvbmNhdAogICAgYnl0ZSAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50IDEKICAgIHJldHVybgoKbWFpbl9iYXJlX3JvdXRpbmdAMTM6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6MTUzCiAgICAvLyBjbGFzcyBTdGF0ZUFwcFBhcmFtc0NvbnRyYWN0KEFSQzRDb250cmFjdCk6CiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gcmVqZWN0IHRyYW5zYWN0aW9uCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgIQogICAgYXNzZXJ0IC8vIGlzIGNyZWF0aW5nCiAgICBpbnQgMQogICAgcmV0dXJuCgoKLy8gdGVzdHMuYXJ0aWZhY3RzLlN0YXRlT3BzLmNvbnRyYWN0LlN0YXRlQXBwUGFyYW1zQ29udHJhY3QudmVyaWZ5X2FwcF9wYXJhbXNfZ2V0X2FwcHJvdmFsX3Byb2dyYW0oYTogdWludDY0KSAtPiBieXRlczoKdmVyaWZ5X2FwcF9wYXJhbXNfZ2V0X2FwcHJvdmFsX3Byb2dyYW06CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6MTU0LTE1NQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIGRlZiB2ZXJpZnlfYXBwX3BhcmFtc19nZXRfYXBwcm92YWxfcHJvZ3JhbShzZWxmLCBhOiBBcHBsaWNhdGlvbikgLT4gQnl0ZXM6CiAgICBwcm90byAxIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weToxNTYKICAgIC8vIGFwcHJvdmFsX3Byb2dyYW0sIF92YWwgPSBvcC5BcHBQYXJhbXNHZXQuYXBwX2FwcHJvdmFsX3Byb2dyYW0oYSkKICAgIGZyYW1lX2RpZyAtMQogICAgYXBwX3BhcmFtc19nZXQgQXBwQXBwcm92YWxQcm9ncmFtCiAgICBwb3AKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weToxNTcKICAgIC8vIHJldHVybiBhcHByb3ZhbF9wcm9ncmFtCiAgICByZXRzdWIKCgovLyB0ZXN0cy5hcnRpZmFjdHMuU3RhdGVPcHMuY29udHJhY3QuU3RhdGVBcHBQYXJhbXNDb250cmFjdC52ZXJpZnlfYXBwX3BhcmFtc19nZXRfY2xlYXJfc3RhdGVfcHJvZ3JhbShhOiB1aW50NjQpIC0+IGJ5dGVzOgp2ZXJpZnlfYXBwX3BhcmFtc19nZXRfY2xlYXJfc3RhdGVfcHJvZ3JhbToKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weToxNTktMTYwCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gZGVmIHZlcmlmeV9hcHBfcGFyYW1zX2dldF9jbGVhcl9zdGF0ZV9wcm9ncmFtKHNlbGYsIGE6IEFwcGxpY2F0aW9uKSAtPiBCeXRlczoKICAgIHByb3RvIDEgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjE2MQogICAgLy8gY2xlYXJfc3RhdGVfcHJvZ3JhbSwgX3ZhbCA9IG9wLkFwcFBhcmFtc0dldC5hcHBfY2xlYXJfc3RhdGVfcHJvZ3JhbShhKQogICAgZnJhbWVfZGlnIC0xCiAgICBhcHBfcGFyYW1zX2dldCBBcHBDbGVhclN0YXRlUHJvZ3JhbQogICAgcG9wCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6MTYyCiAgICAvLyByZXR1cm4gY2xlYXJfc3RhdGVfcHJvZ3JhbQogICAgcmV0c3ViCgoKLy8gdGVzdHMuYXJ0aWZhY3RzLlN0YXRlT3BzLmNvbnRyYWN0LlN0YXRlQXBwUGFyYW1zQ29udHJhY3QudmVyaWZ5X2FwcF9wYXJhbXNfZ2V0X2dsb2JhbF9udW1fdWludChhOiB1aW50NjQpIC0+IHVpbnQ2NDoKdmVyaWZ5X2FwcF9wYXJhbXNfZ2V0X2dsb2JhbF9udW1fdWludDoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weToxNjQtMTY1CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gZGVmIHZlcmlmeV9hcHBfcGFyYW1zX2dldF9nbG9iYWxfbnVtX3VpbnQoc2VsZiwgYTogQXBwbGljYXRpb24pIC0+IFVJbnQ2NDoKICAgIHByb3RvIDEgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjE2NgogICAgLy8gZ2xvYmFsX251bV91aW50LCBfdmFsID0gb3AuQXBwUGFyYW1zR2V0LmFwcF9nbG9iYWxfbnVtX3VpbnQoYSkKICAgIGZyYW1lX2RpZyAtMQogICAgYXBwX3BhcmFtc19nZXQgQXBwR2xvYmFsTnVtVWludAogICAgcG9wCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6MTY3CiAgICAvLyByZXR1cm4gZ2xvYmFsX251bV91aW50CiAgICByZXRzdWIKCgovLyB0ZXN0cy5hcnRpZmFjdHMuU3RhdGVPcHMuY29udHJhY3QuU3RhdGVBcHBQYXJhbXNDb250cmFjdC52ZXJpZnlfYXBwX3BhcmFtc19nZXRfZ2xvYmFsX251bV9ieXRlX3NsaWNlKGE6IHVpbnQ2NCkgLT4gdWludDY0Ogp2ZXJpZnlfYXBwX3BhcmFtc19nZXRfZ2xvYmFsX251bV9ieXRlX3NsaWNlOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjE2OS0xNzAKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBkZWYgdmVyaWZ5X2FwcF9wYXJhbXNfZ2V0X2dsb2JhbF9udW1fYnl0ZV9zbGljZShzZWxmLCBhOiBBcHBsaWNhdGlvbikgLT4gVUludDY0OgogICAgcHJvdG8gMSAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6MTcxCiAgICAvLyBnbG9iYWxfbnVtX2J5dGVfc2xpY2UsIF92YWwgPSBvcC5BcHBQYXJhbXNHZXQuYXBwX2dsb2JhbF9udW1fYnl0ZV9zbGljZShhKQogICAgZnJhbWVfZGlnIC0xCiAgICBhcHBfcGFyYW1zX2dldCBBcHBHbG9iYWxOdW1CeXRlU2xpY2UKICAgIHBvcAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjE3MgogICAgLy8gcmV0dXJuIGdsb2JhbF9udW1fYnl0ZV9zbGljZQogICAgcmV0c3ViCgoKLy8gdGVzdHMuYXJ0aWZhY3RzLlN0YXRlT3BzLmNvbnRyYWN0LlN0YXRlQXBwUGFyYW1zQ29udHJhY3QudmVyaWZ5X2FwcF9wYXJhbXNfZ2V0X2xvY2FsX251bV91aW50KGE6IHVpbnQ2NCkgLT4gdWludDY0Ogp2ZXJpZnlfYXBwX3BhcmFtc19nZXRfbG9jYWxfbnVtX3VpbnQ6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6MTc0LTE3NQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIGRlZiB2ZXJpZnlfYXBwX3BhcmFtc19nZXRfbG9jYWxfbnVtX3VpbnQoc2VsZiwgYTogQXBwbGljYXRpb24pIC0+IFVJbnQ2NDoKICAgIHByb3RvIDEgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjE3NgogICAgLy8gbG9jYWxfbnVtX3VpbnQsIF92YWwgPSBvcC5BcHBQYXJhbXNHZXQuYXBwX2xvY2FsX251bV91aW50KGEpCiAgICBmcmFtZV9kaWcgLTEKICAgIGFwcF9wYXJhbXNfZ2V0IEFwcExvY2FsTnVtVWludAogICAgcG9wCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6MTc3CiAgICAvLyByZXR1cm4gbG9jYWxfbnVtX3VpbnQKICAgIHJldHN1YgoKCi8vIHRlc3RzLmFydGlmYWN0cy5TdGF0ZU9wcy5jb250cmFjdC5TdGF0ZUFwcFBhcmFtc0NvbnRyYWN0LnZlcmlmeV9hcHBfcGFyYW1zX2dldF9sb2NhbF9udW1fYnl0ZV9zbGljZShhOiB1aW50NjQpIC0+IHVpbnQ2NDoKdmVyaWZ5X2FwcF9wYXJhbXNfZ2V0X2xvY2FsX251bV9ieXRlX3NsaWNlOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjE3OS0xODAKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBkZWYgdmVyaWZ5X2FwcF9wYXJhbXNfZ2V0X2xvY2FsX251bV9ieXRlX3NsaWNlKHNlbGYsIGE6IEFwcGxpY2F0aW9uKSAtPiBVSW50NjQ6CiAgICBwcm90byAxIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weToxODEKICAgIC8vIGxvY2FsX251bV9ieXRlX3NsaWNlLCBfdmFsID0gb3AuQXBwUGFyYW1zR2V0LmFwcF9sb2NhbF9udW1fYnl0ZV9zbGljZShhKQogICAgZnJhbWVfZGlnIC0xCiAgICBhcHBfcGFyYW1zX2dldCBBcHBMb2NhbE51bUJ5dGVTbGljZQogICAgcG9wCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6MTgyCiAgICAvLyByZXR1cm4gbG9jYWxfbnVtX2J5dGVfc2xpY2UKICAgIHJldHN1YgoKCi8vIHRlc3RzLmFydGlmYWN0cy5TdGF0ZU9wcy5jb250cmFjdC5TdGF0ZUFwcFBhcmFtc0NvbnRyYWN0LnZlcmlmeV9hcHBfcGFyYW1zX2dldF9leHRyYV9wcm9ncmFtX3BhZ2VzKGE6IHVpbnQ2NCkgLT4gdWludDY0Ogp2ZXJpZnlfYXBwX3BhcmFtc19nZXRfZXh0cmFfcHJvZ3JhbV9wYWdlczoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weToxODQtMTg1CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gZGVmIHZlcmlmeV9hcHBfcGFyYW1zX2dldF9leHRyYV9wcm9ncmFtX3BhZ2VzKHNlbGYsIGE6IEFwcGxpY2F0aW9uKSAtPiBVSW50NjQ6CiAgICBwcm90byAxIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weToxODYKICAgIC8vIGV4dHJhX3Byb2dyYW1fcGFnZXMsIF92YWwgPSBvcC5BcHBQYXJhbXNHZXQuYXBwX2V4dHJhX3Byb2dyYW1fcGFnZXMoYSkKICAgIGZyYW1lX2RpZyAtMQogICAgYXBwX3BhcmFtc19nZXQgQXBwRXh0cmFQcm9ncmFtUGFnZXMKICAgIHBvcAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjE4NwogICAgLy8gcmV0dXJuIGV4dHJhX3Byb2dyYW1fcGFnZXMKICAgIHJldHN1YgoKCi8vIHRlc3RzLmFydGlmYWN0cy5TdGF0ZU9wcy5jb250cmFjdC5TdGF0ZUFwcFBhcmFtc0NvbnRyYWN0LnZlcmlmeV9hcHBfcGFyYW1zX2dldF9jcmVhdG9yKGE6IHVpbnQ2NCkgLT4gYnl0ZXM6CnZlcmlmeV9hcHBfcGFyYW1zX2dldF9jcmVhdG9yOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjE4OS0xOTAKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBkZWYgdmVyaWZ5X2FwcF9wYXJhbXNfZ2V0X2NyZWF0b3Ioc2VsZiwgYTogQXBwbGljYXRpb24pIC0+IEJ5dGVzOgogICAgcHJvdG8gMSAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6MTkxCiAgICAvLyBjcmVhdG9yLCBfdmFsID0gb3AuQXBwUGFyYW1zR2V0LmFwcF9jcmVhdG9yKGEpCiAgICBmcmFtZV9kaWcgLTEKICAgIGFwcF9wYXJhbXNfZ2V0IEFwcENyZWF0b3IKICAgIHBvcAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjE5MgogICAgLy8gcmV0dXJuIGNyZWF0b3IuYnl0ZXMKICAgIHJldHN1YgoKCi8vIHRlc3RzLmFydGlmYWN0cy5TdGF0ZU9wcy5jb250cmFjdC5TdGF0ZUFwcFBhcmFtc0NvbnRyYWN0LnZlcmlmeV9hcHBfcGFyYW1zX2dldF9hZGRyZXNzKGE6IHVpbnQ2NCkgLT4gYnl0ZXM6CnZlcmlmeV9hcHBfcGFyYW1zX2dldF9hZGRyZXNzOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjE5NC0xOTUKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBkZWYgdmVyaWZ5X2FwcF9wYXJhbXNfZ2V0X2FkZHJlc3Moc2VsZiwgYTogQXBwbGljYXRpb24pIC0+IEJ5dGVzOgogICAgcHJvdG8gMSAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6MTk2CiAgICAvLyBhZGRyZXNzLCBfdmFsID0gb3AuQXBwUGFyYW1zR2V0LmFwcF9hZGRyZXNzKGEpCiAgICBmcmFtZV9kaWcgLTEKICAgIGFwcF9wYXJhbXNfZ2V0IEFwcEFkZHJlc3MKICAgIHBvcAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjE5NwogICAgLy8gcmV0dXJuIGFkZHJlc3MuYnl0ZXMKICAgIHJldHN1Ygo=", - "clear": "I3ByYWdtYSB2ZXJzaW9uIDEwCgp0ZXN0cy5hcnRpZmFjdHMuU3RhdGVPcHMuY29udHJhY3QuU3RhdGVBcHBQYXJhbXNDb250cmFjdC5jbGVhcl9zdGF0ZV9wcm9ncmFtOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjE1MwogICAgLy8gY2xhc3MgU3RhdGVBcHBQYXJhbXNDb250cmFjdChBUkM0Q29udHJhY3QpOgogICAgaW50IDEKICAgIHJldHVybgo=" + "approval": "I3ByYWdtYSB2ZXJzaW9uIDEwCgp0ZXN0cy5hcnRpZmFjdHMuU3RhdGVPcHMuY29udHJhY3QuU3RhdGVBcHBQYXJhbXNDb250cmFjdC5hcHByb3ZhbF9wcm9ncmFtOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjIzOAogICAgLy8gY2xhc3MgU3RhdGVBcHBQYXJhbXNDb250cmFjdChBUkM0Q29udHJhY3QpOgogICAgdHhuIE51bUFwcEFyZ3MKICAgIGJ6IG1haW5fYmFyZV9yb3V0aW5nQDEzCiAgICBtZXRob2QgInZlcmlmeV9hcHBfcGFyYW1zX2dldF9hcHByb3ZhbF9wcm9ncmFtKGFwcGxpY2F0aW9uKWJ5dGVbXSIKICAgIG1ldGhvZCAidmVyaWZ5X2FwcF9wYXJhbXNfZ2V0X2NsZWFyX3N0YXRlX3Byb2dyYW0oYXBwbGljYXRpb24pYnl0ZVtdIgogICAgbWV0aG9kICJ2ZXJpZnlfYXBwX3BhcmFtc19nZXRfZ2xvYmFsX251bV91aW50KGFwcGxpY2F0aW9uKXVpbnQ2NCIKICAgIG1ldGhvZCAidmVyaWZ5X2FwcF9wYXJhbXNfZ2V0X2dsb2JhbF9udW1fYnl0ZV9zbGljZShhcHBsaWNhdGlvbil1aW50NjQiCiAgICBtZXRob2QgInZlcmlmeV9hcHBfcGFyYW1zX2dldF9sb2NhbF9udW1fdWludChhcHBsaWNhdGlvbil1aW50NjQiCiAgICBtZXRob2QgInZlcmlmeV9hcHBfcGFyYW1zX2dldF9sb2NhbF9udW1fYnl0ZV9zbGljZShhcHBsaWNhdGlvbil1aW50NjQiCiAgICBtZXRob2QgInZlcmlmeV9hcHBfcGFyYW1zX2dldF9leHRyYV9wcm9ncmFtX3BhZ2VzKGFwcGxpY2F0aW9uKXVpbnQ2NCIKICAgIG1ldGhvZCAidmVyaWZ5X2FwcF9wYXJhbXNfZ2V0X2NyZWF0b3IoYXBwbGljYXRpb24pYWRkcmVzcyIKICAgIG1ldGhvZCAidmVyaWZ5X2FwcF9wYXJhbXNfZ2V0X2FkZHJlc3MoYXBwbGljYXRpb24pYWRkcmVzcyIKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDAKICAgIG1hdGNoIG1haW5fdmVyaWZ5X2FwcF9wYXJhbXNfZ2V0X2FwcHJvdmFsX3Byb2dyYW1fcm91dGVAMiBtYWluX3ZlcmlmeV9hcHBfcGFyYW1zX2dldF9jbGVhcl9zdGF0ZV9wcm9ncmFtX3JvdXRlQDMgbWFpbl92ZXJpZnlfYXBwX3BhcmFtc19nZXRfZ2xvYmFsX251bV91aW50X3JvdXRlQDQgbWFpbl92ZXJpZnlfYXBwX3BhcmFtc19nZXRfZ2xvYmFsX251bV9ieXRlX3NsaWNlX3JvdXRlQDUgbWFpbl92ZXJpZnlfYXBwX3BhcmFtc19nZXRfbG9jYWxfbnVtX3VpbnRfcm91dGVANiBtYWluX3ZlcmlmeV9hcHBfcGFyYW1zX2dldF9sb2NhbF9udW1fYnl0ZV9zbGljZV9yb3V0ZUA3IG1haW5fdmVyaWZ5X2FwcF9wYXJhbXNfZ2V0X2V4dHJhX3Byb2dyYW1fcGFnZXNfcm91dGVAOCBtYWluX3ZlcmlmeV9hcHBfcGFyYW1zX2dldF9jcmVhdG9yX3JvdXRlQDkgbWFpbl92ZXJpZnlfYXBwX3BhcmFtc19nZXRfYWRkcmVzc19yb3V0ZUAxMAogICAgZXJyIC8vIHJlamVjdCB0cmFuc2FjdGlvbgoKbWFpbl92ZXJpZnlfYXBwX3BhcmFtc19nZXRfYXBwcm92YWxfcHJvZ3JhbV9yb3V0ZUAyOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjI0MAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBpcyBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weToyMzgKICAgIC8vIGNsYXNzIFN0YXRlQXBwUGFyYW1zQ29udHJhY3QoQVJDNENvbnRyYWN0KToKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGJ0b2kKICAgIHR4bmFzIEFwcGxpY2F0aW9ucwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjI0MAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X2FwcF9wYXJhbXNfZ2V0X2FwcHJvdmFsX3Byb2dyYW0KICAgIGR1cAogICAgbGVuCiAgICBpdG9iCiAgICBleHRyYWN0IDYgMgogICAgc3dhcAogICAgY29uY2F0CiAgICBieXRlIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnQgMQogICAgcmV0dXJuCgptYWluX3ZlcmlmeV9hcHBfcGFyYW1zX2dldF9jbGVhcl9zdGF0ZV9wcm9ncmFtX3JvdXRlQDM6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6MjQ4CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGlzIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjIzOAogICAgLy8gY2xhc3MgU3RhdGVBcHBQYXJhbXNDb250cmFjdChBUkM0Q29udHJhY3QpOgogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgYnRvaQogICAgdHhuYXMgQXBwbGljYXRpb25zCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6MjQ4CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfYXBwX3BhcmFtc19nZXRfY2xlYXJfc3RhdGVfcHJvZ3JhbQogICAgZHVwCiAgICBsZW4KICAgIGl0b2IKICAgIGV4dHJhY3QgNiAyCiAgICBzd2FwCiAgICBjb25jYXQKICAgIGJ5dGUgMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludCAxCiAgICByZXR1cm4KCm1haW5fdmVyaWZ5X2FwcF9wYXJhbXNfZ2V0X2dsb2JhbF9udW1fdWludF9yb3V0ZUA0OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjI1NgogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBpcyBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weToyMzgKICAgIC8vIGNsYXNzIFN0YXRlQXBwUGFyYW1zQ29udHJhY3QoQVJDNENvbnRyYWN0KToKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGJ0b2kKICAgIHR4bmFzIEFwcGxpY2F0aW9ucwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjI1NgogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X2FwcF9wYXJhbXNfZ2V0X2dsb2JhbF9udW1fdWludAogICAgaXRvYgogICAgYnl0ZSAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50IDEKICAgIHJldHVybgoKbWFpbl92ZXJpZnlfYXBwX3BhcmFtc19nZXRfZ2xvYmFsX251bV9ieXRlX3NsaWNlX3JvdXRlQDU6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6MjY0CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGlzIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjIzOAogICAgLy8gY2xhc3MgU3RhdGVBcHBQYXJhbXNDb250cmFjdChBUkM0Q29udHJhY3QpOgogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgYnRvaQogICAgdHhuYXMgQXBwbGljYXRpb25zCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6MjY0CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfYXBwX3BhcmFtc19nZXRfZ2xvYmFsX251bV9ieXRlX3NsaWNlCiAgICBpdG9iCiAgICBieXRlIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnQgMQogICAgcmV0dXJuCgptYWluX3ZlcmlmeV9hcHBfcGFyYW1zX2dldF9sb2NhbF9udW1fdWludF9yb3V0ZUA2OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjI3MgogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBpcyBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weToyMzgKICAgIC8vIGNsYXNzIFN0YXRlQXBwUGFyYW1zQ29udHJhY3QoQVJDNENvbnRyYWN0KToKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGJ0b2kKICAgIHR4bmFzIEFwcGxpY2F0aW9ucwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjI3MgogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X2FwcF9wYXJhbXNfZ2V0X2xvY2FsX251bV91aW50CiAgICBpdG9iCiAgICBieXRlIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnQgMQogICAgcmV0dXJuCgptYWluX3ZlcmlmeV9hcHBfcGFyYW1zX2dldF9sb2NhbF9udW1fYnl0ZV9zbGljZV9yb3V0ZUA3OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjI4MAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBpcyBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weToyMzgKICAgIC8vIGNsYXNzIFN0YXRlQXBwUGFyYW1zQ29udHJhY3QoQVJDNENvbnRyYWN0KToKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGJ0b2kKICAgIHR4bmFzIEFwcGxpY2F0aW9ucwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjI4MAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X2FwcF9wYXJhbXNfZ2V0X2xvY2FsX251bV9ieXRlX3NsaWNlCiAgICBpdG9iCiAgICBieXRlIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnQgMQogICAgcmV0dXJuCgptYWluX3ZlcmlmeV9hcHBfcGFyYW1zX2dldF9leHRyYV9wcm9ncmFtX3BhZ2VzX3JvdXRlQDg6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6Mjg4CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGlzIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjIzOAogICAgLy8gY2xhc3MgU3RhdGVBcHBQYXJhbXNDb250cmFjdChBUkM0Q29udHJhY3QpOgogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgYnRvaQogICAgdHhuYXMgQXBwbGljYXRpb25zCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6Mjg4CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfYXBwX3BhcmFtc19nZXRfZXh0cmFfcHJvZ3JhbV9wYWdlcwogICAgaXRvYgogICAgYnl0ZSAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50IDEKICAgIHJldHVybgoKbWFpbl92ZXJpZnlfYXBwX3BhcmFtc19nZXRfY3JlYXRvcl9yb3V0ZUA5OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjI5NgogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBpcyBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weToyMzgKICAgIC8vIGNsYXNzIFN0YXRlQXBwUGFyYW1zQ29udHJhY3QoQVJDNENvbnRyYWN0KToKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGJ0b2kKICAgIHR4bmFzIEFwcGxpY2F0aW9ucwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjI5NgogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X2FwcF9wYXJhbXNfZ2V0X2NyZWF0b3IKICAgIGJ5dGUgMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludCAxCiAgICByZXR1cm4KCm1haW5fdmVyaWZ5X2FwcF9wYXJhbXNfZ2V0X2FkZHJlc3Nfcm91dGVAMTA6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6MzA0CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGlzIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjIzOAogICAgLy8gY2xhc3MgU3RhdGVBcHBQYXJhbXNDb250cmFjdChBUkM0Q29udHJhY3QpOgogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgYnRvaQogICAgdHhuYXMgQXBwbGljYXRpb25zCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6MzA0CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfYXBwX3BhcmFtc19nZXRfYWRkcmVzcwogICAgYnl0ZSAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50IDEKICAgIHJldHVybgoKbWFpbl9iYXJlX3JvdXRpbmdAMTM6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6MjM4CiAgICAvLyBjbGFzcyBTdGF0ZUFwcFBhcmFtc0NvbnRyYWN0KEFSQzRDb250cmFjdCk6CiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gcmVqZWN0IHRyYW5zYWN0aW9uCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgIQogICAgYXNzZXJ0IC8vIGlzIGNyZWF0aW5nCiAgICBpbnQgMQogICAgcmV0dXJuCgoKLy8gdGVzdHMuYXJ0aWZhY3RzLlN0YXRlT3BzLmNvbnRyYWN0LlN0YXRlQXBwUGFyYW1zQ29udHJhY3QudmVyaWZ5X2FwcF9wYXJhbXNfZ2V0X2FwcHJvdmFsX3Byb2dyYW0oYTogdWludDY0KSAtPiBieXRlczoKdmVyaWZ5X2FwcF9wYXJhbXNfZ2V0X2FwcHJvdmFsX3Byb2dyYW06CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6MjQwLTI0MQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIGRlZiB2ZXJpZnlfYXBwX3BhcmFtc19nZXRfYXBwcm92YWxfcHJvZ3JhbShzZWxmLCBhOiBBcHBsaWNhdGlvbikgLT4gQnl0ZXM6CiAgICBwcm90byAxIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weToyNDIKICAgIC8vIHZhbHVlLCBleGlzdHMgPSBvcC5BcHBQYXJhbXNHZXQuYXBwX2FwcHJvdmFsX3Byb2dyYW0oYSkKICAgIGZyYW1lX2RpZyAtMQogICAgYXBwX3BhcmFtc19nZXQgQXBwQXBwcm92YWxQcm9ncmFtCiAgICBzd2FwCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6MjQzCiAgICAvLyB2YWx1ZV9pbmRleCwgZXhpc3RzX2luZGV4ID0gb3AuQXBwUGFyYW1zR2V0LmFwcF9hcHByb3ZhbF9wcm9ncmFtKF9nZXRfMXN0X3JlZl9pbmRleCgpKQogICAgY2FsbHN1YiBfZ2V0XzFzdF9yZWZfaW5kZXgKICAgIGFwcF9wYXJhbXNfZ2V0IEFwcEFwcHJvdmFsUHJvZ3JhbQogICAgY292ZXIgMgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjI0NAogICAgLy8gYXNzZXJ0IHZhbHVlID09IHZhbHVlX2luZGV4LCAiZXhwZWN0ZWQgdmFsdWUgYnkgaW5kZXggdG8gbWF0Y2giCiAgICBkaWcgMQogICAgPT0KICAgIGFzc2VydCAvLyBleHBlY3RlZCB2YWx1ZSBieSBpbmRleCB0byBtYXRjaAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjI0NQogICAgLy8gYXNzZXJ0IGV4aXN0cyA9PSBleGlzdHNfaW5kZXgsICJleHBlY3RlZCBleGlzdHMgYnkgaW5kZXggdG8gbWF0Y2giCiAgICBjb3ZlciAyCiAgICA9PQogICAgYXNzZXJ0IC8vIGV4cGVjdGVkIGV4aXN0cyBieSBpbmRleCB0byBtYXRjaAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjI0NgogICAgLy8gcmV0dXJuIHZhbHVlCiAgICByZXRzdWIKCgovLyB0ZXN0cy5hcnRpZmFjdHMuU3RhdGVPcHMuY29udHJhY3QuX2dldF8xc3RfcmVmX2luZGV4KCkgLT4gdWludDY0OgpfZ2V0XzFzdF9yZWZfaW5kZXg6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6MTktMjAKICAgIC8vIEBzdWJyb3V0aW5lCiAgICAvLyBkZWYgX2dldF8xc3RfcmVmX2luZGV4KCkgLT4gVUludDY0OgogICAgcHJvdG8gMCAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6MjEKICAgIC8vIHJldHVybiBvcC5idG9pKFR4bi5hcHBsaWNhdGlvbl9hcmdzKDEpKQogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgYnRvaQogICAgcmV0c3ViCgoKLy8gdGVzdHMuYXJ0aWZhY3RzLlN0YXRlT3BzLmNvbnRyYWN0LlN0YXRlQXBwUGFyYW1zQ29udHJhY3QudmVyaWZ5X2FwcF9wYXJhbXNfZ2V0X2NsZWFyX3N0YXRlX3Byb2dyYW0oYTogdWludDY0KSAtPiBieXRlczoKdmVyaWZ5X2FwcF9wYXJhbXNfZ2V0X2NsZWFyX3N0YXRlX3Byb2dyYW06CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6MjQ4LTI0OQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIGRlZiB2ZXJpZnlfYXBwX3BhcmFtc19nZXRfY2xlYXJfc3RhdGVfcHJvZ3JhbShzZWxmLCBhOiBBcHBsaWNhdGlvbikgLT4gQnl0ZXM6CiAgICBwcm90byAxIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weToyNTAKICAgIC8vIHZhbHVlLCBleGlzdHMgPSBvcC5BcHBQYXJhbXNHZXQuYXBwX2NsZWFyX3N0YXRlX3Byb2dyYW0oYSkKICAgIGZyYW1lX2RpZyAtMQogICAgYXBwX3BhcmFtc19nZXQgQXBwQ2xlYXJTdGF0ZVByb2dyYW0KICAgIHN3YXAKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weToyNTEKICAgIC8vIHZhbHVlX2luZGV4LCBleGlzdHNfaW5kZXggPSBvcC5BcHBQYXJhbXNHZXQuYXBwX2NsZWFyX3N0YXRlX3Byb2dyYW0oX2dldF8xc3RfcmVmX2luZGV4KCkpCiAgICBjYWxsc3ViIF9nZXRfMXN0X3JlZl9pbmRleAogICAgYXBwX3BhcmFtc19nZXQgQXBwQ2xlYXJTdGF0ZVByb2dyYW0KICAgIGNvdmVyIDIKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weToyNTIKICAgIC8vIGFzc2VydCB2YWx1ZSA9PSB2YWx1ZV9pbmRleCwgImV4cGVjdGVkIHZhbHVlIGJ5IGluZGV4IHRvIG1hdGNoIgogICAgZGlnIDEKICAgID09CiAgICBhc3NlcnQgLy8gZXhwZWN0ZWQgdmFsdWUgYnkgaW5kZXggdG8gbWF0Y2gKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weToyNTMKICAgIC8vIGFzc2VydCBleGlzdHMgPT0gZXhpc3RzX2luZGV4LCAiZXhwZWN0ZWQgZXhpc3RzIGJ5IGluZGV4IHRvIG1hdGNoIgogICAgY292ZXIgMgogICAgPT0KICAgIGFzc2VydCAvLyBleHBlY3RlZCBleGlzdHMgYnkgaW5kZXggdG8gbWF0Y2gKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weToyNTQKICAgIC8vIHJldHVybiB2YWx1ZQogICAgcmV0c3ViCgoKLy8gdGVzdHMuYXJ0aWZhY3RzLlN0YXRlT3BzLmNvbnRyYWN0LlN0YXRlQXBwUGFyYW1zQ29udHJhY3QudmVyaWZ5X2FwcF9wYXJhbXNfZ2V0X2dsb2JhbF9udW1fdWludChhOiB1aW50NjQpIC0+IHVpbnQ2NDoKdmVyaWZ5X2FwcF9wYXJhbXNfZ2V0X2dsb2JhbF9udW1fdWludDoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weToyNTYtMjU3CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gZGVmIHZlcmlmeV9hcHBfcGFyYW1zX2dldF9nbG9iYWxfbnVtX3VpbnQoc2VsZiwgYTogQXBwbGljYXRpb24pIC0+IFVJbnQ2NDoKICAgIHByb3RvIDEgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjI1OAogICAgLy8gdmFsdWUsIGV4aXN0cyA9IG9wLkFwcFBhcmFtc0dldC5hcHBfZ2xvYmFsX251bV91aW50KGEpCiAgICBmcmFtZV9kaWcgLTEKICAgIGFwcF9wYXJhbXNfZ2V0IEFwcEdsb2JhbE51bVVpbnQKICAgIHN3YXAKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weToyNTkKICAgIC8vIHZhbHVlX2luZGV4LCBleGlzdHNfaW5kZXggPSBvcC5BcHBQYXJhbXNHZXQuYXBwX2dsb2JhbF9udW1fdWludChfZ2V0XzFzdF9yZWZfaW5kZXgoKSkKICAgIGNhbGxzdWIgX2dldF8xc3RfcmVmX2luZGV4CiAgICBhcHBfcGFyYW1zX2dldCBBcHBHbG9iYWxOdW1VaW50CiAgICBjb3ZlciAyCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6MjYwCiAgICAvLyBhc3NlcnQgdmFsdWUgPT0gdmFsdWVfaW5kZXgsICJleHBlY3RlZCB2YWx1ZSBieSBpbmRleCB0byBtYXRjaCIKICAgIGRpZyAxCiAgICA9PQogICAgYXNzZXJ0IC8vIGV4cGVjdGVkIHZhbHVlIGJ5IGluZGV4IHRvIG1hdGNoCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6MjYxCiAgICAvLyBhc3NlcnQgZXhpc3RzID09IGV4aXN0c19pbmRleCwgImV4cGVjdGVkIGV4aXN0cyBieSBpbmRleCB0byBtYXRjaCIKICAgIGNvdmVyIDIKICAgID09CiAgICBhc3NlcnQgLy8gZXhwZWN0ZWQgZXhpc3RzIGJ5IGluZGV4IHRvIG1hdGNoCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6MjYyCiAgICAvLyByZXR1cm4gdmFsdWUKICAgIHJldHN1YgoKCi8vIHRlc3RzLmFydGlmYWN0cy5TdGF0ZU9wcy5jb250cmFjdC5TdGF0ZUFwcFBhcmFtc0NvbnRyYWN0LnZlcmlmeV9hcHBfcGFyYW1zX2dldF9nbG9iYWxfbnVtX2J5dGVfc2xpY2UoYTogdWludDY0KSAtPiB1aW50NjQ6CnZlcmlmeV9hcHBfcGFyYW1zX2dldF9nbG9iYWxfbnVtX2J5dGVfc2xpY2U6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6MjY0LTI2NQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIGRlZiB2ZXJpZnlfYXBwX3BhcmFtc19nZXRfZ2xvYmFsX251bV9ieXRlX3NsaWNlKHNlbGYsIGE6IEFwcGxpY2F0aW9uKSAtPiBVSW50NjQ6CiAgICBwcm90byAxIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weToyNjYKICAgIC8vIHZhbHVlLCBleGlzdHMgPSBvcC5BcHBQYXJhbXNHZXQuYXBwX2dsb2JhbF9udW1fYnl0ZV9zbGljZShhKQogICAgZnJhbWVfZGlnIC0xCiAgICBhcHBfcGFyYW1zX2dldCBBcHBHbG9iYWxOdW1CeXRlU2xpY2UKICAgIHN3YXAKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weToyNjcKICAgIC8vIHZhbHVlX2luZGV4LCBleGlzdHNfaW5kZXggPSBvcC5BcHBQYXJhbXNHZXQuYXBwX2dsb2JhbF9udW1fYnl0ZV9zbGljZShfZ2V0XzFzdF9yZWZfaW5kZXgoKSkKICAgIGNhbGxzdWIgX2dldF8xc3RfcmVmX2luZGV4CiAgICBhcHBfcGFyYW1zX2dldCBBcHBHbG9iYWxOdW1CeXRlU2xpY2UKICAgIGNvdmVyIDIKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weToyNjgKICAgIC8vIGFzc2VydCB2YWx1ZSA9PSB2YWx1ZV9pbmRleCwgImV4cGVjdGVkIHZhbHVlIGJ5IGluZGV4IHRvIG1hdGNoIgogICAgZGlnIDEKICAgID09CiAgICBhc3NlcnQgLy8gZXhwZWN0ZWQgdmFsdWUgYnkgaW5kZXggdG8gbWF0Y2gKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weToyNjkKICAgIC8vIGFzc2VydCBleGlzdHMgPT0gZXhpc3RzX2luZGV4LCAiZXhwZWN0ZWQgZXhpc3RzIGJ5IGluZGV4IHRvIG1hdGNoIgogICAgY292ZXIgMgogICAgPT0KICAgIGFzc2VydCAvLyBleHBlY3RlZCBleGlzdHMgYnkgaW5kZXggdG8gbWF0Y2gKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weToyNzAKICAgIC8vIHJldHVybiB2YWx1ZQogICAgcmV0c3ViCgoKLy8gdGVzdHMuYXJ0aWZhY3RzLlN0YXRlT3BzLmNvbnRyYWN0LlN0YXRlQXBwUGFyYW1zQ29udHJhY3QudmVyaWZ5X2FwcF9wYXJhbXNfZ2V0X2xvY2FsX251bV91aW50KGE6IHVpbnQ2NCkgLT4gdWludDY0Ogp2ZXJpZnlfYXBwX3BhcmFtc19nZXRfbG9jYWxfbnVtX3VpbnQ6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6MjcyLTI3MwogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIGRlZiB2ZXJpZnlfYXBwX3BhcmFtc19nZXRfbG9jYWxfbnVtX3VpbnQoc2VsZiwgYTogQXBwbGljYXRpb24pIC0+IFVJbnQ2NDoKICAgIHByb3RvIDEgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjI3NAogICAgLy8gdmFsdWUsIGV4aXN0cyA9IG9wLkFwcFBhcmFtc0dldC5hcHBfbG9jYWxfbnVtX3VpbnQoYSkKICAgIGZyYW1lX2RpZyAtMQogICAgYXBwX3BhcmFtc19nZXQgQXBwTG9jYWxOdW1VaW50CiAgICBzd2FwCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6Mjc1CiAgICAvLyB2YWx1ZV9pbmRleCwgZXhpc3RzX2luZGV4ID0gb3AuQXBwUGFyYW1zR2V0LmFwcF9sb2NhbF9udW1fdWludChfZ2V0XzFzdF9yZWZfaW5kZXgoKSkKICAgIGNhbGxzdWIgX2dldF8xc3RfcmVmX2luZGV4CiAgICBhcHBfcGFyYW1zX2dldCBBcHBMb2NhbE51bVVpbnQKICAgIGNvdmVyIDIKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weToyNzYKICAgIC8vIGFzc2VydCB2YWx1ZSA9PSB2YWx1ZV9pbmRleCwgImV4cGVjdGVkIHZhbHVlIGJ5IGluZGV4IHRvIG1hdGNoIgogICAgZGlnIDEKICAgID09CiAgICBhc3NlcnQgLy8gZXhwZWN0ZWQgdmFsdWUgYnkgaW5kZXggdG8gbWF0Y2gKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weToyNzcKICAgIC8vIGFzc2VydCBleGlzdHMgPT0gZXhpc3RzX2luZGV4LCAiZXhwZWN0ZWQgZXhpc3RzIGJ5IGluZGV4IHRvIG1hdGNoIgogICAgY292ZXIgMgogICAgPT0KICAgIGFzc2VydCAvLyBleHBlY3RlZCBleGlzdHMgYnkgaW5kZXggdG8gbWF0Y2gKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weToyNzgKICAgIC8vIHJldHVybiB2YWx1ZQogICAgcmV0c3ViCgoKLy8gdGVzdHMuYXJ0aWZhY3RzLlN0YXRlT3BzLmNvbnRyYWN0LlN0YXRlQXBwUGFyYW1zQ29udHJhY3QudmVyaWZ5X2FwcF9wYXJhbXNfZ2V0X2xvY2FsX251bV9ieXRlX3NsaWNlKGE6IHVpbnQ2NCkgLT4gdWludDY0Ogp2ZXJpZnlfYXBwX3BhcmFtc19nZXRfbG9jYWxfbnVtX2J5dGVfc2xpY2U6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6MjgwLTI4MQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIGRlZiB2ZXJpZnlfYXBwX3BhcmFtc19nZXRfbG9jYWxfbnVtX2J5dGVfc2xpY2Uoc2VsZiwgYTogQXBwbGljYXRpb24pIC0+IFVJbnQ2NDoKICAgIHByb3RvIDEgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjI4MgogICAgLy8gdmFsdWUsIGV4aXN0cyA9IG9wLkFwcFBhcmFtc0dldC5hcHBfbG9jYWxfbnVtX2J5dGVfc2xpY2UoYSkKICAgIGZyYW1lX2RpZyAtMQogICAgYXBwX3BhcmFtc19nZXQgQXBwTG9jYWxOdW1CeXRlU2xpY2UKICAgIHN3YXAKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weToyODMKICAgIC8vIHZhbHVlX2luZGV4LCBleGlzdHNfaW5kZXggPSBvcC5BcHBQYXJhbXNHZXQuYXBwX2xvY2FsX251bV9ieXRlX3NsaWNlKF9nZXRfMXN0X3JlZl9pbmRleCgpKQogICAgY2FsbHN1YiBfZ2V0XzFzdF9yZWZfaW5kZXgKICAgIGFwcF9wYXJhbXNfZ2V0IEFwcExvY2FsTnVtQnl0ZVNsaWNlCiAgICBjb3ZlciAyCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6Mjg0CiAgICAvLyBhc3NlcnQgdmFsdWUgPT0gdmFsdWVfaW5kZXgsICJleHBlY3RlZCB2YWx1ZSBieSBpbmRleCB0byBtYXRjaCIKICAgIGRpZyAxCiAgICA9PQogICAgYXNzZXJ0IC8vIGV4cGVjdGVkIHZhbHVlIGJ5IGluZGV4IHRvIG1hdGNoCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6Mjg1CiAgICAvLyBhc3NlcnQgZXhpc3RzID09IGV4aXN0c19pbmRleCwgImV4cGVjdGVkIGV4aXN0cyBieSBpbmRleCB0byBtYXRjaCIKICAgIGNvdmVyIDIKICAgID09CiAgICBhc3NlcnQgLy8gZXhwZWN0ZWQgZXhpc3RzIGJ5IGluZGV4IHRvIG1hdGNoCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6Mjg2CiAgICAvLyByZXR1cm4gdmFsdWUKICAgIHJldHN1YgoKCi8vIHRlc3RzLmFydGlmYWN0cy5TdGF0ZU9wcy5jb250cmFjdC5TdGF0ZUFwcFBhcmFtc0NvbnRyYWN0LnZlcmlmeV9hcHBfcGFyYW1zX2dldF9leHRyYV9wcm9ncmFtX3BhZ2VzKGE6IHVpbnQ2NCkgLT4gdWludDY0Ogp2ZXJpZnlfYXBwX3BhcmFtc19nZXRfZXh0cmFfcHJvZ3JhbV9wYWdlczoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weToyODgtMjg5CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gZGVmIHZlcmlmeV9hcHBfcGFyYW1zX2dldF9leHRyYV9wcm9ncmFtX3BhZ2VzKHNlbGYsIGE6IEFwcGxpY2F0aW9uKSAtPiBVSW50NjQ6CiAgICBwcm90byAxIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weToyOTAKICAgIC8vIHZhbHVlLCBleGlzdHMgPSBvcC5BcHBQYXJhbXNHZXQuYXBwX2V4dHJhX3Byb2dyYW1fcGFnZXMoYSkKICAgIGZyYW1lX2RpZyAtMQogICAgYXBwX3BhcmFtc19nZXQgQXBwRXh0cmFQcm9ncmFtUGFnZXMKICAgIHN3YXAKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weToyOTEKICAgIC8vIHZhbHVlX2luZGV4LCBleGlzdHNfaW5kZXggPSBvcC5BcHBQYXJhbXNHZXQuYXBwX2V4dHJhX3Byb2dyYW1fcGFnZXMoX2dldF8xc3RfcmVmX2luZGV4KCkpCiAgICBjYWxsc3ViIF9nZXRfMXN0X3JlZl9pbmRleAogICAgYXBwX3BhcmFtc19nZXQgQXBwRXh0cmFQcm9ncmFtUGFnZXMKICAgIGNvdmVyIDIKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weToyOTIKICAgIC8vIGFzc2VydCB2YWx1ZSA9PSB2YWx1ZV9pbmRleCwgImV4cGVjdGVkIHZhbHVlIGJ5IGluZGV4IHRvIG1hdGNoIgogICAgZGlnIDEKICAgID09CiAgICBhc3NlcnQgLy8gZXhwZWN0ZWQgdmFsdWUgYnkgaW5kZXggdG8gbWF0Y2gKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weToyOTMKICAgIC8vIGFzc2VydCBleGlzdHMgPT0gZXhpc3RzX2luZGV4LCAiZXhwZWN0ZWQgZXhpc3RzIGJ5IGluZGV4IHRvIG1hdGNoIgogICAgY292ZXIgMgogICAgPT0KICAgIGFzc2VydCAvLyBleHBlY3RlZCBleGlzdHMgYnkgaW5kZXggdG8gbWF0Y2gKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weToyOTQKICAgIC8vIHJldHVybiB2YWx1ZQogICAgcmV0c3ViCgoKLy8gdGVzdHMuYXJ0aWZhY3RzLlN0YXRlT3BzLmNvbnRyYWN0LlN0YXRlQXBwUGFyYW1zQ29udHJhY3QudmVyaWZ5X2FwcF9wYXJhbXNfZ2V0X2NyZWF0b3IoYTogdWludDY0KSAtPiBieXRlczoKdmVyaWZ5X2FwcF9wYXJhbXNfZ2V0X2NyZWF0b3I6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6Mjk2LTI5NwogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIGRlZiB2ZXJpZnlfYXBwX3BhcmFtc19nZXRfY3JlYXRvcihzZWxmLCBhOiBBcHBsaWNhdGlvbikgLT4gYXJjNC5BZGRyZXNzOgogICAgcHJvdG8gMSAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6Mjk4CiAgICAvLyB2YWx1ZSwgZXhpc3RzID0gb3AuQXBwUGFyYW1zR2V0LmFwcF9jcmVhdG9yKGEpCiAgICBmcmFtZV9kaWcgLTEKICAgIGFwcF9wYXJhbXNfZ2V0IEFwcENyZWF0b3IKICAgIHN3YXAKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weToyOTkKICAgIC8vIHZhbHVlX2luZGV4LCBleGlzdHNfaW5kZXggPSBvcC5BcHBQYXJhbXNHZXQuYXBwX2NyZWF0b3IoX2dldF8xc3RfcmVmX2luZGV4KCkpCiAgICBjYWxsc3ViIF9nZXRfMXN0X3JlZl9pbmRleAogICAgYXBwX3BhcmFtc19nZXQgQXBwQ3JlYXRvcgogICAgY292ZXIgMgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjMwMAogICAgLy8gYXNzZXJ0IHZhbHVlID09IHZhbHVlX2luZGV4LCAiZXhwZWN0ZWQgdmFsdWUgYnkgaW5kZXggdG8gbWF0Y2giCiAgICBkaWcgMQogICAgPT0KICAgIGFzc2VydCAvLyBleHBlY3RlZCB2YWx1ZSBieSBpbmRleCB0byBtYXRjaAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjMwMQogICAgLy8gYXNzZXJ0IGV4aXN0cyA9PSBleGlzdHNfaW5kZXgsICJleHBlY3RlZCBleGlzdHMgYnkgaW5kZXggdG8gbWF0Y2giCiAgICBjb3ZlciAyCiAgICA9PQogICAgYXNzZXJ0IC8vIGV4cGVjdGVkIGV4aXN0cyBieSBpbmRleCB0byBtYXRjaAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjMwMgogICAgLy8gcmV0dXJuIGFyYzQuQWRkcmVzcyh2YWx1ZSkKICAgIHJldHN1YgoKCi8vIHRlc3RzLmFydGlmYWN0cy5TdGF0ZU9wcy5jb250cmFjdC5TdGF0ZUFwcFBhcmFtc0NvbnRyYWN0LnZlcmlmeV9hcHBfcGFyYW1zX2dldF9hZGRyZXNzKGE6IHVpbnQ2NCkgLT4gYnl0ZXM6CnZlcmlmeV9hcHBfcGFyYW1zX2dldF9hZGRyZXNzOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjMwNC0zMDUKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBkZWYgdmVyaWZ5X2FwcF9wYXJhbXNfZ2V0X2FkZHJlc3Moc2VsZiwgYTogQXBwbGljYXRpb24pIC0+IGFyYzQuQWRkcmVzczoKICAgIHByb3RvIDEgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjMwNgogICAgLy8gdmFsdWUsIGV4aXN0cyA9IG9wLkFwcFBhcmFtc0dldC5hcHBfYWRkcmVzcyhhKQogICAgZnJhbWVfZGlnIC0xCiAgICBhcHBfcGFyYW1zX2dldCBBcHBBZGRyZXNzCiAgICBzd2FwCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6MzA3CiAgICAvLyB2YWx1ZV9pbmRleCwgZXhpc3RzX2luZGV4ID0gb3AuQXBwUGFyYW1zR2V0LmFwcF9hZGRyZXNzKF9nZXRfMXN0X3JlZl9pbmRleCgpKQogICAgY2FsbHN1YiBfZ2V0XzFzdF9yZWZfaW5kZXgKICAgIGFwcF9wYXJhbXNfZ2V0IEFwcEFkZHJlc3MKICAgIGNvdmVyIDIKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTozMDgKICAgIC8vIGFzc2VydCB2YWx1ZSA9PSB2YWx1ZV9pbmRleCwgImV4cGVjdGVkIHZhbHVlIGJ5IGluZGV4IHRvIG1hdGNoIgogICAgZGlnIDEKICAgID09CiAgICBhc3NlcnQgLy8gZXhwZWN0ZWQgdmFsdWUgYnkgaW5kZXggdG8gbWF0Y2gKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTozMDkKICAgIC8vIGFzc2VydCBleGlzdHMgPT0gZXhpc3RzX2luZGV4LCAiZXhwZWN0ZWQgZXhpc3RzIGJ5IGluZGV4IHRvIG1hdGNoIgogICAgY292ZXIgMgogICAgPT0KICAgIGFzc2VydCAvLyBleHBlY3RlZCBleGlzdHMgYnkgaW5kZXggdG8gbWF0Y2gKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTozMTAKICAgIC8vIHJldHVybiBhcmM0LkFkZHJlc3ModmFsdWUpCiAgICByZXRzdWIK", + "clear": "I3ByYWdtYSB2ZXJzaW9uIDEwCgp0ZXN0cy5hcnRpZmFjdHMuU3RhdGVPcHMuY29udHJhY3QuU3RhdGVBcHBQYXJhbXNDb250cmFjdC5jbGVhcl9zdGF0ZV9wcm9ncmFtOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjIzOAogICAgLy8gY2xhc3MgU3RhdGVBcHBQYXJhbXNDb250cmFjdChBUkM0Q29udHJhY3QpOgogICAgaW50IDEKICAgIHJldHVybgo=" }, "state": { "global": { @@ -174,7 +174,7 @@ ], "readonly": false, "returns": { - "type": "byte[]" + "type": "address" } }, { @@ -187,7 +187,7 @@ ], "readonly": false, "returns": { - "type": "byte[]" + "type": "address" } } ], diff --git a/tests/artifacts/StateOps/data/StateAppParamsContract.clear.teal b/tests/artifacts/StateOps/data/StateAppParamsContract.clear.teal index c021a77..fc671b0 100644 --- a/tests/artifacts/StateOps/data/StateAppParamsContract.clear.teal +++ b/tests/artifacts/StateOps/data/StateAppParamsContract.clear.teal @@ -1,7 +1,7 @@ #pragma version 10 tests.artifacts.StateOps.contract.StateAppParamsContract.clear_state_program: - // tests/artifacts/StateOps/contract.py:153 + // tests/artifacts/StateOps/contract.py:238 // class StateAppParamsContract(ARC4Contract): int 1 return diff --git a/tests/artifacts/StateOps/data/StateAssetHoldingContract.approval.teal b/tests/artifacts/StateOps/data/StateAssetHoldingContract.approval.teal index 429e110..a611d36 100644 --- a/tests/artifacts/StateOps/data/StateAssetHoldingContract.approval.teal +++ b/tests/artifacts/StateOps/data/StateAssetHoldingContract.approval.teal @@ -1,7 +1,7 @@ #pragma version 10 tests.artifacts.StateOps.contract.StateAssetHoldingContract.approval_program: - // tests/artifacts/StateOps/contract.py:79 + // tests/artifacts/StateOps/contract.py:128 // class StateAssetHoldingContract(ARC4Contract): txn NumAppArgs bz main_bare_routing@6 @@ -12,14 +12,14 @@ tests.artifacts.StateOps.contract.StateAssetHoldingContract.approval_program: err // reject transaction main_verify_asset_holding_get_route@2: - // tests/artifacts/StateOps/contract.py:80 + // tests/artifacts/StateOps/contract.py:129 // @arc4.abimethod() txn OnCompletion ! assert // OnCompletion is NoOp txn ApplicationID assert // is not creating - // tests/artifacts/StateOps/contract.py:79 + // tests/artifacts/StateOps/contract.py:128 // class StateAssetHoldingContract(ARC4Contract): txna ApplicationArgs 1 btoi @@ -27,7 +27,7 @@ main_verify_asset_holding_get_route@2: txna ApplicationArgs 2 btoi txnas Assets - // tests/artifacts/StateOps/contract.py:80 + // tests/artifacts/StateOps/contract.py:129 // @arc4.abimethod() callsub verify_asset_holding_get itob @@ -39,14 +39,14 @@ main_verify_asset_holding_get_route@2: return main_verify_asset_frozen_get_route@3: - // tests/artifacts/StateOps/contract.py:85 + // tests/artifacts/StateOps/contract.py:134 // @arc4.abimethod() txn OnCompletion ! assert // OnCompletion is NoOp txn ApplicationID assert // is not creating - // tests/artifacts/StateOps/contract.py:79 + // tests/artifacts/StateOps/contract.py:128 // class StateAssetHoldingContract(ARC4Contract): txna ApplicationArgs 1 btoi @@ -54,7 +54,7 @@ main_verify_asset_frozen_get_route@3: txna ApplicationArgs 2 btoi txnas Assets - // tests/artifacts/StateOps/contract.py:85 + // tests/artifacts/StateOps/contract.py:134 // @arc4.abimethod() callsub verify_asset_frozen_get byte 0x00 @@ -69,7 +69,7 @@ main_verify_asset_frozen_get_route@3: return main_bare_routing@6: - // tests/artifacts/StateOps/contract.py:79 + // tests/artifacts/StateOps/contract.py:128 // class StateAssetHoldingContract(ARC4Contract): txn OnCompletion ! @@ -83,33 +83,33 @@ main_bare_routing@6: // tests.artifacts.StateOps.contract.StateAssetHoldingContract.verify_asset_holding_get(a: bytes, b: uint64) -> uint64: verify_asset_holding_get: - // tests/artifacts/StateOps/contract.py:80-81 + // tests/artifacts/StateOps/contract.py:129-130 // @arc4.abimethod() // def verify_asset_holding_get(self, a: Account, b: Asset) -> UInt64: proto 2 1 - // tests/artifacts/StateOps/contract.py:82 + // tests/artifacts/StateOps/contract.py:131 // balance, _val = op.AssetHoldingGet.asset_balance(a, b) frame_dig -2 frame_dig -1 asset_holding_get AssetBalance pop - // tests/artifacts/StateOps/contract.py:83 + // tests/artifacts/StateOps/contract.py:132 // return balance retsub // tests.artifacts.StateOps.contract.StateAssetHoldingContract.verify_asset_frozen_get(a: bytes, b: uint64) -> uint64: verify_asset_frozen_get: - // tests/artifacts/StateOps/contract.py:85-86 + // tests/artifacts/StateOps/contract.py:134-135 // @arc4.abimethod() // def verify_asset_frozen_get(self, a: Account, b: Asset) -> bool: proto 2 1 - // tests/artifacts/StateOps/contract.py:87 + // tests/artifacts/StateOps/contract.py:136 // frozen, _val = op.AssetHoldingGet.asset_frozen(a, b) frame_dig -2 frame_dig -1 asset_holding_get AssetFrozen pop - // tests/artifacts/StateOps/contract.py:88 + // tests/artifacts/StateOps/contract.py:137 // return frozen retsub diff --git a/tests/artifacts/StateOps/data/StateAssetHoldingContract.arc32.json b/tests/artifacts/StateOps/data/StateAssetHoldingContract.arc32.json index 3d4b39d..c6be8c8 100644 --- a/tests/artifacts/StateOps/data/StateAssetHoldingContract.arc32.json +++ b/tests/artifacts/StateOps/data/StateAssetHoldingContract.arc32.json @@ -12,8 +12,8 @@ } }, "source": { - "approval": "I3ByYWdtYSB2ZXJzaW9uIDEwCgp0ZXN0cy5hcnRpZmFjdHMuU3RhdGVPcHMuY29udHJhY3QuU3RhdGVBc3NldEhvbGRpbmdDb250cmFjdC5hcHByb3ZhbF9wcm9ncmFtOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5Ojc5CiAgICAvLyBjbGFzcyBTdGF0ZUFzc2V0SG9sZGluZ0NvbnRyYWN0KEFSQzRDb250cmFjdCk6CiAgICB0eG4gTnVtQXBwQXJncwogICAgYnogbWFpbl9iYXJlX3JvdXRpbmdANgogICAgbWV0aG9kICJ2ZXJpZnlfYXNzZXRfaG9sZGluZ19nZXQoYWNjb3VudCxhc3NldCl1aW50NjQiCiAgICBtZXRob2QgInZlcmlmeV9hc3NldF9mcm96ZW5fZ2V0KGFjY291bnQsYXNzZXQpYm9vbCIKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDAKICAgIG1hdGNoIG1haW5fdmVyaWZ5X2Fzc2V0X2hvbGRpbmdfZ2V0X3JvdXRlQDIgbWFpbl92ZXJpZnlfYXNzZXRfZnJvemVuX2dldF9yb3V0ZUAzCiAgICBlcnIgLy8gcmVqZWN0IHRyYW5zYWN0aW9uCgptYWluX3ZlcmlmeV9hc3NldF9ob2xkaW5nX2dldF9yb3V0ZUAyOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjgwCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGlzIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5Ojc5CiAgICAvLyBjbGFzcyBTdGF0ZUFzc2V0SG9sZGluZ0NvbnRyYWN0KEFSQzRDb250cmFjdCk6CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBidG9pCiAgICB0eG5hcyBBY2NvdW50cwogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMgogICAgYnRvaQogICAgdHhuYXMgQXNzZXRzCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6ODAKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV9hc3NldF9ob2xkaW5nX2dldAogICAgaXRvYgogICAgYnl0ZSAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50IDEKICAgIHJldHVybgoKbWFpbl92ZXJpZnlfYXNzZXRfZnJvemVuX2dldF9yb3V0ZUAzOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5Ojg1CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGlzIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5Ojc5CiAgICAvLyBjbGFzcyBTdGF0ZUFzc2V0SG9sZGluZ0NvbnRyYWN0KEFSQzRDb250cmFjdCk6CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBidG9pCiAgICB0eG5hcyBBY2NvdW50cwogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMgogICAgYnRvaQogICAgdHhuYXMgQXNzZXRzCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6ODUKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV9hc3NldF9mcm96ZW5fZ2V0CiAgICBieXRlIDB4MDAKICAgIGludCAwCiAgICB1bmNvdmVyIDIKICAgIHNldGJpdAogICAgYnl0ZSAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50IDEKICAgIHJldHVybgoKbWFpbl9iYXJlX3JvdXRpbmdANjoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTo3OQogICAgLy8gY2xhc3MgU3RhdGVBc3NldEhvbGRpbmdDb250cmFjdChBUkM0Q29udHJhY3QpOgogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIHJlamVjdCB0cmFuc2FjdGlvbgogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgICEKICAgIGFzc2VydCAvLyBpcyBjcmVhdGluZwogICAgaW50IDEKICAgIHJldHVybgoKCi8vIHRlc3RzLmFydGlmYWN0cy5TdGF0ZU9wcy5jb250cmFjdC5TdGF0ZUFzc2V0SG9sZGluZ0NvbnRyYWN0LnZlcmlmeV9hc3NldF9ob2xkaW5nX2dldChhOiBieXRlcywgYjogdWludDY0KSAtPiB1aW50NjQ6CnZlcmlmeV9hc3NldF9ob2xkaW5nX2dldDoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTo4MC04MQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIGRlZiB2ZXJpZnlfYXNzZXRfaG9sZGluZ19nZXQoc2VsZiwgYTogQWNjb3VudCwgYjogQXNzZXQpIC0+IFVJbnQ2NDoKICAgIHByb3RvIDIgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjgyCiAgICAvLyBiYWxhbmNlLCBfdmFsID0gb3AuQXNzZXRIb2xkaW5nR2V0LmFzc2V0X2JhbGFuY2UoYSwgYikKICAgIGZyYW1lX2RpZyAtMgogICAgZnJhbWVfZGlnIC0xCiAgICBhc3NldF9ob2xkaW5nX2dldCBBc3NldEJhbGFuY2UKICAgIHBvcAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjgzCiAgICAvLyByZXR1cm4gYmFsYW5jZQogICAgcmV0c3ViCgoKLy8gdGVzdHMuYXJ0aWZhY3RzLlN0YXRlT3BzLmNvbnRyYWN0LlN0YXRlQXNzZXRIb2xkaW5nQ29udHJhY3QudmVyaWZ5X2Fzc2V0X2Zyb3plbl9nZXQoYTogYnl0ZXMsIGI6IHVpbnQ2NCkgLT4gdWludDY0Ogp2ZXJpZnlfYXNzZXRfZnJvemVuX2dldDoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTo4NS04NgogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIGRlZiB2ZXJpZnlfYXNzZXRfZnJvemVuX2dldChzZWxmLCBhOiBBY2NvdW50LCBiOiBBc3NldCkgLT4gYm9vbDoKICAgIHByb3RvIDIgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5Ojg3CiAgICAvLyBmcm96ZW4sIF92YWwgPSBvcC5Bc3NldEhvbGRpbmdHZXQuYXNzZXRfZnJvemVuKGEsIGIpCiAgICBmcmFtZV9kaWcgLTIKICAgIGZyYW1lX2RpZyAtMQogICAgYXNzZXRfaG9sZGluZ19nZXQgQXNzZXRGcm96ZW4KICAgIHBvcAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5Ojg4CiAgICAvLyByZXR1cm4gZnJvemVuCiAgICByZXRzdWIK", - "clear": "I3ByYWdtYSB2ZXJzaW9uIDEwCgp0ZXN0cy5hcnRpZmFjdHMuU3RhdGVPcHMuY29udHJhY3QuU3RhdGVBc3NldEhvbGRpbmdDb250cmFjdC5jbGVhcl9zdGF0ZV9wcm9ncmFtOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5Ojc5CiAgICAvLyBjbGFzcyBTdGF0ZUFzc2V0SG9sZGluZ0NvbnRyYWN0KEFSQzRDb250cmFjdCk6CiAgICBpbnQgMQogICAgcmV0dXJuCg==" + "approval": "I3ByYWdtYSB2ZXJzaW9uIDEwCgp0ZXN0cy5hcnRpZmFjdHMuU3RhdGVPcHMuY29udHJhY3QuU3RhdGVBc3NldEhvbGRpbmdDb250cmFjdC5hcHByb3ZhbF9wcm9ncmFtOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjEyOAogICAgLy8gY2xhc3MgU3RhdGVBc3NldEhvbGRpbmdDb250cmFjdChBUkM0Q29udHJhY3QpOgogICAgdHhuIE51bUFwcEFyZ3MKICAgIGJ6IG1haW5fYmFyZV9yb3V0aW5nQDYKICAgIG1ldGhvZCAidmVyaWZ5X2Fzc2V0X2hvbGRpbmdfZ2V0KGFjY291bnQsYXNzZXQpdWludDY0IgogICAgbWV0aG9kICJ2ZXJpZnlfYXNzZXRfZnJvemVuX2dldChhY2NvdW50LGFzc2V0KWJvb2wiCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAwCiAgICBtYXRjaCBtYWluX3ZlcmlmeV9hc3NldF9ob2xkaW5nX2dldF9yb3V0ZUAyIG1haW5fdmVyaWZ5X2Fzc2V0X2Zyb3plbl9nZXRfcm91dGVAMwogICAgZXJyIC8vIHJlamVjdCB0cmFuc2FjdGlvbgoKbWFpbl92ZXJpZnlfYXNzZXRfaG9sZGluZ19nZXRfcm91dGVAMjoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weToxMjkKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gaXMgbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6MTI4CiAgICAvLyBjbGFzcyBTdGF0ZUFzc2V0SG9sZGluZ0NvbnRyYWN0KEFSQzRDb250cmFjdCk6CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBidG9pCiAgICB0eG5hcyBBY2NvdW50cwogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMgogICAgYnRvaQogICAgdHhuYXMgQXNzZXRzCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6MTI5CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfYXNzZXRfaG9sZGluZ19nZXQKICAgIGl0b2IKICAgIGJ5dGUgMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludCAxCiAgICByZXR1cm4KCm1haW5fdmVyaWZ5X2Fzc2V0X2Zyb3plbl9nZXRfcm91dGVAMzoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weToxMzQKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gaXMgbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6MTI4CiAgICAvLyBjbGFzcyBTdGF0ZUFzc2V0SG9sZGluZ0NvbnRyYWN0KEFSQzRDb250cmFjdCk6CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBidG9pCiAgICB0eG5hcyBBY2NvdW50cwogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMgogICAgYnRvaQogICAgdHhuYXMgQXNzZXRzCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6MTM0CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfYXNzZXRfZnJvemVuX2dldAogICAgYnl0ZSAweDAwCiAgICBpbnQgMAogICAgdW5jb3ZlciAyCiAgICBzZXRiaXQKICAgIGJ5dGUgMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludCAxCiAgICByZXR1cm4KCm1haW5fYmFyZV9yb3V0aW5nQDY6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6MTI4CiAgICAvLyBjbGFzcyBTdGF0ZUFzc2V0SG9sZGluZ0NvbnRyYWN0KEFSQzRDb250cmFjdCk6CiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gcmVqZWN0IHRyYW5zYWN0aW9uCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgIQogICAgYXNzZXJ0IC8vIGlzIGNyZWF0aW5nCiAgICBpbnQgMQogICAgcmV0dXJuCgoKLy8gdGVzdHMuYXJ0aWZhY3RzLlN0YXRlT3BzLmNvbnRyYWN0LlN0YXRlQXNzZXRIb2xkaW5nQ29udHJhY3QudmVyaWZ5X2Fzc2V0X2hvbGRpbmdfZ2V0KGE6IGJ5dGVzLCBiOiB1aW50NjQpIC0+IHVpbnQ2NDoKdmVyaWZ5X2Fzc2V0X2hvbGRpbmdfZ2V0OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjEyOS0xMzAKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBkZWYgdmVyaWZ5X2Fzc2V0X2hvbGRpbmdfZ2V0KHNlbGYsIGE6IEFjY291bnQsIGI6IEFzc2V0KSAtPiBVSW50NjQ6CiAgICBwcm90byAyIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weToxMzEKICAgIC8vIGJhbGFuY2UsIF92YWwgPSBvcC5Bc3NldEhvbGRpbmdHZXQuYXNzZXRfYmFsYW5jZShhLCBiKQogICAgZnJhbWVfZGlnIC0yCiAgICBmcmFtZV9kaWcgLTEKICAgIGFzc2V0X2hvbGRpbmdfZ2V0IEFzc2V0QmFsYW5jZQogICAgcG9wCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6MTMyCiAgICAvLyByZXR1cm4gYmFsYW5jZQogICAgcmV0c3ViCgoKLy8gdGVzdHMuYXJ0aWZhY3RzLlN0YXRlT3BzLmNvbnRyYWN0LlN0YXRlQXNzZXRIb2xkaW5nQ29udHJhY3QudmVyaWZ5X2Fzc2V0X2Zyb3plbl9nZXQoYTogYnl0ZXMsIGI6IHVpbnQ2NCkgLT4gdWludDY0Ogp2ZXJpZnlfYXNzZXRfZnJvemVuX2dldDoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weToxMzQtMTM1CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gZGVmIHZlcmlmeV9hc3NldF9mcm96ZW5fZ2V0KHNlbGYsIGE6IEFjY291bnQsIGI6IEFzc2V0KSAtPiBib29sOgogICAgcHJvdG8gMiAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6MTM2CiAgICAvLyBmcm96ZW4sIF92YWwgPSBvcC5Bc3NldEhvbGRpbmdHZXQuYXNzZXRfZnJvemVuKGEsIGIpCiAgICBmcmFtZV9kaWcgLTIKICAgIGZyYW1lX2RpZyAtMQogICAgYXNzZXRfaG9sZGluZ19nZXQgQXNzZXRGcm96ZW4KICAgIHBvcAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjEzNwogICAgLy8gcmV0dXJuIGZyb3plbgogICAgcmV0c3ViCg==", + "clear": "I3ByYWdtYSB2ZXJzaW9uIDEwCgp0ZXN0cy5hcnRpZmFjdHMuU3RhdGVPcHMuY29udHJhY3QuU3RhdGVBc3NldEhvbGRpbmdDb250cmFjdC5jbGVhcl9zdGF0ZV9wcm9ncmFtOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjEyOAogICAgLy8gY2xhc3MgU3RhdGVBc3NldEhvbGRpbmdDb250cmFjdChBUkM0Q29udHJhY3QpOgogICAgaW50IDEKICAgIHJldHVybgo=" }, "state": { "global": { diff --git a/tests/artifacts/StateOps/data/StateAssetHoldingContract.clear.teal b/tests/artifacts/StateOps/data/StateAssetHoldingContract.clear.teal index e7b70bd..13f8855 100644 --- a/tests/artifacts/StateOps/data/StateAssetHoldingContract.clear.teal +++ b/tests/artifacts/StateOps/data/StateAssetHoldingContract.clear.teal @@ -1,7 +1,7 @@ #pragma version 10 tests.artifacts.StateOps.contract.StateAssetHoldingContract.clear_state_program: - // tests/artifacts/StateOps/contract.py:79 + // tests/artifacts/StateOps/contract.py:128 // class StateAssetHoldingContract(ARC4Contract): int 1 return diff --git a/tests/artifacts/StateOps/data/StateAssetParamsContract.approval.teal b/tests/artifacts/StateOps/data/StateAssetParamsContract.approval.teal index 44b0402..a166924 100644 --- a/tests/artifacts/StateOps/data/StateAssetParamsContract.approval.teal +++ b/tests/artifacts/StateOps/data/StateAssetParamsContract.approval.teal @@ -1,7 +1,7 @@ #pragma version 10 tests.artifacts.StateOps.contract.StateAssetParamsContract.approval_program: - // tests/artifacts/StateOps/contract.py:91 + // tests/artifacts/StateOps/contract.py:140 // class StateAssetParamsContract(ARC4Contract): txn NumAppArgs bz main_bare_routing@16 @@ -12,29 +12,29 @@ tests.artifacts.StateOps.contract.StateAssetParamsContract.approval_program: method "verify_asset_params_get_name(asset)byte[]" method "verify_asset_params_get_url(asset)byte[]" method "verify_asset_params_get_metadata_hash(asset)byte[]" - method "verify_asset_params_get_manager(asset)byte[]" - method "verify_asset_params_get_reserve(asset)byte[]" - method "verify_asset_params_get_freeze(asset)byte[]" - method "verify_asset_params_get_clawback(asset)byte[]" - method "verify_asset_params_get_creator(asset)byte[]" + method "verify_asset_params_get_manager(asset)address" + method "verify_asset_params_get_reserve(asset)address" + method "verify_asset_params_get_freeze(asset)address" + method "verify_asset_params_get_clawback(asset)address" + method "verify_asset_params_get_creator(asset)address" txna ApplicationArgs 0 match main_verify_asset_params_get_total_route@2 main_verify_asset_params_get_decimals_route@3 main_verify_asset_params_get_default_frozen_route@4 main_verify_asset_params_get_unit_name_route@5 main_verify_asset_params_get_name_route@6 main_verify_asset_params_get_url_route@7 main_verify_asset_params_get_metadata_hash_route@8 main_verify_asset_params_get_manager_route@9 main_verify_asset_params_get_reserve_route@10 main_verify_asset_params_get_freeze_route@11 main_verify_asset_params_get_clawback_route@12 main_verify_asset_params_get_creator_route@13 err // reject transaction main_verify_asset_params_get_total_route@2: - // tests/artifacts/StateOps/contract.py:92 + // tests/artifacts/StateOps/contract.py:141 // @arc4.abimethod() txn OnCompletion ! assert // OnCompletion is NoOp txn ApplicationID assert // is not creating - // tests/artifacts/StateOps/contract.py:91 + // tests/artifacts/StateOps/contract.py:140 // class StateAssetParamsContract(ARC4Contract): txna ApplicationArgs 1 btoi txnas Assets - // tests/artifacts/StateOps/contract.py:92 + // tests/artifacts/StateOps/contract.py:141 // @arc4.abimethod() callsub verify_asset_params_get_total itob @@ -46,19 +46,19 @@ main_verify_asset_params_get_total_route@2: return main_verify_asset_params_get_decimals_route@3: - // tests/artifacts/StateOps/contract.py:97 + // tests/artifacts/StateOps/contract.py:149 // @arc4.abimethod() txn OnCompletion ! assert // OnCompletion is NoOp txn ApplicationID assert // is not creating - // tests/artifacts/StateOps/contract.py:91 + // tests/artifacts/StateOps/contract.py:140 // class StateAssetParamsContract(ARC4Contract): txna ApplicationArgs 1 btoi txnas Assets - // tests/artifacts/StateOps/contract.py:97 + // tests/artifacts/StateOps/contract.py:149 // @arc4.abimethod() callsub verify_asset_params_get_decimals itob @@ -70,19 +70,19 @@ main_verify_asset_params_get_decimals_route@3: return main_verify_asset_params_get_default_frozen_route@4: - // tests/artifacts/StateOps/contract.py:102 + // tests/artifacts/StateOps/contract.py:157 // @arc4.abimethod() txn OnCompletion ! assert // OnCompletion is NoOp txn ApplicationID assert // is not creating - // tests/artifacts/StateOps/contract.py:91 + // tests/artifacts/StateOps/contract.py:140 // class StateAssetParamsContract(ARC4Contract): txna ApplicationArgs 1 btoi txnas Assets - // tests/artifacts/StateOps/contract.py:102 + // tests/artifacts/StateOps/contract.py:157 // @arc4.abimethod() callsub verify_asset_params_get_default_frozen byte 0x00 @@ -97,19 +97,19 @@ main_verify_asset_params_get_default_frozen_route@4: return main_verify_asset_params_get_unit_name_route@5: - // tests/artifacts/StateOps/contract.py:107 + // tests/artifacts/StateOps/contract.py:165 // @arc4.abimethod() txn OnCompletion ! assert // OnCompletion is NoOp txn ApplicationID assert // is not creating - // tests/artifacts/StateOps/contract.py:91 + // tests/artifacts/StateOps/contract.py:140 // class StateAssetParamsContract(ARC4Contract): txna ApplicationArgs 1 btoi txnas Assets - // tests/artifacts/StateOps/contract.py:107 + // tests/artifacts/StateOps/contract.py:165 // @arc4.abimethod() callsub verify_asset_params_get_unit_name dup @@ -126,19 +126,19 @@ main_verify_asset_params_get_unit_name_route@5: return main_verify_asset_params_get_name_route@6: - // tests/artifacts/StateOps/contract.py:112 + // tests/artifacts/StateOps/contract.py:173 // @arc4.abimethod() txn OnCompletion ! assert // OnCompletion is NoOp txn ApplicationID assert // is not creating - // tests/artifacts/StateOps/contract.py:91 + // tests/artifacts/StateOps/contract.py:140 // class StateAssetParamsContract(ARC4Contract): txna ApplicationArgs 1 btoi txnas Assets - // tests/artifacts/StateOps/contract.py:112 + // tests/artifacts/StateOps/contract.py:173 // @arc4.abimethod() callsub verify_asset_params_get_name dup @@ -155,19 +155,19 @@ main_verify_asset_params_get_name_route@6: return main_verify_asset_params_get_url_route@7: - // tests/artifacts/StateOps/contract.py:117 + // tests/artifacts/StateOps/contract.py:181 // @arc4.abimethod() txn OnCompletion ! assert // OnCompletion is NoOp txn ApplicationID assert // is not creating - // tests/artifacts/StateOps/contract.py:91 + // tests/artifacts/StateOps/contract.py:140 // class StateAssetParamsContract(ARC4Contract): txna ApplicationArgs 1 btoi txnas Assets - // tests/artifacts/StateOps/contract.py:117 + // tests/artifacts/StateOps/contract.py:181 // @arc4.abimethod() callsub verify_asset_params_get_url dup @@ -184,19 +184,19 @@ main_verify_asset_params_get_url_route@7: return main_verify_asset_params_get_metadata_hash_route@8: - // tests/artifacts/StateOps/contract.py:122 + // tests/artifacts/StateOps/contract.py:189 // @arc4.abimethod() txn OnCompletion ! assert // OnCompletion is NoOp txn ApplicationID assert // is not creating - // tests/artifacts/StateOps/contract.py:91 + // tests/artifacts/StateOps/contract.py:140 // class StateAssetParamsContract(ARC4Contract): txna ApplicationArgs 1 btoi txnas Assets - // tests/artifacts/StateOps/contract.py:122 + // tests/artifacts/StateOps/contract.py:189 // @arc4.abimethod() callsub verify_asset_params_get_metadata_hash dup @@ -213,27 +213,21 @@ main_verify_asset_params_get_metadata_hash_route@8: return main_verify_asset_params_get_manager_route@9: - // tests/artifacts/StateOps/contract.py:127 + // tests/artifacts/StateOps/contract.py:197 // @arc4.abimethod() txn OnCompletion ! assert // OnCompletion is NoOp txn ApplicationID assert // is not creating - // tests/artifacts/StateOps/contract.py:91 + // tests/artifacts/StateOps/contract.py:140 // class StateAssetParamsContract(ARC4Contract): txna ApplicationArgs 1 btoi txnas Assets - // tests/artifacts/StateOps/contract.py:127 + // tests/artifacts/StateOps/contract.py:197 // @arc4.abimethod() callsub verify_asset_params_get_manager - dup - len - itob - extract 6 2 - swap - concat byte 0x151f7c75 swap concat @@ -242,27 +236,21 @@ main_verify_asset_params_get_manager_route@9: return main_verify_asset_params_get_reserve_route@10: - // tests/artifacts/StateOps/contract.py:132 + // tests/artifacts/StateOps/contract.py:205 // @arc4.abimethod() txn OnCompletion ! assert // OnCompletion is NoOp txn ApplicationID assert // is not creating - // tests/artifacts/StateOps/contract.py:91 + // tests/artifacts/StateOps/contract.py:140 // class StateAssetParamsContract(ARC4Contract): txna ApplicationArgs 1 btoi txnas Assets - // tests/artifacts/StateOps/contract.py:132 + // tests/artifacts/StateOps/contract.py:205 // @arc4.abimethod() callsub verify_asset_params_get_reserve - dup - len - itob - extract 6 2 - swap - concat byte 0x151f7c75 swap concat @@ -271,27 +259,21 @@ main_verify_asset_params_get_reserve_route@10: return main_verify_asset_params_get_freeze_route@11: - // tests/artifacts/StateOps/contract.py:137 + // tests/artifacts/StateOps/contract.py:213 // @arc4.abimethod() txn OnCompletion ! assert // OnCompletion is NoOp txn ApplicationID assert // is not creating - // tests/artifacts/StateOps/contract.py:91 + // tests/artifacts/StateOps/contract.py:140 // class StateAssetParamsContract(ARC4Contract): txna ApplicationArgs 1 btoi txnas Assets - // tests/artifacts/StateOps/contract.py:137 + // tests/artifacts/StateOps/contract.py:213 // @arc4.abimethod() callsub verify_asset_params_get_freeze - dup - len - itob - extract 6 2 - swap - concat byte 0x151f7c75 swap concat @@ -300,27 +282,21 @@ main_verify_asset_params_get_freeze_route@11: return main_verify_asset_params_get_clawback_route@12: - // tests/artifacts/StateOps/contract.py:142 + // tests/artifacts/StateOps/contract.py:221 // @arc4.abimethod() txn OnCompletion ! assert // OnCompletion is NoOp txn ApplicationID assert // is not creating - // tests/artifacts/StateOps/contract.py:91 + // tests/artifacts/StateOps/contract.py:140 // class StateAssetParamsContract(ARC4Contract): txna ApplicationArgs 1 btoi txnas Assets - // tests/artifacts/StateOps/contract.py:142 + // tests/artifacts/StateOps/contract.py:221 // @arc4.abimethod() callsub verify_asset_params_get_clawback - dup - len - itob - extract 6 2 - swap - concat byte 0x151f7c75 swap concat @@ -329,27 +305,21 @@ main_verify_asset_params_get_clawback_route@12: return main_verify_asset_params_get_creator_route@13: - // tests/artifacts/StateOps/contract.py:147 + // tests/artifacts/StateOps/contract.py:229 // @arc4.abimethod() txn OnCompletion ! assert // OnCompletion is NoOp txn ApplicationID assert // is not creating - // tests/artifacts/StateOps/contract.py:91 + // tests/artifacts/StateOps/contract.py:140 // class StateAssetParamsContract(ARC4Contract): txna ApplicationArgs 1 btoi txnas Assets - // tests/artifacts/StateOps/contract.py:147 + // tests/artifacts/StateOps/contract.py:229 // @arc4.abimethod() callsub verify_asset_params_get_creator - dup - len - itob - extract 6 2 - swap - concat byte 0x151f7c75 swap concat @@ -358,7 +328,7 @@ main_verify_asset_params_get_creator_route@13: return main_bare_routing@16: - // tests/artifacts/StateOps/contract.py:91 + // tests/artifacts/StateOps/contract.py:140 // class StateAssetParamsContract(ARC4Contract): txn OnCompletion ! @@ -372,191 +342,384 @@ main_bare_routing@16: // tests.artifacts.StateOps.contract.StateAssetParamsContract.verify_asset_params_get_total(a: uint64) -> uint64: verify_asset_params_get_total: - // tests/artifacts/StateOps/contract.py:92-93 + // tests/artifacts/StateOps/contract.py:141-142 // @arc4.abimethod() // def verify_asset_params_get_total(self, a: Asset) -> UInt64: proto 1 1 - // tests/artifacts/StateOps/contract.py:94 - // total, _val = op.AssetParamsGet.asset_total(a) + // tests/artifacts/StateOps/contract.py:143 + // value, exists = op.AssetParamsGet.asset_total(a) frame_dig -1 asset_params_get AssetTotal - pop - // tests/artifacts/StateOps/contract.py:95 - // return total + swap + // tests/artifacts/StateOps/contract.py:144 + // value_index, exists_index = op.AssetParamsGet.asset_total(_get_1st_ref_index()) + callsub _get_1st_ref_index + asset_params_get AssetTotal + cover 2 + // tests/artifacts/StateOps/contract.py:145 + // assert value == value_index, "expected value by index to match" + dig 1 + == + assert // expected value by index to match + // tests/artifacts/StateOps/contract.py:146 + // assert exists == exists_index, "expected exists by index to match" + cover 2 + == + assert // expected exists by index to match + // tests/artifacts/StateOps/contract.py:147 + // return value + retsub + + +// tests.artifacts.StateOps.contract._get_1st_ref_index() -> uint64: +_get_1st_ref_index: + // tests/artifacts/StateOps/contract.py:19-20 + // @subroutine + // def _get_1st_ref_index() -> UInt64: + proto 0 1 + // tests/artifacts/StateOps/contract.py:21 + // return op.btoi(Txn.application_args(1)) + txna ApplicationArgs 1 + btoi retsub // tests.artifacts.StateOps.contract.StateAssetParamsContract.verify_asset_params_get_decimals(a: uint64) -> uint64: verify_asset_params_get_decimals: - // tests/artifacts/StateOps/contract.py:97-98 + // tests/artifacts/StateOps/contract.py:149-150 // @arc4.abimethod() // def verify_asset_params_get_decimals(self, a: Asset) -> UInt64: proto 1 1 - // tests/artifacts/StateOps/contract.py:99 - // decimals, _val = op.AssetParamsGet.asset_decimals(a) + // tests/artifacts/StateOps/contract.py:151 + // value, exists = op.AssetParamsGet.asset_decimals(a) frame_dig -1 asset_params_get AssetDecimals - pop - // tests/artifacts/StateOps/contract.py:100 - // return decimals + swap + // tests/artifacts/StateOps/contract.py:152 + // value_index, exists_index = op.AssetParamsGet.asset_decimals(_get_1st_ref_index()) + callsub _get_1st_ref_index + asset_params_get AssetDecimals + cover 2 + // tests/artifacts/StateOps/contract.py:153 + // assert value == value_index, "expected value by index to match" + dig 1 + == + assert // expected value by index to match + // tests/artifacts/StateOps/contract.py:154 + // assert exists == exists_index, "expected exists by index to match" + cover 2 + == + assert // expected exists by index to match + // tests/artifacts/StateOps/contract.py:155 + // return value retsub // tests.artifacts.StateOps.contract.StateAssetParamsContract.verify_asset_params_get_default_frozen(a: uint64) -> uint64: verify_asset_params_get_default_frozen: - // tests/artifacts/StateOps/contract.py:102-103 + // tests/artifacts/StateOps/contract.py:157-158 // @arc4.abimethod() // def verify_asset_params_get_default_frozen(self, a: Asset) -> bool: proto 1 1 - // tests/artifacts/StateOps/contract.py:104 - // default_frozen, _val = op.AssetParamsGet.asset_default_frozen(a) + // tests/artifacts/StateOps/contract.py:159 + // value, exists = op.AssetParamsGet.asset_default_frozen(a) frame_dig -1 asset_params_get AssetDefaultFrozen - pop - // tests/artifacts/StateOps/contract.py:105 - // return default_frozen + swap + // tests/artifacts/StateOps/contract.py:160 + // value_index, exists_index = op.AssetParamsGet.asset_default_frozen(_get_1st_ref_index()) + callsub _get_1st_ref_index + asset_params_get AssetDefaultFrozen + cover 2 + // tests/artifacts/StateOps/contract.py:161 + // assert value == value_index, "expected value by index to match" + dig 1 + == + assert // expected value by index to match + // tests/artifacts/StateOps/contract.py:162 + // assert exists == exists_index, "expected exists by index to match" + cover 2 + == + assert // expected exists by index to match + // tests/artifacts/StateOps/contract.py:163 + // return value retsub // tests.artifacts.StateOps.contract.StateAssetParamsContract.verify_asset_params_get_unit_name(a: uint64) -> bytes: verify_asset_params_get_unit_name: - // tests/artifacts/StateOps/contract.py:107-108 + // tests/artifacts/StateOps/contract.py:165-166 // @arc4.abimethod() // def verify_asset_params_get_unit_name(self, a: Asset) -> Bytes: proto 1 1 - // tests/artifacts/StateOps/contract.py:109 - // unit_name, _val = op.AssetParamsGet.asset_unit_name(a) + // tests/artifacts/StateOps/contract.py:167 + // value, exists = op.AssetParamsGet.asset_unit_name(a) frame_dig -1 asset_params_get AssetUnitName - pop - // tests/artifacts/StateOps/contract.py:110 - // return unit_name + swap + // tests/artifacts/StateOps/contract.py:168 + // value_index, exists_index = op.AssetParamsGet.asset_unit_name(_get_1st_ref_index()) + callsub _get_1st_ref_index + asset_params_get AssetUnitName + cover 2 + // tests/artifacts/StateOps/contract.py:169 + // assert value == value_index, "expected value by index to match" + dig 1 + == + assert // expected value by index to match + // tests/artifacts/StateOps/contract.py:170 + // assert exists == exists_index, "expected exists by index to match" + cover 2 + == + assert // expected exists by index to match + // tests/artifacts/StateOps/contract.py:171 + // return value retsub // tests.artifacts.StateOps.contract.StateAssetParamsContract.verify_asset_params_get_name(a: uint64) -> bytes: verify_asset_params_get_name: - // tests/artifacts/StateOps/contract.py:112-113 + // tests/artifacts/StateOps/contract.py:173-174 // @arc4.abimethod() // def verify_asset_params_get_name(self, a: Asset) -> Bytes: proto 1 1 - // tests/artifacts/StateOps/contract.py:114 - // name, _val = op.AssetParamsGet.asset_name(a) + // tests/artifacts/StateOps/contract.py:175 + // value, exists = op.AssetParamsGet.asset_name(a) frame_dig -1 asset_params_get AssetName - pop - // tests/artifacts/StateOps/contract.py:115 - // return name + swap + // tests/artifacts/StateOps/contract.py:176 + // value_index, exists_index = op.AssetParamsGet.asset_name(_get_1st_ref_index()) + callsub _get_1st_ref_index + asset_params_get AssetName + cover 2 + // tests/artifacts/StateOps/contract.py:177 + // assert value == value_index, "expected value by index to match" + dig 1 + == + assert // expected value by index to match + // tests/artifacts/StateOps/contract.py:178 + // assert exists == exists_index, "expected exists by index to match" + cover 2 + == + assert // expected exists by index to match + // tests/artifacts/StateOps/contract.py:179 + // return value retsub // tests.artifacts.StateOps.contract.StateAssetParamsContract.verify_asset_params_get_url(a: uint64) -> bytes: verify_asset_params_get_url: - // tests/artifacts/StateOps/contract.py:117-118 + // tests/artifacts/StateOps/contract.py:181-182 // @arc4.abimethod() // def verify_asset_params_get_url(self, a: Asset) -> Bytes: proto 1 1 - // tests/artifacts/StateOps/contract.py:119 - // url, _val = op.AssetParamsGet.asset_url(a) + // tests/artifacts/StateOps/contract.py:183 + // value, exists = op.AssetParamsGet.asset_url(a) frame_dig -1 asset_params_get AssetURL - pop - // tests/artifacts/StateOps/contract.py:120 - // return url + swap + // tests/artifacts/StateOps/contract.py:184 + // value_index, exists_index = op.AssetParamsGet.asset_url(_get_1st_ref_index()) + callsub _get_1st_ref_index + asset_params_get AssetURL + cover 2 + // tests/artifacts/StateOps/contract.py:185 + // assert value == value_index, "expected value by index to match" + dig 1 + == + assert // expected value by index to match + // tests/artifacts/StateOps/contract.py:186 + // assert exists == exists_index, "expected exists by index to match" + cover 2 + == + assert // expected exists by index to match + // tests/artifacts/StateOps/contract.py:187 + // return value retsub // tests.artifacts.StateOps.contract.StateAssetParamsContract.verify_asset_params_get_metadata_hash(a: uint64) -> bytes: verify_asset_params_get_metadata_hash: - // tests/artifacts/StateOps/contract.py:122-123 + // tests/artifacts/StateOps/contract.py:189-190 // @arc4.abimethod() // def verify_asset_params_get_metadata_hash(self, a: Asset) -> Bytes: proto 1 1 - // tests/artifacts/StateOps/contract.py:124 - // metadata_hash, _val = op.AssetParamsGet.asset_metadata_hash(a) + // tests/artifacts/StateOps/contract.py:191 + // value, exists = op.AssetParamsGet.asset_metadata_hash(a) frame_dig -1 asset_params_get AssetMetadataHash - pop - // tests/artifacts/StateOps/contract.py:125 - // return metadata_hash + swap + // tests/artifacts/StateOps/contract.py:192 + // value_index, exists_index = op.AssetParamsGet.asset_metadata_hash(_get_1st_ref_index()) + callsub _get_1st_ref_index + asset_params_get AssetMetadataHash + cover 2 + // tests/artifacts/StateOps/contract.py:193 + // assert value == value_index, "expected value by index to match" + dig 1 + == + assert // expected value by index to match + // tests/artifacts/StateOps/contract.py:194 + // assert exists == exists_index, "expected exists by index to match" + cover 2 + == + assert // expected exists by index to match + // tests/artifacts/StateOps/contract.py:195 + // return value retsub // tests.artifacts.StateOps.contract.StateAssetParamsContract.verify_asset_params_get_manager(a: uint64) -> bytes: verify_asset_params_get_manager: - // tests/artifacts/StateOps/contract.py:127-128 + // tests/artifacts/StateOps/contract.py:197-198 // @arc4.abimethod() - // def verify_asset_params_get_manager(self, a: Asset) -> Bytes: + // def verify_asset_params_get_manager(self, a: Asset) -> arc4.Address: proto 1 1 - // tests/artifacts/StateOps/contract.py:129 - // manager, _val = op.AssetParamsGet.asset_manager(a) + // tests/artifacts/StateOps/contract.py:199 + // value, exists = op.AssetParamsGet.asset_manager(a) frame_dig -1 asset_params_get AssetManager - pop - // tests/artifacts/StateOps/contract.py:130 - // return manager.bytes + swap + // tests/artifacts/StateOps/contract.py:200 + // value_index, exists_index = op.AssetParamsGet.asset_manager(_get_1st_ref_index()) + callsub _get_1st_ref_index + asset_params_get AssetManager + cover 2 + // tests/artifacts/StateOps/contract.py:201 + // assert value == value_index, "expected value by index to match" + dig 1 + == + assert // expected value by index to match + // tests/artifacts/StateOps/contract.py:202 + // assert exists == exists_index, "expected exists by index to match" + cover 2 + == + assert // expected exists by index to match + // tests/artifacts/StateOps/contract.py:203 + // return arc4.Address(value) retsub // tests.artifacts.StateOps.contract.StateAssetParamsContract.verify_asset_params_get_reserve(a: uint64) -> bytes: verify_asset_params_get_reserve: - // tests/artifacts/StateOps/contract.py:132-133 + // tests/artifacts/StateOps/contract.py:205-206 // @arc4.abimethod() - // def verify_asset_params_get_reserve(self, a: Asset) -> Bytes: + // def verify_asset_params_get_reserve(self, a: Asset) -> arc4.Address: proto 1 1 - // tests/artifacts/StateOps/contract.py:134 - // reserve, _val = op.AssetParamsGet.asset_reserve(a) + // tests/artifacts/StateOps/contract.py:207 + // value, exists = op.AssetParamsGet.asset_reserve(a) frame_dig -1 asset_params_get AssetReserve - pop - // tests/artifacts/StateOps/contract.py:135 - // return reserve.bytes + swap + // tests/artifacts/StateOps/contract.py:208 + // value_index, exists_index = op.AssetParamsGet.asset_reserve(_get_1st_ref_index()) + callsub _get_1st_ref_index + asset_params_get AssetReserve + cover 2 + // tests/artifacts/StateOps/contract.py:209 + // assert value == value_index, "expected value by index to match" + dig 1 + == + assert // expected value by index to match + // tests/artifacts/StateOps/contract.py:210 + // assert exists == exists_index, "expected exists by index to match" + cover 2 + == + assert // expected exists by index to match + // tests/artifacts/StateOps/contract.py:211 + // return arc4.Address(value) retsub // tests.artifacts.StateOps.contract.StateAssetParamsContract.verify_asset_params_get_freeze(a: uint64) -> bytes: verify_asset_params_get_freeze: - // tests/artifacts/StateOps/contract.py:137-138 + // tests/artifacts/StateOps/contract.py:213-214 // @arc4.abimethod() - // def verify_asset_params_get_freeze(self, a: Asset) -> Bytes: + // def verify_asset_params_get_freeze(self, a: Asset) -> arc4.Address: proto 1 1 - // tests/artifacts/StateOps/contract.py:139 - // freeze, _val = op.AssetParamsGet.asset_freeze(a) + // tests/artifacts/StateOps/contract.py:215 + // value, exists = op.AssetParamsGet.asset_freeze(a) frame_dig -1 asset_params_get AssetFreeze - pop - // tests/artifacts/StateOps/contract.py:140 - // return freeze.bytes + swap + // tests/artifacts/StateOps/contract.py:216 + // value_index, exists_index = op.AssetParamsGet.asset_freeze(_get_1st_ref_index()) + callsub _get_1st_ref_index + asset_params_get AssetFreeze + cover 2 + // tests/artifacts/StateOps/contract.py:217 + // assert value == value_index, "expected value by index to match" + dig 1 + == + assert // expected value by index to match + // tests/artifacts/StateOps/contract.py:218 + // assert exists == exists_index, "expected exists by index to match" + cover 2 + == + assert // expected exists by index to match + // tests/artifacts/StateOps/contract.py:219 + // return arc4.Address(value) retsub // tests.artifacts.StateOps.contract.StateAssetParamsContract.verify_asset_params_get_clawback(a: uint64) -> bytes: verify_asset_params_get_clawback: - // tests/artifacts/StateOps/contract.py:142-143 + // tests/artifacts/StateOps/contract.py:221-222 // @arc4.abimethod() - // def verify_asset_params_get_clawback(self, a: Asset) -> Bytes: + // def verify_asset_params_get_clawback(self, a: Asset) -> arc4.Address: proto 1 1 - // tests/artifacts/StateOps/contract.py:144 - // clawback, _val = op.AssetParamsGet.asset_clawback(a) + // tests/artifacts/StateOps/contract.py:223 + // value, exists = op.AssetParamsGet.asset_clawback(a) frame_dig -1 asset_params_get AssetClawback - pop - // tests/artifacts/StateOps/contract.py:145 - // return clawback.bytes + swap + // tests/artifacts/StateOps/contract.py:224 + // value_index, exists_index = op.AssetParamsGet.asset_clawback(_get_1st_ref_index()) + callsub _get_1st_ref_index + asset_params_get AssetClawback + cover 2 + // tests/artifacts/StateOps/contract.py:225 + // assert value == value_index, "expected value by index to match" + dig 1 + == + assert // expected value by index to match + // tests/artifacts/StateOps/contract.py:226 + // assert exists == exists_index, "expected exists by index to match" + cover 2 + == + assert // expected exists by index to match + // tests/artifacts/StateOps/contract.py:227 + // return arc4.Address(value) retsub // tests.artifacts.StateOps.contract.StateAssetParamsContract.verify_asset_params_get_creator(a: uint64) -> bytes: verify_asset_params_get_creator: - // tests/artifacts/StateOps/contract.py:147-148 + // tests/artifacts/StateOps/contract.py:229-230 // @arc4.abimethod() - // def verify_asset_params_get_creator(self, a: Asset) -> Bytes: + // def verify_asset_params_get_creator(self, a: Asset) -> arc4.Address: proto 1 1 - // tests/artifacts/StateOps/contract.py:149 - // creator, _val = op.AssetParamsGet.asset_creator(a) + // tests/artifacts/StateOps/contract.py:231 + // value, exists = op.AssetParamsGet.asset_creator(a) frame_dig -1 asset_params_get AssetCreator - pop - // tests/artifacts/StateOps/contract.py:150 - // return creator.bytes + swap + // tests/artifacts/StateOps/contract.py:232 + // value_index, exists_index = op.AssetParamsGet.asset_creator(_get_1st_ref_index()) + callsub _get_1st_ref_index + asset_params_get AssetCreator + cover 2 + // tests/artifacts/StateOps/contract.py:233 + // assert value == value_index, "expected value by index to match" + dig 1 + == + assert // expected value by index to match + // tests/artifacts/StateOps/contract.py:234 + // assert exists == exists_index, "expected exists by index to match" + cover 2 + == + assert // expected exists by index to match + // tests/artifacts/StateOps/contract.py:235 + // return arc4.Address(value) retsub diff --git a/tests/artifacts/StateOps/data/StateAssetParamsContract.arc32.json b/tests/artifacts/StateOps/data/StateAssetParamsContract.arc32.json index ed0b765..8a9b655 100644 --- a/tests/artifacts/StateOps/data/StateAssetParamsContract.arc32.json +++ b/tests/artifacts/StateOps/data/StateAssetParamsContract.arc32.json @@ -35,35 +35,35 @@ "no_op": "CALL" } }, - "verify_asset_params_get_manager(asset)byte[]": { + "verify_asset_params_get_manager(asset)address": { "call_config": { "no_op": "CALL" } }, - "verify_asset_params_get_reserve(asset)byte[]": { + "verify_asset_params_get_reserve(asset)address": { "call_config": { "no_op": "CALL" } }, - "verify_asset_params_get_freeze(asset)byte[]": { + "verify_asset_params_get_freeze(asset)address": { "call_config": { "no_op": "CALL" } }, - "verify_asset_params_get_clawback(asset)byte[]": { + "verify_asset_params_get_clawback(asset)address": { "call_config": { "no_op": "CALL" } }, - "verify_asset_params_get_creator(asset)byte[]": { + "verify_asset_params_get_creator(asset)address": { "call_config": { "no_op": "CALL" } } }, "source": { - "approval": "I3ByYWdtYSB2ZXJzaW9uIDEwCgp0ZXN0cy5hcnRpZmFjdHMuU3RhdGVPcHMuY29udHJhY3QuU3RhdGVBc3NldFBhcmFtc0NvbnRyYWN0LmFwcHJvdmFsX3Byb2dyYW06CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6OTEKICAgIC8vIGNsYXNzIFN0YXRlQXNzZXRQYXJhbXNDb250cmFjdChBUkM0Q29udHJhY3QpOgogICAgdHhuIE51bUFwcEFyZ3MKICAgIGJ6IG1haW5fYmFyZV9yb3V0aW5nQDE2CiAgICBtZXRob2QgInZlcmlmeV9hc3NldF9wYXJhbXNfZ2V0X3RvdGFsKGFzc2V0KXVpbnQ2NCIKICAgIG1ldGhvZCAidmVyaWZ5X2Fzc2V0X3BhcmFtc19nZXRfZGVjaW1hbHMoYXNzZXQpdWludDY0IgogICAgbWV0aG9kICJ2ZXJpZnlfYXNzZXRfcGFyYW1zX2dldF9kZWZhdWx0X2Zyb3plbihhc3NldClib29sIgogICAgbWV0aG9kICJ2ZXJpZnlfYXNzZXRfcGFyYW1zX2dldF91bml0X25hbWUoYXNzZXQpYnl0ZVtdIgogICAgbWV0aG9kICJ2ZXJpZnlfYXNzZXRfcGFyYW1zX2dldF9uYW1lKGFzc2V0KWJ5dGVbXSIKICAgIG1ldGhvZCAidmVyaWZ5X2Fzc2V0X3BhcmFtc19nZXRfdXJsKGFzc2V0KWJ5dGVbXSIKICAgIG1ldGhvZCAidmVyaWZ5X2Fzc2V0X3BhcmFtc19nZXRfbWV0YWRhdGFfaGFzaChhc3NldClieXRlW10iCiAgICBtZXRob2QgInZlcmlmeV9hc3NldF9wYXJhbXNfZ2V0X21hbmFnZXIoYXNzZXQpYnl0ZVtdIgogICAgbWV0aG9kICJ2ZXJpZnlfYXNzZXRfcGFyYW1zX2dldF9yZXNlcnZlKGFzc2V0KWJ5dGVbXSIKICAgIG1ldGhvZCAidmVyaWZ5X2Fzc2V0X3BhcmFtc19nZXRfZnJlZXplKGFzc2V0KWJ5dGVbXSIKICAgIG1ldGhvZCAidmVyaWZ5X2Fzc2V0X3BhcmFtc19nZXRfY2xhd2JhY2soYXNzZXQpYnl0ZVtdIgogICAgbWV0aG9kICJ2ZXJpZnlfYXNzZXRfcGFyYW1zX2dldF9jcmVhdG9yKGFzc2V0KWJ5dGVbXSIKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDAKICAgIG1hdGNoIG1haW5fdmVyaWZ5X2Fzc2V0X3BhcmFtc19nZXRfdG90YWxfcm91dGVAMiBtYWluX3ZlcmlmeV9hc3NldF9wYXJhbXNfZ2V0X2RlY2ltYWxzX3JvdXRlQDMgbWFpbl92ZXJpZnlfYXNzZXRfcGFyYW1zX2dldF9kZWZhdWx0X2Zyb3plbl9yb3V0ZUA0IG1haW5fdmVyaWZ5X2Fzc2V0X3BhcmFtc19nZXRfdW5pdF9uYW1lX3JvdXRlQDUgbWFpbl92ZXJpZnlfYXNzZXRfcGFyYW1zX2dldF9uYW1lX3JvdXRlQDYgbWFpbl92ZXJpZnlfYXNzZXRfcGFyYW1zX2dldF91cmxfcm91dGVANyBtYWluX3ZlcmlmeV9hc3NldF9wYXJhbXNfZ2V0X21ldGFkYXRhX2hhc2hfcm91dGVAOCBtYWluX3ZlcmlmeV9hc3NldF9wYXJhbXNfZ2V0X21hbmFnZXJfcm91dGVAOSBtYWluX3ZlcmlmeV9hc3NldF9wYXJhbXNfZ2V0X3Jlc2VydmVfcm91dGVAMTAgbWFpbl92ZXJpZnlfYXNzZXRfcGFyYW1zX2dldF9mcmVlemVfcm91dGVAMTEgbWFpbl92ZXJpZnlfYXNzZXRfcGFyYW1zX2dldF9jbGF3YmFja19yb3V0ZUAxMiBtYWluX3ZlcmlmeV9hc3NldF9wYXJhbXNfZ2V0X2NyZWF0b3Jfcm91dGVAMTMKICAgIGVyciAvLyByZWplY3QgdHJhbnNhY3Rpb24KCm1haW5fdmVyaWZ5X2Fzc2V0X3BhcmFtc19nZXRfdG90YWxfcm91dGVAMjoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTo5MgogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBpcyBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTo5MQogICAgLy8gY2xhc3MgU3RhdGVBc3NldFBhcmFtc0NvbnRyYWN0KEFSQzRDb250cmFjdCk6CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBidG9pCiAgICB0eG5hcyBBc3NldHMKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTo5MgogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X2Fzc2V0X3BhcmFtc19nZXRfdG90YWwKICAgIGl0b2IKICAgIGJ5dGUgMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludCAxCiAgICByZXR1cm4KCm1haW5fdmVyaWZ5X2Fzc2V0X3BhcmFtc19nZXRfZGVjaW1hbHNfcm91dGVAMzoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTo5NwogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBpcyBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTo5MQogICAgLy8gY2xhc3MgU3RhdGVBc3NldFBhcmFtc0NvbnRyYWN0KEFSQzRDb250cmFjdCk6CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBidG9pCiAgICB0eG5hcyBBc3NldHMKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTo5NwogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X2Fzc2V0X3BhcmFtc19nZXRfZGVjaW1hbHMKICAgIGl0b2IKICAgIGJ5dGUgMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludCAxCiAgICByZXR1cm4KCm1haW5fdmVyaWZ5X2Fzc2V0X3BhcmFtc19nZXRfZGVmYXVsdF9mcm96ZW5fcm91dGVANDoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weToxMDIKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gaXMgbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6OTEKICAgIC8vIGNsYXNzIFN0YXRlQXNzZXRQYXJhbXNDb250cmFjdChBUkM0Q29udHJhY3QpOgogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgYnRvaQogICAgdHhuYXMgQXNzZXRzCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6MTAyCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfYXNzZXRfcGFyYW1zX2dldF9kZWZhdWx0X2Zyb3plbgogICAgYnl0ZSAweDAwCiAgICBpbnQgMAogICAgdW5jb3ZlciAyCiAgICBzZXRiaXQKICAgIGJ5dGUgMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludCAxCiAgICByZXR1cm4KCm1haW5fdmVyaWZ5X2Fzc2V0X3BhcmFtc19nZXRfdW5pdF9uYW1lX3JvdXRlQDU6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6MTA3CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGlzIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjkxCiAgICAvLyBjbGFzcyBTdGF0ZUFzc2V0UGFyYW1zQ29udHJhY3QoQVJDNENvbnRyYWN0KToKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGJ0b2kKICAgIHR4bmFzIEFzc2V0cwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjEwNwogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X2Fzc2V0X3BhcmFtc19nZXRfdW5pdF9uYW1lCiAgICBkdXAKICAgIGxlbgogICAgaXRvYgogICAgZXh0cmFjdCA2IDIKICAgIHN3YXAKICAgIGNvbmNhdAogICAgYnl0ZSAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50IDEKICAgIHJldHVybgoKbWFpbl92ZXJpZnlfYXNzZXRfcGFyYW1zX2dldF9uYW1lX3JvdXRlQDY6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6MTEyCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGlzIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjkxCiAgICAvLyBjbGFzcyBTdGF0ZUFzc2V0UGFyYW1zQ29udHJhY3QoQVJDNENvbnRyYWN0KToKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGJ0b2kKICAgIHR4bmFzIEFzc2V0cwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjExMgogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X2Fzc2V0X3BhcmFtc19nZXRfbmFtZQogICAgZHVwCiAgICBsZW4KICAgIGl0b2IKICAgIGV4dHJhY3QgNiAyCiAgICBzd2FwCiAgICBjb25jYXQKICAgIGJ5dGUgMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludCAxCiAgICByZXR1cm4KCm1haW5fdmVyaWZ5X2Fzc2V0X3BhcmFtc19nZXRfdXJsX3JvdXRlQDc6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6MTE3CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGlzIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjkxCiAgICAvLyBjbGFzcyBTdGF0ZUFzc2V0UGFyYW1zQ29udHJhY3QoQVJDNENvbnRyYWN0KToKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGJ0b2kKICAgIHR4bmFzIEFzc2V0cwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjExNwogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X2Fzc2V0X3BhcmFtc19nZXRfdXJsCiAgICBkdXAKICAgIGxlbgogICAgaXRvYgogICAgZXh0cmFjdCA2IDIKICAgIHN3YXAKICAgIGNvbmNhdAogICAgYnl0ZSAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50IDEKICAgIHJldHVybgoKbWFpbl92ZXJpZnlfYXNzZXRfcGFyYW1zX2dldF9tZXRhZGF0YV9oYXNoX3JvdXRlQDg6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6MTIyCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGlzIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjkxCiAgICAvLyBjbGFzcyBTdGF0ZUFzc2V0UGFyYW1zQ29udHJhY3QoQVJDNENvbnRyYWN0KToKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGJ0b2kKICAgIHR4bmFzIEFzc2V0cwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjEyMgogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X2Fzc2V0X3BhcmFtc19nZXRfbWV0YWRhdGFfaGFzaAogICAgZHVwCiAgICBsZW4KICAgIGl0b2IKICAgIGV4dHJhY3QgNiAyCiAgICBzd2FwCiAgICBjb25jYXQKICAgIGJ5dGUgMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludCAxCiAgICByZXR1cm4KCm1haW5fdmVyaWZ5X2Fzc2V0X3BhcmFtc19nZXRfbWFuYWdlcl9yb3V0ZUA5OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjEyNwogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBpcyBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTo5MQogICAgLy8gY2xhc3MgU3RhdGVBc3NldFBhcmFtc0NvbnRyYWN0KEFSQzRDb250cmFjdCk6CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBidG9pCiAgICB0eG5hcyBBc3NldHMKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weToxMjcKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV9hc3NldF9wYXJhbXNfZ2V0X21hbmFnZXIKICAgIGR1cAogICAgbGVuCiAgICBpdG9iCiAgICBleHRyYWN0IDYgMgogICAgc3dhcAogICAgY29uY2F0CiAgICBieXRlIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnQgMQogICAgcmV0dXJuCgptYWluX3ZlcmlmeV9hc3NldF9wYXJhbXNfZ2V0X3Jlc2VydmVfcm91dGVAMTA6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6MTMyCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGlzIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjkxCiAgICAvLyBjbGFzcyBTdGF0ZUFzc2V0UGFyYW1zQ29udHJhY3QoQVJDNENvbnRyYWN0KToKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGJ0b2kKICAgIHR4bmFzIEFzc2V0cwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjEzMgogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X2Fzc2V0X3BhcmFtc19nZXRfcmVzZXJ2ZQogICAgZHVwCiAgICBsZW4KICAgIGl0b2IKICAgIGV4dHJhY3QgNiAyCiAgICBzd2FwCiAgICBjb25jYXQKICAgIGJ5dGUgMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludCAxCiAgICByZXR1cm4KCm1haW5fdmVyaWZ5X2Fzc2V0X3BhcmFtc19nZXRfZnJlZXplX3JvdXRlQDExOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjEzNwogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBpcyBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTo5MQogICAgLy8gY2xhc3MgU3RhdGVBc3NldFBhcmFtc0NvbnRyYWN0KEFSQzRDb250cmFjdCk6CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBidG9pCiAgICB0eG5hcyBBc3NldHMKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weToxMzcKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV9hc3NldF9wYXJhbXNfZ2V0X2ZyZWV6ZQogICAgZHVwCiAgICBsZW4KICAgIGl0b2IKICAgIGV4dHJhY3QgNiAyCiAgICBzd2FwCiAgICBjb25jYXQKICAgIGJ5dGUgMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludCAxCiAgICByZXR1cm4KCm1haW5fdmVyaWZ5X2Fzc2V0X3BhcmFtc19nZXRfY2xhd2JhY2tfcm91dGVAMTI6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6MTQyCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGlzIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjkxCiAgICAvLyBjbGFzcyBTdGF0ZUFzc2V0UGFyYW1zQ29udHJhY3QoQVJDNENvbnRyYWN0KToKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGJ0b2kKICAgIHR4bmFzIEFzc2V0cwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjE0MgogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X2Fzc2V0X3BhcmFtc19nZXRfY2xhd2JhY2sKICAgIGR1cAogICAgbGVuCiAgICBpdG9iCiAgICBleHRyYWN0IDYgMgogICAgc3dhcAogICAgY29uY2F0CiAgICBieXRlIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnQgMQogICAgcmV0dXJuCgptYWluX3ZlcmlmeV9hc3NldF9wYXJhbXNfZ2V0X2NyZWF0b3Jfcm91dGVAMTM6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6MTQ3CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGlzIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjkxCiAgICAvLyBjbGFzcyBTdGF0ZUFzc2V0UGFyYW1zQ29udHJhY3QoQVJDNENvbnRyYWN0KToKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGJ0b2kKICAgIHR4bmFzIEFzc2V0cwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjE0NwogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X2Fzc2V0X3BhcmFtc19nZXRfY3JlYXRvcgogICAgZHVwCiAgICBsZW4KICAgIGl0b2IKICAgIGV4dHJhY3QgNiAyCiAgICBzd2FwCiAgICBjb25jYXQKICAgIGJ5dGUgMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludCAxCiAgICByZXR1cm4KCm1haW5fYmFyZV9yb3V0aW5nQDE2OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjkxCiAgICAvLyBjbGFzcyBTdGF0ZUFzc2V0UGFyYW1zQ29udHJhY3QoQVJDNENvbnRyYWN0KToKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyByZWplY3QgdHJhbnNhY3Rpb24KICAgIHR4biBBcHBsaWNhdGlvbklECiAgICAhCiAgICBhc3NlcnQgLy8gaXMgY3JlYXRpbmcKICAgIGludCAxCiAgICByZXR1cm4KCgovLyB0ZXN0cy5hcnRpZmFjdHMuU3RhdGVPcHMuY29udHJhY3QuU3RhdGVBc3NldFBhcmFtc0NvbnRyYWN0LnZlcmlmeV9hc3NldF9wYXJhbXNfZ2V0X3RvdGFsKGE6IHVpbnQ2NCkgLT4gdWludDY0Ogp2ZXJpZnlfYXNzZXRfcGFyYW1zX2dldF90b3RhbDoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTo5Mi05MwogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIGRlZiB2ZXJpZnlfYXNzZXRfcGFyYW1zX2dldF90b3RhbChzZWxmLCBhOiBBc3NldCkgLT4gVUludDY0OgogICAgcHJvdG8gMSAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6OTQKICAgIC8vIHRvdGFsLCBfdmFsID0gb3AuQXNzZXRQYXJhbXNHZXQuYXNzZXRfdG90YWwoYSkKICAgIGZyYW1lX2RpZyAtMQogICAgYXNzZXRfcGFyYW1zX2dldCBBc3NldFRvdGFsCiAgICBwb3AKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTo5NQogICAgLy8gcmV0dXJuIHRvdGFsCiAgICByZXRzdWIKCgovLyB0ZXN0cy5hcnRpZmFjdHMuU3RhdGVPcHMuY29udHJhY3QuU3RhdGVBc3NldFBhcmFtc0NvbnRyYWN0LnZlcmlmeV9hc3NldF9wYXJhbXNfZ2V0X2RlY2ltYWxzKGE6IHVpbnQ2NCkgLT4gdWludDY0Ogp2ZXJpZnlfYXNzZXRfcGFyYW1zX2dldF9kZWNpbWFsczoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTo5Ny05OAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIGRlZiB2ZXJpZnlfYXNzZXRfcGFyYW1zX2dldF9kZWNpbWFscyhzZWxmLCBhOiBBc3NldCkgLT4gVUludDY0OgogICAgcHJvdG8gMSAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6OTkKICAgIC8vIGRlY2ltYWxzLCBfdmFsID0gb3AuQXNzZXRQYXJhbXNHZXQuYXNzZXRfZGVjaW1hbHMoYSkKICAgIGZyYW1lX2RpZyAtMQogICAgYXNzZXRfcGFyYW1zX2dldCBBc3NldERlY2ltYWxzCiAgICBwb3AKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weToxMDAKICAgIC8vIHJldHVybiBkZWNpbWFscwogICAgcmV0c3ViCgoKLy8gdGVzdHMuYXJ0aWZhY3RzLlN0YXRlT3BzLmNvbnRyYWN0LlN0YXRlQXNzZXRQYXJhbXNDb250cmFjdC52ZXJpZnlfYXNzZXRfcGFyYW1zX2dldF9kZWZhdWx0X2Zyb3plbihhOiB1aW50NjQpIC0+IHVpbnQ2NDoKdmVyaWZ5X2Fzc2V0X3BhcmFtc19nZXRfZGVmYXVsdF9mcm96ZW46CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6MTAyLTEwMwogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIGRlZiB2ZXJpZnlfYXNzZXRfcGFyYW1zX2dldF9kZWZhdWx0X2Zyb3plbihzZWxmLCBhOiBBc3NldCkgLT4gYm9vbDoKICAgIHByb3RvIDEgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjEwNAogICAgLy8gZGVmYXVsdF9mcm96ZW4sIF92YWwgPSBvcC5Bc3NldFBhcmFtc0dldC5hc3NldF9kZWZhdWx0X2Zyb3plbihhKQogICAgZnJhbWVfZGlnIC0xCiAgICBhc3NldF9wYXJhbXNfZ2V0IEFzc2V0RGVmYXVsdEZyb3plbgogICAgcG9wCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6MTA1CiAgICAvLyByZXR1cm4gZGVmYXVsdF9mcm96ZW4KICAgIHJldHN1YgoKCi8vIHRlc3RzLmFydGlmYWN0cy5TdGF0ZU9wcy5jb250cmFjdC5TdGF0ZUFzc2V0UGFyYW1zQ29udHJhY3QudmVyaWZ5X2Fzc2V0X3BhcmFtc19nZXRfdW5pdF9uYW1lKGE6IHVpbnQ2NCkgLT4gYnl0ZXM6CnZlcmlmeV9hc3NldF9wYXJhbXNfZ2V0X3VuaXRfbmFtZToKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weToxMDctMTA4CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gZGVmIHZlcmlmeV9hc3NldF9wYXJhbXNfZ2V0X3VuaXRfbmFtZShzZWxmLCBhOiBBc3NldCkgLT4gQnl0ZXM6CiAgICBwcm90byAxIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weToxMDkKICAgIC8vIHVuaXRfbmFtZSwgX3ZhbCA9IG9wLkFzc2V0UGFyYW1zR2V0LmFzc2V0X3VuaXRfbmFtZShhKQogICAgZnJhbWVfZGlnIC0xCiAgICBhc3NldF9wYXJhbXNfZ2V0IEFzc2V0VW5pdE5hbWUKICAgIHBvcAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjExMAogICAgLy8gcmV0dXJuIHVuaXRfbmFtZQogICAgcmV0c3ViCgoKLy8gdGVzdHMuYXJ0aWZhY3RzLlN0YXRlT3BzLmNvbnRyYWN0LlN0YXRlQXNzZXRQYXJhbXNDb250cmFjdC52ZXJpZnlfYXNzZXRfcGFyYW1zX2dldF9uYW1lKGE6IHVpbnQ2NCkgLT4gYnl0ZXM6CnZlcmlmeV9hc3NldF9wYXJhbXNfZ2V0X25hbWU6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6MTEyLTExMwogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIGRlZiB2ZXJpZnlfYXNzZXRfcGFyYW1zX2dldF9uYW1lKHNlbGYsIGE6IEFzc2V0KSAtPiBCeXRlczoKICAgIHByb3RvIDEgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjExNAogICAgLy8gbmFtZSwgX3ZhbCA9IG9wLkFzc2V0UGFyYW1zR2V0LmFzc2V0X25hbWUoYSkKICAgIGZyYW1lX2RpZyAtMQogICAgYXNzZXRfcGFyYW1zX2dldCBBc3NldE5hbWUKICAgIHBvcAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjExNQogICAgLy8gcmV0dXJuIG5hbWUKICAgIHJldHN1YgoKCi8vIHRlc3RzLmFydGlmYWN0cy5TdGF0ZU9wcy5jb250cmFjdC5TdGF0ZUFzc2V0UGFyYW1zQ29udHJhY3QudmVyaWZ5X2Fzc2V0X3BhcmFtc19nZXRfdXJsKGE6IHVpbnQ2NCkgLT4gYnl0ZXM6CnZlcmlmeV9hc3NldF9wYXJhbXNfZ2V0X3VybDoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weToxMTctMTE4CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gZGVmIHZlcmlmeV9hc3NldF9wYXJhbXNfZ2V0X3VybChzZWxmLCBhOiBBc3NldCkgLT4gQnl0ZXM6CiAgICBwcm90byAxIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weToxMTkKICAgIC8vIHVybCwgX3ZhbCA9IG9wLkFzc2V0UGFyYW1zR2V0LmFzc2V0X3VybChhKQogICAgZnJhbWVfZGlnIC0xCiAgICBhc3NldF9wYXJhbXNfZ2V0IEFzc2V0VVJMCiAgICBwb3AKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weToxMjAKICAgIC8vIHJldHVybiB1cmwKICAgIHJldHN1YgoKCi8vIHRlc3RzLmFydGlmYWN0cy5TdGF0ZU9wcy5jb250cmFjdC5TdGF0ZUFzc2V0UGFyYW1zQ29udHJhY3QudmVyaWZ5X2Fzc2V0X3BhcmFtc19nZXRfbWV0YWRhdGFfaGFzaChhOiB1aW50NjQpIC0+IGJ5dGVzOgp2ZXJpZnlfYXNzZXRfcGFyYW1zX2dldF9tZXRhZGF0YV9oYXNoOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjEyMi0xMjMKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBkZWYgdmVyaWZ5X2Fzc2V0X3BhcmFtc19nZXRfbWV0YWRhdGFfaGFzaChzZWxmLCBhOiBBc3NldCkgLT4gQnl0ZXM6CiAgICBwcm90byAxIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weToxMjQKICAgIC8vIG1ldGFkYXRhX2hhc2gsIF92YWwgPSBvcC5Bc3NldFBhcmFtc0dldC5hc3NldF9tZXRhZGF0YV9oYXNoKGEpCiAgICBmcmFtZV9kaWcgLTEKICAgIGFzc2V0X3BhcmFtc19nZXQgQXNzZXRNZXRhZGF0YUhhc2gKICAgIHBvcAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjEyNQogICAgLy8gcmV0dXJuIG1ldGFkYXRhX2hhc2gKICAgIHJldHN1YgoKCi8vIHRlc3RzLmFydGlmYWN0cy5TdGF0ZU9wcy5jb250cmFjdC5TdGF0ZUFzc2V0UGFyYW1zQ29udHJhY3QudmVyaWZ5X2Fzc2V0X3BhcmFtc19nZXRfbWFuYWdlcihhOiB1aW50NjQpIC0+IGJ5dGVzOgp2ZXJpZnlfYXNzZXRfcGFyYW1zX2dldF9tYW5hZ2VyOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjEyNy0xMjgKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBkZWYgdmVyaWZ5X2Fzc2V0X3BhcmFtc19nZXRfbWFuYWdlcihzZWxmLCBhOiBBc3NldCkgLT4gQnl0ZXM6CiAgICBwcm90byAxIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weToxMjkKICAgIC8vIG1hbmFnZXIsIF92YWwgPSBvcC5Bc3NldFBhcmFtc0dldC5hc3NldF9tYW5hZ2VyKGEpCiAgICBmcmFtZV9kaWcgLTEKICAgIGFzc2V0X3BhcmFtc19nZXQgQXNzZXRNYW5hZ2VyCiAgICBwb3AKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weToxMzAKICAgIC8vIHJldHVybiBtYW5hZ2VyLmJ5dGVzCiAgICByZXRzdWIKCgovLyB0ZXN0cy5hcnRpZmFjdHMuU3RhdGVPcHMuY29udHJhY3QuU3RhdGVBc3NldFBhcmFtc0NvbnRyYWN0LnZlcmlmeV9hc3NldF9wYXJhbXNfZ2V0X3Jlc2VydmUoYTogdWludDY0KSAtPiBieXRlczoKdmVyaWZ5X2Fzc2V0X3BhcmFtc19nZXRfcmVzZXJ2ZToKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weToxMzItMTMzCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gZGVmIHZlcmlmeV9hc3NldF9wYXJhbXNfZ2V0X3Jlc2VydmUoc2VsZiwgYTogQXNzZXQpIC0+IEJ5dGVzOgogICAgcHJvdG8gMSAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6MTM0CiAgICAvLyByZXNlcnZlLCBfdmFsID0gb3AuQXNzZXRQYXJhbXNHZXQuYXNzZXRfcmVzZXJ2ZShhKQogICAgZnJhbWVfZGlnIC0xCiAgICBhc3NldF9wYXJhbXNfZ2V0IEFzc2V0UmVzZXJ2ZQogICAgcG9wCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6MTM1CiAgICAvLyByZXR1cm4gcmVzZXJ2ZS5ieXRlcwogICAgcmV0c3ViCgoKLy8gdGVzdHMuYXJ0aWZhY3RzLlN0YXRlT3BzLmNvbnRyYWN0LlN0YXRlQXNzZXRQYXJhbXNDb250cmFjdC52ZXJpZnlfYXNzZXRfcGFyYW1zX2dldF9mcmVlemUoYTogdWludDY0KSAtPiBieXRlczoKdmVyaWZ5X2Fzc2V0X3BhcmFtc19nZXRfZnJlZXplOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjEzNy0xMzgKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBkZWYgdmVyaWZ5X2Fzc2V0X3BhcmFtc19nZXRfZnJlZXplKHNlbGYsIGE6IEFzc2V0KSAtPiBCeXRlczoKICAgIHByb3RvIDEgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjEzOQogICAgLy8gZnJlZXplLCBfdmFsID0gb3AuQXNzZXRQYXJhbXNHZXQuYXNzZXRfZnJlZXplKGEpCiAgICBmcmFtZV9kaWcgLTEKICAgIGFzc2V0X3BhcmFtc19nZXQgQXNzZXRGcmVlemUKICAgIHBvcAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjE0MAogICAgLy8gcmV0dXJuIGZyZWV6ZS5ieXRlcwogICAgcmV0c3ViCgoKLy8gdGVzdHMuYXJ0aWZhY3RzLlN0YXRlT3BzLmNvbnRyYWN0LlN0YXRlQXNzZXRQYXJhbXNDb250cmFjdC52ZXJpZnlfYXNzZXRfcGFyYW1zX2dldF9jbGF3YmFjayhhOiB1aW50NjQpIC0+IGJ5dGVzOgp2ZXJpZnlfYXNzZXRfcGFyYW1zX2dldF9jbGF3YmFjazoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weToxNDItMTQzCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gZGVmIHZlcmlmeV9hc3NldF9wYXJhbXNfZ2V0X2NsYXdiYWNrKHNlbGYsIGE6IEFzc2V0KSAtPiBCeXRlczoKICAgIHByb3RvIDEgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjE0NAogICAgLy8gY2xhd2JhY2ssIF92YWwgPSBvcC5Bc3NldFBhcmFtc0dldC5hc3NldF9jbGF3YmFjayhhKQogICAgZnJhbWVfZGlnIC0xCiAgICBhc3NldF9wYXJhbXNfZ2V0IEFzc2V0Q2xhd2JhY2sKICAgIHBvcAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjE0NQogICAgLy8gcmV0dXJuIGNsYXdiYWNrLmJ5dGVzCiAgICByZXRzdWIKCgovLyB0ZXN0cy5hcnRpZmFjdHMuU3RhdGVPcHMuY29udHJhY3QuU3RhdGVBc3NldFBhcmFtc0NvbnRyYWN0LnZlcmlmeV9hc3NldF9wYXJhbXNfZ2V0X2NyZWF0b3IoYTogdWludDY0KSAtPiBieXRlczoKdmVyaWZ5X2Fzc2V0X3BhcmFtc19nZXRfY3JlYXRvcjoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weToxNDctMTQ4CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gZGVmIHZlcmlmeV9hc3NldF9wYXJhbXNfZ2V0X2NyZWF0b3Ioc2VsZiwgYTogQXNzZXQpIC0+IEJ5dGVzOgogICAgcHJvdG8gMSAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6MTQ5CiAgICAvLyBjcmVhdG9yLCBfdmFsID0gb3AuQXNzZXRQYXJhbXNHZXQuYXNzZXRfY3JlYXRvcihhKQogICAgZnJhbWVfZGlnIC0xCiAgICBhc3NldF9wYXJhbXNfZ2V0IEFzc2V0Q3JlYXRvcgogICAgcG9wCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6MTUwCiAgICAvLyByZXR1cm4gY3JlYXRvci5ieXRlcwogICAgcmV0c3ViCg==", - "clear": "I3ByYWdtYSB2ZXJzaW9uIDEwCgp0ZXN0cy5hcnRpZmFjdHMuU3RhdGVPcHMuY29udHJhY3QuU3RhdGVBc3NldFBhcmFtc0NvbnRyYWN0LmNsZWFyX3N0YXRlX3Byb2dyYW06CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6OTEKICAgIC8vIGNsYXNzIFN0YXRlQXNzZXRQYXJhbXNDb250cmFjdChBUkM0Q29udHJhY3QpOgogICAgaW50IDEKICAgIHJldHVybgo=" + "approval": "I3ByYWdtYSB2ZXJzaW9uIDEwCgp0ZXN0cy5hcnRpZmFjdHMuU3RhdGVPcHMuY29udHJhY3QuU3RhdGVBc3NldFBhcmFtc0NvbnRyYWN0LmFwcHJvdmFsX3Byb2dyYW06CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6MTQwCiAgICAvLyBjbGFzcyBTdGF0ZUFzc2V0UGFyYW1zQ29udHJhY3QoQVJDNENvbnRyYWN0KToKICAgIHR4biBOdW1BcHBBcmdzCiAgICBieiBtYWluX2JhcmVfcm91dGluZ0AxNgogICAgbWV0aG9kICJ2ZXJpZnlfYXNzZXRfcGFyYW1zX2dldF90b3RhbChhc3NldCl1aW50NjQiCiAgICBtZXRob2QgInZlcmlmeV9hc3NldF9wYXJhbXNfZ2V0X2RlY2ltYWxzKGFzc2V0KXVpbnQ2NCIKICAgIG1ldGhvZCAidmVyaWZ5X2Fzc2V0X3BhcmFtc19nZXRfZGVmYXVsdF9mcm96ZW4oYXNzZXQpYm9vbCIKICAgIG1ldGhvZCAidmVyaWZ5X2Fzc2V0X3BhcmFtc19nZXRfdW5pdF9uYW1lKGFzc2V0KWJ5dGVbXSIKICAgIG1ldGhvZCAidmVyaWZ5X2Fzc2V0X3BhcmFtc19nZXRfbmFtZShhc3NldClieXRlW10iCiAgICBtZXRob2QgInZlcmlmeV9hc3NldF9wYXJhbXNfZ2V0X3VybChhc3NldClieXRlW10iCiAgICBtZXRob2QgInZlcmlmeV9hc3NldF9wYXJhbXNfZ2V0X21ldGFkYXRhX2hhc2goYXNzZXQpYnl0ZVtdIgogICAgbWV0aG9kICJ2ZXJpZnlfYXNzZXRfcGFyYW1zX2dldF9tYW5hZ2VyKGFzc2V0KWFkZHJlc3MiCiAgICBtZXRob2QgInZlcmlmeV9hc3NldF9wYXJhbXNfZ2V0X3Jlc2VydmUoYXNzZXQpYWRkcmVzcyIKICAgIG1ldGhvZCAidmVyaWZ5X2Fzc2V0X3BhcmFtc19nZXRfZnJlZXplKGFzc2V0KWFkZHJlc3MiCiAgICBtZXRob2QgInZlcmlmeV9hc3NldF9wYXJhbXNfZ2V0X2NsYXdiYWNrKGFzc2V0KWFkZHJlc3MiCiAgICBtZXRob2QgInZlcmlmeV9hc3NldF9wYXJhbXNfZ2V0X2NyZWF0b3IoYXNzZXQpYWRkcmVzcyIKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDAKICAgIG1hdGNoIG1haW5fdmVyaWZ5X2Fzc2V0X3BhcmFtc19nZXRfdG90YWxfcm91dGVAMiBtYWluX3ZlcmlmeV9hc3NldF9wYXJhbXNfZ2V0X2RlY2ltYWxzX3JvdXRlQDMgbWFpbl92ZXJpZnlfYXNzZXRfcGFyYW1zX2dldF9kZWZhdWx0X2Zyb3plbl9yb3V0ZUA0IG1haW5fdmVyaWZ5X2Fzc2V0X3BhcmFtc19nZXRfdW5pdF9uYW1lX3JvdXRlQDUgbWFpbl92ZXJpZnlfYXNzZXRfcGFyYW1zX2dldF9uYW1lX3JvdXRlQDYgbWFpbl92ZXJpZnlfYXNzZXRfcGFyYW1zX2dldF91cmxfcm91dGVANyBtYWluX3ZlcmlmeV9hc3NldF9wYXJhbXNfZ2V0X21ldGFkYXRhX2hhc2hfcm91dGVAOCBtYWluX3ZlcmlmeV9hc3NldF9wYXJhbXNfZ2V0X21hbmFnZXJfcm91dGVAOSBtYWluX3ZlcmlmeV9hc3NldF9wYXJhbXNfZ2V0X3Jlc2VydmVfcm91dGVAMTAgbWFpbl92ZXJpZnlfYXNzZXRfcGFyYW1zX2dldF9mcmVlemVfcm91dGVAMTEgbWFpbl92ZXJpZnlfYXNzZXRfcGFyYW1zX2dldF9jbGF3YmFja19yb3V0ZUAxMiBtYWluX3ZlcmlmeV9hc3NldF9wYXJhbXNfZ2V0X2NyZWF0b3Jfcm91dGVAMTMKICAgIGVyciAvLyByZWplY3QgdHJhbnNhY3Rpb24KCm1haW5fdmVyaWZ5X2Fzc2V0X3BhcmFtc19nZXRfdG90YWxfcm91dGVAMjoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weToxNDEKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gaXMgbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6MTQwCiAgICAvLyBjbGFzcyBTdGF0ZUFzc2V0UGFyYW1zQ29udHJhY3QoQVJDNENvbnRyYWN0KToKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGJ0b2kKICAgIHR4bmFzIEFzc2V0cwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjE0MQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X2Fzc2V0X3BhcmFtc19nZXRfdG90YWwKICAgIGl0b2IKICAgIGJ5dGUgMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludCAxCiAgICByZXR1cm4KCm1haW5fdmVyaWZ5X2Fzc2V0X3BhcmFtc19nZXRfZGVjaW1hbHNfcm91dGVAMzoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weToxNDkKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gaXMgbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6MTQwCiAgICAvLyBjbGFzcyBTdGF0ZUFzc2V0UGFyYW1zQ29udHJhY3QoQVJDNENvbnRyYWN0KToKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGJ0b2kKICAgIHR4bmFzIEFzc2V0cwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjE0OQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X2Fzc2V0X3BhcmFtc19nZXRfZGVjaW1hbHMKICAgIGl0b2IKICAgIGJ5dGUgMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludCAxCiAgICByZXR1cm4KCm1haW5fdmVyaWZ5X2Fzc2V0X3BhcmFtc19nZXRfZGVmYXVsdF9mcm96ZW5fcm91dGVANDoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weToxNTcKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gaXMgbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6MTQwCiAgICAvLyBjbGFzcyBTdGF0ZUFzc2V0UGFyYW1zQ29udHJhY3QoQVJDNENvbnRyYWN0KToKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGJ0b2kKICAgIHR4bmFzIEFzc2V0cwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjE1NwogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X2Fzc2V0X3BhcmFtc19nZXRfZGVmYXVsdF9mcm96ZW4KICAgIGJ5dGUgMHgwMAogICAgaW50IDAKICAgIHVuY292ZXIgMgogICAgc2V0Yml0CiAgICBieXRlIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnQgMQogICAgcmV0dXJuCgptYWluX3ZlcmlmeV9hc3NldF9wYXJhbXNfZ2V0X3VuaXRfbmFtZV9yb3V0ZUA1OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjE2NQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBpcyBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weToxNDAKICAgIC8vIGNsYXNzIFN0YXRlQXNzZXRQYXJhbXNDb250cmFjdChBUkM0Q29udHJhY3QpOgogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgYnRvaQogICAgdHhuYXMgQXNzZXRzCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6MTY1CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfYXNzZXRfcGFyYW1zX2dldF91bml0X25hbWUKICAgIGR1cAogICAgbGVuCiAgICBpdG9iCiAgICBleHRyYWN0IDYgMgogICAgc3dhcAogICAgY29uY2F0CiAgICBieXRlIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnQgMQogICAgcmV0dXJuCgptYWluX3ZlcmlmeV9hc3NldF9wYXJhbXNfZ2V0X25hbWVfcm91dGVANjoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weToxNzMKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gaXMgbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6MTQwCiAgICAvLyBjbGFzcyBTdGF0ZUFzc2V0UGFyYW1zQ29udHJhY3QoQVJDNENvbnRyYWN0KToKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGJ0b2kKICAgIHR4bmFzIEFzc2V0cwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjE3MwogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X2Fzc2V0X3BhcmFtc19nZXRfbmFtZQogICAgZHVwCiAgICBsZW4KICAgIGl0b2IKICAgIGV4dHJhY3QgNiAyCiAgICBzd2FwCiAgICBjb25jYXQKICAgIGJ5dGUgMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludCAxCiAgICByZXR1cm4KCm1haW5fdmVyaWZ5X2Fzc2V0X3BhcmFtc19nZXRfdXJsX3JvdXRlQDc6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6MTgxCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGlzIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjE0MAogICAgLy8gY2xhc3MgU3RhdGVBc3NldFBhcmFtc0NvbnRyYWN0KEFSQzRDb250cmFjdCk6CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBidG9pCiAgICB0eG5hcyBBc3NldHMKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weToxODEKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV9hc3NldF9wYXJhbXNfZ2V0X3VybAogICAgZHVwCiAgICBsZW4KICAgIGl0b2IKICAgIGV4dHJhY3QgNiAyCiAgICBzd2FwCiAgICBjb25jYXQKICAgIGJ5dGUgMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludCAxCiAgICByZXR1cm4KCm1haW5fdmVyaWZ5X2Fzc2V0X3BhcmFtc19nZXRfbWV0YWRhdGFfaGFzaF9yb3V0ZUA4OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjE4OQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBpcyBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weToxNDAKICAgIC8vIGNsYXNzIFN0YXRlQXNzZXRQYXJhbXNDb250cmFjdChBUkM0Q29udHJhY3QpOgogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgYnRvaQogICAgdHhuYXMgQXNzZXRzCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6MTg5CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfYXNzZXRfcGFyYW1zX2dldF9tZXRhZGF0YV9oYXNoCiAgICBkdXAKICAgIGxlbgogICAgaXRvYgogICAgZXh0cmFjdCA2IDIKICAgIHN3YXAKICAgIGNvbmNhdAogICAgYnl0ZSAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50IDEKICAgIHJldHVybgoKbWFpbl92ZXJpZnlfYXNzZXRfcGFyYW1zX2dldF9tYW5hZ2VyX3JvdXRlQDk6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6MTk3CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGlzIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjE0MAogICAgLy8gY2xhc3MgU3RhdGVBc3NldFBhcmFtc0NvbnRyYWN0KEFSQzRDb250cmFjdCk6CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBidG9pCiAgICB0eG5hcyBBc3NldHMKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weToxOTcKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV9hc3NldF9wYXJhbXNfZ2V0X21hbmFnZXIKICAgIGJ5dGUgMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludCAxCiAgICByZXR1cm4KCm1haW5fdmVyaWZ5X2Fzc2V0X3BhcmFtc19nZXRfcmVzZXJ2ZV9yb3V0ZUAxMDoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weToyMDUKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gaXMgbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6MTQwCiAgICAvLyBjbGFzcyBTdGF0ZUFzc2V0UGFyYW1zQ29udHJhY3QoQVJDNENvbnRyYWN0KToKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGJ0b2kKICAgIHR4bmFzIEFzc2V0cwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjIwNQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X2Fzc2V0X3BhcmFtc19nZXRfcmVzZXJ2ZQogICAgYnl0ZSAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50IDEKICAgIHJldHVybgoKbWFpbl92ZXJpZnlfYXNzZXRfcGFyYW1zX2dldF9mcmVlemVfcm91dGVAMTE6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6MjEzCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGlzIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjE0MAogICAgLy8gY2xhc3MgU3RhdGVBc3NldFBhcmFtc0NvbnRyYWN0KEFSQzRDb250cmFjdCk6CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBidG9pCiAgICB0eG5hcyBBc3NldHMKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weToyMTMKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV9hc3NldF9wYXJhbXNfZ2V0X2ZyZWV6ZQogICAgYnl0ZSAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50IDEKICAgIHJldHVybgoKbWFpbl92ZXJpZnlfYXNzZXRfcGFyYW1zX2dldF9jbGF3YmFja19yb3V0ZUAxMjoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weToyMjEKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gaXMgbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6MTQwCiAgICAvLyBjbGFzcyBTdGF0ZUFzc2V0UGFyYW1zQ29udHJhY3QoQVJDNENvbnRyYWN0KToKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGJ0b2kKICAgIHR4bmFzIEFzc2V0cwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjIyMQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X2Fzc2V0X3BhcmFtc19nZXRfY2xhd2JhY2sKICAgIGJ5dGUgMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludCAxCiAgICByZXR1cm4KCm1haW5fdmVyaWZ5X2Fzc2V0X3BhcmFtc19nZXRfY3JlYXRvcl9yb3V0ZUAxMzoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weToyMjkKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gaXMgbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6MTQwCiAgICAvLyBjbGFzcyBTdGF0ZUFzc2V0UGFyYW1zQ29udHJhY3QoQVJDNENvbnRyYWN0KToKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGJ0b2kKICAgIHR4bmFzIEFzc2V0cwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjIyOQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X2Fzc2V0X3BhcmFtc19nZXRfY3JlYXRvcgogICAgYnl0ZSAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50IDEKICAgIHJldHVybgoKbWFpbl9iYXJlX3JvdXRpbmdAMTY6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6MTQwCiAgICAvLyBjbGFzcyBTdGF0ZUFzc2V0UGFyYW1zQ29udHJhY3QoQVJDNENvbnRyYWN0KToKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyByZWplY3QgdHJhbnNhY3Rpb24KICAgIHR4biBBcHBsaWNhdGlvbklECiAgICAhCiAgICBhc3NlcnQgLy8gaXMgY3JlYXRpbmcKICAgIGludCAxCiAgICByZXR1cm4KCgovLyB0ZXN0cy5hcnRpZmFjdHMuU3RhdGVPcHMuY29udHJhY3QuU3RhdGVBc3NldFBhcmFtc0NvbnRyYWN0LnZlcmlmeV9hc3NldF9wYXJhbXNfZ2V0X3RvdGFsKGE6IHVpbnQ2NCkgLT4gdWludDY0Ogp2ZXJpZnlfYXNzZXRfcGFyYW1zX2dldF90b3RhbDoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weToxNDEtMTQyCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gZGVmIHZlcmlmeV9hc3NldF9wYXJhbXNfZ2V0X3RvdGFsKHNlbGYsIGE6IEFzc2V0KSAtPiBVSW50NjQ6CiAgICBwcm90byAxIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weToxNDMKICAgIC8vIHZhbHVlLCBleGlzdHMgPSBvcC5Bc3NldFBhcmFtc0dldC5hc3NldF90b3RhbChhKQogICAgZnJhbWVfZGlnIC0xCiAgICBhc3NldF9wYXJhbXNfZ2V0IEFzc2V0VG90YWwKICAgIHN3YXAKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weToxNDQKICAgIC8vIHZhbHVlX2luZGV4LCBleGlzdHNfaW5kZXggPSBvcC5Bc3NldFBhcmFtc0dldC5hc3NldF90b3RhbChfZ2V0XzFzdF9yZWZfaW5kZXgoKSkKICAgIGNhbGxzdWIgX2dldF8xc3RfcmVmX2luZGV4CiAgICBhc3NldF9wYXJhbXNfZ2V0IEFzc2V0VG90YWwKICAgIGNvdmVyIDIKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weToxNDUKICAgIC8vIGFzc2VydCB2YWx1ZSA9PSB2YWx1ZV9pbmRleCwgImV4cGVjdGVkIHZhbHVlIGJ5IGluZGV4IHRvIG1hdGNoIgogICAgZGlnIDEKICAgID09CiAgICBhc3NlcnQgLy8gZXhwZWN0ZWQgdmFsdWUgYnkgaW5kZXggdG8gbWF0Y2gKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weToxNDYKICAgIC8vIGFzc2VydCBleGlzdHMgPT0gZXhpc3RzX2luZGV4LCAiZXhwZWN0ZWQgZXhpc3RzIGJ5IGluZGV4IHRvIG1hdGNoIgogICAgY292ZXIgMgogICAgPT0KICAgIGFzc2VydCAvLyBleHBlY3RlZCBleGlzdHMgYnkgaW5kZXggdG8gbWF0Y2gKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weToxNDcKICAgIC8vIHJldHVybiB2YWx1ZQogICAgcmV0c3ViCgoKLy8gdGVzdHMuYXJ0aWZhY3RzLlN0YXRlT3BzLmNvbnRyYWN0Ll9nZXRfMXN0X3JlZl9pbmRleCgpIC0+IHVpbnQ2NDoKX2dldF8xc3RfcmVmX2luZGV4OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjE5LTIwCiAgICAvLyBAc3Vicm91dGluZQogICAgLy8gZGVmIF9nZXRfMXN0X3JlZl9pbmRleCgpIC0+IFVJbnQ2NDoKICAgIHByb3RvIDAgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjIxCiAgICAvLyByZXR1cm4gb3AuYnRvaShUeG4uYXBwbGljYXRpb25fYXJncygxKSkKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGJ0b2kKICAgIHJldHN1YgoKCi8vIHRlc3RzLmFydGlmYWN0cy5TdGF0ZU9wcy5jb250cmFjdC5TdGF0ZUFzc2V0UGFyYW1zQ29udHJhY3QudmVyaWZ5X2Fzc2V0X3BhcmFtc19nZXRfZGVjaW1hbHMoYTogdWludDY0KSAtPiB1aW50NjQ6CnZlcmlmeV9hc3NldF9wYXJhbXNfZ2V0X2RlY2ltYWxzOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjE0OS0xNTAKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBkZWYgdmVyaWZ5X2Fzc2V0X3BhcmFtc19nZXRfZGVjaW1hbHMoc2VsZiwgYTogQXNzZXQpIC0+IFVJbnQ2NDoKICAgIHByb3RvIDEgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjE1MQogICAgLy8gdmFsdWUsIGV4aXN0cyA9IG9wLkFzc2V0UGFyYW1zR2V0LmFzc2V0X2RlY2ltYWxzKGEpCiAgICBmcmFtZV9kaWcgLTEKICAgIGFzc2V0X3BhcmFtc19nZXQgQXNzZXREZWNpbWFscwogICAgc3dhcAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjE1MgogICAgLy8gdmFsdWVfaW5kZXgsIGV4aXN0c19pbmRleCA9IG9wLkFzc2V0UGFyYW1zR2V0LmFzc2V0X2RlY2ltYWxzKF9nZXRfMXN0X3JlZl9pbmRleCgpKQogICAgY2FsbHN1YiBfZ2V0XzFzdF9yZWZfaW5kZXgKICAgIGFzc2V0X3BhcmFtc19nZXQgQXNzZXREZWNpbWFscwogICAgY292ZXIgMgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjE1MwogICAgLy8gYXNzZXJ0IHZhbHVlID09IHZhbHVlX2luZGV4LCAiZXhwZWN0ZWQgdmFsdWUgYnkgaW5kZXggdG8gbWF0Y2giCiAgICBkaWcgMQogICAgPT0KICAgIGFzc2VydCAvLyBleHBlY3RlZCB2YWx1ZSBieSBpbmRleCB0byBtYXRjaAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjE1NAogICAgLy8gYXNzZXJ0IGV4aXN0cyA9PSBleGlzdHNfaW5kZXgsICJleHBlY3RlZCBleGlzdHMgYnkgaW5kZXggdG8gbWF0Y2giCiAgICBjb3ZlciAyCiAgICA9PQogICAgYXNzZXJ0IC8vIGV4cGVjdGVkIGV4aXN0cyBieSBpbmRleCB0byBtYXRjaAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjE1NQogICAgLy8gcmV0dXJuIHZhbHVlCiAgICByZXRzdWIKCgovLyB0ZXN0cy5hcnRpZmFjdHMuU3RhdGVPcHMuY29udHJhY3QuU3RhdGVBc3NldFBhcmFtc0NvbnRyYWN0LnZlcmlmeV9hc3NldF9wYXJhbXNfZ2V0X2RlZmF1bHRfZnJvemVuKGE6IHVpbnQ2NCkgLT4gdWludDY0Ogp2ZXJpZnlfYXNzZXRfcGFyYW1zX2dldF9kZWZhdWx0X2Zyb3plbjoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weToxNTctMTU4CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gZGVmIHZlcmlmeV9hc3NldF9wYXJhbXNfZ2V0X2RlZmF1bHRfZnJvemVuKHNlbGYsIGE6IEFzc2V0KSAtPiBib29sOgogICAgcHJvdG8gMSAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6MTU5CiAgICAvLyB2YWx1ZSwgZXhpc3RzID0gb3AuQXNzZXRQYXJhbXNHZXQuYXNzZXRfZGVmYXVsdF9mcm96ZW4oYSkKICAgIGZyYW1lX2RpZyAtMQogICAgYXNzZXRfcGFyYW1zX2dldCBBc3NldERlZmF1bHRGcm96ZW4KICAgIHN3YXAKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weToxNjAKICAgIC8vIHZhbHVlX2luZGV4LCBleGlzdHNfaW5kZXggPSBvcC5Bc3NldFBhcmFtc0dldC5hc3NldF9kZWZhdWx0X2Zyb3plbihfZ2V0XzFzdF9yZWZfaW5kZXgoKSkKICAgIGNhbGxzdWIgX2dldF8xc3RfcmVmX2luZGV4CiAgICBhc3NldF9wYXJhbXNfZ2V0IEFzc2V0RGVmYXVsdEZyb3plbgogICAgY292ZXIgMgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjE2MQogICAgLy8gYXNzZXJ0IHZhbHVlID09IHZhbHVlX2luZGV4LCAiZXhwZWN0ZWQgdmFsdWUgYnkgaW5kZXggdG8gbWF0Y2giCiAgICBkaWcgMQogICAgPT0KICAgIGFzc2VydCAvLyBleHBlY3RlZCB2YWx1ZSBieSBpbmRleCB0byBtYXRjaAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjE2MgogICAgLy8gYXNzZXJ0IGV4aXN0cyA9PSBleGlzdHNfaW5kZXgsICJleHBlY3RlZCBleGlzdHMgYnkgaW5kZXggdG8gbWF0Y2giCiAgICBjb3ZlciAyCiAgICA9PQogICAgYXNzZXJ0IC8vIGV4cGVjdGVkIGV4aXN0cyBieSBpbmRleCB0byBtYXRjaAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjE2MwogICAgLy8gcmV0dXJuIHZhbHVlCiAgICByZXRzdWIKCgovLyB0ZXN0cy5hcnRpZmFjdHMuU3RhdGVPcHMuY29udHJhY3QuU3RhdGVBc3NldFBhcmFtc0NvbnRyYWN0LnZlcmlmeV9hc3NldF9wYXJhbXNfZ2V0X3VuaXRfbmFtZShhOiB1aW50NjQpIC0+IGJ5dGVzOgp2ZXJpZnlfYXNzZXRfcGFyYW1zX2dldF91bml0X25hbWU6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6MTY1LTE2NgogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIGRlZiB2ZXJpZnlfYXNzZXRfcGFyYW1zX2dldF91bml0X25hbWUoc2VsZiwgYTogQXNzZXQpIC0+IEJ5dGVzOgogICAgcHJvdG8gMSAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6MTY3CiAgICAvLyB2YWx1ZSwgZXhpc3RzID0gb3AuQXNzZXRQYXJhbXNHZXQuYXNzZXRfdW5pdF9uYW1lKGEpCiAgICBmcmFtZV9kaWcgLTEKICAgIGFzc2V0X3BhcmFtc19nZXQgQXNzZXRVbml0TmFtZQogICAgc3dhcAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjE2OAogICAgLy8gdmFsdWVfaW5kZXgsIGV4aXN0c19pbmRleCA9IG9wLkFzc2V0UGFyYW1zR2V0LmFzc2V0X3VuaXRfbmFtZShfZ2V0XzFzdF9yZWZfaW5kZXgoKSkKICAgIGNhbGxzdWIgX2dldF8xc3RfcmVmX2luZGV4CiAgICBhc3NldF9wYXJhbXNfZ2V0IEFzc2V0VW5pdE5hbWUKICAgIGNvdmVyIDIKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weToxNjkKICAgIC8vIGFzc2VydCB2YWx1ZSA9PSB2YWx1ZV9pbmRleCwgImV4cGVjdGVkIHZhbHVlIGJ5IGluZGV4IHRvIG1hdGNoIgogICAgZGlnIDEKICAgID09CiAgICBhc3NlcnQgLy8gZXhwZWN0ZWQgdmFsdWUgYnkgaW5kZXggdG8gbWF0Y2gKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weToxNzAKICAgIC8vIGFzc2VydCBleGlzdHMgPT0gZXhpc3RzX2luZGV4LCAiZXhwZWN0ZWQgZXhpc3RzIGJ5IGluZGV4IHRvIG1hdGNoIgogICAgY292ZXIgMgogICAgPT0KICAgIGFzc2VydCAvLyBleHBlY3RlZCBleGlzdHMgYnkgaW5kZXggdG8gbWF0Y2gKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weToxNzEKICAgIC8vIHJldHVybiB2YWx1ZQogICAgcmV0c3ViCgoKLy8gdGVzdHMuYXJ0aWZhY3RzLlN0YXRlT3BzLmNvbnRyYWN0LlN0YXRlQXNzZXRQYXJhbXNDb250cmFjdC52ZXJpZnlfYXNzZXRfcGFyYW1zX2dldF9uYW1lKGE6IHVpbnQ2NCkgLT4gYnl0ZXM6CnZlcmlmeV9hc3NldF9wYXJhbXNfZ2V0X25hbWU6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6MTczLTE3NAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIGRlZiB2ZXJpZnlfYXNzZXRfcGFyYW1zX2dldF9uYW1lKHNlbGYsIGE6IEFzc2V0KSAtPiBCeXRlczoKICAgIHByb3RvIDEgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjE3NQogICAgLy8gdmFsdWUsIGV4aXN0cyA9IG9wLkFzc2V0UGFyYW1zR2V0LmFzc2V0X25hbWUoYSkKICAgIGZyYW1lX2RpZyAtMQogICAgYXNzZXRfcGFyYW1zX2dldCBBc3NldE5hbWUKICAgIHN3YXAKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weToxNzYKICAgIC8vIHZhbHVlX2luZGV4LCBleGlzdHNfaW5kZXggPSBvcC5Bc3NldFBhcmFtc0dldC5hc3NldF9uYW1lKF9nZXRfMXN0X3JlZl9pbmRleCgpKQogICAgY2FsbHN1YiBfZ2V0XzFzdF9yZWZfaW5kZXgKICAgIGFzc2V0X3BhcmFtc19nZXQgQXNzZXROYW1lCiAgICBjb3ZlciAyCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6MTc3CiAgICAvLyBhc3NlcnQgdmFsdWUgPT0gdmFsdWVfaW5kZXgsICJleHBlY3RlZCB2YWx1ZSBieSBpbmRleCB0byBtYXRjaCIKICAgIGRpZyAxCiAgICA9PQogICAgYXNzZXJ0IC8vIGV4cGVjdGVkIHZhbHVlIGJ5IGluZGV4IHRvIG1hdGNoCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6MTc4CiAgICAvLyBhc3NlcnQgZXhpc3RzID09IGV4aXN0c19pbmRleCwgImV4cGVjdGVkIGV4aXN0cyBieSBpbmRleCB0byBtYXRjaCIKICAgIGNvdmVyIDIKICAgID09CiAgICBhc3NlcnQgLy8gZXhwZWN0ZWQgZXhpc3RzIGJ5IGluZGV4IHRvIG1hdGNoCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6MTc5CiAgICAvLyByZXR1cm4gdmFsdWUKICAgIHJldHN1YgoKCi8vIHRlc3RzLmFydGlmYWN0cy5TdGF0ZU9wcy5jb250cmFjdC5TdGF0ZUFzc2V0UGFyYW1zQ29udHJhY3QudmVyaWZ5X2Fzc2V0X3BhcmFtc19nZXRfdXJsKGE6IHVpbnQ2NCkgLT4gYnl0ZXM6CnZlcmlmeV9hc3NldF9wYXJhbXNfZ2V0X3VybDoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weToxODEtMTgyCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gZGVmIHZlcmlmeV9hc3NldF9wYXJhbXNfZ2V0X3VybChzZWxmLCBhOiBBc3NldCkgLT4gQnl0ZXM6CiAgICBwcm90byAxIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weToxODMKICAgIC8vIHZhbHVlLCBleGlzdHMgPSBvcC5Bc3NldFBhcmFtc0dldC5hc3NldF91cmwoYSkKICAgIGZyYW1lX2RpZyAtMQogICAgYXNzZXRfcGFyYW1zX2dldCBBc3NldFVSTAogICAgc3dhcAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjE4NAogICAgLy8gdmFsdWVfaW5kZXgsIGV4aXN0c19pbmRleCA9IG9wLkFzc2V0UGFyYW1zR2V0LmFzc2V0X3VybChfZ2V0XzFzdF9yZWZfaW5kZXgoKSkKICAgIGNhbGxzdWIgX2dldF8xc3RfcmVmX2luZGV4CiAgICBhc3NldF9wYXJhbXNfZ2V0IEFzc2V0VVJMCiAgICBjb3ZlciAyCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6MTg1CiAgICAvLyBhc3NlcnQgdmFsdWUgPT0gdmFsdWVfaW5kZXgsICJleHBlY3RlZCB2YWx1ZSBieSBpbmRleCB0byBtYXRjaCIKICAgIGRpZyAxCiAgICA9PQogICAgYXNzZXJ0IC8vIGV4cGVjdGVkIHZhbHVlIGJ5IGluZGV4IHRvIG1hdGNoCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6MTg2CiAgICAvLyBhc3NlcnQgZXhpc3RzID09IGV4aXN0c19pbmRleCwgImV4cGVjdGVkIGV4aXN0cyBieSBpbmRleCB0byBtYXRjaCIKICAgIGNvdmVyIDIKICAgID09CiAgICBhc3NlcnQgLy8gZXhwZWN0ZWQgZXhpc3RzIGJ5IGluZGV4IHRvIG1hdGNoCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6MTg3CiAgICAvLyByZXR1cm4gdmFsdWUKICAgIHJldHN1YgoKCi8vIHRlc3RzLmFydGlmYWN0cy5TdGF0ZU9wcy5jb250cmFjdC5TdGF0ZUFzc2V0UGFyYW1zQ29udHJhY3QudmVyaWZ5X2Fzc2V0X3BhcmFtc19nZXRfbWV0YWRhdGFfaGFzaChhOiB1aW50NjQpIC0+IGJ5dGVzOgp2ZXJpZnlfYXNzZXRfcGFyYW1zX2dldF9tZXRhZGF0YV9oYXNoOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjE4OS0xOTAKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBkZWYgdmVyaWZ5X2Fzc2V0X3BhcmFtc19nZXRfbWV0YWRhdGFfaGFzaChzZWxmLCBhOiBBc3NldCkgLT4gQnl0ZXM6CiAgICBwcm90byAxIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weToxOTEKICAgIC8vIHZhbHVlLCBleGlzdHMgPSBvcC5Bc3NldFBhcmFtc0dldC5hc3NldF9tZXRhZGF0YV9oYXNoKGEpCiAgICBmcmFtZV9kaWcgLTEKICAgIGFzc2V0X3BhcmFtc19nZXQgQXNzZXRNZXRhZGF0YUhhc2gKICAgIHN3YXAKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weToxOTIKICAgIC8vIHZhbHVlX2luZGV4LCBleGlzdHNfaW5kZXggPSBvcC5Bc3NldFBhcmFtc0dldC5hc3NldF9tZXRhZGF0YV9oYXNoKF9nZXRfMXN0X3JlZl9pbmRleCgpKQogICAgY2FsbHN1YiBfZ2V0XzFzdF9yZWZfaW5kZXgKICAgIGFzc2V0X3BhcmFtc19nZXQgQXNzZXRNZXRhZGF0YUhhc2gKICAgIGNvdmVyIDIKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weToxOTMKICAgIC8vIGFzc2VydCB2YWx1ZSA9PSB2YWx1ZV9pbmRleCwgImV4cGVjdGVkIHZhbHVlIGJ5IGluZGV4IHRvIG1hdGNoIgogICAgZGlnIDEKICAgID09CiAgICBhc3NlcnQgLy8gZXhwZWN0ZWQgdmFsdWUgYnkgaW5kZXggdG8gbWF0Y2gKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weToxOTQKICAgIC8vIGFzc2VydCBleGlzdHMgPT0gZXhpc3RzX2luZGV4LCAiZXhwZWN0ZWQgZXhpc3RzIGJ5IGluZGV4IHRvIG1hdGNoIgogICAgY292ZXIgMgogICAgPT0KICAgIGFzc2VydCAvLyBleHBlY3RlZCBleGlzdHMgYnkgaW5kZXggdG8gbWF0Y2gKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weToxOTUKICAgIC8vIHJldHVybiB2YWx1ZQogICAgcmV0c3ViCgoKLy8gdGVzdHMuYXJ0aWZhY3RzLlN0YXRlT3BzLmNvbnRyYWN0LlN0YXRlQXNzZXRQYXJhbXNDb250cmFjdC52ZXJpZnlfYXNzZXRfcGFyYW1zX2dldF9tYW5hZ2VyKGE6IHVpbnQ2NCkgLT4gYnl0ZXM6CnZlcmlmeV9hc3NldF9wYXJhbXNfZ2V0X21hbmFnZXI6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6MTk3LTE5OAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIGRlZiB2ZXJpZnlfYXNzZXRfcGFyYW1zX2dldF9tYW5hZ2VyKHNlbGYsIGE6IEFzc2V0KSAtPiBhcmM0LkFkZHJlc3M6CiAgICBwcm90byAxIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weToxOTkKICAgIC8vIHZhbHVlLCBleGlzdHMgPSBvcC5Bc3NldFBhcmFtc0dldC5hc3NldF9tYW5hZ2VyKGEpCiAgICBmcmFtZV9kaWcgLTEKICAgIGFzc2V0X3BhcmFtc19nZXQgQXNzZXRNYW5hZ2VyCiAgICBzd2FwCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6MjAwCiAgICAvLyB2YWx1ZV9pbmRleCwgZXhpc3RzX2luZGV4ID0gb3AuQXNzZXRQYXJhbXNHZXQuYXNzZXRfbWFuYWdlcihfZ2V0XzFzdF9yZWZfaW5kZXgoKSkKICAgIGNhbGxzdWIgX2dldF8xc3RfcmVmX2luZGV4CiAgICBhc3NldF9wYXJhbXNfZ2V0IEFzc2V0TWFuYWdlcgogICAgY292ZXIgMgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjIwMQogICAgLy8gYXNzZXJ0IHZhbHVlID09IHZhbHVlX2luZGV4LCAiZXhwZWN0ZWQgdmFsdWUgYnkgaW5kZXggdG8gbWF0Y2giCiAgICBkaWcgMQogICAgPT0KICAgIGFzc2VydCAvLyBleHBlY3RlZCB2YWx1ZSBieSBpbmRleCB0byBtYXRjaAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjIwMgogICAgLy8gYXNzZXJ0IGV4aXN0cyA9PSBleGlzdHNfaW5kZXgsICJleHBlY3RlZCBleGlzdHMgYnkgaW5kZXggdG8gbWF0Y2giCiAgICBjb3ZlciAyCiAgICA9PQogICAgYXNzZXJ0IC8vIGV4cGVjdGVkIGV4aXN0cyBieSBpbmRleCB0byBtYXRjaAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjIwMwogICAgLy8gcmV0dXJuIGFyYzQuQWRkcmVzcyh2YWx1ZSkKICAgIHJldHN1YgoKCi8vIHRlc3RzLmFydGlmYWN0cy5TdGF0ZU9wcy5jb250cmFjdC5TdGF0ZUFzc2V0UGFyYW1zQ29udHJhY3QudmVyaWZ5X2Fzc2V0X3BhcmFtc19nZXRfcmVzZXJ2ZShhOiB1aW50NjQpIC0+IGJ5dGVzOgp2ZXJpZnlfYXNzZXRfcGFyYW1zX2dldF9yZXNlcnZlOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjIwNS0yMDYKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBkZWYgdmVyaWZ5X2Fzc2V0X3BhcmFtc19nZXRfcmVzZXJ2ZShzZWxmLCBhOiBBc3NldCkgLT4gYXJjNC5BZGRyZXNzOgogICAgcHJvdG8gMSAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6MjA3CiAgICAvLyB2YWx1ZSwgZXhpc3RzID0gb3AuQXNzZXRQYXJhbXNHZXQuYXNzZXRfcmVzZXJ2ZShhKQogICAgZnJhbWVfZGlnIC0xCiAgICBhc3NldF9wYXJhbXNfZ2V0IEFzc2V0UmVzZXJ2ZQogICAgc3dhcAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjIwOAogICAgLy8gdmFsdWVfaW5kZXgsIGV4aXN0c19pbmRleCA9IG9wLkFzc2V0UGFyYW1zR2V0LmFzc2V0X3Jlc2VydmUoX2dldF8xc3RfcmVmX2luZGV4KCkpCiAgICBjYWxsc3ViIF9nZXRfMXN0X3JlZl9pbmRleAogICAgYXNzZXRfcGFyYW1zX2dldCBBc3NldFJlc2VydmUKICAgIGNvdmVyIDIKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weToyMDkKICAgIC8vIGFzc2VydCB2YWx1ZSA9PSB2YWx1ZV9pbmRleCwgImV4cGVjdGVkIHZhbHVlIGJ5IGluZGV4IHRvIG1hdGNoIgogICAgZGlnIDEKICAgID09CiAgICBhc3NlcnQgLy8gZXhwZWN0ZWQgdmFsdWUgYnkgaW5kZXggdG8gbWF0Y2gKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weToyMTAKICAgIC8vIGFzc2VydCBleGlzdHMgPT0gZXhpc3RzX2luZGV4LCAiZXhwZWN0ZWQgZXhpc3RzIGJ5IGluZGV4IHRvIG1hdGNoIgogICAgY292ZXIgMgogICAgPT0KICAgIGFzc2VydCAvLyBleHBlY3RlZCBleGlzdHMgYnkgaW5kZXggdG8gbWF0Y2gKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weToyMTEKICAgIC8vIHJldHVybiBhcmM0LkFkZHJlc3ModmFsdWUpCiAgICByZXRzdWIKCgovLyB0ZXN0cy5hcnRpZmFjdHMuU3RhdGVPcHMuY29udHJhY3QuU3RhdGVBc3NldFBhcmFtc0NvbnRyYWN0LnZlcmlmeV9hc3NldF9wYXJhbXNfZ2V0X2ZyZWV6ZShhOiB1aW50NjQpIC0+IGJ5dGVzOgp2ZXJpZnlfYXNzZXRfcGFyYW1zX2dldF9mcmVlemU6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6MjEzLTIxNAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIGRlZiB2ZXJpZnlfYXNzZXRfcGFyYW1zX2dldF9mcmVlemUoc2VsZiwgYTogQXNzZXQpIC0+IGFyYzQuQWRkcmVzczoKICAgIHByb3RvIDEgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjIxNQogICAgLy8gdmFsdWUsIGV4aXN0cyA9IG9wLkFzc2V0UGFyYW1zR2V0LmFzc2V0X2ZyZWV6ZShhKQogICAgZnJhbWVfZGlnIC0xCiAgICBhc3NldF9wYXJhbXNfZ2V0IEFzc2V0RnJlZXplCiAgICBzd2FwCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6MjE2CiAgICAvLyB2YWx1ZV9pbmRleCwgZXhpc3RzX2luZGV4ID0gb3AuQXNzZXRQYXJhbXNHZXQuYXNzZXRfZnJlZXplKF9nZXRfMXN0X3JlZl9pbmRleCgpKQogICAgY2FsbHN1YiBfZ2V0XzFzdF9yZWZfaW5kZXgKICAgIGFzc2V0X3BhcmFtc19nZXQgQXNzZXRGcmVlemUKICAgIGNvdmVyIDIKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weToyMTcKICAgIC8vIGFzc2VydCB2YWx1ZSA9PSB2YWx1ZV9pbmRleCwgImV4cGVjdGVkIHZhbHVlIGJ5IGluZGV4IHRvIG1hdGNoIgogICAgZGlnIDEKICAgID09CiAgICBhc3NlcnQgLy8gZXhwZWN0ZWQgdmFsdWUgYnkgaW5kZXggdG8gbWF0Y2gKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weToyMTgKICAgIC8vIGFzc2VydCBleGlzdHMgPT0gZXhpc3RzX2luZGV4LCAiZXhwZWN0ZWQgZXhpc3RzIGJ5IGluZGV4IHRvIG1hdGNoIgogICAgY292ZXIgMgogICAgPT0KICAgIGFzc2VydCAvLyBleHBlY3RlZCBleGlzdHMgYnkgaW5kZXggdG8gbWF0Y2gKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weToyMTkKICAgIC8vIHJldHVybiBhcmM0LkFkZHJlc3ModmFsdWUpCiAgICByZXRzdWIKCgovLyB0ZXN0cy5hcnRpZmFjdHMuU3RhdGVPcHMuY29udHJhY3QuU3RhdGVBc3NldFBhcmFtc0NvbnRyYWN0LnZlcmlmeV9hc3NldF9wYXJhbXNfZ2V0X2NsYXdiYWNrKGE6IHVpbnQ2NCkgLT4gYnl0ZXM6CnZlcmlmeV9hc3NldF9wYXJhbXNfZ2V0X2NsYXdiYWNrOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjIyMS0yMjIKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBkZWYgdmVyaWZ5X2Fzc2V0X3BhcmFtc19nZXRfY2xhd2JhY2soc2VsZiwgYTogQXNzZXQpIC0+IGFyYzQuQWRkcmVzczoKICAgIHByb3RvIDEgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjIyMwogICAgLy8gdmFsdWUsIGV4aXN0cyA9IG9wLkFzc2V0UGFyYW1zR2V0LmFzc2V0X2NsYXdiYWNrKGEpCiAgICBmcmFtZV9kaWcgLTEKICAgIGFzc2V0X3BhcmFtc19nZXQgQXNzZXRDbGF3YmFjawogICAgc3dhcAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjIyNAogICAgLy8gdmFsdWVfaW5kZXgsIGV4aXN0c19pbmRleCA9IG9wLkFzc2V0UGFyYW1zR2V0LmFzc2V0X2NsYXdiYWNrKF9nZXRfMXN0X3JlZl9pbmRleCgpKQogICAgY2FsbHN1YiBfZ2V0XzFzdF9yZWZfaW5kZXgKICAgIGFzc2V0X3BhcmFtc19nZXQgQXNzZXRDbGF3YmFjawogICAgY292ZXIgMgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjIyNQogICAgLy8gYXNzZXJ0IHZhbHVlID09IHZhbHVlX2luZGV4LCAiZXhwZWN0ZWQgdmFsdWUgYnkgaW5kZXggdG8gbWF0Y2giCiAgICBkaWcgMQogICAgPT0KICAgIGFzc2VydCAvLyBleHBlY3RlZCB2YWx1ZSBieSBpbmRleCB0byBtYXRjaAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjIyNgogICAgLy8gYXNzZXJ0IGV4aXN0cyA9PSBleGlzdHNfaW5kZXgsICJleHBlY3RlZCBleGlzdHMgYnkgaW5kZXggdG8gbWF0Y2giCiAgICBjb3ZlciAyCiAgICA9PQogICAgYXNzZXJ0IC8vIGV4cGVjdGVkIGV4aXN0cyBieSBpbmRleCB0byBtYXRjaAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjIyNwogICAgLy8gcmV0dXJuIGFyYzQuQWRkcmVzcyh2YWx1ZSkKICAgIHJldHN1YgoKCi8vIHRlc3RzLmFydGlmYWN0cy5TdGF0ZU9wcy5jb250cmFjdC5TdGF0ZUFzc2V0UGFyYW1zQ29udHJhY3QudmVyaWZ5X2Fzc2V0X3BhcmFtc19nZXRfY3JlYXRvcihhOiB1aW50NjQpIC0+IGJ5dGVzOgp2ZXJpZnlfYXNzZXRfcGFyYW1zX2dldF9jcmVhdG9yOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjIyOS0yMzAKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBkZWYgdmVyaWZ5X2Fzc2V0X3BhcmFtc19nZXRfY3JlYXRvcihzZWxmLCBhOiBBc3NldCkgLT4gYXJjNC5BZGRyZXNzOgogICAgcHJvdG8gMSAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6MjMxCiAgICAvLyB2YWx1ZSwgZXhpc3RzID0gb3AuQXNzZXRQYXJhbXNHZXQuYXNzZXRfY3JlYXRvcihhKQogICAgZnJhbWVfZGlnIC0xCiAgICBhc3NldF9wYXJhbXNfZ2V0IEFzc2V0Q3JlYXRvcgogICAgc3dhcAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjIzMgogICAgLy8gdmFsdWVfaW5kZXgsIGV4aXN0c19pbmRleCA9IG9wLkFzc2V0UGFyYW1zR2V0LmFzc2V0X2NyZWF0b3IoX2dldF8xc3RfcmVmX2luZGV4KCkpCiAgICBjYWxsc3ViIF9nZXRfMXN0X3JlZl9pbmRleAogICAgYXNzZXRfcGFyYW1zX2dldCBBc3NldENyZWF0b3IKICAgIGNvdmVyIDIKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weToyMzMKICAgIC8vIGFzc2VydCB2YWx1ZSA9PSB2YWx1ZV9pbmRleCwgImV4cGVjdGVkIHZhbHVlIGJ5IGluZGV4IHRvIG1hdGNoIgogICAgZGlnIDEKICAgID09CiAgICBhc3NlcnQgLy8gZXhwZWN0ZWQgdmFsdWUgYnkgaW5kZXggdG8gbWF0Y2gKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weToyMzQKICAgIC8vIGFzc2VydCBleGlzdHMgPT0gZXhpc3RzX2luZGV4LCAiZXhwZWN0ZWQgZXhpc3RzIGJ5IGluZGV4IHRvIG1hdGNoIgogICAgY292ZXIgMgogICAgPT0KICAgIGFzc2VydCAvLyBleHBlY3RlZCBleGlzdHMgYnkgaW5kZXggdG8gbWF0Y2gKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weToyMzUKICAgIC8vIHJldHVybiBhcmM0LkFkZHJlc3ModmFsdWUpCiAgICByZXRzdWIK", + "clear": "I3ByYWdtYSB2ZXJzaW9uIDEwCgp0ZXN0cy5hcnRpZmFjdHMuU3RhdGVPcHMuY29udHJhY3QuU3RhdGVBc3NldFBhcmFtc0NvbnRyYWN0LmNsZWFyX3N0YXRlX3Byb2dyYW06CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6MTQwCiAgICAvLyBjbGFzcyBTdGF0ZUFzc2V0UGFyYW1zQ29udHJhY3QoQVJDNENvbnRyYWN0KToKICAgIGludCAxCiAgICByZXR1cm4K" }, "state": { "global": { @@ -189,7 +189,7 @@ ], "readonly": false, "returns": { - "type": "byte[]" + "type": "address" } }, { @@ -202,7 +202,7 @@ ], "readonly": false, "returns": { - "type": "byte[]" + "type": "address" } }, { @@ -215,7 +215,7 @@ ], "readonly": false, "returns": { - "type": "byte[]" + "type": "address" } }, { @@ -228,7 +228,7 @@ ], "readonly": false, "returns": { - "type": "byte[]" + "type": "address" } }, { @@ -241,7 +241,7 @@ ], "readonly": false, "returns": { - "type": "byte[]" + "type": "address" } } ], diff --git a/tests/artifacts/StateOps/data/StateAssetParamsContract.clear.teal b/tests/artifacts/StateOps/data/StateAssetParamsContract.clear.teal index e7fc234..a862b3b 100644 --- a/tests/artifacts/StateOps/data/StateAssetParamsContract.clear.teal +++ b/tests/artifacts/StateOps/data/StateAssetParamsContract.clear.teal @@ -1,7 +1,7 @@ #pragma version 10 tests.artifacts.StateOps.contract.StateAssetParamsContract.clear_state_program: - // tests/artifacts/StateOps/contract.py:91 + // tests/artifacts/StateOps/contract.py:140 // class StateAssetParamsContract(ARC4Contract): int 1 return diff --git a/tests/common.py b/tests/common.py index 19fe3a0..e2b0dc7 100644 --- a/tests/common.py +++ b/tests/common.py @@ -35,6 +35,9 @@ def __call__( transaction_parameters={ # random note avoids duplicate txn if tests are running concurrently "note": _random_note(), + "accounts": kwargs.pop("accounts", None), + "foreign_apps": kwargs.pop("foreign_apps", None), + "foreign_assets": kwargs.pop("foreign_assets", None), "suggested_params": kwargs.pop("suggested_params", None), "on_complete": on_complete, }, diff --git a/tests/conftest.py b/tests/conftest.py index 74c6ea5..31ce2e4 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -7,9 +7,13 @@ get_localnet_default_account, is_localnet, ) +from algokit_utils.beta.algorand_client import AlgorandClient +from algokit_utils.network_clients import AlgoClientConfigs from algosdk.v2client.algod import AlgodClient from algosdk.v2client.indexer import IndexerClient +# config.config.configure(debug=True) + @pytest.fixture(scope="session") def algod_client() -> AlgodClient: @@ -31,6 +35,20 @@ def localnet_creator_address(algod_client: AlgodClient) -> str: return get_localnet_default_account(algod_client).address +@pytest.fixture() +def algorand(algod_client: AlgodClient) -> AlgorandClient: + client = AlgorandClient( + AlgoClientConfigs( + algod_config=get_default_localnet_config("algod"), + indexer_config=get_default_localnet_config("indexer"), + kmd_config=get_default_localnet_config("kmd"), + ) + ) + creator = get_localnet_default_account(algod_client) + client.set_default_signer(creator.signer) + return client + + @pytest.fixture() def localnet_creator(localnet_creator_address: str) -> algopy.Account: return algopy.Account(localnet_creator_address) diff --git a/tests/models/test_asset.py b/tests/models/test_asset.py new file mode 100644 index 0000000..e275ffe --- /dev/null +++ b/tests/models/test_asset.py @@ -0,0 +1,130 @@ +from collections.abc import Generator + +import pytest +from algopy import Account, Bytes, UInt64 +from algopy_testing import AlgopyTestContext, algopy_testing_context +from algopy_testing.models.asset import Asset, AssetFields + + +@pytest.fixture() +def context() -> Generator[AlgopyTestContext, None, None]: + with algopy_testing_context() as context: + yield context + + +def test_asset_initialization() -> None: + asset = Asset() + assert asset.id == UInt64(0) + + asset = Asset(123) + assert asset.id == UInt64(123) + + asset = Asset(UInt64(456)) + assert asset.id == UInt64(456) + + +def test_asset_int_property() -> None: + asset = Asset(789) + assert asset.int_ == 789 + + +def test_asset_from_int() -> None: + asset = Asset.from_int(101112) + assert isinstance(asset, Asset) + assert asset.id == UInt64(101112) + + +def test_asset_balance(context: AlgopyTestContext) -> None: + account = context.any.account() + asset = context.any.asset() + context.ledger.update_account( + account.public_key, opted_asset_balances={asset.id.value: UInt64(1000)} + ) + + assert asset.balance(account) == UInt64(1000) + + +def test_asset_balance_not_opted_in(context: AlgopyTestContext) -> None: + account = context.any.account() + asset = context.any.asset() + + with pytest.raises(ValueError, match="The asset is not opted into the account!"): + asset.balance(account) + + +def test_asset_frozen() -> None: + asset = Asset(1) + account = Account() + + with pytest.raises( + NotImplementedError, + match="The 'frozen' method is being executed in a python testing context", + ): + asset.frozen(account) + + +def test_asset_attributes(context: AlgopyTestContext) -> None: + asset_fields: AssetFields = { + "total": UInt64(1000000), + "decimals": UInt64(6), + "default_frozen": False, + "unit_name": Bytes(b"TEST"), + "name": Bytes(b"Test Asset"), + "url": Bytes(b"https://test.com"), + "metadata_hash": Bytes(b"\x00" * 32), + "manager": Account(), + "reserve": Account(), + "freeze": Account(), + "clawback": Account(), + "creator": Account(), + } + + asset = context.any.asset(**asset_fields) + + for field, value in asset_fields.items(): + assert getattr(asset, field) == value + + +def test_asset_attribute_error(context: AlgopyTestContext) -> None: + asset = context.any.asset() + + with pytest.raises( + AttributeError, match="The value for 'non_existent' in the test context is None" + ): + asset.non_existent # noqa: B018 + + +def test_asset_not_in_context() -> None: + asset = Asset(999) + with pytest.raises(ValueError, match="Test context is not initialized!"): + asset.total # noqa: B018 + + +def test_asset_equality() -> None: + asset1 = Asset(1) + asset2 = Asset(1) + asset3 = Asset(2) + + assert asset1 == asset2 + assert asset1 != asset3 + assert asset1 == 1 + assert asset1 != 2 + + +def test_asset_bool() -> None: + assert bool(Asset(1)) is True + assert bool(Asset(0)) is False + + +def test_asset_hash() -> None: + asset1 = Asset(1) + asset2 = Asset(1) + asset3 = Asset(2) + + assert hash(asset1) == hash(asset2) + assert hash(asset1) != hash(asset3) + + # Test that assets can be used as dictionary keys + asset_dict = {asset1: "Asset 1", asset3: "Asset 3"} + assert asset_dict[asset2] == "Asset 1" + assert asset_dict[asset3] == "Asset 3" diff --git a/tests/models/test_box.py b/tests/models/test_box.py index 321f11c..a8194c1 100644 --- a/tests/models/test_box.py +++ b/tests/models/test_box.py @@ -5,6 +5,7 @@ import pytest from algopy_testing import algopy_testing_context, arc4 from algopy_testing.context import AlgopyTestContext +from algopy_testing.op.pure import itob from algopy_testing.primitives.biguint import BigUInt from algopy_testing.primitives.bytes import Bytes from algopy_testing.primitives.string import String @@ -12,6 +13,8 @@ from algopy_testing.state.box import Box from algopy_testing.utils import as_bytes, as_string +from tests.artifacts.BoxContract.contract import BoxContract + BOX_NOT_CREATED_ERROR = "Box has not been created" @@ -22,10 +25,9 @@ def __init__(self) -> None: @pytest.fixture() def context() -> Generator[AlgopyTestContext, None, None]: - with algopy_testing_context() as ctx: + with algopy_testing_context() as ctx: # noqa: SIM117 with ctx.txn.create_group([ctx.any.txn.application_call()]): yield ctx - ctx.reset() def test_init_without_key( @@ -198,3 +200,19 @@ def _assert_box_content_equality( else: assert box_content == expected_value assert box_content == op_box_content + + +def test_enums_in_boxes(context: AlgopyTestContext) -> None: + # Arrange + contract = BoxContract() + + # Act + defered_store = context.txn.defer_app_call(contract.store_enums) + defered_read = context.txn.defer_app_call(contract.read_enums) + with context.txn.create_group([defered_store, defered_read]): + defered_store.submit() + oca, txn = defered_read.submit() + + # Assert + assert context.ledger.get_box(contract, b"oca") == itob(oca.native) + assert context.ledger.get_box(contract, b"txn") == itob(txn.native) diff --git a/tests/models/test_box_map.py b/tests/models/test_box_map.py index 8a42dab..f7ed52f 100644 --- a/tests/models/test_box_map.py +++ b/tests/models/test_box_map.py @@ -22,10 +22,9 @@ def __init__(self) -> None: @pytest.fixture() def context() -> Generator[AlgopyTestContext, None, None]: - with algopy_testing_context() as ctx: + with algopy_testing_context() as ctx: # noqa: SIM117 with ctx.txn.create_group([ctx.any.txn.application_call()]): yield ctx - ctx.reset() def test_init_without_key_prefix( diff --git a/tests/models/test_box_ref.py b/tests/models/test_box_ref.py index c9eed0e..ee09f00 100644 --- a/tests/models/test_box_ref.py +++ b/tests/models/test_box_ref.py @@ -21,10 +21,9 @@ def __init__(self) -> None: @pytest.fixture() def context() -> Generator[AlgopyTestContext, None, None]: - with algopy_testing_context() as ctx: + with algopy_testing_context() as ctx: # noqa: SIM117 with ctx.txn.create_group([ctx.any.txn.application_call()]): yield ctx - ctx.reset() def test_init_without_key( diff --git a/tests/state/conftest.py b/tests/state/conftest.py index 07494dd..066893f 100644 --- a/tests/state/conftest.py +++ b/tests/state/conftest.py @@ -17,4 +17,7 @@ def get_global_state_avm_result(algod_client: AlgodClient) -> AVMInvoker: @pytest.fixture(scope="module") def get_local_state_avm_result(algod_client: AlgodClient) -> AVMInvoker: - return create_avm_invoker(LOCAL_STATE_APP_SPEC, algod_client) + invoker = create_avm_invoker(LOCAL_STATE_APP_SPEC, algod_client) + invoker.client.opt_in() + + return invoker diff --git a/tests/state/test_global_state.py b/tests/state/test_global_state.py index 46f9523..7160e02 100644 --- a/tests/state/test_global_state.py +++ b/tests/state/test_global_state.py @@ -1,54 +1,133 @@ from collections.abc import Generator +from typing import Any -import algopy_testing import pytest +from algopy_testing import arc4 from algopy_testing._context_helpers.context_storage import algopy_testing_context from algopy_testing.context import AlgopyTestContext - -from tests.artifacts.StateOps.contract import GlobalStateContract -from tests.common import AVMInvoker +from algopy_testing.primitives.bytes import Bytes +from algopy_testing.state.global_state import GlobalState @pytest.fixture() def context() -> Generator[AlgopyTestContext, None, None]: with algopy_testing_context() as ctx: yield ctx - ctx.reset() @pytest.mark.usefixtures("context") -@pytest.mark.parametrize( - ("method_name", "expected_type"), - [ - ("get_implicit_key_arc4_uint", algopy_testing.arc4.UInt64), - ("get_implicit_key_arc4_string", algopy_testing.arc4.String), - ("get_implicit_key_arc4_byte", algopy_testing.arc4.Byte), - ("get_implicit_key_arc4_bool", algopy_testing.arc4.Bool), - ("get_implicit_key_arc4_address", algopy_testing.arc4.Address), - ("get_implicit_key_arc4_uint128", algopy_testing.arc4.UInt128), - ("get_implicit_key_arc4_dynamic_bytes", algopy_testing.arc4.DynamicBytes), - ("get_arc4_uint", algopy_testing.arc4.UInt64), - ("get_arc4_string", algopy_testing.arc4.String), - ("get_arc4_byte", algopy_testing.arc4.Byte), - ("get_arc4_bool", algopy_testing.arc4.Bool), - ("get_arc4_address", algopy_testing.arc4.Address), - ("get_arc4_uint128", algopy_testing.arc4.UInt128), - ("get_arc4_dynamic_bytes", algopy_testing.arc4.DynamicBytes), - ], -) -def test_get_global_arc4_value( - get_global_state_avm_result: AVMInvoker, - localnet_creator_address: str, - method_name: str, - expected_type: type, -) -> None: - avm_result = get_global_state_avm_result(method_name) - - with algopy_testing_context(default_sender=localnet_creator_address): - contract = GlobalStateContract() - test_result = getattr(contract, method_name)() - assert isinstance(test_result, expected_type) - if isinstance(test_result, algopy_testing.arc4.Address): - assert test_result.native.public_key == avm_result - else: - assert test_result.native == avm_result # type: ignore[attr-defined] +class TestGlobalState: + @pytest.mark.parametrize( + ("type_or_value", "expected_type", "expected_value"), + [ + (arc4.UInt64, arc4.UInt64, None), + (arc4.String("Hello"), arc4.String, "Hello"), + (arc4.Bool(True), arc4.Bool, True), + ( + arc4.Address("AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAY5HFKQ"), + arc4.Address, + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAY5HFKQ", + ), + (Bytes(b"test"), Bytes, b"test"), + ], + ) + def test_initialization( + self, + context: AlgopyTestContext, + type_or_value: Any, + expected_type: type[Any], + expected_value: Any, + ) -> None: + with context.txn.create_group(gtxns=[context.any.txn.application_call()]): + gs = GlobalState(type_or_value, key="test_key") + assert gs.type_ == expected_type + assert gs.key == Bytes(b"test_key") + if expected_value is not None: + response = gs.value.native if hasattr(gs.value, "native") else gs.value + assert response == expected_value + + @pytest.mark.parametrize( + ("key", "expected_bytes"), + [ + (b"bytes_key", b"bytes_key"), + ("str_key", b"str_key"), + (Bytes(b"bytes_obj_key"), b"bytes_obj_key"), + ("", b""), # Test empty string + ], + ) + def test_set_key(self, context: AlgopyTestContext, key: Any, expected_bytes: bytes) -> None: + with context.txn.create_group(gtxns=[context.any.txn.application_call()]): + gs = GlobalState(arc4.UInt64) + gs.set_key(key) + assert gs.key == Bytes(expected_bytes) + + def test_set_key_invalid(self, context: AlgopyTestContext) -> None: + with context.txn.create_group(gtxns=[context.any.txn.application_call()]): + gs = GlobalState(arc4.UInt64) + with pytest.raises(KeyError, match="Key must be bytes or str"): + gs.set_key(123) # type: ignore[arg-type] + + @pytest.mark.parametrize( + ("type_", "value"), + [ + (arc4.UInt64, 42), + (arc4.String, "test"), + (arc4.Bool, True), + (Bytes, b"test"), + ], + ) + def test_value_operations(self, context: AlgopyTestContext, type_: Any, value: Any) -> None: + with context.txn.create_group(gtxns=[context.any.txn.application_call()]): + gs = GlobalState(type_, key="test_key") + + gs.value = type_(value) + response = gs.value.native if hasattr(gs.value, "native") else gs.value + assert response == value + assert isinstance(gs.value, type_) + + del gs.value + with pytest.raises(ValueError, match="Value is not set"): + _ = gs.value + + def test_get_method(self, context: AlgopyTestContext) -> None: + with context.txn.create_group(gtxns=[context.any.txn.application_call()]): + gs = GlobalState(arc4.UInt64, key="test_uint64") + + assert gs.get(default=arc4.UInt64(0)) == 0 + assert gs.get() == 0 # Default initialization + + gs.value = arc4.UInt64(42) + assert gs.get() == 42 + + def test_maybe_method(self, context: AlgopyTestContext) -> None: + with context.txn.create_group(gtxns=[context.any.txn.application_call()]): + gs = GlobalState(arc4.UInt64, key="test_uint64") + + value, exists = gs.maybe() + assert value is None + assert exists is False + + gs.value = arc4.UInt64(42) + value, exists = gs.maybe() + assert value == 42 + assert exists is True + + def test_pending_value(self, context: AlgopyTestContext) -> None: + with context.txn.create_group(gtxns=[context.any.txn.application_call()]): + gs = GlobalState(arc4.UInt64(100)) + assert gs._pending_value == 100 + + gs.set_key("test_key") + assert gs.value == 100 + assert gs._pending_value is None + + def test_description(self, context: AlgopyTestContext) -> None: + with context.txn.create_group(gtxns=[context.any.txn.application_call()]): + gs = GlobalState(arc4.UInt64, key="test_key", description="Test description") + assert gs.description == "Test description" + + def test_app_id(self, context: AlgopyTestContext) -> None: + with context.txn.create_group(gtxns=[context.any.txn.application_call()]): + gs = GlobalState(arc4.UInt64, key="test_key") + + assert gs.app_id == context.txn.last_active.app_id.id diff --git a/tests/state/test_local_state.py b/tests/state/test_local_state.py index 7657677..1dd91e9 100644 --- a/tests/state/test_local_state.py +++ b/tests/state/test_local_state.py @@ -1,10 +1,7 @@ -import contextlib - +import algopy import algopy_testing -import algosdk import pytest from algopy_testing._context_helpers.context_storage import algopy_testing_context -from algopy_testing.enums import OnCompleteAction from tests.artifacts.StateOps.contract import LocalStateContract from tests.common import AVMInvoker @@ -13,20 +10,20 @@ @pytest.mark.parametrize( ("method_name", "expected_type"), [ - ("get_implicit_key_arc4_uint", algopy_testing.arc4.UInt64), - ("get_implicit_key_arc4_string", algopy_testing.arc4.String), - ("get_implicit_key_arc4_byte", algopy_testing.arc4.Byte), - ("get_implicit_key_arc4_bool", algopy_testing.arc4.Bool), - ("get_implicit_key_arc4_address", algopy_testing.arc4.Address), - ("get_implicit_key_arc4_uint128", algopy_testing.arc4.UInt128), - ("get_implicit_key_arc4_dynamic_bytes", algopy_testing.arc4.DynamicBytes), - ("get_arc4_uint", algopy_testing.arc4.UInt64), - ("get_arc4_string", algopy_testing.arc4.String), - ("get_arc4_byte", algopy_testing.arc4.Byte), - ("get_arc4_bool", algopy_testing.arc4.Bool), - ("get_arc4_address", algopy_testing.arc4.Address), - ("get_arc4_uint128", algopy_testing.arc4.UInt128), - ("get_arc4_dynamic_bytes", algopy_testing.arc4.DynamicBytes), + ("get_implicit_key_arc4_uint", algopy.arc4.UInt64), + ("get_implicit_key_arc4_string", algopy.arc4.String), + ("get_implicit_key_arc4_byte", algopy.arc4.Byte), + ("get_implicit_key_arc4_bool", algopy.arc4.Bool), + ("get_implicit_key_arc4_address", algopy.arc4.Address), + ("get_implicit_key_arc4_uint128", algopy.arc4.UInt128), + ("get_implicit_key_arc4_dynamic_bytes", algopy.arc4.DynamicBytes), + ("get_arc4_uint", algopy.arc4.UInt64), + ("get_arc4_string", algopy.arc4.String), + ("get_arc4_byte", algopy.arc4.Byte), + ("get_arc4_bool", algopy.arc4.Bool), + ("get_arc4_address", algopy.arc4.Address), + ("get_arc4_uint128", algopy.arc4.UInt128), + ("get_arc4_dynamic_bytes", algopy.arc4.DynamicBytes), ], ) def test_get_local_arc4_value( @@ -35,15 +32,13 @@ def test_get_local_arc4_value( method_name: str, expected_type: type, ) -> None: - with contextlib.suppress(algosdk.error.AlgodHTTPError): - get_local_state_avm_result("opt_in", on_complete=algosdk.transaction.OnComplete.OptInOC) avm_result = get_local_state_avm_result(method_name, a=localnet_creator_address) with algopy_testing_context(default_sender=localnet_creator_address) as ctx: contract = LocalStateContract() with ctx.txn.create_group( - gtxns=[ctx.any.txn.application_call(on_completion=OnCompleteAction.OptIn)] + active_txn_overrides={"on_completion": algopy.OnCompleteAction.OptIn} ): contract.opt_in() test_result = getattr(contract, method_name)(ctx.default_sender) diff --git a/tests/test_context.py b/tests/test_context.py index d64e82b..4f0ac40 100644 --- a/tests/test_context.py +++ b/tests/test_context.py @@ -118,8 +118,8 @@ def test_context_reset() -> None: with pytest.raises(ValueError, match="No group transactions found"): assert context.txn.last_group assert len(context.txn._groups) == 0 - assert next(context.ledger.asset_id) == 1001 - assert next(context.ledger.app_id) == 1001 + assert context.ledger.get_next_asset_id() == 1001 + assert context.ledger.get_next_app_id() == 1001 def test_algopy_testing_context() -> None: diff --git a/tests/test_op.py b/tests/test_op.py index 3dd50b1..fcaf3e0 100644 --- a/tests/test_op.py +++ b/tests/test_op.py @@ -13,6 +13,7 @@ from algokit_utils import LogicError, get_localnet_default_account from algopy_testing import algopy_testing_context, op from algopy_testing.context import AlgopyTestContext +from algopy_testing.op.block import Block from algopy_testing.primitives.bytes import Bytes from algopy_testing.primitives.uint64 import UInt64 from algopy_testing.utils import convert_native_to_stack @@ -80,7 +81,6 @@ def _generate_ecdsa_test_data(curve: curves.Curve) -> dict[str, typing.Any]: def context() -> typing.Generator[AlgopyTestContext, None, None]: with algopy_testing_context() as ctx: yield ctx - ctx.reset() @pytest.fixture(scope="module") @@ -98,6 +98,13 @@ def get_state_app_local_avm_result(algod_client: AlgodClient) -> AVMInvoker: return create_avm_invoker(STATE_OPS_APP_LOCAL_SPEC, algod_client) +@pytest.fixture(scope="module") +def get_state_app_local_avm_opted_in(algod_client: AlgodClient) -> AVMInvoker: + invoker = create_avm_invoker(STATE_OPS_APP_LOCAL_SPEC, algod_client) + invoker.client.opt_in() + return invoker + + @pytest.fixture(scope="module") def get_state_app_global_avm_result(algod_client: AlgodClient) -> AVMInvoker: return create_avm_invoker(STATE_OPS_APP_GLOBAL_SPEC, algod_client) @@ -455,7 +462,7 @@ def test_asset_holding_get( ("verify_asset_params_get_reserve", algosdk.constants.ZERO_ADDRESS), ("verify_asset_params_get_freeze", algosdk.constants.ZERO_ADDRESS), ("verify_asset_params_get_clawback", algosdk.constants.ZERO_ADDRESS), - ("verify_asset_params_get_creator", lambda a: algopy.Account(a.address).bytes), + ("verify_asset_params_get_creator", "creator"), ], ) def test_asset_params_get( @@ -463,9 +470,10 @@ def test_asset_params_get( get_state_asset_params_avm_result: AVMInvoker, context: AlgopyTestContext, method_name: str, - expected_value: int | bytes | bool | typing.Callable[..., algopy.Bytes], + expected_value: object, ) -> None: dummy_account = get_localnet_default_account(algod_client) + creator = dummy_account.address metadata_hash = b"test" + b" " * 28 mock_asset = context.any.asset( @@ -475,7 +483,7 @@ def test_asset_params_get( unit_name=algopy.Bytes(b"UNIT"), url=algopy.Bytes(b"https://algorand.co"), metadata_hash=algopy.Bytes(metadata_hash), - creator=algopy.Account(dummy_account.address), + creator=algopy.Account(creator), ) dummy_asset = generate_test_asset( @@ -497,13 +505,10 @@ def test_asset_params_get( avm_result = get_state_asset_params_avm_result(method_name, a=dummy_asset, suggested_params=sp) mock_result = getattr(mock_contract, method_name)(mock_asset) - # TODO: 1.0 add separate tests by foreign array index - expected = expected_value(dummy_account) if callable(expected_value) else expected_value - expected = ( - algopy.Account().bytes if str(expected) == algosdk.constants.ZERO_ADDRESS else expected - ) - assert mock_result == avm_result == expected + if isinstance(expected_value, str): + expected_value = algopy.Account(creator if expected_value == "creator" else expected_value) + assert mock_result == avm_result == expected_value @pytest.mark.parametrize( @@ -516,15 +521,15 @@ def test_asset_params_get( ("verify_app_params_get_local_num_uint", 0), ("verify_app_params_get_local_num_byte_slice", 0), ("verify_app_params_get_extra_program_pages", 0), - ("verify_app_params_get_creator", None), - ("verify_app_params_get_address", None), + ("verify_app_params_get_creator", "app.creator"), + ("verify_app_params_get_address", "app.address"), ], ) def test_app_params_get( algod_client: AlgodClient, get_state_app_params_avm_result: AVMInvoker, method_name: str, - expected_value: int | bytes | bool | str | None, + expected_value: object, ) -> None: client = get_state_app_params_avm_result.client with algopy_testing_context() as ctx: @@ -555,8 +560,11 @@ def test_app_params_get( contract_method = getattr(contract, method_name) result = contract_method(app) - # TODO: 1.0 add alternate tests for testing by index assert avm_result == result + if expected_value == "app.creator": + expected_value = app.creator + elif expected_value == "app.address": + expected_value = app.address if expected_value is not None: assert avm_result == expected_value @@ -566,7 +574,7 @@ def test_app_params_get( [ ("verify_acct_balance", INITIAL_BALANCE_MICRO_ALGOS + 100_000), ("verify_acct_min_balance", 100_000), - ("verify_acct_auth_addr", algosdk.encoding.decode_address(algosdk.constants.ZERO_ADDRESS)), + ("verify_acct_auth_addr", algosdk.constants.ZERO_ADDRESS), ("verify_acct_total_num_uint", 0), ("verify_acct_total_num_byte_slice", 0), ("verify_acct_total_extra_app_pages", 0), @@ -583,12 +591,12 @@ def test_acct_params_get( get_state_acct_params_avm_result: AVMInvoker, context: AlgopyTestContext, method_name: str, - expected_value: int | bytes | bool | str | None, + expected_value: object, ) -> None: dummy_account = generate_test_account(algod_client) mock_account = context.any.account( - balance=algopy.UInt64(100_100_000), + balance=algopy.UInt64(INITIAL_BALANCE_MICRO_ALGOS + 100_000), min_balance=algopy.UInt64(100_000), auth_address=algopy.Account(algosdk.constants.ZERO_ADDRESS), total_num_uint=algopy.UInt64(0), @@ -611,67 +619,57 @@ def test_acct_params_get( avm_result = get_state_acct_params_avm_result( method_name, a=dummy_account.address, suggested_params=sp ) - mock_result = getattr(mock_contract, method_name)(mock_account) - if method_name == "verify_acct_balance": - assert mock_result == 100_100_000 # assert it returns the value set in test context - mock_result = avm_result - - # TODO: 1.0 add alternate tests for testing by index - assert mock_result == avm_result + if isinstance(expected_value, str): + expected_value = algopy.Account(expected_value) + assert mock_result == avm_result == expected_value - if expected_value is not None: - assert mock_result == expected_value - -@pytest.mark.usefixtures("context") @pytest.mark.parametrize( - ("method_name", "key", "value", "expected"), + ("key", "value"), [ - ("verify_put_bytes", b"local_bytes", b"test_bytes", b"test_bytes"), - ("verify_put_uint64", b"local_uint64", 42, 42), + (b"local_bytes", b"test_bytes"), + (b"local_uint64", 42), ], ) -def test_app_local_put_get_and_delete( # noqa: PLR0913 +def test_app_local_put_get_and_delete( + context: algopy_testing.AlgopyTestContext, localnet_creator: algopy_testing.Account, - get_state_app_local_avm_result: AVMInvoker, - method_name: str, + get_state_app_local_avm_opted_in: AVMInvoker, key: bytes, value: bytes | int, - expected: bytes | int, ) -> None: - with contextlib.suppress(algosdk.error.AlgodHTTPError): - get_state_app_local_avm_result.client.opt_in( - "opt_in", - ) + assert context + type_suffix = "bytes" if isinstance(value, bytes) else "uint64" + put_method_name = f"verify_put_{type_suffix}" + get_method_name = f"verify_get_{type_suffix}" # Put operation - get_state_app_local_avm_result( - method_name, + get_state_app_local_avm_opted_in( + put_method_name, a=localnet_creator.public_key, b=key, c=value, ) contract = StateAppLocalContract() - getattr(contract, method_name)( + getattr(contract, put_method_name)( a=localnet_creator, b=Bytes(key), c=Bytes(value) if isinstance(value, bytes) else UInt64(value), ) # Get operation - get_method = "verify_get_bytes" if isinstance(value, bytes) else "verify_get_uint64" - avm_result = get_state_app_local_avm_result( - get_method, + avm_result = get_state_app_local_avm_opted_in( + get_method_name, a=localnet_creator.public_key, b=key, ) - mock_result = getattr(contract, get_method)(a=localnet_creator, b=Bytes(key)) - assert avm_result == mock_result == expected + mock_result = getattr(contract, get_method_name)(a=localnet_creator, b=Bytes(key)) + assert avm_result == mock_result == value # Delete operation - get_state_app_local_avm_result( + get_state_app_local_avm_opted_in( "verify_delete", a=localnet_creator.public_key, b=key, @@ -679,23 +677,11 @@ def test_app_local_put_get_and_delete( # noqa: PLR0913 contract.verify_delete(a=localnet_creator, b=Bytes(key)) # Verify deletion - if method_name == "verify_put_bytes": - with pytest.raises(LogicError): - get_state_app_local_avm_result( - get_method, - a=localnet_creator.public_key, - b=key, - ) - else: - assert ( - get_state_app_local_avm_result( - get_method, - a=localnet_creator.public_key, - b=key, - ) - == 0 - ) - assert getattr(contract, get_method)(a=localnet_creator, b=Bytes(key)) == 0 + avm_result = get_state_app_local_avm_opted_in( + "verify_exists", a=localnet_creator.public_key, b=key + ) + mock_result = contract.verify_exists(a=localnet_creator, b=Bytes(key)) + assert avm_result == mock_result, "verify_exists does not match" def test_app_local_ex_get( @@ -915,7 +901,7 @@ def test_itxn_ops(context: AlgopyTestContext) -> None: appl_itxn = itxn_group.application_call(0) pay_itxn = itxn_group.payment(1) - # TODO: 1.0 also test other array fields, apps, accounts, applications, assets + # Test application call transaction fields assert appl_itxn.approval_program == algopy.Bytes.from_hex("068101068101") assert appl_itxn.clear_state_program == algopy.Bytes.from_hex("068101") approval_pages = [ @@ -925,9 +911,65 @@ def test_itxn_ops(context: AlgopyTestContext) -> None: assert approval_pages == [appl_itxn.approval_program] assert appl_itxn.on_completion == algopy.OnCompleteAction.DeleteApplication assert appl_itxn.fee == algopy.UInt64(algosdk.constants.MIN_TXN_FEE) - + assert appl_itxn.sender == context.get_app_for_contract(contract).address + # NOTE: would implementing emulation for this behavior be useful + # in unit testing context (vs integration tests)? + # considering we don't emulate balance (transfer, accounting for fees and etc) + assert appl_itxn.app_id == 0 + assert appl_itxn.type == algopy.TransactionType.ApplicationCall + assert appl_itxn.type_bytes == algopy.Bytes(b"appl") + + # Test payment transaction fields assert pay_itxn.receiver == context.default_sender assert pay_itxn.amount == algopy.UInt64(1000) + assert pay_itxn.sender == context.get_app_for_contract(contract).address + assert pay_itxn.type == algopy.TransactionType.Payment + assert pay_itxn.type_bytes == algopy.Bytes(b"pay") + + # Test common fields for both transactions + for itxn in [appl_itxn, pay_itxn]: + assert isinstance(itxn.sender, algopy.Account) + assert isinstance(itxn.fee, algopy.UInt64) + assert isinstance(itxn.first_valid, algopy.UInt64) + assert isinstance(itxn.last_valid, algopy.UInt64) + assert isinstance(itxn.note, algopy.Bytes) + assert isinstance(itxn.lease, algopy.Bytes) + assert isinstance(itxn.txn_id, algopy.Bytes) + # Test logs (should be empty for newly created transactions as its a void method) + assert context.txn.last_active.num_logs == algopy.UInt64(0) + assert context.txn.last_active.last_log == algopy.Bytes(b"") -# def test_ + # Test created_app and created_asset (should be created for these transactions) + assert hasattr(appl_itxn, "created_app") + assert hasattr(pay_itxn, "created_asset") + + +def test_blk_seed_existing_block(context: AlgopyTestContext) -> None: + block_index = 42 + block_seed = 123 + context.ledger.set_block(block_index, block_seed, 1234567890) + result = Block.blk_seed(UInt64(block_index)) + assert op.btoi(result) == block_seed + + +@pytest.mark.usefixtures("context") +def test_blk_seed_missing_block() -> None: + block_index = 42 + with pytest.raises(KeyError, match=f"Block {block_index}*"): + Block.blk_seed(UInt64(block_index)) + + +def test_blk_timestamp_existing_block(context: AlgopyTestContext) -> None: + block_index = 42 + block_timestamp = 1234567890 + context.ledger.set_block(block_index, 123, block_timestamp) + result = Block.blk_timestamp(UInt64(block_index)) + assert result == UInt64(block_timestamp) + + +@pytest.mark.usefixtures("context") +def test_blk_timestamp_missing_block() -> None: + block_index = 42 + with pytest.raises(KeyError, match=f"Block {block_index}*"): + Block.blk_timestamp(UInt64(block_index)) diff --git a/tests/utilities/test_log.py b/tests/utilities/test_log.py index 6beca3b..38f6d72 100644 --- a/tests/utilities/test_log.py +++ b/tests/utilities/test_log.py @@ -15,7 +15,6 @@ def context() -> Generator[AlgopyTestContext, None, None]: with algopy_testing_context() as ctx: yield ctx - ctx.reset() def test_log(get_avm_result: AVMInvoker, context: AlgopyTestContext) -> None: