diff --git a/docs/coverage.md b/docs/coverage.md index db774574..be5bcda5 100644 --- a/docs/coverage.md +++ b/docs/coverage.md @@ -40,6 +40,7 @@ See which `algorand-python` stubs are implemented by the `algorand-python-testin | algopy.ensure_budget | Emulated | | algopy.log | Emulated | | algopy.logicsig | Emulated | +| algopy.public | Emulated | | algopy.size_of | Emulated | | algopy.subroutine | Native | | algopy.uenumerate | Native | diff --git a/docs/index.md b/docs/index.md index 7d101f13..9c5df25d 100644 --- a/docs/index.md +++ b/docs/index.md @@ -62,7 +62,7 @@ class VotingContract(algopy.ARC4Contract): ) self.voted = algopy.LocalState(algopy.UInt64, key="voted", description="Tracks if an account has voted") - @arc4.abimethod + @algopy.public def set_topic(self, topic: arc4.String) -> None: self.topic.value = topic.bytes @@ -79,7 +79,7 @@ class VotingContract(algopy.ARC4Contract): self.voted[algopy.Txn.sender] = algopy.UInt64(1) return arc4.Bool(True) - @arc4.abimethod(readonly=True) + @algopy.public(readonly=True) def get_votes(self) -> arc4.UInt64: return arc4.UInt64(self.votes.value) @@ -141,9 +141,9 @@ This example demonstrates key aspects of testing with `algorand-python-testing` 1. ARC4 Contract Features: - Use of `algopy.ARC4Contract` as the base class for the contract. - - ABI methods defined using the `@arc4.abimethod` decorator. + - ABI methods defined using the `@arc4.abimethod`, or its alias `@algopy.public`, decorator. - Use of ARC4-specific types like `arc4.String`, `arc4.Bool`, and `arc4.UInt64`. - - Readonly method annotation with `@arc4.abimethod(readonly=True)`. + - Readonly method annotation with `@arc4.abimethod(readonly=True)` or `@algopy.public(readonly=True)` . 2. Testing ARC4 Contracts: diff --git a/docs/testing-guide/concepts.md b/docs/testing-guide/concepts.md index f476c1d1..47f81d81 100644 --- a/docs/testing-guide/concepts.md +++ b/docs/testing-guide/concepts.md @@ -61,5 +61,5 @@ For a full list of all public `algopy` types and their corresponding implementat ## Data Validation -Algorand Python and the puya compiler have functionality to perform validation of transaction inputs via the `--validate-abi-args`, `--validate-abi-return` CLI arguments, `arc4.abimethod(validate_encoding=...)` decorator and `.validate()` methods. -The Algorand Python Testing library does *NOT* implement this validation behaviour, as you should test invalid inputs using an integrated test against a real Algorand network. +Algorand Python and the puya compiler have functionality to perform validation of transaction inputs via the `--validate-abi-args`, `--validate-abi-return` CLI arguments, `arc4.abimethod(validate_encoding=...)` decorator (or its alias, `algopy.public`) and `.validate()` methods. +The Algorand Python Testing library does _NOT_ implement this validation behaviour, as you should test invalid inputs using an integrated test against a real Algorand network. diff --git a/docs/testing-guide/contract-testing.md b/docs/testing-guide/contract-testing.md index 9c28d331..df057dad 100644 --- a/docs/testing-guide/contract-testing.md +++ b/docs/testing-guide/contract-testing.md @@ -1,6 +1,6 @@ # Smart Contract Testing -This guide provides an overview of how to test smart contracts using the Algorand Python SDK (`algopy`). It covers the basics of testing `ARC4Contract` and `Contract` classes, focusing on the `abimethod` and `baremethod` decorators. +This guide provides an overview of how to test smart contracts using the Algorand Python SDK (`algopy`). It covers the basics of testing `ARC4Contract` and `Contract` classes, focusing on the `baremethod`, `abimethod` and `public` (an alias of `abimethod`) decorators. ![](https://mermaid.ink/img/pako:eNqVkrFugzAQhl_Fujnp1ImhEiJrJNREWeoOV9sNVsFG9iEVBd69R5w0JE2llsk2n7-7_-AAymsDGewDtpXYrqQT_GyKFwl5vfcBnRZlT5V3IjYYSCjvKKAiCa-JzXfrObyzgTqsxRpVZZ25YOX2nnRrIomCneZzpszLkllktu0f8ratrUKyjFsXCZ1K2gTH7i01_8dGUjOT_55YeLdUFVr3zRunf5b6R5hZoFnBq9cX72_Br_Cj8bl4vJCHaVucvowYxHk5Xg_sfPkY6SbbphDL5dMgQZu29n0U5DMJwzTVGyApySKZKFSNMXKVxPJYYAGNCQ1azX_VYboqgSrTcAcZLzWGDwnSjcxhR37TOwUZhc4sIPhuX0H2jnXkXddqrrCyyKNpTqfjF5m74B8?type=png) @@ -24,7 +24,7 @@ context = ctx_manager.__enter__() Subclasses of `algopy.ARC4Contract` are **required** to be instantiated with an active test context. As part of instantiation, the test context will automatically create a matching `algopy.Application` object instance. -Within the class implementation, methods decorated with `algopy.arc4.abimethod` and `algopy.arc4.baremethod` will automatically assemble an `algopy.gtxn.ApplicationCallTransaction` to emulate the AVM application call. This behaviour can be overridden by setting the transaction group manually as part of test setup; this is done via implicit invocation of the `algopy_testing.context.any_application()` _value generator_ (refer to the [API](../api.md) for more details). +Within the class implementation, methods decorated with `algopy.arc4.abimethod` (or its alias, `algopy.public`) and `algopy.arc4.baremethod` will automatically assemble an `algopy.gtxn.ApplicationCallTransaction` to emulate the AVM application call. This behaviour can be overridden by setting the transaction group manually as part of test setup; this is done via implicit invocation of the `algopy_testing.context.any_application()` _value generator_ (refer to the [API](../api.md) for more details). ```{testcode} class SimpleVotingContract(algopy.ARC4Contract): @@ -42,14 +42,14 @@ class SimpleVotingContract(algopy.ARC4Contract): self.topic.value = initial_topic self.votes.value = algopy.UInt64(0) - @algopy.arc4.abimethod + @algopy.public def vote(self) -> algopy.UInt64: assert self.voted[algopy.Txn.sender] == algopy.UInt64(0), "Account has already voted" self.votes.value += algopy.UInt64(1) self.voted[algopy.Txn.sender] = algopy.UInt64(1) return self.votes.value - @algopy.arc4.abimethod(readonly=True) + @algopy.public(readonly=True) def get_votes(self) -> algopy.UInt64: return self.votes.value @@ -74,7 +74,7 @@ assert contract.topic.value == initial_topic assert contract.votes.value == algopy.UInt64(0) # Act - Vote -# The method `.vote()` is decorated with `algopy.arc4.abimethod`, which means it will assemble a transaction to emulate the AVM application call +# The method `.vote()` is decorated with `algopy.public`, an alias of `algopy.arc4.abimethod`, which means it will assemble a transaction to emulate the AVM application call result = contract.vote() # Assert - you can access the corresponding auto generated application call transaction via test context diff --git a/docs/testing-guide/subroutines.md b/docs/testing-guide/subroutines.md index 403d78b9..2dc13383 100644 --- a/docs/testing-guide/subroutines.md +++ b/docs/testing-guide/subroutines.md @@ -18,6 +18,8 @@ context = ctx_manager.__enter__() The `@algopy.subroutine` decorator exposes contract methods for isolated testing within the Algorand Python Testing framework. This enables focused validation of core business logic without the overhead of full application deployment and execution. +`@algopy.subroutine` decorator is optional for the methods in a contract which are not callable externally. + ## Usage 1. Decorate internal methods with `@algopy.subroutine`: @@ -26,7 +28,7 @@ The `@algopy.subroutine` decorator exposes contract methods for isolated testing from algopy import subroutine, UInt64 class MyContract: - @subroutine + @subroutine # optional def calculate_value(self, input: UInt64) -> UInt64: return input * UInt64(2) ``` diff --git a/docs/testing-guide/transactions.md b/docs/testing-guide/transactions.md index 27805811..1ab50dea 100644 --- a/docs/testing-guide/transactions.md +++ b/docs/testing-guide/transactions.md @@ -143,7 +143,7 @@ When testing smart contracts, to stay consistent with AVM, the framework _does n ```{testcode} class MyContract(algopy.ARC4Contract): - @algopy.arc4.abimethod + @algopy.public def pay_via_itxn(self, asset: algopy.Asset) -> None: algopy.itxn.Payment( receiver=algopy.Txn.sender, @@ -180,7 +180,7 @@ first_payment_txn = first_itxn_group.payment(0) In this example, we define a contract method `pay_via_itxn` that creates and submits an inner payment transaction. The test context automatically captures and stores the inner transactions submitted by the contract method. -Note that we don't need to wrap the execution in a `create_group` context manager because the method is decorated with `@algopy.arc4.abimethod`, which automatically creates a transaction group for the method. The `create_group` context manager is only needed when you want to create more complex transaction groups or patch transaction fields for various transaction-related opcodes in AVM. +Note that we don't need to wrap the execution in a `create_group` context manager because the method is decorated with `@algopy.public`, an alias of `@algopy.arc4.abimethod`, which automatically creates a transaction group for the method. The `create_group` context manager is only needed when you want to create more complex transaction groups or patch transaction fields for various transaction-related opcodes in AVM. To access the submitted inner transactions: diff --git a/examples/marketplace/contract.py b/examples/marketplace/contract.py index 63900506..eb18fd9c 100644 --- a/examples/marketplace/contract.py +++ b/examples/marketplace/contract.py @@ -9,7 +9,6 @@ gtxn, itxn, op, - subroutine, ) from algopy.arc4 import abimethod @@ -32,7 +31,6 @@ class DigitalMarketplace(ARC4Contract): def __init__(self) -> None: self.listings = BoxMap(ListingKey, ListingValue) - @subroutine def listings_box_mbr(self) -> UInt64: return ( 2_500 @@ -55,7 +53,6 @@ def listings_box_mbr(self) -> UInt64: * 400 ) - @subroutine def quantity_price(self, quantity: UInt64, price: UInt64, asset_decimals: UInt64) -> UInt64: amount_not_scaled_high, amount_not_scaled_low = op.mulw(price, quantity) scaling_factor_high, scaling_factor_low = op.expw(10, asset_decimals) diff --git a/examples/proof_of_attendance/contract.py b/examples/proof_of_attendance/contract.py index 4aefeb5e..d80e990f 100644 --- a/examples/proof_of_attendance/contract.py +++ b/examples/proof_of_attendance/contract.py @@ -8,12 +8,12 @@ def __init__(self) -> None: self.total_attendees = algopy.UInt64(0) self.box_map = algopy.BoxMap(algopy.Bytes, algopy.UInt64) - @algopy.arc4.abimethod(create="require") + @algopy.public(create="require") def init(self, max_attendees: algopy.UInt64) -> None: assert algopy.Txn.sender == algopy.Global.creator_address, "Only creator can initialize" self.max_attendees = max_attendees - @algopy.arc4.abimethod() + @algopy.public() def confirm_attendance(self) -> None: assert self.total_attendees < self.max_attendees, "Max attendees reached" @@ -25,7 +25,7 @@ def confirm_attendance(self) -> None: algopy.op.Box.put(algopy.Txn.sender.bytes, algopy.op.itob(minted_asset.id)) - @algopy.arc4.abimethod() + @algopy.public() def confirm_attendance_with_box(self) -> None: assert self.total_attendees < self.max_attendees, "Max attendees reached" @@ -38,7 +38,7 @@ def confirm_attendance_with_box(self) -> None: box.value = minted_asset.id - @algopy.arc4.abimethod() + @algopy.public() def confirm_attendance_with_box_ref(self) -> None: assert self.total_attendees < self.max_attendees, "Max attendees reached" @@ -51,7 +51,7 @@ def confirm_attendance_with_box_ref(self) -> None: box_ref.value = algopy.op.itob(minted_asset.id) - @algopy.arc4.abimethod() + @algopy.public() def confirm_attendance_with_box_map(self) -> None: assert self.total_attendees < self.max_attendees, "Max attendees reached" @@ -63,33 +63,33 @@ def confirm_attendance_with_box_map(self) -> None: self.box_map[algopy.Txn.sender.bytes] = minted_asset.id - @algopy.arc4.abimethod(readonly=True) + @algopy.public(readonly=True) def get_poa_id(self) -> algopy.UInt64: poa_id, exists = algopy.op.Box.get(algopy.Txn.sender.bytes) assert exists, "POA not found" return algopy.op.btoi(poa_id) - @algopy.arc4.abimethod(readonly=True) + @algopy.public(readonly=True) def get_poa_id_with_box(self) -> algopy.UInt64: box = algopy.Box(algopy.UInt64, key=algopy.Txn.sender.bytes) poa_id, exists = box.maybe() assert exists, "POA not found" return poa_id - @algopy.arc4.abimethod(readonly=True) + @algopy.public(readonly=True) def get_poa_id_with_box_ref(self) -> algopy.UInt64: box_ref = algopy.Box(algopy.Bytes, key=algopy.Txn.sender.bytes) poa_id, exists = box_ref.maybe() assert exists, "POA not found" return algopy.op.btoi(poa_id) - @algopy.arc4.abimethod(readonly=True) + @algopy.public(readonly=True) def get_poa_id_with_box_map(self) -> algopy.UInt64: poa_id, exists = self.box_map.maybe(algopy.Txn.sender.bytes) assert exists, "POA not found" return poa_id - @algopy.arc4.abimethod() + @algopy.public() def claim_poa(self, opt_in_txn: algopy.gtxn.AssetTransferTransaction) -> None: poa_id, exists = algopy.op.Box.get(algopy.Txn.sender.bytes) assert exists, "POA not found, attendance validation failed!" @@ -108,7 +108,7 @@ def claim_poa(self, opt_in_txn: algopy.gtxn.AssetTransferTransaction) -> None: algopy.op.btoi(poa_id), ) - @algopy.arc4.abimethod() + @algopy.public() def claim_poa_with_box(self, opt_in_txn: algopy.gtxn.AssetTransferTransaction) -> None: box = algopy.Box(algopy.UInt64, key=algopy.Txn.sender.bytes) poa_id, exists = box.maybe() @@ -128,7 +128,7 @@ def claim_poa_with_box(self, opt_in_txn: algopy.gtxn.AssetTransferTransaction) - poa_id, ) - @algopy.arc4.abimethod() + @algopy.public() def claim_poa_with_box_ref(self, opt_in_txn: algopy.gtxn.AssetTransferTransaction) -> None: box_ref = algopy.Box(algopy.Bytes, key=algopy.Txn.sender.bytes) poa_id, exists = box_ref.maybe() @@ -148,7 +148,7 @@ def claim_poa_with_box_ref(self, opt_in_txn: algopy.gtxn.AssetTransferTransactio algopy.op.btoi(poa_id), ) - @algopy.arc4.abimethod() + @algopy.public() def claim_poa_with_box_map(self, opt_in_txn: algopy.gtxn.AssetTransferTransaction) -> None: poa_id, exists = self.box_map.maybe(algopy.Txn.sender.bytes) assert exists, "POA not found, attendance validation failed!" diff --git a/examples/simple_voting/contract.py b/examples/simple_voting/contract.py index 4b296fe8..0a4d181a 100644 --- a/examples/simple_voting/contract.py +++ b/examples/simple_voting/contract.py @@ -8,7 +8,6 @@ Txn, UInt64, op, - subroutine, ) VOTE_PRICE = 10_000 @@ -24,11 +23,9 @@ def __init__(self) -> None: ) self.voted = LocalState(UInt64, key="voted", description="Tracks if an account has voted") - @subroutine def set_topic(self, topic: Bytes) -> None: self.topic.value = topic - @subroutine def vote(self, voter: Account) -> bool: assert op.Global.group_size == UInt64(2) assert op.GTxn.amount(1) == UInt64(VOTE_PRICE) @@ -40,7 +37,6 @@ def vote(self, voter: Account) -> bool: self.voted[voter] = UInt64(1) return True - @subroutine def get_votes(self) -> UInt64: return self.votes.value diff --git a/src/_algopy_testing/__init__.py b/src/_algopy_testing/__init__.py index ffe3bbaf..ddd2d293 100644 --- a/src/_algopy_testing/__init__.py +++ b/src/_algopy_testing/__init__.py @@ -1,3 +1,4 @@ +# ruff: noqa: I001 from _algopy_testing import arc4, gtxn, itxn from _algopy_testing.context import AlgopyTestContext from _algopy_testing.context_helpers.context_storage import algopy_testing_context @@ -24,6 +25,9 @@ from _algopy_testing.value_generators.arc4 import ARC4ValueGenerator from _algopy_testing.value_generators.avm import AVMValueGenerator from _algopy_testing.value_generators.txn import TxnValueGenerator +from _algopy_testing.decorators.arc4 import ( + abimethod as public, +) __all__ = [ "ARC4Contract", @@ -60,6 +64,7 @@ "gtxn", "itxn", "logicsig", + "public", "subroutine", "uenumerate", "urange", diff --git a/src/algopy/__init__.py b/src/algopy/__init__.py index cb985807..a2b574d1 100644 --- a/src/algopy/__init__.py +++ b/src/algopy/__init__.py @@ -1,3 +1,4 @@ +# ruff: noqa: I001 from _algopy_testing.compiled import ( CompiledContract, CompiledLogicSig, @@ -33,6 +34,9 @@ from _algopy_testing.utilities import OpUpFeeSource, ensure_budget, log, size_of from . import arc4, gtxn, itxn, op +from _algopy_testing.decorators.arc4 import ( + abimethod as public, +) __all__ = [ "ARC4Contract", @@ -76,6 +80,7 @@ "log", "logicsig", "op", + "public", "size_of", "subroutine", "uenumerate", diff --git a/tests/arc4/test_abi_call.py b/tests/arc4/test_abi_call.py index b5d89209..14709d0e 100644 --- a/tests/arc4/test_abi_call.py +++ b/tests/arc4/test_abi_call.py @@ -4,12 +4,12 @@ import pytest from _algopy_testing import AlgopyTestContext, algopy_testing_context from _algopy_testing.itxn import ApplicationCallInnerTransaction -from algopy import ARC4Contract, arc4 +from algopy import ARC4Contract, arc4, public from pytest_mock import MockerFixture class Logger(ARC4Contract): - @arc4.abimethod + @public def echo(self, value: arc4.String) -> arc4.String: return "echo: " + value diff --git a/tests/artifacts/Arrays/data/StaticSizeContract.approval.teal b/tests/artifacts/Arrays/data/StaticSizeContract.approval.teal index 7d6b884e..eb1d5b8d 100644 --- a/tests/artifacts/Arrays/data/StaticSizeContract.approval.teal +++ b/tests/artifacts/Arrays/data/StaticSizeContract.approval.teal @@ -308,7 +308,7 @@ test_array_after_for@5: pushbytes "a" swap box_put - // tests/artifacts/Arrays/static_size.py:169 + // tests/artifacts/Arrays/static_size.py:168 // last_point = path[0] extract 0 144 // on error: index access is out of bounds dup @@ -319,24 +319,24 @@ test_array_after_for@5: intc_2 // 8 extract_uint64 bury 6 - // tests/artifacts/Arrays/static_size.py:170 + // tests/artifacts/Arrays/static_size.py:169 // length = UInt64() intc_0 // 0 bury 5 - // tests/artifacts/Arrays/static_size.py:171 + // tests/artifacts/Arrays/static_size.py:170 // for point_idx in urange(1, path.length): intc_1 // 1 bury 3 test_array_for_header@7: - // tests/artifacts/Arrays/static_size.py:171 + // tests/artifacts/Arrays/static_size.py:170 // for point_idx in urange(1, path.length): dig 2 dig 8 < bz test_array_after_for@15 dig 1 - // tests/artifacts/Arrays/static_size.py:172 + // tests/artifacts/Arrays/static_size.py:171 // point = path[point_idx] dig 3 intc 4 // 144 @@ -349,45 +349,45 @@ test_array_for_header@7: intc_2 // 8 extract_uint64 bury 6 - // tests/artifacts/Arrays/static_size.py:173 + // tests/artifacts/Arrays/static_size.py:172 // if point.x < last_point.x: dig 10 b< bz test_array_else_body@10 - // tests/artifacts/Arrays/static_size.py:174 + // tests/artifacts/Arrays/static_size.py:173 // dx = last_point.x.as_uint64() - point.x.as_uint64() dig 10 - // tests/artifacts/Arrays/static_size.py:169 + // tests/artifacts/Arrays/static_size.py:168 // last_point = path[0] intc_0 // 0 - // tests/artifacts/Arrays/static_size.py:174 + // tests/artifacts/Arrays/static_size.py:173 // dx = last_point.x.as_uint64() - point.x.as_uint64() extract_uint64 swap - // tests/artifacts/Arrays/static_size.py:172 + // tests/artifacts/Arrays/static_size.py:171 // point = path[point_idx] intc_0 // 0 - // tests/artifacts/Arrays/static_size.py:174 + // tests/artifacts/Arrays/static_size.py:173 // dx = last_point.x.as_uint64() - point.x.as_uint64() extract_uint64 - bury 7 test_array_after_if_else@11: - // tests/artifacts/Arrays/static_size.py:177 + // tests/artifacts/Arrays/static_size.py:176 // if point.y < last_point.y: dig 3 dig 6 < bz test_array_else_body@13 - // tests/artifacts/Arrays/static_size.py:178 + // tests/artifacts/Arrays/static_size.py:177 // dy = last_point.y - point.y dig 5 dig 4 - test_array_after_if_else@14: - // tests/artifacts/Arrays/static_size.py:181 + // tests/artifacts/Arrays/static_size.py:180 // length += op.sqrt(dx * dx + dy * dy) dig 7 dup @@ -400,7 +400,7 @@ test_array_after_if_else@14: dig 5 + bury 5 - // tests/artifacts/Arrays/static_size.py:171 + // tests/artifacts/Arrays/static_size.py:170 // for point_idx in urange(1, path.length): dig 2 intc_1 // 1 @@ -409,7 +409,7 @@ test_array_after_if_else@14: b test_array_for_header@7 test_array_else_body@13: - // tests/artifacts/Arrays/static_size.py:180 + // tests/artifacts/Arrays/static_size.py:179 // dy = point.y - last_point.y dig 3 dig 6 @@ -417,17 +417,17 @@ test_array_else_body@13: b test_array_after_if_else@14 test_array_else_body@10: - // tests/artifacts/Arrays/static_size.py:172 + // tests/artifacts/Arrays/static_size.py:171 // point = path[point_idx] intc_0 // 0 - // tests/artifacts/Arrays/static_size.py:176 + // tests/artifacts/Arrays/static_size.py:175 // dx = point.x.as_uint64() - last_point.x.as_uint64() extract_uint64 dig 10 - // tests/artifacts/Arrays/static_size.py:169 + // tests/artifacts/Arrays/static_size.py:168 // last_point = path[0] intc_0 // 0 - // tests/artifacts/Arrays/static_size.py:176 + // tests/artifacts/Arrays/static_size.py:175 // dx = point.x.as_uint64() - last_point.x.as_uint64() extract_uint64 - @@ -842,7 +842,7 @@ sum_array_after_for@5: // tests.artifacts.Arrays.static_size.StaticSizeContract.test_arc4_bool[routing]() -> void: test_arc4_bool: - // tests/artifacts/Arrays/static_size.py:143 + // tests/artifacts/Arrays/static_size.py:142 // arr.append(arc4.Bool(Txn.sender == Txn.receiver)) txn Sender txn Receiver @@ -851,7 +851,7 @@ test_arc4_bool: intc_0 // 0 uncover 2 setbit - // tests/artifacts/Arrays/static_size.py:144 + // tests/artifacts/Arrays/static_size.py:143 // arr.append(arc4.Bool(Txn.sender != Txn.receiver)) txn Sender txn Receiver @@ -862,13 +862,13 @@ test_arc4_bool: setbit concat // on error: max array length exceeded dupn 2 - // tests/artifacts/Arrays/static_size.py:147 + // tests/artifacts/Arrays/static_size.py:146 // dyn_arr.extend(arr) len - // tests/artifacts/Arrays/static_size.py:146 + // tests/artifacts/Arrays/static_size.py:145 // dyn_arr = arc4.DynamicArray[arc4.Bool]() bytec 4 // 0x0000 - // tests/artifacts/Arrays/static_size.py:147 + // tests/artifacts/Arrays/static_size.py:146 // dyn_arr.extend(arr) dig 2 uncover 2 @@ -876,7 +876,7 @@ test_arc4_bool: callsub dynamic_array_concat_bits dup cover 2 - // tests/artifacts/Arrays/static_size.py:148 + // tests/artifacts/Arrays/static_size.py:147 // assert dyn_arr.length == 2, "expected correct length" dup intc_0 // 0 @@ -887,14 +887,14 @@ test_arc4_bool: pushint 2 == assert // expected correct length - // tests/artifacts/Arrays/static_size.py:149 + // tests/artifacts/Arrays/static_size.py:148 // assert dyn_arr.bytes.length == 3, "expected 3 bytes" dig 1 len pushint 3 == assert // expected 3 bytes - // tests/artifacts/Arrays/static_size.py:150 + // tests/artifacts/Arrays/static_size.py:149 // assert dyn_arr[0] == (Txn.sender == Txn.receiver), "expected correct value at 0" dup assert // index access is out of bounds @@ -912,7 +912,7 @@ test_arc4_bool: == == assert // expected correct value at 0 - // tests/artifacts/Arrays/static_size.py:151 + // tests/artifacts/Arrays/static_size.py:150 // assert dyn_arr[1] == (Txn.sender != Txn.receiver), "expected correct value at 1" intc_1 // 1 > @@ -933,7 +933,7 @@ test_arc4_bool: intc_0 // 0 test_arc4_bool_for_header@2: - // tests/artifacts/Arrays/static_size.py:154-156 + // tests/artifacts/Arrays/static_size.py:153-155 // # note: not supported currently // # arr2.extend(dyn_array) // for b in dyn_arr: @@ -952,7 +952,7 @@ test_arc4_bool_for_header@2: uncover 2 setbit dig 3 - // tests/artifacts/Arrays/static_size.py:157 + // tests/artifacts/Arrays/static_size.py:156 // arr2.append(b) swap concat // on error: max array length exceeded @@ -964,14 +964,14 @@ test_arc4_bool_for_header@2: test_arc4_bool_after_for@5: dig 1 - // tests/artifacts/Arrays/static_size.py:158 + // tests/artifacts/Arrays/static_size.py:157 // assert arr2.length == 4, "expected correct length" dup len pushint 4 == assert // expected correct length - // tests/artifacts/Arrays/static_size.py:159 + // tests/artifacts/Arrays/static_size.py:158 // assert arr2[0] == (Txn.sender == Txn.receiver), "expected correct value at 0" dup extract 0 1 // on error: index access is out of bounds @@ -982,7 +982,7 @@ test_arc4_bool_after_for@5: == == assert // expected correct value at 0 - // tests/artifacts/Arrays/static_size.py:160 + // tests/artifacts/Arrays/static_size.py:159 // assert arr2[1] == (Txn.sender != Txn.receiver), "expected correct value at 1" dup extract 1 1 // on error: index access is out of bounds @@ -993,7 +993,7 @@ test_arc4_bool_after_for@5: != == assert // expected correct value at 1 - // tests/artifacts/Arrays/static_size.py:161 + // tests/artifacts/Arrays/static_size.py:160 // assert arr2[2] == (Txn.sender == Txn.receiver), "expected correct value at 2" dup extract 2 1 // on error: index access is out of bounds @@ -1004,7 +1004,7 @@ test_arc4_bool_after_for@5: == == assert // expected correct value at 2 - // tests/artifacts/Arrays/static_size.py:162 + // tests/artifacts/Arrays/static_size.py:161 // assert arr2[3] == (Txn.sender != Txn.receiver), "expected correct value at 3" extract 3 1 // on error: index access is out of bounds intc_0 // 0 @@ -1015,7 +1015,7 @@ test_arc4_bool_after_for@5: == assert // expected correct value at 3 dig 4 - // tests/artifacts/Arrays/static_size.py:164 + // tests/artifacts/Arrays/static_size.py:163 // return arr.freeze() dup len @@ -1023,7 +1023,7 @@ test_arc4_bool_after_for@5: cover 2 intc_2 // 8 callsub dynamic_array_concat_bits - // tests/artifacts/Arrays/static_size.py:140 + // tests/artifacts/Arrays/static_size.py:139 // @arc4.abimethod() bytec_1 // 0x151f7c75 swap @@ -1035,7 +1035,7 @@ test_arc4_bool_after_for@5: // tests.artifacts.Arrays.static_size.StaticSizeContract.xtra() -> uint64, uint64, bytes, bytes, bytes: xtra: - // tests/artifacts/Arrays/static_size.py:127 + // tests/artifacts/Arrays/static_size.py:126 // self.count += 1 intc_0 // 0 bytec_2 // "count" @@ -1046,23 +1046,23 @@ xtra: bytec_2 // "count" dig 1 app_global_put - // tests/artifacts/Arrays/static_size.py:129 + // tests/artifacts/Arrays/static_size.py:128 // a=Txn.num_app_args, txn NumAppArgs - // tests/artifacts/Arrays/static_size.py:131 + // tests/artifacts/Arrays/static_size.py:130 // c=Txn.sender, txn Sender - // tests/artifacts/Arrays/static_size.py:132 + // tests/artifacts/Arrays/static_size.py:131 // d=self.more(), callsub more - // tests/artifacts/Arrays/static_size.py:133 + // tests/artifacts/Arrays/static_size.py:132 // e=BigUInt(self.count), intc_0 // 0 bytec_2 // "count" app_global_get_ex assert // check self.count exists itob - // tests/artifacts/Arrays/static_size.py:128-134 + // tests/artifacts/Arrays/static_size.py:127-133 // return Xtra( // a=Txn.num_app_args, // b=self.count, @@ -1077,7 +1077,7 @@ xtra: // tests.artifacts.Arrays.static_size.StaticSizeContract.more() -> bytes: more: - // tests/artifacts/Arrays/static_size.py:138 + // tests/artifacts/Arrays/static_size.py:137 // return More(foo=arc4.UInt64(self.count + 1), bar=arc4.UInt64(self.count * self.count)) intc_0 // 0 bytec_2 // "count" diff --git a/tests/artifacts/Arrays/data/StaticSizeContract.arc56.json b/tests/artifacts/Arrays/data/StaticSizeContract.arc56.json index 28fa8c41..9d298665 100644 --- a/tests/artifacts/Arrays/data/StaticSizeContract.arc56.json +++ b/tests/artifacts/Arrays/data/StaticSizeContract.arc56.json @@ -302,7 +302,7 @@ } }, "source": { - "approval": "I3ByYWdtYSB2ZXJzaW9uIDExCiNwcmFnbWEgdHlwZXRyYWNrIGZhbHNlCgovLyBhbGdvcHkuYXJjNC5BUkM0Q29udHJhY3QuYXBwcm92YWxfcHJvZ3JhbSgpIC0+IHVpbnQ2NDoKbWFpbjoKICAgIGludGNibG9jayAwIDEgOCAxNiAxNDQKICAgIGJ5dGVjYmxvY2sgMHggMHgxNTFmN2M3NSAiY291bnQiIDB4MDAgMHgwMDAwCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYm56IG1haW5fYWZ0ZXJfaWZfZWxzZUAyCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvQXJyYXlzL3N0YXRpY19zaXplLnB5OjM5CiAgICAvLyBzZWxmLmNvdW50ID0gVUludDY0KDApCiAgICBieXRlY18yIC8vICJjb3VudCIKICAgIGludGNfMCAvLyAwCiAgICBhcHBfZ2xvYmFsX3B1dAoKbWFpbl9hZnRlcl9pZl9lbHNlQDI6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvQXJyYXlzL3N0YXRpY19zaXplLnB5OjM3CiAgICAvLyBjbGFzcyBTdGF0aWNTaXplQ29udHJhY3QoYXJjNC5BUkM0Q29udHJhY3QpOgogICAgdHhuIE51bUFwcEFyZ3MKICAgIGJ6IG1haW5fX19hbGdvcHlfZGVmYXVsdF9jcmVhdGVAMTYKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydAogICAgcHVzaGJ5dGVzcyAweDI4ZDdjMWI4IDB4ZmE5Y2I5NzMgMHg2MDM5YTI0MCAweGY4ZmQ2OGE3IDB4MWYwMjhkYjEgMHgwOTZiM2E1OSAweDhkNmUzYTI1IC8vIG1ldGhvZCAidGVzdF9hcnJheSh1aW50NjQsdWludDY0LHVpbnQ2NCx1aW50NjQpdWludDY0IiwgbWV0aG9kICJ0ZXN0X2V4dGVuZF9mcm9tX3R1cGxlKCgodWludDY0LHVpbnQ2NCksKHVpbnQ2NCx1aW50NjQpKSkodWludDY0LHVpbnQ2NClbXSIsIG1ldGhvZCAidGVzdF9leHRlbmRfZnJvbV9hcmM0X3R1cGxlKCgodWludDY0LHVpbnQ2NCksKHVpbnQ2NCx1aW50NjQpKSkodWludDY0LHVpbnQ2NClbXSIsIG1ldGhvZCAidGVzdF9ib29sX2FycmF5KHVpbnQ2NCl1aW50NjQiLCBtZXRob2QgInRlc3RfYXJjNF9jb252ZXJzaW9uKHVpbnQ2NCl1aW50NjRbXSIsIG1ldGhvZCAic3VtX2FycmF5KHVpbnQ2NFtdKXVpbnQ2NCIsIG1ldGhvZCAidGVzdF9hcmM0X2Jvb2woKWJvb2xbXSIKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDAKICAgIG1hdGNoIHRlc3RfYXJyYXkgdGVzdF9leHRlbmRfZnJvbV90dXBsZSB0ZXN0X2V4dGVuZF9mcm9tX2FyYzRfdHVwbGUgdGVzdF9ib29sX2FycmF5IHRlc3RfYXJjNF9jb252ZXJzaW9uIHN1bV9hcnJheSB0ZXN0X2FyYzRfYm9vbAogICAgZXJyCgptYWluX19fYWxnb3B5X2RlZmF1bHRfY3JlYXRlQDE2OgogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgICEKICAgICYmCiAgICByZXR1cm4KCgovLyBfcHV5YV9saWIuYXJjNC5keW5hbWljX2FycmF5X2NvbmNhdF9iaXRzKGFycmF5OiBieXRlcywgbmV3X2l0ZW1zX2J5dGVzOiBieXRlcywgbmV3X2l0ZW1zX2NvdW50OiB1aW50NjQsIHJlYWRfc3RlcDogdWludDY0KSAtPiBieXRlczoKZHluYW1pY19hcnJheV9jb25jYXRfYml0czoKICAgIHByb3RvIDQgMQogICAgYnl0ZWNfMCAvLyAiIgogICAgZHVwbiAyCiAgICBmcmFtZV9kaWcgLTQKICAgIGludGNfMCAvLyAwCiAgICBleHRyYWN0X3VpbnQxNgogICAgZHVwbiAyCiAgICBmcmFtZV9kaWcgLTIKICAgICsKICAgIGR1cAogICAgaXRvYgogICAgZXh0cmFjdCA2IDAKICAgIGZyYW1lX2RpZyAtNAogICAgc3dhcAogICAgcmVwbGFjZTIgMAogICAgY292ZXIgMgogICAgc3dhcAogICAgcHVzaGludCA3CiAgICArCiAgICBpbnRjXzIgLy8gOAogICAgLwogICAgZHVwCiAgICB1bmNvdmVyIDIKICAgIHB1c2hpbnQgNwogICAgKwogICAgaW50Y18yIC8vIDgKICAgIC8KICAgIGR1cAogICAgY292ZXIgMgogICAgPAogICAgYnogZHluYW1pY19hcnJheV9jb25jYXRfYml0c19hZnRlcl9pZl9lbHNlQDIKICAgIGZyYW1lX2RpZyA2CiAgICBmcmFtZV9kaWcgNQogICAgLQogICAgYnplcm8KICAgIGZyYW1lX2RpZyA0CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGZyYW1lX2J1cnkgNAoKZHluYW1pY19hcnJheV9jb25jYXRfYml0c19hZnRlcl9pZl9lbHNlQDI6CiAgICBpbnRjXzAgLy8gMAogICAgZnJhbWVfYnVyeSAwCiAgICBmcmFtZV9kaWcgMwogICAgaW50Y18zIC8vIDE2CiAgICArCiAgICBkdXAKICAgIGZyYW1lX2J1cnkgMgogICAgZnJhbWVfZGlnIC0yCiAgICArCiAgICBmcmFtZV9idXJ5IDEKCmR5bmFtaWNfYXJyYXlfY29uY2F0X2JpdHNfd2hpbGVfdG9wQDM6CiAgICBmcmFtZV9kaWcgMgogICAgZnJhbWVfZGlnIDEKICAgIDwKICAgIGJ6IGR5bmFtaWNfYXJyYXlfY29uY2F0X2JpdHNfYWZ0ZXJfd2hpbGVANQogICAgZnJhbWVfZGlnIC0zCiAgICBmcmFtZV9kaWcgMAogICAgZHVwCiAgICBjb3ZlciAyCiAgICBnZXRiaXQKICAgIGZyYW1lX2RpZyA0CiAgICBmcmFtZV9kaWcgMgogICAgZHVwCiAgICBjb3ZlciAzCiAgICB1bmNvdmVyIDIKICAgIHNldGJpdAogICAgZnJhbWVfYnVyeSA0CiAgICBpbnRjXzEgLy8gMQogICAgKwogICAgZnJhbWVfYnVyeSAyCiAgICBmcmFtZV9kaWcgLTEKICAgICsKICAgIGZyYW1lX2J1cnkgMAogICAgYiBkeW5hbWljX2FycmF5X2NvbmNhdF9iaXRzX3doaWxlX3RvcEAzCgpkeW5hbWljX2FycmF5X2NvbmNhdF9iaXRzX2FmdGVyX3doaWxlQDU6CiAgICBmcmFtZV9kaWcgNAogICAgZnJhbWVfYnVyeSAwCiAgICByZXRzdWIKCgovLyB0ZXN0cy5hcnRpZmFjdHMuQXJyYXlzLnN0YXRpY19zaXplLlN0YXRpY1NpemVDb250cmFjdC50ZXN0X2FycmF5W3JvdXRpbmddKCkgLT4gdm9pZDoKdGVzdF9hcnJheToKICAgIGludGNfMCAvLyAwCiAgICBkdXAKICAgIGJ5dGVjXzAgLy8gIiIKICAgIGR1cG4gNQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL0FycmF5cy9zdGF0aWNfc2l6ZS5weTo0MQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDIKICAgIGJ0b2kKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDMKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDQKICAgIGJ0b2kKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9BcnJheXMvc3RhdGljX3NpemUucHk6NDMKICAgIC8vIHNlbGYuY291bnQgPSBVSW50NjQoMCkKICAgIGJ5dGVjXzIgLy8gImNvdW50IgogICAgaW50Y18wIC8vIDAKICAgIGFwcF9nbG9iYWxfcHV0CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvQXJyYXlzL3N0YXRpY19zaXplLnB5OjQ2CiAgICAvLyBQb2ludCh4PWFyYzQuVUludDY0KCksIHk9VUludDY0KCksIG90aGVyPXNlbGYueHRyYSgpKSwKICAgIGNhbGxzdWIgeHRyYQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL0FycmF5cy9zdGF0aWNfc2l6ZS5weTo0NwogICAgLy8gUG9pbnQoeD14MSwgeT15MSwgb3RoZXI9c2VsZi54dHJhKCkpLAogICAgY2FsbHN1YiB4dHJhCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvQXJyYXlzL3N0YXRpY19zaXplLnB5OjQ4CiAgICAvLyBQb2ludCh4PXgyLCB5PXkyLCBvdGhlcj1zZWxmLnh0cmEoKSksCiAgICBjYWxsc3ViIHh0cmEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9BcnJheXMvc3RhdGljX3NpemUucHk6NDQtNTAKICAgIC8vIHBhdGggPSBSZWZlcmVuY2VBcnJheSgKICAgIC8vICAgICAoCiAgICAvLyAgICAgICAgIFBvaW50KHg9YXJjNC5VSW50NjQoKSwgeT1VSW50NjQoKSwgb3RoZXI9c2VsZi54dHJhKCkpLAogICAgLy8gICAgICAgICBQb2ludCh4PXgxLCB5PXkxLCBvdGhlcj1zZWxmLnh0cmEoKSksCiAgICAvLyAgICAgICAgIFBvaW50KHg9eDIsIHk9eTIsIG90aGVyPXNlbGYueHRyYSgpKSwKICAgIC8vICAgICApCiAgICAvLyApCiAgICB1bmNvdmVyIDE0CiAgICBpdG9iCiAgICB1bmNvdmVyIDE0CiAgICBpdG9iCiAgICBjb25jYXQKICAgIHVuY292ZXIgMTMKICAgIGNvbmNhdAogICAgdW5jb3ZlciAxMgogICAgY29uY2F0CiAgICBkaWcgMTEKICAgIGxlbgogICAgcHVzaGludCA2NAogICAgPD0KICAgIGFzc2VydCAvLyBvdmVyZmxvdwogICAgcHVzaGludCA2NAogICAgYnplcm8KICAgIHVuY292ZXIgMTIKICAgIGRpZyAxCiAgICBifAogICAgdW5jb3ZlciAyCiAgICBzd2FwCiAgICBjb25jYXQKICAgIHB1c2hieXRlcyAweDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwCiAgICBzd2FwCiAgICBjb25jYXQKICAgIHVuY292ZXIgMTQKICAgIGl0b2IKICAgIHVuY292ZXIgMTUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgdW5jb3ZlciAxMgogICAgaXRvYgogICAgdW5jb3ZlciAxMgogICAgaXRvYgogICAgY29uY2F0CiAgICB1bmNvdmVyIDExCiAgICBjb25jYXQKICAgIHVuY292ZXIgMTAKICAgIGNvbmNhdAogICAgZGlnIDkKICAgIGxlbgogICAgcHVzaGludCA2NAogICAgPD0KICAgIGFzc2VydCAvLyBvdmVyZmxvdwogICAgdW5jb3ZlciA5CiAgICBkaWcgNAogICAgYnwKICAgIGNvbmNhdAogICAgY29uY2F0CiAgICBjb25jYXQKICAgIHVuY292ZXIgNwogICAgaXRvYgogICAgdW5jb3ZlciA4CiAgICBzd2FwCiAgICBjb25jYXQKICAgIHVuY292ZXIgNwogICAgaXRvYgogICAgdW5jb3ZlciA3CiAgICBpdG9iCiAgICBjb25jYXQKICAgIHVuY292ZXIgNgogICAgY29uY2F0CiAgICB1bmNvdmVyIDUKICAgIGNvbmNhdAogICAgZGlnIDQKICAgIGxlbgogICAgcHVzaGludCA2NAogICAgPD0KICAgIGFzc2VydCAvLyBvdmVyZmxvdwogICAgdW5jb3ZlciA0CiAgICB1bmNvdmVyIDQKICAgIGJ8CiAgICBjb25jYXQKICAgIGNvbmNhdAogICAgY29uY2F0CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvQXJyYXlzL3N0YXRpY19zaXplLnB5OjUxCiAgICAvLyBmb3IgaSBpbiB1cmFuZ2UoMyk6CiAgICBpbnRjXzAgLy8gMAoKdGVzdF9hcnJheV9mb3JfaGVhZGVyQDI6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvQXJyYXlzL3N0YXRpY19zaXplLnB5OjUxCiAgICAvLyBmb3IgaSBpbiB1cmFuZ2UoMyk6CiAgICBkdXAKICAgIHB1c2hpbnQgMwogICAgPAogICAgYnogdGVzdF9hcnJheV9hZnRlcl9mb3JANQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL0FycmF5cy9zdGF0aWNfc2l6ZS5weTo1MgogICAgLy8gYXNzZXJ0IHBhdGhbaV0ub3RoZXIuYiA9PSBpICsgMQogICAgZHVwMgogICAgZHVwCiAgICBjb3ZlciAyCiAgICBpbnRjIDQgLy8gMTQ0CiAgICAqCiAgICBpbnRjIDQgLy8gMTQ0CiAgICBleHRyYWN0MyAvLyBvbiBlcnJvcjogaW5kZXggYWNjZXNzIGlzIG91dCBvZiBib3VuZHMKICAgIGV4dHJhY3QgMTYgMTI4CiAgICBkdXAKICAgIGludGNfMiAvLyA4CiAgICBleHRyYWN0X3VpbnQ2NAogICAgZGlnIDIKICAgIGludGNfMSAvLyAxCiAgICArCiAgICBzd2FwCiAgICBkaWcgMQogICAgPT0KICAgIGFzc2VydAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL0FycmF5cy9zdGF0aWNfc2l6ZS5weTo1MwogICAgLy8gYXNzZXJ0IHBhdGhbaV0ub3RoZXIuZC5mb28gPT0gaSArIDIKICAgIHN3YXAKICAgIGV4dHJhY3QgNDggMTYKICAgIGR1cAogICAgZXh0cmFjdCAwIDgKICAgIHVuY292ZXIgMwogICAgcHVzaGludCAyCiAgICArCiAgICBpdG9iCiAgICBiPT0KICAgIGFzc2VydAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL0FycmF5cy9zdGF0aWNfc2l6ZS5weTo1NAogICAgLy8gYXNzZXJ0IHBhdGhbaV0ub3RoZXIuZC5iYXIgPT0gKGkgKyAxKSAqIChpICsgMSkKICAgIGV4dHJhY3QgOCA4CiAgICBkaWcgMQogICAgZGlnIDIKICAgICoKICAgIGl0b2IKICAgIGI9PQogICAgYXNzZXJ0CiAgICBidXJ5IDEKICAgIGIgdGVzdF9hcnJheV9mb3JfaGVhZGVyQDIKCnRlc3RfYXJyYXlfYWZ0ZXJfZm9yQDU6CiAgICBkaWcgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL0FycmF5cy9zdGF0aWNfc2l6ZS5weTo1NgogICAgLy8gQm94KEltbXV0YWJsZUFycmF5W1BvaW50XSwga2V5PSJhIikudmFsdWUgPSBwYXRoLmZyZWV6ZSgpCiAgICBkdXAKICAgIGxlbgogICAgaW50YyA0IC8vIDE0NAogICAgLwogICAgZHVwCiAgICBidXJ5IDEwCiAgICBpdG9iCiAgICBleHRyYWN0IDYgMgogICAgZGlnIDEKICAgIGNvbmNhdAogICAgcHVzaGJ5dGVzICJhIgogICAgYm94X2RlbAogICAgcG9wCiAgICBwdXNoYnl0ZXMgImEiCiAgICBzd2FwCiAgICBib3hfcHV0CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvQXJyYXlzL3N0YXRpY19zaXplLnB5OjE2OQogICAgLy8gbGFzdF9wb2ludCA9IHBhdGhbMF0KICAgIGV4dHJhY3QgMCAxNDQgLy8gb24gZXJyb3I6IGluZGV4IGFjY2VzcyBpcyBvdXQgb2YgYm91bmRzCiAgICBkdXAKICAgIGJ1cnkgMTEKICAgIGR1cAogICAgZXh0cmFjdCAwIDgKICAgIGJ1cnkgMTAKICAgIGludGNfMiAvLyA4CiAgICBleHRyYWN0X3VpbnQ2NAogICAgYnVyeSA2CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvQXJyYXlzL3N0YXRpY19zaXplLnB5OjE3MAogICAgLy8gbGVuZ3RoID0gVUludDY0KCkKICAgIGludGNfMCAvLyAwCiAgICBidXJ5IDUKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9BcnJheXMvc3RhdGljX3NpemUucHk6MTcxCiAgICAvLyBmb3IgcG9pbnRfaWR4IGluIHVyYW5nZSgxLCBwYXRoLmxlbmd0aCk6CiAgICBpbnRjXzEgLy8gMQogICAgYnVyeSAzCgp0ZXN0X2FycmF5X2Zvcl9oZWFkZXJANzoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9BcnJheXMvc3RhdGljX3NpemUucHk6MTcxCiAgICAvLyBmb3IgcG9pbnRfaWR4IGluIHVyYW5nZSgxLCBwYXRoLmxlbmd0aCk6CiAgICBkaWcgMgogICAgZGlnIDgKICAgIDwKICAgIGJ6IHRlc3RfYXJyYXlfYWZ0ZXJfZm9yQDE1CiAgICBkaWcgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL0FycmF5cy9zdGF0aWNfc2l6ZS5weToxNzIKICAgIC8vIHBvaW50ID0gcGF0aFtwb2ludF9pZHhdCiAgICBkaWcgMwogICAgaW50YyA0IC8vIDE0NAogICAgKgogICAgaW50YyA0IC8vIDE0NAogICAgZXh0cmFjdDMgLy8gb24gZXJyb3I6IGluZGV4IGFjY2VzcyBpcyBvdXQgb2YgYm91bmRzCiAgICBkdXBuIDIKICAgIGV4dHJhY3QgMCA4CiAgICBzd2FwCiAgICBpbnRjXzIgLy8gOAogICAgZXh0cmFjdF91aW50NjQKICAgIGJ1cnkgNgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL0FycmF5cy9zdGF0aWNfc2l6ZS5weToxNzMKICAgIC8vIGlmIHBvaW50LnggPCBsYXN0X3BvaW50Lng6CiAgICBkaWcgMTAKICAgIGI8CiAgICBieiB0ZXN0X2FycmF5X2Vsc2VfYm9keUAxMAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL0FycmF5cy9zdGF0aWNfc2l6ZS5weToxNzQKICAgIC8vIGR4ID0gbGFzdF9wb2ludC54LmFzX3VpbnQ2NCgpIC0gcG9pbnQueC5hc191aW50NjQoKQogICAgZGlnIDEwCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvQXJyYXlzL3N0YXRpY19zaXplLnB5OjE2OQogICAgLy8gbGFzdF9wb2ludCA9IHBhdGhbMF0KICAgIGludGNfMCAvLyAwCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvQXJyYXlzL3N0YXRpY19zaXplLnB5OjE3NAogICAgLy8gZHggPSBsYXN0X3BvaW50LnguYXNfdWludDY0KCkgLSBwb2ludC54LmFzX3VpbnQ2NCgpCiAgICBleHRyYWN0X3VpbnQ2NAogICAgc3dhcAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL0FycmF5cy9zdGF0aWNfc2l6ZS5weToxNzIKICAgIC8vIHBvaW50ID0gcGF0aFtwb2ludF9pZHhdCiAgICBpbnRjXzAgLy8gMAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL0FycmF5cy9zdGF0aWNfc2l6ZS5weToxNzQKICAgIC8vIGR4ID0gbGFzdF9wb2ludC54LmFzX3VpbnQ2NCgpIC0gcG9pbnQueC5hc191aW50NjQoKQogICAgZXh0cmFjdF91aW50NjQKICAgIC0KICAgIGJ1cnkgNwoKdGVzdF9hcnJheV9hZnRlcl9pZl9lbHNlQDExOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL0FycmF5cy9zdGF0aWNfc2l6ZS5weToxNzcKICAgIC8vIGlmIHBvaW50LnkgPCBsYXN0X3BvaW50Lnk6CiAgICBkaWcgMwogICAgZGlnIDYKICAgIDwKICAgIGJ6IHRlc3RfYXJyYXlfZWxzZV9ib2R5QDEzCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvQXJyYXlzL3N0YXRpY19zaXplLnB5OjE3OAogICAgLy8gZHkgPSBsYXN0X3BvaW50LnkgLSBwb2ludC55CiAgICBkaWcgNQogICAgZGlnIDQKICAgIC0KCnRlc3RfYXJyYXlfYWZ0ZXJfaWZfZWxzZUAxNDoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9BcnJheXMvc3RhdGljX3NpemUucHk6MTgxCiAgICAvLyBsZW5ndGggKz0gb3Auc3FydChkeCAqIGR4ICsgZHkgKiBkeSkKICAgIGRpZyA3CiAgICBkdXAKICAgICoKICAgIHN3YXAKICAgIGR1cAogICAgKgogICAgKwogICAgc3FydAogICAgZGlnIDUKICAgICsKICAgIGJ1cnkgNQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL0FycmF5cy9zdGF0aWNfc2l6ZS5weToxNzEKICAgIC8vIGZvciBwb2ludF9pZHggaW4gdXJhbmdlKDEsIHBhdGgubGVuZ3RoKToKICAgIGRpZyAyCiAgICBpbnRjXzEgLy8gMQogICAgKwogICAgYnVyeSAzCiAgICBiIHRlc3RfYXJyYXlfZm9yX2hlYWRlckA3Cgp0ZXN0X2FycmF5X2Vsc2VfYm9keUAxMzoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9BcnJheXMvc3RhdGljX3NpemUucHk6MTgwCiAgICAvLyBkeSA9IHBvaW50LnkgLSBsYXN0X3BvaW50LnkKICAgIGRpZyAzCiAgICBkaWcgNgogICAgLQogICAgYiB0ZXN0X2FycmF5X2FmdGVyX2lmX2Vsc2VAMTQKCnRlc3RfYXJyYXlfZWxzZV9ib2R5QDEwOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL0FycmF5cy9zdGF0aWNfc2l6ZS5weToxNzIKICAgIC8vIHBvaW50ID0gcGF0aFtwb2ludF9pZHhdCiAgICBpbnRjXzAgLy8gMAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL0FycmF5cy9zdGF0aWNfc2l6ZS5weToxNzYKICAgIC8vIGR4ID0gcG9pbnQueC5hc191aW50NjQoKSAtIGxhc3RfcG9pbnQueC5hc191aW50NjQoKQogICAgZXh0cmFjdF91aW50NjQKICAgIGRpZyAxMAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL0FycmF5cy9zdGF0aWNfc2l6ZS5weToxNjkKICAgIC8vIGxhc3RfcG9pbnQgPSBwYXRoWzBdCiAgICBpbnRjXzAgLy8gMAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL0FycmF5cy9zdGF0aWNfc2l6ZS5weToxNzYKICAgIC8vIGR4ID0gcG9pbnQueC5hc191aW50NjQoKSAtIGxhc3RfcG9pbnQueC5hc191aW50NjQoKQogICAgZXh0cmFjdF91aW50NjQKICAgIC0KICAgIGJ1cnkgNwogICAgYiB0ZXN0X2FycmF5X2FmdGVyX2lmX2Vsc2VAMTEKCnRlc3RfYXJyYXlfYWZ0ZXJfZm9yQDE1OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL0FycmF5cy9zdGF0aWNfc2l6ZS5weTo0MQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGRpZyA0CiAgICBpdG9iCiAgICBieXRlY18xIC8vIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnRjXzEgLy8gMQogICAgcmV0dXJuCgoKLy8gdGVzdHMuYXJ0aWZhY3RzLkFycmF5cy5zdGF0aWNfc2l6ZS5TdGF0aWNTaXplQ29udHJhY3QudGVzdF9leHRlbmRfZnJvbV90dXBsZVtyb3V0aW5nXSgpIC0+IHZvaWQ6CnRlc3RfZXh0ZW5kX2Zyb21fdHVwbGU6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvQXJyYXlzL3N0YXRpY19zaXplLnB5OjU5CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgZHVwCiAgICBleHRyYWN0IDAgMTYKICAgIHN3YXAKICAgIGV4dHJhY3QgMTYgMTYKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9BcnJheXMvc3RhdGljX3NpemUucHk6NjIKICAgIC8vIGFyci5leHRlbmQoc29tZV9tb3JlKQogICAgc3dhcAogICAgZGlnIDEKICAgIGNvbmNhdAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL0FycmF5cy9zdGF0aWNfc2l6ZS5weTo2MwogICAgLy8gbGFzdCA9IGFyclstMV0KICAgIGR1cAogICAgbGVuCiAgICBpbnRjXzMgLy8gMTYKICAgIC8KICAgIGR1cAogICAgaW50Y18xIC8vIDEKICAgIC0KICAgIGludGNfMyAvLyAxNgogICAgKgogICAgZGlnIDIKICAgIHN3YXAKICAgIGludGNfMyAvLyAxNgogICAgZXh0cmFjdDMgLy8gb24gZXJyb3I6IGluZGV4IGFjY2VzcyBpcyBvdXQgb2YgYm91bmRzCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvQXJyYXlzL3N0YXRpY19zaXplLnB5OjY0CiAgICAvLyBhc3NlcnQgbGFzdCA9PSBzb21lX21vcmVbMV0KICAgIGR1cAogICAgdW5jb3ZlciA0CiAgICA9PQogICAgYXNzZXJ0CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvQXJyYXlzL3N0YXRpY19zaXplLnB5OjY1CiAgICAvLyByZXN1bHQgPSBhcnIuZnJlZXplKCkKICAgIHN3YXAKICAgIGl0b2IKICAgIGV4dHJhY3QgNiAyCiAgICB1bmNvdmVyIDIKICAgIGNvbmNhdAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL0FycmF5cy9zdGF0aWNfc2l6ZS5weTo2NgogICAgLy8gYXNzZXJ0IHJlc3VsdFstMV0gPT0gbGFzdAogICAgZHVwCiAgICBpbnRjXzAgLy8gMAogICAgZXh0cmFjdF91aW50MTYgLy8gb24gZXJyb3I6IGludmFsaWQgYXJyYXkgbGVuZ3RoIGhlYWRlcgogICAgaW50Y18xIC8vIDEKICAgIC0KICAgIGRpZyAxCiAgICBleHRyYWN0IDIgMAogICAgc3dhcAogICAgaW50Y18zIC8vIDE2CiAgICAqCiAgICBpbnRjXzMgLy8gMTYKICAgIGV4dHJhY3QzIC8vIG9uIGVycm9yOiBpbmRleCBhY2Nlc3MgaXMgb3V0IG9mIGJvdW5kcwogICAgdW5jb3ZlciAyCiAgICA9PQogICAgYXNzZXJ0CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvQXJyYXlzL3N0YXRpY19zaXplLnB5OjU5CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgYnl0ZWNfMSAvLyAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50Y18xIC8vIDEKICAgIHJldHVybgoKCi8vIHRlc3RzLmFydGlmYWN0cy5BcnJheXMuc3RhdGljX3NpemUuU3RhdGljU2l6ZUNvbnRyYWN0LnRlc3RfZXh0ZW5kX2Zyb21fYXJjNF90dXBsZVtyb3V0aW5nXSgpIC0+IHZvaWQ6CnRlc3RfZXh0ZW5kX2Zyb21fYXJjNF90dXBsZToKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9BcnJheXMvc3RhdGljX3NpemUucHk6NjkKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvQXJyYXlzL3N0YXRpY19zaXplLnB5Ojc1CiAgICAvLyByZXR1cm4gYXJyLmZyZWV6ZSgpCiAgICBkdXAKICAgIGxlbgogICAgaW50Y18zIC8vIDE2CiAgICAvCiAgICBpdG9iCiAgICBleHRyYWN0IDYgMgogICAgc3dhcAogICAgY29uY2F0CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvQXJyYXlzL3N0YXRpY19zaXplLnB5OjY5CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgYnl0ZWNfMSAvLyAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50Y18xIC8vIDEKICAgIHJldHVybgoKCi8vIHRlc3RzLmFydGlmYWN0cy5BcnJheXMuc3RhdGljX3NpemUuU3RhdGljU2l6ZUNvbnRyYWN0LnRlc3RfYm9vbF9hcnJheVtyb3V0aW5nXSgpIC0+IHZvaWQ6CnRlc3RfYm9vbF9hcnJheToKICAgIGJ5dGVjXzAgLy8gIiIKICAgIGR1cG4gMgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL0FycmF5cy9zdGF0aWNfc2l6ZS5weTo3NwogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGJ0b2kKICAgIGR1cAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL0FycmF5cy9zdGF0aWNfc2l6ZS5weTo3OQogICAgLy8gYXJyID0gUmVmZXJlbmNlQXJyYXlbYm9vbF0oKQogICAgYnl0ZWNfMCAvLyAweAogICAgc3dhcAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL0FycmF5cy9zdGF0aWNfc2l6ZS5weTo4MgogICAgLy8gZm9yIGkgaW4gdXJhbmdlKDEsIGxlbmd0aCArIDEpOgogICAgaW50Y18xIC8vIDEKICAgICsKICAgIGludGNfMSAvLyAxCgp0ZXN0X2Jvb2xfYXJyYXlfZm9yX2hlYWRlckAyOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL0FycmF5cy9zdGF0aWNfc2l6ZS5weTo4MgogICAgLy8gZm9yIGkgaW4gdXJhbmdlKDEsIGxlbmd0aCArIDEpOgogICAgZHVwCiAgICBkaWcgMgogICAgPAogICAgYnogdGVzdF9ib29sX2FycmF5X2FmdGVyX2ZvckA1CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvQXJyYXlzL3N0YXRpY19zaXplLnB5OjgzCiAgICAvLyBhcnIuYXBwZW5kKGkgJSAyID09IDApCiAgICBkdXBuIDIKICAgIHB1c2hpbnQgMgogICAgJQogICAgIQogICAgZGlnIDQKICAgIHN3YXAKICAgIGJ5dGVjXzMgLy8gMHgwMAogICAgaW50Y18wIC8vIDAKICAgIHVuY292ZXIgMgogICAgc2V0Yml0CiAgICBjb25jYXQgLy8gb24gZXJyb3I6IG1heCBhcnJheSBsZW5ndGggZXhjZWVkZWQKICAgIGJ1cnkgNAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL0FycmF5cy9zdGF0aWNfc2l6ZS5weTo4MgogICAgLy8gZm9yIGkgaW4gdXJhbmdlKDEsIGxlbmd0aCArIDEpOgogICAgaW50Y18xIC8vIDEKICAgICsKICAgIGJ1cnkgMQogICAgYiB0ZXN0X2Jvb2xfYXJyYXlfZm9yX2hlYWRlckAyCgp0ZXN0X2Jvb2xfYXJyYXlfYWZ0ZXJfZm9yQDU6CiAgICBkaWcgMgogICAgZHVwbiAyCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvQXJyYXlzL3N0YXRpY19zaXplLnB5Ojg0CiAgICAvLyBhc3NlcnQgYXJyLmxlbmd0aCA9PSBsZW5ndGgsICJleHBlY3RlZCBjb3JyZWN0IGxlbmd0aCIKICAgIGxlbgogICAgZGlnIDYKICAgIGR1cAogICAgY292ZXIgNAogICAgPT0KICAgIGFzc2VydCAvLyBleHBlY3RlZCBjb3JyZWN0IGxlbmd0aAogICAgZGlnIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9BcnJheXMvc3RhdGljX3NpemUucHk6ODcKICAgIC8vIGFycjIuZXh0ZW5kKGFycikKICAgIGNvbmNhdCAvLyBvbiBlcnJvcjogbWF4IGFycmF5IGxlbmd0aCBleGNlZWRlZAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL0FycmF5cy9zdGF0aWNfc2l6ZS5weTo4OAogICAgLy8gYXNzZXJ0IGFycjIubGVuZ3RoID09IGxlbmd0aCAqIDIsICJleHBlY3RlZCBjb3JyZWN0IGxlbmd0aCIKICAgIGxlbgogICAgdW5jb3ZlciAyCiAgICBwdXNoaW50IDIKICAgICoKICAgID09CiAgICBhc3NlcnQgLy8gZXhwZWN0ZWQgY29ycmVjdCBsZW5ndGgKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9BcnJheXMvc3RhdGljX3NpemUucHk6OTAKICAgIC8vIGNvdW50ID0gVUludDY0KDApCiAgICBpbnRjXzAgLy8gMAogICAgYnVyeSA3CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvQXJyYXlzL3N0YXRpY19zaXplLnB5OjkxCiAgICAvLyBmb3IgdmFsIGluIGFycjoKICAgIGxlbgogICAgYnVyeSA3CiAgICBpbnRjXzAgLy8gMAogICAgYnVyeSA1Cgp0ZXN0X2Jvb2xfYXJyYXlfZm9yX2hlYWRlckA2OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL0FycmF5cy9zdGF0aWNfc2l6ZS5weTo5MQogICAgLy8gZm9yIHZhbCBpbiBhcnI6CiAgICBkaWcgNAogICAgZGlnIDcKICAgIDwKICAgIGJ6IHRlc3RfYm9vbF9hcnJheV9hZnRlcl9mb3JAMTEKICAgIGRpZyAyCiAgICBkaWcgNQogICAgaW50Y18xIC8vIDEKICAgIGV4dHJhY3QzIC8vIG9uIGVycm9yOiBpbmRleCBhY2Nlc3MgaXMgb3V0IG9mIGJvdW5kcwogICAgaW50Y18wIC8vIDAKICAgIGdldGJpdAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL0FycmF5cy9zdGF0aWNfc2l6ZS5weTo5MgogICAgLy8gaWYgdmFsOgogICAgYnogdGVzdF9ib29sX2FycmF5X2FmdGVyX2lmX2Vsc2VAOQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL0FycmF5cy9zdGF0aWNfc2l6ZS5weTo5MwogICAgLy8gY291bnQgKz0gMQogICAgZGlnIDUKICAgIGludGNfMSAvLyAxCiAgICArCiAgICBidXJ5IDYKCnRlc3RfYm9vbF9hcnJheV9hZnRlcl9pZl9lbHNlQDk6CiAgICBkaWcgNAogICAgaW50Y18xIC8vIDEKICAgICsKICAgIGJ1cnkgNQogICAgYiB0ZXN0X2Jvb2xfYXJyYXlfZm9yX2hlYWRlckA2Cgp0ZXN0X2Jvb2xfYXJyYXlfYWZ0ZXJfZm9yQDExOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL0FycmF5cy9zdGF0aWNfc2l6ZS5weTo3NwogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGRpZyA1CiAgICBpdG9iCiAgICBieXRlY18xIC8vIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnRjXzEgLy8gMQogICAgcmV0dXJuCgoKLy8gdGVzdHMuYXJ0aWZhY3RzLkFycmF5cy5zdGF0aWNfc2l6ZS5TdGF0aWNTaXplQ29udHJhY3QudGVzdF9hcmM0X2NvbnZlcnNpb25bcm91dGluZ10oKSAtPiB2b2lkOgp0ZXN0X2FyYzRfY29udmVyc2lvbjoKICAgIGJ5dGVjXzAgLy8gIiIKICAgIGR1cG4gMgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL0FycmF5cy9zdGF0aWNfc2l6ZS5weTo5NgogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGJ0b2kKICAgIGR1cAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL0FycmF5cy9zdGF0aWNfc2l6ZS5weTo5OAogICAgLy8gYXJyID0gUmVmZXJlbmNlQXJyYXlbYXJjNC5VSW50NjRdKCkKICAgIGJ5dGVjXzAgLy8gMHgKICAgIHN3YXAKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9BcnJheXMvc3RhdGljX3NpemUucHk6MTAxCiAgICAvLyBmb3IgaSBpbiB1cmFuZ2UoMSwgbGVuZ3RoICsgMSk6CiAgICBpbnRjXzEgLy8gMQogICAgKwogICAgaW50Y18xIC8vIDEKCnRlc3RfYXJjNF9jb252ZXJzaW9uX2Zvcl9oZWFkZXJAMjoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9BcnJheXMvc3RhdGljX3NpemUucHk6MTAxCiAgICAvLyBmb3IgaSBpbiB1cmFuZ2UoMSwgbGVuZ3RoICsgMSk6CiAgICBkdXAKICAgIGRpZyAyCiAgICA8CiAgICBieiB0ZXN0X2FyYzRfY29udmVyc2lvbl9hZnRlcl9mb3JANQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL0FycmF5cy9zdGF0aWNfc2l6ZS5weToxMDIKICAgIC8vIGFyci5hcHBlbmQoYXJjNC5VSW50NjQoaSkpCiAgICBkdXBuIDIKICAgIGl0b2IKICAgIGRpZyA0CiAgICBzd2FwCiAgICBjb25jYXQgLy8gb24gZXJyb3I6IG1heCBhcnJheSBsZW5ndGggZXhjZWVkZWQKICAgIGJ1cnkgNAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL0FycmF5cy9zdGF0aWNfc2l6ZS5weToxMDEKICAgIC8vIGZvciBpIGluIHVyYW5nZSgxLCBsZW5ndGggKyAxKToKICAgIGludGNfMSAvLyAxCiAgICArCiAgICBidXJ5IDEKICAgIGIgdGVzdF9hcmM0X2NvbnZlcnNpb25fZm9yX2hlYWRlckAyCgp0ZXN0X2FyYzRfY29udmVyc2lvbl9hZnRlcl9mb3JANToKICAgIGRpZyAyCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvQXJyYXlzL3N0YXRpY19zaXplLnB5OjEwMwogICAgLy8gYXNzZXJ0IGFyci5sZW5ndGggPT0gbGVuZ3RoLCAiZXhwZWN0ZWQgY29ycmVjdCBsZW5ndGgiCiAgICBsZW4KICAgIGludGNfMiAvLyA4CiAgICAvCiAgICBkdXAKICAgIGJ1cnkgOAogICAgZGlnIDQKICAgID09CiAgICBhc3NlcnQgLy8gZXhwZWN0ZWQgY29ycmVjdCBsZW5ndGgKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9BcnJheXMvc3RhdGljX3NpemUucHk6MTA0CiAgICAvLyBjb3VudCA9IFVJbnQ2NCgwKQogICAgaW50Y18wIC8vIDAKICAgIGJ1cnkgNgogICAgaW50Y18wIC8vIDAKICAgIGJ1cnkgNQoKdGVzdF9hcmM0X2NvbnZlcnNpb25fZm9yX2hlYWRlckA2OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL0FycmF5cy9zdGF0aWNfc2l6ZS5weToxMDUKICAgIC8vIGZvciB2YWwgaW4gYXJyOgogICAgZGlnIDQKICAgIGRpZyA3CiAgICA8CiAgICBieiB0ZXN0X2FyYzRfY29udmVyc2lvbl9hZnRlcl9mb3JAMTEKICAgIGRpZyAyCiAgICBkaWcgNQogICAgaW50Y18yIC8vIDgKICAgICoKICAgIGludGNfMiAvLyA4CiAgICBleHRyYWN0MyAvLyBvbiBlcnJvcjogaW5kZXggYWNjZXNzIGlzIG91dCBvZiBib3VuZHMKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9BcnJheXMvc3RhdGljX3NpemUucHk6MTA2CiAgICAvLyBpZiB2YWw6CiAgICBieXRlY18wIC8vIDB4CiAgICBiIT0KICAgIGJ6IHRlc3RfYXJjNF9jb252ZXJzaW9uX2FmdGVyX2lmX2Vsc2VAOQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL0FycmF5cy9zdGF0aWNfc2l6ZS5weToxMDcKICAgIC8vIGNvdW50ICs9IDEKICAgIGRpZyA1CiAgICBpbnRjXzEgLy8gMQogICAgKwogICAgYnVyeSA2Cgp0ZXN0X2FyYzRfY29udmVyc2lvbl9hZnRlcl9pZl9lbHNlQDk6CiAgICBkaWcgNAogICAgaW50Y18xIC8vIDEKICAgICsKICAgIGJ1cnkgNQogICAgYiB0ZXN0X2FyYzRfY29udmVyc2lvbl9mb3JfaGVhZGVyQDYKCnRlc3RfYXJjNF9jb252ZXJzaW9uX2FmdGVyX2ZvckAxMToKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9BcnJheXMvc3RhdGljX3NpemUucHk6MTA5CiAgICAvLyBhcmM0X2FyciA9IGFyYzQuRHluYW1pY0FycmF5W2FyYzQuVUludDY0XSgpCiAgICBieXRlYyA0IC8vIDB4MDAwMAogICAgZGlnIDMKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9BcnJheXMvc3RhdGljX3NpemUucHk6MTEwCiAgICAvLyBhcmM0X2Fyci5leHRlbmQoYXJyKQogICAgY29uY2F0IC8vIG9uIGVycm9yOiBtYXggYXJyYXkgbGVuZ3RoIGV4Y2VlZGVkCiAgICBkdXAKICAgIGV4dHJhY3QgMiAwCiAgICBsZW4KICAgIGludGNfMiAvLyA4CiAgICAvCiAgICBpdG9iCiAgICBleHRyYWN0IDYgMgogICAgcmVwbGFjZTIgMAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL0FycmF5cy9zdGF0aWNfc2l6ZS5weTo5NgogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGJ5dGVjXzEgLy8gMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludGNfMSAvLyAxCiAgICByZXR1cm4KCgovLyB0ZXN0cy5hcnRpZmFjdHMuQXJyYXlzLnN0YXRpY19zaXplLlN0YXRpY1NpemVDb250cmFjdC5zdW1fYXJyYXlbcm91dGluZ10oKSAtPiB2b2lkOgpzdW1fYXJyYXk6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvQXJyYXlzL3N0YXRpY19zaXplLnB5OjExNAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9BcnJheXMvc3RhdGljX3NpemUucHk6MTE3CiAgICAvLyBhcnIuZXh0ZW5kKGFyYzRfYXJyKQogICAgZXh0cmFjdCAyIDAKICAgIGR1cAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL0FycmF5cy9zdGF0aWNfc2l6ZS5weToxMTkKICAgIC8vIHRvdGFsID0gVUludDY0KDApCiAgICBpbnRjXzAgLy8gMAogICAgc3dhcAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL0FycmF5cy9zdGF0aWNfc2l6ZS5weToxMjAKICAgIC8vIGZvciBpdGVtIGluIGFycjoKICAgIGxlbgogICAgaW50Y18yIC8vIDgKICAgIC8KICAgIGludGNfMCAvLyAwCgpzdW1fYXJyYXlfZm9yX2hlYWRlckAyOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL0FycmF5cy9zdGF0aWNfc2l6ZS5weToxMjAKICAgIC8vIGZvciBpdGVtIGluIGFycjoKICAgIGR1cAogICAgZGlnIDIKICAgIDwKICAgIGJ6IHN1bV9hcnJheV9hZnRlcl9mb3JANQogICAgZGlnIDMKICAgIGRpZyAxCiAgICBkdXAKICAgIGNvdmVyIDIKICAgIGludGNfMiAvLyA4CiAgICAqCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvQXJyYXlzL3N0YXRpY19zaXplLnB5OjEyMQogICAgLy8gdG90YWwgKz0gaXRlbS5hc191aW50NjQoKQogICAgZXh0cmFjdF91aW50NjQKICAgIGRpZyA0CiAgICArCiAgICBidXJ5IDQKICAgIGludGNfMSAvLyAxCiAgICArCiAgICBidXJ5IDEKICAgIGIgc3VtX2FycmF5X2Zvcl9oZWFkZXJAMgoKc3VtX2FycmF5X2FmdGVyX2ZvckA1OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL0FycmF5cy9zdGF0aWNfc2l6ZS5weToxMTQKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBkaWcgMgogICAgaXRvYgogICAgYnl0ZWNfMSAvLyAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50Y18xIC8vIDEKICAgIHJldHVybgoKCi8vIHRlc3RzLmFydGlmYWN0cy5BcnJheXMuc3RhdGljX3NpemUuU3RhdGljU2l6ZUNvbnRyYWN0LnRlc3RfYXJjNF9ib29sW3JvdXRpbmddKCkgLT4gdm9pZDoKdGVzdF9hcmM0X2Jvb2w6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvQXJyYXlzL3N0YXRpY19zaXplLnB5OjE0MwogICAgLy8gYXJyLmFwcGVuZChhcmM0LkJvb2woVHhuLnNlbmRlciA9PSBUeG4ucmVjZWl2ZXIpKQogICAgdHhuIFNlbmRlcgogICAgdHhuIFJlY2VpdmVyCiAgICA9PQogICAgYnl0ZWNfMyAvLyAweDAwCiAgICBpbnRjXzAgLy8gMAogICAgdW5jb3ZlciAyCiAgICBzZXRiaXQKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9BcnJheXMvc3RhdGljX3NpemUucHk6MTQ0CiAgICAvLyBhcnIuYXBwZW5kKGFyYzQuQm9vbChUeG4uc2VuZGVyICE9IFR4bi5yZWNlaXZlcikpCiAgICB0eG4gU2VuZGVyCiAgICB0eG4gUmVjZWl2ZXIKICAgICE9CiAgICBieXRlY18zIC8vIDB4MDAKICAgIGludGNfMCAvLyAwCiAgICB1bmNvdmVyIDIKICAgIHNldGJpdAogICAgY29uY2F0IC8vIG9uIGVycm9yOiBtYXggYXJyYXkgbGVuZ3RoIGV4Y2VlZGVkCiAgICBkdXBuIDIKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9BcnJheXMvc3RhdGljX3NpemUucHk6MTQ3CiAgICAvLyBkeW5fYXJyLmV4dGVuZChhcnIpCiAgICBsZW4KICAgIC8vIHRlc3RzL2FydGlmYWN0cy9BcnJheXMvc3RhdGljX3NpemUucHk6MTQ2CiAgICAvLyBkeW5fYXJyID0gYXJjNC5EeW5hbWljQXJyYXlbYXJjNC5Cb29sXSgpCiAgICBieXRlYyA0IC8vIDB4MDAwMAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL0FycmF5cy9zdGF0aWNfc2l6ZS5weToxNDcKICAgIC8vIGR5bl9hcnIuZXh0ZW5kKGFycikKICAgIGRpZyAyCiAgICB1bmNvdmVyIDIKICAgIGludGNfMiAvLyA4CiAgICBjYWxsc3ViIGR5bmFtaWNfYXJyYXlfY29uY2F0X2JpdHMKICAgIGR1cAogICAgY292ZXIgMgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL0FycmF5cy9zdGF0aWNfc2l6ZS5weToxNDgKICAgIC8vIGFzc2VydCBkeW5fYXJyLmxlbmd0aCA9PSAyLCAiZXhwZWN0ZWQgY29ycmVjdCBsZW5ndGgiCiAgICBkdXAKICAgIGludGNfMCAvLyAwCiAgICBleHRyYWN0X3VpbnQxNiAvLyBvbiBlcnJvcjogaW52YWxpZCBhcnJheSBsZW5ndGggaGVhZGVyCiAgICBkdXAKICAgIGNvdmVyIDMKICAgIGR1cAogICAgcHVzaGludCAyCiAgICA9PQogICAgYXNzZXJ0IC8vIGV4cGVjdGVkIGNvcnJlY3QgbGVuZ3RoCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvQXJyYXlzL3N0YXRpY19zaXplLnB5OjE0OQogICAgLy8gYXNzZXJ0IGR5bl9hcnIuYnl0ZXMubGVuZ3RoID09IDMsICJleHBlY3RlZCAzIGJ5dGVzIgogICAgZGlnIDEKICAgIGxlbgogICAgcHVzaGludCAzCiAgICA9PQogICAgYXNzZXJ0IC8vIGV4cGVjdGVkIDMgYnl0ZXMKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9BcnJheXMvc3RhdGljX3NpemUucHk6MTUwCiAgICAvLyBhc3NlcnQgZHluX2FyclswXSA9PSAoVHhuLnNlbmRlciA9PSBUeG4ucmVjZWl2ZXIpLCAiZXhwZWN0ZWQgY29ycmVjdCB2YWx1ZSBhdCAwIgogICAgZHVwCiAgICBhc3NlcnQgLy8gaW5kZXggYWNjZXNzIGlzIG91dCBvZiBib3VuZHMKICAgIGRpZyAxCiAgICBpbnRjXzMgLy8gMTYKICAgIGdldGJpdAogICAgYnl0ZWNfMyAvLyAweDAwCiAgICBpbnRjXzAgLy8gMAogICAgdW5jb3ZlciAyCiAgICBzZXRiaXQKICAgIGludGNfMCAvLyAwCiAgICBnZXRiaXQKICAgIHR4biBTZW5kZXIKICAgIHR4biBSZWNlaXZlcgogICAgPT0KICAgID09CiAgICBhc3NlcnQgLy8gZXhwZWN0ZWQgY29ycmVjdCB2YWx1ZSBhdCAwCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvQXJyYXlzL3N0YXRpY19zaXplLnB5OjE1MQogICAgLy8gYXNzZXJ0IGR5bl9hcnJbMV0gPT0gKFR4bi5zZW5kZXIgIT0gVHhuLnJlY2VpdmVyKSwgImV4cGVjdGVkIGNvcnJlY3QgdmFsdWUgYXQgMSIKICAgIGludGNfMSAvLyAxCiAgICA+CiAgICBhc3NlcnQgLy8gaW5kZXggYWNjZXNzIGlzIG91dCBvZiBib3VuZHMKICAgIHB1c2hpbnQgMTcKICAgIGdldGJpdAogICAgYnl0ZWNfMyAvLyAweDAwCiAgICBpbnRjXzAgLy8gMAogICAgdW5jb3ZlciAyCiAgICBzZXRiaXQKICAgIGludGNfMCAvLyAwCiAgICBnZXRiaXQKICAgIHR4biBTZW5kZXIKICAgIHR4biBSZWNlaXZlcgogICAgIT0KICAgID09CiAgICBhc3NlcnQgLy8gZXhwZWN0ZWQgY29ycmVjdCB2YWx1ZSBhdCAxCiAgICBpbnRjXzAgLy8gMAoKdGVzdF9hcmM0X2Jvb2xfZm9yX2hlYWRlckAyOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL0FycmF5cy9zdGF0aWNfc2l6ZS5weToxNTQtMTU2CiAgICAvLyAjIG5vdGU6IG5vdCBzdXBwb3J0ZWQgY3VycmVudGx5CiAgICAvLyAjIGFycjIuZXh0ZW5kKGR5bl9hcnJheSkKICAgIC8vIGZvciBiIGluIGR5bl9hcnI6CiAgICBkdXAKICAgIGRpZyAzCiAgICA8CiAgICBieiB0ZXN0X2FyYzRfYm9vbF9hZnRlcl9mb3JANQogICAgZHVwbiAyCiAgICBpbnRjXzMgLy8gMTYKICAgICsKICAgIGRpZyA1CiAgICBzd2FwCiAgICBnZXRiaXQKICAgIGJ5dGVjXzMgLy8gMHgwMAogICAgaW50Y18wIC8vIDAKICAgIHVuY292ZXIgMgogICAgc2V0Yml0CiAgICBkaWcgMwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL0FycmF5cy9zdGF0aWNfc2l6ZS5weToxNTcKICAgIC8vIGFycjIuYXBwZW5kKGIpCiAgICBzd2FwCiAgICBjb25jYXQgLy8gb24gZXJyb3I6IG1heCBhcnJheSBsZW5ndGggZXhjZWVkZWQKICAgIGJ1cnkgMwogICAgaW50Y18xIC8vIDEKICAgICsKICAgIGJ1cnkgMQogICAgYiB0ZXN0X2FyYzRfYm9vbF9mb3JfaGVhZGVyQDIKCnRlc3RfYXJjNF9ib29sX2FmdGVyX2ZvckA1OgogICAgZGlnIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9BcnJheXMvc3RhdGljX3NpemUucHk6MTU4CiAgICAvLyBhc3NlcnQgYXJyMi5sZW5ndGggPT0gNCwgImV4cGVjdGVkIGNvcnJlY3QgbGVuZ3RoIgogICAgZHVwCiAgICBsZW4KICAgIHB1c2hpbnQgNAogICAgPT0KICAgIGFzc2VydCAvLyBleHBlY3RlZCBjb3JyZWN0IGxlbmd0aAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL0FycmF5cy9zdGF0aWNfc2l6ZS5weToxNTkKICAgIC8vIGFzc2VydCBhcnIyWzBdID09IChUeG4uc2VuZGVyID09IFR4bi5yZWNlaXZlciksICJleHBlY3RlZCBjb3JyZWN0IHZhbHVlIGF0IDAiCiAgICBkdXAKICAgIGV4dHJhY3QgMCAxIC8vIG9uIGVycm9yOiBpbmRleCBhY2Nlc3MgaXMgb3V0IG9mIGJvdW5kcwogICAgaW50Y18wIC8vIDAKICAgIGdldGJpdAogICAgdHhuIFNlbmRlcgogICAgdHhuIFJlY2VpdmVyCiAgICA9PQogICAgPT0KICAgIGFzc2VydCAvLyBleHBlY3RlZCBjb3JyZWN0IHZhbHVlIGF0IDAKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9BcnJheXMvc3RhdGljX3NpemUucHk6MTYwCiAgICAvLyBhc3NlcnQgYXJyMlsxXSA9PSAoVHhuLnNlbmRlciAhPSBUeG4ucmVjZWl2ZXIpLCAiZXhwZWN0ZWQgY29ycmVjdCB2YWx1ZSBhdCAxIgogICAgZHVwCiAgICBleHRyYWN0IDEgMSAvLyBvbiBlcnJvcjogaW5kZXggYWNjZXNzIGlzIG91dCBvZiBib3VuZHMKICAgIGludGNfMCAvLyAwCiAgICBnZXRiaXQKICAgIHR4biBTZW5kZXIKICAgIHR4biBSZWNlaXZlcgogICAgIT0KICAgID09CiAgICBhc3NlcnQgLy8gZXhwZWN0ZWQgY29ycmVjdCB2YWx1ZSBhdCAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvQXJyYXlzL3N0YXRpY19zaXplLnB5OjE2MQogICAgLy8gYXNzZXJ0IGFycjJbMl0gPT0gKFR4bi5zZW5kZXIgPT0gVHhuLnJlY2VpdmVyKSwgImV4cGVjdGVkIGNvcnJlY3QgdmFsdWUgYXQgMiIKICAgIGR1cAogICAgZXh0cmFjdCAyIDEgLy8gb24gZXJyb3I6IGluZGV4IGFjY2VzcyBpcyBvdXQgb2YgYm91bmRzCiAgICBpbnRjXzAgLy8gMAogICAgZ2V0Yml0CiAgICB0eG4gU2VuZGVyCiAgICB0eG4gUmVjZWl2ZXIKICAgID09CiAgICA9PQogICAgYXNzZXJ0IC8vIGV4cGVjdGVkIGNvcnJlY3QgdmFsdWUgYXQgMgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL0FycmF5cy9zdGF0aWNfc2l6ZS5weToxNjIKICAgIC8vIGFzc2VydCBhcnIyWzNdID09IChUeG4uc2VuZGVyICE9IFR4bi5yZWNlaXZlciksICJleHBlY3RlZCBjb3JyZWN0IHZhbHVlIGF0IDMiCiAgICBleHRyYWN0IDMgMSAvLyBvbiBlcnJvcjogaW5kZXggYWNjZXNzIGlzIG91dCBvZiBib3VuZHMKICAgIGludGNfMCAvLyAwCiAgICBnZXRiaXQKICAgIHR4biBTZW5kZXIKICAgIHR4biBSZWNlaXZlcgogICAgIT0KICAgID09CiAgICBhc3NlcnQgLy8gZXhwZWN0ZWQgY29ycmVjdCB2YWx1ZSBhdCAzCiAgICBkaWcgNAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL0FycmF5cy9zdGF0aWNfc2l6ZS5weToxNjQKICAgIC8vIHJldHVybiBhcnIuZnJlZXplKCkKICAgIGR1cAogICAgbGVuCiAgICBieXRlYyA0IC8vIDB4MDAwMAogICAgY292ZXIgMgogICAgaW50Y18yIC8vIDgKICAgIGNhbGxzdWIgZHluYW1pY19hcnJheV9jb25jYXRfYml0cwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL0FycmF5cy9zdGF0aWNfc2l6ZS5weToxNDAKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBieXRlY18xIC8vIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnRjXzEgLy8gMQogICAgcmV0dXJuCgoKLy8gdGVzdHMuYXJ0aWZhY3RzLkFycmF5cy5zdGF0aWNfc2l6ZS5TdGF0aWNTaXplQ29udHJhY3QueHRyYSgpIC0+IHVpbnQ2NCwgdWludDY0LCBieXRlcywgYnl0ZXMsIGJ5dGVzOgp4dHJhOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL0FycmF5cy9zdGF0aWNfc2l6ZS5weToxMjcKICAgIC8vIHNlbGYuY291bnQgKz0gMQogICAgaW50Y18wIC8vIDAKICAgIGJ5dGVjXzIgLy8gImNvdW50IgogICAgYXBwX2dsb2JhbF9nZXRfZXgKICAgIGFzc2VydCAvLyBjaGVjayBzZWxmLmNvdW50IGV4aXN0cwogICAgaW50Y18xIC8vIDEKICAgICsKICAgIGJ5dGVjXzIgLy8gImNvdW50IgogICAgZGlnIDEKICAgIGFwcF9nbG9iYWxfcHV0CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvQXJyYXlzL3N0YXRpY19zaXplLnB5OjEyOQogICAgLy8gYT1UeG4ubnVtX2FwcF9hcmdzLAogICAgdHhuIE51bUFwcEFyZ3MKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9BcnJheXMvc3RhdGljX3NpemUucHk6MTMxCiAgICAvLyBjPVR4bi5zZW5kZXIsCiAgICB0eG4gU2VuZGVyCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvQXJyYXlzL3N0YXRpY19zaXplLnB5OjEzMgogICAgLy8gZD1zZWxmLm1vcmUoKSwKICAgIGNhbGxzdWIgbW9yZQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL0FycmF5cy9zdGF0aWNfc2l6ZS5weToxMzMKICAgIC8vIGU9QmlnVUludChzZWxmLmNvdW50KSwKICAgIGludGNfMCAvLyAwCiAgICBieXRlY18yIC8vICJjb3VudCIKICAgIGFwcF9nbG9iYWxfZ2V0X2V4CiAgICBhc3NlcnQgLy8gY2hlY2sgc2VsZi5jb3VudCBleGlzdHMKICAgIGl0b2IKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9BcnJheXMvc3RhdGljX3NpemUucHk6MTI4LTEzNAogICAgLy8gcmV0dXJuIFh0cmEoCiAgICAvLyAgICAgYT1UeG4ubnVtX2FwcF9hcmdzLAogICAgLy8gICAgIGI9c2VsZi5jb3VudCwKICAgIC8vICAgICBjPVR4bi5zZW5kZXIsCiAgICAvLyAgICAgZD1zZWxmLm1vcmUoKSwKICAgIC8vICAgICBlPUJpZ1VJbnQoc2VsZi5jb3VudCksCiAgICAvLyApCiAgICB1bmNvdmVyIDMKICAgIGNvdmVyIDQKICAgIHJldHN1YgoKCi8vIHRlc3RzLmFydGlmYWN0cy5BcnJheXMuc3RhdGljX3NpemUuU3RhdGljU2l6ZUNvbnRyYWN0Lm1vcmUoKSAtPiBieXRlczoKbW9yZToKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9BcnJheXMvc3RhdGljX3NpemUucHk6MTM4CiAgICAvLyByZXR1cm4gTW9yZShmb289YXJjNC5VSW50NjQoc2VsZi5jb3VudCArIDEpLCBiYXI9YXJjNC5VSW50NjQoc2VsZi5jb3VudCAqIHNlbGYuY291bnQpKQogICAgaW50Y18wIC8vIDAKICAgIGJ5dGVjXzIgLy8gImNvdW50IgogICAgYXBwX2dsb2JhbF9nZXRfZXgKICAgIGFzc2VydCAvLyBjaGVjayBzZWxmLmNvdW50IGV4aXN0cwogICAgZHVwCiAgICBpbnRjXzEgLy8gMQogICAgKwogICAgaXRvYgogICAgZGlnIDEKICAgIHVuY292ZXIgMgogICAgKgogICAgaXRvYgogICAgY29uY2F0CiAgICByZXRzdWIK", + "approval": "I3ByYWdtYSB2ZXJzaW9uIDExCiNwcmFnbWEgdHlwZXRyYWNrIGZhbHNlCgovLyBhbGdvcHkuYXJjNC5BUkM0Q29udHJhY3QuYXBwcm92YWxfcHJvZ3JhbSgpIC0+IHVpbnQ2NDoKbWFpbjoKICAgIGludGNibG9jayAwIDEgOCAxNiAxNDQKICAgIGJ5dGVjYmxvY2sgMHggMHgxNTFmN2M3NSAiY291bnQiIDB4MDAgMHgwMDAwCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYm56IG1haW5fYWZ0ZXJfaWZfZWxzZUAyCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvQXJyYXlzL3N0YXRpY19zaXplLnB5OjM5CiAgICAvLyBzZWxmLmNvdW50ID0gVUludDY0KDApCiAgICBieXRlY18yIC8vICJjb3VudCIKICAgIGludGNfMCAvLyAwCiAgICBhcHBfZ2xvYmFsX3B1dAoKbWFpbl9hZnRlcl9pZl9lbHNlQDI6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvQXJyYXlzL3N0YXRpY19zaXplLnB5OjM3CiAgICAvLyBjbGFzcyBTdGF0aWNTaXplQ29udHJhY3QoYXJjNC5BUkM0Q29udHJhY3QpOgogICAgdHhuIE51bUFwcEFyZ3MKICAgIGJ6IG1haW5fX19hbGdvcHlfZGVmYXVsdF9jcmVhdGVAMTYKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydAogICAgcHVzaGJ5dGVzcyAweDI4ZDdjMWI4IDB4ZmE5Y2I5NzMgMHg2MDM5YTI0MCAweGY4ZmQ2OGE3IDB4MWYwMjhkYjEgMHgwOTZiM2E1OSAweDhkNmUzYTI1IC8vIG1ldGhvZCAidGVzdF9hcnJheSh1aW50NjQsdWludDY0LHVpbnQ2NCx1aW50NjQpdWludDY0IiwgbWV0aG9kICJ0ZXN0X2V4dGVuZF9mcm9tX3R1cGxlKCgodWludDY0LHVpbnQ2NCksKHVpbnQ2NCx1aW50NjQpKSkodWludDY0LHVpbnQ2NClbXSIsIG1ldGhvZCAidGVzdF9leHRlbmRfZnJvbV9hcmM0X3R1cGxlKCgodWludDY0LHVpbnQ2NCksKHVpbnQ2NCx1aW50NjQpKSkodWludDY0LHVpbnQ2NClbXSIsIG1ldGhvZCAidGVzdF9ib29sX2FycmF5KHVpbnQ2NCl1aW50NjQiLCBtZXRob2QgInRlc3RfYXJjNF9jb252ZXJzaW9uKHVpbnQ2NCl1aW50NjRbXSIsIG1ldGhvZCAic3VtX2FycmF5KHVpbnQ2NFtdKXVpbnQ2NCIsIG1ldGhvZCAidGVzdF9hcmM0X2Jvb2woKWJvb2xbXSIKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDAKICAgIG1hdGNoIHRlc3RfYXJyYXkgdGVzdF9leHRlbmRfZnJvbV90dXBsZSB0ZXN0X2V4dGVuZF9mcm9tX2FyYzRfdHVwbGUgdGVzdF9ib29sX2FycmF5IHRlc3RfYXJjNF9jb252ZXJzaW9uIHN1bV9hcnJheSB0ZXN0X2FyYzRfYm9vbAogICAgZXJyCgptYWluX19fYWxnb3B5X2RlZmF1bHRfY3JlYXRlQDE2OgogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgICEKICAgICYmCiAgICByZXR1cm4KCgovLyBfcHV5YV9saWIuYXJjNC5keW5hbWljX2FycmF5X2NvbmNhdF9iaXRzKGFycmF5OiBieXRlcywgbmV3X2l0ZW1zX2J5dGVzOiBieXRlcywgbmV3X2l0ZW1zX2NvdW50OiB1aW50NjQsIHJlYWRfc3RlcDogdWludDY0KSAtPiBieXRlczoKZHluYW1pY19hcnJheV9jb25jYXRfYml0czoKICAgIHByb3RvIDQgMQogICAgYnl0ZWNfMCAvLyAiIgogICAgZHVwbiAyCiAgICBmcmFtZV9kaWcgLTQKICAgIGludGNfMCAvLyAwCiAgICBleHRyYWN0X3VpbnQxNgogICAgZHVwbiAyCiAgICBmcmFtZV9kaWcgLTIKICAgICsKICAgIGR1cAogICAgaXRvYgogICAgZXh0cmFjdCA2IDAKICAgIGZyYW1lX2RpZyAtNAogICAgc3dhcAogICAgcmVwbGFjZTIgMAogICAgY292ZXIgMgogICAgc3dhcAogICAgcHVzaGludCA3CiAgICArCiAgICBpbnRjXzIgLy8gOAogICAgLwogICAgZHVwCiAgICB1bmNvdmVyIDIKICAgIHB1c2hpbnQgNwogICAgKwogICAgaW50Y18yIC8vIDgKICAgIC8KICAgIGR1cAogICAgY292ZXIgMgogICAgPAogICAgYnogZHluYW1pY19hcnJheV9jb25jYXRfYml0c19hZnRlcl9pZl9lbHNlQDIKICAgIGZyYW1lX2RpZyA2CiAgICBmcmFtZV9kaWcgNQogICAgLQogICAgYnplcm8KICAgIGZyYW1lX2RpZyA0CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGZyYW1lX2J1cnkgNAoKZHluYW1pY19hcnJheV9jb25jYXRfYml0c19hZnRlcl9pZl9lbHNlQDI6CiAgICBpbnRjXzAgLy8gMAogICAgZnJhbWVfYnVyeSAwCiAgICBmcmFtZV9kaWcgMwogICAgaW50Y18zIC8vIDE2CiAgICArCiAgICBkdXAKICAgIGZyYW1lX2J1cnkgMgogICAgZnJhbWVfZGlnIC0yCiAgICArCiAgICBmcmFtZV9idXJ5IDEKCmR5bmFtaWNfYXJyYXlfY29uY2F0X2JpdHNfd2hpbGVfdG9wQDM6CiAgICBmcmFtZV9kaWcgMgogICAgZnJhbWVfZGlnIDEKICAgIDwKICAgIGJ6IGR5bmFtaWNfYXJyYXlfY29uY2F0X2JpdHNfYWZ0ZXJfd2hpbGVANQogICAgZnJhbWVfZGlnIC0zCiAgICBmcmFtZV9kaWcgMAogICAgZHVwCiAgICBjb3ZlciAyCiAgICBnZXRiaXQKICAgIGZyYW1lX2RpZyA0CiAgICBmcmFtZV9kaWcgMgogICAgZHVwCiAgICBjb3ZlciAzCiAgICB1bmNvdmVyIDIKICAgIHNldGJpdAogICAgZnJhbWVfYnVyeSA0CiAgICBpbnRjXzEgLy8gMQogICAgKwogICAgZnJhbWVfYnVyeSAyCiAgICBmcmFtZV9kaWcgLTEKICAgICsKICAgIGZyYW1lX2J1cnkgMAogICAgYiBkeW5hbWljX2FycmF5X2NvbmNhdF9iaXRzX3doaWxlX3RvcEAzCgpkeW5hbWljX2FycmF5X2NvbmNhdF9iaXRzX2FmdGVyX3doaWxlQDU6CiAgICBmcmFtZV9kaWcgNAogICAgZnJhbWVfYnVyeSAwCiAgICByZXRzdWIKCgovLyB0ZXN0cy5hcnRpZmFjdHMuQXJyYXlzLnN0YXRpY19zaXplLlN0YXRpY1NpemVDb250cmFjdC50ZXN0X2FycmF5W3JvdXRpbmddKCkgLT4gdm9pZDoKdGVzdF9hcnJheToKICAgIGludGNfMCAvLyAwCiAgICBkdXAKICAgIGJ5dGVjXzAgLy8gIiIKICAgIGR1cG4gNQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL0FycmF5cy9zdGF0aWNfc2l6ZS5weTo0MQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDIKICAgIGJ0b2kKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDMKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDQKICAgIGJ0b2kKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9BcnJheXMvc3RhdGljX3NpemUucHk6NDMKICAgIC8vIHNlbGYuY291bnQgPSBVSW50NjQoMCkKICAgIGJ5dGVjXzIgLy8gImNvdW50IgogICAgaW50Y18wIC8vIDAKICAgIGFwcF9nbG9iYWxfcHV0CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvQXJyYXlzL3N0YXRpY19zaXplLnB5OjQ2CiAgICAvLyBQb2ludCh4PWFyYzQuVUludDY0KCksIHk9VUludDY0KCksIG90aGVyPXNlbGYueHRyYSgpKSwKICAgIGNhbGxzdWIgeHRyYQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL0FycmF5cy9zdGF0aWNfc2l6ZS5weTo0NwogICAgLy8gUG9pbnQoeD14MSwgeT15MSwgb3RoZXI9c2VsZi54dHJhKCkpLAogICAgY2FsbHN1YiB4dHJhCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvQXJyYXlzL3N0YXRpY19zaXplLnB5OjQ4CiAgICAvLyBQb2ludCh4PXgyLCB5PXkyLCBvdGhlcj1zZWxmLnh0cmEoKSksCiAgICBjYWxsc3ViIHh0cmEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9BcnJheXMvc3RhdGljX3NpemUucHk6NDQtNTAKICAgIC8vIHBhdGggPSBSZWZlcmVuY2VBcnJheSgKICAgIC8vICAgICAoCiAgICAvLyAgICAgICAgIFBvaW50KHg9YXJjNC5VSW50NjQoKSwgeT1VSW50NjQoKSwgb3RoZXI9c2VsZi54dHJhKCkpLAogICAgLy8gICAgICAgICBQb2ludCh4PXgxLCB5PXkxLCBvdGhlcj1zZWxmLnh0cmEoKSksCiAgICAvLyAgICAgICAgIFBvaW50KHg9eDIsIHk9eTIsIG90aGVyPXNlbGYueHRyYSgpKSwKICAgIC8vICAgICApCiAgICAvLyApCiAgICB1bmNvdmVyIDE0CiAgICBpdG9iCiAgICB1bmNvdmVyIDE0CiAgICBpdG9iCiAgICBjb25jYXQKICAgIHVuY292ZXIgMTMKICAgIGNvbmNhdAogICAgdW5jb3ZlciAxMgogICAgY29uY2F0CiAgICBkaWcgMTEKICAgIGxlbgogICAgcHVzaGludCA2NAogICAgPD0KICAgIGFzc2VydCAvLyBvdmVyZmxvdwogICAgcHVzaGludCA2NAogICAgYnplcm8KICAgIHVuY292ZXIgMTIKICAgIGRpZyAxCiAgICBifAogICAgdW5jb3ZlciAyCiAgICBzd2FwCiAgICBjb25jYXQKICAgIHB1c2hieXRlcyAweDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwCiAgICBzd2FwCiAgICBjb25jYXQKICAgIHVuY292ZXIgMTQKICAgIGl0b2IKICAgIHVuY292ZXIgMTUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgdW5jb3ZlciAxMgogICAgaXRvYgogICAgdW5jb3ZlciAxMgogICAgaXRvYgogICAgY29uY2F0CiAgICB1bmNvdmVyIDExCiAgICBjb25jYXQKICAgIHVuY292ZXIgMTAKICAgIGNvbmNhdAogICAgZGlnIDkKICAgIGxlbgogICAgcHVzaGludCA2NAogICAgPD0KICAgIGFzc2VydCAvLyBvdmVyZmxvdwogICAgdW5jb3ZlciA5CiAgICBkaWcgNAogICAgYnwKICAgIGNvbmNhdAogICAgY29uY2F0CiAgICBjb25jYXQKICAgIHVuY292ZXIgNwogICAgaXRvYgogICAgdW5jb3ZlciA4CiAgICBzd2FwCiAgICBjb25jYXQKICAgIHVuY292ZXIgNwogICAgaXRvYgogICAgdW5jb3ZlciA3CiAgICBpdG9iCiAgICBjb25jYXQKICAgIHVuY292ZXIgNgogICAgY29uY2F0CiAgICB1bmNvdmVyIDUKICAgIGNvbmNhdAogICAgZGlnIDQKICAgIGxlbgogICAgcHVzaGludCA2NAogICAgPD0KICAgIGFzc2VydCAvLyBvdmVyZmxvdwogICAgdW5jb3ZlciA0CiAgICB1bmNvdmVyIDQKICAgIGJ8CiAgICBjb25jYXQKICAgIGNvbmNhdAogICAgY29uY2F0CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvQXJyYXlzL3N0YXRpY19zaXplLnB5OjUxCiAgICAvLyBmb3IgaSBpbiB1cmFuZ2UoMyk6CiAgICBpbnRjXzAgLy8gMAoKdGVzdF9hcnJheV9mb3JfaGVhZGVyQDI6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvQXJyYXlzL3N0YXRpY19zaXplLnB5OjUxCiAgICAvLyBmb3IgaSBpbiB1cmFuZ2UoMyk6CiAgICBkdXAKICAgIHB1c2hpbnQgMwogICAgPAogICAgYnogdGVzdF9hcnJheV9hZnRlcl9mb3JANQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL0FycmF5cy9zdGF0aWNfc2l6ZS5weTo1MgogICAgLy8gYXNzZXJ0IHBhdGhbaV0ub3RoZXIuYiA9PSBpICsgMQogICAgZHVwMgogICAgZHVwCiAgICBjb3ZlciAyCiAgICBpbnRjIDQgLy8gMTQ0CiAgICAqCiAgICBpbnRjIDQgLy8gMTQ0CiAgICBleHRyYWN0MyAvLyBvbiBlcnJvcjogaW5kZXggYWNjZXNzIGlzIG91dCBvZiBib3VuZHMKICAgIGV4dHJhY3QgMTYgMTI4CiAgICBkdXAKICAgIGludGNfMiAvLyA4CiAgICBleHRyYWN0X3VpbnQ2NAogICAgZGlnIDIKICAgIGludGNfMSAvLyAxCiAgICArCiAgICBzd2FwCiAgICBkaWcgMQogICAgPT0KICAgIGFzc2VydAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL0FycmF5cy9zdGF0aWNfc2l6ZS5weTo1MwogICAgLy8gYXNzZXJ0IHBhdGhbaV0ub3RoZXIuZC5mb28gPT0gaSArIDIKICAgIHN3YXAKICAgIGV4dHJhY3QgNDggMTYKICAgIGR1cAogICAgZXh0cmFjdCAwIDgKICAgIHVuY292ZXIgMwogICAgcHVzaGludCAyCiAgICArCiAgICBpdG9iCiAgICBiPT0KICAgIGFzc2VydAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL0FycmF5cy9zdGF0aWNfc2l6ZS5weTo1NAogICAgLy8gYXNzZXJ0IHBhdGhbaV0ub3RoZXIuZC5iYXIgPT0gKGkgKyAxKSAqIChpICsgMSkKICAgIGV4dHJhY3QgOCA4CiAgICBkaWcgMQogICAgZGlnIDIKICAgICoKICAgIGl0b2IKICAgIGI9PQogICAgYXNzZXJ0CiAgICBidXJ5IDEKICAgIGIgdGVzdF9hcnJheV9mb3JfaGVhZGVyQDIKCnRlc3RfYXJyYXlfYWZ0ZXJfZm9yQDU6CiAgICBkaWcgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL0FycmF5cy9zdGF0aWNfc2l6ZS5weTo1NgogICAgLy8gQm94KEltbXV0YWJsZUFycmF5W1BvaW50XSwga2V5PSJhIikudmFsdWUgPSBwYXRoLmZyZWV6ZSgpCiAgICBkdXAKICAgIGxlbgogICAgaW50YyA0IC8vIDE0NAogICAgLwogICAgZHVwCiAgICBidXJ5IDEwCiAgICBpdG9iCiAgICBleHRyYWN0IDYgMgogICAgZGlnIDEKICAgIGNvbmNhdAogICAgcHVzaGJ5dGVzICJhIgogICAgYm94X2RlbAogICAgcG9wCiAgICBwdXNoYnl0ZXMgImEiCiAgICBzd2FwCiAgICBib3hfcHV0CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvQXJyYXlzL3N0YXRpY19zaXplLnB5OjE2OAogICAgLy8gbGFzdF9wb2ludCA9IHBhdGhbMF0KICAgIGV4dHJhY3QgMCAxNDQgLy8gb24gZXJyb3I6IGluZGV4IGFjY2VzcyBpcyBvdXQgb2YgYm91bmRzCiAgICBkdXAKICAgIGJ1cnkgMTEKICAgIGR1cAogICAgZXh0cmFjdCAwIDgKICAgIGJ1cnkgMTAKICAgIGludGNfMiAvLyA4CiAgICBleHRyYWN0X3VpbnQ2NAogICAgYnVyeSA2CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvQXJyYXlzL3N0YXRpY19zaXplLnB5OjE2OQogICAgLy8gbGVuZ3RoID0gVUludDY0KCkKICAgIGludGNfMCAvLyAwCiAgICBidXJ5IDUKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9BcnJheXMvc3RhdGljX3NpemUucHk6MTcwCiAgICAvLyBmb3IgcG9pbnRfaWR4IGluIHVyYW5nZSgxLCBwYXRoLmxlbmd0aCk6CiAgICBpbnRjXzEgLy8gMQogICAgYnVyeSAzCgp0ZXN0X2FycmF5X2Zvcl9oZWFkZXJANzoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9BcnJheXMvc3RhdGljX3NpemUucHk6MTcwCiAgICAvLyBmb3IgcG9pbnRfaWR4IGluIHVyYW5nZSgxLCBwYXRoLmxlbmd0aCk6CiAgICBkaWcgMgogICAgZGlnIDgKICAgIDwKICAgIGJ6IHRlc3RfYXJyYXlfYWZ0ZXJfZm9yQDE1CiAgICBkaWcgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL0FycmF5cy9zdGF0aWNfc2l6ZS5weToxNzEKICAgIC8vIHBvaW50ID0gcGF0aFtwb2ludF9pZHhdCiAgICBkaWcgMwogICAgaW50YyA0IC8vIDE0NAogICAgKgogICAgaW50YyA0IC8vIDE0NAogICAgZXh0cmFjdDMgLy8gb24gZXJyb3I6IGluZGV4IGFjY2VzcyBpcyBvdXQgb2YgYm91bmRzCiAgICBkdXBuIDIKICAgIGV4dHJhY3QgMCA4CiAgICBzd2FwCiAgICBpbnRjXzIgLy8gOAogICAgZXh0cmFjdF91aW50NjQKICAgIGJ1cnkgNgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL0FycmF5cy9zdGF0aWNfc2l6ZS5weToxNzIKICAgIC8vIGlmIHBvaW50LnggPCBsYXN0X3BvaW50Lng6CiAgICBkaWcgMTAKICAgIGI8CiAgICBieiB0ZXN0X2FycmF5X2Vsc2VfYm9keUAxMAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL0FycmF5cy9zdGF0aWNfc2l6ZS5weToxNzMKICAgIC8vIGR4ID0gbGFzdF9wb2ludC54LmFzX3VpbnQ2NCgpIC0gcG9pbnQueC5hc191aW50NjQoKQogICAgZGlnIDEwCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvQXJyYXlzL3N0YXRpY19zaXplLnB5OjE2OAogICAgLy8gbGFzdF9wb2ludCA9IHBhdGhbMF0KICAgIGludGNfMCAvLyAwCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvQXJyYXlzL3N0YXRpY19zaXplLnB5OjE3MwogICAgLy8gZHggPSBsYXN0X3BvaW50LnguYXNfdWludDY0KCkgLSBwb2ludC54LmFzX3VpbnQ2NCgpCiAgICBleHRyYWN0X3VpbnQ2NAogICAgc3dhcAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL0FycmF5cy9zdGF0aWNfc2l6ZS5weToxNzEKICAgIC8vIHBvaW50ID0gcGF0aFtwb2ludF9pZHhdCiAgICBpbnRjXzAgLy8gMAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL0FycmF5cy9zdGF0aWNfc2l6ZS5weToxNzMKICAgIC8vIGR4ID0gbGFzdF9wb2ludC54LmFzX3VpbnQ2NCgpIC0gcG9pbnQueC5hc191aW50NjQoKQogICAgZXh0cmFjdF91aW50NjQKICAgIC0KICAgIGJ1cnkgNwoKdGVzdF9hcnJheV9hZnRlcl9pZl9lbHNlQDExOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL0FycmF5cy9zdGF0aWNfc2l6ZS5weToxNzYKICAgIC8vIGlmIHBvaW50LnkgPCBsYXN0X3BvaW50Lnk6CiAgICBkaWcgMwogICAgZGlnIDYKICAgIDwKICAgIGJ6IHRlc3RfYXJyYXlfZWxzZV9ib2R5QDEzCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvQXJyYXlzL3N0YXRpY19zaXplLnB5OjE3NwogICAgLy8gZHkgPSBsYXN0X3BvaW50LnkgLSBwb2ludC55CiAgICBkaWcgNQogICAgZGlnIDQKICAgIC0KCnRlc3RfYXJyYXlfYWZ0ZXJfaWZfZWxzZUAxNDoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9BcnJheXMvc3RhdGljX3NpemUucHk6MTgwCiAgICAvLyBsZW5ndGggKz0gb3Auc3FydChkeCAqIGR4ICsgZHkgKiBkeSkKICAgIGRpZyA3CiAgICBkdXAKICAgICoKICAgIHN3YXAKICAgIGR1cAogICAgKgogICAgKwogICAgc3FydAogICAgZGlnIDUKICAgICsKICAgIGJ1cnkgNQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL0FycmF5cy9zdGF0aWNfc2l6ZS5weToxNzAKICAgIC8vIGZvciBwb2ludF9pZHggaW4gdXJhbmdlKDEsIHBhdGgubGVuZ3RoKToKICAgIGRpZyAyCiAgICBpbnRjXzEgLy8gMQogICAgKwogICAgYnVyeSAzCiAgICBiIHRlc3RfYXJyYXlfZm9yX2hlYWRlckA3Cgp0ZXN0X2FycmF5X2Vsc2VfYm9keUAxMzoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9BcnJheXMvc3RhdGljX3NpemUucHk6MTc5CiAgICAvLyBkeSA9IHBvaW50LnkgLSBsYXN0X3BvaW50LnkKICAgIGRpZyAzCiAgICBkaWcgNgogICAgLQogICAgYiB0ZXN0X2FycmF5X2FmdGVyX2lmX2Vsc2VAMTQKCnRlc3RfYXJyYXlfZWxzZV9ib2R5QDEwOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL0FycmF5cy9zdGF0aWNfc2l6ZS5weToxNzEKICAgIC8vIHBvaW50ID0gcGF0aFtwb2ludF9pZHhdCiAgICBpbnRjXzAgLy8gMAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL0FycmF5cy9zdGF0aWNfc2l6ZS5weToxNzUKICAgIC8vIGR4ID0gcG9pbnQueC5hc191aW50NjQoKSAtIGxhc3RfcG9pbnQueC5hc191aW50NjQoKQogICAgZXh0cmFjdF91aW50NjQKICAgIGRpZyAxMAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL0FycmF5cy9zdGF0aWNfc2l6ZS5weToxNjgKICAgIC8vIGxhc3RfcG9pbnQgPSBwYXRoWzBdCiAgICBpbnRjXzAgLy8gMAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL0FycmF5cy9zdGF0aWNfc2l6ZS5weToxNzUKICAgIC8vIGR4ID0gcG9pbnQueC5hc191aW50NjQoKSAtIGxhc3RfcG9pbnQueC5hc191aW50NjQoKQogICAgZXh0cmFjdF91aW50NjQKICAgIC0KICAgIGJ1cnkgNwogICAgYiB0ZXN0X2FycmF5X2FmdGVyX2lmX2Vsc2VAMTEKCnRlc3RfYXJyYXlfYWZ0ZXJfZm9yQDE1OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL0FycmF5cy9zdGF0aWNfc2l6ZS5weTo0MQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGRpZyA0CiAgICBpdG9iCiAgICBieXRlY18xIC8vIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnRjXzEgLy8gMQogICAgcmV0dXJuCgoKLy8gdGVzdHMuYXJ0aWZhY3RzLkFycmF5cy5zdGF0aWNfc2l6ZS5TdGF0aWNTaXplQ29udHJhY3QudGVzdF9leHRlbmRfZnJvbV90dXBsZVtyb3V0aW5nXSgpIC0+IHZvaWQ6CnRlc3RfZXh0ZW5kX2Zyb21fdHVwbGU6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvQXJyYXlzL3N0YXRpY19zaXplLnB5OjU5CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgZHVwCiAgICBleHRyYWN0IDAgMTYKICAgIHN3YXAKICAgIGV4dHJhY3QgMTYgMTYKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9BcnJheXMvc3RhdGljX3NpemUucHk6NjIKICAgIC8vIGFyci5leHRlbmQoc29tZV9tb3JlKQogICAgc3dhcAogICAgZGlnIDEKICAgIGNvbmNhdAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL0FycmF5cy9zdGF0aWNfc2l6ZS5weTo2MwogICAgLy8gbGFzdCA9IGFyclstMV0KICAgIGR1cAogICAgbGVuCiAgICBpbnRjXzMgLy8gMTYKICAgIC8KICAgIGR1cAogICAgaW50Y18xIC8vIDEKICAgIC0KICAgIGludGNfMyAvLyAxNgogICAgKgogICAgZGlnIDIKICAgIHN3YXAKICAgIGludGNfMyAvLyAxNgogICAgZXh0cmFjdDMgLy8gb24gZXJyb3I6IGluZGV4IGFjY2VzcyBpcyBvdXQgb2YgYm91bmRzCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvQXJyYXlzL3N0YXRpY19zaXplLnB5OjY0CiAgICAvLyBhc3NlcnQgbGFzdCA9PSBzb21lX21vcmVbMV0KICAgIGR1cAogICAgdW5jb3ZlciA0CiAgICA9PQogICAgYXNzZXJ0CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvQXJyYXlzL3N0YXRpY19zaXplLnB5OjY1CiAgICAvLyByZXN1bHQgPSBhcnIuZnJlZXplKCkKICAgIHN3YXAKICAgIGl0b2IKICAgIGV4dHJhY3QgNiAyCiAgICB1bmNvdmVyIDIKICAgIGNvbmNhdAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL0FycmF5cy9zdGF0aWNfc2l6ZS5weTo2NgogICAgLy8gYXNzZXJ0IHJlc3VsdFstMV0gPT0gbGFzdAogICAgZHVwCiAgICBpbnRjXzAgLy8gMAogICAgZXh0cmFjdF91aW50MTYgLy8gb24gZXJyb3I6IGludmFsaWQgYXJyYXkgbGVuZ3RoIGhlYWRlcgogICAgaW50Y18xIC8vIDEKICAgIC0KICAgIGRpZyAxCiAgICBleHRyYWN0IDIgMAogICAgc3dhcAogICAgaW50Y18zIC8vIDE2CiAgICAqCiAgICBpbnRjXzMgLy8gMTYKICAgIGV4dHJhY3QzIC8vIG9uIGVycm9yOiBpbmRleCBhY2Nlc3MgaXMgb3V0IG9mIGJvdW5kcwogICAgdW5jb3ZlciAyCiAgICA9PQogICAgYXNzZXJ0CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvQXJyYXlzL3N0YXRpY19zaXplLnB5OjU5CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgYnl0ZWNfMSAvLyAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50Y18xIC8vIDEKICAgIHJldHVybgoKCi8vIHRlc3RzLmFydGlmYWN0cy5BcnJheXMuc3RhdGljX3NpemUuU3RhdGljU2l6ZUNvbnRyYWN0LnRlc3RfZXh0ZW5kX2Zyb21fYXJjNF90dXBsZVtyb3V0aW5nXSgpIC0+IHZvaWQ6CnRlc3RfZXh0ZW5kX2Zyb21fYXJjNF90dXBsZToKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9BcnJheXMvc3RhdGljX3NpemUucHk6NjkKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvQXJyYXlzL3N0YXRpY19zaXplLnB5Ojc1CiAgICAvLyByZXR1cm4gYXJyLmZyZWV6ZSgpCiAgICBkdXAKICAgIGxlbgogICAgaW50Y18zIC8vIDE2CiAgICAvCiAgICBpdG9iCiAgICBleHRyYWN0IDYgMgogICAgc3dhcAogICAgY29uY2F0CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvQXJyYXlzL3N0YXRpY19zaXplLnB5OjY5CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgYnl0ZWNfMSAvLyAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50Y18xIC8vIDEKICAgIHJldHVybgoKCi8vIHRlc3RzLmFydGlmYWN0cy5BcnJheXMuc3RhdGljX3NpemUuU3RhdGljU2l6ZUNvbnRyYWN0LnRlc3RfYm9vbF9hcnJheVtyb3V0aW5nXSgpIC0+IHZvaWQ6CnRlc3RfYm9vbF9hcnJheToKICAgIGJ5dGVjXzAgLy8gIiIKICAgIGR1cG4gMgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL0FycmF5cy9zdGF0aWNfc2l6ZS5weTo3NwogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGJ0b2kKICAgIGR1cAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL0FycmF5cy9zdGF0aWNfc2l6ZS5weTo3OQogICAgLy8gYXJyID0gUmVmZXJlbmNlQXJyYXlbYm9vbF0oKQogICAgYnl0ZWNfMCAvLyAweAogICAgc3dhcAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL0FycmF5cy9zdGF0aWNfc2l6ZS5weTo4MgogICAgLy8gZm9yIGkgaW4gdXJhbmdlKDEsIGxlbmd0aCArIDEpOgogICAgaW50Y18xIC8vIDEKICAgICsKICAgIGludGNfMSAvLyAxCgp0ZXN0X2Jvb2xfYXJyYXlfZm9yX2hlYWRlckAyOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL0FycmF5cy9zdGF0aWNfc2l6ZS5weTo4MgogICAgLy8gZm9yIGkgaW4gdXJhbmdlKDEsIGxlbmd0aCArIDEpOgogICAgZHVwCiAgICBkaWcgMgogICAgPAogICAgYnogdGVzdF9ib29sX2FycmF5X2FmdGVyX2ZvckA1CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvQXJyYXlzL3N0YXRpY19zaXplLnB5OjgzCiAgICAvLyBhcnIuYXBwZW5kKGkgJSAyID09IDApCiAgICBkdXBuIDIKICAgIHB1c2hpbnQgMgogICAgJQogICAgIQogICAgZGlnIDQKICAgIHN3YXAKICAgIGJ5dGVjXzMgLy8gMHgwMAogICAgaW50Y18wIC8vIDAKICAgIHVuY292ZXIgMgogICAgc2V0Yml0CiAgICBjb25jYXQgLy8gb24gZXJyb3I6IG1heCBhcnJheSBsZW5ndGggZXhjZWVkZWQKICAgIGJ1cnkgNAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL0FycmF5cy9zdGF0aWNfc2l6ZS5weTo4MgogICAgLy8gZm9yIGkgaW4gdXJhbmdlKDEsIGxlbmd0aCArIDEpOgogICAgaW50Y18xIC8vIDEKICAgICsKICAgIGJ1cnkgMQogICAgYiB0ZXN0X2Jvb2xfYXJyYXlfZm9yX2hlYWRlckAyCgp0ZXN0X2Jvb2xfYXJyYXlfYWZ0ZXJfZm9yQDU6CiAgICBkaWcgMgogICAgZHVwbiAyCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvQXJyYXlzL3N0YXRpY19zaXplLnB5Ojg0CiAgICAvLyBhc3NlcnQgYXJyLmxlbmd0aCA9PSBsZW5ndGgsICJleHBlY3RlZCBjb3JyZWN0IGxlbmd0aCIKICAgIGxlbgogICAgZGlnIDYKICAgIGR1cAogICAgY292ZXIgNAogICAgPT0KICAgIGFzc2VydCAvLyBleHBlY3RlZCBjb3JyZWN0IGxlbmd0aAogICAgZGlnIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9BcnJheXMvc3RhdGljX3NpemUucHk6ODcKICAgIC8vIGFycjIuZXh0ZW5kKGFycikKICAgIGNvbmNhdCAvLyBvbiBlcnJvcjogbWF4IGFycmF5IGxlbmd0aCBleGNlZWRlZAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL0FycmF5cy9zdGF0aWNfc2l6ZS5weTo4OAogICAgLy8gYXNzZXJ0IGFycjIubGVuZ3RoID09IGxlbmd0aCAqIDIsICJleHBlY3RlZCBjb3JyZWN0IGxlbmd0aCIKICAgIGxlbgogICAgdW5jb3ZlciAyCiAgICBwdXNoaW50IDIKICAgICoKICAgID09CiAgICBhc3NlcnQgLy8gZXhwZWN0ZWQgY29ycmVjdCBsZW5ndGgKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9BcnJheXMvc3RhdGljX3NpemUucHk6OTAKICAgIC8vIGNvdW50ID0gVUludDY0KDApCiAgICBpbnRjXzAgLy8gMAogICAgYnVyeSA3CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvQXJyYXlzL3N0YXRpY19zaXplLnB5OjkxCiAgICAvLyBmb3IgdmFsIGluIGFycjoKICAgIGxlbgogICAgYnVyeSA3CiAgICBpbnRjXzAgLy8gMAogICAgYnVyeSA1Cgp0ZXN0X2Jvb2xfYXJyYXlfZm9yX2hlYWRlckA2OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL0FycmF5cy9zdGF0aWNfc2l6ZS5weTo5MQogICAgLy8gZm9yIHZhbCBpbiBhcnI6CiAgICBkaWcgNAogICAgZGlnIDcKICAgIDwKICAgIGJ6IHRlc3RfYm9vbF9hcnJheV9hZnRlcl9mb3JAMTEKICAgIGRpZyAyCiAgICBkaWcgNQogICAgaW50Y18xIC8vIDEKICAgIGV4dHJhY3QzIC8vIG9uIGVycm9yOiBpbmRleCBhY2Nlc3MgaXMgb3V0IG9mIGJvdW5kcwogICAgaW50Y18wIC8vIDAKICAgIGdldGJpdAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL0FycmF5cy9zdGF0aWNfc2l6ZS5weTo5MgogICAgLy8gaWYgdmFsOgogICAgYnogdGVzdF9ib29sX2FycmF5X2FmdGVyX2lmX2Vsc2VAOQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL0FycmF5cy9zdGF0aWNfc2l6ZS5weTo5MwogICAgLy8gY291bnQgKz0gMQogICAgZGlnIDUKICAgIGludGNfMSAvLyAxCiAgICArCiAgICBidXJ5IDYKCnRlc3RfYm9vbF9hcnJheV9hZnRlcl9pZl9lbHNlQDk6CiAgICBkaWcgNAogICAgaW50Y18xIC8vIDEKICAgICsKICAgIGJ1cnkgNQogICAgYiB0ZXN0X2Jvb2xfYXJyYXlfZm9yX2hlYWRlckA2Cgp0ZXN0X2Jvb2xfYXJyYXlfYWZ0ZXJfZm9yQDExOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL0FycmF5cy9zdGF0aWNfc2l6ZS5weTo3NwogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGRpZyA1CiAgICBpdG9iCiAgICBieXRlY18xIC8vIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnRjXzEgLy8gMQogICAgcmV0dXJuCgoKLy8gdGVzdHMuYXJ0aWZhY3RzLkFycmF5cy5zdGF0aWNfc2l6ZS5TdGF0aWNTaXplQ29udHJhY3QudGVzdF9hcmM0X2NvbnZlcnNpb25bcm91dGluZ10oKSAtPiB2b2lkOgp0ZXN0X2FyYzRfY29udmVyc2lvbjoKICAgIGJ5dGVjXzAgLy8gIiIKICAgIGR1cG4gMgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL0FycmF5cy9zdGF0aWNfc2l6ZS5weTo5NgogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGJ0b2kKICAgIGR1cAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL0FycmF5cy9zdGF0aWNfc2l6ZS5weTo5OAogICAgLy8gYXJyID0gUmVmZXJlbmNlQXJyYXlbYXJjNC5VSW50NjRdKCkKICAgIGJ5dGVjXzAgLy8gMHgKICAgIHN3YXAKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9BcnJheXMvc3RhdGljX3NpemUucHk6MTAxCiAgICAvLyBmb3IgaSBpbiB1cmFuZ2UoMSwgbGVuZ3RoICsgMSk6CiAgICBpbnRjXzEgLy8gMQogICAgKwogICAgaW50Y18xIC8vIDEKCnRlc3RfYXJjNF9jb252ZXJzaW9uX2Zvcl9oZWFkZXJAMjoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9BcnJheXMvc3RhdGljX3NpemUucHk6MTAxCiAgICAvLyBmb3IgaSBpbiB1cmFuZ2UoMSwgbGVuZ3RoICsgMSk6CiAgICBkdXAKICAgIGRpZyAyCiAgICA8CiAgICBieiB0ZXN0X2FyYzRfY29udmVyc2lvbl9hZnRlcl9mb3JANQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL0FycmF5cy9zdGF0aWNfc2l6ZS5weToxMDIKICAgIC8vIGFyci5hcHBlbmQoYXJjNC5VSW50NjQoaSkpCiAgICBkdXBuIDIKICAgIGl0b2IKICAgIGRpZyA0CiAgICBzd2FwCiAgICBjb25jYXQgLy8gb24gZXJyb3I6IG1heCBhcnJheSBsZW5ndGggZXhjZWVkZWQKICAgIGJ1cnkgNAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL0FycmF5cy9zdGF0aWNfc2l6ZS5weToxMDEKICAgIC8vIGZvciBpIGluIHVyYW5nZSgxLCBsZW5ndGggKyAxKToKICAgIGludGNfMSAvLyAxCiAgICArCiAgICBidXJ5IDEKICAgIGIgdGVzdF9hcmM0X2NvbnZlcnNpb25fZm9yX2hlYWRlckAyCgp0ZXN0X2FyYzRfY29udmVyc2lvbl9hZnRlcl9mb3JANToKICAgIGRpZyAyCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvQXJyYXlzL3N0YXRpY19zaXplLnB5OjEwMwogICAgLy8gYXNzZXJ0IGFyci5sZW5ndGggPT0gbGVuZ3RoLCAiZXhwZWN0ZWQgY29ycmVjdCBsZW5ndGgiCiAgICBsZW4KICAgIGludGNfMiAvLyA4CiAgICAvCiAgICBkdXAKICAgIGJ1cnkgOAogICAgZGlnIDQKICAgID09CiAgICBhc3NlcnQgLy8gZXhwZWN0ZWQgY29ycmVjdCBsZW5ndGgKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9BcnJheXMvc3RhdGljX3NpemUucHk6MTA0CiAgICAvLyBjb3VudCA9IFVJbnQ2NCgwKQogICAgaW50Y18wIC8vIDAKICAgIGJ1cnkgNgogICAgaW50Y18wIC8vIDAKICAgIGJ1cnkgNQoKdGVzdF9hcmM0X2NvbnZlcnNpb25fZm9yX2hlYWRlckA2OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL0FycmF5cy9zdGF0aWNfc2l6ZS5weToxMDUKICAgIC8vIGZvciB2YWwgaW4gYXJyOgogICAgZGlnIDQKICAgIGRpZyA3CiAgICA8CiAgICBieiB0ZXN0X2FyYzRfY29udmVyc2lvbl9hZnRlcl9mb3JAMTEKICAgIGRpZyAyCiAgICBkaWcgNQogICAgaW50Y18yIC8vIDgKICAgICoKICAgIGludGNfMiAvLyA4CiAgICBleHRyYWN0MyAvLyBvbiBlcnJvcjogaW5kZXggYWNjZXNzIGlzIG91dCBvZiBib3VuZHMKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9BcnJheXMvc3RhdGljX3NpemUucHk6MTA2CiAgICAvLyBpZiB2YWw6CiAgICBieXRlY18wIC8vIDB4CiAgICBiIT0KICAgIGJ6IHRlc3RfYXJjNF9jb252ZXJzaW9uX2FmdGVyX2lmX2Vsc2VAOQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL0FycmF5cy9zdGF0aWNfc2l6ZS5weToxMDcKICAgIC8vIGNvdW50ICs9IDEKICAgIGRpZyA1CiAgICBpbnRjXzEgLy8gMQogICAgKwogICAgYnVyeSA2Cgp0ZXN0X2FyYzRfY29udmVyc2lvbl9hZnRlcl9pZl9lbHNlQDk6CiAgICBkaWcgNAogICAgaW50Y18xIC8vIDEKICAgICsKICAgIGJ1cnkgNQogICAgYiB0ZXN0X2FyYzRfY29udmVyc2lvbl9mb3JfaGVhZGVyQDYKCnRlc3RfYXJjNF9jb252ZXJzaW9uX2FmdGVyX2ZvckAxMToKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9BcnJheXMvc3RhdGljX3NpemUucHk6MTA5CiAgICAvLyBhcmM0X2FyciA9IGFyYzQuRHluYW1pY0FycmF5W2FyYzQuVUludDY0XSgpCiAgICBieXRlYyA0IC8vIDB4MDAwMAogICAgZGlnIDMKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9BcnJheXMvc3RhdGljX3NpemUucHk6MTEwCiAgICAvLyBhcmM0X2Fyci5leHRlbmQoYXJyKQogICAgY29uY2F0IC8vIG9uIGVycm9yOiBtYXggYXJyYXkgbGVuZ3RoIGV4Y2VlZGVkCiAgICBkdXAKICAgIGV4dHJhY3QgMiAwCiAgICBsZW4KICAgIGludGNfMiAvLyA4CiAgICAvCiAgICBpdG9iCiAgICBleHRyYWN0IDYgMgogICAgcmVwbGFjZTIgMAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL0FycmF5cy9zdGF0aWNfc2l6ZS5weTo5NgogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGJ5dGVjXzEgLy8gMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludGNfMSAvLyAxCiAgICByZXR1cm4KCgovLyB0ZXN0cy5hcnRpZmFjdHMuQXJyYXlzLnN0YXRpY19zaXplLlN0YXRpY1NpemVDb250cmFjdC5zdW1fYXJyYXlbcm91dGluZ10oKSAtPiB2b2lkOgpzdW1fYXJyYXk6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvQXJyYXlzL3N0YXRpY19zaXplLnB5OjExNAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9BcnJheXMvc3RhdGljX3NpemUucHk6MTE3CiAgICAvLyBhcnIuZXh0ZW5kKGFyYzRfYXJyKQogICAgZXh0cmFjdCAyIDAKICAgIGR1cAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL0FycmF5cy9zdGF0aWNfc2l6ZS5weToxMTkKICAgIC8vIHRvdGFsID0gVUludDY0KDApCiAgICBpbnRjXzAgLy8gMAogICAgc3dhcAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL0FycmF5cy9zdGF0aWNfc2l6ZS5weToxMjAKICAgIC8vIGZvciBpdGVtIGluIGFycjoKICAgIGxlbgogICAgaW50Y18yIC8vIDgKICAgIC8KICAgIGludGNfMCAvLyAwCgpzdW1fYXJyYXlfZm9yX2hlYWRlckAyOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL0FycmF5cy9zdGF0aWNfc2l6ZS5weToxMjAKICAgIC8vIGZvciBpdGVtIGluIGFycjoKICAgIGR1cAogICAgZGlnIDIKICAgIDwKICAgIGJ6IHN1bV9hcnJheV9hZnRlcl9mb3JANQogICAgZGlnIDMKICAgIGRpZyAxCiAgICBkdXAKICAgIGNvdmVyIDIKICAgIGludGNfMiAvLyA4CiAgICAqCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvQXJyYXlzL3N0YXRpY19zaXplLnB5OjEyMQogICAgLy8gdG90YWwgKz0gaXRlbS5hc191aW50NjQoKQogICAgZXh0cmFjdF91aW50NjQKICAgIGRpZyA0CiAgICArCiAgICBidXJ5IDQKICAgIGludGNfMSAvLyAxCiAgICArCiAgICBidXJ5IDEKICAgIGIgc3VtX2FycmF5X2Zvcl9oZWFkZXJAMgoKc3VtX2FycmF5X2FmdGVyX2ZvckA1OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL0FycmF5cy9zdGF0aWNfc2l6ZS5weToxMTQKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBkaWcgMgogICAgaXRvYgogICAgYnl0ZWNfMSAvLyAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50Y18xIC8vIDEKICAgIHJldHVybgoKCi8vIHRlc3RzLmFydGlmYWN0cy5BcnJheXMuc3RhdGljX3NpemUuU3RhdGljU2l6ZUNvbnRyYWN0LnRlc3RfYXJjNF9ib29sW3JvdXRpbmddKCkgLT4gdm9pZDoKdGVzdF9hcmM0X2Jvb2w6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvQXJyYXlzL3N0YXRpY19zaXplLnB5OjE0MgogICAgLy8gYXJyLmFwcGVuZChhcmM0LkJvb2woVHhuLnNlbmRlciA9PSBUeG4ucmVjZWl2ZXIpKQogICAgdHhuIFNlbmRlcgogICAgdHhuIFJlY2VpdmVyCiAgICA9PQogICAgYnl0ZWNfMyAvLyAweDAwCiAgICBpbnRjXzAgLy8gMAogICAgdW5jb3ZlciAyCiAgICBzZXRiaXQKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9BcnJheXMvc3RhdGljX3NpemUucHk6MTQzCiAgICAvLyBhcnIuYXBwZW5kKGFyYzQuQm9vbChUeG4uc2VuZGVyICE9IFR4bi5yZWNlaXZlcikpCiAgICB0eG4gU2VuZGVyCiAgICB0eG4gUmVjZWl2ZXIKICAgICE9CiAgICBieXRlY18zIC8vIDB4MDAKICAgIGludGNfMCAvLyAwCiAgICB1bmNvdmVyIDIKICAgIHNldGJpdAogICAgY29uY2F0IC8vIG9uIGVycm9yOiBtYXggYXJyYXkgbGVuZ3RoIGV4Y2VlZGVkCiAgICBkdXBuIDIKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9BcnJheXMvc3RhdGljX3NpemUucHk6MTQ2CiAgICAvLyBkeW5fYXJyLmV4dGVuZChhcnIpCiAgICBsZW4KICAgIC8vIHRlc3RzL2FydGlmYWN0cy9BcnJheXMvc3RhdGljX3NpemUucHk6MTQ1CiAgICAvLyBkeW5fYXJyID0gYXJjNC5EeW5hbWljQXJyYXlbYXJjNC5Cb29sXSgpCiAgICBieXRlYyA0IC8vIDB4MDAwMAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL0FycmF5cy9zdGF0aWNfc2l6ZS5weToxNDYKICAgIC8vIGR5bl9hcnIuZXh0ZW5kKGFycikKICAgIGRpZyAyCiAgICB1bmNvdmVyIDIKICAgIGludGNfMiAvLyA4CiAgICBjYWxsc3ViIGR5bmFtaWNfYXJyYXlfY29uY2F0X2JpdHMKICAgIGR1cAogICAgY292ZXIgMgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL0FycmF5cy9zdGF0aWNfc2l6ZS5weToxNDcKICAgIC8vIGFzc2VydCBkeW5fYXJyLmxlbmd0aCA9PSAyLCAiZXhwZWN0ZWQgY29ycmVjdCBsZW5ndGgiCiAgICBkdXAKICAgIGludGNfMCAvLyAwCiAgICBleHRyYWN0X3VpbnQxNiAvLyBvbiBlcnJvcjogaW52YWxpZCBhcnJheSBsZW5ndGggaGVhZGVyCiAgICBkdXAKICAgIGNvdmVyIDMKICAgIGR1cAogICAgcHVzaGludCAyCiAgICA9PQogICAgYXNzZXJ0IC8vIGV4cGVjdGVkIGNvcnJlY3QgbGVuZ3RoCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvQXJyYXlzL3N0YXRpY19zaXplLnB5OjE0OAogICAgLy8gYXNzZXJ0IGR5bl9hcnIuYnl0ZXMubGVuZ3RoID09IDMsICJleHBlY3RlZCAzIGJ5dGVzIgogICAgZGlnIDEKICAgIGxlbgogICAgcHVzaGludCAzCiAgICA9PQogICAgYXNzZXJ0IC8vIGV4cGVjdGVkIDMgYnl0ZXMKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9BcnJheXMvc3RhdGljX3NpemUucHk6MTQ5CiAgICAvLyBhc3NlcnQgZHluX2FyclswXSA9PSAoVHhuLnNlbmRlciA9PSBUeG4ucmVjZWl2ZXIpLCAiZXhwZWN0ZWQgY29ycmVjdCB2YWx1ZSBhdCAwIgogICAgZHVwCiAgICBhc3NlcnQgLy8gaW5kZXggYWNjZXNzIGlzIG91dCBvZiBib3VuZHMKICAgIGRpZyAxCiAgICBpbnRjXzMgLy8gMTYKICAgIGdldGJpdAogICAgYnl0ZWNfMyAvLyAweDAwCiAgICBpbnRjXzAgLy8gMAogICAgdW5jb3ZlciAyCiAgICBzZXRiaXQKICAgIGludGNfMCAvLyAwCiAgICBnZXRiaXQKICAgIHR4biBTZW5kZXIKICAgIHR4biBSZWNlaXZlcgogICAgPT0KICAgID09CiAgICBhc3NlcnQgLy8gZXhwZWN0ZWQgY29ycmVjdCB2YWx1ZSBhdCAwCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvQXJyYXlzL3N0YXRpY19zaXplLnB5OjE1MAogICAgLy8gYXNzZXJ0IGR5bl9hcnJbMV0gPT0gKFR4bi5zZW5kZXIgIT0gVHhuLnJlY2VpdmVyKSwgImV4cGVjdGVkIGNvcnJlY3QgdmFsdWUgYXQgMSIKICAgIGludGNfMSAvLyAxCiAgICA+CiAgICBhc3NlcnQgLy8gaW5kZXggYWNjZXNzIGlzIG91dCBvZiBib3VuZHMKICAgIHB1c2hpbnQgMTcKICAgIGdldGJpdAogICAgYnl0ZWNfMyAvLyAweDAwCiAgICBpbnRjXzAgLy8gMAogICAgdW5jb3ZlciAyCiAgICBzZXRiaXQKICAgIGludGNfMCAvLyAwCiAgICBnZXRiaXQKICAgIHR4biBTZW5kZXIKICAgIHR4biBSZWNlaXZlcgogICAgIT0KICAgID09CiAgICBhc3NlcnQgLy8gZXhwZWN0ZWQgY29ycmVjdCB2YWx1ZSBhdCAxCiAgICBpbnRjXzAgLy8gMAoKdGVzdF9hcmM0X2Jvb2xfZm9yX2hlYWRlckAyOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL0FycmF5cy9zdGF0aWNfc2l6ZS5weToxNTMtMTU1CiAgICAvLyAjIG5vdGU6IG5vdCBzdXBwb3J0ZWQgY3VycmVudGx5CiAgICAvLyAjIGFycjIuZXh0ZW5kKGR5bl9hcnJheSkKICAgIC8vIGZvciBiIGluIGR5bl9hcnI6CiAgICBkdXAKICAgIGRpZyAzCiAgICA8CiAgICBieiB0ZXN0X2FyYzRfYm9vbF9hZnRlcl9mb3JANQogICAgZHVwbiAyCiAgICBpbnRjXzMgLy8gMTYKICAgICsKICAgIGRpZyA1CiAgICBzd2FwCiAgICBnZXRiaXQKICAgIGJ5dGVjXzMgLy8gMHgwMAogICAgaW50Y18wIC8vIDAKICAgIHVuY292ZXIgMgogICAgc2V0Yml0CiAgICBkaWcgMwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL0FycmF5cy9zdGF0aWNfc2l6ZS5weToxNTYKICAgIC8vIGFycjIuYXBwZW5kKGIpCiAgICBzd2FwCiAgICBjb25jYXQgLy8gb24gZXJyb3I6IG1heCBhcnJheSBsZW5ndGggZXhjZWVkZWQKICAgIGJ1cnkgMwogICAgaW50Y18xIC8vIDEKICAgICsKICAgIGJ1cnkgMQogICAgYiB0ZXN0X2FyYzRfYm9vbF9mb3JfaGVhZGVyQDIKCnRlc3RfYXJjNF9ib29sX2FmdGVyX2ZvckA1OgogICAgZGlnIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9BcnJheXMvc3RhdGljX3NpemUucHk6MTU3CiAgICAvLyBhc3NlcnQgYXJyMi5sZW5ndGggPT0gNCwgImV4cGVjdGVkIGNvcnJlY3QgbGVuZ3RoIgogICAgZHVwCiAgICBsZW4KICAgIHB1c2hpbnQgNAogICAgPT0KICAgIGFzc2VydCAvLyBleHBlY3RlZCBjb3JyZWN0IGxlbmd0aAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL0FycmF5cy9zdGF0aWNfc2l6ZS5weToxNTgKICAgIC8vIGFzc2VydCBhcnIyWzBdID09IChUeG4uc2VuZGVyID09IFR4bi5yZWNlaXZlciksICJleHBlY3RlZCBjb3JyZWN0IHZhbHVlIGF0IDAiCiAgICBkdXAKICAgIGV4dHJhY3QgMCAxIC8vIG9uIGVycm9yOiBpbmRleCBhY2Nlc3MgaXMgb3V0IG9mIGJvdW5kcwogICAgaW50Y18wIC8vIDAKICAgIGdldGJpdAogICAgdHhuIFNlbmRlcgogICAgdHhuIFJlY2VpdmVyCiAgICA9PQogICAgPT0KICAgIGFzc2VydCAvLyBleHBlY3RlZCBjb3JyZWN0IHZhbHVlIGF0IDAKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9BcnJheXMvc3RhdGljX3NpemUucHk6MTU5CiAgICAvLyBhc3NlcnQgYXJyMlsxXSA9PSAoVHhuLnNlbmRlciAhPSBUeG4ucmVjZWl2ZXIpLCAiZXhwZWN0ZWQgY29ycmVjdCB2YWx1ZSBhdCAxIgogICAgZHVwCiAgICBleHRyYWN0IDEgMSAvLyBvbiBlcnJvcjogaW5kZXggYWNjZXNzIGlzIG91dCBvZiBib3VuZHMKICAgIGludGNfMCAvLyAwCiAgICBnZXRiaXQKICAgIHR4biBTZW5kZXIKICAgIHR4biBSZWNlaXZlcgogICAgIT0KICAgID09CiAgICBhc3NlcnQgLy8gZXhwZWN0ZWQgY29ycmVjdCB2YWx1ZSBhdCAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvQXJyYXlzL3N0YXRpY19zaXplLnB5OjE2MAogICAgLy8gYXNzZXJ0IGFycjJbMl0gPT0gKFR4bi5zZW5kZXIgPT0gVHhuLnJlY2VpdmVyKSwgImV4cGVjdGVkIGNvcnJlY3QgdmFsdWUgYXQgMiIKICAgIGR1cAogICAgZXh0cmFjdCAyIDEgLy8gb24gZXJyb3I6IGluZGV4IGFjY2VzcyBpcyBvdXQgb2YgYm91bmRzCiAgICBpbnRjXzAgLy8gMAogICAgZ2V0Yml0CiAgICB0eG4gU2VuZGVyCiAgICB0eG4gUmVjZWl2ZXIKICAgID09CiAgICA9PQogICAgYXNzZXJ0IC8vIGV4cGVjdGVkIGNvcnJlY3QgdmFsdWUgYXQgMgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL0FycmF5cy9zdGF0aWNfc2l6ZS5weToxNjEKICAgIC8vIGFzc2VydCBhcnIyWzNdID09IChUeG4uc2VuZGVyICE9IFR4bi5yZWNlaXZlciksICJleHBlY3RlZCBjb3JyZWN0IHZhbHVlIGF0IDMiCiAgICBleHRyYWN0IDMgMSAvLyBvbiBlcnJvcjogaW5kZXggYWNjZXNzIGlzIG91dCBvZiBib3VuZHMKICAgIGludGNfMCAvLyAwCiAgICBnZXRiaXQKICAgIHR4biBTZW5kZXIKICAgIHR4biBSZWNlaXZlcgogICAgIT0KICAgID09CiAgICBhc3NlcnQgLy8gZXhwZWN0ZWQgY29ycmVjdCB2YWx1ZSBhdCAzCiAgICBkaWcgNAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL0FycmF5cy9zdGF0aWNfc2l6ZS5weToxNjMKICAgIC8vIHJldHVybiBhcnIuZnJlZXplKCkKICAgIGR1cAogICAgbGVuCiAgICBieXRlYyA0IC8vIDB4MDAwMAogICAgY292ZXIgMgogICAgaW50Y18yIC8vIDgKICAgIGNhbGxzdWIgZHluYW1pY19hcnJheV9jb25jYXRfYml0cwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL0FycmF5cy9zdGF0aWNfc2l6ZS5weToxMzkKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBieXRlY18xIC8vIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnRjXzEgLy8gMQogICAgcmV0dXJuCgoKLy8gdGVzdHMuYXJ0aWZhY3RzLkFycmF5cy5zdGF0aWNfc2l6ZS5TdGF0aWNTaXplQ29udHJhY3QueHRyYSgpIC0+IHVpbnQ2NCwgdWludDY0LCBieXRlcywgYnl0ZXMsIGJ5dGVzOgp4dHJhOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL0FycmF5cy9zdGF0aWNfc2l6ZS5weToxMjYKICAgIC8vIHNlbGYuY291bnQgKz0gMQogICAgaW50Y18wIC8vIDAKICAgIGJ5dGVjXzIgLy8gImNvdW50IgogICAgYXBwX2dsb2JhbF9nZXRfZXgKICAgIGFzc2VydCAvLyBjaGVjayBzZWxmLmNvdW50IGV4aXN0cwogICAgaW50Y18xIC8vIDEKICAgICsKICAgIGJ5dGVjXzIgLy8gImNvdW50IgogICAgZGlnIDEKICAgIGFwcF9nbG9iYWxfcHV0CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvQXJyYXlzL3N0YXRpY19zaXplLnB5OjEyOAogICAgLy8gYT1UeG4ubnVtX2FwcF9hcmdzLAogICAgdHhuIE51bUFwcEFyZ3MKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9BcnJheXMvc3RhdGljX3NpemUucHk6MTMwCiAgICAvLyBjPVR4bi5zZW5kZXIsCiAgICB0eG4gU2VuZGVyCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvQXJyYXlzL3N0YXRpY19zaXplLnB5OjEzMQogICAgLy8gZD1zZWxmLm1vcmUoKSwKICAgIGNhbGxzdWIgbW9yZQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL0FycmF5cy9zdGF0aWNfc2l6ZS5weToxMzIKICAgIC8vIGU9QmlnVUludChzZWxmLmNvdW50KSwKICAgIGludGNfMCAvLyAwCiAgICBieXRlY18yIC8vICJjb3VudCIKICAgIGFwcF9nbG9iYWxfZ2V0X2V4CiAgICBhc3NlcnQgLy8gY2hlY2sgc2VsZi5jb3VudCBleGlzdHMKICAgIGl0b2IKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9BcnJheXMvc3RhdGljX3NpemUucHk6MTI3LTEzMwogICAgLy8gcmV0dXJuIFh0cmEoCiAgICAvLyAgICAgYT1UeG4ubnVtX2FwcF9hcmdzLAogICAgLy8gICAgIGI9c2VsZi5jb3VudCwKICAgIC8vICAgICBjPVR4bi5zZW5kZXIsCiAgICAvLyAgICAgZD1zZWxmLm1vcmUoKSwKICAgIC8vICAgICBlPUJpZ1VJbnQoc2VsZi5jb3VudCksCiAgICAvLyApCiAgICB1bmNvdmVyIDMKICAgIGNvdmVyIDQKICAgIHJldHN1YgoKCi8vIHRlc3RzLmFydGlmYWN0cy5BcnJheXMuc3RhdGljX3NpemUuU3RhdGljU2l6ZUNvbnRyYWN0Lm1vcmUoKSAtPiBieXRlczoKbW9yZToKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9BcnJheXMvc3RhdGljX3NpemUucHk6MTM3CiAgICAvLyByZXR1cm4gTW9yZShmb289YXJjNC5VSW50NjQoc2VsZi5jb3VudCArIDEpLCBiYXI9YXJjNC5VSW50NjQoc2VsZi5jb3VudCAqIHNlbGYuY291bnQpKQogICAgaW50Y18wIC8vIDAKICAgIGJ5dGVjXzIgLy8gImNvdW50IgogICAgYXBwX2dsb2JhbF9nZXRfZXgKICAgIGFzc2VydCAvLyBjaGVjayBzZWxmLmNvdW50IGV4aXN0cwogICAgZHVwCiAgICBpbnRjXzEgLy8gMQogICAgKwogICAgaXRvYgogICAgZGlnIDEKICAgIHVuY292ZXIgMgogICAgKgogICAgaXRvYgogICAgY29uY2F0CiAgICByZXRzdWIK", "clear": "I3ByYWdtYSB2ZXJzaW9uIDExCiNwcmFnbWEgdHlwZXRyYWNrIGZhbHNlCgovLyBhbGdvcHkuYXJjNC5BUkM0Q29udHJhY3QuY2xlYXJfc3RhdGVfcHJvZ3JhbSgpIC0+IHVpbnQ2NDoKbWFpbjoKICAgIHB1c2hpbnQgMQogICAgcmV0dXJuCg==" }, "byteCode": { diff --git a/tests/artifacts/Arrays/static_size.py b/tests/artifacts/Arrays/static_size.py index cf0d01d3..61a4036f 100644 --- a/tests/artifacts/Arrays/static_size.py +++ b/tests/artifacts/Arrays/static_size.py @@ -122,7 +122,6 @@ def sum_array(self, arc4_arr: arc4.DynamicArray[arc4.UInt64]) -> UInt64: return total - @subroutine def xtra(self) -> Xtra: self.count += 1 return Xtra( diff --git a/tests/artifacts/Contains/contract.py b/tests/artifacts/Contains/contract.py index 886ffbcf..ca506bf4 100644 --- a/tests/artifacts/Contains/contract.py +++ b/tests/artifacts/Contains/contract.py @@ -39,19 +39,15 @@ def approval_program(self) -> UInt64: def clear_state_program(self) -> UInt64: return UInt64(1) - @subroutine def is_in_tuple_1(self, x: UInt64, y: tuple[UInt64, UInt64, Bytes]) -> bool: return x in y - @subroutine def is_in_tuple_2(self, x: Bytes, y: tuple[Bytes, UInt64, Bytes]) -> bool: return x in y - @subroutine def is_in_tuple_3(self, x: BigUInt, y: tuple[BigUInt, BigUInt]) -> bool: return x in y - @subroutine def test_string_types(self) -> None: assert foo_string() in (foo_string(), baz_string()), "foo in (foo, baz)" assert foo_string() not in (bar_string(), baz_string()), "foo not in (bar, baz)" @@ -83,7 +79,6 @@ def test_string_types(self) -> None: Bytes(b"bar"), ), "b'foo' not in (foo, foo, b'bar')" - @subroutine def test_numeric_types(self) -> None: assert one_u64() in (one_u64(), two_u64()), "1 in (1, 2)" assert one_u64() not in (UInt64(3), two_u64()), "1 not in (3, 2)" diff --git a/tests/artifacts/Contains/data/MyContract.approval.teal b/tests/artifacts/Contains/data/MyContract.approval.teal index fa4fd569..441b33cd 100644 --- a/tests/artifacts/Contains/data/MyContract.approval.teal +++ b/tests/artifacts/Contains/data/MyContract.approval.teal @@ -104,11 +104,10 @@ main: // tests.artifacts.Contains.contract.MyContract.is_in_tuple_1(x: uint64, y.0: uint64, y.1: uint64, y.2: bytes) -> uint64: is_in_tuple_1: - // tests/artifacts/Contains/contract.py:42-43 - // @subroutine + // tests/artifacts/Contains/contract.py:42 // def is_in_tuple_1(self, x: UInt64, y: tuple[UInt64, UInt64, Bytes]) -> bool: proto 4 1 - // tests/artifacts/Contains/contract.py:44 + // tests/artifacts/Contains/contract.py:43 // return x in y frame_dig -4 frame_dig -3 @@ -121,24 +120,23 @@ is_in_tuple_1: is_in_tuple_1_bool_true@2: intc_1 // 1 - // tests/artifacts/Contains/contract.py:44 + // tests/artifacts/Contains/contract.py:43 // return x in y retsub is_in_tuple_1_bool_false@3: intc_0 // 0 - // tests/artifacts/Contains/contract.py:44 + // tests/artifacts/Contains/contract.py:43 // return x in y retsub // tests.artifacts.Contains.contract.MyContract.is_in_tuple_2(x: bytes, y.0: bytes, y.1: uint64, y.2: bytes) -> uint64: is_in_tuple_2: - // tests/artifacts/Contains/contract.py:46-47 - // @subroutine + // tests/artifacts/Contains/contract.py:45 // def is_in_tuple_2(self, x: Bytes, y: tuple[Bytes, UInt64, Bytes]) -> bool: proto 4 1 - // tests/artifacts/Contains/contract.py:48 + // tests/artifacts/Contains/contract.py:46 // return x in y frame_dig -4 frame_dig -3 @@ -151,24 +149,23 @@ is_in_tuple_2: is_in_tuple_2_bool_true@2: intc_1 // 1 - // tests/artifacts/Contains/contract.py:48 + // tests/artifacts/Contains/contract.py:46 // return x in y retsub is_in_tuple_2_bool_false@3: intc_0 // 0 - // tests/artifacts/Contains/contract.py:48 + // tests/artifacts/Contains/contract.py:46 // return x in y retsub // tests.artifacts.Contains.contract.MyContract.is_in_tuple_3(x: bytes, y.0: bytes, y.1: bytes) -> uint64: is_in_tuple_3: - // tests/artifacts/Contains/contract.py:50-51 - // @subroutine + // tests/artifacts/Contains/contract.py:48 // def is_in_tuple_3(self, x: BigUInt, y: tuple[BigUInt, BigUInt]) -> bool: proto 3 1 - // tests/artifacts/Contains/contract.py:52 + // tests/artifacts/Contains/contract.py:49 // return x in y frame_dig -3 frame_dig -2 @@ -181,12 +178,12 @@ is_in_tuple_3: is_in_tuple_3_bool_true@2: intc_1 // 1 - // tests/artifacts/Contains/contract.py:52 + // tests/artifacts/Contains/contract.py:49 // return x in y retsub is_in_tuple_3_bool_false@3: intc_0 // 0 - // tests/artifacts/Contains/contract.py:52 + // tests/artifacts/Contains/contract.py:49 // return x in y retsub diff --git a/tests/models/test_contract.py b/tests/models/test_contract.py index aaec2d73..7f97d630 100644 --- a/tests/models/test_contract.py +++ b/tests/models/test_contract.py @@ -11,7 +11,6 @@ class ContractTxnInit(algopy.Contract): - def __init__(self) -> None: self.arg1 = algopy.Txn.app_args(0) if algopy.Txn.num_app_args else algopy.Bytes() self.creator = algopy.Txn.sender @@ -32,14 +31,13 @@ class ContractARC4Create( local_uints=7, ), ): - def __init__(self) -> None: self.creator = algopy.Txn.sender self._name = algopy.String("name") self._scratch_slots = algopy.UInt64() self._state_totals = algopy.UInt64() - @algopy.arc4.abimethod(create="require") + @algopy.public(create="require") def create(self, val: algopy.UInt64) -> None: self.arg1 = val assert algopy.Global.current_application_id.global_num_bytes == 4