diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md new file mode 100644 index 0000000..729d5e0 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -0,0 +1,27 @@ +--- +name: "\U0001F41C Bug report" +about: Report a reproducible bug. +title: '' +labels: new-bug +assignees: '' +--- + +### Subject of the issue + + + +### Your environment + + + +### Steps to reproduce + +1. +2. + +### Expected behaviour + +### Actual behaviour diff --git a/.github/ISSUE_TEMPLATE/feature_request.md b/.github/ISSUE_TEMPLATE/feature_request.md new file mode 100644 index 0000000..c36da88 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/feature_request.md @@ -0,0 +1,27 @@ +--- +name: "\U0001F514 Feature Request" +about: Suggestions for how we can improve the algorand platform. +title: '' +labels: new-feature-request +assignees: '' +--- + +## Problem + + + +## Solution + + + +### Proposal + + + +### Pros and Cons + + + +## Dependencies + + diff --git a/.github/workflows/pr.yml b/.github/workflows/pr.yml index c2e6eb1..28a0d2c 100644 --- a/.github/workflows/pr.yml +++ b/.github/workflows/pr.yml @@ -9,7 +9,6 @@ on: - 'docs/**' - 'scripts/**' - permissions: contents: read @@ -19,8 +18,9 @@ jobs: uses: ./.github/workflows/node-ci.yml with: pre-test-script: | - pipx install algokit - algokit localnet start + pipx install algokit --python 3.12.6 + algokit localnet reset --update + pipx install puyapy --python 3.12.6 node-version: 20.x run-build: true run-commit-lint: true diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index f651e06..aa02c36 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -22,7 +22,8 @@ jobs: with: pre-test-script: | pipx install algokit - algokit localnet start + algokit localnet reset --update + pipx install puyapy node-version: 20.x run-build: true run-commit-lint: true @@ -63,3 +64,5 @@ jobs: token: ${{ secrets.NPM_TOKEN }} package: artifacts/algo-ts-testing/package.json access: 'public' + # Tagging 'main' branch with latest for now, even though it's beta because we don't have a non-beta + tag: ${{ github.ref_name == 'alpha' && 'alpha' || github.ref_name == 'main' && 'latest' || github.ref_name == 'release' && 'latest' || 'pre-release' }} diff --git a/.gitignore b/.gitignore index 929222c..119c7fb 100644 --- a/.gitignore +++ b/.gitignore @@ -65,3 +65,4 @@ out/ examples/debug-out/ +examples/**/data/ diff --git a/.tstoolkitrc.ts b/.tstoolkitrc.ts index b9c2800..a0ce61a 100644 --- a/.tstoolkitrc.ts +++ b/.tstoolkitrc.ts @@ -10,7 +10,11 @@ const config: TsToolkitConfig = { exports: { '.': 'index.ts', './runtime-helpers': 'runtime-helpers.ts', - './test-transformer': 'test-transformer/index.ts', + './internal': 'internal/index.ts', + './internal/arc4': 'internal/arc4.ts', + './internal/op': 'internal/op.ts', + './vitest-transformer': 'test-transformer/vitest-transformer.ts', + './jest-transformer': 'test-transformer/jest-transformer.ts', }, }, } diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 0000000..e4b72b9 --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,51 @@ +# Contributing to Algorand TypeScript Testing + +Contributions are welcome. For new features, please open an issue to discuss first. + +## Workflow + +We use [Conventional Commits](https://www.conventionalcommits.org/en/v1.0.0/#summary). User-facing changes should include at least one `fix:` or `feat:` commit for release notes. Other conventions like `docs:` or `test:` are optional but helpful. + +## Local Development + +To set up the project locally: + +1. **Install Node.js**: Download from [nodejs.org](https://nodejs.org/). + +1. **Install Python 3.12+**. + +1. **Install Puya**: + + ```sh + pipx install puyapy --python 3.12.6 + ``` + +1. **Install AlgoKit CLI**: Follow the guide from [Algokit](https://github.com/algorandfoundation/algokit-cli?tab=readme-ov-file#install). + +1. **Start localnet**: + + ```sh + algokit localnet start + # or `algokit localnet reset --update` to update localnet docker images + ``` + +1. **Install npm dependencies**: + + ```sh + npm install + ``` + +1. **Run tests**: + ```sh + npm test + ``` + +## Common Commands + +Here are some common commands you will use with npm: + +- **Generate API reference documentation** `npm run script:documentation` +- **Fix linting errors** `npm run lint:fix` +- **Build a distribution locally** `npm run build` +- **Compile all contracts used by tests for debugging** `npm run script:refresh-test-artifacts` +- **Compile all example contracts for debugging** `npm run script:compile-examples` diff --git a/README.md b/README.md new file mode 100644 index 0000000..c8f8d29 --- /dev/null +++ b/README.md @@ -0,0 +1,285 @@ +# Algorand TypeScript Testing + +[![docs-repository](https://img.shields.io/badge/url-repository-74dfdc?logo=github&style=flat.svg)](https://github.com/algorandfoundation/algorand-typescript-testing/) +[![learn-AlgoKit](https://img.shields.io/badge/learn-AlgoKit-74dfdc?logo=algorand&mac=flat.svg)](https://developer.algorand.org/algokit/) +[![github-stars](https://img.shields.io/github/stars/algorandfoundation/algorand-typescript-testing?color=74dfdc&logo=star&style=flat)](https://github.com/algorandfoundation/algorand-typescript-testing) +[![visitor-badge](https://api.visitorbadge.io/api/visitors?path=https%3A%2F%2Fgithub.com%2Falgorandfoundation%2Falgorand-typescript-testing&countColor=%2374dfdc&style=flat)](https://github.com/algorandfoundation/algorand-typescript-testing/) + +`algorand-typescript-testing` is a companion package to [Algorand Typescript](https://github.com/algorandfoundation/puya-ts/tree/main/packages/algo-ts) that enables efficient unit testing of Algorand TypeScript smart contracts in an offline environment. This package emulates key AVM behaviors without requiring a network connection, offering fast and reliable testing capabilities with a familiar TypeScript interface. + +The `algorand-typescript-testing` package provides: + +- A simple interface for fast and reliable unit testing +- An offline testing environment that simulates core AVM functionality +- A familiar TypeScript experience, compatible with testing frameworks like [vitest](https://vitest.dev/), and [jest](https://jestjs.io/) + +## Quick Start + +`algorand-typescript` is a prerequisite for `algorand-typescript-testing`, providing stubs and type annotations for Algorand TypeScript syntax. It enhances code completion and type checking when writing smart contracts. Note that this code isn't directly executable in standard Node.js environment; it's compiled by `puya-ts` into TEAL for Algorand Network deployment. + +Traditionally, testing Algorand smart contracts involved deployment on sandboxed networks and interacting with live instances. While robust, this approach can be inefficient and lacks versatility for testing Algorand TypeScript code. + +Enter `algorand-typescript-testing`: it leverages TypeScript's rich testing ecosystem for unit testing without network deployment. This enables rapid iteration and granular logic testing. + +> **NOTE**: While `algorand-typescript-testing` offers valuable unit testing capabilities, it's not a replacement for comprehensive testing. Use it alongside other test types, particularly those running against the actual Algorand Network, for thorough contract validation. + +### Prerequisites + +- Python 3.12 or later +- [Algorand Python](https://github.com/algorandfoundation/puya) +- Node.js 20.x or later +- [Algorand TypeScript](https://github.com/algorandfoundation/puya-ts) + +### Installation + +`algorand-typescript-testing` is distributed via [npm](https://www.npmjs.com/package/@algorandfoundation/algorand-typescript-testing/). Install the package using `npm`: + +```bash +npm i @algorandfoundation/algorand-typescript-testing +``` + +### Testing your first contract + +Let's write a simple contract and test it using the `algorand-typescript-testing` framework. + +#### Configuring vitest + +If you are using [vitest](https://vitest.dev/) with [@rollup/plugin-typescript](https://www.npmjs.com/package/@rollup/plugin-typescript) plugin, configure `puyaTsTransformer` as a `before` stage transformer of the `typescript` plugin in `vitest.config.mts` file. + +```typescript +import typescript from '@rollup/plugin-typescript' +import { defineConfig } from 'vitest/config' +import { puyaTsTransformer } from '@algorandfoundation/algorand-typescript-testing/vitest-transformer' + +export default defineConfig({ + esbuild: {}, + test: { + setupFiles: 'vitest.setup.ts', + }, + plugins: [ + typescript({ + transformers: { + before: [puyaTsTransformer], + }, + }), + ], +}) +``` + +`algorand-typescript-testing` package also exposes additional equality testers which enables the smart contract developers to write terser test by avoiding type casting in assertions. It can setup in `beforeAll` hook point in the setup file, `vitest.setup.ts`. + +```typescript +import { beforeAll, expect } from 'vitest' +import { addEqualityTesters } from '@algorandfoundation/algorand-typescript-testing' + +beforeAll(() => { + addEqualityTesters({ expect }) +}) +``` + +#### Configuring jest + +If you are using [jest](https://jestjs.io/) with [ts-jest](https://www.npmjs.com/package/ts-jest), [@jest/globals](https://www.npmjs.com/package/@jest/globals) and [ts-node](https://www.npmjs.com/package/ts-node) plugins, configure `puyaTsTransformer` as a `before` stage transformer of the `typescript` plugin in `jest.config.ts` file. + +```typescript +import { createDefaultEsmPreset, type JestConfigWithTsJest } from 'ts-jest' + +const presetConfig = createDefaultEsmPreset({}) +const jestConfig: JestConfigWithTsJest = { + ...presetConfig, + testMatch: ['**/*.test.ts'], + setupFilesAfterEnv: ['/jest.setup.ts'], + transform: { + '^.+\\.tsx?$': [ + 'ts-jest', + { + useESM: true, + astTransformers: { + before: ['node_modules/@algorandfoundation/algorand-typescript-testing/test-transformer/jest-transformer.mjs'], + }, + }, + ], + }, + extensionsToTreatAsEsm: ['.ts'], +} +export default jestConfig +``` + +`algorand-typescript-testing` package also exposes additional equality testers which enables the smart contract developers to write terser test by avoiding type casting in assertions. It can setup in `beforeAll` hook point in the setup file, `jest.setup.ts`. + +```typescript +import { beforeAll, expect } from '@jest/globals' +import { addEqualityTesters } from '@algorandfoundation/algorand-typescript-testing' + +beforeAll(() => { + addEqualityTesters({ expect }) +}) +``` + +You'll also need to run `jest` with the `--experimental-vm-modules` and `--experimental-require-module` flags in the `package.json`. This requires node 20.17 or greater. + +```json +{ + "name": "puya-ts-demo", + "scripts": { + "test:jest": "tsc && node --experimental-vm-modules --experimental-require-module node_modules/jest/bin/jest" + }, + "engines": { + "node": ">=20.17" + } +} +``` + +There is also a patch file `ts-jest+29.2.5.patch` that needs to be applied to `ts-jest` package to for the `puyaTsTransformer` to work with the test files. + +1. Place the file in `\patches` folder. +1. Install [patch-package](https://www.npmjs.com/package/patch-package) package as a dev dependency. +1. Add `"postinstall": "patch-package",` script in `package.json` file. + The patch will then be applied with every `npm install` call. + +```patch +diff --git a/node_modules/ts-jest/dist/legacy/compiler/ts-compiler.js b/node_modules/ts-jest/dist/legacy/compiler/ts-compiler.js +index 5198f8f..addb47c 100644 +--- a/node_modules/ts-jest/dist/legacy/compiler/ts-compiler.js ++++ b/node_modules/ts-jest/dist/legacy/compiler/ts-compiler.js +@@ -234,7 +234,7 @@ var TsCompiler = /** @class */ (function () { + var _a; + // Initialize memory cache for typescript compiler + this._parsedTsConfig.fileNames +- .filter(function (fileName) { return constants_1.TS_TSX_REGEX.test(fileName) && !_this.configSet.isTestFile(fileName); }) ++ .filter(function (fileName) { return constants_1.TS_TSX_REGEX.test(fileName); }) + // eslint-disable-next-line @typescript-eslint/no-non-null-assertion + .forEach(function (fileName) { return _this._fileVersionCache.set(fileName, 0); }); + /* istanbul ignore next */ + +``` + +After the setup, the examples provided using `vitest` can be converted to work with `jest` by simply swapping the `import {...} from 'vitest'` with `import {...} from '@jest/globals'`. + +#### Contract Definition + +```typescript +import { arc4, assert, Bytes, GlobalState, gtxn, LocalState, op, Txn, uint64, Uint64 } from '@algorandfoundation/algorand-typescript' + +export default class VotingContract extends arc4.Contract { + topic = GlobalState({ initialValue: 'default_topic', key: Bytes('topic') }) + votes = GlobalState({ initialValue: Uint64(0), key: Bytes('votes') }) + voted = LocalState({ key: Bytes('voted') }) + + @arc4.abimethod() + public setTopic(topic: string): void { + this.topic.value = topic + } + @arc4.abimethod() + public vote(pay: gtxn.PaymentTxn): boolean { + assert(op.Global.groupSize === 2, 'Expected 2 transactions') + assert(pay.amount === 10_000, 'Incorrect payment amount') + assert(pay.sender === Txn.sender, 'Payment sender must match transaction sender') + + if (this.voted(Txn.sender).hasValue) { + return false // Already voted + } + + this.votes.value = this.votes.value + 1 + this.voted(Txn.sender).value = 1 + return true + } + + @arc4.abimethod({ readonly: true }) + public getVotes(): uint64 { + return this.votes.value + } + + public clearStateProgram(): boolean { + return true + } +} +``` + +#### Test Definition + +```typescript +import { Uint64 } from '@algorandfoundation/algorand-typescript' +import { TestExecutionContext } from '@algorandfoundation/algorand-typescript-testing' +import { afterEach, describe, expect, test } from 'vitest' +import VotingContract from './contract.algo' + +describe('Voting contract', () => { + const ctx = new TestExecutionContext() + afterEach(() => { + ctx.reset() + }) + + test('vote function', () => { + // Initialize the contract within the testing context + const contract = ctx.contract.create(VotingContract) + + const voter = ctx.defaultSender + const payment = ctx.any.txn.payment({ + sender: voter, + amount: 10_000, + }) + + const result = contract.vote(payment) + expect(result).toEqual(true) + expect(contract.votes.value).toEqual(1) + expect(contract.voted(voter).value).toEqual(1) + }) + + test('setTopic function', () => { + // Initialize the contract within the testing context + const contract = ctx.contract.create(VotingContract) + + const newTopic = ctx.any.string(10) + contract.setTopic(newTopic) + expect(contract.topic.value).toEqual(newTopic) + }) + + test('getVotes function', () => { + // Initialize the contract within the testing context + const contract = ctx.contract.create(VotingContract) + + contract.votes.value = 5 + const votes = contract.getVotes() + expect(votes).toEqual(5) + }) +}) +``` + +This example demonstrates key aspects of testing with `algorand-typescript-testing` for ARC4-based contracts: + +1. ARC4 Contract Features: + + - Use of `arc4.Contract` as the base class for the contract. + - ABI methods defined using the `@arc4.abimethod` decorator. + - Readonly method annotation with `@arc4.abimethod({readonly: true})`. + +2. Testing ARC4 Contracts: + + - Creation of an `arc4.Contract` instance within the test context. + - Use of `ctx.any` for generating random test data. + - Direct invocation of ABI methods on the contract instance. + +3. Transaction Handling: + + - Use of `ctx.any.txn` to create test transactions. + - Passing transaction objects as parameters to contract methods. + +4. State Verification: + - Checking global and local state changes after method execution. + - Verifying return values from ABI methods. + +> **NOTE**: Thorough testing is crucial in smart contract development due to their immutable nature post-deployment. Comprehensive unit and integration tests ensure contract validity and reliability. Optimizing for efficiency can significantly improve user experience by reducing transaction fees and simplifying interactions. Investing in robust testing and optimization practices is crucial and offers many benefits in the long run. + +### Next steps + +To dig deeper into the capabilities of `algorand-typescript-testing`, continue with the following sections. + +#### Contents + +- [Testing Guide](./docs/testing-guide/index.md) +- [Examples](./docs/examples.md) +- [Coverage](./docs/coverage.md) +- [FQA](./docs/faq.md) +- [API Reference](./docs/api.md) +- [Algorand TypeScript](./docs/algots.md) diff --git a/docs/algots.md b/docs/algots.md new file mode 100644 index 0000000..7efd44f --- /dev/null +++ b/docs/algots.md @@ -0,0 +1,11 @@ +# Algorand TypeScript + +Algorand TypeScript is a partial implementation of the TypeScript programming language that runs on the Algorand Virtual Machine (AVM). It includes a statically typed framework for development of Algorand smart contracts and logic signatures, with TypeScript interfaces to underlying AVM functionality that works with standard TypeScript tooling. + +It maintains the syntax and semantics of TypeScript such that a developer who knows TypeScript can make safe assumptions +about the behaviour of the compiled code when running on the AVM. Algorand TypeScript is also executable TypeScript that can be run +and debugged on a Node.js virtual machine with transpilation to EcmaScript and run from automated tests. + +Algorand TypeScript is compiled for execution on the AVM by PuyaTs, a TypeScript frontend for the [Puya](https://github.com/algorandfoundation/puya) optimising compiler that ensures the resulting AVM bytecode execution semantics that match the given TypeScript code. PuyaTs produces output that is directly compatible with AlgoKit typed clients to make deployment and calling easy. + +[Documentation](https://github.com/algorandfoundation/puya-ts/blob/main/README.md) diff --git a/docs/api.md b/docs/api.md new file mode 100644 index 0000000..c6ea0a7 --- /dev/null +++ b/docs/api.md @@ -0,0 +1,29 @@ +# API Reference + +An overview of the `algorand-typescript-testing` package - covering the main classes and functions. + +```{hint} +Spotted a typo in documentation? This project is open source, please submit an issue or a PR on [GitHub](https://github.com/algorandfoundation/algorand-typescript-testing). +``` + +## Contexts + +- [TestExecutionContext](./code/index/classes/TestExecutionContext.md) +- [ContractContext](./code/subcontexts/contract-context/classes/ContractContext.md) +- [LedgerContext](./code/subcontexts/ledger-context/classes/LedgerContext.md) +- [TransactionContext](./code/subcontexts/transaction-context/classes/TransactionContext.md) + +## Value Generators + +- [AvmValueGenerator](./code/value-generators/avm/classes/AvmValueGenerator.md) +- [Arc4ValueGenerator](./code/value-generators/arc4/classes/Arc4ValueGenerator.md) +- [TxnValueGenerator](./code/value-generators/txn/classes/TxnValueGenerator.md) + +## Utils + +- [addEqualityTesters](./code/index/functions/addEqualityTesters.md) +- [encodingUtils](./code/index/variables/encodingUtil.md) + +## Reference documentation + +We also have [auto-generated reference documentation for the code](./code/README.md). diff --git a/docs/code/README.md b/docs/code/README.md new file mode 100644 index 0000000..a729f30 --- /dev/null +++ b/docs/code/README.md @@ -0,0 +1,18 @@ +**@algorandfoundation/algorand-typescript-testing** + +*** + +# @algorandfoundation/algorand-typescript-testing + +## Modules + +- [index](index/README.md) +- [subcontexts/contract-context](subcontexts/contract-context/README.md) +- [subcontexts/ledger-context](subcontexts/ledger-context/README.md) +- [subcontexts/transaction-context](subcontexts/transaction-context/README.md) +- [test-transformer/jest-transformer](test-transformer/jest-transformer/README.md) +- [test-transformer/vitest-transformer](test-transformer/vitest-transformer/README.md) +- [value-generators](value-generators/README.md) +- [value-generators/arc4](value-generators/arc4/README.md) +- [value-generators/avm](value-generators/avm/README.md) +- [value-generators/txn](value-generators/txn/README.md) diff --git a/docs/code/index/README.md b/docs/code/index/README.md new file mode 100644 index 0000000..8bb4be4 --- /dev/null +++ b/docs/code/index/README.md @@ -0,0 +1,21 @@ +[**@algorandfoundation/algorand-typescript-testing**](../README.md) + +*** + +[@algorandfoundation/algorand-typescript-testing](../README.md) / index + +# index + +## Classes + +- [AssertError](classes/AssertError.md) +- [AvmError](classes/AvmError.md) +- [CodeError](classes/CodeError.md) +- [InternalError](classes/InternalError.md) +- [NotImplementedError](classes/NotImplementedError.md) +- [TestExecutionContext](classes/TestExecutionContext.md) + +## Functions + +- [addEqualityTesters](functions/addEqualityTesters.md) +- [toExternalValue](functions/toExternalValue.md) diff --git a/docs/code/index/classes/AssertError.md b/docs/code/index/classes/AssertError.md new file mode 100644 index 0000000..ae040d4 --- /dev/null +++ b/docs/code/index/classes/AssertError.md @@ -0,0 +1,157 @@ +[**@algorandfoundation/algorand-typescript-testing**](../../README.md) + +*** + +[@algorandfoundation/algorand-typescript-testing](../../README.md) / [index](../README.md) / AssertError + +# Class: AssertError + +Defined in: [src/errors.ts:22](https://github.com/algorandfoundation/algorand-typescript-testing/blob/main/src/errors.ts#L22) + +Raised when an assertion fails + +## Extends + +- [`AvmError`](AvmError.md) + +## Constructors + +### new AssertError() + +> **new AssertError**(`message`): [`AssertError`](AssertError.md) + +Defined in: [src/errors.ts:23](https://github.com/algorandfoundation/algorand-typescript-testing/blob/main/src/errors.ts#L23) + +#### Parameters + +##### message + +`string` + +#### Returns + +[`AssertError`](AssertError.md) + +#### Overrides + +[`AvmError`](AvmError.md).[`constructor`](AvmError.md#constructors) + +## Properties + +### cause? + +> `optional` **cause**: `unknown` + +Defined in: node\_modules/typescript/lib/lib.es2022.error.d.ts:26 + +#### Inherited from + +[`AvmError`](AvmError.md).[`cause`](AvmError.md#cause) + +*** + +### message + +> **message**: `string` + +Defined in: node\_modules/typescript/lib/lib.es5.d.ts:1077 + +#### Inherited from + +[`AvmError`](AvmError.md).[`message`](AvmError.md#message-1) + +*** + +### name + +> **name**: `string` + +Defined in: node\_modules/typescript/lib/lib.es5.d.ts:1076 + +#### Inherited from + +[`AvmError`](AvmError.md).[`name`](AvmError.md#name) + +*** + +### stack? + +> `optional` **stack**: `string` + +Defined in: node\_modules/typescript/lib/lib.es5.d.ts:1078 + +#### Inherited from + +[`AvmError`](AvmError.md).[`stack`](AvmError.md#stack) + +*** + +### prepareStackTrace()? + +> `static` `optional` **prepareStackTrace**: (`err`, `stackTraces`) => `any` + +Defined in: node\_modules/@types/node/globals.d.ts:143 + +Optional override for formatting stack traces + +#### Parameters + +##### err + +`Error` + +##### stackTraces + +`CallSite`[] + +#### Returns + +`any` + +#### See + +https://v8.dev/docs/stack-trace-api#customizing-stack-traces + +#### Inherited from + +[`AvmError`](AvmError.md).[`prepareStackTrace`](AvmError.md#preparestacktrace) + +*** + +### stackTraceLimit + +> `static` **stackTraceLimit**: `number` + +Defined in: node\_modules/@types/node/globals.d.ts:145 + +#### Inherited from + +[`AvmError`](AvmError.md).[`stackTraceLimit`](AvmError.md#stacktracelimit) + +## Methods + +### captureStackTrace() + +> `static` **captureStackTrace**(`targetObject`, `constructorOpt`?): `void` + +Defined in: node\_modules/@types/node/globals.d.ts:136 + +Create .stack property on a target object + +#### Parameters + +##### targetObject + +`object` + +##### constructorOpt? + +`Function` + +#### Returns + +`void` + +#### Inherited from + +[`AvmError`](AvmError.md).[`captureStackTrace`](AvmError.md#capturestacktrace) diff --git a/docs/code/index/classes/AvmError.md b/docs/code/index/classes/AvmError.md new file mode 100644 index 0000000..49cf6ce --- /dev/null +++ b/docs/code/index/classes/AvmError.md @@ -0,0 +1,162 @@ +[**@algorandfoundation/algorand-typescript-testing**](../../README.md) + +*** + +[@algorandfoundation/algorand-typescript-testing](../../README.md) / [index](../README.md) / AvmError + +# Class: AvmError + +Defined in: [src/errors.ts:5](https://github.com/algorandfoundation/algorand-typescript-testing/blob/main/src/errors.ts#L5) + +Raised when an `err` op is encountered, or when the testing VM is asked to do something that would cause +the AVM to fail. + +## Extends + +- `Error` + +## Extended by + +- [`AssertError`](AssertError.md) + +## Constructors + +### new AvmError() + +> **new AvmError**(`message`): [`AvmError`](AvmError.md) + +Defined in: [src/errors.ts:6](https://github.com/algorandfoundation/algorand-typescript-testing/blob/main/src/errors.ts#L6) + +#### Parameters + +##### message + +`string` + +#### Returns + +[`AvmError`](AvmError.md) + +#### Overrides + +`Error.constructor` + +## Properties + +### cause? + +> `optional` **cause**: `unknown` + +Defined in: node\_modules/typescript/lib/lib.es2022.error.d.ts:26 + +#### Inherited from + +`Error.cause` + +*** + +### message + +> **message**: `string` + +Defined in: node\_modules/typescript/lib/lib.es5.d.ts:1077 + +#### Inherited from + +`Error.message` + +*** + +### name + +> **name**: `string` + +Defined in: node\_modules/typescript/lib/lib.es5.d.ts:1076 + +#### Inherited from + +`Error.name` + +*** + +### stack? + +> `optional` **stack**: `string` + +Defined in: node\_modules/typescript/lib/lib.es5.d.ts:1078 + +#### Inherited from + +`Error.stack` + +*** + +### prepareStackTrace()? + +> `static` `optional` **prepareStackTrace**: (`err`, `stackTraces`) => `any` + +Defined in: node\_modules/@types/node/globals.d.ts:143 + +Optional override for formatting stack traces + +#### Parameters + +##### err + +`Error` + +##### stackTraces + +`CallSite`[] + +#### Returns + +`any` + +#### See + +https://v8.dev/docs/stack-trace-api#customizing-stack-traces + +#### Inherited from + +`Error.prepareStackTrace` + +*** + +### stackTraceLimit + +> `static` **stackTraceLimit**: `number` + +Defined in: node\_modules/@types/node/globals.d.ts:145 + +#### Inherited from + +`Error.stackTraceLimit` + +## Methods + +### captureStackTrace() + +> `static` **captureStackTrace**(`targetObject`, `constructorOpt`?): `void` + +Defined in: node\_modules/@types/node/globals.d.ts:136 + +Create .stack property on a target object + +#### Parameters + +##### targetObject + +`object` + +##### constructorOpt? + +`Function` + +#### Returns + +`void` + +#### Inherited from + +`Error.captureStackTrace` diff --git a/docs/code/index/classes/CodeError.md b/docs/code/index/classes/CodeError.md new file mode 100644 index 0000000..c400da3 --- /dev/null +++ b/docs/code/index/classes/CodeError.md @@ -0,0 +1,161 @@ +[**@algorandfoundation/algorand-typescript-testing**](../../README.md) + +*** + +[@algorandfoundation/algorand-typescript-testing](../../README.md) / [index](../README.md) / CodeError + +# Class: CodeError + +Defined in: [src/errors.ts:40](https://github.com/algorandfoundation/algorand-typescript-testing/blob/main/src/errors.ts#L40) + +Raised when unsupported user code is encountered + +## Extends + +- `Error` + +## Constructors + +### new CodeError() + +> **new CodeError**(`message`, `options`?): [`CodeError`](CodeError.md) + +Defined in: [src/errors.ts:41](https://github.com/algorandfoundation/algorand-typescript-testing/blob/main/src/errors.ts#L41) + +#### Parameters + +##### message + +`string` + +##### options? + +`ErrorOptions` + +#### Returns + +[`CodeError`](CodeError.md) + +#### Overrides + +`Error.constructor` + +## Properties + +### cause? + +> `optional` **cause**: `unknown` + +Defined in: node\_modules/typescript/lib/lib.es2022.error.d.ts:26 + +#### Inherited from + +`Error.cause` + +*** + +### message + +> **message**: `string` + +Defined in: node\_modules/typescript/lib/lib.es5.d.ts:1077 + +#### Inherited from + +`Error.message` + +*** + +### name + +> **name**: `string` + +Defined in: node\_modules/typescript/lib/lib.es5.d.ts:1076 + +#### Inherited from + +`Error.name` + +*** + +### stack? + +> `optional` **stack**: `string` + +Defined in: node\_modules/typescript/lib/lib.es5.d.ts:1078 + +#### Inherited from + +`Error.stack` + +*** + +### prepareStackTrace()? + +> `static` `optional` **prepareStackTrace**: (`err`, `stackTraces`) => `any` + +Defined in: node\_modules/@types/node/globals.d.ts:143 + +Optional override for formatting stack traces + +#### Parameters + +##### err + +`Error` + +##### stackTraces + +`CallSite`[] + +#### Returns + +`any` + +#### See + +https://v8.dev/docs/stack-trace-api#customizing-stack-traces + +#### Inherited from + +`Error.prepareStackTrace` + +*** + +### stackTraceLimit + +> `static` **stackTraceLimit**: `number` + +Defined in: node\_modules/@types/node/globals.d.ts:145 + +#### Inherited from + +`Error.stackTraceLimit` + +## Methods + +### captureStackTrace() + +> `static` **captureStackTrace**(`targetObject`, `constructorOpt`?): `void` + +Defined in: node\_modules/@types/node/globals.d.ts:136 + +Create .stack property on a target object + +#### Parameters + +##### targetObject + +`object` + +##### constructorOpt? + +`Function` + +#### Returns + +`void` + +#### Inherited from + +`Error.captureStackTrace` diff --git a/docs/code/index/classes/InternalError.md b/docs/code/index/classes/InternalError.md new file mode 100644 index 0000000..94b5fd4 --- /dev/null +++ b/docs/code/index/classes/InternalError.md @@ -0,0 +1,161 @@ +[**@algorandfoundation/algorand-typescript-testing**](../../README.md) + +*** + +[@algorandfoundation/algorand-typescript-testing](../../README.md) / [index](../README.md) / InternalError + +# Class: InternalError + +Defined in: [src/errors.ts:31](https://github.com/algorandfoundation/algorand-typescript-testing/blob/main/src/errors.ts#L31) + +Raised when testing code errors + +## Extends + +- `Error` + +## Constructors + +### new InternalError() + +> **new InternalError**(`message`, `options`?): [`InternalError`](InternalError.md) + +Defined in: [src/errors.ts:32](https://github.com/algorandfoundation/algorand-typescript-testing/blob/main/src/errors.ts#L32) + +#### Parameters + +##### message + +`string` + +##### options? + +`ErrorOptions` + +#### Returns + +[`InternalError`](InternalError.md) + +#### Overrides + +`Error.constructor` + +## Properties + +### cause? + +> `optional` **cause**: `unknown` + +Defined in: node\_modules/typescript/lib/lib.es2022.error.d.ts:26 + +#### Inherited from + +`Error.cause` + +*** + +### message + +> **message**: `string` + +Defined in: node\_modules/typescript/lib/lib.es5.d.ts:1077 + +#### Inherited from + +`Error.message` + +*** + +### name + +> **name**: `string` + +Defined in: node\_modules/typescript/lib/lib.es5.d.ts:1076 + +#### Inherited from + +`Error.name` + +*** + +### stack? + +> `optional` **stack**: `string` + +Defined in: node\_modules/typescript/lib/lib.es5.d.ts:1078 + +#### Inherited from + +`Error.stack` + +*** + +### prepareStackTrace()? + +> `static` `optional` **prepareStackTrace**: (`err`, `stackTraces`) => `any` + +Defined in: node\_modules/@types/node/globals.d.ts:143 + +Optional override for formatting stack traces + +#### Parameters + +##### err + +`Error` + +##### stackTraces + +`CallSite`[] + +#### Returns + +`any` + +#### See + +https://v8.dev/docs/stack-trace-api#customizing-stack-traces + +#### Inherited from + +`Error.prepareStackTrace` + +*** + +### stackTraceLimit + +> `static` **stackTraceLimit**: `number` + +Defined in: node\_modules/@types/node/globals.d.ts:145 + +#### Inherited from + +`Error.stackTraceLimit` + +## Methods + +### captureStackTrace() + +> `static` **captureStackTrace**(`targetObject`, `constructorOpt`?): `void` + +Defined in: node\_modules/@types/node/globals.d.ts:136 + +Create .stack property on a target object + +#### Parameters + +##### targetObject + +`object` + +##### constructorOpt? + +`Function` + +#### Returns + +`void` + +#### Inherited from + +`Error.captureStackTrace` diff --git a/docs/code/index/classes/NotImplementedError.md b/docs/code/index/classes/NotImplementedError.md new file mode 100644 index 0000000..fbc21aa --- /dev/null +++ b/docs/code/index/classes/NotImplementedError.md @@ -0,0 +1,155 @@ +[**@algorandfoundation/algorand-typescript-testing**](../../README.md) + +*** + +[@algorandfoundation/algorand-typescript-testing](../../README.md) / [index](../README.md) / NotImplementedError + +# Class: NotImplementedError + +Defined in: [src/errors.ts:46](https://github.com/algorandfoundation/algorand-typescript-testing/blob/main/src/errors.ts#L46) + +## Extends + +- `Error` + +## Constructors + +### new NotImplementedError() + +> **new NotImplementedError**(`feature`): [`NotImplementedError`](NotImplementedError.md) + +Defined in: [src/errors.ts:47](https://github.com/algorandfoundation/algorand-typescript-testing/blob/main/src/errors.ts#L47) + +#### Parameters + +##### feature + +`string` + +#### Returns + +[`NotImplementedError`](NotImplementedError.md) + +#### Overrides + +`Error.constructor` + +## Properties + +### cause? + +> `optional` **cause**: `unknown` + +Defined in: node\_modules/typescript/lib/lib.es2022.error.d.ts:26 + +#### Inherited from + +`Error.cause` + +*** + +### message + +> **message**: `string` + +Defined in: node\_modules/typescript/lib/lib.es5.d.ts:1077 + +#### Inherited from + +`Error.message` + +*** + +### name + +> **name**: `string` + +Defined in: node\_modules/typescript/lib/lib.es5.d.ts:1076 + +#### Inherited from + +`Error.name` + +*** + +### stack? + +> `optional` **stack**: `string` + +Defined in: node\_modules/typescript/lib/lib.es5.d.ts:1078 + +#### Inherited from + +`Error.stack` + +*** + +### prepareStackTrace()? + +> `static` `optional` **prepareStackTrace**: (`err`, `stackTraces`) => `any` + +Defined in: node\_modules/@types/node/globals.d.ts:143 + +Optional override for formatting stack traces + +#### Parameters + +##### err + +`Error` + +##### stackTraces + +`CallSite`[] + +#### Returns + +`any` + +#### See + +https://v8.dev/docs/stack-trace-api#customizing-stack-traces + +#### Inherited from + +`Error.prepareStackTrace` + +*** + +### stackTraceLimit + +> `static` **stackTraceLimit**: `number` + +Defined in: node\_modules/@types/node/globals.d.ts:145 + +#### Inherited from + +`Error.stackTraceLimit` + +## Methods + +### captureStackTrace() + +> `static` **captureStackTrace**(`targetObject`, `constructorOpt`?): `void` + +Defined in: node\_modules/@types/node/globals.d.ts:136 + +Create .stack property on a target object + +#### Parameters + +##### targetObject + +`object` + +##### constructorOpt? + +`Function` + +#### Returns + +`void` + +#### Inherited from + +`Error.captureStackTrace` diff --git a/docs/code/index/classes/TestExecutionContext.md b/docs/code/index/classes/TestExecutionContext.md new file mode 100644 index 0000000..6fb3471 --- /dev/null +++ b/docs/code/index/classes/TestExecutionContext.md @@ -0,0 +1,376 @@ +[**@algorandfoundation/algorand-typescript-testing**](../../README.md) + +*** + +[@algorandfoundation/algorand-typescript-testing](../../README.md) / [index](../README.md) / TestExecutionContext + +# Class: TestExecutionContext + +Defined in: [src/test-execution-context.ts:20](https://github.com/algorandfoundation/algorand-typescript-testing/blob/main/src/test-execution-context.ts#L20) + +The `TestExecutionContext` class provides a context for executing tests in an Algorand environment. +It manages various contexts such as contract, ledger, and transaction contexts, and provides utilities +for generating values, managing accounts, and handling logic signatures. + +## Constructors + +### new TestExecutionContext() + +> **new TestExecutionContext**(`defaultSenderAddress`?): [`TestExecutionContext`](TestExecutionContext.md) + +Defined in: [src/test-execution-context.ts:36](https://github.com/algorandfoundation/algorand-typescript-testing/blob/main/src/test-execution-context.ts#L36) + +Creates an instance of `TestExecutionContext`. + +#### Parameters + +##### defaultSenderAddress? + +`bytes` + +The default sender address. + +#### Returns + +[`TestExecutionContext`](TestExecutionContext.md) + +## Accessors + +### activeLogicSigArgs + +#### Get Signature + +> **get** **activeLogicSigArgs**(): `bytes`[] + +Defined in: [src/test-execution-context.ts:117](https://github.com/algorandfoundation/algorand-typescript-testing/blob/main/src/test-execution-context.ts#L117) + +Returns the active logic signature arguments. + +##### Returns + +`bytes`[] + +*** + +### any + +#### Get Signature + +> **get** **any**(): [`ValueGenerator`](../../value-generators/classes/ValueGenerator.md) + +Defined in: [src/test-execution-context.ts:90](https://github.com/algorandfoundation/algorand-typescript-testing/blob/main/src/test-execution-context.ts#L90) + +Returns the value generator. + +##### Returns + +[`ValueGenerator`](../../value-generators/classes/ValueGenerator.md) + +*** + +### contract + +#### Get Signature + +> **get** **contract**(): [`ContractContext`](../../subcontexts/contract-context/classes/ContractContext.md) + +Defined in: [src/test-execution-context.ts:63](https://github.com/algorandfoundation/algorand-typescript-testing/blob/main/src/test-execution-context.ts#L63) + +Returns the contract context. + +##### Returns + +[`ContractContext`](../../subcontexts/contract-context/classes/ContractContext.md) + +*** + +### defaultSender + +#### Get Signature + +> **get** **defaultSender**(): `Account` + +Defined in: [src/test-execution-context.ts:99](https://github.com/algorandfoundation/algorand-typescript-testing/blob/main/src/test-execution-context.ts#L99) + +Returns the default sender account. + +##### Returns + +`Account` + +#### Set Signature + +> **set** **defaultSender**(`val`): `void` + +Defined in: [src/test-execution-context.ts:108](https://github.com/algorandfoundation/algorand-typescript-testing/blob/main/src/test-execution-context.ts#L108) + +Sets the default sender account. + +##### Parameters + +###### val + +The default sender account. + +`bytes` | `Account` + +##### Returns + +`void` + +*** + +### ledger + +#### Get Signature + +> **get** **ledger**(): [`LedgerContext`](../../subcontexts/ledger-context/classes/LedgerContext.md) + +Defined in: [src/test-execution-context.ts:72](https://github.com/algorandfoundation/algorand-typescript-testing/blob/main/src/test-execution-context.ts#L72) + +Returns the ledger context. + +##### Returns + +[`LedgerContext`](../../subcontexts/ledger-context/classes/LedgerContext.md) + +*** + +### templateVars + +#### Get Signature + +> **get** **templateVars**(): `Record`\<`string`, `any`\> + +Defined in: [src/test-execution-context.ts:126](https://github.com/algorandfoundation/algorand-typescript-testing/blob/main/src/test-execution-context.ts#L126) + +Returns the template variables. + +##### Returns + +`Record`\<`string`, `any`\> + +*** + +### txn + +#### Get Signature + +> **get** **txn**(): [`TransactionContext`](../../subcontexts/transaction-context/classes/TransactionContext.md) + +Defined in: [src/test-execution-context.ts:81](https://github.com/algorandfoundation/algorand-typescript-testing/blob/main/src/test-execution-context.ts#L81) + +Returns the transaction context. + +##### Returns + +[`TransactionContext`](../../subcontexts/transaction-context/classes/TransactionContext.md) + +## Methods + +### executeLogicSig() + +> **executeLogicSig**(`logicSig`, ...`args`): `boolean` \| `uint64` + +Defined in: [src/test-execution-context.ts:137](https://github.com/algorandfoundation/algorand-typescript-testing/blob/main/src/test-execution-context.ts#L137) + +Executes a logic signature with the given arguments. + +#### Parameters + +##### logicSig + +`LogicSig` + +The logic signature to execute. + +##### args + +...`bytes`[] + +The arguments for the logic signature. + +#### Returns + +`boolean` \| `uint64` + +*** + +### exportLogs() + +> **exportLogs**\<`T`\>(`appId`, ...`decoding`): `DecodedLogs`\<`T`\> + +Defined in: [src/test-execution-context.ts:54](https://github.com/algorandfoundation/algorand-typescript-testing/blob/main/src/test-execution-context.ts#L54) + +Exports logs for a given application ID and decoding. + +#### Type Parameters + +• **T** *extends* `LogDecoding`[] + +#### Parameters + +##### appId + +`uint64` + +The application ID. + +##### decoding + +...`T` + +The log decoding. + +#### Returns + +`DecodedLogs`\<`T`\> + +*** + +### getCompiledApp() + +> **getCompiledApp**(`contract`): `undefined` \| \[`ConstructorFor`\<`BaseContract`\>, `uint64`\] + +Defined in: [src/test-execution-context.ts:163](https://github.com/algorandfoundation/algorand-typescript-testing/blob/main/src/test-execution-context.ts#L163) + +Gets a compiled application by contract. + +#### Parameters + +##### contract + +`ConstructorFor`\<`BaseContract`\> + +The contract class. + +#### Returns + +`undefined` \| \[`ConstructorFor`\<`BaseContract`\>, `uint64`\] + +*** + +### getCompiledLogicSig() + +> **getCompiledLogicSig**(`logicsig`): `undefined` \| \[`ConstructorFor`\<`LogicSig`\>, `Account`\] + +Defined in: [src/test-execution-context.ts:188](https://github.com/algorandfoundation/algorand-typescript-testing/blob/main/src/test-execution-context.ts#L188) + +Gets a compiled logic signature. + +#### Parameters + +##### logicsig + +`ConstructorFor`\<`LogicSig`\> + +The logic signature class. + +#### Returns + +`undefined` \| \[`ConstructorFor`\<`LogicSig`\>, `Account`\] + +*** + +### reset() + +> **reset**(): `void` + +Defined in: [src/test-execution-context.ts:211](https://github.com/algorandfoundation/algorand-typescript-testing/blob/main/src/test-execution-context.ts#L211) + +Reinitializes the execution context, clearing all state variables and resetting internal components. +Invoked between test cases to ensure isolation. + +#### Returns + +`void` + +*** + +### setCompiledApp() + +> **setCompiledApp**(`c`, `appId`): `void` + +Defined in: [src/test-execution-context.ts:173](https://github.com/algorandfoundation/algorand-typescript-testing/blob/main/src/test-execution-context.ts#L173) + +Sets a compiled application. + +#### Parameters + +##### c + +`ConstructorFor`\<`BaseContract`\> + +The contract class. + +##### appId + +`uint64` + +The application ID. + +#### Returns + +`void` + +*** + +### setCompiledLogicSig() + +> **setCompiledLogicSig**(`c`, `account`): `void` + +Defined in: [src/test-execution-context.ts:198](https://github.com/algorandfoundation/algorand-typescript-testing/blob/main/src/test-execution-context.ts#L198) + +Sets a compiled logic signature. + +#### Parameters + +##### c + +`ConstructorFor`\<`LogicSig`\> + +The logic signature class. + +##### account + +`Account` + +The account associated with the logic signature. + +#### Returns + +`void` + +*** + +### setTemplateVar() + +> **setTemplateVar**(`name`, `value`, `prefix`?): `void` + +Defined in: [src/test-execution-context.ts:153](https://github.com/algorandfoundation/algorand-typescript-testing/blob/main/src/test-execution-context.ts#L153) + +Sets a template variable. + +#### Parameters + +##### name + +`string` + +The name of the template variable. + +##### value + +`any` + +The value of the template variable. + +##### prefix? + +`string` + +The prefix for the template variable. + +#### Returns + +`void` diff --git a/docs/code/index/functions/addEqualityTesters.md b/docs/code/index/functions/addEqualityTesters.md new file mode 100644 index 0000000..b67e49a --- /dev/null +++ b/docs/code/index/functions/addEqualityTesters.md @@ -0,0 +1,42 @@ +[**@algorandfoundation/algorand-typescript-testing**](../../README.md) + +*** + +[@algorandfoundation/algorand-typescript-testing](../../README.md) / [index](../README.md) / addEqualityTesters + +# Function: addEqualityTesters() + +> **addEqualityTesters**(`params`): `void` + +Defined in: [src/set-up.ts:159](https://github.com/algorandfoundation/algorand-typescript-testing/blob/main/src/set-up.ts#L159) + +Adds custom equality testers for Algorand types to vitest's expect function. +This allows vitest to properly compare Algorand types such as uint64, biguint, and bytes +against JS native types such as number, bigint and Uint8Array, in tests. + +## Parameters + +### params + +The parameters object + +#### expect + +`ExpectObj` + +vitest's expect object to extend with custom equality testers + +## Returns + +`void` + +## Example + +```ts +import { beforeAll, expect } from 'vitest' +import { addEqualityTesters } from '@algorandfoundation/algorand-typescript-testing'; + +beforeAll(() => { + addEqualityTesters({ expect }); +}); +``` diff --git a/docs/code/index/functions/toExternalValue.md b/docs/code/index/functions/toExternalValue.md new file mode 100644 index 0000000..f173902 --- /dev/null +++ b/docs/code/index/functions/toExternalValue.md @@ -0,0 +1,159 @@ +[**@algorandfoundation/algorand-typescript-testing**](../../README.md) + +*** + +[@algorandfoundation/algorand-typescript-testing](../../README.md) / [index](../README.md) / toExternalValue + +# Function: toExternalValue() + +## Call Signature + +> **toExternalValue**(`val`): `bigint` + +Defined in: [src/impl/primitives.ts:42](https://github.com/algorandfoundation/algorand-typescript-testing/blob/main/src/impl/primitives.ts#L42) + +Converts internal Algorand type representations to their external primitive values. + +### Parameters + +#### val + +`uint64` + +A uint64 value to convert + +### Returns + +`bigint` + +The uint64 value as a bigint + +The biguint value as a bigint + +The bytes value as a Uint8Array + +The original string value unchanged + +### Example + +```ts +const uint64Val = Uint64(123n) +toExternalValue(uint64Val) // returns 123n + +const bytesVal = Bytes.fromBase64("SGVsbG8="); +toExternalValue(bytesVal) // returns Uint8Array([72, 101, 108, 108, 111]) +``` + +## Call Signature + +> **toExternalValue**(`val`): `bigint` + +Defined in: [src/impl/primitives.ts:43](https://github.com/algorandfoundation/algorand-typescript-testing/blob/main/src/impl/primitives.ts#L43) + +Converts internal Algorand type representations to their external primitive values. + +### Parameters + +#### val + +`biguint` + +A uint64 value to convert + +### Returns + +`bigint` + +The uint64 value as a bigint + +The biguint value as a bigint + +The bytes value as a Uint8Array + +The original string value unchanged + +### Example + +```ts +const uint64Val = Uint64(123n) +toExternalValue(uint64Val) // returns 123n + +const bytesVal = Bytes.fromBase64("SGVsbG8="); +toExternalValue(bytesVal) // returns Uint8Array([72, 101, 108, 108, 111]) +``` + +## Call Signature + +> **toExternalValue**(`val`): `Uint8Array` + +Defined in: [src/impl/primitives.ts:44](https://github.com/algorandfoundation/algorand-typescript-testing/blob/main/src/impl/primitives.ts#L44) + +Converts internal Algorand type representations to their external primitive values. + +### Parameters + +#### val + +`bytes` + +A uint64 value to convert + +### Returns + +`Uint8Array` + +The uint64 value as a bigint + +The biguint value as a bigint + +The bytes value as a Uint8Array + +The original string value unchanged + +### Example + +```ts +const uint64Val = Uint64(123n) +toExternalValue(uint64Val) // returns 123n + +const bytesVal = Bytes.fromBase64("SGVsbG8="); +toExternalValue(bytesVal) // returns Uint8Array([72, 101, 108, 108, 111]) +``` + +## Call Signature + +> **toExternalValue**(`val`): `string` + +Defined in: [src/impl/primitives.ts:45](https://github.com/algorandfoundation/algorand-typescript-testing/blob/main/src/impl/primitives.ts#L45) + +Converts internal Algorand type representations to their external primitive values. + +### Parameters + +#### val + +`string` + +A uint64 value to convert + +### Returns + +`string` + +The uint64 value as a bigint + +The biguint value as a bigint + +The bytes value as a Uint8Array + +The original string value unchanged + +### Example + +```ts +const uint64Val = Uint64(123n) +toExternalValue(uint64Val) // returns 123n + +const bytesVal = Bytes.fromBase64("SGVsbG8="); +toExternalValue(bytesVal) // returns Uint8Array([72, 101, 108, 108, 111]) +``` diff --git a/docs/code/subcontexts/contract-context/README.md b/docs/code/subcontexts/contract-context/README.md new file mode 100644 index 0000000..0e52d7d --- /dev/null +++ b/docs/code/subcontexts/contract-context/README.md @@ -0,0 +1,11 @@ +[**@algorandfoundation/algorand-typescript-testing**](../../README.md) + +*** + +[@algorandfoundation/algorand-typescript-testing](../../README.md) / subcontexts/contract-context + +# subcontexts/contract-context + +## Classes + +- [ContractContext](classes/ContractContext.md) diff --git a/docs/code/subcontexts/contract-context/classes/ContractContext.md b/docs/code/subcontexts/contract-context/classes/ContractContext.md new file mode 100644 index 0000000..05bd9b9 --- /dev/null +++ b/docs/code/subcontexts/contract-context/classes/ContractContext.md @@ -0,0 +1,120 @@ +[**@algorandfoundation/algorand-typescript-testing**](../../../README.md) + +*** + +[@algorandfoundation/algorand-typescript-testing](../../../README.md) / [subcontexts/contract-context](../README.md) / ContractContext + +# Class: ContractContext + +Defined in: [src/subcontexts/contract-context.ts:138](https://github.com/algorandfoundation/algorand-typescript-testing/blob/main/src/subcontexts/contract-context.ts#L138) + +Provides a context for creating contracts and registering created contract instances +with test execution context. + +## Constructors + +### new ContractContext() + +> **new ContractContext**(): [`ContractContext`](ContractContext.md) + +#### Returns + +[`ContractContext`](ContractContext.md) + +## Methods + +### create() + +> **create**\<`T`\>(`type`, ...`args`): `T` + +Defined in: [src/subcontexts/contract-context.ts:150](https://github.com/algorandfoundation/algorand-typescript-testing/blob/main/src/subcontexts/contract-context.ts#L150) + +Creates a new contract instance and register the created instance with test execution context. + +#### Type Parameters + +• **T** *extends* `BaseContract` + +Type of contract extending BaseContract + +#### Parameters + +##### type + +`IConstructor`\<`T`\> + +The contract class constructor + +##### args + +...`any`[] + +Constructor arguments for the contract + +#### Returns + +`T` + +Proxied instance of the contract + +#### Example + +```ts +const ctx = new TestExecutionContext(); +const contract = ctx.contract.create(MyContract); +``` + +*** + +### createMethodCallTxns() + +> `static` **createMethodCallTxns**\<`TParams`\>(`contract`, `abiMetadata`, ...`args`): `Transaction`[] + +Defined in: [src/subcontexts/contract-context.ts:172](https://github.com/algorandfoundation/algorand-typescript-testing/blob/main/src/subcontexts/contract-context.ts#L172) + +**`Internal`** + +Creates an array of transactions for calling a contract method. + +#### Type Parameters + +• **TParams** *extends* `unknown`[] + +Array of parameter types + +#### Parameters + +##### contract + +`BaseContract` + +The contract instance + +##### abiMetadata + +ABI metadata for the method + +`undefined` | `AbiMetadata` + +##### args + +...`TParams` + +Method arguments + +#### Returns + +`Transaction`[] + +Array of transactions needed to execute the method + +#### Example + +```ts +const txns = ContractContext.createMethodCallTxns( + myContract, + methodAbiMetadata, + arg1, + arg2 +); +``` diff --git a/docs/code/subcontexts/ledger-context/README.md b/docs/code/subcontexts/ledger-context/README.md new file mode 100644 index 0000000..3572c51 --- /dev/null +++ b/docs/code/subcontexts/ledger-context/README.md @@ -0,0 +1,11 @@ +[**@algorandfoundation/algorand-typescript-testing**](../../README.md) + +*** + +[@algorandfoundation/algorand-typescript-testing](../../README.md) / subcontexts/ledger-context + +# subcontexts/ledger-context + +## Classes + +- [LedgerContext](classes/LedgerContext.md) diff --git a/docs/code/subcontexts/ledger-context/classes/LedgerContext.md b/docs/code/subcontexts/ledger-context/classes/LedgerContext.md new file mode 100644 index 0000000..047a301 --- /dev/null +++ b/docs/code/subcontexts/ledger-context/classes/LedgerContext.md @@ -0,0 +1,750 @@ +[**@algorandfoundation/algorand-typescript-testing**](../../../README.md) + +*** + +[@algorandfoundation/algorand-typescript-testing](../../../README.md) / [subcontexts/ledger-context](../README.md) / LedgerContext + +# Class: LedgerContext + +Defined in: [src/subcontexts/ledger-context.ts:32](https://github.com/algorandfoundation/algorand-typescript-testing/blob/main/src/subcontexts/ledger-context.ts#L32) + +## Constructors + +### new LedgerContext() + +> **new LedgerContext**(): [`LedgerContext`](LedgerContext.md) + +#### Returns + +[`LedgerContext`](LedgerContext.md) + +## Properties + +### accountDataMap + +> **accountDataMap**: `AccountMap`\<`AccountData`\> + +Defined in: [src/subcontexts/ledger-context.ts:37](https://github.com/algorandfoundation/algorand-typescript-testing/blob/main/src/subcontexts/ledger-context.ts#L37) + +*** + +### appIdContractMap + +> **appIdContractMap**: `Uint64Map`\<`BaseContract`\> + +Defined in: [src/subcontexts/ledger-context.ts:36](https://github.com/algorandfoundation/algorand-typescript-testing/blob/main/src/subcontexts/ledger-context.ts#L36) + +*** + +### appIdIter + +> **appIdIter**: `Generator`\<`bigint`\> + +Defined in: [src/subcontexts/ledger-context.ts:33](https://github.com/algorandfoundation/algorand-typescript-testing/blob/main/src/subcontexts/ledger-context.ts#L33) + +*** + +### applicationDataMap + +> **applicationDataMap**: `Uint64Map`\<`ApplicationData`\> + +Defined in: [src/subcontexts/ledger-context.ts:35](https://github.com/algorandfoundation/algorand-typescript-testing/blob/main/src/subcontexts/ledger-context.ts#L35) + +*** + +### assetDataMap + +> **assetDataMap**: `Uint64Map`\<`Mutable`\<`Omit`\<`Asset`, `"id"` \| `"balance"` \| `"frozen"`\>\>\> + +Defined in: [src/subcontexts/ledger-context.ts:38](https://github.com/algorandfoundation/algorand-typescript-testing/blob/main/src/subcontexts/ledger-context.ts#L38) + +*** + +### assetIdIter + +> **assetIdIter**: `Generator`\<`bigint`\> + +Defined in: [src/subcontexts/ledger-context.ts:34](https://github.com/algorandfoundation/algorand-typescript-testing/blob/main/src/subcontexts/ledger-context.ts#L34) + +*** + +### blocks + +> **blocks**: `Uint64Map`\<`BlockData`\> + +Defined in: [src/subcontexts/ledger-context.ts:40](https://github.com/algorandfoundation/algorand-typescript-testing/blob/main/src/subcontexts/ledger-context.ts#L40) + +*** + +### globalData + +> **globalData**: `GlobalData` + +Defined in: [src/subcontexts/ledger-context.ts:41](https://github.com/algorandfoundation/algorand-typescript-testing/blob/main/src/subcontexts/ledger-context.ts#L41) + +*** + +### onlineStake + +> **onlineStake**: `number` = `0` + +Defined in: [src/subcontexts/ledger-context.ts:42](https://github.com/algorandfoundation/algorand-typescript-testing/blob/main/src/subcontexts/ledger-context.ts#L42) + +*** + +### voterDataMap + +> **voterDataMap**: `AccountMap`\<`VoterData`\> + +Defined in: [src/subcontexts/ledger-context.ts:39](https://github.com/algorandfoundation/algorand-typescript-testing/blob/main/src/subcontexts/ledger-context.ts#L39) + +## Methods + +### addAppIdContractMap() + +> **addAppIdContractMap**(`appId`, `contract`): `void` + +Defined in: [src/subcontexts/ledger-context.ts:50](https://github.com/algorandfoundation/algorand-typescript-testing/blob/main/src/subcontexts/ledger-context.ts#L50) + +**`Internal`** + +Adds a contract to the application ID contract map. + +#### Parameters + +##### appId + +`StubUint64Compat` + +The application ID. + +##### contract + +`BaseContract` + +The contract to add. + +#### Returns + +`void` + +*** + +### boxExists() + +> **boxExists**(`app`, `key`): `boolean` + +Defined in: [src/subcontexts/ledger-context.ts:377](https://github.com/algorandfoundation/algorand-typescript-testing/blob/main/src/subcontexts/ledger-context.ts#L377) + +Checks if a box exists for an application by key. + +#### Parameters + +##### app + +The application. + +`Application` | `BaseContract` + +##### key + +`StubBytesCompat` + +The key. + +#### Returns + +`boolean` + +True if the box exists, false otherwise. + +*** + +### deleteBox() + +> **deleteBox**(`app`, `key`): `boolean` + +Defined in: [src/subcontexts/ledger-context.ts:365](https://github.com/algorandfoundation/algorand-typescript-testing/blob/main/src/subcontexts/ledger-context.ts#L365) + +Deletes a box for an application by key. + +#### Parameters + +##### app + +The application. + +`Application` | `BaseContract` + +##### key + +`StubBytesCompat` + +The key. + +#### Returns + +`boolean` + +True if the box was deleted, false otherwise. + +*** + +### getAccount() + +> **getAccount**(`address`): `Account` + +Defined in: [src/subcontexts/ledger-context.ts:59](https://github.com/algorandfoundation/algorand-typescript-testing/blob/main/src/subcontexts/ledger-context.ts#L59) + +Retrieves an account by address. + +#### Parameters + +##### address + +The account address. + +`StubBytesCompat` | `Account` + +#### Returns + +`Account` + +The account. + +*** + +### getApplication() + +> **getApplication**(`applicationId`): `Application` + +Defined in: [src/subcontexts/ledger-context.ts:82](https://github.com/algorandfoundation/algorand-typescript-testing/blob/main/src/subcontexts/ledger-context.ts#L82) + +Retrieves an application by application ID. + +#### Parameters + +##### applicationId + +`StubUint64Compat` + +The application ID. + +#### Returns + +`Application` + +The application. + +#### Throws + +If the application is unknown. + +*** + +### getApplicationForApprovalProgram() + +> **getApplicationForApprovalProgram**(`approvalProgram`): `undefined` \| `Application` + +Defined in: [src/subcontexts/ledger-context.ts:111](https://github.com/algorandfoundation/algorand-typescript-testing/blob/main/src/subcontexts/ledger-context.ts#L111) + +Retrieves an application for a given approval program. + +#### Parameters + +##### approvalProgram + +The approval program. + +`undefined` | `bytes` | readonly `bytes`[] + +#### Returns + +`undefined` \| `Application` + +The application or undefined if not found. + +*** + +### getApplicationForContract() + +> **getApplicationForContract**(`contract`): `Application` + +Defined in: [src/subcontexts/ledger-context.ts:95](https://github.com/algorandfoundation/algorand-typescript-testing/blob/main/src/subcontexts/ledger-context.ts#L95) + +Retrieves an application for a given contract. + +#### Parameters + +##### contract + +`BaseContract` + +The contract. + +#### Returns + +`Application` + +The application. + +#### Throws + +If the contract is unknown. + +*** + +### getAsset() + +> **getAsset**(`assetId`): `Asset` + +Defined in: [src/subcontexts/ledger-context.ts:69](https://github.com/algorandfoundation/algorand-typescript-testing/blob/main/src/subcontexts/ledger-context.ts#L69) + +Retrieves an asset by asset ID. + +#### Parameters + +##### assetId + +`StubUint64Compat` + +The asset ID. + +#### Returns + +`Asset` + +The asset. + +#### Throws + +If the asset is unknown. + +*** + +### getBlockData() + +> **getBlockData**(`index`): `BlockData` + +Defined in: [src/subcontexts/ledger-context.ts:245](https://github.com/algorandfoundation/algorand-typescript-testing/blob/main/src/subcontexts/ledger-context.ts#L245) + +Retrieves block data by index. + +#### Parameters + +##### index + +`StubUint64Compat` + +The block index. + +#### Returns + +`BlockData` + +The block data. + +#### Throws + +If the block is not set. + +*** + +### getBox() + +> **getBox**(`app`, `key`): `Uint8Array` + +Defined in: [src/subcontexts/ledger-context.ts:340](https://github.com/algorandfoundation/algorand-typescript-testing/blob/main/src/subcontexts/ledger-context.ts#L340) + +Retrieves a box for an application by key. + +#### Parameters + +##### app + +The application. + +`Application` | `BaseContract` + +##### key + +`StubBytesCompat` + +The key. + +#### Returns + +`Uint8Array` + +The box data. + +*** + +### getGlobalState() + +> **getGlobalState**(`app`, `key`): \[`GlobalStateCls`\<`unknown`\>, `true`\] \| \[`undefined`, `false`\] + +Defined in: [src/subcontexts/ledger-context.ts:259](https://github.com/algorandfoundation/algorand-typescript-testing/blob/main/src/subcontexts/ledger-context.ts#L259) + +Retrieves global state for an application by key. + +#### Parameters + +##### app + +The application. + +`Application` | `BaseContract` + +##### key + +`StubBytesCompat` + +The key. + +#### Returns + +\[`GlobalStateCls`\<`unknown`\>, `true`\] \| \[`undefined`, `false`\] + +The global state and a boolean indicating if it was found. + +*** + +### getLocalState() + +> **getLocalState**(`app`, `account`, `key`): \[`undefined`, `false`\] \| \[`LocalStateForAccount`\<`unknown`\>, `true`\] + +Defined in: [src/subcontexts/ledger-context.ts:294](https://github.com/algorandfoundation/algorand-typescript-testing/blob/main/src/subcontexts/ledger-context.ts#L294) + +Retrieves local state for an application and account by key. + +#### Parameters + +##### app + +The application. + +`uint64` | `Application` | `BaseContract` + +##### account + +`Account` + +The account. + +##### key + +`StubBytesCompat` + +The key. + +#### Returns + +\[`undefined`, `false`\] \| \[`LocalStateForAccount`\<`unknown`\>, `true`\] + +The local state and a boolean indicating if it was found. + +*** + +### patchAccountData() + +> **patchAccountData**(`account`, `data`): `void` + +Defined in: [src/subcontexts/ledger-context.ts:167](https://github.com/algorandfoundation/algorand-typescript-testing/blob/main/src/subcontexts/ledger-context.ts#L167) + +Patches account data with the provided partial data. + +#### Parameters + +##### account + +`Account` + +The account. + +##### data + +`Partial`\<`Omit`\<`AccountData`, `"account"`\>\> & `Partial`\<`PickPartial`\<`AccountData`, `"account"`\>\> + +The partial account data. + +#### Returns + +`void` + +*** + +### patchApplicationData() + +> **patchApplicationData**(`app`, `data`): `void` + +Defined in: [src/subcontexts/ledger-context.ts:184](https://github.com/algorandfoundation/algorand-typescript-testing/blob/main/src/subcontexts/ledger-context.ts#L184) + +Patches application data with the provided partial data. + +#### Parameters + +##### app + +`Application` + +The application. + +##### data + +`Partial`\<`Omit`\<`ApplicationData`, `"application"`\>\> & `Partial`\<`PickPartial`\<`ApplicationData`, `"application"`\>\> + +The partial application data. + +#### Returns + +`void` + +*** + +### patchAssetData() + +> **patchAssetData**(`asset`, `data`): `void` + +Defined in: [src/subcontexts/ledger-context.ts:204](https://github.com/algorandfoundation/algorand-typescript-testing/blob/main/src/subcontexts/ledger-context.ts#L204) + +Patches asset data with the provided partial data. + +#### Parameters + +##### asset + +`Asset` + +##### data + +`Partial`\<`Mutable`\<`Omit`\<`Asset`, `"id"` \| `"balance"` \| `"frozen"`\>\>\> + +The partial asset data. + +#### Returns + +`void` + +*** + +### patchBlockData() + +> **patchBlockData**(`index`, `data`): `void` + +Defined in: [src/subcontexts/ledger-context.ts:230](https://github.com/algorandfoundation/algorand-typescript-testing/blob/main/src/subcontexts/ledger-context.ts#L230) + +Patches block data with the provided partial data. + +#### Parameters + +##### index + +`StubUint64Compat` + +The block index. + +##### data + +`Partial`\<`BlockData`\> + +The partial block data. + +#### Returns + +`void` + +*** + +### patchGlobalData() + +> **patchGlobalData**(`data`): `void` + +Defined in: [src/subcontexts/ledger-context.ts:155](https://github.com/algorandfoundation/algorand-typescript-testing/blob/main/src/subcontexts/ledger-context.ts#L155) + +Patches global data with the provided partial data. + +#### Parameters + +##### data + +`Partial`\<`GlobalData`\> + +The partial global data. + +#### Returns + +`void` + +*** + +### patchVoterData() + +> **patchVoterData**(`account`, `data`): `void` + +Defined in: [src/subcontexts/ledger-context.ts:217](https://github.com/algorandfoundation/algorand-typescript-testing/blob/main/src/subcontexts/ledger-context.ts#L217) + +Patches voter data with the provided partial data. + +#### Parameters + +##### account + +`Account` + +The account. + +##### data + +`Partial`\<`VoterData`\> + +The partial voter data. + +#### Returns + +`void` + +*** + +### setBox() + +> **setBox**(`app`, `key`, `value`): `void` + +Defined in: [src/subcontexts/ledger-context.ts:352](https://github.com/algorandfoundation/algorand-typescript-testing/blob/main/src/subcontexts/ledger-context.ts#L352) + +Sets a box for an application by key. + +#### Parameters + +##### app + +The application. + +`Application` | `BaseContract` + +##### key + +`StubBytesCompat` + +The key. + +##### value + +The box data. + +`Uint8Array` | `StubBytesCompat` + +#### Returns + +`void` + +*** + +### setGlobalState() + +> **setGlobalState**(`app`, `key`, `value`): `void` + +Defined in: [src/subcontexts/ledger-context.ts:274](https://github.com/algorandfoundation/algorand-typescript-testing/blob/main/src/subcontexts/ledger-context.ts#L274) + +Sets global state for an application by key. + +#### Parameters + +##### app + +The application. + +`Application` | `BaseContract` + +##### key + +`StubBytesCompat` + +The key. + +##### value + +The value (optional). + +`undefined` | `StubBytesCompat` | `StubUint64Compat` + +#### Returns + +`void` + +*** + +### setLocalState() + +> **setLocalState**\<`T`\>(`app`, `account`, `key`, `value`): `void` + +Defined in: [src/subcontexts/ledger-context.ts:316](https://github.com/algorandfoundation/algorand-typescript-testing/blob/main/src/subcontexts/ledger-context.ts#L316) + +Sets local state for an application and account by key. + +#### Type Parameters + +• **T** + +#### Parameters + +##### app + +The application. + +`uint64` | `Application` | `BaseContract` + +##### account + +`Account` + +The account. + +##### key + +`StubBytesCompat` + +The key. + +##### value + +The value (optional). + +`undefined` | `T` + +#### Returns + +`void` + +*** + +### updateAssetHolding() + +> **updateAssetHolding**(`account`, `assetId`, `balance`?, `frozen`?): `void` + +Defined in: [src/subcontexts/ledger-context.ts:141](https://github.com/algorandfoundation/algorand-typescript-testing/blob/main/src/subcontexts/ledger-context.ts#L141) + +Update asset holdings for account, only specified values will be updated. +AccountType will also be opted-in to asset + +#### Parameters + +##### account + +`Account` + +##### assetId + +`StubUint64Compat` | `Asset` + +##### balance? + +`StubUint64Compat` + +##### frozen? + +`boolean` + +#### Returns + +`void` diff --git a/docs/code/subcontexts/transaction-context/README.md b/docs/code/subcontexts/transaction-context/README.md new file mode 100644 index 0000000..32e8d08 --- /dev/null +++ b/docs/code/subcontexts/transaction-context/README.md @@ -0,0 +1,14 @@ +[**@algorandfoundation/algorand-typescript-testing**](../../README.md) + +*** + +[@algorandfoundation/algorand-typescript-testing](../../README.md) / subcontexts/transaction-context + +# subcontexts/transaction-context + +## Classes + +- [DeferredAppCall](classes/DeferredAppCall.md) +- [ItxnGroup](classes/ItxnGroup.md) +- [TransactionContext](classes/TransactionContext.md) +- [TransactionGroup](classes/TransactionGroup.md) diff --git a/docs/code/subcontexts/transaction-context/classes/DeferredAppCall.md b/docs/code/subcontexts/transaction-context/classes/DeferredAppCall.md new file mode 100644 index 0000000..a6cde11 --- /dev/null +++ b/docs/code/subcontexts/transaction-context/classes/DeferredAppCall.md @@ -0,0 +1,75 @@ +[**@algorandfoundation/algorand-typescript-testing**](../../../README.md) + +*** + +[@algorandfoundation/algorand-typescript-testing](../../../README.md) / [subcontexts/transaction-context](../README.md) / DeferredAppCall + +# Class: DeferredAppCall\ + +Defined in: [src/subcontexts/transaction-context.ts:59](https://github.com/algorandfoundation/algorand-typescript-testing/blob/main/src/subcontexts/transaction-context.ts#L59) + +Represents a deferred application call. + +## Type Parameters + +• **TParams** *extends* `unknown`[] + +• **TReturn** + +## Constructors + +### new DeferredAppCall() + +> **new DeferredAppCall**\<`TParams`, `TReturn`\>(`appId`, `txns`, `method`, `abiMetadata`, `args`): [`DeferredAppCall`](DeferredAppCall.md)\<`TParams`, `TReturn`\> + +Defined in: [src/subcontexts/transaction-context.ts:60](https://github.com/algorandfoundation/algorand-typescript-testing/blob/main/src/subcontexts/transaction-context.ts#L60) + +#### Parameters + +##### appId + +`uint64` + +##### txns + +`Transaction`[] + +##### method + +(...`args`) => `TReturn` + +##### abiMetadata + +`AbiMetadata` + +##### args + +`TParams` + +#### Returns + +[`DeferredAppCall`](DeferredAppCall.md)\<`TParams`, `TReturn`\> + +## Properties + +### txns + +> `readonly` **txns**: `Transaction`[] + +Defined in: [src/subcontexts/transaction-context.ts:62](https://github.com/algorandfoundation/algorand-typescript-testing/blob/main/src/subcontexts/transaction-context.ts#L62) + +## Methods + +### submit() + +> **submit**(): `TReturn` + +Defined in: [src/subcontexts/transaction-context.ts:72](https://github.com/algorandfoundation/algorand-typescript-testing/blob/main/src/subcontexts/transaction-context.ts#L72) + +Submits the deferred application call. + +#### Returns + +`TReturn` + +The result of the application call. diff --git a/docs/code/subcontexts/transaction-context/classes/ItxnGroup.md b/docs/code/subcontexts/transaction-context/classes/ItxnGroup.md new file mode 100644 index 0000000..b63bb38 --- /dev/null +++ b/docs/code/subcontexts/transaction-context/classes/ItxnGroup.md @@ -0,0 +1,205 @@ +[**@algorandfoundation/algorand-typescript-testing**](../../../README.md) + +*** + +[@algorandfoundation/algorand-typescript-testing](../../../README.md) / [subcontexts/transaction-context](../README.md) / ItxnGroup + +# Class: ItxnGroup + +Defined in: [src/subcontexts/transaction-context.ts:485](https://github.com/algorandfoundation/algorand-typescript-testing/blob/main/src/subcontexts/transaction-context.ts#L485) + +Represents a group of inner transactions. + +## Constructors + +### new ItxnGroup() + +> **new ItxnGroup**(`itxns`): [`ItxnGroup`](ItxnGroup.md) + +Defined in: [src/subcontexts/transaction-context.ts:487](https://github.com/algorandfoundation/algorand-typescript-testing/blob/main/src/subcontexts/transaction-context.ts#L487) + +#### Parameters + +##### itxns + +`InnerTxn`[] + +#### Returns + +[`ItxnGroup`](ItxnGroup.md) + +## Properties + +### itxns + +> **itxns**: `InnerTxn`[] = `[]` + +Defined in: [src/subcontexts/transaction-context.ts:486](https://github.com/algorandfoundation/algorand-typescript-testing/blob/main/src/subcontexts/transaction-context.ts#L486) + +## Methods + +### getApplicationInnerTxn() + +> **getApplicationInnerTxn**(`index`?): `ApplicationInnerTxn` + +Defined in: [src/subcontexts/transaction-context.ts:496](https://github.com/algorandfoundation/algorand-typescript-testing/blob/main/src/subcontexts/transaction-context.ts#L496) + +Gets an application inner transaction by index. + +#### Parameters + +##### index? + +`StubUint64Compat` + +The index of the transaction. + +#### Returns + +`ApplicationInnerTxn` + +The application inner transaction. + +*** + +### getAssetConfigInnerTxn() + +> **getAssetConfigInnerTxn**(`index`?): `AssetConfigInnerTxn` + +Defined in: [src/subcontexts/transaction-context.ts:505](https://github.com/algorandfoundation/algorand-typescript-testing/blob/main/src/subcontexts/transaction-context.ts#L505) + +Gets an asset configuration inner transaction by index. + +#### Parameters + +##### index? + +`StubUint64Compat` + +The index of the transaction. + +#### Returns + +`AssetConfigInnerTxn` + +The asset configuration inner transaction. + +*** + +### getAssetFreezeInnerTxn() + +> **getAssetFreezeInnerTxn**(`index`?): `AssetFreezeInnerTxn` + +Defined in: [src/subcontexts/transaction-context.ts:523](https://github.com/algorandfoundation/algorand-typescript-testing/blob/main/src/subcontexts/transaction-context.ts#L523) + +Gets an asset freeze inner transaction by index. + +#### Parameters + +##### index? + +`StubUint64Compat` + +The index of the transaction. + +#### Returns + +`AssetFreezeInnerTxn` + +The asset freeze inner transaction. + +*** + +### getAssetTransferInnerTxn() + +> **getAssetTransferInnerTxn**(`index`?): `AssetTransferInnerTxn` + +Defined in: [src/subcontexts/transaction-context.ts:514](https://github.com/algorandfoundation/algorand-typescript-testing/blob/main/src/subcontexts/transaction-context.ts#L514) + +Gets an asset transfer inner transaction by index. + +#### Parameters + +##### index? + +`StubUint64Compat` + +The index of the transaction. + +#### Returns + +`AssetTransferInnerTxn` + +The asset transfer inner transaction. + +*** + +### getInnerTxn() + +> **getInnerTxn**(`index`?): `InnerTxn` + +Defined in: [src/subcontexts/transaction-context.ts:550](https://github.com/algorandfoundation/algorand-typescript-testing/blob/main/src/subcontexts/transaction-context.ts#L550) + +Gets an inner transaction by index. + +#### Parameters + +##### index? + +`StubUint64Compat` + +The index of the transaction. + +#### Returns + +`InnerTxn` + +The inner transaction. + +*** + +### getKeyRegistrationInnerTxn() + +> **getKeyRegistrationInnerTxn**(`index`?): `KeyRegistrationInnerTxn` + +Defined in: [src/subcontexts/transaction-context.ts:532](https://github.com/algorandfoundation/algorand-typescript-testing/blob/main/src/subcontexts/transaction-context.ts#L532) + +Gets a key registration inner transaction by index. + +#### Parameters + +##### index? + +`StubUint64Compat` + +The index of the transaction. + +#### Returns + +`KeyRegistrationInnerTxn` + +The key registration inner transaction. + +*** + +### getPaymentInnerTxn() + +> **getPaymentInnerTxn**(`index`?): `PaymentInnerTxn` + +Defined in: [src/subcontexts/transaction-context.ts:541](https://github.com/algorandfoundation/algorand-typescript-testing/blob/main/src/subcontexts/transaction-context.ts#L541) + +Gets a payment inner transaction by index. + +#### Parameters + +##### index? + +`StubUint64Compat` + +The index of the transaction. + +#### Returns + +`PaymentInnerTxn` + +The payment inner transaction. diff --git a/docs/code/subcontexts/transaction-context/classes/TransactionContext.md b/docs/code/subcontexts/transaction-context/classes/TransactionContext.md new file mode 100644 index 0000000..da359b5 --- /dev/null +++ b/docs/code/subcontexts/transaction-context/classes/TransactionContext.md @@ -0,0 +1,265 @@ +[**@algorandfoundation/algorand-typescript-testing**](../../../README.md) + +*** + +[@algorandfoundation/algorand-typescript-testing](../../../README.md) / [subcontexts/transaction-context](../README.md) / TransactionContext + +# Class: TransactionContext + +Defined in: [src/subcontexts/transaction-context.ts:81](https://github.com/algorandfoundation/algorand-typescript-testing/blob/main/src/subcontexts/transaction-context.ts#L81) + +Manages transaction contexts and groups. + +## Constructors + +### new TransactionContext() + +> **new TransactionContext**(): [`TransactionContext`](TransactionContext.md) + +#### Returns + +[`TransactionContext`](TransactionContext.md) + +## Properties + +### groups + +> `readonly` **groups**: [`TransactionGroup`](TransactionGroup.md)[] = `[]` + +Defined in: [src/subcontexts/transaction-context.ts:82](https://github.com/algorandfoundation/algorand-typescript-testing/blob/main/src/subcontexts/transaction-context.ts#L82) + +## Accessors + +### activeGroup + +#### Get Signature + +> **get** **activeGroup**(): [`TransactionGroup`](TransactionGroup.md) + +Defined in: [src/subcontexts/transaction-context.ts:148](https://github.com/algorandfoundation/algorand-typescript-testing/blob/main/src/subcontexts/transaction-context.ts#L148) + +Gets the active transaction group. + +##### Throws + +If there is no active transaction group. + +##### Returns + +[`TransactionGroup`](TransactionGroup.md) + +The active transaction group. + +*** + +### lastActive + +#### Get Signature + +> **get** **lastActive**(): `Transaction` + +Defined in: [src/subcontexts/transaction-context.ts:171](https://github.com/algorandfoundation/algorand-typescript-testing/blob/main/src/subcontexts/transaction-context.ts#L171) + +Gets the last active transaction. + +##### Returns + +`Transaction` + +The last active transaction. + +*** + +### lastGroup + +#### Get Signature + +> **get** **lastGroup**(): [`TransactionGroup`](TransactionGroup.md) + +Defined in: [src/subcontexts/transaction-context.ts:160](https://github.com/algorandfoundation/algorand-typescript-testing/blob/main/src/subcontexts/transaction-context.ts#L160) + +Gets the last transaction group. + +##### Throws + +If there are no transaction groups. + +##### Returns + +[`TransactionGroup`](TransactionGroup.md) + +The last transaction group. + +## Methods + +### appendLog() + +> **appendLog**(`value`): `void` + +Defined in: [src/subcontexts/transaction-context.ts:181](https://github.com/algorandfoundation/algorand-typescript-testing/blob/main/src/subcontexts/transaction-context.ts#L181) + +**`Internal`** + +Appends a log to the active transaction. + +#### Parameters + +##### value + +`StubBytesCompat` + +The log value. + +#### Returns + +`void` + +#### Throws + +If the active transaction is not an application call. + +*** + +### createScope() + +> **createScope**(`group`, `activeTransactionIndex`?): `ExecutionScope` + +Defined in: [src/subcontexts/transaction-context.ts:91](https://github.com/algorandfoundation/algorand-typescript-testing/blob/main/src/subcontexts/transaction-context.ts#L91) + +Creates a new execution scope for a group of transactions. + +#### Parameters + +##### group + +(`Transaction` \| [`DeferredAppCall`](DeferredAppCall.md)\<`any`[], `any`\>)[] + +The group of transactions or deferred application calls. + +##### activeTransactionIndex? + +`number` + +The index of the active transaction. + +#### Returns + +`ExecutionScope` + +The execution scope. + +*** + +### deferAppCall() + +> **deferAppCall**\<`TContract`, `TParams`, `TReturn`\>(`contract`, `method`, `methodName`, ...`args`): [`DeferredAppCall`](DeferredAppCall.md)\<`TParams`, `TReturn`\> + +Defined in: [src/subcontexts/transaction-context.ts:197](https://github.com/algorandfoundation/algorand-typescript-testing/blob/main/src/subcontexts/transaction-context.ts#L197) + +Defers an application call. + +#### Type Parameters + +• **TContract** *extends* `Contract` + +• **TParams** *extends* `unknown`[] + +• **TReturn** + +#### Parameters + +##### contract + +`TContract` + +The contract. + +##### method + +(...`args`) => `TReturn` + +The method to call. + +##### methodName + +`FunctionKeys`\<`TContract`\> + +The name of the method. + +##### args + +...`TParams` + +The arguments for the method. + +#### Returns + +[`DeferredAppCall`](DeferredAppCall.md)\<`TParams`, `TReturn`\> + +The deferred application call. + +*** + +### ensureScope() + +> **ensureScope**(`group`, `activeTransactionIndex`?): `ExecutionScope` + +Defined in: [src/subcontexts/transaction-context.ts:132](https://github.com/algorandfoundation/algorand-typescript-testing/blob/main/src/subcontexts/transaction-context.ts#L132) + +**`Internal`** + +Ensures that a scope is created for the given group of transactions. + +#### Parameters + +##### group + +`Transaction`[] + +The group of transactions. + +##### activeTransactionIndex? + +`number` + +The index of the active transaction. + +#### Returns + +`ExecutionScope` + +The execution scope. + +*** + +### exportLogs() + +> **exportLogs**\<`T`\>(`appId`, ...`decoding`): `DecodedLogs`\<`T`\> + +Defined in: [src/subcontexts/transaction-context.ts:215](https://github.com/algorandfoundation/algorand-typescript-testing/blob/main/src/subcontexts/transaction-context.ts#L215) + +Exports logs for the given application ID. + +#### Type Parameters + +• **T** *extends* `LogDecoding`[] + +#### Parameters + +##### appId + +`uint64` + +The application ID. + +##### decoding + +...`T` + +The log decoding. + +#### Returns + +`DecodedLogs`\<`T`\> + +The decoded logs. diff --git a/docs/code/subcontexts/transaction-context/classes/TransactionGroup.md b/docs/code/subcontexts/transaction-context/classes/TransactionGroup.md new file mode 100644 index 0000000..b290a8c --- /dev/null +++ b/docs/code/subcontexts/transaction-context/classes/TransactionGroup.md @@ -0,0 +1,485 @@ +[**@algorandfoundation/algorand-typescript-testing**](../../../README.md) + +*** + +[@algorandfoundation/algorand-typescript-testing](../../../README.md) / [subcontexts/transaction-context](../README.md) / TransactionGroup + +# Class: TransactionGroup + +Defined in: [src/subcontexts/transaction-context.ts:233](https://github.com/algorandfoundation/algorand-typescript-testing/blob/main/src/subcontexts/transaction-context.ts#L233) + +Represents a group of transactions. + +## Constructors + +### new TransactionGroup() + +> **new TransactionGroup**(`transactions`, `activeTransactionIndex`?): [`TransactionGroup`](TransactionGroup.md) + +Defined in: [src/subcontexts/transaction-context.ts:240](https://github.com/algorandfoundation/algorand-typescript-testing/blob/main/src/subcontexts/transaction-context.ts#L240) + +#### Parameters + +##### transactions + +`Transaction`[] + +##### activeTransactionIndex? + +`number` + +#### Returns + +[`TransactionGroup`](TransactionGroup.md) + +## Properties + +### activeTransactionIndex + +> **activeTransactionIndex**: `number` + +Defined in: [src/subcontexts/transaction-context.ts:234](https://github.com/algorandfoundation/algorand-typescript-testing/blob/main/src/subcontexts/transaction-context.ts#L234) + +*** + +### constructingItxnGroup + +> **constructingItxnGroup**: `InnerTxnFields`[] = `[]` + +Defined in: [src/subcontexts/transaction-context.ts:238](https://github.com/algorandfoundation/algorand-typescript-testing/blob/main/src/subcontexts/transaction-context.ts#L238) + +*** + +### itxnGroups + +> **itxnGroups**: [`ItxnGroup`](ItxnGroup.md)[] = `[]` + +Defined in: [src/subcontexts/transaction-context.ts:237](https://github.com/algorandfoundation/algorand-typescript-testing/blob/main/src/subcontexts/transaction-context.ts#L237) + +*** + +### latestTimestamp + +> **latestTimestamp**: `number` + +Defined in: [src/subcontexts/transaction-context.ts:235](https://github.com/algorandfoundation/algorand-typescript-testing/blob/main/src/subcontexts/transaction-context.ts#L235) + +*** + +### transactions + +> **transactions**: `Transaction`[] + +Defined in: [src/subcontexts/transaction-context.ts:236](https://github.com/algorandfoundation/algorand-typescript-testing/blob/main/src/subcontexts/transaction-context.ts#L236) + +## Accessors + +### activeApplicationId + +#### Get Signature + +> **get** **activeApplicationId**(): `uint64` + +Defined in: [src/subcontexts/transaction-context.ts:263](https://github.com/algorandfoundation/algorand-typescript-testing/blob/main/src/subcontexts/transaction-context.ts#L263) + +Gets the active application ID. + +##### Throws + +If there are no transactions in the group or the active transaction is not an application call. + +##### Returns + +`uint64` + +The active application ID. + +*** + +### activeTransaction + +#### Get Signature + +> **get** **activeTransaction**(): `Transaction` + +Defined in: [src/subcontexts/transaction-context.ts:254](https://github.com/algorandfoundation/algorand-typescript-testing/blob/main/src/subcontexts/transaction-context.ts#L254) + +Gets the active transaction. + +##### Returns + +`Transaction` + +The active transaction. + +*** + +### constructingItxn + +#### Get Signature + +> **get** **constructingItxn**(): `InnerTxnFields` + +Defined in: [src/subcontexts/transaction-context.ts:273](https://github.com/algorandfoundation/algorand-typescript-testing/blob/main/src/subcontexts/transaction-context.ts#L273) + +##### Returns + +`InnerTxnFields` + +## Methods + +### addInnerTransactionGroup() + +> **addInnerTransactionGroup**(...`itxns`): `void` + +Defined in: [src/subcontexts/transaction-context.ts:312](https://github.com/algorandfoundation/algorand-typescript-testing/blob/main/src/subcontexts/transaction-context.ts#L312) + +**`Internal`** + +Adds a group of inner transactions. + +#### Parameters + +##### itxns + +...`InnerTxn`[] + +The inner transactions. + +#### Returns + +`void` + +*** + +### appendInnerTransactionGroup() + +> **appendInnerTransactionGroup**(): `void` + +Defined in: [src/subcontexts/transaction-context.ts:337](https://github.com/algorandfoundation/algorand-typescript-testing/blob/main/src/subcontexts/transaction-context.ts#L337) + +**`Internal`** + +Appends a new inner transaction to the current group. + +#### Returns + +`void` + +#### Throws + +If there is no inner transaction group being constructed. + +*** + +### beginInnerTransactionGroup() + +> **beginInnerTransactionGroup**(): `void` + +Defined in: [src/subcontexts/transaction-context.ts:321](https://github.com/algorandfoundation/algorand-typescript-testing/blob/main/src/subcontexts/transaction-context.ts#L321) + +**`Internal`** + +Begins a new inner transaction group. + +#### Returns + +`void` + +#### Throws + +If there is already an inner transaction group being constructed or the active transaction is not an application call. + +*** + +### getApplicationTransaction() + +> **getApplicationTransaction**(`index`?): `ApplicationTransaction` + +Defined in: [src/subcontexts/transaction-context.ts:394](https://github.com/algorandfoundation/algorand-typescript-testing/blob/main/src/subcontexts/transaction-context.ts#L394) + +Gets an application transaction by index. + +#### Parameters + +##### index? + +`StubUint64Compat` + +The index of the transaction. + +#### Returns + +`ApplicationTransaction` + +The application transaction. + +*** + +### getAssetConfigTransaction() + +> **getAssetConfigTransaction**(`index`?): `AssetConfigTransaction` + +Defined in: [src/subcontexts/transaction-context.ts:403](https://github.com/algorandfoundation/algorand-typescript-testing/blob/main/src/subcontexts/transaction-context.ts#L403) + +Gets an asset configuration transaction by index. + +#### Parameters + +##### index? + +`StubUint64Compat` + +The index of the transaction. + +#### Returns + +`AssetConfigTransaction` + +The asset configuration transaction. + +*** + +### getAssetFreezeTransaction() + +> **getAssetFreezeTransaction**(`index`?): `AssetFreezeTransaction` + +Defined in: [src/subcontexts/transaction-context.ts:421](https://github.com/algorandfoundation/algorand-typescript-testing/blob/main/src/subcontexts/transaction-context.ts#L421) + +Gets an asset freeze transaction by index. + +#### Parameters + +##### index? + +`StubUint64Compat` + +The index of the transaction. + +#### Returns + +`AssetFreezeTransaction` + +The asset freeze transaction. + +*** + +### getAssetTransferTransaction() + +> **getAssetTransferTransaction**(`index`?): `AssetTransferTransaction` + +Defined in: [src/subcontexts/transaction-context.ts:412](https://github.com/algorandfoundation/algorand-typescript-testing/blob/main/src/subcontexts/transaction-context.ts#L412) + +Gets an asset transfer transaction by index. + +#### Parameters + +##### index? + +`StubUint64Compat` + +The index of the transaction. + +#### Returns + +`AssetTransferTransaction` + +The asset transfer transaction. + +*** + +### getItxnGroup() + +> **getItxnGroup**(`index`?): [`ItxnGroup`](ItxnGroup.md) + +Defined in: [src/subcontexts/transaction-context.ts:376](https://github.com/algorandfoundation/algorand-typescript-testing/blob/main/src/subcontexts/transaction-context.ts#L376) + +Gets an inner transaction group by index. + +#### Parameters + +##### index? + +`StubUint64Compat` + +The index of the group. If not provided, the last group is returned. + +#### Returns + +[`ItxnGroup`](ItxnGroup.md) + +The inner transaction group. + +#### Throws + +If the index is invalid or there are no previous inner transactions. + +*** + +### getKeyRegistrationTransaction() + +> **getKeyRegistrationTransaction**(`index`?): `KeyRegistrationTransaction` + +Defined in: [src/subcontexts/transaction-context.ts:430](https://github.com/algorandfoundation/algorand-typescript-testing/blob/main/src/subcontexts/transaction-context.ts#L430) + +Gets a key registration transaction by index. + +#### Parameters + +##### index? + +`StubUint64Compat` + +The index of the transaction. + +#### Returns + +`KeyRegistrationTransaction` + +The key registration transaction. + +*** + +### getPaymentTransaction() + +> **getPaymentTransaction**(`index`?): `PaymentTransaction` + +Defined in: [src/subcontexts/transaction-context.ts:439](https://github.com/algorandfoundation/algorand-typescript-testing/blob/main/src/subcontexts/transaction-context.ts#L439) + +Gets a payment transaction by index. + +#### Parameters + +##### index? + +`StubUint64Compat` + +The index of the transaction. + +#### Returns + +`PaymentTransaction` + +The payment transaction. + +*** + +### getScratchSlot() + +> **getScratchSlot**(`index`): `bytes` \| `uint64` + +Defined in: [src/subcontexts/transaction-context.ts:293](https://github.com/algorandfoundation/algorand-typescript-testing/blob/main/src/subcontexts/transaction-context.ts#L293) + +Gets the scratch slot of the active transaction. + +#### Parameters + +##### index + +`StubUint64Compat` + +The index of the scratch slot. + +#### Returns + +`bytes` \| `uint64` + +The scratch slot value. + +*** + +### getScratchSpace() + +> **getScratchSpace**(): (`bytes` \| `uint64`)[] + +Defined in: [src/subcontexts/transaction-context.ts:284](https://github.com/algorandfoundation/algorand-typescript-testing/blob/main/src/subcontexts/transaction-context.ts#L284) + +Gets the scratch space of the active transaction. + +#### Returns + +(`bytes` \| `uint64`)[] + +The scratch space. + +*** + +### getTransaction() + +> **getTransaction**(`index`?): `Transaction` + +Defined in: [src/subcontexts/transaction-context.ts:448](https://github.com/algorandfoundation/algorand-typescript-testing/blob/main/src/subcontexts/transaction-context.ts#L448) + +Gets a transaction by index. + +#### Parameters + +##### index? + +`StubUint64Compat` + +The index of the transaction. + +#### Returns + +`Transaction` + +The transaction. + +*** + +### lastItxnGroup() + +> **lastItxnGroup**(): [`ItxnGroup`](ItxnGroup.md) + +Defined in: [src/subcontexts/transaction-context.ts:366](https://github.com/algorandfoundation/algorand-typescript-testing/blob/main/src/subcontexts/transaction-context.ts#L366) + +Gets the last inner transaction group. + +#### Returns + +[`ItxnGroup`](ItxnGroup.md) + +The last inner transaction group. + +*** + +### patchActiveTransactionFields() + +> **patchActiveTransactionFields**(`fields`): `void` + +Defined in: [src/subcontexts/transaction-context.ts:301](https://github.com/algorandfoundation/algorand-typescript-testing/blob/main/src/subcontexts/transaction-context.ts#L301) + +Patches the fields of the active transaction. + +#### Parameters + +##### fields + +`AllTransactionFields` + +The fields to patch. + +#### Returns + +`void` + +*** + +### submitInnerTransactionGroup() + +> **submitInnerTransactionGroup**(): `void` + +Defined in: [src/subcontexts/transaction-context.ts:349](https://github.com/algorandfoundation/algorand-typescript-testing/blob/main/src/subcontexts/transaction-context.ts#L349) + +**`Internal`** + +Submits the current inner transaction group. + +#### Returns + +`void` + +#### Throws + +If there is no inner transaction group being constructed or the group exceeds the maximum size. diff --git a/docs/code/test-transformer/jest-transformer/README.md b/docs/code/test-transformer/jest-transformer/README.md new file mode 100644 index 0000000..13ff78f --- /dev/null +++ b/docs/code/test-transformer/jest-transformer/README.md @@ -0,0 +1,16 @@ +[**@algorandfoundation/algorand-typescript-testing**](../../README.md) + +*** + +[@algorandfoundation/algorand-typescript-testing](../../README.md) / test-transformer/jest-transformer + +# test-transformer/jest-transformer + +## Variables + +- [name](variables/name.md) +- [version](variables/version.md) + +## Functions + +- [factory](functions/factory.md) diff --git a/docs/code/test-transformer/jest-transformer/functions/factory.md b/docs/code/test-transformer/jest-transformer/functions/factory.md new file mode 100644 index 0000000..18e4a98 --- /dev/null +++ b/docs/code/test-transformer/jest-transformer/functions/factory.md @@ -0,0 +1,52 @@ +[**@algorandfoundation/algorand-typescript-testing**](../../../README.md) + +*** + +[@algorandfoundation/algorand-typescript-testing](../../../README.md) / [test-transformer/jest-transformer](../README.md) / factory + +# Function: factory() + +> **factory**(`compilerInstance`): `TransformerFactory`\<`SourceFile`\> + +Defined in: [src/test-transformer/jest-transformer.ts:49](https://github.com/algorandfoundation/algorand-typescript-testing/blob/main/src/test-transformer/jest-transformer.ts#L49) + +Factory function that creates TypeScript program transformers for Jest. +Used by ts-jest to transform TypeScript files during test execution. +Initialized with default transformer configuration. + +## Parameters + +### compilerInstance + +#### program + +`Program` + +## Returns + +`TransformerFactory`\<`SourceFile`\> + +## Example + +```ts +// Use as before stage transformer with custom config in jest.config.ts +import { createDefaultEsmPreset, type JestConfigWithTsJest } from 'ts-jest' + +const presetConfig = createDefaultEsmPreset({}) +const jestConfig: JestConfigWithTsJest = { + ...presetConfig, + transform: { + '^.+\\.tsx?$': [ + 'ts-jest', + { + useESM: true, + astTransformers: { + before: ['node_modules/@algorandfoundation/algorand-typescript-testing/test-transformer/jest-transformer.mjs'], + }, + }, + ], + }, + extensionsToTreatAsEsm: ['.ts'], +} +export default jestConfig +``` diff --git a/docs/code/test-transformer/jest-transformer/variables/name.md b/docs/code/test-transformer/jest-transformer/variables/name.md new file mode 100644 index 0000000..4e5c23f --- /dev/null +++ b/docs/code/test-transformer/jest-transformer/variables/name.md @@ -0,0 +1,11 @@ +[**@algorandfoundation/algorand-typescript-testing**](../../../README.md) + +*** + +[@algorandfoundation/algorand-typescript-testing](../../../README.md) / [test-transformer/jest-transformer](../README.md) / name + +# Variable: name + +> `const` **name**: `"puyaTsTransformer"` = `'puyaTsTransformer'` + +Defined in: [src/test-transformer/jest-transformer.ts:15](https://github.com/algorandfoundation/algorand-typescript-testing/blob/main/src/test-transformer/jest-transformer.ts#L15) diff --git a/docs/code/test-transformer/jest-transformer/variables/version.md b/docs/code/test-transformer/jest-transformer/variables/version.md new file mode 100644 index 0000000..85d81f7 --- /dev/null +++ b/docs/code/test-transformer/jest-transformer/variables/version.md @@ -0,0 +1,11 @@ +[**@algorandfoundation/algorand-typescript-testing**](../../../README.md) + +*** + +[@algorandfoundation/algorand-typescript-testing](../../../README.md) / [test-transformer/jest-transformer](../README.md) / version + +# Variable: version + +> `const` **version**: `"0.1.0"` = `'0.1.0'` + +Defined in: [src/test-transformer/jest-transformer.ts:16](https://github.com/algorandfoundation/algorand-typescript-testing/blob/main/src/test-transformer/jest-transformer.ts#L16) diff --git a/docs/code/test-transformer/vitest-transformer/README.md b/docs/code/test-transformer/vitest-transformer/README.md new file mode 100644 index 0000000..5eb1d1a --- /dev/null +++ b/docs/code/test-transformer/vitest-transformer/README.md @@ -0,0 +1,11 @@ +[**@algorandfoundation/algorand-typescript-testing**](../../README.md) + +*** + +[@algorandfoundation/algorand-typescript-testing](../../README.md) / test-transformer/vitest-transformer + +# test-transformer/vitest-transformer + +## Functions + +- [puyaTsTransformer](functions/puyaTsTransformer.md) diff --git a/docs/code/test-transformer/vitest-transformer/functions/puyaTsTransformer.md b/docs/code/test-transformer/vitest-transformer/functions/puyaTsTransformer.md new file mode 100644 index 0000000..54a6e99 --- /dev/null +++ b/docs/code/test-transformer/vitest-transformer/functions/puyaTsTransformer.md @@ -0,0 +1,78 @@ +[**@algorandfoundation/algorand-typescript-testing**](../../../README.md) + +*** + +[@algorandfoundation/algorand-typescript-testing](../../../README.md) / [test-transformer/vitest-transformer](../README.md) / puyaTsTransformer + +# Function: puyaTsTransformer() + +TypeScript transformer for Algorand TypeScript smart contracts and testing files +which is mainly responsilbe for swapping in stub implementations of op codes, +and capturing TypeScript type information for the Node.js runtime. + +* + +## Param + +Configuration options + +## Param + +File extensions to process + +## Param + +Package name for testing imports + +## Example + +```ts +// Use as before stage transformer with custom config in vitest.config.mts +import typescript from '@rollup/plugin-typescript' +import { defineConfig } from 'vitest/config' +import { puyaTsTransformer } from '@algorandfoundation/algorand-typescript-testing/vitest-transformer' + +export default defineConfig({ + esbuild: {}, + plugins: [ + typescript({ + tsconfig: './tsconfig.json', + transformers: { + before: [puyaTsTransformer], + }, + }), + ], +}) +``` + +## Call Signature + +> **puyaTsTransformer**(`context`): `Transformer`\<`SourceFile`\> + +Defined in: [src/test-transformer/vitest-transformer.ts:54](https://github.com/algorandfoundation/algorand-typescript-testing/blob/main/src/test-transformer/vitest-transformer.ts#L54) + +### Parameters + +#### context + +`TransformationContext` + +### Returns + +`Transformer`\<`SourceFile`\> + +## Call Signature + +> **puyaTsTransformer**(`config`): `TransformerFactory`\<`SourceFile`\> + +Defined in: [src/test-transformer/vitest-transformer.ts:55](https://github.com/algorandfoundation/algorand-typescript-testing/blob/main/src/test-transformer/vitest-transformer.ts#L55) + +### Parameters + +#### config + +`Partial`\<`TransformerConfig`\> + +### Returns + +`TransformerFactory`\<`SourceFile`\> diff --git a/docs/code/value-generators/README.md b/docs/code/value-generators/README.md new file mode 100644 index 0000000..5e7671a --- /dev/null +++ b/docs/code/value-generators/README.md @@ -0,0 +1,11 @@ +[**@algorandfoundation/algorand-typescript-testing**](../README.md) + +*** + +[@algorandfoundation/algorand-typescript-testing](../README.md) / value-generators + +# value-generators + +## Classes + +- [ValueGenerator](classes/ValueGenerator.md) diff --git a/docs/code/value-generators/arc4/README.md b/docs/code/value-generators/arc4/README.md new file mode 100644 index 0000000..6ef802d --- /dev/null +++ b/docs/code/value-generators/arc4/README.md @@ -0,0 +1,11 @@ +[**@algorandfoundation/algorand-typescript-testing**](../../README.md) + +*** + +[@algorandfoundation/algorand-typescript-testing](../../README.md) / value-generators/arc4 + +# value-generators/arc4 + +## Classes + +- [Arc4ValueGenerator](classes/Arc4ValueGenerator.md) diff --git a/docs/code/value-generators/arc4/classes/Arc4ValueGenerator.md b/docs/code/value-generators/arc4/classes/Arc4ValueGenerator.md new file mode 100644 index 0000000..49aeebc --- /dev/null +++ b/docs/code/value-generators/arc4/classes/Arc4ValueGenerator.md @@ -0,0 +1,242 @@ +[**@algorandfoundation/algorand-typescript-testing**](../../../README.md) + +*** + +[@algorandfoundation/algorand-typescript-testing](../../../README.md) / [value-generators/arc4](../README.md) / Arc4ValueGenerator + +# Class: Arc4ValueGenerator + +Defined in: [src/value-generators/arc4.ts:7](https://github.com/algorandfoundation/algorand-typescript-testing/blob/main/src/value-generators/arc4.ts#L7) + +## Constructors + +### new Arc4ValueGenerator() + +> **new Arc4ValueGenerator**(): [`Arc4ValueGenerator`](Arc4ValueGenerator.md) + +#### Returns + +[`Arc4ValueGenerator`](Arc4ValueGenerator.md) + +## Methods + +### address() + +> **address**(): `Address` + +Defined in: [src/value-generators/arc4.ts:12](https://github.com/algorandfoundation/algorand-typescript-testing/blob/main/src/value-generators/arc4.ts#L12) + +Generate a random Algorand address. +@returns: A new, random Algorand address. + +#### Returns + +`Address` + +*** + +### dynamicBytes() + +> **dynamicBytes**(`n`): `DynamicBytes` + +Defined in: [src/value-generators/arc4.ts:97](https://github.com/algorandfoundation/algorand-typescript-testing/blob/main/src/value-generators/arc4.ts#L97) + +Generate a random dynamic bytes of size `n` bits. + +#### Parameters + +##### n + +`number` + +#### Returns + +`DynamicBytes` + +*** + +### str() + +> **str**(`n`): `Str` + +Defined in: [src/value-generators/arc4.ts:109](https://github.com/algorandfoundation/algorand-typescript-testing/blob/main/src/value-generators/arc4.ts#L109) + +Generate a random dynamic string of size `n` bits. + +#### Parameters + +##### n + +`number` + +#### Returns + +`Str` + +*** + +### uintN128() + +> **uintN128**(`minValue`, `maxValue`): `UintN128` + +Defined in: [src/value-generators/arc4.ts:67](https://github.com/algorandfoundation/algorand-typescript-testing/blob/main/src/value-generators/arc4.ts#L67) + +Generate a random UintN128 within the specified range. + +#### Parameters + +##### minValue + +`number` | `bigint` + +##### maxValue + +`number` | `bigint` + +#### Returns + +`UintN128` + +*** + +### uintN16() + +> **uintN16**(`minValue`, `maxValue`): `UintN16` + +Defined in: [src/value-generators/arc4.ts:37](https://github.com/algorandfoundation/algorand-typescript-testing/blob/main/src/value-generators/arc4.ts#L37) + +Generate a random UintN16 within the specified range. + +#### Parameters + +##### minValue + +`number` | `bigint` + +##### maxValue + +`number` | `bigint` + +#### Returns + +`UintN16` + +*** + +### uintN256() + +> **uintN256**(`minValue`, `maxValue`): `UintN256` + +Defined in: [src/value-generators/arc4.ts:77](https://github.com/algorandfoundation/algorand-typescript-testing/blob/main/src/value-generators/arc4.ts#L77) + +Generate a random UintN256 within the specified range. + +#### Parameters + +##### minValue + +`number` | `bigint` + +##### maxValue + +`number` | `bigint` + +#### Returns + +`UintN256` + +*** + +### uintN32() + +> **uintN32**(`minValue`, `maxValue`): `UintN32` + +Defined in: [src/value-generators/arc4.ts:47](https://github.com/algorandfoundation/algorand-typescript-testing/blob/main/src/value-generators/arc4.ts#L47) + +Generate a random UintN32 within the specified range. + +#### Parameters + +##### minValue + +`number` | `bigint` + +##### maxValue + +`number` | `bigint` + +#### Returns + +`UintN32` + +*** + +### uintN512() + +> **uintN512**(`minValue`, `maxValue`): `UintN`\<`512`\> + +Defined in: [src/value-generators/arc4.ts:87](https://github.com/algorandfoundation/algorand-typescript-testing/blob/main/src/value-generators/arc4.ts#L87) + +Generate a random UintN512 within the specified range. + +#### Parameters + +##### minValue + +`number` | `bigint` + +##### maxValue + +`number` | `bigint` + +#### Returns + +`UintN`\<`512`\> + +*** + +### uintN64() + +> **uintN64**(`minValue`, `maxValue`): `UintN64` + +Defined in: [src/value-generators/arc4.ts:57](https://github.com/algorandfoundation/algorand-typescript-testing/blob/main/src/value-generators/arc4.ts#L57) + +Generate a random UintN64 within the specified range. + +#### Parameters + +##### minValue + +`number` | `bigint` + +##### maxValue + +`number` | `bigint` + +#### Returns + +`UintN64` + +*** + +### uintN8() + +> **uintN8**(`minValue`, `maxValue`): `UintN8` + +Defined in: [src/value-generators/arc4.ts:27](https://github.com/algorandfoundation/algorand-typescript-testing/blob/main/src/value-generators/arc4.ts#L27) + +Generate a random UintN8 within the specified range. + +#### Parameters + +##### minValue + +`number` | `bigint` + +##### maxValue + +`number` | `bigint` + +#### Returns + +`UintN8` diff --git a/docs/code/value-generators/avm/README.md b/docs/code/value-generators/avm/README.md new file mode 100644 index 0000000..b528e26 --- /dev/null +++ b/docs/code/value-generators/avm/README.md @@ -0,0 +1,11 @@ +[**@algorandfoundation/algorand-typescript-testing**](../../README.md) + +*** + +[@algorandfoundation/algorand-typescript-testing](../../README.md) / value-generators/avm + +# value-generators/avm + +## Classes + +- [AvmValueGenerator](classes/AvmValueGenerator.md) diff --git a/docs/code/value-generators/avm/classes/AvmValueGenerator.md b/docs/code/value-generators/avm/classes/AvmValueGenerator.md new file mode 100644 index 0000000..77156d7 --- /dev/null +++ b/docs/code/value-generators/avm/classes/AvmValueGenerator.md @@ -0,0 +1,197 @@ +[**@algorandfoundation/algorand-typescript-testing**](../../../README.md) + +*** + +[@algorandfoundation/algorand-typescript-testing](../../../README.md) / [value-generators/avm](../README.md) / AvmValueGenerator + +# Class: AvmValueGenerator + +Defined in: [src/value-generators/avm.ts:31](https://github.com/algorandfoundation/algorand-typescript-testing/blob/main/src/value-generators/avm.ts#L31) + +## Extended by + +- [`ValueGenerator`](../../classes/ValueGenerator.md) + +## Constructors + +### new AvmValueGenerator() + +> **new AvmValueGenerator**(): [`AvmValueGenerator`](AvmValueGenerator.md) + +#### Returns + +[`AvmValueGenerator`](AvmValueGenerator.md) + +## Methods + +### account() + +> **account**(`input`?): `Account` + +Defined in: [src/value-generators/avm.ts:95](https://github.com/algorandfoundation/algorand-typescript-testing/blob/main/src/value-generators/avm.ts#L95) + +Generates a random account with the specified context data. + +#### Parameters + +##### input? + +`AccountContextData` + +The context data for the account. + +#### Returns + +`Account` + +- A random account. + +*** + +### application() + +> **application**(`input`?): `Application` + +Defined in: [src/value-generators/avm.ts:153](https://github.com/algorandfoundation/algorand-typescript-testing/blob/main/src/value-generators/avm.ts#L153) + +Generates a random application with the specified context data. + +#### Parameters + +##### input? + +`ApplicationContextData` + +The context data for the application. + +#### Returns + +`Application` + +- A random application. + +*** + +### asset() + +> **asset**(`input`?): `Asset` + +Defined in: [src/value-generators/avm.ts:133](https://github.com/algorandfoundation/algorand-typescript-testing/blob/main/src/value-generators/avm.ts#L133) + +Generates a random asset with the specified context data. + +#### Parameters + +##### input? + +`AssetContextData` + +The context data for the asset. + +#### Returns + +`Asset` + +- A random asset. + +*** + +### biguint() + +> **biguint**(`minValue`?): `biguint` + +Defined in: [src/value-generators/avm.ts:58](https://github.com/algorandfoundation/algorand-typescript-testing/blob/main/src/value-generators/avm.ts#L58) + +Generates a random biguint value within the specified range. + +#### Parameters + +##### minValue? + +`StubBigUintCompat` = `0n` + +The minimum value (inclusive). + +#### Returns + +`biguint` + +- A random biguint value. + +*** + +### bytes() + +> **bytes**(`length`?): `bytes` + +Defined in: [src/value-generators/avm.ts:72](https://github.com/algorandfoundation/algorand-typescript-testing/blob/main/src/value-generators/avm.ts#L72) + +Generates a random bytes of the specified length. + +#### Parameters + +##### length? + +`number` = `MAX_BYTES_SIZE` + +The length of the bytes. + +#### Returns + +`bytes` + +- A random bytes. + +*** + +### string() + +> **string**(`length`?): `string` + +Defined in: [src/value-generators/avm.ts:81](https://github.com/algorandfoundation/algorand-typescript-testing/blob/main/src/value-generators/avm.ts#L81) + +Generates a random string of the specified length. + +#### Parameters + +##### length? + +`number` = `11` + +The length of the string. + +#### Returns + +`string` + +- A random string. + +*** + +### uint64() + +> **uint64**(`minValue`?, `maxValue`?): `uint64` + +Defined in: [src/value-generators/avm.ts:38](https://github.com/algorandfoundation/algorand-typescript-testing/blob/main/src/value-generators/avm.ts#L38) + +Generates a random uint64 value within the specified range. + +#### Parameters + +##### minValue? + +`StubUint64Compat` = `0n` + +The minimum value (inclusive). + +##### maxValue? + +`StubUint64Compat` = `MAX_UINT64` + +The maximum value (inclusive). + +#### Returns + +`uint64` + +- A random uint64 value. diff --git a/docs/code/value-generators/classes/ValueGenerator.md b/docs/code/value-generators/classes/ValueGenerator.md new file mode 100644 index 0000000..e7e1940 --- /dev/null +++ b/docs/code/value-generators/classes/ValueGenerator.md @@ -0,0 +1,247 @@ +[**@algorandfoundation/algorand-typescript-testing**](../../README.md) + +*** + +[@algorandfoundation/algorand-typescript-testing](../../README.md) / [value-generators](../README.md) / ValueGenerator + +# Class: ValueGenerator + +Defined in: [src/value-generators/index.ts:5](https://github.com/algorandfoundation/algorand-typescript-testing/blob/main/src/value-generators/index.ts#L5) + +## Extends + +- [`AvmValueGenerator`](../avm/classes/AvmValueGenerator.md) + +## Constructors + +### new ValueGenerator() + +> **new ValueGenerator**(): [`ValueGenerator`](ValueGenerator.md) + +Defined in: [src/value-generators/index.ts:9](https://github.com/algorandfoundation/algorand-typescript-testing/blob/main/src/value-generators/index.ts#L9) + +#### Returns + +[`ValueGenerator`](ValueGenerator.md) + +#### Overrides + +[`AvmValueGenerator`](../avm/classes/AvmValueGenerator.md).[`constructor`](../avm/classes/AvmValueGenerator.md#constructors) + +## Properties + +### arc4 + +> **arc4**: [`Arc4ValueGenerator`](../arc4/classes/Arc4ValueGenerator.md) + +Defined in: [src/value-generators/index.ts:7](https://github.com/algorandfoundation/algorand-typescript-testing/blob/main/src/value-generators/index.ts#L7) + +*** + +### txn + +> **txn**: [`TxnValueGenerator`](../txn/classes/TxnValueGenerator.md) + +Defined in: [src/value-generators/index.ts:6](https://github.com/algorandfoundation/algorand-typescript-testing/blob/main/src/value-generators/index.ts#L6) + +## Methods + +### account() + +> **account**(`input`?): `Account` + +Defined in: [src/value-generators/avm.ts:95](https://github.com/algorandfoundation/algorand-typescript-testing/blob/main/src/value-generators/avm.ts#L95) + +Generates a random account with the specified context data. + +#### Parameters + +##### input? + +`AccountContextData` + +The context data for the account. + +#### Returns + +`Account` + +- A random account. + +#### Inherited from + +[`AvmValueGenerator`](../avm/classes/AvmValueGenerator.md).[`account`](../avm/classes/AvmValueGenerator.md#account) + +*** + +### application() + +> **application**(`input`?): `Application` + +Defined in: [src/value-generators/avm.ts:153](https://github.com/algorandfoundation/algorand-typescript-testing/blob/main/src/value-generators/avm.ts#L153) + +Generates a random application with the specified context data. + +#### Parameters + +##### input? + +`ApplicationContextData` + +The context data for the application. + +#### Returns + +`Application` + +- A random application. + +#### Inherited from + +[`AvmValueGenerator`](../avm/classes/AvmValueGenerator.md).[`application`](../avm/classes/AvmValueGenerator.md#application) + +*** + +### asset() + +> **asset**(`input`?): `Asset` + +Defined in: [src/value-generators/avm.ts:133](https://github.com/algorandfoundation/algorand-typescript-testing/blob/main/src/value-generators/avm.ts#L133) + +Generates a random asset with the specified context data. + +#### Parameters + +##### input? + +`AssetContextData` + +The context data for the asset. + +#### Returns + +`Asset` + +- A random asset. + +#### Inherited from + +[`AvmValueGenerator`](../avm/classes/AvmValueGenerator.md).[`asset`](../avm/classes/AvmValueGenerator.md#asset) + +*** + +### biguint() + +> **biguint**(`minValue`?): `biguint` + +Defined in: [src/value-generators/avm.ts:58](https://github.com/algorandfoundation/algorand-typescript-testing/blob/main/src/value-generators/avm.ts#L58) + +Generates a random biguint value within the specified range. + +#### Parameters + +##### minValue? + +`StubBigUintCompat` = `0n` + +The minimum value (inclusive). + +#### Returns + +`biguint` + +- A random biguint value. + +#### Inherited from + +[`AvmValueGenerator`](../avm/classes/AvmValueGenerator.md).[`biguint`](../avm/classes/AvmValueGenerator.md#biguint) + +*** + +### bytes() + +> **bytes**(`length`?): `bytes` + +Defined in: [src/value-generators/avm.ts:72](https://github.com/algorandfoundation/algorand-typescript-testing/blob/main/src/value-generators/avm.ts#L72) + +Generates a random bytes of the specified length. + +#### Parameters + +##### length? + +`number` = `MAX_BYTES_SIZE` + +The length of the bytes. + +#### Returns + +`bytes` + +- A random bytes. + +#### Inherited from + +[`AvmValueGenerator`](../avm/classes/AvmValueGenerator.md).[`bytes`](../avm/classes/AvmValueGenerator.md#bytes) + +*** + +### string() + +> **string**(`length`?): `string` + +Defined in: [src/value-generators/avm.ts:81](https://github.com/algorandfoundation/algorand-typescript-testing/blob/main/src/value-generators/avm.ts#L81) + +Generates a random string of the specified length. + +#### Parameters + +##### length? + +`number` = `11` + +The length of the string. + +#### Returns + +`string` + +- A random string. + +#### Inherited from + +[`AvmValueGenerator`](../avm/classes/AvmValueGenerator.md).[`string`](../avm/classes/AvmValueGenerator.md#string) + +*** + +### uint64() + +> **uint64**(`minValue`?, `maxValue`?): `uint64` + +Defined in: [src/value-generators/avm.ts:38](https://github.com/algorandfoundation/algorand-typescript-testing/blob/main/src/value-generators/avm.ts#L38) + +Generates a random uint64 value within the specified range. + +#### Parameters + +##### minValue? + +`StubUint64Compat` = `0n` + +The minimum value (inclusive). + +##### maxValue? + +`StubUint64Compat` = `MAX_UINT64` + +The maximum value (inclusive). + +#### Returns + +`uint64` + +- A random uint64 value. + +#### Inherited from + +[`AvmValueGenerator`](../avm/classes/AvmValueGenerator.md).[`uint64`](../avm/classes/AvmValueGenerator.md#uint64) diff --git a/docs/code/value-generators/txn/README.md b/docs/code/value-generators/txn/README.md new file mode 100644 index 0000000..bf67a30 --- /dev/null +++ b/docs/code/value-generators/txn/README.md @@ -0,0 +1,11 @@ +[**@algorandfoundation/algorand-typescript-testing**](../../README.md) + +*** + +[@algorandfoundation/algorand-typescript-testing](../../README.md) / value-generators/txn + +# value-generators/txn + +## Classes + +- [TxnValueGenerator](classes/TxnValueGenerator.md) diff --git a/docs/code/value-generators/txn/classes/TxnValueGenerator.md b/docs/code/value-generators/txn/classes/TxnValueGenerator.md new file mode 100644 index 0000000..5a44aca --- /dev/null +++ b/docs/code/value-generators/txn/classes/TxnValueGenerator.md @@ -0,0 +1,163 @@ +[**@algorandfoundation/algorand-typescript-testing**](../../../README.md) + +*** + +[@algorandfoundation/algorand-typescript-testing](../../../README.md) / [value-generators/txn](../README.md) / TxnValueGenerator + +# Class: TxnValueGenerator + +Defined in: [src/value-generators/txn.ts:16](https://github.com/algorandfoundation/algorand-typescript-testing/blob/main/src/value-generators/txn.ts#L16) + +## Constructors + +### new TxnValueGenerator() + +> **new TxnValueGenerator**(): [`TxnValueGenerator`](TxnValueGenerator.md) + +#### Returns + +[`TxnValueGenerator`](TxnValueGenerator.md) + +## Methods + +### applicationCall() + +> **applicationCall**(`fields`?): `ApplicationTransaction` + +Defined in: [src/value-generators/txn.ts:22](https://github.com/algorandfoundation/algorand-typescript-testing/blob/main/src/value-generators/txn.ts#L22) + +Generates a random application call transaction with the specified fields. + +#### Parameters + +##### fields? + +`Partial`\<`Omit`\<`ApplicationTransactionFields`, `"appId"`\> & `object`\> + +The fields for the application call transaction where `appId` value can be instance of Application or BaseContract. + +#### Returns + +`ApplicationTransaction` + +- A random application call transaction. + +*** + +### assetConfig() + +> **assetConfig**(`fields`?): `AssetConfigTransaction` + +Defined in: [src/value-generators/txn.ts:65](https://github.com/algorandfoundation/algorand-typescript-testing/blob/main/src/value-generators/txn.ts#L65) + +Generates a random asset configuration transaction with the specified fields. + +#### Parameters + +##### fields? + +`Partial`\<`Mutable`\<`Pick`\<`AssetConfigTxn`, keyof `AssetConfigTxn`\>\>\> + +The fields for the asset configuration transaction. + +#### Returns + +`AssetConfigTransaction` + +- A random asset configuration transaction. + +*** + +### assetFreeze() + +> **assetFreeze**(`fields`?): `AssetFreezeTransaction` + +Defined in: [src/value-generators/txn.ts:83](https://github.com/algorandfoundation/algorand-typescript-testing/blob/main/src/value-generators/txn.ts#L83) + +Generates a random asset freeze transaction with the specified fields. + +#### Parameters + +##### fields? + +`Partial`\<`Mutable`\<`Pick`\<`AssetFreezeTxn`, keyof `AssetFreezeTxn`\>\>\> + +The fields for the asset freeze transaction. + +#### Returns + +`AssetFreezeTransaction` + +- A random asset freeze transaction. + +*** + +### assetTransfer() + +> **assetTransfer**(`fields`?): `AssetTransferTransaction` + +Defined in: [src/value-generators/txn.ts:74](https://github.com/algorandfoundation/algorand-typescript-testing/blob/main/src/value-generators/txn.ts#L74) + +Generates a random asset transfer transaction with the specified fields. + +#### Parameters + +##### fields? + +`Partial`\<`Mutable`\<`Pick`\<`AssetTransferTxn`, keyof `AssetTransferTxn`\>\>\> + +The fields for the asset transfer transaction. + +#### Returns + +`AssetTransferTransaction` + +- A random asset transfer transaction. + +*** + +### keyRegistration() + +> **keyRegistration**(`fields`?): `KeyRegistrationTransaction` + +Defined in: [src/value-generators/txn.ts:56](https://github.com/algorandfoundation/algorand-typescript-testing/blob/main/src/value-generators/txn.ts#L56) + +Generates a random key registration transaction with the specified fields. + +#### Parameters + +##### fields? + +`Partial`\<`Mutable`\<`Pick`\<`KeyRegistrationTxn`, keyof `KeyRegistrationTxn`\>\>\> + +The fields for the key registration transaction. + +#### Returns + +`KeyRegistrationTransaction` + +- A random key registration transaction. + +*** + +### payment() + +> **payment**(`fields`?): `PaymentTransaction` + +Defined in: [src/value-generators/txn.ts:47](https://github.com/algorandfoundation/algorand-typescript-testing/blob/main/src/value-generators/txn.ts#L47) + +Generates a random payment transaction with the specified fields. + +#### Parameters + +##### fields? + +`Partial`\<`Mutable`\<`Pick`\<`PaymentTxn`, keyof `PaymentTxn`\>\>\> + +The fields for the payment transaction. + +#### Returns + +`PaymentTransaction` + +- A random payment transaction. diff --git a/docs/coverage.md b/docs/coverage.md new file mode 100644 index 0000000..165c9b0 --- /dev/null +++ b/docs/coverage.md @@ -0,0 +1,138 @@ +# Coverage + +See which `algorand-typescript` stubs are implemented by the `algorand-typescript-testing` library. See the [Concepts](testing-guide/concepts.md#types-of-algorand-typescript-stub-implementations) section for more details on the implementation categories. Refer to the [`algorand-typescript` stubs API](api.md) for the full list of the stubs for which the `algorand-typescript-testing` library provides implementations referenced in the table below. + +| Name | Implementation type | +| ----------------------- | ------------------- | +| Account | Emulated | +| Application | Emulated | +| Asset | Emulated | +| BaseContract | Emulated | +| BigUint | Native | +| Box | Emulated | +| BoxMap | Emulated | +| BoxRef | Emulated | +| Bytes | Native | +| CompiledContract | Mockable | +| CompiledLogicSig | Mockable | +| Global | Emulated | +| GlobalState | Emulated | +| LocalState | Emulated | +| OnCompleteAction | Native | +| OpUpFeeSource | Native | +| StateTotals | Emulated | +| TemplateVar | Emulated | +| TransactionType | Native | +| Txn | Emulated | +| Uint64 | Native | +| compile | Mockable | +| emit | Emulated | +| ensureBudget | Emulated | +| err | Native | +| log | Emulated | +| logicSig | Emulated | +| logicsig | Emulated | +| string | Native | +| urange | Native | +| arc4.Address | Native | +| arc4.Bool | Native | +| arc4.Byte | Native | +| arc4.Contract | Emulated | +| arc4.DynamicArray | Native | +| arc4.DynamicBytes | Native | +| arc4.StaticArray | Native | +| arc4.StaticBytes | Native | +| arc4.Str | Native | +| arc4.Struct | Native | +| arc4.Tuple | Native | +| arc4.UFixedNxM | Native | +| arc4.UintN | Native | +| arc4.UintN128 | Native | +| arc4.UintN16 | Native | +| arc4.UintN256 | Native | +| arc4.UintN32 | Native | +| arc4.UintN64 | Native | +| arc4.UintN8 | Native | +| arc4.UIntN | Native | +| arc4.abimethod | Emulated | +| arc4.methodSelector | Native | +| arc4.baremethod | Emulated | +| gtxn.ApplicationTxn | Emulated | +| gtxn.AssetConfigTxn | Emulated | +| gtxn.AssetFreezeTxn | Emulated | +| gtxn.AssetTransferTxn | Emulated | +| gtxn.KeyRegistrationTxn | Emulated | +| gtxn.PaymentTxn | Emulated | +| gtxn.Transaction | Emulated | +| itxn.applicationCall | Emulated | +| itxn.assetConfig | Emulated | +| itxn.assetFreeze | Emulated | +| itxn.assetTransfer | Emulated | +| itxn.keyRegistration | Emulated | +| itxn.payment | Emulated | +| itxn.submitGroup | Emulated | +| op.AcctParams | Emulated | +| op.AppGlobal | Emulated | +| op.AppLocal | Emulated | +| op.AppParams | Emulated | +| op.AssetHolding | Emulated | +| op.AssetParams | Emulated | +| op.Block | Emulated | +| op.Box | Emulated | +| op.EllipticCurve | Mockable | +| op.GITxn | Emulated | +| op.GTxn | Emulated | +| op.Global | Emulated | +| op.ITxn | Emulated | +| op.ITxnCreate | Emulated | +| op.JsonRef | Mockable | +| op.Scratch | Emulated | +| op.Txn | Emulated | +| op.VoterParams | Emulated | +| op.addw | Native | +| op.appOptedIn | Emulated | +| op.arg | Emulated | +| op.balance | Emulated | +| op.base64Decode | Native | +| op.bitLength | Native | +| op.bsqrt | Native | +| op.btoi | Native | +| op.bzero | Native | +| op.concat | Native | +| op.divmodw | Native | +| op.divw | Native | +| op.ecdsaPkDecompress | Native | +| op.ecdsaPkRecover | Native | +| op.ecdsaVerify | Native | +| op.ed25519verify | Native | +| op.ed25519verifyBare | Native | +| op.exp | Native | +| op.expw | Native | +| op.extract | Native | +| op.extractUint16 | Native | +| op.extractUint32 | Native | +| op.extractUint64 | Native | +| op.gaid | Emulated | +| op.getBit | Native | +| op.getByte | Native | +| op.gloadBytes | Emulated | +| op.gloadUint64 | Emulated | +| op.itob | Native | +| op.keccak256 | Native | +| op.len | Native | +| op.mimc | Mockable | +| op.minBalance | Emulated | +| op.mulw | Native | +| op.onlineStake | Mockable | +| op.replace | Native | +| op.select | Native | +| op.setBit | Native | +| op.setByte | Native | +| op.sha256 | Native | +| op.sha3_256 | Native | +| op.sha512_256 | Native | +| op.shl | Native | +| op.shr | Native | +| op.sqrt | Native | +| op.substring | Native | +| op.vrfVerify | Mockable | diff --git a/docs/examples.md b/docs/examples.md new file mode 100644 index 0000000..84bbe69 --- /dev/null +++ b/docs/examples.md @@ -0,0 +1,13 @@ +# Examples + +Below is a showcase of various examples of unit testing real and sample Algorand Python smart contracts using `algorand-typescript-testing`. + +| Contract Name | Test File | Key Features Demonstrated | Test versions of Algorand TypeScript Abstractions used | +| ------------------- | --------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------- | +| Auction | [contract.algo.ts](https://github.com/algorandfoundation/algorand-typescript-testing/blob/main/examples/auction/contract.algo.ts) | - Use of TestExecutionContext
- Mocking of global state and transaction fields
- Testing of ARC4 contract methods
- Emulation of asset creation and transfers
- Verification of inner transactions | - **arc4.Contract**
- **Global**
- **Txn**
- **Asset**
- **Account**
- **LocalState** | +| Proof of Attendance | [contract.algo.ts](https://github.com/algorandfoundation/algorand-typescript-testing/blob/main/examples/proof-of-attendance/contract.algo.ts) | - Creation and management of dummy assets
- Testing of box storage operations
- Verification of inner transactions for asset transfers
- Use of any\_\* methods for generating test data | - **arc4.Contract**
- **Box**
- **BoxMap**
- **Asset**
- **Account**
- **op** | +| Simple Voting | [contract.algo.ts](https://github.com/algorandfoundation/algorand-typescript-testing/blob/main/examples/simple-voting/contract.algo.ts) | - Testing of global and local state operations
- Verification of transaction group operations
- Mocking of payment transactions | - **BaseContract**
- **GlobalState**
- **LocalState**
- **Txn**
- **op.GTxn** | +| ZK Whitelist | [contract.algo.ts](https://github.com/algorandfoundation/algorand-typescript-testing/blob/main/examples/zk-whitelist/contract.algo.ts) | - Testing of zero-knowledge proof verification
- Mocking of external application calls
- Use of ARC4 types and methods | - **arc4.Contract**
- **arc4 types**
- **LocalState**
- **Global**
- **Txn** | +| HTLC LogicSig | [signature.algo.ts](https://github.com/algorandfoundation/algorand-typescript-testing/blob/main/examples/htlc-logicsig/signature.algo.ts) | - Testing of LogicSig contracts
- Verification of time-based conditions
- Mocking of transaction parameters | - **logicsig**
- **Account**
- **Txn**
- **Global**
- **op** | +| Marketplace | [contract.algo.ts](https://github.com/algorandfoundation/algorand-typescript-testing/blob/main/examples/marketplace/contract.algo.ts) | - Testing of complex marketplace operations
- Use of BoxMap for listings
- Testing of asset transfers and payments | - **arc4.Contract**
- **BoxMap**
- **Asset**
- **arc4 types**
- **Global**
- **Txn** | +| Scratch Storage | [contract.algo.ts](https://github.com/algorandfoundation/algorand-typescript-testing/blob/main/examples/scratch-storage/contract.algo.ts) | - Testing of scratch space usage
- Verification of scratch slot values | - **arc4.Contract**
- **Contract**
- **op** | diff --git a/docs/faq.md b/docs/faq.md new file mode 100644 index 0000000..f93119a --- /dev/null +++ b/docs/faq.md @@ -0,0 +1,61 @@ +# FAQ + +## What is a Test Context? + +A Test Context is a context manager that provides a simulated Algorand environment for testing TypeScript smart contracts. It allows developers to create and manipulate a virtual Algorand ecosystem for testing purposes. For more details, see the [Test Context section](testing-guide/concepts.md#test-context) in our documentation. + +## What is the Algorand Virtual Machine (AVM)? + +The Algorand Virtual Machine (AVM) is the runtime environment for Algorand smart contracts. It executes the compiled code of smart contracts on the Algorand blockchain. To learn more about the AVM, visit the [official Algorand documentation](https://developer.algorand.org/docs/get-details/dapps/avm/). + +## What are Operational Codes in Algorand? + +Operational Codes, or opcodes, are AVM instructions that are executed directly by the AVM. In the context of Algorand TypeScript testing, these opcodes are provided by `algorand-typescript-testing` stubs and are either emulated, implemented, or mocked by `algorand-typescript-testing`. For a comprehensive list of opcodes, refer to the [Algorand Developer Documentation](https://developer.algorand.org/docs/get-details/dapps/avm/teal/opcodes/?from_query=OPcodes#template-modal-overlay). + +## What are Value Generators? + +Value Generators are helper methods that generate randomized values for testing when the specific value of the tested type is not important. In the context of Algorand TypeScript testing, these are represented by property on the context manager, accessed via `any.*` (`any.txn.*`, or `any.arc4.*`. in the case of ARC 4 types). To understand how to use Value Generators effectively, check out our [Value Generators section](testing-guide/concepts.md#value-generators) in the documentation. + +## What are the limitations of the Algorand TypeScript Testing framework? + +The Algorand TypeScript Testing framework emulates the Algorand Virtual Machine (AVM) for unit testing Algorand TypeScript smart contracts without interacting with the real Algorand Network. However, it has some limitations due to its scope and purpose: + +1. Simplified balance tracking and transaction validation +2. No consensus mechanism or AVM network operations simulation +3. Absence of a strict opcode budget system +4. Certain cryptographic operations are mocked or simplified +5. No state proof generation or verification + +For scenarios where these limitations are crucial, it's recommended to pair this framework with integration testing. If you have a solid reason to justify introducing new emulated behaviour, please open an issue or contribute to the project on [Github](https://github.com/algorandfoundation/algorand-typescript-testing). + +## How does balance tracking work in the testing framework? + +The framework uses simplified balance tracking and transaction validation. For scenarios where precise balance or fee verification is important, it's recommended to complement unit tests with integration testing. + +## Does the framework simulate the entire AVM network? + +No, the framework does not simulate the entire AVM network or consensus mechanism. It focuses on emulating the parts of the AVM relevant to unit testing smart contracts. + +## How does the framework handle opcode budgets? + +The framework does not implement a strict opcode budget system. For scenarios where validating opcode budget is crucial, it's recommended to use integration testing alongside this framework. + +## Are all cryptographic operations fully implemented? + +Some cryptographic operations are mocked or simplified in the framework. For a detailed list of which operations are mocked, refer to the _mockable_ types under the [coverage](./coverage.md) section. + +## Can I use this framework for security-critical validations? + +While this framework is useful for unit testing and local development, it should not be the only tool used for security-critical validations or performance benchmarking. It's designed to approximate AVM behavior for common scenarios. Always complement your testing with additional integration testing options available in `algokit`, where you can test against real localnet or testnet environments. + +## Is there an example of how to use this framework alongside integration tests? + +Yes, the `algokit-typescript-template`, accessible via `algokit init`, provides a working example of how to structure `algorand-typecript-testing` along with regular integration tests against localnet. + +```{hint} +An `algokit-typescript-template` accessible via `algokit init -t typescript`, provides a comprehensive and customizable working example of how to structure `algorand-typescript-testing` along with regular integration tests against localnet. +``` + +## Is it compatible with `vitest`? + +Yes, it is compatible with `vitest` and _any_ other TypeScript testing framework as its agnostic of the testing framework as long as it's TypeScript. If you spot incompatibility with a certain tool, please open an issue or contribute to the project on [Github](https://github.com/algorandfoundation/algorand-typescript-testing). diff --git a/docs/testing-guide/arc4-types.md b/docs/testing-guide/arc4-types.md new file mode 100644 index 0000000..badddb8 --- /dev/null +++ b/docs/testing-guide/arc4-types.md @@ -0,0 +1,85 @@ +# ARC4 Types + +These types are available under the `arc4` namespace. Refer to the [ARC4 specification](https://arc.algorand.foundation/ARCs/arc-0004) for more details on the spec. + +```{hint} +Test execution context provides _value generators_ for ARC4 types. To access their _value generators_, use `{context_instance}.any.arc4` property. See more examples below. +``` + +```{note} +For all `arc4` types with and without respective _value generator_, instantiation can be performed directly. If you have a suggestion for a new _value generator_ implementation, please open an issue in the [`algorand-typescript-testing`](https://github.com/algorandfoundation/algorand-typescript-testing) repository or contribute by following the [contribution guide](https://github.com/algorandfoundation/algorand-typescript-testing/blob/main/CONTRIBUTING.md). +``` + +```ts +import { arc4 } from '@algorandfoundation/algorand-typescript' +import { TestExecutionContext } from '@algorandfoundation/algorand-typescript-testing' + +// Create the context manager for snippets below +const ctx = new TestExecutionContext() +``` + +## Unsigned Integers + +```ts +// Integer types +const uint8Value = new arc4.UintN8(255) +const uint16Value = new arc4.UintN16(65535) +const uint32Value = new arc4.UintN32(4294967295) +const uint64Value = new arc4.UintN64(18446744073709551615n) + +// Generate a random unsigned arc4 integer with default range +const uint8 = ctx.any.arc4.uintN8() +const uint16 = ctx.any.arc4.uintN16() +const uint32 = ctx.any.arc4.uintN32() +const uint64 = ctx.any.arc4.uintN64() +const biguint128 = ctx.any.arc4.uintN128() +const biguint256 = ctx.any.arc4.uintN256() +const biguint512 = ctx.any.arc4.uintN512() + +// Generate a random unsigned arc4 integer with specified range +const uint8Custom = ctx.any.arc4.uintN8(10, 100) +const uint16Custom = ctx.any.arc4.uintN16(1000, 5000) +const uint32Custom = ctx.any.arc4.uintN32(100000, 1000000) +const uint64Custom = ctx.any.arc4.uintN64(1000000000, 10000000000) +const biguint128Custom = ctx.any.arc4.uintN128(1000000000000000, 10000000000000000n) +const biguint256Custom = ctx.any.arc4.uintN256(1000000000000000000000000n, 10000000000000000000000000n) +const biguint512Custom = ctx.any.arc4.uintN512(10000000000000000000000000000000000n, 10000000000000000000000000000000000n) +``` + +## Address + +```ts +// Address type +const addressValue = new arc4.Address('AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAY5HFKQ') + +// Generate a random address +const randomAddress = ctx.any.arc4.address() + +// Access native underlaying type +const native = randomAddress.native +``` + +## Dynamic Bytes + +```ts +// Dynamic byte string +const bytesValue = new arc4.DynamicBytes('Hello, Algorand!') + +// Generate random dynamic bytes +const randomDynamicBytes = ctx.any.arc4.dynamicBytes(123) // n is the number of bits in the arc4 dynamic bytes +``` + +## String + +```ts +// UTF-8 encoded string +const stringValue = new arc4.Str('Hello, Algorand!') + +// Generate random string +const randomString = ctx.any.arc4.str(12) // n is the number of bits in the arc4 string +``` + +```ts +// test cleanup +ctx.reset() +``` diff --git a/docs/testing-guide/avm-types.md b/docs/testing-guide/avm-types.md new file mode 100644 index 0000000..53753c9 --- /dev/null +++ b/docs/testing-guide/avm-types.md @@ -0,0 +1,212 @@ +# AVM Types + +These types are available directly under the `algorand-typescript` namespace. They represent the basic AVM primitive types and can be instantiated directly or via _value generators_: + +```{note} +For 'primitive `algorand-typescript` types such as `Account`, `Application`, `Asset`, `uint64`, `biguint`, `bytes`, `string` with and without respective _value generator_, instantiation can be performed directly. If you have a suggestion for a new _value generator_ implementation, please open an issue in the [`algorand-typescript-testing`](https://github.com/algorandfoundation/algorand-typescript-testing) repository or contribute by following the [contribution guide](https://github.com/algorandfoundation/algorand-typescript-testing/blob/main/CONTRIBUTING.md). +``` + +```ts +import * as algots from '@algorandfoundation/algorand-typescript' +import { TestExecutionContext } from '@algorandfoundation/algorand-typescript-testing' + +// Create the context manager for snippets below +const ctx = new TestExecutionContext() +``` + +## uint64 + +```ts +// Direct instantiation +const uint64Value = algots.Uint64(100) + +// Generate a random UInt64 value +const randomUint64 = ctx.any.uint64() + +// Specify a range +const randomUint64InRange = ctx.any.uint64(1000, 9999) +``` + +## bytes + +```ts +// Direct instantiation +const bytesValue = algots.Bytes('Hello, Algorand!') + +// Generate random byte sequences +const randomBytes = ctx.any.bytes() + +// Specify the length +const randomBytesOfLength = ctx.any.bytes(32) +``` + +## string + +```ts +// Direct instantiation +const stringValue = 'Hello, Algorand!' + +// Generate random strings +const randomString = ctx.any.string() + +// Specify the length +const randomStringOfLength = ctx.any.string(16) +``` + +## biguint + +```ts +// Direct instantiation +const biguintValue = algots.BigUint(100) + +// Generate a random BigUInt value +const randomBiguint = ctx.any.biguint() + +// Specify the min value +const randomBiguintOver = ctx.any.biguint(100n) +``` + +## Asset + +```ts +// Direct instantiation +const asset = algots.Asset(1001) + +// Generate a random asset +const randomAsset = ctx.any.asset({ + clawback: ctx.any.account(), // Optional: Clawback address + creator: ctx.any.account(), // Optional: Creator account + decimals: 6, // Optional: Number of decimals + defaultFrozen: false, // Optional: Default frozen state + freeze: ctx.any.account(), // Optional: Freeze address + manager: ctx.any.account(), // Optional: Manager address + metadataHash: ctx.any.bytes(32), // Optional: Metadata hash + name: algots.Bytes(ctx.any.string()), // Optional: Asset name + reserve: ctx.any.account(), // Optional: Reserve address + total: 1000000, // Optional: Total supply + unitName: algots.Bytes(ctx.any.string()), // Optional: Unit name + url: algots.Bytes(ctx.any.string()), // Optional: Asset URL +}) + +// Get an asset by ID +const asset = ctx.ledger.getAsset(randomAsset.id) + +// Update an asset +ctx.ledger.patchAssetData(randomAsset, { + clawback: ctx.any.account(), // Optional: New clawback address + creator: ctx.any.account(), // Optional: Creator account + decimals: 6, // Optional: New number of decimals + defaultFrozen: false, // Optional: Default frozen state + freeze: ctx.any.account(), // Optional: New freeze address + manager: ctx.any.account(), // Optional: New manager address + metadataHash: ctx.any.bytes(32), // Optional: New metadata hash + name: algots.Bytes(ctx.any.string()), // Optional: New asset name + reserve: ctx.any.account(), // Optional: New reserve address + total: 1000000, // Optional: New total supply + unitName: algots.Bytes(ctx.any.string()), // Optional: Unit name + url: algots.Bytes(ctx.any.string()), // Optional: New asset URL +}) +``` + +## Account + +```ts +// Direct instantiation +const rawAddress = algots.Bytes.fromBase32('PUYAGEGVCOEBP57LUKPNOCSMRWHZJSU4S62RGC2AONDUEIHC6P7FOPJQ4I') +const account = algots.Account(rawAddress) // zero address by default + +// Generate a random account +const randomAccount = ctx.any.account({ + address: rawAddress, // Optional: Specify a custom address, defaults to a random address + optedAssetBalances: new Map([]), // Optional: Specify opted asset balances as dict of assets to balance + optedApplications: [], // Optional: Specify opted apps as sequence of algopy.Application objects + totalAppsCreated: 0, // Optional: Specify the total number of created applications + totalAppsOptedIn: 0, // Optional: Specify the total number of applications opted into + totalAssets: 0, // Optional: Specify the total number of assets + totalAssetsCreated: 0, // Optional: Specify the total number of created assets + totalBoxBytes: 0, // Optional: Specify the total number of box bytes + totalBoxes: 0, // Optional: Specify the total number of boxes + totalExtraAppPages: 0, // Optional: Specify the total number of extra + totalNumByteSlice: 0, // Optional: Specify the total number of byte slices + totalNumUint: 0, // Optional: Specify the total number of uints + minBalance: 0, // Optional: Specify a minimum balance + balance: 0, // Optional: Specify an initial balance + authAddress: algots.Account(), // Optional: Specify an auth address, +}) + +// Generate a random account that is opted into a specific asset +const mockAsset = ctx.any.asset() +const mockAccount = ctx.any.account({ + optedAssetBalances: new Map([[mockAsset.id, 123]]), +}) + +// Get an account by address +const account = ctx.ledger.getAccount(mockAccount) + +// Update an account +ctx.ledger.patchAccountData(mockAccount, { + account: { + balance: 0, // Optional: New balance + minBalance: 0, // Optional: New minimum balance + authAddress: ctx.any.account(), // Optional: New auth address + totalAssets: 0, // Optional: New total number of assets + totalAssetsCreated: 0, // Optional: New total number of created assets + totalAppsCreated: 0, // Optional: New total number of created applications + totalAppsOptedIn: 0, // Optional: New total number of applications opted into + totalExtraAppPages: 0, // Optional: New total number of extra application pages + }, +}) + +// Check if an account is opted into a specific asset +const optedIn = account.isOptedIn(mockAsset) +``` + +## Application + +```ts +// Direct instantiation +const application = algots.Application() + +// Generate a random application +const randomApp = ctx.any.application({ + approvalProgram: algots.Bytes(''), // Optional: Specify a custom approval program + clearStateProgram: algots.Bytes(''), // Optional: Specify a custom clear state program + globalNumUint: 1, // Optional: Number of global uint values + globalNumBytes: 1, // Optional: Number of global byte values + localNumUint: 1, // Optional: Number of local uint values + localNumBytes: 1, // Optional: Number of local byte values + extraProgramPages: 1, // Optional: Number of extra program pages + creator: ctx.defaultSender, // Optional: Specify the creator account +}) + +// Get an application by ID +const app = ctx.ledger.getApplication(randomApp.id) + +// Update an application +ctx.ledger.patchApplicationData(randomApp, { + application: { + approvalProgram: algots.Bytes(''), // Optional: New approval program + clearStateProgram: algots.Bytes(''), // Optional: New clear state program + globalNumUint: 1, // Optional: New number of global uint values + globalNumBytes: 1, // Optional: New number of global byte values + localNumUint: 1, // Optional: New number of local uint values + localNumBytes: 1, // Optional: New number of local byte values + extraProgramPages: 1, // Optional: New number of extra program pages + creator: ctx.defaultSender, // Optional: New creator account + }, +}) + +// Patch logs for an application. When accessing via transactions or inner transaction related opcodes, will return the patched logs unless new logs where added into the transaction during execution. +const testApp = ctx.any.application({ appLogs: [algots.Bytes('log entry 1'), algots.Bytes('log entry 2')] }) + +// Get app associated with the active contract +class MyContract extends algots.arc4.Contract {} +const contract = ctx.contract.create(MyContract) + +const activeApp = ctx.ledger.getApplicationForContract(contract) +``` + +```ts +// test context clean up +ctx.reset() +``` diff --git a/docs/testing-guide/concepts.md b/docs/testing-guide/concepts.md new file mode 100644 index 0000000..c892fea --- /dev/null +++ b/docs/testing-guide/concepts.md @@ -0,0 +1,66 @@ +# Concepts + +The following sections provide an overview of key concepts and features in the Algorand TypeScript Testing framework. + +## Test Context + +The main abstraction for interacting with the testing framework is the [`TestExecutionContext`](../api.md#contexts). It creates an emulated Algorand environment that closely mimics AVM behavior relevant to unit testing the contracts and provides a TypeScript interface for interacting with the emulated environment. + +```typescript +import { TestExecutionContext } from '@algorandfoundation/algorand-typescript-testing' +import { afterEach, describe, it } from 'vitest' + +describe('MyContract', () => { + // Recommended way to instantiate the test context + const ctx = new TestExecutionContext() + afterEach(() => { + // ctx should be reset after each test is executed + ctx.reset() + }) + + it('test my contract', () => { + // Your test code here + }) +}) +``` + +The context manager interface exposes four main properties: + +1. `contract`: An instance of `ContractContext` for creating instances of Contract under test and register them with the test execution context. +1. `ledger`: An instance of `LedgerContext` for interacting with and querying the emulated Algorand ledger state. +1. `txn`: An instance of `TransactionContext` for creating and managing transaction groups, submitting transactions, and accessing transaction results. +1. `any`: An instance of `AlgopyValueGenerator` for generating randomized test data. + +For detailed method signatures, parameters, and return types, refer to the following API sections: + +- [`ContractContext`](../code/subcontexts/contract-context/classes/ContractContext.md) +- [`LedgerContext`](../code/subcontexts/ledger-context/classes/LedgerContext.md) +- [`TransactionContext`](../code/subcontexts/transaction-context/classes/TransactionContext.md) +- [`AvmValueGenerator`, `TxnValueGenerator`, `Arc4ValueGenerator`](../api.md) + +The `any` property provides access to different value generators: + +- `AvmValueGenerator`: Base abstractions for AVM types. All methods are available directly on the instance returned from `any`. +- `TxnValueGenerator`: Accessible via `any.txn`, for transaction-related data. +- `Arc4ValueGenerator`: Accessible via `any.arc4`, for ARC4 type data. + +These generators allow creation of constrained random values for various AVM entities (accounts, assets, applications, etc.) when specific values are not required. + +```{hint} +Value generators are powerful tools for generating test data for specified AVM types. They allow further constraints on random value generation via arguments, making it easier to generate test data when exact values are not necessary. + +When used with the 'Arrange, Act, Assert' pattern, value generators can be especially useful in setting up clear and concise test data in arrange steps. + +``` + +## Types of `algorand-typescript` stub implementations + +As explained in the [introduction](index.md), `algorand-typescript-testing` _injects_ test implementations for stubs available in the `algorand-typescript` package. However, not all of the stubs are implemented in the same manner: + +1. **Native**: Fully matches AVM computation in Python. For example, `op.sha256` and other cryptographic operations behave identically in AVM and unit tests. This implies that the majority of opcodes that are 'pure' functions in AVM also have a native TypeScript implementation provided by this package. These abstractions and opcodes can be used within and outside of the testing context. + +2. **Emulated**: Uses `TestExecutionContext` to mimic AVM behavior. For example, `Box.put` on an `Box` within a test context stores data in the test manager, not the real Algorand network, but provides the same interface. + +3. **Mockable**: Not implemented, but can be mocked or patched. For example, `op.onlineStake` can be mocked to return specific values or behaviors; otherwise, it raises a `NotImplementedError`. This category covers cases where native or emulated implementation in a unit test context is impractical or overly complex. + +For a full list of all public `algorand-typescript` types and their corresponding implementation category, refer to the [Coverage](../coverage.md) section. diff --git a/docs/testing-guide/contract-testing.md b/docs/testing-guide/contract-testing.md new file mode 100644 index 0000000..7a5d71d --- /dev/null +++ b/docs/testing-guide/contract-testing.md @@ -0,0 +1,229 @@ +# Smart Contract Testing + +This guide provides an overview of how to test smart contracts using the [Algorand Typescript Testing package](https://www.npmjs.com/package/@algorandfoundation/algorand-typescript-testing). We will cover the basics of testing `arc4.Contract` and `BaseContract` classes, focusing on `abimethod` and `baremethod` decorators. + +```{note} +The code snippets showcasing the contract testing capabilities are using [vitest](https://vitest.dev/) as the test framework. However, note that the `algorand-typescript-testing` package can be used with any other test framework that supports TypeScript. `vitest` is used for demonstration purposes in this documentation. +``` + +```ts +import { arc4 } from '@algorandfoundation/algorand-typescript' +import { TestExecutionContext } from '@algorandfoundation/algorand-typescript-testing' + +// Create the context manager for snippets below +const ctx = new TestExecutionContext() +``` + +## `arc4.Contract` + +Subclasses of `arc4.Contract` are **required** to be instantiated with an active test context. As part of instantiation, the test context will automatically create a matching `Application` object instance. + +Within the class implementation, methods decorated with `arc4.abimethod` and `arc4.baremethod` will automatically assemble an `gtxn.ApplicationTxn` transaction to emulate the AVM application call. This behavior can be overriden by setting the transaction group manually as part of test setup, this is done via implicit invocation of `ctx.any.txn.applicationCall` _value generator_ (refer to [APIs](../apis.md) for more details). + +```ts +class SimpleVotingContract extends arc4.Contract { + topic = GlobalState({ initialValue: Bytes('default_topic'), key: 'topic' }) + votes = GlobalState({ + initialValue: Uint64(0), + key: 'votes', + }) + voted = LocalState({ key: 'voted' }) + + @arc4.abimethod({ onCreate: 'require' }) + create(initialTopic: bytes) { + this.topic.value = initialTopic + this.votes.value = Uint64(0) + } + + @arc4.abimethod() + vote(): uint64 { + assert(this.voted(Txn.sender).value === 0, 'Account has already voted') + this.votes.value = this.votes.value + 1 + this.voted(Txn.sender).value = Uint64(1) + return this.votes.value + } + + @arc4.abimethod({ readonly: true }) + getVotes(): uint64 { + return this.votes.value + } + + @arc4.abimethod() + changeTopic(newTopic: bytes) { + assert(Txn.sender === Txn.applicationId.creator, 'Only creator can change topic') + this.topic.value = newTopic + this.votes.value = Uint64(0) + // Reset user's vote (this is simplified per single user for the sake of example) + this.voted(Txn.sender).value = Uint64(0) + } +} + +// Arrange +const initialTopic = Bytes('initial_topic') +const contract = ctx.contract.create(SimpleVotingContract) +contract.voted(ctx.defaultSender).value = Uint64(0) + +// Act - Create the topic +contract.create(initialTopic) + +// Assert - Check initial state +expect(contract.topic.value).toEqual(initialTopic) +expect(contract.votes.value).toEqual(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 +const result = contract.vote() + +// Assert - you can access the corresponding auto generated application call transaction via test context +expect(ctx.txn.lastGroup.transactions.length).toEqual(1) + +// Assert - Note how local and global state are accessed via regular python instance attributes +expect(result).toEqual(1) +expect(contract.votes.value).toEqual(1) +expect(contract.voted(ctx.defaultSender).value).toEqual(1) + +// Act - Change topic +const newTopic = Bytes('new_topic') +contract.changeTopic(newTopic) + +// Assert - Check topic changed and votes reset +expect(contract.topic.value).toEqual(newTopic) +expect(contract.votes.value).toEqual(0) +expect(contract.voted(ctx.defaultSender).value).toEqual(0) + +// Act - Get votes (should be 0 after reset) +const votes = contract.getVotes() + +// Assert - Check votes +expect(votes).toEqual(0) +``` + +For more examples of tests using `arc4.Contract`, see the [examples](../examples.md) section. + +## `BaseContract`` + +Subclasses of `BaseContract` are **required** to be instantiated with an active test context. As part of instantiation, the test context will automatically create a matching `Application` object instance. This behavior is identical to `arc4.Contract` class instances. + +Unlike `arc4.Contract`, `BaseContract` requires manual setup of the transaction context and explicit method calls. + +Here's an updated example demonstrating how to test a `BaseContract` class: + +```ts +import { BaseContract, Bytes, GlobalState, Uint64 } from '@algorandfoundation/algorand-typescript' +import { TestExecutionContext } from '@algorandfoundation/algorand-typescript-testing' +import { afterEach, expect, test } from 'vitest' + +class CounterContract extends BaseContract { + counter = GlobalState({ initialValue: Uint64(0) }) + + increment() { + this.counter.value = this.counter.value + 1 + return Uint64(1) + } + + approvalProgram() { + return this.increment() + } + + clearStateProgram() { + return Uint64(1) + } +} + +const ctx = new TestExecutionContext() +afterEach(() => { + ctx.reset() +}) + +test('increment', () => { + // Instantiate contract + const contract = ctx.contract.create(CounterContract) + + // Set up the transaction context using active_txn_overrides + ctx.txn + .createScope([ctx.any.txn.applicationCall({ appId: contract, sender: ctx.defaultSender, appArgs: [Bytes('increment')] })]) + .execute(() => { + // Invoke approval program + const result = contract.approvalProgram() + + // Assert approval program result + expect(result).toEqual(1) + + // Assert counter value + expect(contract.counter.value).toEqual(1) + }) + // Test clear state program + expect(contract.clearStateProgram()).toEqual(1) +}) + +test('increment with multiple txns', () => { + const contract = ctx.contract.create(CounterContract) + + // For scenarios with multiple transactions, you can still use gtxns + const extraPayment = ctx.any.txn.payment() + + ctx.txn + .createScope( + [ + extraPayment, + ctx.any.txn.applicationCall({ + sender: ctx.defaultSender, + appId: contract, + appArgs: [Bytes('increment')], + }), + ], + + 1, // Set the application call as the active transaction + ) + .execute(() => { + const result = contract.approvalProgram() + + expect(result).toEqual(1) + expect(contract.counter.value).toEqual(1) + }) + expect(ctx.txn.lastGroup.transactions.length).toEqual(2) +}) +``` + +In this updated example: + +1. We use `ctx.txn.createScope()` with `ctx.any.txn.applicationCall` to set up the transaction context for a single application call. + +2. For scenarios involving multiple transactions, you can still use the `group` parameter to create a transaction group, as shown in the `test('increment with multiple txns', () => {})` function. + +This approach provides more flexibility in setting up the transaction context for testing `Contract` classes, allowing for both simple single-transaction scenarios and more complex multi-transaction tests. + +## Defer contract method invocation + +You can create deferred application calls for more complex testing scenarios where order of transactions needs to be controlled: + +```ts +class MyARC4Contract extends arc4.Contract { + someMethod(payment: gtxn.PaymentTxn) { + return Uint64(1) + } +} + +const ctx = new TestExecutionContext() + +test('deferred call', () => { + const contract = ctx.contract.create(MyARC4Contract) + + const extraPayment = ctx.any.txn.payment() + const extraAssetTransfer = ctx.any.txn.assetTransfer() + const implicitPayment = ctx.any.txn.payment() + const deferredCall = ctx.txn.deferAppCall(contract, contract.someMethod, 'someMethod', implicitPayment) + + ctx.txn.createScope([extraPayment, deferredCall, extraAssetTransfer]).execute(() => { + const result = deferredCall.submit() + }) + console.log(ctx.txn.lastGroup) // [extra_payment, implicit_payment, app call, extra_asset_transfer] +}) +``` + +A deferred application call prepares the application call transaction without immediately executing it. The call can be executed later by invoking the `.submit()` method on the deferred application call instance. As demonstrated in the example, you can also include the deferred call in a transaction group creation context manager to execute it as part of a larger transaction group. When `.submit()` is called, only the specific method passed to `defer_app_call()` will be executed. + +```ts +// test cleanup +ctx.reset() +``` diff --git a/docs/testing-guide/index.md b/docs/testing-guide/index.md new file mode 100644 index 0000000..e004e52 --- /dev/null +++ b/docs/testing-guide/index.md @@ -0,0 +1,41 @@ +# Testing Guide + +The Algorand TypeScript Testing framework provides powerful tools for testing Algorand TypeScript smart contracts within a Node.js environment. This guide covers the main features and concepts of the framework, helping you write effective tests for your Algorand applications. + +```{note} +For all code examples in the _Testing Guide_ section, assume `context` is an instance of `TestExecutionContext` obtained using the initialising an instance of `TestExecutionContext` class. All subsequent code is executed within this context. +``` + +The Algorand TypeScript Testing framework streamlines unit testing of your Algorand TypeScript smart contracts by offering functionality to: + +1. Simulate the Algorand Virtual Machine (AVM) environment +2. Create and manipulate test accounts, assets, applications, transactions, and ARC4 types +3. Test smart contract classes, including their states, variables, and methods +4. Verify logic signatures and subroutines +5. Manage global state, local state, scratch slots, and boxes in test contexts +6. Simulate transactions and transaction groups, including inner transactions +7. Verify opcode behavior + +By using this framework, you can ensure your Algorand TypeScript smart contracts function correctly before deploying them to a live network. + +Key features of the framework include: + +- `TestExecutionContext`: The main entry point for testing, providing access to various testing utilities and simulated blockchain state +- AVM Type Simulation: Accurate representations of AVM types like `uint64` and `bytes` +- ARC4 Support: Tools for testing ARC4 contracts and methods, including struct definitions and ABI encoding/decoding +- Transaction Simulation: Ability to create and execute various transaction types +- State Management: Tools for managing and verifying global and local state changes +- Opcode Simulation: Implementations of AVM opcodes for accurate smart contract behavior testing + +The framework is designed to work seamlessly with Algorand TypeScript smart contracts, allowing developers to write comprehensive unit tests that closely mimic the behavior of contracts on the Algorand blockchain. + +## Table of Contents + +- [Concepts](./concepts.md) +- [AVM Types](./avm-types.md) +- [ARC4 Types](./arc4-types.md) +- [Transactions](./transactions.md) +- [Smart Contract Testing](./contract-testing.md) +- [Smart Signature Testing](./signature-testing.md) +- [State Management](./state-management.md) +- [AVM Opcodes](./opcodes.md) diff --git a/docs/testing-guide/opcodes.md b/docs/testing-guide/opcodes.md new file mode 100644 index 0000000..9ccb9b5 --- /dev/null +++ b/docs/testing-guide/opcodes.md @@ -0,0 +1,399 @@ +# AVM Opcodes + +The [coverage](coverage.md) file provides a comprehensive list of all opcodes and their respective types, categorized as _Mockable_, _Emulated_, or _Native_ within the `algorand-typescript-testing` package. This section highlights a **subset** of opcodes and types that typically require interaction with the test execution context. + +`Native` opcodes are assumed to function as they do in the Algorand Virtual Machine, given their stateless nature. If you encounter issues with any `Native` opcodes, please raise an issue in the [`algorand-typescript-testing` repo](https://github.com/algorandfoundation/algorand-typescript-testing/issues/new/choose) or contribute a PR following the [Contributing](https://github.com/algorandfoundation/algorand-typescript-testing/blob/main/CONTRIBUTING.md) guide. + +```ts +import { TestExecutionContext } from '@algorandfoundation/algorand-typescript-testing' + +// Create the context manager for snippets below +const ctx = new TestExecutionContext() +``` + +## Implemented Types + +These types are fully implemented in TypeScript and behave identically to their AVM counterparts: + +### 1. Cryptographic Operations + +The following opcodes are demonstrated: + +- `op.sha256` +- `op.keccak256` +- `op.ecdsaVerify` + +```ts +import { op } from '@algorandfoundation/algorand-typescript' + +// SHA256 hash +const data = Bytes('Hello, World!') +const hashed = op.sha256(data) + +// Keccak256 hash +const keccakHashed = op.keccak256(data) + +// ECDSA verification +const messageHash = Bytes.fromHex('f809fd0aa0bb0f20b354c6b2f86ea751957a4e262a546bd716f34f69b9516ae1') +const sigR = Bytes.fromHex('18d96c7cda4bc14d06277534681ded8a94828eb731d8b842e0da8105408c83cf') +const sigS = Bytes.fromHex('7d33c61acf39cbb7a1d51c7126f1718116179adebd31618c4604a1f03b5c274a') +const pubkeyX = Bytes.fromHex('f8140e3b2b92f7cbdc8196bc6baa9ce86cf15c18e8ad0145d50824e6fa890264') +const pubkeyY = Bytes.fromHex('bd437b75d6f1db67155a95a0da4b41f2b6b3dc5d42f7db56238449e404a6c0a3') + +const result = op.ecdsaVerify(op.Ecdsa.Secp256r1, messageHash, sigR, sigS, pubkeyX, pubkeyY) +expect(result).toBe(true) +``` + +### 2. Arithmetic and Bitwise Operations + +The following opcodes are demonstrated: + +- `op.addw` +- `op.bitLength` +- `op.getBit` +- `op.setBit` + +```ts +import { op, Uint64 } from '@algorandfoundation/algorand-typescript' + +// Addition with carry +const [result, carry] = op.addw(Uint64(2n ** 63n), Uint64(2n ** 63n)) + +// Bitwise operations +const value = Uint64(42) +const bitLength = op.bitLength(value) +const isBitSet = op.getBit(value, 3) +const newValue = op.setBit(value, 2, 1) +``` + +For a comprehensive list of all opcodes and types, refer to the [coverage](../coverage.md) page. + +## Emulated Types Requiring Transaction Context + +These types necessitate interaction with the transaction context: + +### algopy.op.Global + +```ts +import { TestExecutionContext } from '@algorandfoundation/algorand-typescript-testing' +import { op, arc4, uint64, Uint64 } from '@algorandfoundation/algorand-typescript' +import { TestExecutionContext } from '@algorandfoundation/algorand-typescript-testing' + +class MyContract extends arc4.Contract { + @arc4.abimethod() + checkGlobals(): uint64 { + return op.Global.minTxnFee + op.Global.minBalance + } +} + +// Create the context manager for snippets below +const ctx = new TestExecutionContext() +ctx.ledger.patchGlobalData({ + minTxnFee: 1000, + minBalance: 100000, +}) + +const contract = ctx.contract.create(MyContract) +const result = contract.checkGlobals() +expect(result).toEqual(101000) +``` + +### algopy.op.Txn + +```ts +import { op, arc4 } from '@algorandfoundation/algorand-typescript' +import { TestExecutionContext } from '@algorandfoundation/algorand-typescript-testing' + +class MyContract extends arc4.Contract { + @arc4.abimethod() + checkTxnFields(): arc4.Address { + return new arc4.Address(op.Txn.sender) + } +} + +// Create the context manager for snippets below +const ctx = new TestExecutionContext() + +const contract = ctx.contract.create(MyContract) +const customSender = ctx.any.account() +ctx.txn.createScope([ctx.any.txn.applicationCall({ sender: customSender })]).execute(() => { + const result = contract.checkTxnFields() + expect(result).toEqual(customSender) +}) +``` + +### algopy.op.AssetHoldingGet + +```ts +import { Account, arc4, Asset, op, uint64, Uint64 } from '@algorandfoundation/algorand-typescript' +import { TestExecutionContext } from '@algorandfoundation/algorand-typescript-testing' + +class AssetContract extends arc4.Contract { + @arc4.abimethod() + checkAssetHolding(account: Account, asset: Asset): uint64 { + const [balance, _] = op.AssetHolding.assetBalance(account, asset) + return balance + } +} + +// Create the context manager for snippets below +const ctx = new TestExecutionContext() + +const contract = ctx.contract.create(AssetContract) +const asset = ctx.any.asset({ total: 1000000 }) +const account = ctx.any.account({ optedAssetBalances: new Map([[asset.id, Uint64(5000)]]) }) + +const result = contract.checkAssetHolding(account, asset) +expect(result).toEqual(5000) +``` + +### algopy.op.AppGlobal + +```ts +import { arc4, bytes, Bytes, op, uint64, Uint64 } from '@algorandfoundation/algorand-typescript' +import { TestExecutionContext } from '@algorandfoundation/algorand-typescript-testing' + +class StateContract extends arc4.Contract { + @arc4.abimethod() + setAndGetState(key: bytes, value: uint64): uint64 { + op.AppGlobal.put(key, value) + return op.AppGlobal.getUint64(key) + } +} + +// Create the context manager for snippets below +const ctx = new TestExecutionContext() + +const contract = ctx.contract.create(StateContract) +const key = Bytes('test_key') +const value = Uint64(42) +const result = contract.setAndGetState(key, value) +expect(result).toEqual(value) + +const [storedValue, _] = ctx.ledger.getGlobalState(contract, key) +expect(storedValue?.value).toEqual(42) +``` + +### algopy.op.Block + +```ts +import { arc4, bytes, op } from '@algorandfoundation/algorand-typescript' +import { TestExecutionContext } from '@algorandfoundation/algorand-typescript-testing' + +class BlockInfoContract extends arc4.Contract { + @arc4.abimethod() + getBlockSeed(): bytes { + return op.Block.blkSeed(1000) + } +} +// Create the context manager for snippets below +const ctx = new TestExecutionContext() + +const contract = ctx.contract.create(BlockInfoContract) +ctx.ledger.patchBlockData(1000, { seed: op.itob(123456), timestamp: 1625097600 }) + +const seed = contract.getBlockSeed() +expect(seed).toEqual(op.itob(123456)) +``` + +### algopy.op.AcctParamsGet + +```ts +import type { Account, uint64 } from '@algorandfoundation/algorand-typescript' +import { arc4, assert, op, Uint64 } from '@algorandfoundation/algorand-typescript' +import { TestExecutionContext } from '@algorandfoundation/algorand-typescript-testing' + +class AccountParamsContract extends arc4.Contract { + @arc4.abimethod() + getAccountBalance(account: Account): uint64 { + const [balance, exists] = op.AcctParams.acctBalance(account) + assert(exists) + return balance + } +} +// Create the context manager for snippets below +const ctx = new TestExecutionContext() + +const contract = ctx.contract.create(AccountParamsContract) +const account = ctx.any.account({ balance: 1000000 }) + +const balance = contract.getAccountBalance(account) +expect(balance).toEqual(Uint64(1000000)) +``` + +### algopy.op.AppParamsGet + +```ts +import type { Application } from '@algorandfoundation/algorand-typescript' +import { arc4, assert, op } from '@algorandfoundation/algorand-typescript' +import { TestExecutionContext } from '@algorandfoundation/algorand-typescript-testing' + +class AppParamsContract extends arc4.Contract { + @arc4.abimethod() + getAppCreator(appId: Application): arc4.Address { + const [creator, exists] = op.AppParams.appCreator(appId) + assert(exists) + return new arc4.Address(creator) + } +} +// Create the context manager for snippets below +const ctx = new TestExecutionContext() + +const contract = ctx.contract.create(AppParamsContract) +const app = ctx.any.application() +const creator = contract.getAppCreator(app) +expect(creator).toEqual(ctx.defaultSender) +``` + +### algopy.op.AssetParamsGet + +```ts +import type { uint64 } from '@algorandfoundation/algorand-typescript' +import { arc4, assert, op } from '@algorandfoundation/algorand-typescript' +import { TestExecutionContext } from '@algorandfoundation/algorand-typescript-testing' + +class AssetParamsContract extends arc4.Contract { + @arc4.abimethod() + getAssetTotal(assetId: uint64): uint64 { + const [total, exists] = op.AssetParams.assetTotal(assetId) + assert(exists) + return total + } +} +// Create the context manager for snippets below +const ctx = new TestExecutionContext() + +const contract = ctx.contract.create(AssetParamsContract) +const asset = ctx.any.asset({ total: 1000000, decimals: 6 }) +const total = contract.getAssetTotal(asset.id) +expect(total).toEqual(1000000) +``` + +### algopy.op.Box + +```ts +import type { bytes } from '@algorandfoundation/algorand-typescript' +import { arc4, assert, Bytes, op } from '@algorandfoundation/algorand-typescript' +import { TestExecutionContext } from '@algorandfoundation/algorand-typescript-testing' + +class BoxStorageContract extends arc4.Contract { + @arc4.abimethod() + storeAndRetrieve(key: bytes, value: bytes): bytes { + op.Box.put(key, value) + const [retrievedValue, exists] = op.Box.get(key) + assert(exists) + return retrievedValue + } +} +// Create the context manager for snippets below +const ctx = new TestExecutionContext() +const contract = ctx.contract.create(BoxStorageContract) + +const key = Bytes('test_key') +const value = Bytes('test_value') + +const result = contract.storeAndRetrieve(key, value) +expect(result).toEqual(value) + +const storedValue = ctx.ledger.getBox(contract, key) +expect(storedValue).toEqual(value) +``` + +### algopy.compile_contract + +```ts +import { arc4, compile, uint64 } from '@algorandfoundation/algorand-typescript' +import { TestExecutionContext } from '@algorandfoundation/algorand-typescript-testing' + +class MockContract extends arc4.Contract {} + +class ContractFactory extends arc4.Contract { + @arc4.abimethod() + compileAndGetBytes(): uint64 { + const contractResponse = compile(MockContract) + return compiled.localBytes + } +} +// Create the context manager for snippets below +const ctx = new TestExecutionContext() + +const contract = ctx.contract.create(ContractFactory) +const mockApp = ctx.any.application({ localNumBytes: 4 }) +ctx.setCompiledApp(MockContract, mockApp.id) + +const result = contract.compileAndGetBytes() +expect(result).toBe(4) +``` + +## Mockable Opcodes + +These opcodes are mockable in `algorand-typescript-testing`, allowing for controlled testing of complex operations. Note that the module being mocked is `@algorandfoundation/algorand-typescript-testing/internal` which holds the stub implementations of `algorand-typescript` functions to be executed in Node.js environment. + +### algopy.op.vrf_verify + +```ts +import { expect, Mock, test, vi } from 'vitest' +import { bytes, Bytes, op, VrfVerify } from '@algorandfoundation/algorand-typescript' + +vi.mock(import('@algorandfoundation/algorand-typescript-testing/internal'), async (importOriginal) => { + const mod = await importOriginal() + return { + ...mod, + op: { + ...mod.op, + vrfVerify: vi.fn(), + }, + } +}) + +test('mock vrfVerify', () => { + const mockedVrfVerify = op.vrfVerify as Mock + const mockResult = [Bytes('mock_output'), true] as readonly [bytes, boolean] + mockedVrfVerify.mockReturnValue(mockResult) + const result = op.vrfVerify(VrfVerify.VrfAlgorand, Bytes('proof'), Bytes('message'), Bytes('public_key')) + + expect(result).toEqual(mockResult) +}) +``` + +### algopy.op.EllipticCurve + +```ts +import { expect, Mock, test, vi } from 'vitest' +import { Bytes, op } from '@algorandfoundation/algorand-typescript' + +vi.mock(import('@algorandfoundation/algorand-typescript-testing/internal'), async (importOriginal) => { + const mod = await importOriginal() + return { + ...mod, + op: { + ...mod.op, + EllipticCurve: { + ...mod.op.EllipticCurve, + add: vi.fn(), + }, + }, + } +}) +test('mock EllipticCurve', () => { + const mockedEllipticCurveAdd = op.EllipticCurve.add as Mock + const mockResult = Bytes('mock_output') + mockedEllipticCurveAdd.mockReturnValue(mockResult) + + const result = op.EllipticCurve.add(op.Ec.BN254g1, Bytes('A'), Bytes('B')) + expect(result).toEqual(mockResult) +}) +``` + +These examples demonstrate how to mock key mockable opcodes in `algorand-typescript-testing`. Use similar techniques (in your preferred testing framework) for other mockable opcodes like `mimc`, and `JsonRef`. + +Mocking these opcodes allows you to: + +1. Control complex operations' behavior not covered by _implemented_ and _emulated_ types. +2. Test edge cases and error conditions. +3. Isolate contract logic from external dependencies. + +```ts +// test cleanup +ctx.reset() +``` diff --git a/docs/testing-guide/signature-testing.md b/docs/testing-guide/signature-testing.md new file mode 100644 index 0000000..47cd144 --- /dev/null +++ b/docs/testing-guide/signature-testing.md @@ -0,0 +1,76 @@ +# Smart Signature Testing + +Test Algorand smart signatures (LogicSigs) with ease using the Algorand TypeScript Testing framework. + +```ts +import * as algots from '@algorandfoundation/algorand-typescript' +import { TestExecutionContext } from '@algorandfoundation/algorand-typescript-testing' + +// Create the context manager for snippets below +const ctx = new TestExecutionContext() +``` + +## Define a LogicSig + +Extend `algots.LogicSig` class to create a LogicSig: + +```ts +import * as algots from '@algorandfoundation/algorand-typescript' + +class HashedTimeLockedLogicSig extends LogicSig { + program(): boolean { + // LogicSig code here + return true // Approve transaction + } +} +``` + +## Execute and Test + +Use `ctx.executeLogicSig()` to run and verify LogicSigs: + +```ts +ctx.txn.createScope([ctx.any.txn.payment()]).execute(() => { + const result = ctx.executeLogicSig(new HashedTimeLockedLogicSig(), Bytes('secret')) + expect(result).toBe(true) +}) +``` + +`executeLogicSig()` returns a boolean: + +- `true`: Transaction approved +- `false`: Transaction rejected + +## Pass Arguments + +Provide arguments to LogicSigs using `executeLogicSig()`: + +```ts +const result = ctx.executeLogicSig(new HashedTimeLockedLogicSig(), Bytes('secret')) +``` + +Access arguments in the LogicSig with `algots.op.arg()` opcode: + +```ts +import * as algots from '@algorandfoundation/algorand-typescript' + +class HashedTimeLockedLogicSig extends LogicSig { + program(): boolean { + // LogicSig code here + const secret = algots.op.arg(0) + const expectedHash = algots.op.sha256(algots.Bytes('secret')) + return algots.op.sha256(secret) === expectedHash + } +} + +// Example usage +const secret = algots.Bytes('secret') +expect(ctx.executeLogicSig(new HashedTimeLockedLogicSig(), secret)) +``` + +For more details on available operations, see the [coverage](../coverage.md). + +```ts +// test cleanup +ctx.reset() +``` diff --git a/docs/testing-guide/state-management.md b/docs/testing-guide/state-management.md new file mode 100644 index 0000000..e97749f --- /dev/null +++ b/docs/testing-guide/state-management.md @@ -0,0 +1,106 @@ +# State Management + +`algorand-typescript-testing` provides tools to test state-related abstractions in Algorand smart contracts. This guide covers global state, local state, boxes, and scratch space management. + +```ts +import * as algots from '@algorandfoundation/algorand-typescript' +import { TestExecutionContext } from '@algorandfoundation/algorand-typescript-testing' + +// Create the context manager for snippets below +const ctx = new TestExecutionContext() +``` + +## Global State + +Global state is represented as instance attributes on `algots.Contract` and `algots.arc4.Contract` classes. + +```ts +class MyContract extends algots.arc4.Contract { + stateA = algots.GlobalState({ key: 'globalStateA' }) + stateB = algots.GlobalState({ initialValue: algots.Uint64(1), key: 'globalStateB' }) +} + +// In your test +const contract = ctx.contract.create(MyContract) +contract.stateA.value = algots.Uint64(10) +contract.stateB.value = algots.Uint64(20) +``` + +## Local State + +Local state is defined similarly to global state, but accessed using account addresses as keys. + +```ts +class MyContract extends algots.arc4.Contract { + localStateA = algots.LocalState({ key: 'localStateA' }) +} + +// In your test +const contract = ctx.contract.create(MyContract) +const account = ctx.any.account() +contract.localStateA(account).value = algots.Uint64(10) +``` + +## Boxes + +The framework supports various Box abstractions available in `algorand-typescript`. + +```ts +class MyContract extends algots.arc4.Contract { + box: algots.Box | undefined + boxMap = algots.BoxMap({ keyPrefix: 'boxMap' }) + + @algots.arc4.abimethod() + someMethod(keyA: algots.bytes, keyB: algots.bytes, keyC: algots.bytes) { + this.box = algots.Box({ key: keyA }) + this.box.value = algots.Uint64(1) + this.boxMap.set(keyB, algots.Uint64(1)) + this.boxMap.set(keyC, algots.Uint64(2)) + } +} + +// In your test +const contract = ctx.contract.create(MyContract) +const keyA = algots.Bytes('keyA') +const keyB = algots.Bytes('keyB') +const keyC = algots.Bytes('keyC') + +contract.someMethod(keyA, keyB, keyC) + +// Access boxes +const boxContent = ctx.ledger.getBox(contract, keyA) +expect(ctx.ledger.boxExists(contract, keyA)).toBe(true) + +// Set box content manually +ctx.ledger.setBox(contract, keyA, algots.op.itob(algots.Uint64(1))) +``` + +## Scratch Space + +Scratch space is represented as a list of 256 slots for each transaction. + +```ts +@algots.contract({ scratchSlots: [1, 2, { from: 3, to: 20 }] }) +class MyContract extends algots.Contract { + approvalProgram(): boolean { + algots.op.Scratch.store(1, algots.Uint64(5)) + algots.assert(algots.op.Scratch.loadUint64(1) === algots.Uint64(5)) + return true + } +} + +// In your test +const contract = ctx.contract.create(MyContract) +const result = contract.approvalProgram() + +expect(result).toBe(true) +const scratchSpace = ctx.txn.lastGroup.getScratchSpace() +expect(scratchSpace[1]).toEqual(5) +``` + +For more detailed information, explore the example contracts in the `examples/` directory, the [coverage](../coverage.md) page, and the [API documentation](../api.md). + +```ts +// test cleanup +ctx.reset() +``` diff --git a/docs/testing-guide/transactions.md b/docs/testing-guide/transactions.md new file mode 100644 index 0000000..4cf4dd1 --- /dev/null +++ b/docs/testing-guide/transactions.md @@ -0,0 +1,193 @@ +# Transactions + +The testing framework follows the Transaction definitions described in [`algorand-typescript` docs](https://github.com/algorandfoundation/puya-ts/blob/main/docs/lg-transactions.md). This section focuses on _value generators_ and interactions with inner transactions, it also explains how the framework identifies _active_ transaction group during contract method/subroutine/logicsig invocation. + +```ts +import * as algots from '@algorandfoundation/algorand-typescript' +import { TestExecutionContext } from '@algorandfoundation/algorand-typescript-testing' + +// Create the context manager for snippets below +const ctx = new TestExecutionContext() +``` + +## Group Transactions + +Refers to test implementation of transaction stubs available under `algots.gtxn.*` namespace. Available under [`TxnValueGenerator`](../code/value-generators/txn/classes/TxnValueGenerator.md) instance accessible via `ctx.any.txn` property: + +```ts +// Generate a random payment transaction +const payTxn = ctx.any.txn.payment({ + sender: ctx.any.account(), // Optional: Defaults to context's default sender if not provided + receiver: ctx.any.account(), // Required + amount: 1000000, // Required +}) + +// Generate a random asset transfer transaction +const assetTransferTxn = ctx.any.txn.assetTransfer({ + sender: ctx.any.account(), // Optional: Defaults to context's default sender if not provided + assetReceiver: ctx.any.account(), // Required + xferAsset: ctx.any.asset({ assetId: 1 }), // Required + assetAmount: 1000, // Required +}) + +// Generate a random application call transaction +const appCallTxn = ctx.any.txn.applicationCall({ + appId: ctx.any.application(), // Required + appArgs: [algots.Bytes('arg1'), algots.Bytes('arg2')], // Optional: Defaults to empty list if not provided + accounts: [ctx.any.account()], // Optional: Defaults to empty list if not provided + assets: [ctx.any.asset()], // Optional: Defaults to empty list if not provided + apps: [ctx.any.application()], // Optional: Defaults to empty list if not provided + approvalProgramPages: [algots.Bytes('approval_code')], // Optional: Defaults to empty list if not provided + clearStateProgramPages: [algots.Bytes('clear_code')], // Optional: Defaults to empty list if not provided + scratchSpace: { 0: algots.Bytes('scratch') }, // Optional: Defaults to empty dict if not provided +}) + +// Generate a random asset config transaction +const assetConfigTxn = ctx.any.txn.assetConfig({ + sender: ctx.any.account(), // Optional: Defaults to context's default sender if not provided + configAsset: undefined, // Optional: If not provided, creates a new asset + total: 1000000, // Required for new assets + decimals: 0, // Required for new assets + defaultFrozen: false, // Optional: Defaults to False if not provided + unitName: algots.Bytes('UNIT'), // Optional: Defaults to empty string if not provided + assetName: algots.Bytes('Asset'), // Optional: Defaults to empty string if not provided + url: algots.Bytes('http://asset-url'), // Optional: Defaults to empty string if not provided + metadataHash: algots.Bytes('metadata_hash'), // Optional: Defaults to empty bytes if not provided + manager: ctx.any.account(), // Optional: Defaults to sender if not provided + reserve: ctx.any.account(), // Optional: Defaults to zero address if not provided + freeze: ctx.any.account(), // Optional: Defaults to zero address if not provided + clawback: ctx.any.account(), // Optional: Defaults to zero address if not provided +}) + +// Generate a random key registration transaction +const keyRegTxn = ctx.any.txn.keyRegistration({ + sender: ctx.any.account(), // Optional: Defaults to context's default sender if not provided + voteKey: algots.Bytes('vote_pk'), // Optional: Defaults to empty bytes if not provided + selectionKey: algots.Bytes('selection_pk'), // Optional: Defaults to empty bytes if not provided + voteFirst: 1, // Optional: Defaults to 0 if not provided + voteLast: 1000, // Optional: Defaults to 0 if not provided + voteKeyDilution: 10000, // Optional: Defaults to 0 if not provided +}) + +// Generate a random asset freeze transaction +const assetFreezeTxn = ctx.any.txn.assetFreeze({ + sender: ctx.any.account(), // Optional: Defaults to context's default sender if not provided + freezeAsset: ctx.ledger.getAsset(algots.Uint64(1)), // Required + freezeAccount: ctx.any.account(), // Required + frozen: true, // Required +}) +``` + +## Preparing for execution + +When a smart contract instance (application) is interacted with on the Algorand network, it must be performed in relation to a specific transaction or transaction group where one or many transactions are application calls to target smart contract instances. + +To emulate this behaviour, the `createScope` context manager is available on [`TransactionContext`](../code/subcontexts/transaction-context/classes/TransactionContext.md) instance that allows setting temporary transaction fields within a specific scope, passing in emulated transaction objects and identifying the active transaction index within the transaction group + +```ts +import { arc4, Txn } from '@algorandfoundation/algorand-typescript' +import { TestExecutionContext } from '@algorandfoundation/algorand-typescript-testing' + +class SimpleContract extends arc4.Contract { + @arc4.abimethod() + checkSender(): arc4.Address { + return new arc4.Address(Txn.sender) + } +} + +const ctx = new TestExecutionContext() + +// Create a contract instance +const contract = ctx.contract.create(SimpleContract) + +// Use active_txn_overrides to change the sender +const testSender = ctx.any.account() + +ctx.txn.createScope([ctx.any.txn.applicationCall({ appId: contract, sender: testSender })]).execute(() => { + // Call the contract method + const result = contract.checkSender() + expect(result).toEqual(testSender) +}) + +// Assert that the sender is the test_sender after exiting the +// transaction group context +expect(ctx.txn.lastActive.sender).toEqual(testSender) + +// Assert the size of last transaction group +expect(ctx.txn.lastGroup.transactions.length).toEqual(1) +``` + +## Inner Transaction + +Inner transactions are AVM transactions that are signed and executed by AVM applications (instances of deployed smart contracts or signatures). + +When testing smart contracts, to stay consistent with AVM, the framework \_does not allow you to submit inner transactions outside of contract/subroutine invocation, but you can interact with and manage inner transactions using the test execution context as follows: + +```ts +import { arc4, Asset, itxn, Txn, Uint64 } from '@algorandfoundation/algorand-typescript' +import { TestExecutionContext } from '@algorandfoundation/algorand-typescript-testing' + +class MyContract extends arc4.Contract { + @arc4.abimethod() + payViaItxn(asset: Asset) { + itxn + .payment({ + receiver: Txn.sender, + amount: 1, + }) + .submit() + } +} + +// setup context +const ctx = new TestExecutionContext() + +// Create a contract instance +const contract = ctx.contract.create(MyContract) + +// Generate a random asset +const asset = ctx.any.asset() + +// Execute the contract method +contract.payViaItxn(asset) + +// Access the last submitted inner transaction +const paymentTxn = ctx.txn.lastGroup.lastItxnGroup().getPaymentInnerTxn() + +// Assert properties of the inner transaction +expect(paymentTxn.receiver).toEqual(ctx.txn.lastActive.sender) +expect(paymentTxn.amount).toEqual(1) + +// Access all inner transactions in the last group +ctx.txn.lastGroup.itxnGroups.at(-1)?.itxns.forEach((itxn) => { + // Perform assertions on each inner transaction + expect(itxn.type).toEqual(TransactionType.Payment) +}) + +// Access a specific inner transaction group +const firstItxnGroup = ctx.txn.lastGroup.getItxnGroup(0) +const firstPaymentTxn = firstItxnGroup.getPaymentInnerTxn(0) +expect(firstPaymentTxn.type).toEqual(TransactionType.Payment) +``` + +In this example, we define a contract method `payViaItxn` that creates and submits an inner payment transaction. The test execution 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 `createScope` context manager because the method is decorated with `@arc4.abimethod`, which automatically creates a transaction group for the method. The `createScope` 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: + +1. Use `ctx.txn.lastGroup.lastItxnGroup().getPaymentInnerTxn()` to access the last submitted inner transaction of a specific type, in this case payment transaction. +2. Iterate over all inner transactions in the last group using `ctx.txn.lastGroup.itxnGroups.at(-1)?.itxns`. +3. Access a specific inner transaction group using `ctx.txn.lastGroup.getItxnGroup(index)`. + +These methods provide type validation and will raise an error if the requested transaction type doesn't match the actual type of the inner transaction. + +## References + +- [API](../api.md) for more details on the test context manager and inner transactions related methods that perform implicit inner transaction type validation. +- [Examples](../examples.md) for more examples of smart contracts and associated tests that interact with inner transactions. + +```ts +// test cleanup +ctx.reset() +``` diff --git a/eslint.config.mjs b/eslint.config.mjs index 4351651..6fdcfcf 100644 --- a/eslint.config.mjs +++ b/eslint.config.mjs @@ -1,8 +1,8 @@ +import { FlatCompat } from '@eslint/eslintrc' +import js from '@eslint/js' import globals from 'globals' import path from 'node:path' import { fileURLToPath } from 'node:url' -import js from '@eslint/js' -import { FlatCompat } from '@eslint/eslintrc' const __filename = fileURLToPath(import.meta.url) const __dirname = path.dirname(__filename) @@ -33,5 +33,8 @@ export default [ ...globals.node, }, }, + rules: { + '@typescript-eslint/consistent-type-imports': 'error', + }, }, ] diff --git a/examples/arc4-simple-voting/contract.algo.ts b/examples/arc4-simple-voting/contract.algo.ts new file mode 100644 index 0000000..5dd7587 --- /dev/null +++ b/examples/arc4-simple-voting/contract.algo.ts @@ -0,0 +1,36 @@ +import type { gtxn, uint64 } from '@algorandfoundation/algorand-typescript' +import { arc4, assert, Bytes, GlobalState, LocalState, op, Txn, Uint64 } from '@algorandfoundation/algorand-typescript' + +export default class VotingContract extends arc4.Contract { + topic = GlobalState({ initialValue: Bytes('default_topic'), key: Bytes('topic') }) + votes = GlobalState({ initialValue: Uint64(0), key: Bytes('votes') }) + voted = LocalState({ key: Bytes('voted') }) + + @arc4.abimethod() + public setTopic(topic: arc4.Str): void { + this.topic.value = topic.bytes + } + @arc4.abimethod() + public vote(pay: gtxn.PaymentTxn): arc4.Bool { + assert(op.Global.groupSize === 2, 'Expected 2 transactions') + assert(pay.amount === 10_000, 'Incorrect payment amount') + assert(pay.sender === Txn.sender, 'Payment sender must match transaction sender') + + if (this.voted(Txn.sender).hasValue) { + return new arc4.Bool(false) // Already voted + } + + this.votes.value = this.votes.value + 1 + this.voted(Txn.sender).value = 1 + return new arc4.Bool(true) + } + + @arc4.abimethod({ readonly: true }) + public getVotes(): arc4.UintN64 { + return new arc4.UintN64(this.votes.value) + } + + public clearStateProgram(): boolean { + return true + } +} diff --git a/examples/arc4-simple-voting/contract.spec.ts b/examples/arc4-simple-voting/contract.spec.ts new file mode 100644 index 0000000..a7381fe --- /dev/null +++ b/examples/arc4-simple-voting/contract.spec.ts @@ -0,0 +1,45 @@ +import { Uint64 } from '@algorandfoundation/algorand-typescript' +import { TestExecutionContext } from '@algorandfoundation/algorand-typescript-testing' +import { afterEach, describe, expect, test } from 'vitest' +import VotingContract from './contract.algo' + +describe('Voting contract', () => { + const ctx = new TestExecutionContext() + afterEach(() => { + ctx.reset() + }) + + test('vote function', () => { + // Initialize the contract within the testing context + const contract = ctx.contract.create(VotingContract) + + const voter = ctx.defaultSender + const payment = ctx.any.txn.payment({ + sender: voter, + amount: 10_000, + }) + + const result = contract.vote(payment) + expect(result.native).toEqual(true) + expect(contract.votes.value).toEqual(1) + expect(contract.voted(voter).value).toEqual(1) + }) + + test('setTopic function', () => { + // Initialize the contract within the testing context + const contract = ctx.contract.create(VotingContract) + + const newTopic = ctx.any.arc4.str(10) + contract.setTopic(newTopic) + expect(contract.topic.value).toEqual(newTopic.bytes) + }) + + test('getVotes function', () => { + // Initialize the contract within the testing context + const contract = ctx.contract.create(VotingContract) + + contract.votes.value = Uint64(5) + const votes = contract.getVotes() + expect(votes.native).toEqual(5) + }) +}) diff --git a/examples/calculator/contract.algo.ts b/examples/calculator/contract.algo.ts index 421937d..c041163 100644 --- a/examples/calculator/contract.algo.ts +++ b/examples/calculator/contract.algo.ts @@ -1,4 +1,5 @@ -import { assert, BaseContract, Bytes, err, log, op, Txn, uint64, Uint64 } from '@algorandfoundation/algorand-typescript' +import type { uint64 } from '@algorandfoundation/algorand-typescript' +import { assert, BaseContract, Bytes, err, log, op, Txn, Uint64 } from '@algorandfoundation/algorand-typescript' const ADD = Uint64(1) const SUB = Uint64(2) diff --git a/examples/calculator/contract.spec.ts b/examples/calculator/contract.spec.ts index 61b1721..9e3f4c7 100644 --- a/examples/calculator/contract.spec.ts +++ b/examples/calculator/contract.spec.ts @@ -1,5 +1,5 @@ -import { internal, Uint64 } from '@algorandfoundation/algorand-typescript' -import { TestExecutionContext } from '@algorandfoundation/algorand-typescript-testing' +import { Uint64 } from '@algorandfoundation/algorand-typescript' +import { AvmError, TestExecutionContext } from '@algorandfoundation/algorand-typescript-testing' import { afterEach, describe, expect, it } from 'vitest' import MyContract from './contract.algo' @@ -14,12 +14,12 @@ describe('Calculator', () => { ctx.txn .createScope([ ctx.any.txn.applicationCall({ - appId: ctx.ledger.getApplicationForContract(contract), + appId: contract, appArgs: [], }), ]) .execute(() => { - expect(() => contract.approvalProgram()).toThrowError(new internal.errors.AvmError('Unknown operation')) + expect(() => contract.approvalProgram()).toThrowError(new AvmError('Unknown operation')) }) }) }) diff --git a/examples/htlc-logicsig/signature.algo.ts b/examples/htlc-logicsig/signature.algo.ts index 8c83506..b7ed21d 100644 --- a/examples/htlc-logicsig/signature.algo.ts +++ b/examples/htlc-logicsig/signature.algo.ts @@ -1,7 +1,7 @@ -import { Account, Bytes, Global, LogicSig, op, TransactionType, Txn, Uint64, uint64 } from '@algorandfoundation/algorand-typescript' +import { Account, Bytes, Global, LogicSig, op, TransactionType, Txn, Uint64 } from '@algorandfoundation/algorand-typescript' export default class HashedTimeLockedLogicSig extends LogicSig { - program(): boolean | uint64 { + program(): boolean { // Participants const sellerAddress = Bytes.fromBase32('6ZHGHH5Z5CTPCF5WCESXMGRSVK7QJETR63M3NY5FJCUYDHO57VTC') const buyerAddress = Bytes.fromBase32('7Z5PWO2C6LFNQFGHWKSK5H47IQP5OJW2M3HA2QPXTY3WTNP5NU2M') diff --git a/examples/local-storage/contract.algo.ts b/examples/local-storage/contract.algo.ts new file mode 100644 index 0000000..285c4b5 --- /dev/null +++ b/examples/local-storage/contract.algo.ts @@ -0,0 +1,163 @@ +import type { Account, bytes, uint64 } from '@algorandfoundation/algorand-typescript' +import { Bytes, Global, LocalState, Txn, arc4, assert, contract } from '@algorandfoundation/algorand-typescript' + +/** + * A contract demonstrating local storage functionality. + * This contract shows how to use local state storage in an Algorand smart contract, + * including initialization, reading, writing, and clearing of local state values. + * Local state is per-account storage that requires accounts to opt-in before use. + * + * @stateTotals.localBytes - 4 bytes allocated for local byte storage + * @stateTotals.localUints - 3 uints allocated for local integer storage + */ +@contract({ stateTotals: { localBytes: 4, localUints: 3 } }) +export default class LocalStorage extends arc4.Contract { + // example: INIT_LOCAL_STATE + public localInt = LocalState({ key: 'int' }) + public localIntNoDefault = LocalState() + public localBytes = LocalState() + public localString = LocalState() + public localBool = LocalState() + public localAccount = LocalState() + // example: INIT_LOCAL_STATE + + // example: OPT_IN_TO_APPLICATION + /** + * Initializes local state values when an account opts into the application. + * This method can only be called during an OptIn transaction. + * Sets initial values for all local state variables: + * - localInt: 100 + * - localIntNoDefault: 200 + * - localBytes: 'Silvio' + * - localString: 'Micali' + * - localBool: true + * - localAccount: sender's address + */ + @arc4.abimethod({ allowActions: 'OptIn' }) + public optInToApplication(): void { + this.localInt(Txn.sender).value = 100 + this.localIntNoDefault(Txn.sender).value = 200 + this.localBytes(Txn.sender).value = Bytes('Silvio') + this.localString(Txn.sender).value = 'Micali' + this.localBool(Txn.sender).value = true + this.localAccount(Txn.sender).value = Txn.sender + } + // example: OPT_IN_TO_APPLICATION + + // example: READ_LOCAL_STATE + /** + * Reads and returns all local state values for the transaction sender. + * @returns A tuple containing: + * - [0] uint64: The value of localInt + * - [1] uint64: The value of localIntNoDefault + * - [2] bytes: The value of localBytes + * - [3] string: The value of localString + * - [4] boolean: The value of localBool + * - [5] Address: The value of localAccount converted to Address type + */ + @arc4.abimethod({ readonly: true }) + public readLocalState(): [uint64, uint64, bytes, string, boolean, arc4.Address] { + const sender = Txn.sender + // Convert Account reference type to native Address type for return value + const accountAddress = new arc4.Address(this.localAccount(sender).value) + + return [ + this.localInt(sender).value, + this.localIntNoDefault(sender).value, + this.localBytes(sender).value, + this.localString(sender).value, + this.localBool(sender).value, + accountAddress, + ] + } + // example: READ_LOCAL_STATE + + // example: WRITE_LOCAL_STATE + /** + * Updates multiple local state values for the transaction sender. + * Requires the account to be opted into the application. + * @param valueString - New string value to store + * @param valueBool - New boolean value to store + * @param valueAccount - New account address to store + */ + @arc4.abimethod() + public writeLocalState(valueString: string, valueBool: boolean, valueAccount: Account): void { + // Dynamic keys must be explicitly reserved in the contract's stateTotals configuration + const sender = Txn.sender + + assert(sender.isOptedIn(Global.currentApplicationId), 'Account must opt in to contract first') + + this.localString(sender).value = valueString + this.localBool(sender).value = valueBool + this.localAccount(sender).value = valueAccount + + assert(this.localString(sender).value === valueString) + assert(this.localBool(sender).value === valueBool) + assert(this.localAccount(sender).value === valueAccount) + } + // example: WRITE_LOCAL_STATE + + // example: WRITE_DYNAMIC_LOCAL_STATE + /** + * Writes a value to local state using a dynamic key. + * Demonstrates dynamic key-value storage in local state. + * @param key - The dynamic key to store the value under + * @param value - The string value to store + * @returns The stored string value + */ + @arc4.abimethod() + public writeDynamicLocalState(key: string, value: string): string { + const sender = Txn.sender + + assert(sender.isOptedIn(Global.currentApplicationId), 'Account must opt in to contract first') + + const localDynamicAccess = LocalState({ key }) + + localDynamicAccess(sender).value = value + + assert(localDynamicAccess(sender).value === value) + + return localDynamicAccess(sender).value + } + // example: WRITE_DYNAMIC_LOCAL_STATE + + // example: READ_DYNAMIC_LOCAL_STATE + /** + * Reads a value from local state using a dynamic key. + * @param key - The dynamic key to read the value from + * @returns The stored string value for the given key + */ + @arc4.abimethod() + public readDynamicLocalState(key: string): string { + const sender = Txn.sender + + assert(sender.isOptedIn(Global.currentApplicationId), 'Account must opt in to contract first') + + const localDynamicAccess = LocalState({ key }) + + assert(localDynamicAccess(sender).hasValue, 'Key not found') + + return localDynamicAccess(sender).value + } + // example: READ_DYNAMIC_LOCAL_STATE + + // example: CLEAR_LOCAL_STATE + /** + * Clears all local state values for the transaction sender. + * After calling this method, all local state values will be deleted. + */ + @arc4.abimethod() + public clearLocalState(): void { + const sender = Txn.sender + + assert(sender.isOptedIn(Global.currentApplicationId), 'Account must opt in to contract first') + + this.localInt(sender).delete() + this.localIntNoDefault(sender).delete() + this.localBytes(sender).delete() + this.localString(sender).delete() + this.localBool(sender).delete() + this.localAccount(sender).delete() + } + // example: CLEAR_LOCAL_STATE +} diff --git a/examples/local-storage/contract.spec.ts b/examples/local-storage/contract.spec.ts new file mode 100644 index 0000000..74f3166 --- /dev/null +++ b/examples/local-storage/contract.spec.ts @@ -0,0 +1,95 @@ +import { Bytes } from '@algorandfoundation/algorand-typescript' +import { TestExecutionContext } from '@algorandfoundation/algorand-typescript-testing' +import { describe, expect, it } from 'vitest' +import LocalStorage from './contract.algo' + +describe('LocalStorage contract', () => { + const ctx = new TestExecutionContext() + + it('should initialize local state with correct values after opting in', () => { + const contract = ctx.contract.create(LocalStorage) + + contract.optInToApplication() + + const [localInt, localIntNoDefault, localBytes, localString, localBool, localAddress] = contract.readLocalState() + + expect(localInt.valueOf()).toBe(100) + expect(localIntNoDefault.valueOf()).toBe(200) + expect(localBytes.toString()).toBe(Bytes('Silvio').toString()) + expect(localString).toBe('Micali') + expect(localBool).toBe(true) + expect(localAddress.bytes.toString()).toBe(ctx.defaultSender.bytes.toString()) + }) + + it('should write and verify multiple local state values', () => { + const contract = ctx.contract.create(LocalStorage) + const account = ctx.any.account({ optedApplications: [ctx.ledger.getApplicationForContract(contract)] }) + + ctx.txn.createScope([ctx.any.txn.applicationCall({ appId: contract, sender: account, onCompletion: 'OptIn' })]).execute(() => { + contract.optInToApplication() + }) + + ctx.txn.createScope([ctx.any.txn.applicationCall({ appId: contract, sender: account })]).execute(() => { + contract.writeLocalState('New String', false, account) + + const [, , , localString, localBool, localAccount] = contract.readLocalState() + + expect(localString).toBe('New String') + expect(localBool).toBe(false) + expect(localAccount.bytes).toEqual(account.bytes) + }) + }) + + it('should write and read dynamic local state values', () => { + const contract = ctx.contract.create(LocalStorage) + const account = ctx.any.account({ optedApplications: [ctx.ledger.getApplicationForContract(contract)] }) + + ctx.txn.createScope([ctx.any.txn.applicationCall({ appId: contract, sender: account, onCompletion: 'OptIn' })]).execute(() => { + contract.optInToApplication() + }) + + ctx.txn.createScope([ctx.any.txn.applicationCall({ appId: contract, sender: account })]).execute(() => { + const testKey = 'testKey' + const testValue = 'testValue' + + const writtenValue = contract.writeDynamicLocalState(testKey, testValue) + expect(writtenValue).toBe(testValue) + + const readValue = contract.readDynamicLocalState(testKey) + expect(readValue).toBe(testValue) + }) + }) + + it('should clear all local state values', () => { + const contract = ctx.contract.create(LocalStorage) + const account = ctx.any.account({ optedApplications: [ctx.ledger.getApplicationForContract(contract)] }) + ctx.txn.createScope([ctx.any.txn.applicationCall({ appId: contract, sender: account, onCompletion: 'OptIn' })]).execute(() => { + contract.optInToApplication() + }) + + ctx.txn.createScope([ctx.any.txn.applicationCall({ appId: contract, sender: account })]).execute(() => { + contract.clearLocalState() + + expect(() => contract.readLocalState()).toThrow() + }) + }) + + it('should fail to write local state if not opted in', () => { + const contract = ctx.contract.create(LocalStorage) + const newAccount = ctx.defaultSender + + expect(() => contract.writeLocalState('New String', false, newAccount)).toThrow('Account must opt in to contract first') + }) + + it('should fail to read dynamic local state for non-existent key', () => { + const contract = ctx.contract.create(LocalStorage) + const account = ctx.any.account({ optedApplications: [ctx.ledger.getApplicationForContract(contract)] }) + ctx.txn.createScope([ctx.any.txn.applicationCall({ appId: contract, sender: account, onCompletion: 'OptIn' })]).execute(() => { + contract.optInToApplication() + }) + + ctx.txn.createScope([ctx.any.txn.applicationCall({ appId: contract, sender: account })]).execute(() => { + expect(() => contract.readDynamicLocalState('nonexistentKey')).toThrow('Key not found') + }) + }) +}) diff --git a/examples/marketplace/contract.algo.ts b/examples/marketplace/contract.algo.ts new file mode 100644 index 0000000..2799e2d --- /dev/null +++ b/examples/marketplace/contract.algo.ts @@ -0,0 +1,259 @@ +import type { Asset, gtxn, uint64 } from '@algorandfoundation/algorand-typescript' +import { arc4, assert, BoxMap, Global, itxn, op, Txn } from '@algorandfoundation/algorand-typescript' + +export class ListingKey extends arc4.Struct<{ + owner: arc4.Address + asset: arc4.UintN64 + nonce: arc4.UintN64 +}> {} + +export class ListingValue extends arc4.Struct<{ + deposited: arc4.UintN64 + unitaryPrice: arc4.UintN64 + bidder: arc4.Address + bid: arc4.UintN64 + bidUnitaryPrice: arc4.UintN64 +}> {} + +export default class DigitalMarketplace extends arc4.Contract { + listings = BoxMap({ keyPrefix: 'listings' }) + + listingsBoxMbr(): uint64 { + return ( + 2_500 + + // fmt: off + // Key length + (8 + + 32 + + 8 + + 8 + + // Value length + 8 + + 8 + + 32 + + 8 + + 8) * + // fmt: on + 400 + ) + } + + quantityPrice(quantity: uint64, price: uint64, assetDecimals: uint64): uint64 { + const [amountNotScaledHigh, amountNotScaledLow] = op.mulw(price, quantity) + const [scalingFactorHigh, scalingFactorLow] = op.expw(10, assetDecimals) + const [_quotientHigh, amountToBePaid, _remainderHigh, _remainderLow] = op.divmodw( + amountNotScaledHigh, + amountNotScaledLow, + scalingFactorHigh, + scalingFactorLow, + ) + assert(_quotientHigh === 0) + + return amountToBePaid + } + + @arc4.abimethod({ readonly: true }) + getListingsMbr(): uint64 { + return this.listingsBoxMbr() + } + + @arc4.abimethod() + allowAsset(mbrPay: gtxn.PaymentTxn, asset: Asset) { + assert(!Global.currentApplicationAddress.isOptedIn(asset)) + + assert(mbrPay.receiver === Global.currentApplicationAddress) + assert(mbrPay.amount === Global.assetOptInMinBalance) + + itxn + .assetTransfer({ + xferAsset: asset, + assetReceiver: Global.currentApplicationAddress, + assetAmount: 0, + }) + .submit() + } + + @arc4.abimethod() + firstDeposit(mbrPay: gtxn.PaymentTxn, xfer: gtxn.AssetTransferTxn, unitaryPrice: arc4.UintN64, nonce: arc4.UintN64) { + assert(mbrPay.sender === Txn.sender) + assert(mbrPay.receiver === Global.currentApplicationAddress) + assert(mbrPay.amount === this.listingsBoxMbr()) + + const key = new ListingKey({ + owner: new arc4.Address(Txn.sender), + asset: new arc4.UintN64(xfer.xferAsset.id), + nonce: nonce, + }) + assert(!this.listings(key).exists) + + assert(xfer.sender === Txn.sender) + assert(xfer.assetReceiver === Global.currentApplicationAddress) + assert(xfer.assetAmount > 0) + + this.listings(key).value = new ListingValue({ + deposited: new arc4.UintN64(xfer.assetAmount), + unitaryPrice: unitaryPrice, + bidder: new arc4.Address(), + bid: new arc4.UintN64(), + bidUnitaryPrice: new arc4.UintN64(), + }) + } + + @arc4.abimethod() + deposit(xfer: gtxn.AssetTransferTxn, nonce: arc4.UintN64) { + const key = new ListingKey({ + owner: new arc4.Address(Txn.sender), + asset: new arc4.UintN64(xfer.xferAsset.id), + nonce: nonce, + }) + + assert(xfer.sender === Txn.sender) + assert(xfer.assetReceiver === Global.currentApplicationAddress) + assert(xfer.assetAmount > 0) + + const existing = this.listings(key).value.copy() + this.listings(key).value = new ListingValue({ + bid: existing.bid, + bidUnitaryPrice: existing.bidUnitaryPrice, + bidder: existing.bidder, + unitaryPrice: existing.unitaryPrice, + deposited: new arc4.UintN64(existing.deposited.native + xfer.assetAmount), + }) + } + + @arc4.abimethod() + setPrice(asset: Asset, nonce: arc4.UintN64, unitaryPrice: arc4.UintN64) { + const key = new ListingKey({ + owner: new arc4.Address(Txn.sender), + asset: new arc4.UintN64(asset.id), + nonce: nonce, + }) + + const existing = this.listings(key).value.copy() + this.listings(key).value = new ListingValue({ + bid: existing.bid, + bidUnitaryPrice: existing.bidUnitaryPrice, + bidder: existing.bidder, + deposited: existing.deposited, + unitaryPrice: unitaryPrice, + }) + } + + @arc4.abimethod() + buy(owner: arc4.Address, asset: Asset, nonce: arc4.UintN64, buyPay: gtxn.PaymentTxn, quantity: uint64) { + const key = new ListingKey({ + owner: owner, + asset: new arc4.UintN64(asset.id), + nonce: nonce, + }) + + const listing = this.listings(key).value.copy() + + const amountToBePaid = this.quantityPrice(quantity, listing.unitaryPrice.native, asset.decimals) + + assert(buyPay.sender === Txn.sender) + assert(buyPay.receiver.bytes === owner.bytes) + assert(buyPay.amount === amountToBePaid) + + this.listings(key).value = new ListingValue({ + bid: listing.bid, + bidUnitaryPrice: listing.bidUnitaryPrice, + bidder: listing.bidder, + unitaryPrice: listing.unitaryPrice, + deposited: new arc4.UintN64(listing.deposited.native - quantity), + }) + + itxn + .assetTransfer({ + xferAsset: asset, + assetReceiver: Txn.sender, + assetAmount: quantity, + }) + .submit() + } + + @arc4.abimethod() + withdraw(asset: Asset, nonce: arc4.UintN64) { + const key = new ListingKey({ + owner: new arc4.Address(Txn.sender), + asset: new arc4.UintN64(asset.id), + nonce: nonce, + }) + + const listing = this.listings(key).value.copy() + if (listing.bidder !== new arc4.Address()) { + const currentBidDeposit = this.quantityPrice(listing.bid.native, listing.bidUnitaryPrice.native, asset.decimals) + itxn.payment({ receiver: listing.bidder.native, amount: currentBidDeposit }).submit() + } + + this.listings(key).delete() + + itxn.payment({ receiver: Txn.sender, amount: this.listingsBoxMbr() }).submit() + + itxn + .assetTransfer({ + xferAsset: asset, + assetReceiver: Txn.sender, + assetAmount: listing.deposited.native, + }) + .submit() + } + + @arc4.abimethod() + bid(owner: arc4.Address, asset: Asset, nonce: arc4.UintN64, bidPay: gtxn.PaymentTxn, quantity: arc4.UintN64, unitaryPrice: arc4.UintN64) { + const key = new ListingKey({ owner, asset: new arc4.UintN64(asset.id), nonce }) + + const listing = this.listings(key).value.copy() + if (listing.bidder !== new arc4.Address()) { + assert(unitaryPrice.native > listing.bidUnitaryPrice.native) + + const currentBidAmount = this.quantityPrice(listing.bid.native, listing.bidUnitaryPrice.native, asset.decimals) + + itxn.payment({ receiver: listing.bidder.native, amount: currentBidAmount }).submit() + } + + const amountToBeBid = this.quantityPrice(quantity.native, unitaryPrice.native, asset.decimals) + + assert(bidPay.sender === Txn.sender) + assert(bidPay.receiver === Global.currentApplicationAddress) + assert(bidPay.amount === amountToBeBid) + + this.listings(key).value = new ListingValue({ + deposited: listing.deposited, + unitaryPrice: listing.unitaryPrice, + bidder: new arc4.Address(Txn.sender), + bid: quantity, + bidUnitaryPrice: unitaryPrice, + }) + } + + @arc4.abimethod() + acceptBid(asset: Asset, nonce: arc4.UintN64) { + const key = new ListingKey({ owner: new arc4.Address(Txn.sender), asset: new arc4.UintN64(asset.id), nonce }) + + const listing = this.listings(key).value.copy() + assert(listing.bidder !== new arc4.Address()) + + const minQuantity = listing.deposited.native < listing.bid.native ? listing.deposited.native : listing.bid.native + + const bestBidAmount = this.quantityPrice(minQuantity, listing.bidUnitaryPrice.native, asset.decimals) + + itxn.payment({ receiver: Txn.sender, amount: bestBidAmount }).submit() + + itxn + .assetTransfer({ + xferAsset: asset, + assetReceiver: listing.bidder.native, + assetAmount: minQuantity, + }) + .submit() + + this.listings(key).value = new ListingValue({ + bidder: listing.bidder, + bidUnitaryPrice: listing.bidUnitaryPrice, + unitaryPrice: listing.unitaryPrice, + deposited: new arc4.UintN64(listing.deposited.native - minQuantity), + bid: new arc4.UintN64(listing.bid.native - minQuantity), + }) + } +} diff --git a/examples/marketplace/contract.spec.ts b/examples/marketplace/contract.spec.ts new file mode 100644 index 0000000..8bd1434 --- /dev/null +++ b/examples/marketplace/contract.spec.ts @@ -0,0 +1,275 @@ +import { arc4, Bytes } from '@algorandfoundation/algorand-typescript' +import { TestExecutionContext } from '@algorandfoundation/algorand-typescript-testing' +import { interpretAsArc4 } from '@algorandfoundation/algorand-typescript/arc4' +import { afterEach, describe, expect, test } from 'vitest' +import DigitalMarketplace, { ListingKey, ListingValue } from './contract.algo' + +const TEST_DECIMALS = 6 + +describe('DigitalMarketplace', () => { + const ctx = new TestExecutionContext() + + afterEach(() => { + ctx.reset() + }) + + test('first deposit', () => { + const contract = ctx.contract.create(DigitalMarketplace) + const testAsset = ctx.any.asset({ decimals: TEST_DECIMALS }) + const testNonce = ctx.any.arc4.uintN64() + + // Arrange + const testApp = ctx.ledger.getApplicationForContract(contract) + + // Act + contract.firstDeposit( + ctx.any.txn.payment({ receiver: testApp.address, amount: 50500 }), + ctx.any.txn.assetTransfer({ + xferAsset: testAsset, + assetReceiver: testApp.address, + assetAmount: 10, + }), + ctx.any.arc4.uintN64(), + testNonce, + ) + + // Assert + const listingKey = new ListingKey({ + owner: new arc4.Address(ctx.defaultSender), + asset: new arc4.UintN64(testAsset.id), + nonce: testNonce, + }) + const listingValue = interpretAsArc4(Bytes(ctx.ledger.getBox(contract, Bytes('listings').concat(listingKey.bytes)))) + expect(listingValue.deposited.native).toEqual(10) + }) + + test('deposit', () => { + const contract = ctx.contract.create(DigitalMarketplace) + const testAsset = ctx.any.asset({ decimals: TEST_DECIMALS }) + const testNonce = ctx.any.arc4.uintN64() + + // Arrange + const testApp = ctx.ledger.getApplicationForContract(contract) + const listingKey = new ListingKey({ + owner: new arc4.Address(ctx.defaultSender), + asset: new arc4.UintN64(testAsset.id), + nonce: testNonce, + }) + contract.listings(listingKey).value = new ListingValue({ + deposited: new arc4.UintN64(10), + unitaryPrice: new arc4.UintN64(10), + bidder: new arc4.Address(ctx.defaultSender), + bid: new arc4.UintN64(10), + bidUnitaryPrice: new arc4.UintN64(10), + }) + + // Act + contract.deposit( + ctx.any.txn.assetTransfer({ + xferAsset: testAsset, + assetReceiver: testApp.address, + assetAmount: 10, + }), + testNonce, + ) + + // Assert + expect(ctx.ledger.boxExists(contract, Bytes('listings').concat(listingKey.bytes))) + }) + + test('setPrice', () => { + const contract = ctx.contract.create(DigitalMarketplace) + const testAsset = ctx.any.asset({ decimals: TEST_DECIMALS }) + const testNonce = ctx.any.arc4.uintN64() + // Arrange + const testUnitaryPrice = ctx.any.arc4.uintN64() + const listingKey = new ListingKey({ + owner: new arc4.Address(ctx.defaultSender), + asset: new arc4.UintN64(testAsset.id), + nonce: testNonce, + }) + contract.listings(listingKey).value = new ListingValue({ + deposited: new arc4.UintN64(10), + unitaryPrice: new arc4.UintN64(10), + bidder: new arc4.Address(ctx.defaultSender), + bid: new arc4.UintN64(10), + bidUnitaryPrice: new arc4.UintN64(10), + }) + + // Act + contract.setPrice(testAsset, testNonce, testUnitaryPrice) + + // Assert + const updatedListing = interpretAsArc4(Bytes(ctx.ledger.getBox(contract, Bytes('listings').concat(listingKey.bytes)))) + expect(updatedListing.unitaryPrice.native).toEqual(testUnitaryPrice.native) + }) + + test('buy', () => { + const contract = ctx.contract.create(DigitalMarketplace) + const testAsset = ctx.any.asset({ decimals: TEST_DECIMALS }) + const testNonce = ctx.any.arc4.uintN64() + // Arrange + const testOwner = new arc4.Address(ctx.defaultSender) + const testUnitaryPrice = ctx.any.arc4.uintN64(0, 10000000n) + const initialDeposit = ctx.any.arc4.uintN64() + const testBuyQuantity = ctx.any.arc4.uintN64(0, 1000000n) + + const listingKey = new ListingKey({ owner: testOwner, asset: new arc4.UintN64(testAsset.id), nonce: testNonce }) + contract.listings(listingKey).value = new ListingValue({ + deposited: initialDeposit, + unitaryPrice: testUnitaryPrice, + bidder: new arc4.Address(), + bid: new arc4.UintN64(0), + bidUnitaryPrice: new arc4.UintN64(0), + }) + + // Act + contract.buy( + testOwner, + testAsset, + testNonce, + ctx.any.txn.payment({ + receiver: ctx.defaultSender, + amount: contract.quantityPrice(testBuyQuantity.native, testUnitaryPrice.native, testAsset.decimals), + }), + testBuyQuantity.native, + ) + + // Assert + const updatedListing = interpretAsArc4(Bytes(ctx.ledger.getBox(contract, Bytes('listings').concat(listingKey.bytes)))) + expect(updatedListing.deposited.native).toEqual(initialDeposit.native - testBuyQuantity.native) + expect(ctx.txn.lastGroup.getItxnGroup(0).getAssetTransferInnerTxn(0).assetReceiver).toEqual(ctx.defaultSender) + }) + + test('withdraw', () => { + const contract = ctx.contract.create(DigitalMarketplace) + const testAsset = ctx.any.asset({ decimals: TEST_DECIMALS }) + const testNonce = ctx.any.arc4.uintN64() + + // Arrange + const testOwner = new arc4.Address(ctx.defaultSender) + const initialDeposit = ctx.any.arc4.uintN64(1) + const testUnitaryPrice = ctx.any.arc4.uintN64() + + const listingsBoxMbr = contract.listingsBoxMbr() + + const listingKey = new ListingKey({ owner: testOwner, asset: new arc4.UintN64(testAsset.id), nonce: testNonce }) + contract.listings(listingKey).value = new ListingValue({ + deposited: initialDeposit, + unitaryPrice: testUnitaryPrice, + bidder: new arc4.Address(), + bid: new arc4.UintN64(0), + bidUnitaryPrice: new arc4.UintN64(0), + }) + + // Act + contract.withdraw(testAsset, testNonce) + + // Assert + expect(ctx.ledger.boxExists(contract, Bytes('listings').concat(listingKey.bytes))).toEqual(false) + expect(ctx.txn.lastGroup.itxnGroups.length).toEqual(2) + + const paymentTxn = ctx.txn.lastGroup.getItxnGroup(0).getPaymentInnerTxn(0) + expect(paymentTxn.receiver).toEqual(testOwner.native) + expect(paymentTxn.amount).toEqual(listingsBoxMbr) + + const assetTransferTxn = ctx.txn.lastGroup.getItxnGroup(1).getAssetTransferInnerTxn(0) + expect(assetTransferTxn.xferAsset).toEqual(testAsset) + expect(assetTransferTxn.assetReceiver).toEqual(testOwner.native) + expect(assetTransferTxn.assetAmount).toEqual(initialDeposit.native) + }) + + test('bid', () => { + const contract = ctx.contract.create(DigitalMarketplace) + const testAsset = ctx.any.asset({ decimals: TEST_DECIMALS }) + const testNonce = ctx.any.arc4.uintN64() + + // Arrange + const app = ctx.ledger.getApplicationForContract(contract) + const owner = new arc4.Address(ctx.defaultSender) + const initialPrice = ctx.any.arc4.uintN64(0, 10000000n) + const initialDeposit = ctx.any.arc4.uintN64(0, 1000000n) + + const listingKey = new ListingKey({ owner, asset: new arc4.UintN64(testAsset.id), nonce: testNonce }) + contract.listings(listingKey).value = new ListingValue({ + deposited: initialDeposit, + unitaryPrice: initialPrice, + bidder: new arc4.Address(), + bid: new arc4.UintN64(0), + bidUnitaryPrice: new arc4.UintN64(0), + }) + + const bidder = ctx.any.account() + const bidQuantity = ctx.any.arc4.uintN64(0, BigInt(initialDeposit.native)) + const bidPrice = ctx.any.arc4.uintN64(initialPrice.native + 1, 10000000n) + const bidAmount = contract.quantityPrice(bidQuantity.native, bidPrice.native, testAsset.decimals) + + // Act + ctx.txn.createScope([ctx.any.txn.applicationCall({ appId: app, sender: bidder })]).execute(() => { + contract.bid( + owner, + testAsset, + testNonce, + ctx.any.txn.payment({ + sender: bidder, + receiver: app.address, + amount: bidAmount, + }), + bidQuantity, + bidPrice, + ) + }) + + // Assert + const updatedListing = contract.listings(listingKey).value + expect(updatedListing.bidder.native).toEqual(bidder) + expect(updatedListing.bid.native).toEqual(bidQuantity.native) + expect(updatedListing.bidUnitaryPrice.native).toEqual(bidPrice.native) + }) + + test('acceptBid', () => { + const contract = ctx.contract.create(DigitalMarketplace) + const testAsset = ctx.any.asset({ decimals: TEST_DECIMALS }) + const testNonce = ctx.any.arc4.uintN64() + // Arrange + const owner = ctx.defaultSender + const initialDeposit = ctx.any.arc4.uintN64(1, 10000000n) + const bidQuantity = ctx.any.arc4.uintN64(0, BigInt(initialDeposit.native)) + const bidPrice = ctx.any.arc4.uintN64(0, 10000000n) + const bidder = ctx.any.account() + + const listingKey = new ListingKey({ + owner: new arc4.Address(owner), + asset: new arc4.UintN64(testAsset.id), + nonce: testNonce, + }) + contract.listings(listingKey).value = new ListingValue({ + deposited: initialDeposit, + unitaryPrice: ctx.any.arc4.uintN64(), + bidder: new arc4.Address(bidder), + bid: bidQuantity, + bidUnitaryPrice: bidPrice, + }) + + const minQuantity = initialDeposit.native < bidQuantity.native ? initialDeposit.native : bidQuantity.native + const expectedPayment = contract.quantityPrice(minQuantity, bidPrice.native, testAsset.decimals) + + // Act + contract.acceptBid(testAsset, testNonce) + + // Assert + const updatedListing = contract.listings(listingKey).value + expect(updatedListing.deposited.native).toEqual(initialDeposit.native - minQuantity) + + expect(ctx.txn.lastGroup.itxnGroups.length).toEqual(2) + + const paymentTxn = ctx.txn.lastGroup.getItxnGroup(0).getPaymentInnerTxn(0) + expect(paymentTxn.receiver).toEqual(owner) + expect(paymentTxn.amount).toEqual(expectedPayment) + + const assetTransferTxn = ctx.txn.lastGroup.getItxnGroup(1).getAssetTransferInnerTxn(0) + expect(assetTransferTxn.xferAsset).toEqual(testAsset) + expect(assetTransferTxn.assetReceiver).toEqual(bidder) + expect(assetTransferTxn.assetAmount).toEqual(minQuantity) + }) +}) diff --git a/examples/precompiled/contract.algo.ts b/examples/precompiled/contract.algo.ts index abce1ec..f766ab1 100644 --- a/examples/precompiled/contract.algo.ts +++ b/examples/precompiled/contract.algo.ts @@ -1,15 +1,14 @@ import type { bytes, uint64 } from '@algorandfoundation/algorand-typescript' -import { assert, compile, Contract, itxn } from '@algorandfoundation/algorand-typescript' -import { decodeArc4, encodeArc4, methodSelector, OnCompleteAction } from '@algorandfoundation/algorand-typescript/arc4' +import { assert, compile, Contract, itxn, OnCompleteAction } from '@algorandfoundation/algorand-typescript' +import { decodeArc4, encodeArc4, methodSelector } from '@algorandfoundation/algorand-typescript/arc4' import { Hello, HelloTemplate, HelloTemplateCustomPrefix, LargeProgram, TerribleCustodialAccount } from './precompiled-apps.algo' export class HelloFactory extends Contract { test_compile_contract() { const compiled = compile(Hello) - const helloApp = itxn .applicationCall({ - appArgs: [methodSelector('create(string)void'), encodeArc4('hello')], + appArgs: [methodSelector(Hello.prototype.create), encodeArc4('hello')], approvalProgram: compiled.approvalProgram, clearStateProgram: compiled.clearStateProgram, globalNumBytes: 1, @@ -18,7 +17,7 @@ export class HelloFactory extends Contract { const txn = itxn .applicationCall({ - appArgs: [methodSelector('greet(string)string'), encodeArc4('world')], + appArgs: [methodSelector(Hello.prototype.greet), encodeArc4('world')], appId: helloApp, }) .submit() @@ -29,7 +28,7 @@ export class HelloFactory extends Contract { itxn .applicationCall({ appId: helloApp, - appArgs: [methodSelector('delete()void')], + appArgs: [methodSelector(Hello.prototype.delete)], onCompletion: OnCompleteAction.DeleteApplication, }) .submit() diff --git a/examples/precompiled/precompiled-apps.algo.ts b/examples/precompiled/precompiled-apps.algo.ts index bdec103..8f06158 100644 --- a/examples/precompiled/precompiled-apps.algo.ts +++ b/examples/precompiled/precompiled-apps.algo.ts @@ -15,7 +15,7 @@ abstract class HelloBase extends Contract { } export class Hello extends HelloBase { - @abimethod({ onCreate: 'require' }) + @abimethod({ name: 'helloCreate', onCreate: 'require' }) create(greeting: string) { this.greeting.value = greeting } diff --git a/examples/proof-of-attendance/contract.algo.ts b/examples/proof-of-attendance/contract.algo.ts new file mode 100644 index 0000000..6fa7ddc --- /dev/null +++ b/examples/proof-of-attendance/contract.algo.ts @@ -0,0 +1,217 @@ +import type { Account, Asset, bytes, gtxn, uint64 } from '@algorandfoundation/algorand-typescript' +import { + arc4, + assert, + Box, + BoxMap, + BoxRef, + Bytes, + ensureBudget, + Global, + GlobalState, + itxn, + op, + OpUpFeeSource, + Txn, + Uint64, +} from '@algorandfoundation/algorand-typescript' + +export default class ProofOfAttendance extends arc4.Contract { + maxAttendees = GlobalState({ initialValue: Uint64(30) }) + assetUrl = GlobalState({ initialValue: 'ipfs://QmW5vERkgeJJtSY1YQdcWU6gsHCZCyLFtM1oT9uyy2WGm8' }) + totalAttendees = GlobalState({ initialValue: Uint64(0) }) + boxMap = BoxMap({ keyPrefix: 'boxMap' }) + + @arc4.abimethod({ onCreate: 'require' }) + init(maxAttendees: uint64) { + assert(Txn.sender === Global.creatorAddress, 'Only creator can initialize') + this.maxAttendees.value = maxAttendees + } + + @arc4.abimethod() + confirmAttendance() { + assert(this.totalAttendees.value < this.maxAttendees.value, 'Max attendees reached') + + const mintedAsset = this.mintPoa(Txn.sender) + this.totalAttendees.value += 1 + + const [_id, hasClaimed] = op.Box.get(Txn.sender.bytes) + assert(!hasClaimed, 'Already claimed POA') + + op.Box.put(Txn.sender.bytes, op.itob(mintedAsset.id)) + } + + @arc4.abimethod() + confirmAttendanceWithBox() { + assert(this.totalAttendees.value < this.maxAttendees.value, 'Max attendees reached') + + const mintedAsset = this.mintPoa(Txn.sender) + this.totalAttendees.value += 1 + + const box = Box({ key: Txn.sender.bytes }) + const hasClaimed = box.exists + assert(!hasClaimed, 'Already claimed POA') + + box.value = mintedAsset.id + } + + @arc4.abimethod() + confirmAttendanceWithBoxRef() { + assert(this.totalAttendees.value < this.maxAttendees.value, 'Max attendees reached') + + const mintedAsset = this.mintPoa(Txn.sender) + this.totalAttendees.value += 1 + + const boxRef = BoxRef({ key: Txn.sender.bytes }) + const hasClaimed = boxRef.exists + assert(!hasClaimed, 'Already claimed POA') + + boxRef.put(op.itob(mintedAsset.id)) + } + + @arc4.abimethod() + confirmAttendanceWithBoxMap() { + assert(this.totalAttendees.value < this.maxAttendees.value, 'Max attendees reached') + + const mintedAsset = this.mintPoa(Txn.sender) + this.totalAttendees.value += 1 + + const hasClaimed = this.boxMap(Txn.sender.bytes).exists + assert(!hasClaimed, 'Already claimed POA') + + this.boxMap(Txn.sender.bytes).value = mintedAsset.id + } + @arc4.abimethod({ readonly: true }) + getPoaId(): uint64 { + const [poaId, exists] = op.Box.get(Txn.sender.bytes) + assert(exists, 'POA not found') + return op.btoi(poaId) + } + + @arc4.abimethod({ readonly: true }) + getPoaIdWithBox(): uint64 { + const box = Box({ key: Txn.sender.bytes }) + const [poaId, exists] = box.maybe() + assert(exists, 'POA not found') + return poaId + } + + @arc4.abimethod({ readonly: true }) + getPoaIdWithBoxRef(): uint64 { + const boxRef = BoxRef({ key: Txn.sender.bytes }) + const [poaId, exists] = boxRef.maybe() + assert(exists, 'POA not found') + return op.btoi(poaId) + } + + @arc4.abimethod({ readonly: true }) + getPoaIdWithBoxMap(): uint64 { + const [poaId, exists] = this.boxMap(Txn.sender.bytes).maybe() + assert(exists, 'POA not found') + return poaId + } + + @arc4.abimethod() + claimPoa(optInTxn: gtxn.AssetTransferTxn) { + const [poaId, exists] = op.Box.get(Txn.sender.bytes) + assert(exists, 'POA not found, attendance validation failed!') + assert(optInTxn.xferAsset.id === op.btoi(poaId), 'POA ID mismatch') + assert(optInTxn.fee === 0, 'We got you covered for free!') + assert(optInTxn.assetAmount === 0) + assert( + optInTxn.sender === optInTxn.assetReceiver && optInTxn.assetReceiver === Txn.sender, + 'Opt-in transaction sender and receiver must be the same', + ) + assert( + optInTxn.assetCloseTo === optInTxn.rekeyTo && optInTxn.rekeyTo === Global.zeroAddress, + 'Opt-in transaction close to must be zero address', + ) + + this.sendPoa(Txn.sender, optInTxn.xferAsset) + } + + @arc4.abimethod() + claimPoaWithBox(optInTxn: gtxn.AssetTransferTxn) { + const box = Box({ key: Txn.sender.bytes }) + const [poaId, exists] = box.maybe() + assert(exists, 'POA not found, attendance validation failed!') + assert(optInTxn.xferAsset.id === poaId, 'POA ID mismatch') + assert(optInTxn.fee === 0, 'We got you covered for free!') + assert(optInTxn.assetAmount === 0) + assert( + optInTxn.sender === optInTxn.assetReceiver && optInTxn.assetReceiver === Txn.sender, + 'Opt-in transaction sender and receiver must be the same', + ) + assert( + optInTxn.assetCloseTo === optInTxn.rekeyTo && optInTxn.rekeyTo === Global.zeroAddress, + 'Opt-in transaction close to must be zero address', + ) + + this.sendPoa(Txn.sender, optInTxn.xferAsset) + } + + @arc4.abimethod() + claimPoaWithBoxRef(optInTxn: gtxn.AssetTransferTxn) { + const boxRef = BoxRef({ key: Txn.sender.bytes }) + const [poaId, exists] = boxRef.maybe() + assert(exists, 'POA not found, attendance validation failed!') + assert(optInTxn.xferAsset.id === op.btoi(poaId), 'POA ID mismatch') + assert(optInTxn.fee === 0, 'We got you covered for free!') + assert(optInTxn.assetAmount === 0) + assert( + optInTxn.sender === optInTxn.assetReceiver && optInTxn.assetReceiver === Txn.sender, + 'Opt-in transaction sender and receiver must be the same', + ) + assert( + optInTxn.assetCloseTo === optInTxn.rekeyTo && optInTxn.rekeyTo === Global.zeroAddress, + 'Opt-in transaction close to must be zero address', + ) + + this.sendPoa(Txn.sender, optInTxn.xferAsset) + } + + @arc4.abimethod() + claimPoaWithBoxMap(optInTxn: gtxn.AssetTransferTxn) { + const [poaId, exists] = this.boxMap(Txn.sender.bytes).maybe() + assert(exists, 'POA not found, attendance validation failed!') + assert(optInTxn.xferAsset.id === poaId, 'POA ID mismatch') + assert(optInTxn.fee === 0, 'We got you covered for free!') + assert(optInTxn.assetAmount === 0) + assert( + optInTxn.sender === optInTxn.assetReceiver && optInTxn.assetReceiver === Txn.sender, + 'Opt-in transaction sender and receiver must be the same', + ) + assert( + optInTxn.assetCloseTo === optInTxn.rekeyTo && optInTxn.rekeyTo === Global.zeroAddress, + 'Opt-in transaction close to must be zero address', + ) + + this.sendPoa(Txn.sender, optInTxn.xferAsset) + } + + private mintPoa(claimer: Account): Asset { + ensureBudget(10000, OpUpFeeSource.AppAccount) + const assetName = Bytes('AlgoKit POA #').concat(op.itob(this.totalAttendees.value)) + return itxn + .assetConfig({ + assetName: assetName, + unitName: 'POA', + total: 1, + decimals: 0, + url: this.assetUrl.value, + manager: claimer, + }) + .submit().createdAsset + } + + private sendPoa(receiver: Account, asset: Asset) { + itxn + .assetTransfer({ + xferAsset: asset, + sender: Global.currentApplicationAddress, + assetReceiver: receiver, + assetAmount: 1, + }) + .submit() + } +} diff --git a/examples/proof-of-attendance/contract.spec.ts b/examples/proof-of-attendance/contract.spec.ts new file mode 100644 index 0000000..08fa987 --- /dev/null +++ b/examples/proof-of-attendance/contract.spec.ts @@ -0,0 +1,81 @@ +import { Account, Bytes, op } from '@algorandfoundation/algorand-typescript' +import { TestExecutionContext } from '@algorandfoundation/algorand-typescript-testing' +import { afterEach, describe, expect, it, test } from 'vitest' +import ProofOfAttendance from './contract.algo' + +/* eslint-disable-next-line @typescript-eslint/no-explicit-any */ +type DeliberateAny = any +const ZERO_ADDRESS = Bytes.fromBase32('AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA') + +describe('ProofOfAttendance', () => { + const ctx = new TestExecutionContext() + + const getContract = () => { + const contract = ctx.contract.create(ProofOfAttendance) + contract.init(ctx.any.uint64(1, 100)) + return contract + } + afterEach(() => { + ctx.reset() + }) + + it('should be able to init', () => { + // Arrange + const contract = ctx.contract.create(ProofOfAttendance) + const maxAttendees = ctx.any.uint64(1, 100) + + // Act + contract.init(maxAttendees) + + // Assert + expect(contract.maxAttendees.value).toEqual(maxAttendees) + }) + + test.each([ + ['confirmAttendance', Bytes('')], + ['confirmAttendanceWithBox', Bytes('')], + ['confirmAttendanceWithBoxRef', Bytes('')], + ['confirmAttendanceWithBoxMap', Bytes('boxMap')], + ])('%s', (confirmAttendance, keyPrefix) => { + // Arrange + const contract = getContract() + + // Act + const confirm = (contract as DeliberateAny)[confirmAttendance] + confirm() + + // Assert + const boxContent = ctx.ledger.getBox(contract, keyPrefix.concat(ctx.defaultSender.bytes)) + expect(boxContent).toEqual(op.itob(1001)) + }) + test.each([ + ['claimPoa', Bytes('')], + ['claimPoaWithBox', Bytes('')], + ['claimPoaWithBoxRef', Bytes('')], + ['claimPoaWithBoxMap', Bytes('boxMap')], + ])('%s', (claimPoa, keyPrefix) => { + // Arrange + const contract = getContract() + + const dummyPoa = ctx.any.asset() + const optInTxn = ctx.any.txn.assetTransfer({ + sender: ctx.defaultSender, + assetReceiver: ctx.defaultSender, + assetCloseTo: Account(ZERO_ADDRESS), + rekeyTo: Account(ZERO_ADDRESS), + xferAsset: dummyPoa, + fee: 0, + assetAmount: 0, + }) + ctx.ledger.setBox(contract, keyPrefix.concat(ctx.defaultSender.bytes), op.itob(dummyPoa.id)) + + // Act + const claim = (contract as DeliberateAny)[claimPoa] + claim(optInTxn) + + // Assert + const axferItxn = ctx.txn.lastGroup.getItxnGroup().getAssetTransferInnerTxn(0) + expect(axferItxn.assetReceiver).toEqual(ctx.defaultSender) + expect(axferItxn.assetAmount).toEqual(1) + }) +}) diff --git a/examples/rollup.config.ts b/examples/rollup.config.ts index 4aa1a7a..766fcd5 100644 --- a/examples/rollup.config.ts +++ b/examples/rollup.config.ts @@ -1,17 +1,20 @@ import typescript from '@rollup/plugin-typescript' import type { RollupOptions } from 'rollup' -import { puyaTsTransformer } from '../src/test-transformer' +import { puyaTsTransformer } from '../src/test-transformer/vitest-transformer' // This config allows you to build the example contracts with the test transformer applied to verify the output statically const config: RollupOptions = { input: [ + 'examples/arc4-simple-voting/contract.algo.ts', 'examples/auction/contract.algo.ts', 'examples/calculator/contract.algo.ts', 'examples/hello-world-abi/contract.algo.ts', 'examples/hello-world/contract.algo.ts', 'examples/htlc-logicsig/signature.algo.ts', + 'examples/marketplace/contract.algo.ts', 'examples/precompiled/contract.algo.ts', + 'examples/proof-of-attendance/contract.algo.ts', 'examples/scratch-storage/contract.algo.ts', 'examples/simple-voting/contract.algo.ts', 'examples/tealscript/example.algo.ts', diff --git a/examples/scratch-storage/contract.algo.ts b/examples/scratch-storage/contract.algo.ts index 4fd0290..c258c9d 100644 --- a/examples/scratch-storage/contract.algo.ts +++ b/examples/scratch-storage/contract.algo.ts @@ -1,23 +1,26 @@ -import { arc4, assert, BaseContract, Bytes, op, uint64, Uint64 } from '@algorandfoundation/algorand-typescript' +import type { uint64 } from '@algorandfoundation/algorand-typescript' +import { arc4, assert, BaseContract, Bytes, contract, op, Uint64 } from '@algorandfoundation/algorand-typescript' +@contract({ scratchSlots: [1, 2] }) export class ScratchSlotsContract extends arc4.Contract { @arc4.abimethod() public storeData(): boolean { op.Scratch.store(1, Uint64(5)) op.Scratch.store(2, Bytes('Hello World')) - assert(op.Scratch.loadUint64(1) === Uint64(5)) + assert(op.Scratch.loadUint64(1) === 5) assert(op.Scratch.loadBytes(2) === Bytes('Hello World')) return true } } +@contract({ scratchSlots: [1, 2] }) export class SimpleScratchSlotsContract extends BaseContract { - approvalProgram(): boolean | uint64 { - assert(op.Scratch.loadUint64(1) === Uint64(5)) + approvalProgram(): uint64 { + assert(op.Scratch.loadUint64(1) === 5) assert(op.Scratch.loadBytes(2) === Bytes('Hello World')) return Uint64(1) } - clearStateProgram(): boolean | uint64 { + clearStateProgram(): uint64 { return Uint64(1) } } diff --git a/examples/simple-voting/contract.algo.ts b/examples/simple-voting/contract.algo.ts index d8159b3..b63e4bc 100644 --- a/examples/simple-voting/contract.algo.ts +++ b/examples/simple-voting/contract.algo.ts @@ -1,5 +1,15 @@ import type { Account, bytes, uint64 } from '@algorandfoundation/algorand-typescript' -import { assert, BaseContract, Bytes, GlobalState, LocalState, op, TransactionType, Uint64 } from '@algorandfoundation/algorand-typescript' +import { + assert, + BaseContract, + Bytes, + GlobalState, + gtxn, + LocalState, + op, + TransactionType, + Uint64, +} from '@algorandfoundation/algorand-typescript' const VOTE_PRICE = Uint64(10_000) export default class SimpleVotingContract extends BaseContract { @@ -11,16 +21,16 @@ export default class SimpleVotingContract extends BaseContract { switch (op.Txn.applicationArgs(0)) { case Bytes('set_topic'): { this.setTopic(op.Txn.applicationArgs(1)) - return Uint64(1) + return 1 } case Bytes('vote'): { - return this.vote(op.Txn.sender) ? Uint64(1) : Uint64(0) + return this.vote(op.Txn.sender) ? 1 : 0 } case Bytes('get_votes'): { return this.votes.value } default: - return Uint64(0) + return 0 } } @@ -33,7 +43,8 @@ export default class SimpleVotingContract extends BaseContract { } private vote(voter: Account): boolean { - assert(op.Global.groupSize === Uint64(2)) + assert(op.Global.groupSize === 2) + assert(gtxn.PaymentTxn(1).amount === VOTE_PRICE) assert(op.GTxn.amount(1) === VOTE_PRICE) assert(op.GTxn.typeEnum(1) === TransactionType.Payment) diff --git a/examples/simple-voting/contract.spec.ts b/examples/simple-voting/contract.spec.ts index 9d28685..861db96 100644 --- a/examples/simple-voting/contract.spec.ts +++ b/examples/simple-voting/contract.spec.ts @@ -19,19 +19,19 @@ describe('Simple voting contract', () => { .createScope( [ ctx.any.txn.applicationCall({ - appId: ctx.ledger.getApplicationForContract(contract), + appId: contract, appArgs: [Bytes('set_topic'), topic], }), ctx.any.txn.payment({ - amount: Uint64(10_000), + amount: 10_000, }), ], 0, ) .execute(contract.approvalProgram) - expect(result).toEqual(Uint64(1)) - expect(contract.topic.value.toString()).toBe(topic.toString()) + expect(result).toEqual(1) + expect(contract.topic.value).toBe(topic) }) }) }) @@ -43,9 +43,9 @@ describe('Simple voting contract', () => { const result = castVote(ctx, contract, voter) - expect(result).toEqual(Uint64(1)) - expect(contract.votes.value).toEqual(Uint64(1)) - expect(contract.voted(voter).value).toEqual(Uint64(1)) + expect(result).toEqual(1) + expect(contract.votes.value).toEqual(1) + expect(contract.voted(voter).value).toEqual(1) }) it('ignores subsequent votes from the same voter', async () => { const contract = ctx.contract.create(SimpleVotingContract) @@ -55,9 +55,9 @@ describe('Simple voting contract', () => { const result = castVote(ctx, contract, voter) - expect(result).toEqual(Uint64(0)) - expect(contract.votes.value).toEqual(Uint64(1)) - expect(contract.voted(voter).value).toEqual(Uint64(1)) + expect(result).toEqual(0) + expect(contract.votes.value).toEqual(1) + expect(contract.voted(voter).value).toEqual(1) }) }) describe('When getting the votes', () => { @@ -72,18 +72,18 @@ describe('Simple voting contract', () => { .createScope( [ ctx.any.txn.applicationCall({ - appId: ctx.ledger.getApplicationForContract(contract), + appId: contract, appArgs: [Bytes('get_votes')], }), ctx.any.txn.payment({ - amount: Uint64(10_000), + amount: 10_000, }), ], 0, ) .execute(contract.approvalProgram) - expect(result).toEqual(Uint64(2)) + expect(result).toEqual(2) }) }) }) @@ -93,13 +93,13 @@ const castVote = (ctx: TestExecutionContext, contract: SimpleVotingContract, vot .createScope( [ ctx.any.txn.applicationCall({ - appId: ctx.ledger.getApplicationForContract(contract), + appId: contract, sender: voter, appArgs: [Bytes('vote'), voter.bytes], }), ctx.any.txn.payment({ sender: voter, - amount: Uint64(10_000), + amount: 10_000, }), ], 0, diff --git a/examples/voting/contract.algo.ts b/examples/voting/contract.algo.ts index 734f50d..37b86bc 100644 --- a/examples/voting/contract.algo.ts +++ b/examples/voting/contract.algo.ts @@ -173,7 +173,7 @@ export class VotingRoundApp extends arc4.Contract { } private alreadyVoted(): boolean { - return this.votesByAccount.has(Txn.sender) + return this.votesByAccount(Txn.sender).exists } public vote(fundMinBalReq: gtxn.PaymentTxn, signature: bytes, answerIds: VoteIndexArray): void { @@ -207,7 +207,7 @@ export class VotingRoundApp extends arc4.Contract { assert(answerOptionIndex < optionsCount, 'Answer option index invalid') this.incrementVoteInBox(cumulativeOffset + answerOptionIndex) cumulativeOffset += optionsCount - this.votesByAccount.set(Txn.sender, answerIds.copy()) + this.votesByAccount(Txn.sender).value = answerIds.copy() this.voterCount.value += 1 } } diff --git a/examples/voting/contract.spec.ts b/examples/voting/contract.spec.ts index 96d09bb..e8dbc42 100644 --- a/examples/voting/contract.spec.ts +++ b/examples/voting/contract.spec.ts @@ -1,5 +1,5 @@ import { Bytes, Uint64 } from '@algorandfoundation/algorand-typescript' -import { encodingUtil, TestExecutionContext } from '@algorandfoundation/algorand-typescript-testing' +import { TestExecutionContext, toExternalValue } from '@algorandfoundation/algorand-typescript-testing' import { DynamicArray, UintN8 } from '@algorandfoundation/algorand-typescript/arc4' import nacl from 'tweetnacl' import { afterEach, describe, expect, it } from 'vitest' @@ -50,7 +50,7 @@ describe('VotingRoundApp', () => { contract.bootstrap(ctx.any.txn.payment({ receiver: app.address, amount: boostrapMinBalanceReq })) const account = ctx.any.account() - const signature = nacl.sign.detached(encodingUtil.toExternalValue(account.bytes), keyPair.secretKey) + const signature = nacl.sign.detached(toExternalValue(account.bytes), keyPair.secretKey) ctx.txn.createScope([ctx.any.txn.applicationCall({ sender: account })]).execute(() => { const preconditions = contract.getPreconditions(Bytes(signature)) @@ -67,7 +67,7 @@ describe('VotingRoundApp', () => { contract.bootstrap(ctx.any.txn.payment({ receiver: app.address, amount: boostrapMinBalanceReq })) const account = ctx.any.account() - const signature = nacl.sign.detached(encodingUtil.toExternalValue(account.bytes), keyPair.secretKey) + const signature = nacl.sign.detached(toExternalValue(account.bytes), keyPair.secretKey) const answerIds = new DynamicArray( ...Array(13) .fill(0) @@ -77,7 +77,7 @@ describe('VotingRoundApp', () => { ctx.txn.createScope([ctx.any.txn.applicationCall({ appId: app, sender: account })]).execute(() => { contract.vote(ctx.any.txn.payment({ receiver: app.address, amount: voteMinBalanceReq }), Bytes(signature), answerIds) - expect(contract.votesByAccount.get(account).bytes).toEqual(answerIds.bytes) + expect(contract.votesByAccount(account).value.bytes).toEqual(answerIds.bytes) expect(contract.voterCount.value).toEqual(13) }) }) diff --git a/examples/zk-whitelist/contract.algo.ts b/examples/zk-whitelist/contract.algo.ts index d1a9224..3e04153 100644 --- a/examples/zk-whitelist/contract.algo.ts +++ b/examples/zk-whitelist/contract.algo.ts @@ -1,3 +1,4 @@ +import type { uint64 } from '@algorandfoundation/algorand-typescript' import { abimethod, Account, @@ -7,26 +8,28 @@ import { Bytes, ensureBudget, Global, + GlobalState, itxn, LocalState, + OnCompleteAction, op, OpUpFeeSource, TemplateVar, Txn, - uint64, + Uint64, } from '@algorandfoundation/algorand-typescript' -const curveMod = 21888242871839275222246405745257275088548364400416034343698204186575808495617n -const verifierBudget = 145000 +const curveMod = BigUint(21888242871839275222246405745257275088548364400416034343698204186575808495617n) +const verifierBudget = Uint64(145000) export default class ZkWhitelistContract extends arc4.Contract { - appName: arc4.Str | undefined + appName = GlobalState({}) whiteList = LocalState() @abimethod({ onCreate: 'require' }) create(name: arc4.Str) { // Create the application - this.appName = name + this.appName.value = name } @abimethod({ allowActions: ['UpdateApplication', 'DeleteApplication'] }) @@ -86,7 +89,7 @@ export default class ZkWhitelistContract extends arc4.Contract { appId: appId, fee: 0, appArgs: [arc4.methodSelector('verify(byte[32][],byte[32][])bool'), proof.copy(), publicInputs.copy()], - onCompletion: arc4.OnCompleteAction.NoOp, + onCompletion: OnCompleteAction.NoOp, }) .submit().lastLog return arc4.interpretAsArc4(verified, 'log') diff --git a/examples/zk-whitelist/contract.spec.ts b/examples/zk-whitelist/contract.spec.ts index 468e93b..e6daaeb 100644 --- a/examples/zk-whitelist/contract.spec.ts +++ b/examples/zk-whitelist/contract.spec.ts @@ -1,9 +1,10 @@ import { arc4, Bytes } from '@algorandfoundation/algorand-typescript' import { TestExecutionContext } from '@algorandfoundation/algorand-typescript-testing' import { afterEach, describe, expect, it } from 'vitest' -import { ABI_RETURN_VALUE_LOG_PREFIX } from '../../src/constants' import ZkWhitelistContract from './contract.algo' +const ABI_RETURN_VALUE_LOG_PREFIX = Bytes.fromHex('151F7C75') + describe('ZK Whitelist', () => { const ctx = new TestExecutionContext() diff --git a/package-lock.json b/package-lock.json index c4f787f..6c3fb0b 100644 --- a/package-lock.json +++ b/package-lock.json @@ -7,10 +7,9 @@ "": { "name": "@algorandfoundation/algorand-typescript-testing", "version": "1.0.0", - "hasInstallScript": true, "dependencies": { - "@algorandfoundation/algorand-typescript": "^0.0.1-alpha.24", - "@algorandfoundation/puya-ts": "^1.0.0-alpha.36", + "@algorandfoundation/algorand-typescript": "^1.0.0-beta.25", + "@algorandfoundation/puya-ts": "^1.0.0-beta.46", "elliptic": "^6.5.7", "js-sha256": "^0.11.0", "js-sha3": "^0.9.3", @@ -18,48 +17,49 @@ "tweetnacl": "^1.0.3" }, "devDependencies": { - "@algorandfoundation/algokit-utils": "^8.0.3", - "@commitlint/cli": "^19.5.0", - "@commitlint/config-conventional": "^19.5.0", - "@eslint/eslintrc": "3.1.0", - "@eslint/js": "9.12.0", + "@algorandfoundation/algokit-utils": "^8.2.2", + "@commitlint/cli": "^19.8.0", + "@commitlint/config-conventional": "^19.8.0", + "@eslint/eslintrc": "3.3.0", + "@eslint/js": "9.22.0", "@makerx/eslint-config": "4.0.0", "@makerx/prettier-config": "2.0.1", "@makerx/ts-toolkit": "4.0.0-beta.21", - "@rollup/plugin-commonjs": "28.0.0", + "@rollup/plugin-commonjs": "28.0.3", "@rollup/plugin-json": "6.1.0", - "@rollup/plugin-node-resolve": "15.3.0", - "@rollup/plugin-typescript": "^12.1.0", + "@rollup/plugin-node-resolve": "16.0.0", + "@rollup/plugin-typescript": "^12.1.2", "@tsconfig/node20": "20.1.4", "@types/elliptic": "^6.4.18", - "@types/node": "22.7.5", - "@typescript-eslint/eslint-plugin": "8.8.1", - "@typescript-eslint/parser": "8.8.1", - "@vitest/coverage-v8": "2.1.2", + "@types/node": "22.13.10", + "@typescript-eslint/eslint-plugin": "8.26.1", + "@typescript-eslint/parser": "8.26.1", + "@vitest/coverage-v8": "3.0.8", "better-npm-audit": "3.11.0", "conventional-changelog-conventionalcommits": "^8.0.0", "copyfiles": "2.4.1", - "eslint": "9.12.0", - "eslint-config-prettier": "^9.1.0", - "eslint-plugin-prettier": "^5.2.1", + "eslint": "9.22.0", + "eslint-config-prettier": "^10.1.1", + "eslint-plugin-prettier": "^5.2.3", + "glob": "^11.0.0", "npm-run-all": "4.1.5", - "patch-package": "^8.0.0", - "prettier": "3.3.3", + "polytype": "^0.17.0", + "prettier": "3.5.3", "rimraf": "6.0.1", - "rollup": "^4.24.0", - "semantic-release": "^24.1.2", - "tsx": "4.19.1", - "typescript": "^5.7.2", - "vitest": "2.1.2" - }, - "peerDependencies": { - "tslib": "^2.6.2" + "rollup": "^4.34.9", + "semantic-release": "^24.2.3", + "tsx": "4.19.3", + "typedoc": "^0.27.9", + "typedoc-plugin-markdown": "^4.4.2", + "typescript": "^5.8.2", + "upath": "^2.0.1", + "vitest": "3.0.8" } }, "node_modules/@algorandfoundation/algokit-utils": { - "version": "8.0.3", - "resolved": "https://registry.npmjs.org/@algorandfoundation/algokit-utils/-/algokit-utils-8.0.3.tgz", - "integrity": "sha512-2YYlCDJmT4pvNLUOLqdX6M1nwC2hh4l1gDZFi2ID+JFQ7ZDyASZqg+c2euFrzvxhZJi2Ue94iP+ARqrv74b0+w==", + "version": "8.2.2", + "resolved": "https://registry.npmjs.org/@algorandfoundation/algokit-utils/-/algokit-utils-8.2.2.tgz", + "integrity": "sha512-cDlukxXRHEIWR9Iae/Jnxl0Z5JUuHTdVbGpGgFUBxaHCSVxb+VUE5b0fsuSOmUvAEyFiMLe7PLb9DCv0xjdE5Q==", "dev": true, "license": "MIT", "dependencies": { @@ -73,47 +73,40 @@ } }, "node_modules/@algorandfoundation/algorand-typescript": { - "version": "0.0.1-alpha.24", - "resolved": "https://registry.npmjs.org/@algorandfoundation/algorand-typescript/-/algorand-typescript-0.0.1-alpha.24.tgz", - "integrity": "sha512-aAuIRrTmnprfquxY7ZNrlBmnH6SyCGHUOKrC5L+K5AKduCgWS3S4I2e9CRBZlSpdMKBZ5Ek97Ufm5ZJHvs1I+g==", + "version": "1.0.0-beta.25", + "resolved": "https://registry.npmjs.org/@algorandfoundation/algorand-typescript/-/algorand-typescript-1.0.0-beta.25.tgz", + "integrity": "sha512-LZD0j4XqzGACBoici7uTAVQxsUVx4/r0PvD4HWEQYdqSnXQqqZGlpEV71PZTyhI3dWZcsQbqORhG6WAXCiWn+w==", "peerDependencies": { "tslib": "^2.6.2" } }, "node_modules/@algorandfoundation/puya-ts": { - "version": "1.0.0-alpha.36", - "resolved": "https://registry.npmjs.org/@algorandfoundation/puya-ts/-/puya-ts-1.0.0-alpha.36.tgz", - "integrity": "sha512-HHjRTvVMK3/9Oa1YRcKg/d1t9bsTnU3EdhF3rJyRSLOBDl87U5g3MUYgUuxzTbFDfUgqYNKfftL6m75EVpQ0og==", - "bundleDependencies": [ - "typescript" - ], + "version": "1.0.0-beta.46", + "resolved": "https://registry.npmjs.org/@algorandfoundation/puya-ts/-/puya-ts-1.0.0-beta.46.tgz", + "integrity": "sha512-q/I1DjlFRvBWWkRkecphhIRC+mLj+N6YWlRYddbTYN3KbU12YfKohnPcuKuc8ta1SphhEmCq8sgB5s/CgKguAA==", "license": "MIT", "dependencies": { - "chalk": "^5.3.0", + "arcsecond": "^5.0.0", + "argparse": "^2.0.1", + "chalk": "^5.4.1", "change-case": "^5.4.4", - "commander": "^12.1.0", "cross-spawn": "7.0.6", - "glob": "^11.0.0", + "glob": "^11.0.1", + "minimatch": "^10.0.1", "polytype": "^0.17.0", - "typescript": "^5.7.2", + "tslib": "^2.8.1", + "typescript": "^5.8.2", "upath": "^2.0.1", - "zod": "^3.24.0" + "vscode-languageserver": "^9.0.1", + "vscode-languageserver-textdocument": "^1.0.12", + "vscode-uri": "^3.1.0", + "which": "^5.0.0", + "zod": "^3.24.2" }, "bin": { "puya-ts": "bin/run-cli.mjs", - "puyats": "bin/run-cli.mjs" - } - }, - "node_modules/@algorandfoundation/puya-ts/node_modules/typescript": { - "version": "5.7.2", - "inBundle": true, - "license": "Apache-2.0", - "bin": { - "tsc": "bin/tsc", - "tsserver": "bin/tsserver" - }, - "engines": { - "node": ">=14.17" + "puyats": "bin/run-cli.mjs", + "run-language-server": "bin/run-language-server.mjs" } }, "node_modules/@ampproject/remapping": { @@ -166,13 +159,13 @@ } }, "node_modules/@babel/parser": { - "version": "7.26.3", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.26.3.tgz", - "integrity": "sha512-WJ/CvmY8Mea8iDXo6a7RK2wbmJITT5fN3BEkRuFlxVyNx8jOKIIhmC4fSkTcPcf8JyavbBwIe6OpiCOBXt/IcA==", + "version": "7.26.9", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.26.9.tgz", + "integrity": "sha512-81NWa1njQblgZbQHxWHpxxCzNsa3ZwvFqpUg7P+NNUU6f3UU2jBEg4OlF/J6rl8+PQGh1q6/zWScd001YwcA5A==", "dev": true, "license": "MIT", "dependencies": { - "@babel/types": "^7.26.3" + "@babel/types": "^7.26.9" }, "bin": { "parser": "bin/babel-parser.js" @@ -182,9 +175,9 @@ } }, "node_modules/@babel/types": { - "version": "7.26.3", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.26.3.tgz", - "integrity": "sha512-vN5p+1kl59GVKMvTHt55NzzmYVxprfJD+ql7U9NFIfKCBkYE55LYtS+WtPlaYOyzydrKI8Nezd+aZextrd+FMA==", + "version": "7.26.9", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.26.9.tgz", + "integrity": "sha512-Y3IR1cRnOxOCDvMmNiym7XpXQ93iGDDPHx+Zj+NM+rg0fBaShfQLkg+hKPaZCEvg5N/LeCo4+Rj/i3FuJsIQaw==", "dev": true, "license": "MIT", "dependencies": { @@ -196,11 +189,14 @@ } }, "node_modules/@bcoe/v8-coverage": { - "version": "0.2.3", - "resolved": "https://registry.npmjs.org/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz", - "integrity": "sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@bcoe/v8-coverage/-/v8-coverage-1.0.2.tgz", + "integrity": "sha512-6zABk/ECA/QYSCQ1NGiVwwbQerUCZ+TQbp64Q3AgmfNvurHH0j8TtXa1qbShXA6qqkpAj4V5W8pP6mLe1mcMqA==", "dev": true, - "license": "MIT" + "license": "MIT", + "engines": { + "node": ">=18" + } }, "node_modules/@colors/colors": { "version": "1.5.0", @@ -214,17 +210,17 @@ } }, "node_modules/@commitlint/cli": { - "version": "19.6.1", - "resolved": "https://registry.npmjs.org/@commitlint/cli/-/cli-19.6.1.tgz", - "integrity": "sha512-8hcyA6ZoHwWXC76BoC8qVOSr8xHy00LZhZpauiD0iO0VYbVhMnED0da85lTfIULxl7Lj4c6vZgF0Wu/ed1+jlQ==", + "version": "19.8.0", + "resolved": "https://registry.npmjs.org/@commitlint/cli/-/cli-19.8.0.tgz", + "integrity": "sha512-t/fCrLVu+Ru01h0DtlgHZXbHV2Y8gKocTR5elDOqIRUzQd0/6hpt2VIWOj9b3NDo7y4/gfxeR2zRtXq/qO6iUg==", "dev": true, "license": "MIT", "dependencies": { - "@commitlint/format": "^19.5.0", - "@commitlint/lint": "^19.6.0", - "@commitlint/load": "^19.6.1", - "@commitlint/read": "^19.5.0", - "@commitlint/types": "^19.5.0", + "@commitlint/format": "^19.8.0", + "@commitlint/lint": "^19.8.0", + "@commitlint/load": "^19.8.0", + "@commitlint/read": "^19.8.0", + "@commitlint/types": "^19.8.0", "tinyexec": "^0.3.0", "yargs": "^17.0.0" }, @@ -236,13 +232,13 @@ } }, "node_modules/@commitlint/config-conventional": { - "version": "19.6.0", - "resolved": "https://registry.npmjs.org/@commitlint/config-conventional/-/config-conventional-19.6.0.tgz", - "integrity": "sha512-DJT40iMnTYtBtUfw9ApbsLZFke1zKh6llITVJ+x9mtpHD08gsNXaIRqHTmwTZL3dNX5+WoyK7pCN/5zswvkBCQ==", + "version": "19.8.0", + "resolved": "https://registry.npmjs.org/@commitlint/config-conventional/-/config-conventional-19.8.0.tgz", + "integrity": "sha512-9I2kKJwcAPwMoAj38hwqFXG0CzS2Kj+SAByPUQ0SlHTfb7VUhYVmo7G2w2tBrqmOf7PFd6MpZ/a1GQJo8na8kw==", "dev": true, "license": "MIT", "dependencies": { - "@commitlint/types": "^19.5.0", + "@commitlint/types": "^19.8.0", "conventional-changelog-conventionalcommits": "^7.0.2" }, "engines": { @@ -263,13 +259,13 @@ } }, "node_modules/@commitlint/config-validator": { - "version": "19.5.0", - "resolved": "https://registry.npmjs.org/@commitlint/config-validator/-/config-validator-19.5.0.tgz", - "integrity": "sha512-CHtj92H5rdhKt17RmgALhfQt95VayrUo2tSqY9g2w+laAXyk7K/Ef6uPm9tn5qSIwSmrLjKaXK9eiNuxmQrDBw==", + "version": "19.8.0", + "resolved": "https://registry.npmjs.org/@commitlint/config-validator/-/config-validator-19.8.0.tgz", + "integrity": "sha512-+r5ZvD/0hQC3w5VOHJhGcCooiAVdynFlCe2d6I9dU+PvXdV3O+fU4vipVg+6hyLbQUuCH82mz3HnT/cBQTYYuA==", "dev": true, "license": "MIT", "dependencies": { - "@commitlint/types": "^19.5.0", + "@commitlint/types": "^19.8.0", "ajv": "^8.11.0" }, "engines": { @@ -277,13 +273,13 @@ } }, "node_modules/@commitlint/ensure": { - "version": "19.5.0", - "resolved": "https://registry.npmjs.org/@commitlint/ensure/-/ensure-19.5.0.tgz", - "integrity": "sha512-Kv0pYZeMrdg48bHFEU5KKcccRfKmISSm9MvgIgkpI6m+ohFTB55qZlBW6eYqh/XDfRuIO0x4zSmvBjmOwWTwkg==", + "version": "19.8.0", + "resolved": "https://registry.npmjs.org/@commitlint/ensure/-/ensure-19.8.0.tgz", + "integrity": "sha512-kNiNU4/bhEQ/wutI1tp1pVW1mQ0QbAjfPRo5v8SaxoVV+ARhkB8Wjg3BSseNYECPzWWfg/WDqQGIfV1RaBFQZg==", "dev": true, "license": "MIT", "dependencies": { - "@commitlint/types": "^19.5.0", + "@commitlint/types": "^19.8.0", "lodash.camelcase": "^4.3.0", "lodash.kebabcase": "^4.1.1", "lodash.snakecase": "^4.1.1", @@ -295,9 +291,9 @@ } }, "node_modules/@commitlint/execute-rule": { - "version": "19.5.0", - "resolved": "https://registry.npmjs.org/@commitlint/execute-rule/-/execute-rule-19.5.0.tgz", - "integrity": "sha512-aqyGgytXhl2ejlk+/rfgtwpPexYyri4t8/n4ku6rRJoRhGZpLFMqrZ+YaubeGysCP6oz4mMA34YSTaSOKEeNrg==", + "version": "19.8.0", + "resolved": "https://registry.npmjs.org/@commitlint/execute-rule/-/execute-rule-19.8.0.tgz", + "integrity": "sha512-fuLeI+EZ9x2v/+TXKAjplBJWI9CNrHnyi5nvUQGQt4WRkww/d95oVRsc9ajpt4xFrFmqMZkd/xBQHZDvALIY7A==", "dev": true, "license": "MIT", "engines": { @@ -305,13 +301,13 @@ } }, "node_modules/@commitlint/format": { - "version": "19.5.0", - "resolved": "https://registry.npmjs.org/@commitlint/format/-/format-19.5.0.tgz", - "integrity": "sha512-yNy088miE52stCI3dhG/vvxFo9e4jFkU1Mj3xECfzp/bIS/JUay4491huAlVcffOoMK1cd296q0W92NlER6r3A==", + "version": "19.8.0", + "resolved": "https://registry.npmjs.org/@commitlint/format/-/format-19.8.0.tgz", + "integrity": "sha512-EOpA8IERpQstxwp/WGnDArA7S+wlZDeTeKi98WMOvaDLKbjptuHWdOYYr790iO7kTCif/z971PKPI2PkWMfOxg==", "dev": true, "license": "MIT", "dependencies": { - "@commitlint/types": "^19.5.0", + "@commitlint/types": "^19.8.0", "chalk": "^5.3.0" }, "engines": { @@ -319,13 +315,13 @@ } }, "node_modules/@commitlint/is-ignored": { - "version": "19.6.0", - "resolved": "https://registry.npmjs.org/@commitlint/is-ignored/-/is-ignored-19.6.0.tgz", - "integrity": "sha512-Ov6iBgxJQFR9koOupDPHvcHU9keFupDgtB3lObdEZDroiG4jj1rzky60fbQozFKVYRTUdrBGICHG0YVmRuAJmw==", + "version": "19.8.0", + "resolved": "https://registry.npmjs.org/@commitlint/is-ignored/-/is-ignored-19.8.0.tgz", + "integrity": "sha512-L2Jv9yUg/I+jF3zikOV0rdiHUul9X3a/oU5HIXhAJLE2+TXTnEBfqYP9G5yMw/Yb40SnR764g4fyDK6WR2xtpw==", "dev": true, "license": "MIT", "dependencies": { - "@commitlint/types": "^19.5.0", + "@commitlint/types": "^19.8.0", "semver": "^7.6.0" }, "engines": { @@ -333,32 +329,32 @@ } }, "node_modules/@commitlint/lint": { - "version": "19.6.0", - "resolved": "https://registry.npmjs.org/@commitlint/lint/-/lint-19.6.0.tgz", - "integrity": "sha512-LRo7zDkXtcIrpco9RnfhOKeg8PAnE3oDDoalnrVU/EVaKHYBWYL1DlRR7+3AWn0JiBqD8yKOfetVxJGdEtZ0tg==", + "version": "19.8.0", + "resolved": "https://registry.npmjs.org/@commitlint/lint/-/lint-19.8.0.tgz", + "integrity": "sha512-+/NZKyWKSf39FeNpqhfMebmaLa1P90i1Nrb1SrA7oSU5GNN/lksA4z6+ZTnsft01YfhRZSYMbgGsARXvkr/VLQ==", "dev": true, "license": "MIT", "dependencies": { - "@commitlint/is-ignored": "^19.6.0", - "@commitlint/parse": "^19.5.0", - "@commitlint/rules": "^19.6.0", - "@commitlint/types": "^19.5.0" + "@commitlint/is-ignored": "^19.8.0", + "@commitlint/parse": "^19.8.0", + "@commitlint/rules": "^19.8.0", + "@commitlint/types": "^19.8.0" }, "engines": { "node": ">=v18" } }, "node_modules/@commitlint/load": { - "version": "19.6.1", - "resolved": "https://registry.npmjs.org/@commitlint/load/-/load-19.6.1.tgz", - "integrity": "sha512-kE4mRKWWNju2QpsCWt428XBvUH55OET2N4QKQ0bF85qS/XbsRGG1MiTByDNlEVpEPceMkDr46LNH95DtRwcsfA==", + "version": "19.8.0", + "resolved": "https://registry.npmjs.org/@commitlint/load/-/load-19.8.0.tgz", + "integrity": "sha512-4rvmm3ff81Sfb+mcWT5WKlyOa+Hd33WSbirTVUer0wjS1Hv/Hzr07Uv1ULIV9DkimZKNyOwXn593c+h8lsDQPQ==", "dev": true, "license": "MIT", "dependencies": { - "@commitlint/config-validator": "^19.5.0", - "@commitlint/execute-rule": "^19.5.0", - "@commitlint/resolve-extends": "^19.5.0", - "@commitlint/types": "^19.5.0", + "@commitlint/config-validator": "^19.8.0", + "@commitlint/execute-rule": "^19.8.0", + "@commitlint/resolve-extends": "^19.8.0", + "@commitlint/types": "^19.8.0", "chalk": "^5.3.0", "cosmiconfig": "^9.0.0", "cosmiconfig-typescript-loader": "^6.1.0", @@ -371,9 +367,9 @@ } }, "node_modules/@commitlint/message": { - "version": "19.5.0", - "resolved": "https://registry.npmjs.org/@commitlint/message/-/message-19.5.0.tgz", - "integrity": "sha512-R7AM4YnbxN1Joj1tMfCyBryOC5aNJBdxadTZkuqtWi3Xj0kMdutq16XQwuoGbIzL2Pk62TALV1fZDCv36+JhTQ==", + "version": "19.8.0", + "resolved": "https://registry.npmjs.org/@commitlint/message/-/message-19.8.0.tgz", + "integrity": "sha512-qs/5Vi9bYjf+ZV40bvdCyBn5DvbuelhR6qewLE8Bh476F7KnNyLfdM/ETJ4cp96WgeeHo6tesA2TMXS0sh5X4A==", "dev": true, "license": "MIT", "engines": { @@ -381,13 +377,13 @@ } }, "node_modules/@commitlint/parse": { - "version": "19.5.0", - "resolved": "https://registry.npmjs.org/@commitlint/parse/-/parse-19.5.0.tgz", - "integrity": "sha512-cZ/IxfAlfWYhAQV0TwcbdR1Oc0/r0Ik1GEessDJ3Lbuma/MRO8FRQX76eurcXtmhJC//rj52ZSZuXUg0oIX0Fw==", + "version": "19.8.0", + "resolved": "https://registry.npmjs.org/@commitlint/parse/-/parse-19.8.0.tgz", + "integrity": "sha512-YNIKAc4EXvNeAvyeEnzgvm1VyAe0/b3Wax7pjJSwXuhqIQ1/t2hD3OYRXb6D5/GffIvaX82RbjD+nWtMZCLL7Q==", "dev": true, "license": "MIT", "dependencies": { - "@commitlint/types": "^19.5.0", + "@commitlint/types": "^19.8.0", "conventional-changelog-angular": "^7.0.0", "conventional-commits-parser": "^5.0.0" }, @@ -396,14 +392,14 @@ } }, "node_modules/@commitlint/read": { - "version": "19.5.0", - "resolved": "https://registry.npmjs.org/@commitlint/read/-/read-19.5.0.tgz", - "integrity": "sha512-TjS3HLPsLsxFPQj6jou8/CZFAmOP2y+6V4PGYt3ihbQKTY1Jnv0QG28WRKl/d1ha6zLODPZqsxLEov52dhR9BQ==", + "version": "19.8.0", + "resolved": "https://registry.npmjs.org/@commitlint/read/-/read-19.8.0.tgz", + "integrity": "sha512-6ywxOGYajcxK1y1MfzrOnwsXO6nnErna88gRWEl3qqOOP8MDu/DTeRkGLXBFIZuRZ7mm5yyxU5BmeUvMpNte5w==", "dev": true, "license": "MIT", "dependencies": { - "@commitlint/top-level": "^19.5.0", - "@commitlint/types": "^19.5.0", + "@commitlint/top-level": "^19.8.0", + "@commitlint/types": "^19.8.0", "git-raw-commits": "^4.0.0", "minimist": "^1.2.8", "tinyexec": "^0.3.0" @@ -413,14 +409,14 @@ } }, "node_modules/@commitlint/resolve-extends": { - "version": "19.5.0", - "resolved": "https://registry.npmjs.org/@commitlint/resolve-extends/-/resolve-extends-19.5.0.tgz", - "integrity": "sha512-CU/GscZhCUsJwcKTJS9Ndh3AKGZTNFIOoQB2n8CmFnizE0VnEuJoum+COW+C1lNABEeqk6ssfc1Kkalm4bDklA==", + "version": "19.8.0", + "resolved": "https://registry.npmjs.org/@commitlint/resolve-extends/-/resolve-extends-19.8.0.tgz", + "integrity": "sha512-CLanRQwuG2LPfFVvrkTrBR/L/DMy3+ETsgBqW1OvRxmzp/bbVJW0Xw23LnnExgYcsaFtos967lul1CsbsnJlzQ==", "dev": true, "license": "MIT", "dependencies": { - "@commitlint/config-validator": "^19.5.0", - "@commitlint/types": "^19.5.0", + "@commitlint/config-validator": "^19.8.0", + "@commitlint/types": "^19.8.0", "global-directory": "^4.0.1", "import-meta-resolve": "^4.0.0", "lodash.mergewith": "^4.6.2", @@ -431,25 +427,25 @@ } }, "node_modules/@commitlint/rules": { - "version": "19.6.0", - "resolved": "https://registry.npmjs.org/@commitlint/rules/-/rules-19.6.0.tgz", - "integrity": "sha512-1f2reW7lbrI0X0ozZMesS/WZxgPa4/wi56vFuJENBmed6mWq5KsheN/nxqnl/C23ioxpPO/PL6tXpiiFy5Bhjw==", + "version": "19.8.0", + "resolved": "https://registry.npmjs.org/@commitlint/rules/-/rules-19.8.0.tgz", + "integrity": "sha512-IZ5IE90h6DSWNuNK/cwjABLAKdy8tP8OgGVGbXe1noBEX5hSsu00uRlLu6JuruiXjWJz2dZc+YSw3H0UZyl/mA==", "dev": true, "license": "MIT", "dependencies": { - "@commitlint/ensure": "^19.5.0", - "@commitlint/message": "^19.5.0", - "@commitlint/to-lines": "^19.5.0", - "@commitlint/types": "^19.5.0" + "@commitlint/ensure": "^19.8.0", + "@commitlint/message": "^19.8.0", + "@commitlint/to-lines": "^19.8.0", + "@commitlint/types": "^19.8.0" }, "engines": { "node": ">=v18" } }, "node_modules/@commitlint/to-lines": { - "version": "19.5.0", - "resolved": "https://registry.npmjs.org/@commitlint/to-lines/-/to-lines-19.5.0.tgz", - "integrity": "sha512-R772oj3NHPkodOSRZ9bBVNq224DOxQtNef5Pl8l2M8ZnkkzQfeSTr4uxawV2Sd3ui05dUVzvLNnzenDBO1KBeQ==", + "version": "19.8.0", + "resolved": "https://registry.npmjs.org/@commitlint/to-lines/-/to-lines-19.8.0.tgz", + "integrity": "sha512-3CKLUw41Cur8VMjh16y8LcsOaKbmQjAKCWlXx6B0vOUREplp6em9uIVhI8Cv934qiwkbi2+uv+mVZPnXJi1o9A==", "dev": true, "license": "MIT", "engines": { @@ -457,9 +453,9 @@ } }, "node_modules/@commitlint/top-level": { - "version": "19.5.0", - "resolved": "https://registry.npmjs.org/@commitlint/top-level/-/top-level-19.5.0.tgz", - "integrity": "sha512-IP1YLmGAk0yWrImPRRc578I3dDUI5A2UBJx9FbSOjxe9sTlzFiwVJ+zeMLgAtHMtGZsC8LUnzmW1qRemkFU4ng==", + "version": "19.8.0", + "resolved": "https://registry.npmjs.org/@commitlint/top-level/-/top-level-19.8.0.tgz", + "integrity": "sha512-Rphgoc/omYZisoNkcfaBRPQr4myZEHhLPx2/vTXNLjiCw4RgfPR1wEgUpJ9OOmDCiv5ZyIExhprNLhteqH4FuQ==", "dev": true, "license": "MIT", "dependencies": { @@ -470,9 +466,9 @@ } }, "node_modules/@commitlint/types": { - "version": "19.5.0", - "resolved": "https://registry.npmjs.org/@commitlint/types/-/types-19.5.0.tgz", - "integrity": "sha512-DSHae2obMSMkAtTBSOulg5X7/z+rGLxcXQIkg3OmWvY6wifojge5uVMydfhUvs7yQj+V7jNmRZ2Xzl8GJyqRgg==", + "version": "19.8.0", + "resolved": "https://registry.npmjs.org/@commitlint/types/-/types-19.8.0.tgz", + "integrity": "sha512-LRjP623jPyf3Poyfb0ohMj8I3ORyBDOwXAgxxVPbSD0unJuW2mJWeiRfaQinjtccMqC5Wy1HOMfa4btKjbNxbg==", "dev": true, "license": "MIT", "dependencies": { @@ -484,9 +480,9 @@ } }, "node_modules/@esbuild/aix-ppc64": { - "version": "0.23.1", - "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.23.1.tgz", - "integrity": "sha512-6VhYk1diRqrhBAqpJEdjASR/+WVRtfjpqKuNw11cLiaWpAT/Uu+nokB+UJnevzy/P9C/ty6AOe0dwueMrGh/iQ==", + "version": "0.25.0", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.25.0.tgz", + "integrity": "sha512-O7vun9Sf8DFjH2UtqK8Ku3LkquL9SZL8OLY1T5NZkA34+wG3OQF7cl4Ql8vdNzM6fzBbYfLaiRLIOZ+2FOCgBQ==", "cpu": [ "ppc64" ], @@ -501,9 +497,9 @@ } }, "node_modules/@esbuild/android-arm": { - "version": "0.23.1", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.23.1.tgz", - "integrity": "sha512-uz6/tEy2IFm9RYOyvKl88zdzZfwEfKZmnX9Cj1BHjeSGNuGLuMD1kR8y5bteYmwqKm1tj8m4cb/aKEorr6fHWQ==", + "version": "0.25.0", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.25.0.tgz", + "integrity": "sha512-PTyWCYYiU0+1eJKmw21lWtC+d08JDZPQ5g+kFyxP0V+es6VPPSUhM6zk8iImp2jbV6GwjX4pap0JFbUQN65X1g==", "cpu": [ "arm" ], @@ -518,9 +514,9 @@ } }, "node_modules/@esbuild/android-arm64": { - "version": "0.23.1", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.23.1.tgz", - "integrity": "sha512-xw50ipykXcLstLeWH7WRdQuysJqejuAGPd30vd1i5zSyKK3WE+ijzHmLKxdiCMtH1pHz78rOg0BKSYOSB/2Khw==", + "version": "0.25.0", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.25.0.tgz", + "integrity": "sha512-grvv8WncGjDSyUBjN9yHXNt+cq0snxXbDxy5pJtzMKGmmpPxeAmAhWxXI+01lU5rwZomDgD3kJwulEnhTRUd6g==", "cpu": [ "arm64" ], @@ -535,9 +531,9 @@ } }, "node_modules/@esbuild/android-x64": { - "version": "0.23.1", - "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.23.1.tgz", - "integrity": "sha512-nlN9B69St9BwUoB+jkyU090bru8L0NA3yFvAd7k8dNsVH8bi9a8cUAUSEcEEgTp2z3dbEDGJGfP6VUnkQnlReg==", + "version": "0.25.0", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.25.0.tgz", + "integrity": "sha512-m/ix7SfKG5buCnxasr52+LI78SQ+wgdENi9CqyCXwjVR2X4Jkz+BpC3le3AoBPYTC9NHklwngVXvbJ9/Akhrfg==", "cpu": [ "x64" ], @@ -552,9 +548,9 @@ } }, "node_modules/@esbuild/darwin-arm64": { - "version": "0.23.1", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.23.1.tgz", - "integrity": "sha512-YsS2e3Wtgnw7Wq53XXBLcV6JhRsEq8hkfg91ESVadIrzr9wO6jJDMZnCQbHm1Guc5t/CdDiFSSfWP58FNuvT3Q==", + "version": "0.25.0", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.25.0.tgz", + "integrity": "sha512-mVwdUb5SRkPayVadIOI78K7aAnPamoeFR2bT5nszFUZ9P8UpK4ratOdYbZZXYSqPKMHfS1wdHCJk1P1EZpRdvw==", "cpu": [ "arm64" ], @@ -569,9 +565,9 @@ } }, "node_modules/@esbuild/darwin-x64": { - "version": "0.23.1", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.23.1.tgz", - "integrity": "sha512-aClqdgTDVPSEGgoCS8QDG37Gu8yc9lTHNAQlsztQ6ENetKEO//b8y31MMu2ZaPbn4kVsIABzVLXYLhCGekGDqw==", + "version": "0.25.0", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.25.0.tgz", + "integrity": "sha512-DgDaYsPWFTS4S3nWpFcMn/33ZZwAAeAFKNHNa1QN0rI4pUjgqf0f7ONmXf6d22tqTY+H9FNdgeaAa+YIFUn2Rg==", "cpu": [ "x64" ], @@ -586,9 +582,9 @@ } }, "node_modules/@esbuild/freebsd-arm64": { - "version": "0.23.1", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.23.1.tgz", - "integrity": "sha512-h1k6yS8/pN/NHlMl5+v4XPfikhJulk4G+tKGFIOwURBSFzE8bixw1ebjluLOjfwtLqY0kewfjLSrO6tN2MgIhA==", + "version": "0.25.0", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.25.0.tgz", + "integrity": "sha512-VN4ocxy6dxefN1MepBx/iD1dH5K8qNtNe227I0mnTRjry8tj5MRk4zprLEdG8WPyAPb93/e4pSgi1SoHdgOa4w==", "cpu": [ "arm64" ], @@ -603,9 +599,9 @@ } }, "node_modules/@esbuild/freebsd-x64": { - "version": "0.23.1", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.23.1.tgz", - "integrity": "sha512-lK1eJeyk1ZX8UklqFd/3A60UuZ/6UVfGT2LuGo3Wp4/z7eRTRYY+0xOu2kpClP+vMTi9wKOfXi2vjUpO1Ro76g==", + "version": "0.25.0", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.25.0.tgz", + "integrity": "sha512-mrSgt7lCh07FY+hDD1TxiTyIHyttn6vnjesnPoVDNmDfOmggTLXRv8Id5fNZey1gl/V2dyVK1VXXqVsQIiAk+A==", "cpu": [ "x64" ], @@ -620,9 +616,9 @@ } }, "node_modules/@esbuild/linux-arm": { - "version": "0.23.1", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.23.1.tgz", - "integrity": "sha512-CXXkzgn+dXAPs3WBwE+Kvnrf4WECwBdfjfeYHpMeVxWE0EceB6vhWGShs6wi0IYEqMSIzdOF1XjQ/Mkm5d7ZdQ==", + "version": "0.25.0", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.25.0.tgz", + "integrity": "sha512-vkB3IYj2IDo3g9xX7HqhPYxVkNQe8qTK55fraQyTzTX/fxaDtXiEnavv9geOsonh2Fd2RMB+i5cbhu2zMNWJwg==", "cpu": [ "arm" ], @@ -637,9 +633,9 @@ } }, "node_modules/@esbuild/linux-arm64": { - "version": "0.23.1", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.23.1.tgz", - "integrity": "sha512-/93bf2yxencYDnItMYV/v116zff6UyTjo4EtEQjUBeGiVpMmffDNUyD9UN2zV+V3LRV3/on4xdZ26NKzn6754g==", + "version": "0.25.0", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.25.0.tgz", + "integrity": "sha512-9QAQjTWNDM/Vk2bgBl17yWuZxZNQIF0OUUuPZRKoDtqF2k4EtYbpyiG5/Dk7nqeK6kIJWPYldkOcBqjXjrUlmg==", "cpu": [ "arm64" ], @@ -654,9 +650,9 @@ } }, "node_modules/@esbuild/linux-ia32": { - "version": "0.23.1", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.23.1.tgz", - "integrity": "sha512-VTN4EuOHwXEkXzX5nTvVY4s7E/Krz7COC8xkftbbKRYAl96vPiUssGkeMELQMOnLOJ8k3BY1+ZY52tttZnHcXQ==", + "version": "0.25.0", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.25.0.tgz", + "integrity": "sha512-43ET5bHbphBegyeqLb7I1eYn2P/JYGNmzzdidq/w0T8E2SsYL1U6un2NFROFRg1JZLTzdCoRomg8Rvf9M6W6Gg==", "cpu": [ "ia32" ], @@ -671,9 +667,9 @@ } }, "node_modules/@esbuild/linux-loong64": { - "version": "0.23.1", - "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.23.1.tgz", - "integrity": "sha512-Vx09LzEoBa5zDnieH8LSMRToj7ir/Jeq0Gu6qJ/1GcBq9GkfoEAoXvLiW1U9J1qE/Y/Oyaq33w5p2ZWrNNHNEw==", + "version": "0.25.0", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.25.0.tgz", + "integrity": "sha512-fC95c/xyNFueMhClxJmeRIj2yrSMdDfmqJnyOY4ZqsALkDrrKJfIg5NTMSzVBr5YW1jf+l7/cndBfP3MSDpoHw==", "cpu": [ "loong64" ], @@ -688,9 +684,9 @@ } }, "node_modules/@esbuild/linux-mips64el": { - "version": "0.23.1", - "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.23.1.tgz", - "integrity": "sha512-nrFzzMQ7W4WRLNUOU5dlWAqa6yVeI0P78WKGUo7lg2HShq/yx+UYkeNSE0SSfSure0SqgnsxPvmAUu/vu0E+3Q==", + "version": "0.25.0", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.25.0.tgz", + "integrity": "sha512-nkAMFju7KDW73T1DdH7glcyIptm95a7Le8irTQNO/qtkoyypZAnjchQgooFUDQhNAy4iu08N79W4T4pMBwhPwQ==", "cpu": [ "mips64el" ], @@ -705,9 +701,9 @@ } }, "node_modules/@esbuild/linux-ppc64": { - "version": "0.23.1", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.23.1.tgz", - "integrity": "sha512-dKN8fgVqd0vUIjxuJI6P/9SSSe/mB9rvA98CSH2sJnlZ/OCZWO1DJvxj8jvKTfYUdGfcq2dDxoKaC6bHuTlgcw==", + "version": "0.25.0", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.25.0.tgz", + "integrity": "sha512-NhyOejdhRGS8Iwv+KKR2zTq2PpysF9XqY+Zk77vQHqNbo/PwZCzB5/h7VGuREZm1fixhs4Q/qWRSi5zmAiO4Fw==", "cpu": [ "ppc64" ], @@ -722,9 +718,9 @@ } }, "node_modules/@esbuild/linux-riscv64": { - "version": "0.23.1", - "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.23.1.tgz", - "integrity": "sha512-5AV4Pzp80fhHL83JM6LoA6pTQVWgB1HovMBsLQ9OZWLDqVY8MVobBXNSmAJi//Csh6tcY7e7Lny2Hg1tElMjIA==", + "version": "0.25.0", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.25.0.tgz", + "integrity": "sha512-5S/rbP5OY+GHLC5qXp1y/Mx//e92L1YDqkiBbO9TQOvuFXM+iDqUNG5XopAnXoRH3FjIUDkeGcY1cgNvnXp/kA==", "cpu": [ "riscv64" ], @@ -739,9 +735,9 @@ } }, "node_modules/@esbuild/linux-s390x": { - "version": "0.23.1", - "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.23.1.tgz", - "integrity": "sha512-9ygs73tuFCe6f6m/Tb+9LtYxWR4c9yg7zjt2cYkjDbDpV/xVn+68cQxMXCjUpYwEkze2RcU/rMnfIXNRFmSoDw==", + "version": "0.25.0", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.25.0.tgz", + "integrity": "sha512-XM2BFsEBz0Fw37V0zU4CXfcfuACMrppsMFKdYY2WuTS3yi8O1nFOhil/xhKTmE1nPmVyvQJjJivgDT+xh8pXJA==", "cpu": [ "s390x" ], @@ -756,9 +752,9 @@ } }, "node_modules/@esbuild/linux-x64": { - "version": "0.23.1", - "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.23.1.tgz", - "integrity": "sha512-EV6+ovTsEXCPAp58g2dD68LxoP/wK5pRvgy0J/HxPGB009omFPv3Yet0HiaqvrIrgPTBuC6wCH1LTOY91EO5hQ==", + "version": "0.25.0", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.25.0.tgz", + "integrity": "sha512-9yl91rHw/cpwMCNytUDxwj2XjFpxML0y9HAOH9pNVQDpQrBxHy01Dx+vaMu0N1CKa/RzBD2hB4u//nfc+Sd3Cw==", "cpu": [ "x64" ], @@ -772,10 +768,27 @@ "node": ">=18" } }, + "node_modules/@esbuild/netbsd-arm64": { + "version": "0.25.0", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.25.0.tgz", + "integrity": "sha512-RuG4PSMPFfrkH6UwCAqBzauBWTygTvb1nxWasEJooGSJ/NwRw7b2HOwyRTQIU97Hq37l3npXoZGYMy3b3xYvPw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=18" + } + }, "node_modules/@esbuild/netbsd-x64": { - "version": "0.23.1", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.23.1.tgz", - "integrity": "sha512-aevEkCNu7KlPRpYLjwmdcuNz6bDFiE7Z8XC4CPqExjTvrHugh28QzUXVOZtiYghciKUacNktqxdpymplil1beA==", + "version": "0.25.0", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.25.0.tgz", + "integrity": "sha512-jl+qisSB5jk01N5f7sPCsBENCOlPiS/xptD5yxOx2oqQfyourJwIKLRA2yqWdifj3owQZCL2sn6o08dBzZGQzA==", "cpu": [ "x64" ], @@ -790,9 +803,9 @@ } }, "node_modules/@esbuild/openbsd-arm64": { - "version": "0.23.1", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.23.1.tgz", - "integrity": "sha512-3x37szhLexNA4bXhLrCC/LImN/YtWis6WXr1VESlfVtVeoFJBRINPJ3f0a/6LV8zpikqoUg4hyXw0sFBt5Cr+Q==", + "version": "0.25.0", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.25.0.tgz", + "integrity": "sha512-21sUNbq2r84YE+SJDfaQRvdgznTD8Xc0oc3p3iW/a1EVWeNj/SdUCbm5U0itZPQYRuRTW20fPMWMpcrciH2EJw==", "cpu": [ "arm64" ], @@ -807,9 +820,9 @@ } }, "node_modules/@esbuild/openbsd-x64": { - "version": "0.23.1", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.23.1.tgz", - "integrity": "sha512-aY2gMmKmPhxfU+0EdnN+XNtGbjfQgwZj43k8G3fyrDM/UdZww6xrWxmDkuz2eCZchqVeABjV5BpildOrUbBTqA==", + "version": "0.25.0", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.25.0.tgz", + "integrity": "sha512-2gwwriSMPcCFRlPlKx3zLQhfN/2WjJ2NSlg5TKLQOJdV0mSxIcYNTMhk3H3ulL/cak+Xj0lY1Ym9ysDV1igceg==", "cpu": [ "x64" ], @@ -824,9 +837,9 @@ } }, "node_modules/@esbuild/sunos-x64": { - "version": "0.23.1", - "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.23.1.tgz", - "integrity": "sha512-RBRT2gqEl0IKQABT4XTj78tpk9v7ehp+mazn2HbUeZl1YMdaGAQqhapjGTCe7uw7y0frDi4gS0uHzhvpFuI1sA==", + "version": "0.25.0", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.25.0.tgz", + "integrity": "sha512-bxI7ThgLzPrPz484/S9jLlvUAHYMzy6I0XiU1ZMeAEOBcS0VePBFxh1JjTQt3Xiat5b6Oh4x7UC7IwKQKIJRIg==", "cpu": [ "x64" ], @@ -841,9 +854,9 @@ } }, "node_modules/@esbuild/win32-arm64": { - "version": "0.23.1", - "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.23.1.tgz", - "integrity": "sha512-4O+gPR5rEBe2FpKOVyiJ7wNDPA8nGzDuJ6gN4okSA1gEOYZ67N8JPk58tkWtdtPeLz7lBnY6I5L3jdsr3S+A6A==", + "version": "0.25.0", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.25.0.tgz", + "integrity": "sha512-ZUAc2YK6JW89xTbXvftxdnYy3m4iHIkDtK3CLce8wg8M2L+YZhIvO1DKpxrd0Yr59AeNNkTiic9YLf6FTtXWMw==", "cpu": [ "arm64" ], @@ -858,9 +871,9 @@ } }, "node_modules/@esbuild/win32-ia32": { - "version": "0.23.1", - "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.23.1.tgz", - "integrity": "sha512-BcaL0Vn6QwCwre3Y717nVHZbAa4UBEigzFm6VdsVdT/MbZ38xoj1X9HPkZhbmaBGUD1W8vxAfffbDe8bA6AKnQ==", + "version": "0.25.0", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.25.0.tgz", + "integrity": "sha512-eSNxISBu8XweVEWG31/JzjkIGbGIJN/TrRoiSVZwZ6pkC6VX4Im/WV2cz559/TXLcYbcrDN8JtKgd9DJVIo8GA==", "cpu": [ "ia32" ], @@ -875,9 +888,9 @@ } }, "node_modules/@esbuild/win32-x64": { - "version": "0.23.1", - "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.23.1.tgz", - "integrity": "sha512-BHpFFeslkWrXWyUPnbKm+xYYVYruCinGcftSBaa8zoF9hZO4BcSCFUvHVTtzpIY6YzUnYtuEhZ+C9iEXjxnasg==", + "version": "0.25.0", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.25.0.tgz", + "integrity": "sha512-ZENoHJBxA20C2zFzh6AI4fT6RraMzjYw4xKWemRTRmRVtN9c5DcH9r/f2ihEkMjOW5eGgrwCslG/+Y/3bL+DHQ==", "cpu": [ "x64" ], @@ -892,9 +905,9 @@ } }, "node_modules/@eslint-community/eslint-utils": { - "version": "4.4.1", - "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.1.tgz", - "integrity": "sha512-s3O3waFUrMV8P/XaF/+ZTp1X9XBZW1a4B97ZnjQF2KYWaFD2A8KyFBsrsfSjEmjn3RGWAIuvlneuZm3CUK3jbA==", + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.5.0.tgz", + "integrity": "sha512-RoV8Xs9eNwiDvhv7M+xcL4PWyRyIXRY/FLp3buU4h1EYfdF7unWUy3dOjPqb3C7rMUewIcqwW850PgS8h1o1yg==", "dev": true, "license": "MIT", "dependencies": { @@ -921,13 +934,13 @@ } }, "node_modules/@eslint/config-array": { - "version": "0.18.0", - "resolved": "https://registry.npmjs.org/@eslint/config-array/-/config-array-0.18.0.tgz", - "integrity": "sha512-fTxvnS1sRMu3+JjXwJG0j/i4RT9u4qJ+lqS/yCGap4lH4zZGzQ7tu+xZqQmcMZq5OBZDL4QRxQzRjkWcGt8IVw==", + "version": "0.19.2", + "resolved": "https://registry.npmjs.org/@eslint/config-array/-/config-array-0.19.2.tgz", + "integrity": "sha512-GNKqxfHG2ySmJOBSHg7LxeUx4xpuCoFjacmlCoYWEbaPXLwvfIjixRI12xCQZeULksQb23uiA8F40w5TojpV7w==", "dev": true, "license": "Apache-2.0", "dependencies": { - "@eslint/object-schema": "^2.1.4", + "@eslint/object-schema": "^2.1.6", "debug": "^4.3.1", "minimatch": "^3.1.2" }, @@ -935,20 +948,57 @@ "node": "^18.18.0 || ^20.9.0 || >=21.1.0" } }, + "node_modules/@eslint/config-array/node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/@eslint/config-array/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/@eslint/config-helpers": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/@eslint/config-helpers/-/config-helpers-0.1.0.tgz", + "integrity": "sha512-kLrdPDJE1ckPo94kmPPf9Hfd0DU0Jw6oKYrhe+pwSC0iTUInmTa+w6fw8sGgcfkFJGNdWOUeOaDM4quW4a7OkA==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, "node_modules/@eslint/core": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/@eslint/core/-/core-0.6.0.tgz", - "integrity": "sha512-8I2Q8ykA4J0x0o7cg67FPVnehcqWTBehu/lmY+bolPFHGjh49YzGBMXTvpqVgEbBdvNCSxj6iFgiIyHzf03lzg==", + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/@eslint/core/-/core-0.12.0.tgz", + "integrity": "sha512-cmrR6pytBuSMTaBweKoGMwu3EiHiEC+DoyupPmlZ0HxBJBtIxwe+j/E4XPIKNx+Q74c8lXKPwYawBf5glsTkHg==", "dev": true, "license": "Apache-2.0", + "dependencies": { + "@types/json-schema": "^7.0.15" + }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" } }, "node_modules/@eslint/eslintrc": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-3.1.0.tgz", - "integrity": "sha512-4Bfj15dVJdoy3RfZmmo86RK1Fwzn6SstsvK9JS+BaVKqC6QQQQyXekNaC+g+LKNgkQ+2VhGAzm6hO40AhMR3zQ==", + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-3.3.0.tgz", + "integrity": "sha512-yaVPAiNAalnCZedKLdR21GOGILMLKPyqSLWaAjQFvYA2i/ciDi8ArYVr69Anohb6cH2Ukhqti4aFnYyPm8wdwQ==", "dev": true, "license": "MIT", "dependencies": { @@ -986,6 +1036,17 @@ "url": "https://github.com/sponsors/epoberezkin" } }, + "node_modules/@eslint/eslintrc/node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, "node_modules/@eslint/eslintrc/node_modules/json-schema-traverse": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", @@ -993,10 +1054,23 @@ "dev": true, "license": "MIT" }, + "node_modules/@eslint/eslintrc/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, "node_modules/@eslint/js": { - "version": "9.12.0", - "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.12.0.tgz", - "integrity": "sha512-eohesHH8WFRUprDNyEREgqP6beG6htMeUYeCpkEgBCieCMme5r9zFWjzAJp//9S+Kub4rqE+jXe9Cp1a7IYIIA==", + "version": "9.22.0", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.22.0.tgz", + "integrity": "sha512-vLFajx9o8d1/oL2ZkpMYbkLv8nDB6yaIwFNt7nI4+I80U/z03SxmfOMsLbvWr3p7C+Wnoh//aOu2pQW8cS0HCQ==", "dev": true, "license": "MIT", "engines": { @@ -1004,9 +1078,9 @@ } }, "node_modules/@eslint/object-schema": { - "version": "2.1.5", - "resolved": "https://registry.npmjs.org/@eslint/object-schema/-/object-schema-2.1.5.tgz", - "integrity": "sha512-o0bhxnL89h5Bae5T318nFoFzGy+YE5i/gGkoPAgkmTVdRKTiv3p8JHevPiPaMwoloKfEiiaHlawCqaZMqRm+XQ==", + "version": "2.1.6", + "resolved": "https://registry.npmjs.org/@eslint/object-schema/-/object-schema-2.1.6.tgz", + "integrity": "sha512-RBMg5FRL0I0gs51M/guSAj5/e14VQ4tpZnQNWwuDT66P14I43ItmPfIZRhO9fUVIPOAQXU47atlywZ/czoqFPA==", "dev": true, "license": "Apache-2.0", "engines": { @@ -1014,18 +1088,31 @@ } }, "node_modules/@eslint/plugin-kit": { - "version": "0.2.4", - "resolved": "https://registry.npmjs.org/@eslint/plugin-kit/-/plugin-kit-0.2.4.tgz", - "integrity": "sha512-zSkKow6H5Kdm0ZUQUB2kV5JIXqoG0+uH5YADhaEHswm664N9Db8dXSi0nMJpacpMf+MyyglF1vnZohpEg5yUtg==", + "version": "0.2.7", + "resolved": "https://registry.npmjs.org/@eslint/plugin-kit/-/plugin-kit-0.2.7.tgz", + "integrity": "sha512-JubJ5B2pJ4k4yGxaNLdbjrnk9d/iDz6/q8wOilpIowd6PJPgaxCuHBnBszq7Ce2TyMrywm5r4PnKm6V3iiZF+g==", "dev": true, "license": "Apache-2.0", "dependencies": { + "@eslint/core": "^0.12.0", "levn": "^0.4.1" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" } }, + "node_modules/@gerrit0/mini-shiki": { + "version": "1.27.2", + "resolved": "https://registry.npmjs.org/@gerrit0/mini-shiki/-/mini-shiki-1.27.2.tgz", + "integrity": "sha512-GeWyHz8ao2gBiUW4OJnQDxXQnFgZQwwQk05t/CVVgNBN7/rK8XZ7xY6YhLVv9tH3VppWWmr9DCl3MwemB/i+Og==", + "dev": true, + "license": "MIT", + "dependencies": { + "@shikijs/engine-oniguruma": "^1.27.2", + "@shikijs/types": "^1.27.2", + "@shikijs/vscode-textmate": "^10.0.1" + } + }, "node_modules/@humanfs/core": { "version": "0.19.1", "resolved": "https://registry.npmjs.org/@humanfs/core/-/core-0.19.1.tgz", @@ -1050,6 +1137,20 @@ "node": ">=18.18.0" } }, + "node_modules/@humanfs/node/node_modules/@humanwhocodes/retry": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/retry/-/retry-0.3.1.tgz", + "integrity": "sha512-JBxkERygn7Bv/GbN5Rv8Ul6LVknS+5Bp6RgDC/O8gEBU/yeH5Ui5C/OlWrTb6qct7LjjfT6Re2NxB0ln0yYybA==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=18.18" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/nzakas" + } + }, "node_modules/@humanwhocodes/module-importer": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", @@ -1065,9 +1166,9 @@ } }, "node_modules/@humanwhocodes/retry": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/@humanwhocodes/retry/-/retry-0.3.1.tgz", - "integrity": "sha512-JBxkERygn7Bv/GbN5Rv8Ul6LVknS+5Bp6RgDC/O8gEBU/yeH5Ui5C/OlWrTb6qct7LjjfT6Re2NxB0ln0yYybA==", + "version": "0.4.2", + "resolved": "https://registry.npmjs.org/@humanwhocodes/retry/-/retry-0.4.2.tgz", + "integrity": "sha512-xeO57FpIu4p1Ri3Jq/EXq4ClRm86dVF2z/+kvFnyqVYRavTZmaFaUBbWCOuuTh0o/g7DSsk6kc2vrS4Vl5oPOQ==", "dev": true, "license": "Apache-2.0", "engines": { @@ -1284,9 +1385,9 @@ } }, "node_modules/@octokit/auth-token": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/@octokit/auth-token/-/auth-token-5.1.1.tgz", - "integrity": "sha512-rh3G3wDO8J9wSjfI436JUKzHIxq8NaiL0tVeB2aXmG6p/9859aUOAjA9pmSPNGGZxfwmaJ9ozOJImuNVJdpvbA==", + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/@octokit/auth-token/-/auth-token-5.1.2.tgz", + "integrity": "sha512-JcQDsBdg49Yky2w2ld20IHAlwr8d/d8N6NiOXbtuoPCqzbsiJgF633mVUw3x4mo0H5ypataQIX7SFu3yy44Mpw==", "dev": true, "license": "MIT", "engines": { @@ -1294,17 +1395,17 @@ } }, "node_modules/@octokit/core": { - "version": "6.1.2", - "resolved": "https://registry.npmjs.org/@octokit/core/-/core-6.1.2.tgz", - "integrity": "sha512-hEb7Ma4cGJGEUNOAVmyfdB/3WirWMg5hDuNFVejGEDFqupeOysLc2sG6HJxY2etBp5YQu5Wtxwi020jS9xlUwg==", + "version": "6.1.4", + "resolved": "https://registry.npmjs.org/@octokit/core/-/core-6.1.4.tgz", + "integrity": "sha512-lAS9k7d6I0MPN+gb9bKDt7X8SdxknYqAMh44S5L+lNqIN2NuV8nvv3g8rPp7MuRxcOpxpUIATWprO0C34a8Qmg==", "dev": true, "license": "MIT", "dependencies": { "@octokit/auth-token": "^5.0.0", - "@octokit/graphql": "^8.0.0", - "@octokit/request": "^9.0.0", - "@octokit/request-error": "^6.0.1", - "@octokit/types": "^13.0.0", + "@octokit/graphql": "^8.1.2", + "@octokit/request": "^9.2.1", + "@octokit/request-error": "^6.1.7", + "@octokit/types": "^13.6.2", "before-after-hook": "^3.0.2", "universal-user-agent": "^7.0.0" }, @@ -1313,13 +1414,13 @@ } }, "node_modules/@octokit/endpoint": { - "version": "10.1.1", - "resolved": "https://registry.npmjs.org/@octokit/endpoint/-/endpoint-10.1.1.tgz", - "integrity": "sha512-JYjh5rMOwXMJyUpj028cu0Gbp7qe/ihxfJMLc8VZBMMqSwLgOxDI1911gV4Enl1QSavAQNJcwmwBF9M0VvLh6Q==", + "version": "10.1.3", + "resolved": "https://registry.npmjs.org/@octokit/endpoint/-/endpoint-10.1.3.tgz", + "integrity": "sha512-nBRBMpKPhQUxCsQQeW+rCJ/OPSMcj3g0nfHn01zGYZXuNDvvXudF/TYY6APj5THlurerpFN4a/dQAIAaM6BYhA==", "dev": true, "license": "MIT", "dependencies": { - "@octokit/types": "^13.0.0", + "@octokit/types": "^13.6.2", "universal-user-agent": "^7.0.2" }, "engines": { @@ -1327,14 +1428,14 @@ } }, "node_modules/@octokit/graphql": { - "version": "8.1.1", - "resolved": "https://registry.npmjs.org/@octokit/graphql/-/graphql-8.1.1.tgz", - "integrity": "sha512-ukiRmuHTi6ebQx/HFRCXKbDlOh/7xEV6QUXaE7MJEKGNAncGI/STSbOkl12qVXZrfZdpXctx5O9X1AIaebiDBg==", + "version": "8.2.1", + "resolved": "https://registry.npmjs.org/@octokit/graphql/-/graphql-8.2.1.tgz", + "integrity": "sha512-n57hXtOoHrhwTWdvhVkdJHdhTv0JstjDbDRhJfwIRNfFqmSo1DaK/mD2syoNUoLCyqSjBpGAKOG0BuwF392slw==", "dev": true, "license": "MIT", "dependencies": { - "@octokit/request": "^9.0.0", - "@octokit/types": "^13.0.0", + "@octokit/request": "^9.2.2", + "@octokit/types": "^13.8.0", "universal-user-agent": "^7.0.0" }, "engines": { @@ -1342,20 +1443,20 @@ } }, "node_modules/@octokit/openapi-types": { - "version": "22.2.0", - "resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-22.2.0.tgz", - "integrity": "sha512-QBhVjcUa9W7Wwhm6DBFu6ZZ+1/t/oYxqc2tp81Pi41YNuJinbFRx8B133qVOrAaBbF7D/m0Et6f9/pZt9Rc+tg==", + "version": "23.0.1", + "resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-23.0.1.tgz", + "integrity": "sha512-izFjMJ1sir0jn0ldEKhZ7xegCTj/ObmEDlEfpFrx4k/JyZSMRHbO3/rBwgE7f3m2DHt+RrNGIVw4wSmwnm3t/g==", "dev": true, "license": "MIT" }, "node_modules/@octokit/plugin-paginate-rest": { - "version": "11.3.6", - "resolved": "https://registry.npmjs.org/@octokit/plugin-paginate-rest/-/plugin-paginate-rest-11.3.6.tgz", - "integrity": "sha512-zcvqqf/+TicbTCa/Z+3w4eBJcAxCFymtc0UAIsR3dEVoNilWld4oXdscQ3laXamTszUZdusw97K8+DrbFiOwjw==", + "version": "11.4.3", + "resolved": "https://registry.npmjs.org/@octokit/plugin-paginate-rest/-/plugin-paginate-rest-11.4.3.tgz", + "integrity": "sha512-tBXaAbXkqVJlRoA/zQVe9mUdb8rScmivqtpv3ovsC5xhje/a+NOCivs7eUhWBwCApJVsR4G5HMeaLbq7PxqZGA==", "dev": true, "license": "MIT", "dependencies": { - "@octokit/types": "^13.6.2" + "@octokit/types": "^13.7.0" }, "engines": { "node": ">= 18" @@ -1365,14 +1466,14 @@ } }, "node_modules/@octokit/plugin-retry": { - "version": "7.1.2", - "resolved": "https://registry.npmjs.org/@octokit/plugin-retry/-/plugin-retry-7.1.2.tgz", - "integrity": "sha512-XOWnPpH2kJ5VTwozsxGurw+svB2e61aWlmk5EVIYZPwFK5F9h4cyPyj9CIKRyMXMHSwpIsI3mPOdpMmrRhe7UQ==", + "version": "7.1.4", + "resolved": "https://registry.npmjs.org/@octokit/plugin-retry/-/plugin-retry-7.1.4.tgz", + "integrity": "sha512-7AIP4p9TttKN7ctygG4BtR7rrB0anZqoU9ThXFk8nETqIfvgPUANTSYHqWYknK7W3isw59LpZeLI8pcEwiJdRg==", "dev": true, "license": "MIT", "dependencies": { - "@octokit/request-error": "^6.0.0", - "@octokit/types": "^13.0.0", + "@octokit/request-error": "^6.1.7", + "@octokit/types": "^13.6.2", "bottleneck": "^2.15.3" }, "engines": { @@ -1383,32 +1484,33 @@ } }, "node_modules/@octokit/plugin-throttling": { - "version": "9.3.2", - "resolved": "https://registry.npmjs.org/@octokit/plugin-throttling/-/plugin-throttling-9.3.2.tgz", - "integrity": "sha512-FqpvcTpIWFpMMwIeSoypoJXysSAQ3R+ALJhXXSG1HTP3YZOIeLmcNcimKaXxTcws+Sh6yoRl13SJ5r8sXc1Fhw==", + "version": "9.4.0", + "resolved": "https://registry.npmjs.org/@octokit/plugin-throttling/-/plugin-throttling-9.4.0.tgz", + "integrity": "sha512-IOlXxXhZA4Z3m0EEYtrrACkuHiArHLZ3CvqWwOez/pURNqRuwfoFlTPbN5Muf28pzFuztxPyiUiNwz8KctdZaQ==", "dev": true, "license": "MIT", "dependencies": { - "@octokit/types": "^13.0.0", + "@octokit/types": "^13.7.0", "bottleneck": "^2.15.3" }, "engines": { "node": ">= 18" }, "peerDependencies": { - "@octokit/core": "^6.0.0" + "@octokit/core": "^6.1.3" } }, "node_modules/@octokit/request": { - "version": "9.1.3", - "resolved": "https://registry.npmjs.org/@octokit/request/-/request-9.1.3.tgz", - "integrity": "sha512-V+TFhu5fdF3K58rs1pGUJIDH5RZLbZm5BI+MNF+6o/ssFNT4vWlCh/tVpF3NxGtP15HUxTTMUbsG5llAuU2CZA==", + "version": "9.2.2", + "resolved": "https://registry.npmjs.org/@octokit/request/-/request-9.2.2.tgz", + "integrity": "sha512-dZl0ZHx6gOQGcffgm1/Sf6JfEpmh34v3Af2Uci02vzUYz6qEN6zepoRtmybWXIGXFIK8K9ylE3b+duCWqhArtg==", "dev": true, "license": "MIT", "dependencies": { - "@octokit/endpoint": "^10.0.0", - "@octokit/request-error": "^6.0.1", - "@octokit/types": "^13.1.0", + "@octokit/endpoint": "^10.1.3", + "@octokit/request-error": "^6.1.7", + "@octokit/types": "^13.6.2", + "fast-content-type-parse": "^2.0.0", "universal-user-agent": "^7.0.2" }, "engines": { @@ -1416,26 +1518,26 @@ } }, "node_modules/@octokit/request-error": { - "version": "6.1.5", - "resolved": "https://registry.npmjs.org/@octokit/request-error/-/request-error-6.1.5.tgz", - "integrity": "sha512-IlBTfGX8Yn/oFPMwSfvugfncK2EwRLjzbrpifNaMY8o/HTEAFqCA1FZxjD9cWvSKBHgrIhc4CSBIzMxiLsbzFQ==", + "version": "6.1.7", + "resolved": "https://registry.npmjs.org/@octokit/request-error/-/request-error-6.1.7.tgz", + "integrity": "sha512-69NIppAwaauwZv6aOzb+VVLwt+0havz9GT5YplkeJv7fG7a40qpLt/yZKyiDxAhgz0EtgNdNcb96Z0u+Zyuy2g==", "dev": true, "license": "MIT", "dependencies": { - "@octokit/types": "^13.0.0" + "@octokit/types": "^13.6.2" }, "engines": { "node": ">= 18" } }, "node_modules/@octokit/types": { - "version": "13.6.2", - "resolved": "https://registry.npmjs.org/@octokit/types/-/types-13.6.2.tgz", - "integrity": "sha512-WpbZfZUcZU77DrSW4wbsSgTPfKcp286q3ItaIgvSbBpZJlu6mnYXAkjZz6LVZPXkEvLIM8McanyZejKTYUHipA==", + "version": "13.8.0", + "resolved": "https://registry.npmjs.org/@octokit/types/-/types-13.8.0.tgz", + "integrity": "sha512-x7DjTIbEpEWXK99DMd01QfWy0hd5h4EN+Q7shkdKds3otGQP+oWE/y0A76i1OvH9fygo4ddvNf7ZvF0t78P98A==", "dev": true, "license": "MIT", "dependencies": { - "@octokit/openapi-types": "^22.2.0" + "@octokit/openapi-types": "^23.0.1" } }, "node_modules/@pkgjs/parseargs": { @@ -1508,19 +1610,19 @@ } }, "node_modules/@rollup/plugin-commonjs": { - "version": "28.0.0", - "resolved": "https://registry.npmjs.org/@rollup/plugin-commonjs/-/plugin-commonjs-28.0.0.tgz", - "integrity": "sha512-BJcu+a+Mpq476DMXG+hevgPSl56bkUoi88dKT8t3RyUp8kGuOh+2bU8Gs7zXDlu+fyZggnJ+iOBGrb/O1SorYg==", + "version": "28.0.3", + "resolved": "https://registry.npmjs.org/@rollup/plugin-commonjs/-/plugin-commonjs-28.0.3.tgz", + "integrity": "sha512-pyltgilam1QPdn+Zd9gaCfOLcnjMEJ9gV+bTw6/r73INdvzf1ah9zLIJBm+kW7R6IUFIQ1YO+VqZtYxZNWFPEQ==", "dev": true, "license": "MIT", "dependencies": { "@rollup/pluginutils": "^5.0.1", "commondir": "^1.0.1", "estree-walker": "^2.0.2", - "fdir": "^6.1.1", + "fdir": "^6.2.0", "is-reference": "1.2.1", "magic-string": "^0.30.3", - "picomatch": "^2.3.1" + "picomatch": "^4.0.2" }, "engines": { "node": ">=16.0.0 || 14 >= 14.17" @@ -1534,19 +1636,6 @@ } } }, - "node_modules/@rollup/plugin-commonjs/node_modules/picomatch": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", - "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8.6" - }, - "funding": { - "url": "https://github.com/sponsors/jonschlinkert" - } - }, "node_modules/@rollup/plugin-json": { "version": "6.1.0", "resolved": "https://registry.npmjs.org/@rollup/plugin-json/-/plugin-json-6.1.0.tgz", @@ -1569,9 +1658,9 @@ } }, "node_modules/@rollup/plugin-node-resolve": { - "version": "15.3.0", - "resolved": "https://registry.npmjs.org/@rollup/plugin-node-resolve/-/plugin-node-resolve-15.3.0.tgz", - "integrity": "sha512-9eO5McEICxMzJpDW9OnMYSv4Sta3hmt7VtBFz5zR9273suNOydOyq/FrGeGy+KsTRFm8w0SLVhzig2ILFT63Ag==", + "version": "16.0.0", + "resolved": "https://registry.npmjs.org/@rollup/plugin-node-resolve/-/plugin-node-resolve-16.0.0.tgz", + "integrity": "sha512-0FPvAeVUT/zdWoO0jnb/V5BlBsUSNfkIOtFHzMO4H9MOklrmQFY6FduVHKucNb/aTFxvnGhj4MNj/T1oNdDfNg==", "dev": true, "license": "MIT", "dependencies": { @@ -1644,9 +1733,9 @@ } }, "node_modules/@rollup/rollup-android-arm-eabi": { - "version": "4.29.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.29.1.tgz", - "integrity": "sha512-ssKhA8RNltTZLpG6/QNkCSge+7mBQGUqJRisZ2MDQcEGaK93QESEgWK2iOpIDZ7k9zPVkG5AS3ksvD5ZWxmItw==", + "version": "4.35.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.35.0.tgz", + "integrity": "sha512-uYQ2WfPaqz5QtVgMxfN6NpLD+no0MYHDBywl7itPYd3K5TjjSghNKmX8ic9S8NU8w81NVhJv/XojcHptRly7qQ==", "cpu": [ "arm" ], @@ -1658,9 +1747,9 @@ ] }, "node_modules/@rollup/rollup-android-arm64": { - "version": "4.29.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.29.1.tgz", - "integrity": "sha512-CaRfrV0cd+NIIcVVN/jx+hVLN+VRqnuzLRmfmlzpOzB87ajixsN/+9L5xNmkaUUvEbI5BmIKS+XTwXsHEb65Ew==", + "version": "4.35.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.35.0.tgz", + "integrity": "sha512-FtKddj9XZudurLhdJnBl9fl6BwCJ3ky8riCXjEw3/UIbjmIY58ppWwPEvU3fNu+W7FUsAsB1CdH+7EQE6CXAPA==", "cpu": [ "arm64" ], @@ -1672,9 +1761,9 @@ ] }, "node_modules/@rollup/rollup-darwin-arm64": { - "version": "4.29.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.29.1.tgz", - "integrity": "sha512-2ORr7T31Y0Mnk6qNuwtyNmy14MunTAMx06VAPI6/Ju52W10zk1i7i5U3vlDRWjhOI5quBcrvhkCHyF76bI7kEw==", + "version": "4.35.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.35.0.tgz", + "integrity": "sha512-Uk+GjOJR6CY844/q6r5DR/6lkPFOw0hjfOIzVx22THJXMxktXG6CbejseJFznU8vHcEBLpiXKY3/6xc+cBm65Q==", "cpu": [ "arm64" ], @@ -1686,9 +1775,9 @@ ] }, "node_modules/@rollup/rollup-darwin-x64": { - "version": "4.29.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.29.1.tgz", - "integrity": "sha512-j/Ej1oanzPjmN0tirRd5K2/nncAhS9W6ICzgxV+9Y5ZsP0hiGhHJXZ2JQ53iSSjj8m6cRY6oB1GMzNn2EUt6Ng==", + "version": "4.35.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.35.0.tgz", + "integrity": "sha512-3IrHjfAS6Vkp+5bISNQnPogRAW5GAV1n+bNCrDwXmfMHbPl5EhTmWtfmwlJxFRUCBZ+tZ/OxDyU08aF6NI/N5Q==", "cpu": [ "x64" ], @@ -1700,9 +1789,9 @@ ] }, "node_modules/@rollup/rollup-freebsd-arm64": { - "version": "4.29.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.29.1.tgz", - "integrity": "sha512-91C//G6Dm/cv724tpt7nTyP+JdN12iqeXGFM1SqnljCmi5yTXriH7B1r8AD9dAZByHpKAumqP1Qy2vVNIdLZqw==", + "version": "4.35.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.35.0.tgz", + "integrity": "sha512-sxjoD/6F9cDLSELuLNnY0fOrM9WA0KrM0vWm57XhrIMf5FGiN8D0l7fn+bpUeBSU7dCgPV2oX4zHAsAXyHFGcQ==", "cpu": [ "arm64" ], @@ -1714,9 +1803,9 @@ ] }, "node_modules/@rollup/rollup-freebsd-x64": { - "version": "4.29.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.29.1.tgz", - "integrity": "sha512-hEioiEQ9Dec2nIRoeHUP6hr1PSkXzQaCUyqBDQ9I9ik4gCXQZjJMIVzoNLBRGet+hIUb3CISMh9KXuCcWVW/8w==", + "version": "4.35.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.35.0.tgz", + "integrity": "sha512-2mpHCeRuD1u/2kruUiHSsnjWtHjqVbzhBkNVQ1aVD63CcexKVcQGwJ2g5VphOd84GvxfSvnnlEyBtQCE5hxVVw==", "cpu": [ "x64" ], @@ -1728,9 +1817,9 @@ ] }, "node_modules/@rollup/rollup-linux-arm-gnueabihf": { - "version": "4.29.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.29.1.tgz", - "integrity": "sha512-Py5vFd5HWYN9zxBv3WMrLAXY3yYJ6Q/aVERoeUFwiDGiMOWsMs7FokXihSOaT/PMWUty/Pj60XDQndK3eAfE6A==", + "version": "4.35.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.35.0.tgz", + "integrity": "sha512-mrA0v3QMy6ZSvEuLs0dMxcO2LnaCONs1Z73GUDBHWbY8tFFocM6yl7YyMu7rz4zS81NDSqhrUuolyZXGi8TEqg==", "cpu": [ "arm" ], @@ -1742,9 +1831,9 @@ ] }, "node_modules/@rollup/rollup-linux-arm-musleabihf": { - "version": "4.29.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.29.1.tgz", - "integrity": "sha512-RiWpGgbayf7LUcuSNIbahr0ys2YnEERD4gYdISA06wa0i8RALrnzflh9Wxii7zQJEB2/Eh74dX4y/sHKLWp5uQ==", + "version": "4.35.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.35.0.tgz", + "integrity": "sha512-DnYhhzcvTAKNexIql8pFajr0PiDGrIsBYPRvCKlA5ixSS3uwo/CWNZxB09jhIapEIg945KOzcYEAGGSmTSpk7A==", "cpu": [ "arm" ], @@ -1756,9 +1845,9 @@ ] }, "node_modules/@rollup/rollup-linux-arm64-gnu": { - "version": "4.29.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.29.1.tgz", - "integrity": "sha512-Z80O+taYxTQITWMjm/YqNoe9d10OX6kDh8X5/rFCMuPqsKsSyDilvfg+vd3iXIqtfmp+cnfL1UrYirkaF8SBZA==", + "version": "4.35.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.35.0.tgz", + "integrity": "sha512-uagpnH2M2g2b5iLsCTZ35CL1FgyuzzJQ8L9VtlJ+FckBXroTwNOaD0z0/UF+k5K3aNQjbm8LIVpxykUOQt1m/A==", "cpu": [ "arm64" ], @@ -1770,9 +1859,9 @@ ] }, "node_modules/@rollup/rollup-linux-arm64-musl": { - "version": "4.29.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.29.1.tgz", - "integrity": "sha512-fOHRtF9gahwJk3QVp01a/GqS4hBEZCV1oKglVVq13kcK3NeVlS4BwIFzOHDbmKzt3i0OuHG4zfRP0YoG5OF/rA==", + "version": "4.35.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.35.0.tgz", + "integrity": "sha512-XQxVOCd6VJeHQA/7YcqyV0/88N6ysSVzRjJ9I9UA/xXpEsjvAgDTgH3wQYz5bmr7SPtVK2TsP2fQ2N9L4ukoUg==", "cpu": [ "arm64" ], @@ -1784,9 +1873,9 @@ ] }, "node_modules/@rollup/rollup-linux-loongarch64-gnu": { - "version": "4.29.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loongarch64-gnu/-/rollup-linux-loongarch64-gnu-4.29.1.tgz", - "integrity": "sha512-5a7q3tnlbcg0OodyxcAdrrCxFi0DgXJSoOuidFUzHZ2GixZXQs6Tc3CHmlvqKAmOs5eRde+JJxeIf9DonkmYkw==", + "version": "4.35.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loongarch64-gnu/-/rollup-linux-loongarch64-gnu-4.35.0.tgz", + "integrity": "sha512-5pMT5PzfgwcXEwOaSrqVsz/LvjDZt+vQ8RT/70yhPU06PTuq8WaHhfT1LW+cdD7mW6i/J5/XIkX/1tCAkh1W6g==", "cpu": [ "loong64" ], @@ -1798,9 +1887,9 @@ ] }, "node_modules/@rollup/rollup-linux-powerpc64le-gnu": { - "version": "4.29.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.29.1.tgz", - "integrity": "sha512-9b4Mg5Yfz6mRnlSPIdROcfw1BU22FQxmfjlp/CShWwO3LilKQuMISMTtAu/bxmmrE6A902W2cZJuzx8+gJ8e9w==", + "version": "4.35.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.35.0.tgz", + "integrity": "sha512-c+zkcvbhbXF98f4CtEIP1EBA/lCic5xB0lToneZYvMeKu5Kamq3O8gqrxiYYLzlZH6E3Aq+TSW86E4ay8iD8EA==", "cpu": [ "ppc64" ], @@ -1812,9 +1901,9 @@ ] }, "node_modules/@rollup/rollup-linux-riscv64-gnu": { - "version": "4.29.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.29.1.tgz", - "integrity": "sha512-G5pn0NChlbRM8OJWpJFMX4/i8OEU538uiSv0P6roZcbpe/WfhEO+AT8SHVKfp8qhDQzaz7Q+1/ixMy7hBRidnQ==", + "version": "4.35.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.35.0.tgz", + "integrity": "sha512-s91fuAHdOwH/Tad2tzTtPX7UZyytHIRR6V4+2IGlV0Cej5rkG0R61SX4l4y9sh0JBibMiploZx3oHKPnQBKe4g==", "cpu": [ "riscv64" ], @@ -1826,9 +1915,9 @@ ] }, "node_modules/@rollup/rollup-linux-s390x-gnu": { - "version": "4.29.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.29.1.tgz", - "integrity": "sha512-WM9lIkNdkhVwiArmLxFXpWndFGuOka4oJOZh8EP3Vb8q5lzdSCBuhjavJsw68Q9AKDGeOOIHYzYm4ZFvmWez5g==", + "version": "4.35.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.35.0.tgz", + "integrity": "sha512-hQRkPQPLYJZYGP+Hj4fR9dDBMIM7zrzJDWFEMPdTnTy95Ljnv0/4w/ixFw3pTBMEuuEuoqtBINYND4M7ujcuQw==", "cpu": [ "s390x" ], @@ -1840,9 +1929,9 @@ ] }, "node_modules/@rollup/rollup-linux-x64-gnu": { - "version": "4.29.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.29.1.tgz", - "integrity": "sha512-87xYCwb0cPGZFoGiErT1eDcssByaLX4fc0z2nRM6eMtV9njAfEE6OW3UniAoDhX4Iq5xQVpE6qO9aJbCFumKYQ==", + "version": "4.35.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.35.0.tgz", + "integrity": "sha512-Pim1T8rXOri+0HmV4CdKSGrqcBWX0d1HoPnQ0uw0bdp1aP5SdQVNBy8LjYncvnLgu3fnnCt17xjWGd4cqh8/hA==", "cpu": [ "x64" ], @@ -1854,9 +1943,9 @@ ] }, "node_modules/@rollup/rollup-linux-x64-musl": { - "version": "4.29.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.29.1.tgz", - "integrity": "sha512-xufkSNppNOdVRCEC4WKvlR1FBDyqCSCpQeMMgv9ZyXqqtKBfkw1yfGMTUTs9Qsl6WQbJnsGboWCp7pJGkeMhKA==", + "version": "4.35.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.35.0.tgz", + "integrity": "sha512-QysqXzYiDvQWfUiTm8XmJNO2zm9yC9P/2Gkrwg2dH9cxotQzunBHYr6jk4SujCTqnfGxduOmQcI7c2ryuW8XVg==", "cpu": [ "x64" ], @@ -1868,9 +1957,9 @@ ] }, "node_modules/@rollup/rollup-win32-arm64-msvc": { - "version": "4.29.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.29.1.tgz", - "integrity": "sha512-F2OiJ42m77lSkizZQLuC+jiZ2cgueWQL5YC9tjo3AgaEw+KJmVxHGSyQfDUoYR9cci0lAywv2Clmckzulcq6ig==", + "version": "4.35.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.35.0.tgz", + "integrity": "sha512-OUOlGqPkVJCdJETKOCEf1mw848ZyJ5w50/rZ/3IBQVdLfR5jk/6Sr5m3iO2tdPgwo0x7VcncYuOvMhBWZq8ayg==", "cpu": [ "arm64" ], @@ -1882,9 +1971,9 @@ ] }, "node_modules/@rollup/rollup-win32-ia32-msvc": { - "version": "4.29.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.29.1.tgz", - "integrity": "sha512-rYRe5S0FcjlOBZQHgbTKNrqxCBUmgDJem/VQTCcTnA2KCabYSWQDrytOzX7avb79cAAweNmMUb/Zw18RNd4mng==", + "version": "4.35.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.35.0.tgz", + "integrity": "sha512-2/lsgejMrtwQe44glq7AFFHLfJBPafpsTa6JvP2NGef/ifOa4KBoglVf7AKN7EV9o32evBPRqfg96fEHzWo5kw==", "cpu": [ "ia32" ], @@ -1896,9 +1985,9 @@ ] }, "node_modules/@rollup/rollup-win32-x64-msvc": { - "version": "4.29.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.29.1.tgz", - "integrity": "sha512-+10CMg9vt1MoHj6x1pxyjPSMjHTIlqs8/tBztXvPAx24SKs9jwVnKqHJumlH/IzhaPUaj3T6T6wfZr8okdXaIg==", + "version": "4.35.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.35.0.tgz", + "integrity": "sha512-PIQeY5XDkrOysbQblSW7v3l1MDZzkTEzAfTPkj5VAu3FW8fS4ynyLg2sINp0fp3SjZ8xkRYpLqoKcYqAkhU1dw==", "cpu": [ "x64" ], @@ -1917,9 +2006,9 @@ "license": "MIT" }, "node_modules/@semantic-release/commit-analyzer": { - "version": "13.0.0", - "resolved": "https://registry.npmjs.org/@semantic-release/commit-analyzer/-/commit-analyzer-13.0.0.tgz", - "integrity": "sha512-KtXWczvTAB1ZFZ6B4O+w8HkfYm/OgQb1dUGNFZtDgQ0csggrmkq8sTxhd+lwGF8kMb59/RnG9o4Tn7M/I8dQ9Q==", + "version": "13.0.1", + "resolved": "https://registry.npmjs.org/@semantic-release/commit-analyzer/-/commit-analyzer-13.0.1.tgz", + "integrity": "sha512-wdnBPHKkr9HhNhXOhZD5a2LNl91+hs8CC2vsAVYxtZH3y0dV3wKn+uZSN61rdJQZ8EGxzWB3inWocBHV9+u/CQ==", "dev": true, "license": "MIT", "dependencies": { @@ -1928,7 +2017,7 @@ "conventional-commits-filter": "^5.0.0", "conventional-commits-parser": "^6.0.0", "debug": "^4.0.0", - "import-from-esm": "^1.0.3", + "import-from-esm": "^2.0.0", "lodash-es": "^4.17.21", "micromatch": "^4.0.2" }, @@ -1953,9 +2042,9 @@ } }, "node_modules/@semantic-release/commit-analyzer/node_modules/conventional-commits-parser": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/conventional-commits-parser/-/conventional-commits-parser-6.0.0.tgz", - "integrity": "sha512-TbsINLp48XeMXR8EvGjTnKGsZqBemisPoyWESlpRyR8lif0lcwzqz+NMtYSj1ooF/WYjSuu7wX0CtdeeMEQAmA==", + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/conventional-commits-parser/-/conventional-commits-parser-6.1.0.tgz", + "integrity": "sha512-5nxDo7TwKB5InYBl4ZC//1g9GRwB/F3TXOGR9hgUjMGfvSP4Vu5NkpNro2+1+TIEy1vwxApl5ircECr2ri5JIw==", "dev": true, "license": "MIT", "dependencies": { @@ -2050,21 +2139,6 @@ "semantic-release": ">=20.1.0" } }, - "node_modules/@semantic-release/npm/node_modules/fs-extra": { - "version": "11.2.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-11.2.0.tgz", - "integrity": "sha512-PmDi3uwK5nFuXh7XDTlVnS17xJS7vW36is2+w3xcv8SVxiB4NyATf4ctkVY5bkSjX0Y4nbvZCq1/EjtEyr9ktw==", - "dev": true, - "license": "MIT", - "dependencies": { - "graceful-fs": "^4.2.0", - "jsonfile": "^6.0.1", - "universalify": "^2.0.0" - }, - "engines": { - "node": ">=14.14" - } - }, "node_modules/@semantic-release/npm/node_modules/hosted-git-info": { "version": "7.0.2", "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-7.0.2.tgz", @@ -2139,9 +2213,9 @@ } }, "node_modules/@semantic-release/release-notes-generator": { - "version": "14.0.2", - "resolved": "https://registry.npmjs.org/@semantic-release/release-notes-generator/-/release-notes-generator-14.0.2.tgz", - "integrity": "sha512-ur2l2tVLBfX3fSEO2rCy2X6Kzg5S7BHGqdwTHvJrpWp4mOEN7W4K/2kWAjvfAlwMenEKjMnDIhBbxxjnP0S9hw==", + "version": "14.0.3", + "resolved": "https://registry.npmjs.org/@semantic-release/release-notes-generator/-/release-notes-generator-14.0.3.tgz", + "integrity": "sha512-XxAZRPWGwO5JwJtS83bRdoIhCiYIx8Vhr+u231pQAsdFIAbm19rSVJLdnBN+Avvk7CKvNQE/nJ4y7uqKH6WTiw==", "dev": true, "license": "MIT", "dependencies": { @@ -2151,7 +2225,7 @@ "conventional-commits-parser": "^6.0.0", "debug": "^4.0.0", "get-stream": "^7.0.0", - "import-from-esm": "^1.0.3", + "import-from-esm": "^2.0.0", "into-stream": "^7.0.0", "lodash-es": "^4.17.21", "read-package-up": "^11.0.0" @@ -2177,9 +2251,9 @@ } }, "node_modules/@semantic-release/release-notes-generator/node_modules/conventional-commits-parser": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/conventional-commits-parser/-/conventional-commits-parser-6.0.0.tgz", - "integrity": "sha512-TbsINLp48XeMXR8EvGjTnKGsZqBemisPoyWESlpRyR8lif0lcwzqz+NMtYSj1ooF/WYjSuu7wX0CtdeeMEQAmA==", + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/conventional-commits-parser/-/conventional-commits-parser-6.1.0.tgz", + "integrity": "sha512-5nxDo7TwKB5InYBl4ZC//1g9GRwB/F3TXOGR9hgUjMGfvSP4Vu5NkpNro2+1+TIEy1vwxApl5ircECr2ri5JIw==", "dev": true, "license": "MIT", "dependencies": { @@ -2218,6 +2292,35 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/@shikijs/engine-oniguruma": { + "version": "1.29.2", + "resolved": "https://registry.npmjs.org/@shikijs/engine-oniguruma/-/engine-oniguruma-1.29.2.tgz", + "integrity": "sha512-7iiOx3SG8+g1MnlzZVDYiaeHe7Ez2Kf2HrJzdmGwkRisT7r4rak0e655AcM/tF9JG/kg5fMNYlLLKglbN7gBqA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@shikijs/types": "1.29.2", + "@shikijs/vscode-textmate": "^10.0.1" + } + }, + "node_modules/@shikijs/types": { + "version": "1.29.2", + "resolved": "https://registry.npmjs.org/@shikijs/types/-/types-1.29.2.tgz", + "integrity": "sha512-VJjK0eIijTZf0QSTODEXCqinjBn0joAHQ+aPSBzrv4O2d/QSbsMw+ZeSRx03kV34Hy7NzUvV/7NqfYGRLrASmw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@shikijs/vscode-textmate": "^10.0.1", + "@types/hast": "^3.0.4" + } + }, + "node_modules/@shikijs/vscode-textmate": { + "version": "10.0.2", + "resolved": "https://registry.npmjs.org/@shikijs/vscode-textmate/-/vscode-textmate-10.0.2.tgz", + "integrity": "sha512-83yeghZ2xxin3Nj8z1NMd/NCuca+gsYXswywDy5bHvwlWL8tpTQmzGeUuHd9FC3E/SBEMvzJRwWEOz5gGes9Qg==", + "dev": true, + "license": "MIT" + }, "node_modules/@sindresorhus/is": { "version": "4.6.0", "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-4.6.0.tgz", @@ -2288,6 +2391,16 @@ "dev": true, "license": "MIT" }, + "node_modules/@types/hast": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@types/hast/-/hast-3.0.4.tgz", + "integrity": "sha512-WPs+bbQw5aCj+x6laNGWLH3wviHtoCv/P3+otBhbOhJgG8qtpdAMlTCxLtsTWA7LH1Oh/bFCHsBn0TPS5m30EQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/unist": "*" + } + }, "node_modules/@types/json-schema": { "version": "7.0.15", "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", @@ -2296,13 +2409,13 @@ "license": "MIT" }, "node_modules/@types/node": { - "version": "22.7.5", - "resolved": "https://registry.npmjs.org/@types/node/-/node-22.7.5.tgz", - "integrity": "sha512-jML7s2NAzMWc//QSJ1a3prpk78cOPchGvXJsC3C6R6PSMoooztvRVQEz89gmBTBY1SPMaqo5teB4uNHPdetShQ==", + "version": "22.13.10", + "resolved": "https://registry.npmjs.org/@types/node/-/node-22.13.10.tgz", + "integrity": "sha512-I6LPUvlRH+O6VRUqYOcMudhaIdUVWfsjnZavnsraHvpBwaEyMN29ry+0UVJhImYL16xsscu0aske3yA+uPOWfw==", "dev": true, "license": "MIT", "dependencies": { - "undici-types": "~6.19.2" + "undici-types": "~6.20.0" } }, "node_modules/@types/normalize-package-data": { @@ -2319,29 +2432,29 @@ "dev": true, "license": "MIT" }, - "node_modules/@types/semver": { - "version": "7.5.8", - "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.5.8.tgz", - "integrity": "sha512-I8EUhyrgfLrcTkzV3TSsGyl1tSuPrEDzr0yd5m90UgNxQkyDXULk3b6MlQqTCpZpNtWe1K0hzclnZkTcLBe2UQ==", + "node_modules/@types/unist": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.3.tgz", + "integrity": "sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q==", "dev": true, "license": "MIT" }, "node_modules/@typescript-eslint/eslint-plugin": { - "version": "8.8.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.8.1.tgz", - "integrity": "sha512-xfvdgA8AP/vxHgtgU310+WBnLB4uJQ9XdyP17RebG26rLtDrQJV3ZYrcopX91GrHmMoH8bdSwMRh2a//TiJ1jQ==", + "version": "8.26.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.26.1.tgz", + "integrity": "sha512-2X3mwqsj9Bd3Ciz508ZUtoQQYpOhU/kWoUqIf49H8Z0+Vbh6UF/y0OEYp0Q0axOGzaBGs7QxRwq0knSQ8khQNA==", "dev": true, "license": "MIT", "dependencies": { "@eslint-community/regexpp": "^4.10.0", - "@typescript-eslint/scope-manager": "8.8.1", - "@typescript-eslint/type-utils": "8.8.1", - "@typescript-eslint/utils": "8.8.1", - "@typescript-eslint/visitor-keys": "8.8.1", + "@typescript-eslint/scope-manager": "8.26.1", + "@typescript-eslint/type-utils": "8.26.1", + "@typescript-eslint/utils": "8.26.1", + "@typescript-eslint/visitor-keys": "8.26.1", "graphemer": "^1.4.0", "ignore": "^5.3.1", "natural-compare": "^1.4.0", - "ts-api-utils": "^1.3.0" + "ts-api-utils": "^2.0.1" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -2352,25 +2465,21 @@ }, "peerDependencies": { "@typescript-eslint/parser": "^8.0.0 || ^8.0.0-alpha.0", - "eslint": "^8.57.0 || ^9.0.0" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } + "eslint": "^8.57.0 || ^9.0.0", + "typescript": ">=4.8.4 <5.9.0" } }, "node_modules/@typescript-eslint/parser": { - "version": "8.8.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.8.1.tgz", - "integrity": "sha512-hQUVn2Lij2NAxVFEdvIGxT9gP1tq2yM83m+by3whWFsWC+1y8pxxxHUFE1UqDu2VsGi2i6RLcv4QvouM84U+ow==", + "version": "8.26.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.26.1.tgz", + "integrity": "sha512-w6HZUV4NWxqd8BdeFf81t07d7/YV9s7TCWrQQbG5uhuvGUAW+fq1usZ1Hmz9UPNLniFnD8GLSsDpjP0hm1S4lQ==", "dev": true, - "license": "BSD-2-Clause", + "license": "MIT", "dependencies": { - "@typescript-eslint/scope-manager": "8.8.1", - "@typescript-eslint/types": "8.8.1", - "@typescript-eslint/typescript-estree": "8.8.1", - "@typescript-eslint/visitor-keys": "8.8.1", + "@typescript-eslint/scope-manager": "8.26.1", + "@typescript-eslint/types": "8.26.1", + "@typescript-eslint/typescript-estree": "8.26.1", + "@typescript-eslint/visitor-keys": "8.26.1", "debug": "^4.3.4" }, "engines": { @@ -2381,23 +2490,19 @@ "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { - "eslint": "^8.57.0 || ^9.0.0" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } + "eslint": "^8.57.0 || ^9.0.0", + "typescript": ">=4.8.4 <5.9.0" } }, "node_modules/@typescript-eslint/scope-manager": { - "version": "8.8.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.8.1.tgz", - "integrity": "sha512-X4JdU+66Mazev/J0gfXlcC/dV6JI37h+93W9BRYXrSn0hrE64IoWgVkO9MSJgEzoWkxONgaQpICWg8vAN74wlA==", + "version": "8.26.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.26.1.tgz", + "integrity": "sha512-6EIvbE5cNER8sqBu6V7+KeMZIC1664d2Yjt+B9EWUXrsyWpxx4lEZrmvxgSKRC6gX+efDL/UY9OpPZ267io3mg==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/types": "8.8.1", - "@typescript-eslint/visitor-keys": "8.8.1" + "@typescript-eslint/types": "8.26.1", + "@typescript-eslint/visitor-keys": "8.26.1" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -2408,16 +2513,16 @@ } }, "node_modules/@typescript-eslint/type-utils": { - "version": "8.8.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.8.1.tgz", - "integrity": "sha512-qSVnpcbLP8CALORf0za+vjLYj1Wp8HSoiI8zYU5tHxRVj30702Z1Yw4cLwfNKhTPWp5+P+k1pjmD5Zd1nhxiZA==", + "version": "8.26.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.26.1.tgz", + "integrity": "sha512-Kcj/TagJLwoY/5w9JGEFV0dclQdyqw9+VMndxOJKtoFSjfZhLXhYjzsQEeyza03rwHx2vFEGvrJWJBXKleRvZg==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/typescript-estree": "8.8.1", - "@typescript-eslint/utils": "8.8.1", + "@typescript-eslint/typescript-estree": "8.26.1", + "@typescript-eslint/utils": "8.26.1", "debug": "^4.3.4", - "ts-api-utils": "^1.3.0" + "ts-api-utils": "^2.0.1" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -2426,16 +2531,15 @@ "type": "opencollective", "url": "https://opencollective.com/typescript-eslint" }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } + "peerDependencies": { + "eslint": "^8.57.0 || ^9.0.0", + "typescript": ">=4.8.4 <5.9.0" } }, "node_modules/@typescript-eslint/types": { - "version": "8.8.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.8.1.tgz", - "integrity": "sha512-WCcTP4SDXzMd23N27u66zTKMuEevH4uzU8C9jf0RO4E04yVHgQgW+r+TeVTNnO1KIfrL8ebgVVYYMMO3+jC55Q==", + "version": "8.26.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.26.1.tgz", + "integrity": "sha512-n4THUQW27VmQMx+3P+B0Yptl7ydfceUj4ON/AQILAASwgYdZ/2dhfymRMh5egRUrvK5lSmaOm77Ry+lmXPOgBQ==", "dev": true, "license": "MIT", "engines": { @@ -2447,20 +2551,20 @@ } }, "node_modules/@typescript-eslint/typescript-estree": { - "version": "8.8.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.8.1.tgz", - "integrity": "sha512-A5d1R9p+X+1js4JogdNilDuuq+EHZdsH9MjTVxXOdVFfTJXunKJR/v+fNNyO4TnoOn5HqobzfRlc70NC6HTcdg==", + "version": "8.26.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.26.1.tgz", + "integrity": "sha512-yUwPpUHDgdrv1QJ7YQal3cMVBGWfnuCdKbXw1yyjArax3353rEJP1ZA+4F8nOlQ3RfS2hUN/wze3nlY+ZOhvoA==", "dev": true, - "license": "BSD-2-Clause", + "license": "MIT", "dependencies": { - "@typescript-eslint/types": "8.8.1", - "@typescript-eslint/visitor-keys": "8.8.1", + "@typescript-eslint/types": "8.26.1", + "@typescript-eslint/visitor-keys": "8.26.1", "debug": "^4.3.4", "fast-glob": "^3.3.2", "is-glob": "^4.0.3", "minimatch": "^9.0.4", "semver": "^7.6.0", - "ts-api-utils": "^1.3.0" + "ts-api-utils": "^2.0.1" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -2469,20 +2573,8 @@ "type": "opencollective", "url": "https://opencollective.com/typescript-eslint" }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "node_modules/@typescript-eslint/typescript-estree/node_modules/brace-expansion": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", - "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", - "dev": true, - "license": "MIT", - "dependencies": { - "balanced-match": "^1.0.0" + "peerDependencies": { + "typescript": ">=4.8.4 <5.9.0" } }, "node_modules/@typescript-eslint/typescript-estree/node_modules/minimatch": { @@ -2502,16 +2594,16 @@ } }, "node_modules/@typescript-eslint/utils": { - "version": "8.8.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.8.1.tgz", - "integrity": "sha512-/QkNJDbV0bdL7H7d0/y0qBbV2HTtf0TIyjSDTvvmQEzeVx8jEImEbLuOA4EsvE8gIgqMitns0ifb5uQhMj8d9w==", + "version": "8.26.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.26.1.tgz", + "integrity": "sha512-V4Urxa/XtSUroUrnI7q6yUTD3hDtfJ2jzVfeT3VK0ciizfK2q/zGC0iDh1lFMUZR8cImRrep6/q0xd/1ZGPQpg==", "dev": true, "license": "MIT", "dependencies": { "@eslint-community/eslint-utils": "^4.4.0", - "@typescript-eslint/scope-manager": "8.8.1", - "@typescript-eslint/types": "8.8.1", - "@typescript-eslint/typescript-estree": "8.8.1" + "@typescript-eslint/scope-manager": "8.26.1", + "@typescript-eslint/types": "8.26.1", + "@typescript-eslint/typescript-estree": "8.26.1" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -2521,18 +2613,19 @@ "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { - "eslint": "^8.57.0 || ^9.0.0" + "eslint": "^8.57.0 || ^9.0.0", + "typescript": ">=4.8.4 <5.9.0" } }, "node_modules/@typescript-eslint/visitor-keys": { - "version": "8.8.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.8.1.tgz", - "integrity": "sha512-0/TdC3aeRAsW7MDvYRwEc1Uwm0TIBfzjPFgg60UU2Haj5qsCs9cc3zNgY71edqE3LbWfF/WoZQd3lJoDXFQpag==", + "version": "8.26.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.26.1.tgz", + "integrity": "sha512-AjOC3zfnxd6S4Eiy3jwktJPclqhFHNyd8L6Gycf9WUPoKZpgM5PjkxY1X7uSy61xVpiJDhhk7XT2NVsN3ALTWg==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/types": "8.8.1", - "eslint-visitor-keys": "^3.4.3" + "@typescript-eslint/types": "8.26.1", + "eslint-visitor-keys": "^4.2.0" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -2542,32 +2635,45 @@ "url": "https://opencollective.com/typescript-eslint" } }, + "node_modules/@typescript-eslint/visitor-keys/node_modules/eslint-visitor-keys": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.2.0.tgz", + "integrity": "sha512-UyLnSehNt62FFhSwjZlHmeokpRK59rcz29j+F1/aDgbkbRTk7wIc9XzdoasMUbRNKDM0qQt/+BJ4BrpFeABemw==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, "node_modules/@vitest/coverage-v8": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/@vitest/coverage-v8/-/coverage-v8-2.1.2.tgz", - "integrity": "sha512-b7kHrFrs2urS0cOk5N10lttI8UdJ/yP3nB4JYTREvR5o18cR99yPpK4gK8oQgI42BVv0ILWYUSYB7AXkAUDc0g==", + "version": "3.0.8", + "resolved": "https://registry.npmjs.org/@vitest/coverage-v8/-/coverage-v8-3.0.8.tgz", + "integrity": "sha512-y7SAKsQirsEJ2F8bulBck4DoluhI2EEgTimHd6EEUgJBGKy9tC25cpywh1MH4FvDGoG2Unt7+asVd1kj4qOSAw==", "dev": true, "license": "MIT", "dependencies": { "@ampproject/remapping": "^2.3.0", - "@bcoe/v8-coverage": "^0.2.3", - "debug": "^4.3.6", + "@bcoe/v8-coverage": "^1.0.2", + "debug": "^4.4.0", "istanbul-lib-coverage": "^3.2.2", "istanbul-lib-report": "^3.0.1", "istanbul-lib-source-maps": "^5.0.6", "istanbul-reports": "^3.1.7", - "magic-string": "^0.30.11", - "magicast": "^0.3.4", - "std-env": "^3.7.0", + "magic-string": "^0.30.17", + "magicast": "^0.3.5", + "std-env": "^3.8.0", "test-exclude": "^7.0.1", - "tinyrainbow": "^1.2.0" + "tinyrainbow": "^2.0.0" }, "funding": { "url": "https://opencollective.com/vitest" }, "peerDependencies": { - "@vitest/browser": "2.1.2", - "vitest": "2.1.2" + "@vitest/browser": "3.0.8", + "vitest": "3.0.8" }, "peerDependenciesMeta": { "@vitest/browser": { @@ -2576,39 +2682,38 @@ } }, "node_modules/@vitest/expect": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-2.1.2.tgz", - "integrity": "sha512-FEgtlN8mIUSEAAnlvn7mP8vzaWhEaAEvhSXCqrsijM7K6QqjB11qoRZYEd4AKSCDz8p0/+yH5LzhZ47qt+EyPg==", + "version": "3.0.8", + "resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-3.0.8.tgz", + "integrity": "sha512-Xu6TTIavTvSSS6LZaA3EebWFr6tsoXPetOWNMOlc7LO88QVVBwq2oQWBoDiLCN6YTvNYsGSjqOO8CAdjom5DCQ==", "dev": true, "license": "MIT", "dependencies": { - "@vitest/spy": "2.1.2", - "@vitest/utils": "2.1.2", - "chai": "^5.1.1", - "tinyrainbow": "^1.2.0" + "@vitest/spy": "3.0.8", + "@vitest/utils": "3.0.8", + "chai": "^5.2.0", + "tinyrainbow": "^2.0.0" }, "funding": { "url": "https://opencollective.com/vitest" } }, "node_modules/@vitest/mocker": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/@vitest/mocker/-/mocker-2.1.2.tgz", - "integrity": "sha512-ExElkCGMS13JAJy+812fw1aCv2QO/LBK6CyO4WOPAzLTmve50gydOlWhgdBJPx2ztbADUq3JVI0C5U+bShaeEA==", + "version": "3.0.8", + "resolved": "https://registry.npmjs.org/@vitest/mocker/-/mocker-3.0.8.tgz", + "integrity": "sha512-n3LjS7fcW1BCoF+zWZxG7/5XvuYH+lsFg+BDwwAz0arIwHQJFUEsKBQ0BLU49fCxuM/2HSeBPHQD8WjgrxMfow==", "dev": true, "license": "MIT", "dependencies": { - "@vitest/spy": "^2.1.0-beta.1", + "@vitest/spy": "3.0.8", "estree-walker": "^3.0.3", - "magic-string": "^0.30.11" + "magic-string": "^0.30.17" }, "funding": { "url": "https://opencollective.com/vitest" }, "peerDependencies": { - "@vitest/spy": "2.1.2", - "msw": "^2.3.5", - "vite": "^5.0.0" + "msw": "^2.4.9", + "vite": "^5.0.0 || ^6.0.0" }, "peerDependenciesMeta": { "msw": { @@ -2630,116 +2735,83 @@ } }, "node_modules/@vitest/pretty-format": { - "version": "2.1.8", - "resolved": "https://registry.npmjs.org/@vitest/pretty-format/-/pretty-format-2.1.8.tgz", - "integrity": "sha512-9HiSZ9zpqNLKlbIDRWOnAWqgcA7xu+8YxXSekhr0Ykab7PAYFkhkwoqVArPOtJhPmYeE2YHgKZlj3CP36z2AJQ==", + "version": "3.0.8", + "resolved": "https://registry.npmjs.org/@vitest/pretty-format/-/pretty-format-3.0.8.tgz", + "integrity": "sha512-BNqwbEyitFhzYMYHUVbIvepOyeQOSFA/NeJMIP9enMntkkxLgOcgABH6fjyXG85ipTgvero6noreavGIqfJcIg==", "dev": true, "license": "MIT", "dependencies": { - "tinyrainbow": "^1.2.0" + "tinyrainbow": "^2.0.0" }, "funding": { "url": "https://opencollective.com/vitest" } }, "node_modules/@vitest/runner": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/@vitest/runner/-/runner-2.1.2.tgz", - "integrity": "sha512-UCsPtvluHO3u7jdoONGjOSil+uON5SSvU9buQh3lP7GgUXHp78guN1wRmZDX4wGK6J10f9NUtP6pO+SFquoMlw==", + "version": "3.0.8", + "resolved": "https://registry.npmjs.org/@vitest/runner/-/runner-3.0.8.tgz", + "integrity": "sha512-c7UUw6gEcOzI8fih+uaAXS5DwjlBaCJUo7KJ4VvJcjL95+DSR1kova2hFuRt3w41KZEFcOEiq098KkyrjXeM5w==", "dev": true, "license": "MIT", "dependencies": { - "@vitest/utils": "2.1.2", - "pathe": "^1.1.2" + "@vitest/utils": "3.0.8", + "pathe": "^2.0.3" }, "funding": { "url": "https://opencollective.com/vitest" } }, "node_modules/@vitest/snapshot": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/@vitest/snapshot/-/snapshot-2.1.2.tgz", - "integrity": "sha512-xtAeNsZ++aRIYIUsek7VHzry/9AcxeULlegBvsdLncLmNCR6tR8SRjn8BbDP4naxtccvzTqZ+L1ltZlRCfBZFA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@vitest/pretty-format": "2.1.2", - "magic-string": "^0.30.11", - "pathe": "^1.1.2" - }, - "funding": { - "url": "https://opencollective.com/vitest" - } - }, - "node_modules/@vitest/snapshot/node_modules/@vitest/pretty-format": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/@vitest/pretty-format/-/pretty-format-2.1.2.tgz", - "integrity": "sha512-FIoglbHrSUlOJPDGIrh2bjX1sNars5HbxlcsFKCtKzu4+5lpsRhOCVcuzp0fEhAGHkPZRIXVNzPcpSlkoZ3LuA==", + "version": "3.0.8", + "resolved": "https://registry.npmjs.org/@vitest/snapshot/-/snapshot-3.0.8.tgz", + "integrity": "sha512-x8IlMGSEMugakInj44nUrLSILh/zy1f2/BgH0UeHpNyOocG18M9CWVIFBaXPt8TrqVZWmcPjwfG/ht5tnpba8A==", "dev": true, "license": "MIT", "dependencies": { - "tinyrainbow": "^1.2.0" + "@vitest/pretty-format": "3.0.8", + "magic-string": "^0.30.17", + "pathe": "^2.0.3" }, "funding": { "url": "https://opencollective.com/vitest" } }, "node_modules/@vitest/spy": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-2.1.2.tgz", - "integrity": "sha512-GSUi5zoy+abNRJwmFhBDC0yRuVUn8WMlQscvnbbXdKLXX9dE59YbfwXxuJ/mth6eeqIzofU8BB5XDo/Ns/qK2A==", + "version": "3.0.8", + "resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-3.0.8.tgz", + "integrity": "sha512-MR+PzJa+22vFKYb934CejhR4BeRpMSoxkvNoDit68GQxRLSf11aT6CTj3XaqUU9rxgWJFnqicN/wxw6yBRkI1Q==", "dev": true, "license": "MIT", "dependencies": { - "tinyspy": "^3.0.0" + "tinyspy": "^3.0.2" }, "funding": { "url": "https://opencollective.com/vitest" } }, "node_modules/@vitest/utils": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-2.1.2.tgz", - "integrity": "sha512-zMO2KdYy6mx56btx9JvAqAZ6EyS3g49krMPPrgOp1yxGZiA93HumGk+bZ5jIZtOg5/VBYl5eBmGRQHqq4FG6uQ==", + "version": "3.0.8", + "resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-3.0.8.tgz", + "integrity": "sha512-nkBC3aEhfX2PdtQI/QwAWp8qZWwzASsU4Npbcd5RdMPBSSLCpkZp52P3xku3s3uA0HIEhGvEcF8rNkBsz9dQ4Q==", "dev": true, "license": "MIT", "dependencies": { - "@vitest/pretty-format": "2.1.2", - "loupe": "^3.1.1", - "tinyrainbow": "^1.2.0" + "@vitest/pretty-format": "3.0.8", + "loupe": "^3.1.3", + "tinyrainbow": "^2.0.0" }, "funding": { "url": "https://opencollective.com/vitest" } }, - "node_modules/@vitest/utils/node_modules/@vitest/pretty-format": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/@vitest/pretty-format/-/pretty-format-2.1.2.tgz", - "integrity": "sha512-FIoglbHrSUlOJPDGIrh2bjX1sNars5HbxlcsFKCtKzu4+5lpsRhOCVcuzp0fEhAGHkPZRIXVNzPcpSlkoZ3LuA==", + "node_modules/acorn": { + "version": "8.14.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.14.1.tgz", + "integrity": "sha512-OvQ/2pUDKmgfCg++xsTX1wGxfTaszcHVcTctW4UJB4hibJx2HXxxO5UmVgyjMa+ZDsiaf5wWLXYpRWMmBI0QHg==", "dev": true, "license": "MIT", - "dependencies": { - "tinyrainbow": "^1.2.0" - }, - "funding": { - "url": "https://opencollective.com/vitest" - } - }, - "node_modules/@yarnpkg/lockfile": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@yarnpkg/lockfile/-/lockfile-1.1.0.tgz", - "integrity": "sha512-GpSwvyXOcOOlV70vbnzjj4fW5xW/FdUF6nQEt1ENy7m4ZCczi1+/buVUPAqmGfqznsORNFzUMjctTIp8a9tuCQ==", - "dev": true, - "license": "BSD-2-Clause" - }, - "node_modules/acorn": { - "version": "8.14.0", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.14.0.tgz", - "integrity": "sha512-cl669nCJTZBsL97OF4kUQm5g5hC2uihk0NxY3WENAC0TYdILVkAyHymAntgxGkl7K+t0cXIrH5siy5S4XkFycA==", - "dev": true, - "license": "MIT", - "bin": { - "acorn": "bin/acorn" + "bin": { + "acorn": "bin/acorn" }, "engines": { "node": ">=0.4.0" @@ -2811,9 +2883,9 @@ } }, "node_modules/algosdk": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/algosdk/-/algosdk-3.0.0.tgz", - "integrity": "sha512-PIKZ/YvbBpCudduug4KSH1CY/pTotI7/ccbUIbXKtcI9Onevl+57E+K5X4ow4gsCdysZ8zVvSLdxuCcXvsmPOw==", + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/algosdk/-/algosdk-3.2.0.tgz", + "integrity": "sha512-iz7cRtv03vuYgQYp2IfLs+n512dxdjpalALZNiiFvreM7/oPmflfLkfD5dph/HUQwuJTomXx51LgiY19QP5ihg==", "dev": true, "license": "MIT", "peer": true, @@ -2903,11 +2975,16 @@ "dev": true, "license": "MIT" }, + "node_modules/arcsecond": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/arcsecond/-/arcsecond-5.0.0.tgz", + "integrity": "sha512-J/fHdyadnsIencRsM6oUSsraCKG+Ni9Udcgr/eusxjTzX3SEQtCUQSpP0YtImFPfIK6DdT1nqwN0ng4FqNmwgA==", + "license": "MIT" + }, "node_modules/argparse": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", - "dev": true, "license": "Python-2.0" }, "node_modules/argv-formatter": { @@ -2983,14 +3060,14 @@ "node": ">=8" } }, - "node_modules/at-least-node": { + "node_modules/async-function": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/at-least-node/-/at-least-node-1.0.0.tgz", - "integrity": "sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg==", + "resolved": "https://registry.npmjs.org/async-function/-/async-function-1.0.0.tgz", + "integrity": "sha512-hsU18Ae8CDTR6Kgu9DYf0EbCr/a5iGL0rytQDobUcdpYOKokk8LEjVphnXkDkgpi0wYVsqrXuP0bZxJaTqdgoA==", "dev": true, - "license": "ISC", + "license": "MIT", "engines": { - "node": ">= 4.0.0" + "node": ">= 0.4" } }, "node_modules/available-typed-arrays": { @@ -3098,14 +3175,12 @@ "license": "MIT" }, "node_modules/brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dev": true, + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", "license": "MIT", "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" + "balanced-match": "^1.0.0" } }, "node_modules/braces": { @@ -3182,9 +3257,9 @@ } }, "node_modules/call-bind-apply-helpers": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.1.tgz", - "integrity": "sha512-BhYE+WDaywFg2TBWYNXAE+8B1ATnThNBqXHP5nQu0jWJdVvY2hvkpyB3qOmtmDePiS5/BDQ8wASEWGMWRG148g==", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz", + "integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==", "dev": true, "license": "MIT", "dependencies": { @@ -3196,14 +3271,14 @@ } }, "node_modules/call-bound": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/call-bound/-/call-bound-1.0.3.tgz", - "integrity": "sha512-YTd+6wGlNlPxSuri7Y6X8tY2dmm12UMH66RpKMhiX6rsk5wXXnYgbUcOt8kiS31/AjfoTOvCsE+w8nZQLQnzHA==", + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/call-bound/-/call-bound-1.0.4.tgz", + "integrity": "sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==", "dev": true, "license": "MIT", "dependencies": { - "call-bind-apply-helpers": "^1.0.1", - "get-intrinsic": "^1.2.6" + "call-bind-apply-helpers": "^1.0.2", + "get-intrinsic": "^1.3.0" }, "engines": { "node": ">= 0.4" @@ -3223,9 +3298,9 @@ } }, "node_modules/chai": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/chai/-/chai-5.1.2.tgz", - "integrity": "sha512-aGtmf24DW6MLHHG5gCx4zaI3uBq3KRtxeVs0DjFH6Z0rDNbsvTxFASFvdj79pxjxZ8/5u3PIiN3IwEIQkiiuPw==", + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/chai/-/chai-5.2.0.tgz", + "integrity": "sha512-mCuXncKXk5iCLhfhwTc0izo0gtEmpz5CtG2y8GiOINBlMVS6v8TMRc5TaLWKS6692m9+dVVfzgeVxR5UxWHTYw==", "dev": true, "license": "MIT", "dependencies": { @@ -3277,22 +3352,6 @@ "node": ">= 16" } }, - "node_modules/ci-info": { - "version": "3.9.0", - "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.9.0.tgz", - "integrity": "sha512-NIxF55hv4nSqQswkAeiOi1r83xy8JldOFDTWiug55KBu9Jnblncd2U6ViHmYgHf01TPZS77NJBhBMKdWj9HQMQ==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/sibiraj-s" - } - ], - "license": "MIT", - "engines": { - "node": ">=8" - } - }, "node_modules/clean-stack": { "version": "5.2.0", "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-5.2.0.tgz", @@ -3697,6 +3756,7 @@ "version": "12.1.0", "resolved": "https://registry.npmjs.org/commander/-/commander-12.1.0.tgz", "integrity": "sha512-Vw8qHK3bZM9y/P10u3Vib8o/DdkvA2OtPtZvD871QKjy74Wj1WSKFILMPRPSdUSx5RFK1arlJzEtA4PkFgnbuA==", + "dev": true, "license": "MIT", "engines": { "node": ">=18" @@ -3779,13 +3839,12 @@ } }, "node_modules/conventional-changelog-writer": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/conventional-changelog-writer/-/conventional-changelog-writer-8.0.0.tgz", - "integrity": "sha512-TQcoYGRatlAnT2qEWDON/XSfnVG38JzA7E0wcGScu7RElQBkg9WWgZd1peCWFcWDh1xfb2CfsrcvOn1bbSzztA==", + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/conventional-changelog-writer/-/conventional-changelog-writer-8.0.1.tgz", + "integrity": "sha512-hlqcy3xHred2gyYg/zXSMXraY2mjAYYo0msUCpK+BGyaVJMFCKWVXPIHiaacGO2GGp13kvHWXFhYmxT4QQqW3Q==", "dev": true, "license": "MIT", "dependencies": { - "@types/semver": "^7.5.5", "conventional-commits-filter": "^5.0.0", "handlebars": "^4.7.7", "meow": "^13.0.0", @@ -3899,6 +3958,17 @@ "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, + "node_modules/copyfiles/node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, "node_modules/copyfiles/node_modules/cliui": { "version": "7.0.4", "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", @@ -3960,6 +4030,19 @@ "url": "https://github.com/sponsors/isaacs" } }, + "node_modules/copyfiles/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, "node_modules/copyfiles/node_modules/string-width": { "version": "4.2.3", "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", @@ -4101,6 +4184,27 @@ "node": ">= 8" } }, + "node_modules/cross-spawn/node_modules/isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", + "license": "ISC" + }, + "node_modules/cross-spawn/node_modules/which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "license": "ISC", + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" + } + }, "node_modules/crypto-random-string": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/crypto-random-string/-/crypto-random-string-4.0.0.tgz", @@ -4423,6 +4527,19 @@ "dev": true, "license": "MIT" }, + "node_modules/entities": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz", + "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=0.12" + }, + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, "node_modules/env-ci": { "version": "11.1.0", "resolved": "https://registry.npmjs.org/env-ci/-/env-ci-11.1.0.tgz", @@ -4573,9 +4690,9 @@ } }, "node_modules/es-abstract": { - "version": "1.23.7", - "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.23.7.tgz", - "integrity": "sha512-OygGC8kIcDhXX+6yAZRGLqwi2CmEXCbLQixeGUgYeR+Qwlppqmo7DIDr8XibtEBZp+fJcoYpoatp5qwLMEdcqQ==", + "version": "1.23.9", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.23.9.tgz", + "integrity": "sha512-py07lI0wjxAC/DcfK1S6G7iANonniZwTISvdPzk9hzeH0IZIshbuuFxLIU96OyF89Yb9hiqWn8M/bY83KY5vzA==", "dev": true, "license": "MIT", "dependencies": { @@ -4590,10 +4707,11 @@ "es-define-property": "^1.0.1", "es-errors": "^1.3.0", "es-object-atoms": "^1.0.0", - "es-set-tostringtag": "^2.0.3", + "es-set-tostringtag": "^2.1.0", "es-to-primitive": "^1.3.0", "function.prototype.name": "^1.1.8", - "get-intrinsic": "^1.2.6", + "get-intrinsic": "^1.2.7", + "get-proto": "^1.0.0", "get-symbol-description": "^1.1.0", "globalthis": "^1.0.4", "gopd": "^1.2.0", @@ -4614,9 +4732,12 @@ "object-inspect": "^1.13.3", "object-keys": "^1.1.1", "object.assign": "^4.1.7", + "own-keys": "^1.0.1", "regexp.prototype.flags": "^1.5.3", "safe-array-concat": "^1.1.3", + "safe-push-apply": "^1.0.0", "safe-regex-test": "^1.1.0", + "set-proto": "^1.0.0", "string.prototype.trim": "^1.2.10", "string.prototype.trimend": "^1.0.9", "string.prototype.trimstart": "^1.0.8", @@ -4654,10 +4775,17 @@ "node": ">= 0.4" } }, + "node_modules/es-module-lexer": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-1.6.0.tgz", + "integrity": "sha512-qqnD1yMU6tk/jnaMosogGySTZP8YtUgAffA9nMN+E/rjxcfRQ6IEk7IiozUjgxKoFHBGjTLnrHB/YC45r/59EQ==", + "dev": true, + "license": "MIT" + }, "node_modules/es-object-atoms": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.0.0.tgz", - "integrity": "sha512-MZ4iQ6JwHOBQjahnjwaC1ZtIBH+2ohjamzAO3oaHcXYup7qxjF2fixyH+Q71voWHeOkI2q/TnJao/KfXYIZWbw==", + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.1.tgz", + "integrity": "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==", "dev": true, "license": "MIT", "dependencies": { @@ -4668,15 +4796,16 @@ } }, "node_modules/es-set-tostringtag": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.0.3.tgz", - "integrity": "sha512-3T8uNMC3OQTHkFUsFq8r/BwAXLHvU/9O9mE0fBc/MY5iq/8H7ncvO947LmYA6ldWw9Uh8Yhf25zu6n7nML5QWQ==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.1.0.tgz", + "integrity": "sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==", "dev": true, "license": "MIT", "dependencies": { - "get-intrinsic": "^1.2.4", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.6", "has-tostringtag": "^1.0.2", - "hasown": "^2.0.1" + "hasown": "^2.0.2" }, "engines": { "node": ">= 0.4" @@ -4701,9 +4830,9 @@ } }, "node_modules/esbuild": { - "version": "0.23.1", - "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.23.1.tgz", - "integrity": "sha512-VVNz/9Sa0bs5SELtn3f7qhJCDPCF5oMEl5cO9/SSinpE9hbPVvxbd572HH5AKiP7WD8INO53GgfDDhRjkylHEg==", + "version": "0.25.0", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.25.0.tgz", + "integrity": "sha512-BXq5mqc8ltbaN34cDqWuYKyNhX8D/Z0J1xdtdQ8UcIIIyJyz+ZMKUt58tF3SrZ85jcfN/PZYhjR5uDQAYNVbuw==", "dev": true, "hasInstallScript": true, "license": "MIT", @@ -4714,30 +4843,31 @@ "node": ">=18" }, "optionalDependencies": { - "@esbuild/aix-ppc64": "0.23.1", - "@esbuild/android-arm": "0.23.1", - "@esbuild/android-arm64": "0.23.1", - "@esbuild/android-x64": "0.23.1", - "@esbuild/darwin-arm64": "0.23.1", - "@esbuild/darwin-x64": "0.23.1", - "@esbuild/freebsd-arm64": "0.23.1", - "@esbuild/freebsd-x64": "0.23.1", - "@esbuild/linux-arm": "0.23.1", - "@esbuild/linux-arm64": "0.23.1", - "@esbuild/linux-ia32": "0.23.1", - "@esbuild/linux-loong64": "0.23.1", - "@esbuild/linux-mips64el": "0.23.1", - "@esbuild/linux-ppc64": "0.23.1", - "@esbuild/linux-riscv64": "0.23.1", - "@esbuild/linux-s390x": "0.23.1", - "@esbuild/linux-x64": "0.23.1", - "@esbuild/netbsd-x64": "0.23.1", - "@esbuild/openbsd-arm64": "0.23.1", - "@esbuild/openbsd-x64": "0.23.1", - "@esbuild/sunos-x64": "0.23.1", - "@esbuild/win32-arm64": "0.23.1", - "@esbuild/win32-ia32": "0.23.1", - "@esbuild/win32-x64": "0.23.1" + "@esbuild/aix-ppc64": "0.25.0", + "@esbuild/android-arm": "0.25.0", + "@esbuild/android-arm64": "0.25.0", + "@esbuild/android-x64": "0.25.0", + "@esbuild/darwin-arm64": "0.25.0", + "@esbuild/darwin-x64": "0.25.0", + "@esbuild/freebsd-arm64": "0.25.0", + "@esbuild/freebsd-x64": "0.25.0", + "@esbuild/linux-arm": "0.25.0", + "@esbuild/linux-arm64": "0.25.0", + "@esbuild/linux-ia32": "0.25.0", + "@esbuild/linux-loong64": "0.25.0", + "@esbuild/linux-mips64el": "0.25.0", + "@esbuild/linux-ppc64": "0.25.0", + "@esbuild/linux-riscv64": "0.25.0", + "@esbuild/linux-s390x": "0.25.0", + "@esbuild/linux-x64": "0.25.0", + "@esbuild/netbsd-arm64": "0.25.0", + "@esbuild/netbsd-x64": "0.25.0", + "@esbuild/openbsd-arm64": "0.25.0", + "@esbuild/openbsd-x64": "0.25.0", + "@esbuild/sunos-x64": "0.25.0", + "@esbuild/win32-arm64": "0.25.0", + "@esbuild/win32-ia32": "0.25.0", + "@esbuild/win32-x64": "0.25.0" } }, "node_modules/escalade": { @@ -4764,32 +4894,33 @@ } }, "node_modules/eslint": { - "version": "9.12.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.12.0.tgz", - "integrity": "sha512-UVIOlTEWxwIopRL1wgSQYdnVDcEvs2wyaO6DGo5mXqe3r16IoCNWkR29iHhyaP4cICWjbgbmFUGAhh0GJRuGZw==", + "version": "9.22.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.22.0.tgz", + "integrity": "sha512-9V/QURhsRN40xuHXWjV64yvrzMjcz7ZyNoF2jJFmy9j/SLk0u1OLSZgXi28MrXjymnjEGSR80WCdab3RGMDveQ==", "dev": true, "license": "MIT", "dependencies": { "@eslint-community/eslint-utils": "^4.2.0", - "@eslint-community/regexpp": "^4.11.0", - "@eslint/config-array": "^0.18.0", - "@eslint/core": "^0.6.0", - "@eslint/eslintrc": "^3.1.0", - "@eslint/js": "9.12.0", - "@eslint/plugin-kit": "^0.2.0", - "@humanfs/node": "^0.16.5", + "@eslint-community/regexpp": "^4.12.1", + "@eslint/config-array": "^0.19.2", + "@eslint/config-helpers": "^0.1.0", + "@eslint/core": "^0.12.0", + "@eslint/eslintrc": "^3.3.0", + "@eslint/js": "9.22.0", + "@eslint/plugin-kit": "^0.2.7", + "@humanfs/node": "^0.16.6", "@humanwhocodes/module-importer": "^1.0.1", - "@humanwhocodes/retry": "^0.3.1", + "@humanwhocodes/retry": "^0.4.2", "@types/estree": "^1.0.6", "@types/json-schema": "^7.0.15", "ajv": "^6.12.4", "chalk": "^4.0.0", - "cross-spawn": "^7.0.2", + "cross-spawn": "^7.0.6", "debug": "^4.3.2", "escape-string-regexp": "^4.0.0", - "eslint-scope": "^8.1.0", - "eslint-visitor-keys": "^4.1.0", - "espree": "^10.2.0", + "eslint-scope": "^8.3.0", + "eslint-visitor-keys": "^4.2.0", + "espree": "^10.3.0", "esquery": "^1.5.0", "esutils": "^2.0.2", "fast-deep-equal": "^3.1.3", @@ -4803,8 +4934,7 @@ "lodash.merge": "^4.6.2", "minimatch": "^3.1.2", "natural-compare": "^1.4.0", - "optionator": "^0.9.3", - "text-table": "^0.2.0" + "optionator": "^0.9.3" }, "bin": { "eslint": "bin/eslint.js" @@ -4825,9 +4955,9 @@ } }, "node_modules/eslint-config-prettier": { - "version": "9.1.0", - "resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-9.1.0.tgz", - "integrity": "sha512-NSWl5BFQWEPi1j4TjVNItzYV7dZXZ+wP6I6ZhrBGpChQhZRUaElihE9uRRkcbRnNb76UMKDF3r+WTmNcGPKsqw==", + "version": "10.1.1", + "resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-10.1.1.tgz", + "integrity": "sha512-4EQQr6wXwS+ZJSzaR5ZCrYgLxqvUjdXctaEtBqHcbkW944B1NQyO4qpdHQbXBONfwxXdkAY81HH4+LUfrg+zPw==", "dev": true, "license": "MIT", "bin": { @@ -4838,9 +4968,9 @@ } }, "node_modules/eslint-plugin-prettier": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/eslint-plugin-prettier/-/eslint-plugin-prettier-5.2.1.tgz", - "integrity": "sha512-gH3iR3g4JfF+yYPaJYkN7jEl9QbweL/YfkoRlNnuIEHEz1vHVlCmWOS+eGGiRuzHQXdJFCOTxRgvju9b8VUmrw==", + "version": "5.2.3", + "resolved": "https://registry.npmjs.org/eslint-plugin-prettier/-/eslint-plugin-prettier-5.2.3.tgz", + "integrity": "sha512-qJ+y0FfCp/mQYQ/vWQ3s7eUlFEL4PyKfAJxsnYTJ4YT73nsJBWqmEpFryxV9OeUiqmsTsYJ5Y+KDNaeP31wrRw==", "dev": true, "license": "MIT", "dependencies": { @@ -4869,9 +4999,9 @@ } }, "node_modules/eslint-scope": { - "version": "8.2.0", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-8.2.0.tgz", - "integrity": "sha512-PHlWUfG6lvPc3yvP5A4PNyBL1W8fkDUccmI21JUu/+GKZBoH/W5u6usENXUrWFRsyoW5ACUjFGgAFQp5gUlb/A==", + "version": "8.3.0", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-8.3.0.tgz", + "integrity": "sha512-pUNxi75F8MJ/GdeKtVLSbYg4ZI34J6C0C7sbL4YOp2exGwen7ZsuBqKzUhXd0qMQ362yET3z+uPwKeg/0C2XCQ==", "dev": true, "license": "BSD-2-Clause", "dependencies": { @@ -4931,6 +5061,17 @@ "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, + "node_modules/eslint/node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, "node_modules/eslint/node_modules/chalk": { "version": "4.1.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", @@ -5021,6 +5162,19 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/eslint/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, "node_modules/eslint/node_modules/p-limit": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", @@ -5204,6 +5358,33 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/expect-type": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/expect-type/-/expect-type-1.2.0.tgz", + "integrity": "sha512-80F22aiJ3GLyVnS/B3HzgR6RelZVumzj9jkL0Rhz4h0xYbNW9PjlQz5h3J/SShErbXBc295vseR4/MIbVmUbeA==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=12.0.0" + } + }, + "node_modules/fast-content-type-parse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/fast-content-type-parse/-/fast-content-type-parse-2.0.1.tgz", + "integrity": "sha512-nGqtvLrj5w0naR6tDPfB4cUmYCqouzyQiz6C5y/LtcDllJdrcc6WaWW6iXyIIOErTa/XRybj28aasdn4LkVk6Q==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/fastify" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/fastify" + } + ], + "license": "MIT" + }, "node_modules/fast-deep-equal": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", @@ -5219,9 +5400,9 @@ "license": "Apache-2.0" }, "node_modules/fast-glob": { - "version": "3.3.2", - "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.2.tgz", - "integrity": "sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==", + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.3.tgz", + "integrity": "sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==", "dev": true, "license": "MIT", "dependencies": { @@ -5229,7 +5410,7 @@ "@nodelib/fs.walk": "^1.2.3", "glob-parent": "^5.1.2", "merge2": "^1.3.0", - "micromatch": "^4.0.4" + "micromatch": "^4.0.8" }, "engines": { "node": ">=8.6.0" @@ -5263,16 +5444,26 @@ "license": "MIT" }, "node_modules/fast-uri": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.0.3.tgz", - "integrity": "sha512-aLrHthzCjH5He4Z2H9YZ+v6Ujb9ocRuW6ZzkJQOrTxleEijANq4v1TsaPaVG1PZcuurEzrLcWRyYBYXD5cEiaw==", + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.0.6.tgz", + "integrity": "sha512-Atfo14OibSv5wAp4VWNsFYE1AchQRTv9cBGWET4pZWHzYshFSS9NQI6I57rdKn9croWVMbYFbLhJ+yJvmZIIHw==", "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/fastify" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/fastify" + } + ], "license": "BSD-3-Clause" }, "node_modules/fastq": { - "version": "1.17.1", - "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.17.1.tgz", - "integrity": "sha512-sRVD3lWVIXWg6By68ZN7vho9a1pQcN/WBFaAAsDDFzlJjvoGx0P8z7V1t72grFJfJhu3YPZBuu25f7Kaw2jN1w==", + "version": "1.19.1", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.19.1.tgz", + "integrity": "sha512-GwLTyxkCXjXbxqIhTsMI2Nui8huMPtnxg7krajPJAjnEG/iiOS7i+zCtWGZR9G0NBKbXKh6X9m9UIsYX/N6vvQ==", "dev": true, "license": "ISC", "dependencies": { @@ -5280,9 +5471,9 @@ } }, "node_modules/fdir": { - "version": "6.4.2", - "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.4.2.tgz", - "integrity": "sha512-KnhMXsKSPZlAhp7+IjUkRZKPb4fUyccpDrdFXbi4QL1qkmFh9kVY09Yox+n4MaOb3lHZ1Tv829C3oaaXoMYPDQ==", + "version": "6.4.3", + "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.4.3.tgz", + "integrity": "sha512-PMXmW2y1hDDfTSRc9gaXIuCCRpuoz3Kaz8cUelp3smouvfT632ozg2vrT6lJsHKKOF59YLbOGfAWGUcKEfRMQw==", "dev": true, "license": "MIT", "peerDependencies": { @@ -5355,9 +5546,9 @@ } }, "node_modules/find-up-simple": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/find-up-simple/-/find-up-simple-1.0.0.tgz", - "integrity": "sha512-q7Us7kcjj2VMePAa02hDAF6d+MzsdsAWEwYyOpwUtlerRBkOEPBCRZrAV4XfcSN8fHAgaD0hP7miwoay6DCprw==", + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/find-up-simple/-/find-up-simple-1.0.1.tgz", + "integrity": "sha512-afd4O7zpqHeRyg4PfDQsXmlDe2PfdHtJt6Akt8jOWaApLOZk5JXs6VMR29lz03pRe9mpykrRCYIYxaJYcfpncQ==", "dev": true, "license": "MIT", "engines": { @@ -5384,16 +5575,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/find-yarn-workspace-root": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/find-yarn-workspace-root/-/find-yarn-workspace-root-2.0.0.tgz", - "integrity": "sha512-1IMnbjt4KzsQfnhnzNd8wUEgXZ44IzZaZmnLYx7D5FZlaHt2gW20Cri8Q+E/t5tIj4+epTBub+2Zxu/vNILzqQ==", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "micromatch": "^4.0.2" - } - }, "node_modules/flat-cache": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-4.0.1.tgz", @@ -5409,29 +5590,35 @@ } }, "node_modules/flatted": { - "version": "3.3.2", - "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.3.2.tgz", - "integrity": "sha512-AiwGJM8YcNOaobumgtng+6NHuOqC3A7MixFeDafM3X9cIUM+xUXoS5Vfgf+OihAYe20fxqNM9yPBXJzRtZ/4eA==", + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.3.3.tgz", + "integrity": "sha512-GX+ysw4PBCz0PzosHDepZGANEuFCMLrnRTiEy9McGjmkCQYwRq4A/X786G/fjM/+OjsWSU1ZrY5qyARZmO/uwg==", "dev": true, "license": "ISC" }, "node_modules/for-each": { - "version": "0.3.3", - "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.3.tgz", - "integrity": "sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==", + "version": "0.3.5", + "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.5.tgz", + "integrity": "sha512-dKx12eRCVIzqCxFGplyFKJMPvLEWgmNtUrpTiJIR5u97zEhRG8ySrtboPHZXx7daLxQVrl643cTzbab2tkQjxg==", "dev": true, "license": "MIT", "dependencies": { - "is-callable": "^1.1.3" + "is-callable": "^1.2.7" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, "node_modules/foreground-child": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.3.0.tgz", - "integrity": "sha512-Ld2g8rrAyMYFXBhEqMz8ZAHBi4J4uS1i/CxGMDnjyFWddMXLVcDp051DZfu+t7+ab7Wv6SMqpWmyFIj5UbfFvg==", + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.3.1.tgz", + "integrity": "sha512-gIXjKqtFuWEgzFRJA9WCQeSJLZDjgJUOMCMzxtvFq/37KojM1BFGufqsCy0r4qSQmYLsZYMeyRqzIWOMup03sw==", "license": "ISC", "dependencies": { - "cross-spawn": "^7.0.0", + "cross-spawn": "^7.0.6", "signal-exit": "^4.0.1" }, "engines": { @@ -5486,19 +5673,18 @@ } }, "node_modules/fs-extra": { - "version": "9.1.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.1.0.tgz", - "integrity": "sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==", + "version": "11.3.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-11.3.0.tgz", + "integrity": "sha512-Z4XaCL6dUDHfP/jT25jJKMmtxvuwbkrD1vNSMFlo9lNLY2c5FHYSQgHPRZUjAB26TpDEoW9HCOgplrdbaPV/ew==", "dev": true, "license": "MIT", "dependencies": { - "at-least-node": "^1.0.0", "graceful-fs": "^4.2.0", "jsonfile": "^6.0.1", "universalify": "^2.0.0" }, "engines": { - "node": ">=10" + "node": ">=14.14" } }, "node_modules/fs.realpath": { @@ -5588,22 +5774,22 @@ } }, "node_modules/get-intrinsic": { - "version": "1.2.6", - "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.6.tgz", - "integrity": "sha512-qxsEs+9A+u85HhllWJJFicJfPDhRmjzoYdl64aMWW9yRIJmSyxdn8IEkuIM530/7T+lv0TIHd8L6Q/ra0tEoeA==", + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz", + "integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==", "dev": true, "license": "MIT", "dependencies": { - "call-bind-apply-helpers": "^1.0.1", - "dunder-proto": "^1.0.0", + "call-bind-apply-helpers": "^1.0.2", "es-define-property": "^1.0.1", "es-errors": "^1.3.0", - "es-object-atoms": "^1.0.0", + "es-object-atoms": "^1.1.1", "function-bind": "^1.1.2", + "get-proto": "^1.0.1", "gopd": "^1.2.0", "has-symbols": "^1.1.0", "hasown": "^2.0.2", - "math-intrinsics": "^1.0.0" + "math-intrinsics": "^1.1.0" }, "engines": { "node": ">= 0.4" @@ -5612,6 +5798,20 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/get-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz", + "integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==", + "dev": true, + "license": "MIT", + "dependencies": { + "dunder-proto": "^1.0.1", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + } + }, "node_modules/get-stream": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz", @@ -5644,9 +5844,9 @@ } }, "node_modules/get-tsconfig": { - "version": "4.8.1", - "resolved": "https://registry.npmjs.org/get-tsconfig/-/get-tsconfig-4.8.1.tgz", - "integrity": "sha512-k9PN+cFBmaLWtVz29SkUoqU5O0slLuHJXt/2P+tMVFT+phsSGXGkp9t3rQIqdz0e+06EHNGs3oM6ZX1s2zHxRg==", + "version": "4.10.0", + "resolved": "https://registry.npmjs.org/get-tsconfig/-/get-tsconfig-4.10.0.tgz", + "integrity": "sha512-kGzZ3LWWQcGIAmg6iWvXn0ei6WDtV26wzHRMwDSzmAbcXrTEXxHy6IehI6/4eT6VRKyMP1eF1VqwrVUmE/LR7A==", "dev": true, "license": "MIT", "dependencies": { @@ -5700,9 +5900,9 @@ } }, "node_modules/glob": { - "version": "11.0.0", - "resolved": "https://registry.npmjs.org/glob/-/glob-11.0.0.tgz", - "integrity": "sha512-9UiX/Bl6J2yaBbxKoEBRm4Cipxgok8kQYcOPEhScPwebu2I0HoQOuYdIO6S3hLuWoZgpDpwQZMzTFxgpkyT76g==", + "version": "11.0.1", + "resolved": "https://registry.npmjs.org/glob/-/glob-11.0.1.tgz", + "integrity": "sha512-zrQDm8XPnYEKawJScsnM0QzobJxlT/kHOOlRTio8IH/GrmxRE5fjllkzdaHclIuNjUQTJYH2xHNIGfdpJkDJUw==", "license": "ISC", "dependencies": { "foreground-child": "^3.1.0", @@ -5735,30 +5935,6 @@ "node": ">=10.13.0" } }, - "node_modules/glob/node_modules/brace-expansion": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", - "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", - "license": "MIT", - "dependencies": { - "balanced-match": "^1.0.0" - } - }, - "node_modules/glob/node_modules/minimatch": { - "version": "10.0.1", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.0.1.tgz", - "integrity": "sha512-ethXTt3SGGR+95gudmqJ1eNhRO7eGEGIgYA9vnPatK4/etz2MEVDno5GMCibdMTuBMyElzIlgxMna3K94XDIDQ==", - "license": "ISC", - "dependencies": { - "brace-expansion": "^2.0.1" - }, - "engines": { - "node": "20 || >=22" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, "node_modules/global-directory": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/global-directory/-/global-directory-4.0.1.tgz", @@ -5806,18 +5982,18 @@ } }, "node_modules/globby": { - "version": "14.0.2", - "resolved": "https://registry.npmjs.org/globby/-/globby-14.0.2.tgz", - "integrity": "sha512-s3Fq41ZVh7vbbe2PN3nrW7yC7U7MFVc5c98/iTl9c2GawNMKx/J648KQRW6WKkuU8GIbbh2IXfIRQjOZnXcTnw==", + "version": "14.1.0", + "resolved": "https://registry.npmjs.org/globby/-/globby-14.1.0.tgz", + "integrity": "sha512-0Ia46fDOaT7k4og1PDW4YbodWWr3scS2vAr2lTbsplOt2WkKp0vQbkI9wKis/T5LV/dqPjO3bpS/z6GTJB82LA==", "dev": true, "license": "MIT", "dependencies": { "@sindresorhus/merge-streams": "^2.1.0", - "fast-glob": "^3.3.2", - "ignore": "^5.2.4", - "path-type": "^5.0.0", + "fast-glob": "^3.3.3", + "ignore": "^7.0.3", + "path-type": "^6.0.0", "slash": "^5.1.0", - "unicorn-magic": "^0.1.0" + "unicorn-magic": "^0.3.0" }, "engines": { "node": ">=18" @@ -5839,27 +6015,37 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/globby/node_modules/ignore": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-7.0.3.tgz", + "integrity": "sha512-bAH5jbK/F3T3Jls4I0SO1hmPR0dKU0a7+SY6n1yzRtG54FLO8d6w/nxLFX2Nb7dBu6cCWXPaAME6cYqFUMmuCA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 4" + } + }, "node_modules/globby/node_modules/path-type": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/path-type/-/path-type-5.0.0.tgz", - "integrity": "sha512-5HviZNaZcfqP95rwpv+1HDgUamezbqdSYTyzjTvwtJSnIH+3vnbmWsItli8OFEndS984VT55M3jduxZbX351gg==", + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-6.0.0.tgz", + "integrity": "sha512-Vj7sf++t5pBD637NSfkxpHSMfWaeig5+DKWLhcqIYx6mWQz5hdJTGDVMQiJcw1ZYkhs7AazKDGpRVji1LJCZUQ==", "dev": true, "license": "MIT", "engines": { - "node": ">=12" + "node": ">=18" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/globby/node_modules/slash": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/slash/-/slash-5.1.0.tgz", - "integrity": "sha512-ZA6oR3T/pEyuqwMgAKT0/hAv8oAXckzbkmR0UkUosQ+Mc4RxGoJkRmwHgHufaenlyAgE1Mxgpdcrf75y6XcnDg==", + "node_modules/globby/node_modules/unicorn-magic": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/unicorn-magic/-/unicorn-magic-0.3.0.tgz", + "integrity": "sha512-+QBBXBCvifc56fsbuxZQ6Sic3wqqc3WWaqxs58gvJrcOuN83HGTCwz3oS5phzU9LthRNE9VrJCFCLUgHeeFnfA==", "dev": true, "license": "MIT", "engines": { - "node": ">=14.16" + "node": ">=18" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" @@ -6144,9 +6330,9 @@ } }, "node_modules/import-fresh": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", - "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.1.tgz", + "integrity": "sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ==", "dev": true, "license": "MIT", "dependencies": { @@ -6171,9 +6357,9 @@ } }, "node_modules/import-from-esm": { - "version": "1.3.4", - "resolved": "https://registry.npmjs.org/import-from-esm/-/import-from-esm-1.3.4.tgz", - "integrity": "sha512-7EyUlPFC0HOlBDpUFGfYstsU7XHxZJKAAMzCT8wZ0hMW7b+hG51LIKTDcsgtz8Pu6YC0HqRVbX+rVUtsGMUKvg==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/import-from-esm/-/import-from-esm-2.0.0.tgz", + "integrity": "sha512-YVt14UZCgsX1vZQ3gKjkWVdBdHQ6eu3MPU1TBgL1H5orXe2+jWD006WCPPtOuwlQm10NuzOW5WawiF1Q9veW8g==", "dev": true, "license": "MIT", "dependencies": { @@ -6181,7 +6367,7 @@ "import-meta-resolve": "^4.0.0" }, "engines": { - "node": ">=16.20" + "node": ">=18.20" } }, "node_modules/import-meta-resolve": { @@ -6317,13 +6503,17 @@ "license": "MIT" }, "node_modules/is-async-function": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-async-function/-/is-async-function-2.0.0.tgz", - "integrity": "sha512-Y1JXKrfykRJGdlDwdKlLpLyMIiWqWvuSd17TvZk68PLAOGOoF4Xyav1z0Xhoi+gCYjZVeC5SI+hYFOfvXmGRCA==", + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-async-function/-/is-async-function-2.1.1.tgz", + "integrity": "sha512-9dgM/cZBnNvjzaMYHVoxxfPj2QXt22Ev7SuuPrs+xav0ukGB0S6d4ydZdEiM48kLx5kDV+QBPrpVnFyefL8kkQ==", "dev": true, "license": "MIT", "dependencies": { - "has-tostringtag": "^1.0.0" + "async-function": "^1.0.0", + "call-bound": "^1.0.3", + "get-proto": "^1.0.1", + "has-tostringtag": "^1.0.2", + "safe-regex-test": "^1.1.0" }, "engines": { "node": ">= 0.4" @@ -6349,13 +6539,13 @@ } }, "node_modules/is-boolean-object": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.2.1.tgz", - "integrity": "sha512-l9qO6eFlUETHtuihLcYOaLKByJ1f+N4kthcU9YjHy3N+B3hWv0y/2Nd0mu/7lTFnRQHTrSdXF50HQ3bl5fEnng==", + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.2.2.tgz", + "integrity": "sha512-wa56o2/ElJMYqjCjGkXri7it5FbebW5usLw/nPmCMs5DeZ7eziSYZhSmPRn0txqeW4LnAmQQU7FgqLpsEFKM4A==", "dev": true, "license": "MIT", "dependencies": { - "call-bound": "^1.0.2", + "call-bound": "^1.0.3", "has-tostringtag": "^1.0.2" }, "engines": { @@ -6429,22 +6619,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/is-docker": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-2.2.1.tgz", - "integrity": "sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ==", - "dev": true, - "license": "MIT", - "bin": { - "is-docker": "cli.js" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/is-extglob": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", @@ -6481,13 +6655,16 @@ } }, "node_modules/is-generator-function": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/is-generator-function/-/is-generator-function-1.0.10.tgz", - "integrity": "sha512-jsEjy9l3yiXEQ+PsXdmBwEPcOxaXWLspKdplFUVI9vq1iZgIekeC0L167qeu86czQaxed3q/Uzuw0swL0irL8A==", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-generator-function/-/is-generator-function-1.1.0.tgz", + "integrity": "sha512-nPUB5km40q9e8UfN/Zc24eLlzdSf9OfKByBw9CIdw4H1giPMeA0OIJvbchsCu4npfI2QcMVBsGEBHKZ7wLTWmQ==", "dev": true, "license": "MIT", "dependencies": { - "has-tostringtag": "^1.0.0" + "call-bound": "^1.0.3", + "get-proto": "^1.0.0", + "has-tostringtag": "^1.0.2", + "safe-regex-test": "^1.1.0" }, "engines": { "node": ">= 0.4" @@ -6741,13 +6918,13 @@ } }, "node_modules/is-weakref": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-weakref/-/is-weakref-1.1.0.tgz", - "integrity": "sha512-SXM8Nwyys6nT5WP6pltOwKytLV7FqQ4UiibxVmW+EIosHcmCqkkjViTb5SNssDlkCiEYRP1/pdWUKVvZBmsR2Q==", + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/is-weakref/-/is-weakref-1.1.1.tgz", + "integrity": "sha512-6i9mGWSlqzNMEqpCp93KwRS1uUOodk2OJ6b+sq7ZPDSy2WuI5NFIxp/254TytR8ftefexkWn5xNiHUNpPOfSew==", "dev": true, "license": "MIT", "dependencies": { - "call-bound": "^1.0.2" + "call-bound": "^1.0.3" }, "engines": { "node": ">= 0.4" @@ -6773,31 +6950,21 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/is-wsl": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-2.2.0.tgz", - "integrity": "sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==", - "dev": true, - "license": "MIT", - "dependencies": { - "is-docker": "^2.0.0" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/isarray": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz", - "integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==", + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", + "integrity": "sha512-D2S+3GLxWH+uhrNEcoh/fnmYeP8E8/zHl644d/jdA0g2uyXvy3sb0qxotE+ne0LtccHknQzWwZEzhak7oJ0COQ==", "dev": true, "license": "MIT" }, "node_modules/isexe": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", - "license": "ISC" + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-3.1.1.tgz", + "integrity": "sha512-LpB/54B+/2J5hqQ7imZHfdU31OlgQqx7ZicVlkm9kzg9/w8GKLEcFfJl/t7DCEDueOyBAD6zCCwTO6Fzs0NoEQ==", + "license": "ISC", + "engines": { + "node": ">=16" + } }, "node_modules/issue-parser": { "version": "7.0.1", @@ -6871,9 +7038,9 @@ } }, "node_modules/jackspeak": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-4.0.2.tgz", - "integrity": "sha512-bZsjR/iRjl1Nk1UkjGpAzLNfQtzuijhn2g+pbZb98HQ1Gk8vM9hfbxeMBP+M2/UUdwj0RqGG3mlvk2MsAqwvEw==", + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-4.1.0.tgz", + "integrity": "sha512-9DDdhb5j6cpeitCbvLO7n7J4IxnbM6hoF6O1g4HQ5TfhvvKN8ywDM7668ZhMHRqVmxqhps/F6syWK2KcPxYlkw==", "license": "BlueOak-1.0.0", "dependencies": { "@isaacs/cliui": "^8.0.2" @@ -6982,26 +7149,6 @@ "dev": true, "license": "MIT" }, - "node_modules/json-stable-stringify": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/json-stable-stringify/-/json-stable-stringify-1.2.1.tgz", - "integrity": "sha512-Lp6HbbBgosLmJbjx0pBLbgvx68FaFU1sdkmBuckmhhJ88kL13OA51CDtR2yJB50eCNMH9wRqtQNNiAqQH4YXnA==", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bind": "^1.0.8", - "call-bound": "^1.0.3", - "isarray": "^2.0.5", - "jsonify": "^0.0.1", - "object-keys": "^1.1.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/json-stable-stringify-without-jsonify": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", @@ -7022,16 +7169,6 @@ "graceful-fs": "^4.1.6" } }, - "node_modules/jsonify": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/jsonify/-/jsonify-0.0.1.tgz", - "integrity": "sha512-2/Ki0GcmuqSrgFyelQq9M05y7PS0mEwuIzrf3f1fPqkVDVRvZrPZtVSMHxdgo8Aq0sxAOb/cr2aqqA3LeWHVPg==", - "dev": true, - "license": "Public Domain", - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/jsonparse": { "version": "1.3.1", "resolved": "https://registry.npmjs.org/jsonparse/-/jsonparse-1.3.1.tgz", @@ -7069,16 +7206,6 @@ "json-buffer": "3.0.1" } }, - "node_modules/klaw-sync": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/klaw-sync/-/klaw-sync-6.0.0.tgz", - "integrity": "sha512-nIeuVSzdCCs6TDPTqI8w1Yre34sSq7AkZ4B3sfOBbI2CgVSB4Du4aLQijFU2+lhAFCwt9+42Hel6lQNIv6AntQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "graceful-fs": "^4.1.11" - } - }, "node_modules/levn": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", @@ -7100,6 +7227,16 @@ "dev": true, "license": "MIT" }, + "node_modules/linkify-it": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/linkify-it/-/linkify-it-5.0.0.tgz", + "integrity": "sha512-5aHCbzQRADcdP+ATqnDuhhJ/MRIqDkZX5pyjFHRRysS8vZ5AbqGEoFIb6pYHPZ+L/OC2Lc+xT8uHVVR5CAK/wQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "uc.micro": "^2.0.0" + } + }, "node_modules/load-json-file": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-4.0.0.tgz", @@ -7178,6 +7315,7 @@ "version": "4.4.2", "resolved": "https://registry.npmjs.org/lodash.get/-/lodash.get-4.4.2.tgz", "integrity": "sha512-z+Uw/vLuy6gQe8cfaFWD7p0wVv8fJl3mbzXh33RS+0oW2wvUqiRXiQ69gLWSLpgB5/6sU+r6BlQR0MBILadqTQ==", + "deprecated": "This package is deprecated. Use the optional chaining (?.) operator instead.", "dev": true, "license": "MIT" }, @@ -7259,9 +7397,9 @@ "license": "MIT" }, "node_modules/loupe": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/loupe/-/loupe-3.1.2.tgz", - "integrity": "sha512-23I4pFZHmAemUnz8WZXbYRSKYj801VDaNv9ETuMh7IrMc7VuVVSo+Z9iLE3ni30+U48iDWfi30d3twAXBYmnCg==", + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/loupe/-/loupe-3.1.3.tgz", + "integrity": "sha512-kkIp7XSkP78ZxJEsSxW3712C6teJVoeHHwgo9zJ380de7IYyJ2ISlxojcH2pC5OFLewESmnRi/+XCDIEEVyoug==", "dev": true, "license": "MIT" }, @@ -7274,6 +7412,13 @@ "node": "20 || >=22" } }, + "node_modules/lunr": { + "version": "2.3.9", + "resolved": "https://registry.npmjs.org/lunr/-/lunr-2.3.9.tgz", + "integrity": "sha512-zTU3DaZaF3Rt9rhN3uBMGQD3dD2/vFQqnvZCDv4dl5iOzq2IZQqTxu90r4E5J+nP70J3ilqVCrbho2eWaeW8Ow==", + "dev": true, + "license": "MIT" + }, "node_modules/magic-string": { "version": "0.30.17", "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.17.tgz", @@ -7312,6 +7457,24 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/markdown-it": { + "version": "14.1.0", + "resolved": "https://registry.npmjs.org/markdown-it/-/markdown-it-14.1.0.tgz", + "integrity": "sha512-a54IwgWPaeBCAAsv13YgmALOF1elABB08FxO9i+r4VFk5Vl4pKokRPeX8u5TCgSsPi6ec1otfLjdOpVcgbpshg==", + "dev": true, + "license": "MIT", + "dependencies": { + "argparse": "^2.0.1", + "entities": "^4.4.0", + "linkify-it": "^5.0.0", + "mdurl": "^2.0.0", + "punycode.js": "^2.3.1", + "uc.micro": "^2.1.0" + }, + "bin": { + "markdown-it": "bin/markdown-it.mjs" + } + }, "node_modules/marked": { "version": "12.0.2", "resolved": "https://registry.npmjs.org/marked/-/marked-12.0.2.tgz", @@ -7326,25 +7489,25 @@ } }, "node_modules/marked-terminal": { - "version": "7.2.1", - "resolved": "https://registry.npmjs.org/marked-terminal/-/marked-terminal-7.2.1.tgz", - "integrity": "sha512-rQ1MoMFXZICWNsKMiiHwP/Z+92PLKskTPXj+e7uwXmuMPkNn7iTqC+IvDekVm1MPeC9wYQeLxeFaOvudRR/XbQ==", + "version": "7.3.0", + "resolved": "https://registry.npmjs.org/marked-terminal/-/marked-terminal-7.3.0.tgz", + "integrity": "sha512-t4rBvPsHc57uE/2nJOLmMbZCQ4tgAccAED3ngXQqW6g+TxA488JzJ+FK3lQkzBQOI1mRV/r/Kq+1ZlJ4D0owQw==", "dev": true, "license": "MIT", "dependencies": { "ansi-escapes": "^7.0.0", "ansi-regex": "^6.1.0", - "chalk": "^5.3.0", + "chalk": "^5.4.1", "cli-highlight": "^2.1.11", "cli-table3": "^0.6.5", - "node-emoji": "^2.1.3", + "node-emoji": "^2.2.0", "supports-hyperlinks": "^3.1.0" }, "engines": { "node": ">=16.0.0" }, "peerDependencies": { - "marked": ">=1 <15" + "marked": ">=1 <16" } }, "node_modules/math-intrinsics": { @@ -7357,6 +7520,13 @@ "node": ">= 0.4" } }, + "node_modules/mdurl": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/mdurl/-/mdurl-2.0.0.tgz", + "integrity": "sha512-Lf+9+2r+Tdp5wXDXC4PcIBjTDtq4UKjCPMQhKIuzpJNW0b96kVqSwW0bT7FhRSfmAiFYgP+SCRvdrDozfh0U5w==", + "dev": true, + "license": "MIT" + }, "node_modules/memorystream": { "version": "0.3.1", "resolved": "https://registry.npmjs.org/memorystream/-/memorystream-0.3.1.tgz", @@ -7465,16 +7635,18 @@ "license": "MIT" }, "node_modules/minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "dev": true, + "version": "10.0.1", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.0.1.tgz", + "integrity": "sha512-ethXTt3SGGR+95gudmqJ1eNhRO7eGEGIgYA9vnPatK4/etz2MEVDno5GMCibdMTuBMyElzIlgxMna3K94XDIDQ==", "license": "ISC", "dependencies": { - "brace-expansion": "^1.1.7" + "brace-expansion": "^2.0.1" }, "engines": { - "node": "*" + "node": "20 || >=22" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" } }, "node_modules/minimist": { @@ -7529,9 +7701,9 @@ } }, "node_modules/nanoid": { - "version": "3.3.8", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.8.tgz", - "integrity": "sha512-WNLf5Sd8oZxOm+TzppcYk8gVOgP+l58xNy58D0nbUnOxOWRWvlcCV4kUF7ltmI6PsrLl/BgKEyS4mqsGChFN0w==", + "version": "3.3.9", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.9.tgz", + "integrity": "sha512-SppoicMGpZvbF1l3z4x7No3OlIjP7QJvC9XR7AhZr1kL133KHnKPztkKDc+Ir4aJ/1VhTySrtKhrsycmrMQfvg==", "dev": true, "funding": [ { @@ -7818,6 +7990,17 @@ "node": ">= 4" } }, + "node_modules/npm-run-all/node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, "node_modules/npm-run-all/node_modules/chalk": { "version": "2.4.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", @@ -7853,6 +8036,19 @@ "node": ">=4" } }, + "node_modules/npm-run-all/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, "node_modules/npm-run-all/node_modules/supports-color": { "version": "5.5.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", @@ -10656,9 +10852,9 @@ } }, "node_modules/object-inspect": { - "version": "1.13.3", - "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.3.tgz", - "integrity": "sha512-kDCGIbxkDSXE3euJZZXzc6to7fCrKHNI/hSRQnRuQ+BWjFNzZwiFF8fj/6o2t2G9/jTj8PSIYTfCLelLZEeRpA==", + "version": "1.13.4", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.4.tgz", + "integrity": "sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==", "dev": true, "license": "MIT", "engines": { @@ -10725,23 +10921,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/open": { - "version": "7.4.2", - "resolved": "https://registry.npmjs.org/open/-/open-7.4.2.tgz", - "integrity": "sha512-MVHddDVweXZF3awtlAS+6pgKLlm/JgxZ90+/NBurBoQctVOOB/zDdVjcyPzQ+0laDGbsWgrRkflI65sQeOgT9Q==", - "dev": true, - "license": "MIT", - "dependencies": { - "is-docker": "^2.0.0", - "is-wsl": "^2.1.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/optionator": { "version": "0.9.4", "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.4.tgz", @@ -10760,14 +10939,22 @@ "node": ">= 0.8.0" } }, - "node_modules/os-tmpdir": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", - "integrity": "sha512-D2FR03Vir7FIu45XBY20mTb+/ZSWB00sjU9jdQXt83gDrI4Ztz5Fs7/yy74g2N5SVQY4xY1qDr4rNddwYRVX0g==", + "node_modules/own-keys": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/own-keys/-/own-keys-1.0.1.tgz", + "integrity": "sha512-qFOyK5PjiWZd+QQIh+1jhdb9LpxTF0qs7Pm8o5QHYZ0M3vKqSqzsZaEB6oWlxZ+q2sJBMI/Ktgd2N5ZwQoRHfg==", "dev": true, "license": "MIT", + "dependencies": { + "get-intrinsic": "^1.2.6", + "object-keys": "^1.1.1", + "safe-push-apply": "^1.0.0" + }, "engines": { - "node": ">=0.10.0" + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, "node_modules/p-each-series": { @@ -10952,126 +11139,6 @@ "dev": true, "license": "MIT" }, - "node_modules/patch-package": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/patch-package/-/patch-package-8.0.0.tgz", - "integrity": "sha512-da8BVIhzjtgScwDJ2TtKsfT5JFWz1hYoBl9rUQ1f38MC2HwnEIkK8VN3dKMKcP7P7bvvgzNDbfNHtx3MsQb5vA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@yarnpkg/lockfile": "^1.1.0", - "chalk": "^4.1.2", - "ci-info": "^3.7.0", - "cross-spawn": "^7.0.3", - "find-yarn-workspace-root": "^2.0.0", - "fs-extra": "^9.0.0", - "json-stable-stringify": "^1.0.2", - "klaw-sync": "^6.0.0", - "minimist": "^1.2.6", - "open": "^7.4.2", - "rimraf": "^2.6.3", - "semver": "^7.5.3", - "slash": "^2.0.0", - "tmp": "^0.0.33", - "yaml": "^2.2.2" - }, - "bin": { - "patch-package": "index.js" - }, - "engines": { - "node": ">=14", - "npm": ">5" - } - }, - "node_modules/patch-package/node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "license": "MIT", - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/patch-package/node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/patch-package/node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/patch-package/node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true, - "license": "MIT" - }, - "node_modules/patch-package/node_modules/glob": { - "version": "7.2.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", - "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", - "deprecated": "Glob versions prior to v9 are no longer supported", - "dev": true, - "license": "ISC", - "dependencies": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.1.1", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - }, - "engines": { - "node": "*" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/patch-package/node_modules/rimraf": { - "version": "2.7.1", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", - "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", - "deprecated": "Rimraf versions prior to v4 are no longer supported", - "dev": true, - "license": "ISC", - "dependencies": { - "glob": "^7.1.3" - }, - "bin": { - "rimraf": "bin.js" - } - }, "node_modules/path-exists": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-5.0.0.tgz", @@ -11138,9 +11205,9 @@ } }, "node_modules/pathe": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/pathe/-/pathe-1.1.2.tgz", - "integrity": "sha512-whLdWMYL2TwI08hn8/ZqAbrVemu0LNaNNJZX73O6qaIdCTfXutsLhMkjdENX0qhsQ9uIimo4/aQOmXkoon2nDQ==", + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/pathe/-/pathe-2.0.3.tgz", + "integrity": "sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==", "dev": true, "license": "MIT" }, @@ -11284,9 +11351,9 @@ } }, "node_modules/possible-typed-array-names": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/possible-typed-array-names/-/possible-typed-array-names-1.0.0.tgz", - "integrity": "sha512-d7Uw+eZoloe0EHDIYoe+bQ5WXnGMOpmiZFTuMWCwpjzzkL2nTjcKiAk4hh8TjnGye2TwWOk3UXucZ+3rbmBa8Q==", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/possible-typed-array-names/-/possible-typed-array-names-1.1.0.tgz", + "integrity": "sha512-/+5VFTchJDoVj3bhoqi6UeymcD00DAwb1nJwamzPvHEszJ4FpF6SNNbUbOS8yI56qHzdV8eK0qEfOSiodkTdxg==", "dev": true, "license": "MIT", "engines": { @@ -11294,9 +11361,9 @@ } }, "node_modules/postcss": { - "version": "8.4.49", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.49.tgz", - "integrity": "sha512-OCVPnIObs4N29kxTjzLfUryOkvZEq+pf8jTF0lg8E7uETuWHA+v7j3c/xJmiqpX450191LlmZfUKkXxkTry7nA==", + "version": "8.5.3", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.3.tgz", + "integrity": "sha512-dle9A3yYxlBSrt8Fu+IpjGT8SY8hN0mlaA6GY8t0P5PjIOZemULz/E2Bnm/2dcUOena75OTNkHI76uZBNUUq3A==", "dev": true, "funding": [ { @@ -11314,7 +11381,7 @@ ], "license": "MIT", "dependencies": { - "nanoid": "^3.3.7", + "nanoid": "^3.3.8", "picocolors": "^1.1.1", "source-map-js": "^1.2.1" }, @@ -11333,9 +11400,9 @@ } }, "node_modules/prettier": { - "version": "3.3.3", - "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.3.3.tgz", - "integrity": "sha512-i2tDNA0O5IrMO757lfrdQZCc2jPNDVntV0m/+4whiDfWaTKfMNgR7Qz0NAeGz/nRqF4m5/6CLzbP4/liHt12Ew==", + "version": "3.5.3", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.5.3.tgz", + "integrity": "sha512-QQtaxnoDJeAkDvDKWCLiwIXkTgRhwYDEQCghU9Z6q03iyek/rxRh/2lC3HB7P8sWT2xC/y5JDctPLBIGzHKbhw==", "dev": true, "license": "MIT", "bin": { @@ -11401,6 +11468,16 @@ "node": ">=6" } }, + "node_modules/punycode.js": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/punycode.js/-/punycode.js-2.3.1.tgz", + "integrity": "sha512-uxFIHU0YlHYhDQtV4R9J6a52SLx28BCjT+4ieh7IGbgwVJWO+km431c4yRlREUAsAmt/uMjQUyQHNEPf0M39CA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, "node_modules/queue-microtask": { "version": "1.2.3", "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", @@ -11574,27 +11651,20 @@ "string_decoder": "~0.10.x" } }, - "node_modules/readable-stream/node_modules/isarray": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", - "integrity": "sha512-D2S+3GLxWH+uhrNEcoh/fnmYeP8E8/zHl644d/jdA0g2uyXvy3sb0qxotE+ne0LtccHknQzWwZEzhak7oJ0COQ==", - "dev": true, - "license": "MIT" - }, "node_modules/reflect.getprototypeof": { - "version": "1.0.9", - "resolved": "https://registry.npmjs.org/reflect.getprototypeof/-/reflect.getprototypeof-1.0.9.tgz", - "integrity": "sha512-r0Ay04Snci87djAsI4U+WNRcSw5S4pOH7qFjd/veA5gC7TbqESR3tcj28ia95L/fYUDw11JKP7uqUKUAfVvV5Q==", + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/reflect.getprototypeof/-/reflect.getprototypeof-1.0.10.tgz", + "integrity": "sha512-00o4I+DVrefhv+nX0ulyi3biSHCPDe+yLv5o/p6d/UVlirijB8E16FtfwSAi4g3tcqrQ4lRAqQSoFEZJehYEcw==", "dev": true, "license": "MIT", "dependencies": { "call-bind": "^1.0.8", "define-properties": "^1.2.1", - "dunder-proto": "^1.0.1", - "es-abstract": "^1.23.6", + "es-abstract": "^1.23.9", "es-errors": "^1.3.0", - "get-intrinsic": "^1.2.6", - "gopd": "^1.2.0", + "es-object-atoms": "^1.0.0", + "get-intrinsic": "^1.2.7", + "get-proto": "^1.0.1", "which-builtin-type": "^1.2.1" }, "engines": { @@ -11605,15 +11675,17 @@ } }, "node_modules/regexp.prototype.flags": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.5.3.tgz", - "integrity": "sha512-vqlC04+RQoFalODCbCumG2xIOvapzVMHwsyIGM/SIE8fRhFFsXeH8/QQ+s0T0kDAhKc4k30s73/0ydkHQz6HlQ==", + "version": "1.5.4", + "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.5.4.tgz", + "integrity": "sha512-dYqgNSZbDwkaJ2ceRd9ojCGjBq+mOm9LmtXnAnEGyHhN/5R7iDW2TRw3h+o/jCFxus3P2LfWIIiwowAjANm7IA==", "dev": true, "license": "MIT", "dependencies": { - "call-bind": "^1.0.7", + "call-bind": "^1.0.8", "define-properties": "^1.2.1", "es-errors": "^1.3.0", + "get-proto": "^1.0.1", + "gopd": "^1.2.0", "set-function-name": "^2.0.2" }, "engines": { @@ -11624,9 +11696,9 @@ } }, "node_modules/registry-auth-token": { - "version": "5.0.3", - "resolved": "https://registry.npmjs.org/registry-auth-token/-/registry-auth-token-5.0.3.tgz", - "integrity": "sha512-1bpc9IyC+e+CNFRaWyn77tk4xGG4PPUyfakSmA6F6cvUDjrm58dfyJ3II+9yb10EDkHoy1LaPSmHaWLOH3m6HA==", + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/registry-auth-token/-/registry-auth-token-5.1.0.tgz", + "integrity": "sha512-GdekYuwLXLxMuFTwAPg5UKGLW/UXzQrZvH/Zj791BQif5T05T0RsaLfHc9q3ZOKi7n+BoprPD9mJ0O0k4xzUlw==", "dev": true, "license": "MIT", "dependencies": { @@ -11698,9 +11770,9 @@ } }, "node_modules/reusify": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", - "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.1.0.tgz", + "integrity": "sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==", "dev": true, "license": "MIT", "engines": { @@ -11729,9 +11801,9 @@ } }, "node_modules/rollup": { - "version": "4.29.1", - "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.29.1.tgz", - "integrity": "sha512-RaJ45M/kmJUzSWDs1Nnd5DdV4eerC98idtUOVr6FfKcgxqvjwHmxc5upLF9qZU9EpsVzzhleFahrT3shLuJzIw==", + "version": "4.35.0", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.35.0.tgz", + "integrity": "sha512-kg6oI4g+vc41vePJyO6dHt/yl0Rz3Thv0kJeVQ3D1kS3E5XSuKbPc29G4IpT/Kv1KQwgHVcN+HtyS+HYLNSvQg==", "dev": true, "license": "MIT", "dependencies": { @@ -11745,25 +11817,25 @@ "npm": ">=8.0.0" }, "optionalDependencies": { - "@rollup/rollup-android-arm-eabi": "4.29.1", - "@rollup/rollup-android-arm64": "4.29.1", - "@rollup/rollup-darwin-arm64": "4.29.1", - "@rollup/rollup-darwin-x64": "4.29.1", - "@rollup/rollup-freebsd-arm64": "4.29.1", - "@rollup/rollup-freebsd-x64": "4.29.1", - "@rollup/rollup-linux-arm-gnueabihf": "4.29.1", - "@rollup/rollup-linux-arm-musleabihf": "4.29.1", - "@rollup/rollup-linux-arm64-gnu": "4.29.1", - "@rollup/rollup-linux-arm64-musl": "4.29.1", - "@rollup/rollup-linux-loongarch64-gnu": "4.29.1", - "@rollup/rollup-linux-powerpc64le-gnu": "4.29.1", - "@rollup/rollup-linux-riscv64-gnu": "4.29.1", - "@rollup/rollup-linux-s390x-gnu": "4.29.1", - "@rollup/rollup-linux-x64-gnu": "4.29.1", - "@rollup/rollup-linux-x64-musl": "4.29.1", - "@rollup/rollup-win32-arm64-msvc": "4.29.1", - "@rollup/rollup-win32-ia32-msvc": "4.29.1", - "@rollup/rollup-win32-x64-msvc": "4.29.1", + "@rollup/rollup-android-arm-eabi": "4.35.0", + "@rollup/rollup-android-arm64": "4.35.0", + "@rollup/rollup-darwin-arm64": "4.35.0", + "@rollup/rollup-darwin-x64": "4.35.0", + "@rollup/rollup-freebsd-arm64": "4.35.0", + "@rollup/rollup-freebsd-x64": "4.35.0", + "@rollup/rollup-linux-arm-gnueabihf": "4.35.0", + "@rollup/rollup-linux-arm-musleabihf": "4.35.0", + "@rollup/rollup-linux-arm64-gnu": "4.35.0", + "@rollup/rollup-linux-arm64-musl": "4.35.0", + "@rollup/rollup-linux-loongarch64-gnu": "4.35.0", + "@rollup/rollup-linux-powerpc64le-gnu": "4.35.0", + "@rollup/rollup-linux-riscv64-gnu": "4.35.0", + "@rollup/rollup-linux-s390x-gnu": "4.35.0", + "@rollup/rollup-linux-x64-gnu": "4.35.0", + "@rollup/rollup-linux-x64-musl": "4.35.0", + "@rollup/rollup-win32-arm64-msvc": "4.35.0", + "@rollup/rollup-win32-ia32-msvc": "4.35.0", + "@rollup/rollup-win32-x64-msvc": "4.35.0", "fsevents": "~2.3.2" } }, @@ -11811,6 +11883,13 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/safe-array-concat/node_modules/isarray": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz", + "integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==", + "dev": true, + "license": "MIT" + }, "node_modules/safe-buffer": { "version": "5.1.2", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", @@ -11818,6 +11897,30 @@ "dev": true, "license": "MIT" }, + "node_modules/safe-push-apply": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/safe-push-apply/-/safe-push-apply-1.0.0.tgz", + "integrity": "sha512-iKE9w/Z7xCzUMIZqdBsp6pEQvwuEebH4vdpjcDWnyzaI6yl6O9FHvVpmGelvEHNsoY6wGblkxR6Zty/h00WiSA==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "isarray": "^2.0.5" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/safe-push-apply/node_modules/isarray": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz", + "integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==", + "dev": true, + "license": "MIT" + }, "node_modules/safe-regex-test": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/safe-regex-test/-/safe-regex-test-1.1.0.tgz", @@ -11837,9 +11940,9 @@ } }, "node_modules/semantic-release": { - "version": "24.2.0", - "resolved": "https://registry.npmjs.org/semantic-release/-/semantic-release-24.2.0.tgz", - "integrity": "sha512-fQfn6e/aYToRtVJYKqneFM1Rg3KP2gh3wSWtpYsLlz6uaPKlISrTzvYAFn+mYWo07F0X1Cz5ucU89AVE8X1mbg==", + "version": "24.2.3", + "resolved": "https://registry.npmjs.org/semantic-release/-/semantic-release-24.2.3.tgz", + "integrity": "sha512-KRhQG9cUazPavJiJEFIJ3XAMjgfd0fcK3B+T26qOl8L0UG5aZUjeRfREO0KM5InGtYwxqiiytkJrbcYoLDEv0A==", "dev": true, "license": "MIT", "dependencies": { @@ -11859,7 +11962,7 @@ "git-log-parser": "^1.2.0", "hook-std": "^3.0.0", "hosted-git-info": "^8.0.0", - "import-from-esm": "^1.3.1", + "import-from-esm": "^2.0.0", "lodash-es": "^4.17.21", "marked": "^12.0.0", "marked-terminal": "^7.0.0", @@ -11901,9 +12004,9 @@ "license": "ISC" }, "node_modules/semver": { - "version": "7.6.3", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz", - "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==", + "version": "7.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.1.tgz", + "integrity": "sha512-hlq8tAfn0m/61p4BVRcPzIGr6LKiMwo4VM6dGi6pt4qcRkmNzTcWq6eCEjEh+qXjkMDvPlOFFSGwQjoEa6gyMA==", "dev": true, "license": "ISC", "bin": { @@ -11976,6 +12079,21 @@ "node": ">= 0.4" } }, + "node_modules/set-proto": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/set-proto/-/set-proto-1.0.0.tgz", + "integrity": "sha512-RJRdvCo6IAnPdsvP/7m6bsQqNnn1FCBX5ZNtFL98MmFF/4xAIJTIg1YbHW5DC2W5SKZanrC6i4HsJqlajw/dZw==", + "dev": true, + "license": "MIT", + "dependencies": { + "dunder-proto": "^1.0.1", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + } + }, "node_modules/shebang-command": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", @@ -12195,13 +12313,16 @@ } }, "node_modules/slash": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/slash/-/slash-2.0.0.tgz", - "integrity": "sha512-ZYKh3Wh2z1PpEXWr0MpSBZ0V6mZHAQfYevttO11c51CaWjGTaadiKZ+wVt1PbMlDV5qhMFslpZCemhwOK7C89A==", + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-5.1.0.tgz", + "integrity": "sha512-ZA6oR3T/pEyuqwMgAKT0/hAv8oAXckzbkmR0UkUosQ+Mc4RxGoJkRmwHgHufaenlyAgE1Mxgpdcrf75y6XcnDg==", "dev": true, "license": "MIT", "engines": { - "node": ">=6" + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/slice-ansi": { @@ -12315,9 +12436,9 @@ } }, "node_modules/spdx-license-ids": { - "version": "3.0.20", - "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.20.tgz", - "integrity": "sha512-jg25NiDV/1fLtSgEgyvVyDunvaNHbuwF9lfNV17gSmPFAlYzdfNBlLtLzXTevwkPj7DhGbmN9VnmJIgLnhvaBw==", + "version": "3.0.21", + "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.21.tgz", + "integrity": "sha512-Bvg/8F5XephndSK3JffaRqdT+gyhfqIPwDHpX80tJrF8QQRYMo8sNMeaZ2Dp5+jhwKnUmIOyFFQfHRkjJm5nXg==", "dev": true, "license": "CC0-1.0" }, @@ -12339,9 +12460,9 @@ "license": "MIT" }, "node_modules/std-env": { - "version": "3.8.0", - "resolved": "https://registry.npmjs.org/std-env/-/std-env-3.8.0.tgz", - "integrity": "sha512-Bc3YwwCB+OzldMxOXJIIvC6cPRWr/LxOp48CdQTOkPyk/t4JWWJbrilwBd7RJzKV8QW7tJkcgAmeuLLJugl5/w==", + "version": "3.8.1", + "resolved": "https://registry.npmjs.org/std-env/-/std-env-3.8.1.tgz", + "integrity": "sha512-vj5lIj3Mwf9D79hBkltk5qmkFI+biIKWS2IBxEyEU3AX1tUf7AoL8nSazCOiiqQsGKIq01SClsKEzweu34uwvA==", "dev": true, "license": "MIT" }, @@ -12637,9 +12758,9 @@ } }, "node_modules/supports-hyperlinks": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/supports-hyperlinks/-/supports-hyperlinks-3.1.0.tgz", - "integrity": "sha512-2rn0BZ+/f7puLOHZm1HOJfwBggfaHXUpPUSSG/SWM4TWp5KCfmNYwnC3hruy2rZlMnmWZ+QAGpZfchu3f3695A==", + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/supports-hyperlinks/-/supports-hyperlinks-3.2.0.tgz", + "integrity": "sha512-zFObLMyZeEwzAoKCyu1B91U79K2t7ApXuQfo8OuxwXLDgcKxuwM+YvcbIhm6QWqz7mHUH1TVytR1PwVVjEuMig==", "dev": true, "license": "MIT", "dependencies": { @@ -12650,7 +12771,7 @@ "node": ">=14.18" }, "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "url": "https://github.com/chalk/supports-hyperlinks?sponsor=1" } }, "node_modules/supports-preserve-symlinks-flag": { @@ -12815,16 +12936,6 @@ "node": ">=18" } }, - "node_modules/test-exclude/node_modules/brace-expansion": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", - "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", - "dev": true, - "license": "MIT", - "dependencies": { - "balanced-match": "^1.0.0" - } - }, "node_modules/test-exclude/node_modules/glob": { "version": "10.4.5", "resolved": "https://registry.npmjs.org/glob/-/glob-10.4.5.tgz", @@ -12915,13 +13026,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/text-table": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", - "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==", - "dev": true, - "license": "MIT" - }, "node_modules/thenify": { "version": "3.3.1", "resolved": "https://registry.npmjs.org/thenify/-/thenify-3.3.1.tgz", @@ -13020,9 +13124,9 @@ "license": "MIT" }, "node_modules/tinyexec": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/tinyexec/-/tinyexec-0.3.1.tgz", - "integrity": "sha512-WiCJLEECkO18gwqIp6+hJg0//p23HXp4S+gGtAKu3mI2F2/sXC4FvHvXvB0zJVVaTPhx1/tOwdbRsa1sOBIKqQ==", + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/tinyexec/-/tinyexec-0.3.2.tgz", + "integrity": "sha512-KQQR9yN7R5+OSwaK0XQoj22pwHoTlgYqmUscPYoknOoWCWfj/5/ABTMRi69FrKU5ffPVh5QcFikpWJI/P1ocHA==", "dev": true, "license": "MIT" }, @@ -13037,9 +13141,9 @@ } }, "node_modules/tinyrainbow": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/tinyrainbow/-/tinyrainbow-1.2.0.tgz", - "integrity": "sha512-weEDEq7Z5eTHPDh4xjX789+fHfF+P8boiFB+0vbWzpbnbsEr/GRaohi/uMKxg8RZMXnl1ItAi/IUHWMsjDV7kQ==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/tinyrainbow/-/tinyrainbow-2.0.0.tgz", + "integrity": "sha512-op4nsTR47R6p0vMUUoYl/a+ljLFVtlfaXkLQmqfLR1qHma1h/ysYk4hEXZ880bf2CYgTskvTa/e196Vd5dDQXw==", "dev": true, "license": "MIT", "engines": { @@ -13056,19 +13160,6 @@ "node": ">=14.0.0" } }, - "node_modules/tmp": { - "version": "0.0.33", - "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz", - "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==", - "dev": true, - "license": "MIT", - "dependencies": { - "os-tmpdir": "~1.0.2" - }, - "engines": { - "node": ">=0.6.0" - } - }, "node_modules/to-regex-range": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", @@ -13096,16 +13187,16 @@ } }, "node_modules/ts-api-utils": { - "version": "1.4.3", - "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-1.4.3.tgz", - "integrity": "sha512-i3eMG77UTMD0hZhgRS562pv83RC6ukSAC2GMNWc+9dieh/+jDM5u5YG+NHX6VNDRHQcHwmsTHctP9LhbC3WxVw==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-2.0.1.tgz", + "integrity": "sha512-dnlgjFSVetynI8nzgJ+qF62efpglpWRk8isUEWZGWlJYySCTD6aKvbUDu+zbPeDakk3bg5H4XpitHukgfL1m9w==", "dev": true, "license": "MIT", "engines": { - "node": ">=16" + "node": ">=18.12" }, "peerDependencies": { - "typescript": ">=4.2.0" + "typescript": ">=4.8.4" } }, "node_modules/tslib": { @@ -13115,13 +13206,13 @@ "license": "0BSD" }, "node_modules/tsx": { - "version": "4.19.1", - "resolved": "https://registry.npmjs.org/tsx/-/tsx-4.19.1.tgz", - "integrity": "sha512-0flMz1lh74BR4wOvBjuh9olbnwqCPc35OOlfyzHba0Dc+QNUeWX/Gq2YTbnwcWPO3BMd8fkzRVrHcsR+a7z7rA==", + "version": "4.19.3", + "resolved": "https://registry.npmjs.org/tsx/-/tsx-4.19.3.tgz", + "integrity": "sha512-4H8vUNGNjQ4V2EOoGw005+c+dGuPSnhpPBPHBtsZdGZBk/iJb4kguGlPWaZTZ3q5nMtFOEsY0nRDlh9PJyd6SQ==", "dev": true, "license": "MIT", "dependencies": { - "esbuild": "~0.23.0", + "esbuild": "~0.25.0", "get-tsconfig": "^4.7.5" }, "bin": { @@ -13154,9 +13245,9 @@ } }, "node_modules/type-fest": { - "version": "4.30.2", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-4.30.2.tgz", - "integrity": "sha512-UJShLPYi1aWqCdq9HycOL/gwsuqda1OISdBO3t8RlXQC4QvtuIz4b5FCfe2dQIWEpmlRExKmcTBfP1r9bhY7ig==", + "version": "4.37.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-4.37.0.tgz", + "integrity": "sha512-S/5/0kFftkq27FPNye0XM1e2NsnoD/3FS+pBmbjmmtLT6I+i344KoOf7pvXreaFsDamWeaJX55nczA1m5PsBDg==", "dev": true, "license": "(MIT OR CC0-1.0)", "engines": { @@ -13244,11 +13335,62 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/typescript": { - "version": "5.7.2", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.7.2.tgz", - "integrity": "sha512-i5t66RHxDvVN40HfDd1PsEThGNnlMCMT3jMUuoh9/0TaqWevNontacunWyN02LA9/fIbEWlcHZcgTKb9QoaLfg==", + "node_modules/typedoc": { + "version": "0.27.9", + "resolved": "https://registry.npmjs.org/typedoc/-/typedoc-0.27.9.tgz", + "integrity": "sha512-/z585740YHURLl9DN2jCWe6OW7zKYm6VoQ93H0sxZ1cwHQEQrUn5BJrEnkWhfzUdyO+BLGjnKUZ9iz9hKloFDw==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@gerrit0/mini-shiki": "^1.24.0", + "lunr": "^2.3.9", + "markdown-it": "^14.1.0", + "minimatch": "^9.0.5", + "yaml": "^2.6.1" + }, + "bin": { + "typedoc": "bin/typedoc" + }, + "engines": { + "node": ">= 18" + }, + "peerDependencies": { + "typescript": "5.0.x || 5.1.x || 5.2.x || 5.3.x || 5.4.x || 5.5.x || 5.6.x || 5.7.x || 5.8.x" + } + }, + "node_modules/typedoc-plugin-markdown": { + "version": "4.4.2", + "resolved": "https://registry.npmjs.org/typedoc-plugin-markdown/-/typedoc-plugin-markdown-4.4.2.tgz", + "integrity": "sha512-kJVkU2Wd+AXQpyL6DlYXXRrfNrHrEIUgiABWH8Z+2Lz5Sq6an4dQ/hfvP75bbokjNDUskOdFlEEm/0fSVyC7eg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 18" + }, + "peerDependencies": { + "typedoc": "0.27.x" + } + }, + "node_modules/typedoc/node_modules/minimatch": { + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", + "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/typescript": { + "version": "5.8.2", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.8.2.tgz", + "integrity": "sha512-aJn6wq13/afZp/jT9QZmwEjDqqvSGp1VT5GVg+f/t6/oVyrgXM6BY1h9BRh/O5p3PlUPAe+WuiEZOmb/49RqoQ==", "license": "Apache-2.0", "bin": { "tsc": "bin/tsc", @@ -13258,6 +13400,13 @@ "node": ">=14.17" } }, + "node_modules/uc.micro": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/uc.micro/-/uc.micro-2.1.0.tgz", + "integrity": "sha512-ARDJmphmdvUk6Glw7y9DQ2bFkKBHwQHLi2lsaH6PPmz/Ka9sFOBsBluozhDltWmnv9u/cF6Rt87znRTPV+yp/A==", + "dev": true, + "license": "MIT" + }, "node_modules/uglify-js": { "version": "3.19.3", "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.19.3.tgz", @@ -13292,9 +13441,9 @@ } }, "node_modules/undici-types": { - "version": "6.19.8", - "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.19.8.tgz", - "integrity": "sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw==", + "version": "6.20.0", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.20.0.tgz", + "integrity": "sha512-Ny6QZ2Nju20vw1SRHe3d9jVu6gJ+4e3+MMpqu7pqE5HT6WsTSlce++GQmK5UXS8mzV8DSYHrQH+Xrf2jVcuKNg==", "dev": true, "license": "MIT" }, @@ -13413,21 +13562,21 @@ } }, "node_modules/vite": { - "version": "5.4.11", - "resolved": "https://registry.npmjs.org/vite/-/vite-5.4.11.tgz", - "integrity": "sha512-c7jFQRklXua0mTzneGW9QVyxFjUgwcihC4bXEtujIo2ouWCe1Ajt/amn2PCxYnhYfd5k09JX3SB7OYWFKYqj8Q==", + "version": "6.2.3", + "resolved": "https://registry.npmjs.org/vite/-/vite-6.2.3.tgz", + "integrity": "sha512-IzwM54g4y9JA/xAeBPNaDXiBF8Jsgl3VBQ2YQ/wOY6fyW3xMdSoltIV3Bo59DErdqdE6RxUfv8W69DvUorE4Eg==", "dev": true, "license": "MIT", "dependencies": { - "esbuild": "^0.21.3", - "postcss": "^8.4.43", - "rollup": "^4.20.0" + "esbuild": "^0.25.0", + "postcss": "^8.5.3", + "rollup": "^4.30.1" }, "bin": { "vite": "bin/vite.js" }, "engines": { - "node": "^18.0.0 || >=20.0.0" + "node": "^18.0.0 || ^20.0.0 || >=22.0.0" }, "funding": { "url": "https://github.com/vitejs/vite?sponsor=1" @@ -13436,19 +13585,25 @@ "fsevents": "~2.3.3" }, "peerDependencies": { - "@types/node": "^18.0.0 || >=20.0.0", + "@types/node": "^18.0.0 || ^20.0.0 || >=22.0.0", + "jiti": ">=1.21.0", "less": "*", "lightningcss": "^1.21.0", "sass": "*", "sass-embedded": "*", "stylus": "*", "sugarss": "*", - "terser": "^5.4.0" + "terser": "^5.16.0", + "tsx": "^4.8.1", + "yaml": "^2.4.2" }, "peerDependenciesMeta": { "@types/node": { "optional": true }, + "jiti": { + "optional": true + }, "less": { "optional": true }, @@ -13469,547 +13624,178 @@ }, "terser": { "optional": true + }, + "tsx": { + "optional": true + }, + "yaml": { + "optional": true } } }, "node_modules/vite-node": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/vite-node/-/vite-node-2.1.2.tgz", - "integrity": "sha512-HPcGNN5g/7I2OtPjLqgOtCRu/qhVvBxTUD3qzitmL0SrG1cWFzxzhMDWussxSbrRYWqnKf8P2jiNhPMSN+ymsQ==", + "version": "3.0.8", + "resolved": "https://registry.npmjs.org/vite-node/-/vite-node-3.0.8.tgz", + "integrity": "sha512-6PhR4H9VGlcwXZ+KWCdMqbtG649xCPZqfI9j2PsK1FcXgEzro5bGHcVKFCTqPLaNKZES8Evqv4LwvZARsq5qlg==", "dev": true, "license": "MIT", "dependencies": { "cac": "^6.7.14", - "debug": "^4.3.6", - "pathe": "^1.1.2", - "vite": "^5.0.0" + "debug": "^4.4.0", + "es-module-lexer": "^1.6.0", + "pathe": "^2.0.3", + "vite": "^5.0.0 || ^6.0.0" }, "bin": { "vite-node": "vite-node.mjs" }, "engines": { - "node": "^18.0.0 || >=20.0.0" + "node": "^18.0.0 || ^20.0.0 || >=22.0.0" }, "funding": { "url": "https://opencollective.com/vitest" } }, - "node_modules/vite/node_modules/@esbuild/aix-ppc64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.21.5.tgz", - "integrity": "sha512-1SDgH6ZSPTlggy1yI6+Dbkiz8xzpHJEVAlF/AM1tHPLsf5STom9rwtjE4hKAF20FfXXNTFqEYXyJNWh1GiZedQ==", - "cpu": [ - "ppc64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "aix" - ], + "node_modules/vitest": { + "version": "3.0.8", + "resolved": "https://registry.npmjs.org/vitest/-/vitest-3.0.8.tgz", + "integrity": "sha512-dfqAsNqRGUc8hB9OVR2P0w8PZPEckti2+5rdZip0WIz9WW0MnImJ8XiR61QhqLa92EQzKP2uPkzenKOAHyEIbA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@vitest/expect": "3.0.8", + "@vitest/mocker": "3.0.8", + "@vitest/pretty-format": "^3.0.8", + "@vitest/runner": "3.0.8", + "@vitest/snapshot": "3.0.8", + "@vitest/spy": "3.0.8", + "@vitest/utils": "3.0.8", + "chai": "^5.2.0", + "debug": "^4.4.0", + "expect-type": "^1.1.0", + "magic-string": "^0.30.17", + "pathe": "^2.0.3", + "std-env": "^3.8.0", + "tinybench": "^2.9.0", + "tinyexec": "^0.3.2", + "tinypool": "^1.0.2", + "tinyrainbow": "^2.0.0", + "vite": "^5.0.0 || ^6.0.0", + "vite-node": "3.0.8", + "why-is-node-running": "^2.3.0" + }, + "bin": { + "vitest": "vitest.mjs" + }, "engines": { - "node": ">=12" + "node": "^18.0.0 || ^20.0.0 || >=22.0.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + }, + "peerDependencies": { + "@edge-runtime/vm": "*", + "@types/debug": "^4.1.12", + "@types/node": "^18.0.0 || ^20.0.0 || >=22.0.0", + "@vitest/browser": "3.0.8", + "@vitest/ui": "3.0.8", + "happy-dom": "*", + "jsdom": "*" + }, + "peerDependenciesMeta": { + "@edge-runtime/vm": { + "optional": true + }, + "@types/debug": { + "optional": true + }, + "@types/node": { + "optional": true + }, + "@vitest/browser": { + "optional": true + }, + "@vitest/ui": { + "optional": true + }, + "happy-dom": { + "optional": true + }, + "jsdom": { + "optional": true + } } }, - "node_modules/vite/node_modules/@esbuild/android-arm": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.21.5.tgz", - "integrity": "sha512-vCPvzSjpPHEi1siZdlvAlsPxXl7WbOVUBBAowWug4rJHb68Ox8KualB+1ocNvT5fjv6wpkX6o/iEpbDrf68zcg==", - "cpu": [ - "arm" - ], + "node_modules/vlq": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/vlq/-/vlq-2.0.4.tgz", + "integrity": "sha512-aodjPa2wPQFkra1G8CzJBTHXhgk3EVSwxSWXNPr1fgdFLUb8kvLV1iEb6rFgasIsjP82HWI6dsb5Io26DDnasA==", "dev": true, "license": "MIT", - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=12" - } + "peer": true }, - "node_modules/vite/node_modules/@esbuild/android-arm64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.21.5.tgz", - "integrity": "sha512-c0uX9VAUBQ7dTDCjq+wdyGLowMdtR/GoC2U5IYk/7D1H1JYC0qseD7+11iMP2mRLN9RcCMRcjC4YMclCzGwS/A==", - "cpu": [ - "arm64" - ], - "dev": true, + "node_modules/vscode-jsonrpc": { + "version": "8.2.0", + "resolved": "https://registry.npmjs.org/vscode-jsonrpc/-/vscode-jsonrpc-8.2.0.tgz", + "integrity": "sha512-C+r0eKJUIfiDIfwJhria30+TYWPtuHJXHtI7J0YlOmKAo7ogxP20T0zxB7HZQIFhIyvoBPwWskjxrvAtfjyZfA==", "license": "MIT", - "optional": true, - "os": [ - "android" - ], "engines": { - "node": ">=12" + "node": ">=14.0.0" } }, - "node_modules/vite/node_modules/@esbuild/android-x64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.21.5.tgz", - "integrity": "sha512-D7aPRUUNHRBwHxzxRvp856rjUHRFW1SdQATKXH2hqA0kAZb1hKmi02OpYRacl0TxIGz/ZmXWlbZgjwWYaCakTA==", - "cpu": [ - "x64" - ], - "dev": true, + "node_modules/vscode-languageserver": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/vscode-languageserver/-/vscode-languageserver-9.0.1.tgz", + "integrity": "sha512-woByF3PDpkHFUreUa7Hos7+pUWdeWMXRd26+ZX2A8cFx6v/JPTtd4/uN0/jB6XQHYaOlHbio03NTHCqrgG5n7g==", "license": "MIT", - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=12" + "dependencies": { + "vscode-languageserver-protocol": "3.17.5" + }, + "bin": { + "installServerIntoExtension": "bin/installServerIntoExtension" } }, - "node_modules/vite/node_modules/@esbuild/darwin-arm64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.21.5.tgz", - "integrity": "sha512-DwqXqZyuk5AiWWf3UfLiRDJ5EDd49zg6O9wclZ7kUMv2WRFr4HKjXp/5t8JZ11QbQfUS6/cRCKGwYhtNAY88kQ==", - "cpu": [ - "arm64" - ], - "dev": true, + "node_modules/vscode-languageserver-protocol": { + "version": "3.17.5", + "resolved": "https://registry.npmjs.org/vscode-languageserver-protocol/-/vscode-languageserver-protocol-3.17.5.tgz", + "integrity": "sha512-mb1bvRJN8SVznADSGWM9u/b07H7Ecg0I3OgXDuLdn307rl/J3A9YD6/eYOssqhecL27hK1IPZAsaqh00i/Jljg==", "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">=12" + "dependencies": { + "vscode-jsonrpc": "8.2.0", + "vscode-languageserver-types": "3.17.5" } }, - "node_modules/vite/node_modules/@esbuild/darwin-x64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.21.5.tgz", - "integrity": "sha512-se/JjF8NlmKVG4kNIuyWMV/22ZaerB+qaSi5MdrXtd6R08kvs2qCN4C09miupktDitvh8jRFflwGFBQcxZRjbw==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/vite/node_modules/@esbuild/freebsd-arm64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.21.5.tgz", - "integrity": "sha512-5JcRxxRDUJLX8JXp/wcBCy3pENnCgBR9bN6JsY4OmhfUtIHe3ZW0mawA7+RDAcMLrMIZaf03NlQiX9DGyB8h4g==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "freebsd" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/vite/node_modules/@esbuild/freebsd-x64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.21.5.tgz", - "integrity": "sha512-J95kNBj1zkbMXtHVH29bBriQygMXqoVQOQYA+ISs0/2l3T9/kj42ow2mpqerRBxDJnmkUDCaQT/dfNXWX/ZZCQ==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "freebsd" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/vite/node_modules/@esbuild/linux-arm": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.21.5.tgz", - "integrity": "sha512-bPb5AHZtbeNGjCKVZ9UGqGwo8EUu4cLq68E95A53KlxAPRmUyYv2D6F0uUI65XisGOL1hBP5mTronbgo+0bFcA==", - "cpu": [ - "arm" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/vite/node_modules/@esbuild/linux-arm64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.21.5.tgz", - "integrity": "sha512-ibKvmyYzKsBeX8d8I7MH/TMfWDXBF3db4qM6sy+7re0YXya+K1cem3on9XgdT2EQGMu4hQyZhan7TeQ8XkGp4Q==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/vite/node_modules/@esbuild/linux-ia32": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.21.5.tgz", - "integrity": "sha512-YvjXDqLRqPDl2dvRODYmmhz4rPeVKYvppfGYKSNGdyZkA01046pLWyRKKI3ax8fbJoK5QbxblURkwK/MWY18Tg==", - "cpu": [ - "ia32" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/vite/node_modules/@esbuild/linux-loong64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.21.5.tgz", - "integrity": "sha512-uHf1BmMG8qEvzdrzAqg2SIG/02+4/DHB6a9Kbya0XDvwDEKCoC8ZRWI5JJvNdUjtciBGFQ5PuBlpEOXQj+JQSg==", - "cpu": [ - "loong64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/vite/node_modules/@esbuild/linux-mips64el": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.21.5.tgz", - "integrity": "sha512-IajOmO+KJK23bj52dFSNCMsz1QP1DqM6cwLUv3W1QwyxkyIWecfafnI555fvSGqEKwjMXVLokcV5ygHW5b3Jbg==", - "cpu": [ - "mips64el" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/vite/node_modules/@esbuild/linux-ppc64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.21.5.tgz", - "integrity": "sha512-1hHV/Z4OEfMwpLO8rp7CvlhBDnjsC3CttJXIhBi+5Aj5r+MBvy4egg7wCbe//hSsT+RvDAG7s81tAvpL2XAE4w==", - "cpu": [ - "ppc64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/vite/node_modules/@esbuild/linux-riscv64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.21.5.tgz", - "integrity": "sha512-2HdXDMd9GMgTGrPWnJzP2ALSokE/0O5HhTUvWIbD3YdjME8JwvSCnNGBnTThKGEB91OZhzrJ4qIIxk/SBmyDDA==", - "cpu": [ - "riscv64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/vite/node_modules/@esbuild/linux-s390x": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.21.5.tgz", - "integrity": "sha512-zus5sxzqBJD3eXxwvjN1yQkRepANgxE9lgOW2qLnmr8ikMTphkjgXu1HR01K4FJg8h1kEEDAqDcZQtbrRnB41A==", - "cpu": [ - "s390x" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/vite/node_modules/@esbuild/linux-x64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.21.5.tgz", - "integrity": "sha512-1rYdTpyv03iycF1+BhzrzQJCdOuAOtaqHTWJZCWvijKD2N5Xu0TtVC8/+1faWqcP9iBCWOmjmhoH94dH82BxPQ==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/vite/node_modules/@esbuild/netbsd-x64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.21.5.tgz", - "integrity": "sha512-Woi2MXzXjMULccIwMnLciyZH4nCIMpWQAs049KEeMvOcNADVxo0UBIQPfSmxB3CWKedngg7sWZdLvLczpe0tLg==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "netbsd" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/vite/node_modules/@esbuild/openbsd-x64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.21.5.tgz", - "integrity": "sha512-HLNNw99xsvx12lFBUwoT8EVCsSvRNDVxNpjZ7bPn947b8gJPzeHWyNVhFsaerc0n3TsbOINvRP2byTZ5LKezow==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "openbsd" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/vite/node_modules/@esbuild/sunos-x64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.21.5.tgz", - "integrity": "sha512-6+gjmFpfy0BHU5Tpptkuh8+uw3mnrvgs+dSPQXQOv3ekbordwnzTVEb4qnIvQcYXq6gzkyTnoZ9dZG+D4garKg==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "sunos" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/vite/node_modules/@esbuild/win32-arm64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.21.5.tgz", - "integrity": "sha512-Z0gOTd75VvXqyq7nsl93zwahcTROgqvuAcYDUr+vOv8uHhNSKROyU961kgtCD1e95IqPKSQKH7tBTslnS3tA8A==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/vite/node_modules/@esbuild/win32-ia32": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.21.5.tgz", - "integrity": "sha512-SWXFF1CL2RVNMaVs+BBClwtfZSvDgtL//G/smwAc5oVK/UPu2Gu9tIaRgFmYFFKrmg3SyAjSrElf0TiJ1v8fYA==", - "cpu": [ - "ia32" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/vite/node_modules/@esbuild/win32-x64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.21.5.tgz", - "integrity": "sha512-tQd/1efJuzPC6rCFwEvLtci/xNFcTZknmXs98FYDfGE4wP9ClFV98nyKrzJKVPMhdDnjzLhdUyMX4PsQAPjwIw==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/vite/node_modules/esbuild": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.21.5.tgz", - "integrity": "sha512-mg3OPMV4hXywwpoDxu3Qda5xCKQi+vCTZq8S9J/EpkhB2HzKXq4SNFZE3+NK93JYxc8VMSep+lOUSC/RVKaBqw==", - "dev": true, - "hasInstallScript": true, - "license": "MIT", - "bin": { - "esbuild": "bin/esbuild" - }, - "engines": { - "node": ">=12" - }, - "optionalDependencies": { - "@esbuild/aix-ppc64": "0.21.5", - "@esbuild/android-arm": "0.21.5", - "@esbuild/android-arm64": "0.21.5", - "@esbuild/android-x64": "0.21.5", - "@esbuild/darwin-arm64": "0.21.5", - "@esbuild/darwin-x64": "0.21.5", - "@esbuild/freebsd-arm64": "0.21.5", - "@esbuild/freebsd-x64": "0.21.5", - "@esbuild/linux-arm": "0.21.5", - "@esbuild/linux-arm64": "0.21.5", - "@esbuild/linux-ia32": "0.21.5", - "@esbuild/linux-loong64": "0.21.5", - "@esbuild/linux-mips64el": "0.21.5", - "@esbuild/linux-ppc64": "0.21.5", - "@esbuild/linux-riscv64": "0.21.5", - "@esbuild/linux-s390x": "0.21.5", - "@esbuild/linux-x64": "0.21.5", - "@esbuild/netbsd-x64": "0.21.5", - "@esbuild/openbsd-x64": "0.21.5", - "@esbuild/sunos-x64": "0.21.5", - "@esbuild/win32-arm64": "0.21.5", - "@esbuild/win32-ia32": "0.21.5", - "@esbuild/win32-x64": "0.21.5" - } + "node_modules/vscode-languageserver-textdocument": { + "version": "1.0.12", + "resolved": "https://registry.npmjs.org/vscode-languageserver-textdocument/-/vscode-languageserver-textdocument-1.0.12.tgz", + "integrity": "sha512-cxWNPesCnQCcMPeenjKKsOCKQZ/L6Tv19DTRIGuLWe32lyzWhihGVJ/rcckZXJxfdKCFvRLS3fpBIsV/ZGX4zA==", + "license": "MIT" }, - "node_modules/vitest": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/vitest/-/vitest-2.1.2.tgz", - "integrity": "sha512-veNjLizOMkRrJ6xxb+pvxN6/QAWg95mzcRjtmkepXdN87FNfxAss9RKe2far/G9cQpipfgP2taqg0KiWsquj8A==", - "dev": true, - "license": "MIT", - "dependencies": { - "@vitest/expect": "2.1.2", - "@vitest/mocker": "2.1.2", - "@vitest/pretty-format": "^2.1.2", - "@vitest/runner": "2.1.2", - "@vitest/snapshot": "2.1.2", - "@vitest/spy": "2.1.2", - "@vitest/utils": "2.1.2", - "chai": "^5.1.1", - "debug": "^4.3.6", - "magic-string": "^0.30.11", - "pathe": "^1.1.2", - "std-env": "^3.7.0", - "tinybench": "^2.9.0", - "tinyexec": "^0.3.0", - "tinypool": "^1.0.0", - "tinyrainbow": "^1.2.0", - "vite": "^5.0.0", - "vite-node": "2.1.2", - "why-is-node-running": "^2.3.0" - }, - "bin": { - "vitest": "vitest.mjs" - }, - "engines": { - "node": "^18.0.0 || >=20.0.0" - }, - "funding": { - "url": "https://opencollective.com/vitest" - }, - "peerDependencies": { - "@edge-runtime/vm": "*", - "@types/node": "^18.0.0 || >=20.0.0", - "@vitest/browser": "2.1.2", - "@vitest/ui": "2.1.2", - "happy-dom": "*", - "jsdom": "*" - }, - "peerDependenciesMeta": { - "@edge-runtime/vm": { - "optional": true - }, - "@types/node": { - "optional": true - }, - "@vitest/browser": { - "optional": true - }, - "@vitest/ui": { - "optional": true - }, - "happy-dom": { - "optional": true - }, - "jsdom": { - "optional": true - } - } + "node_modules/vscode-languageserver-types": { + "version": "3.17.5", + "resolved": "https://registry.npmjs.org/vscode-languageserver-types/-/vscode-languageserver-types-3.17.5.tgz", + "integrity": "sha512-Ld1VelNuX9pdF39h2Hgaeb5hEZM2Z3jUrrMgWQAu82jMtZp7p3vJT3BzToKtZI7NgQssZje5o0zryOrhQvzQAg==", + "license": "MIT" }, - "node_modules/vlq": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/vlq/-/vlq-2.0.4.tgz", - "integrity": "sha512-aodjPa2wPQFkra1G8CzJBTHXhgk3EVSwxSWXNPr1fgdFLUb8kvLV1iEb6rFgasIsjP82HWI6dsb5Io26DDnasA==", - "dev": true, - "license": "MIT", - "peer": true + "node_modules/vscode-uri": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/vscode-uri/-/vscode-uri-3.1.0.tgz", + "integrity": "sha512-/BpdSx+yCQGnCvecbyXdxHDkuk55/G3xwnC0GqY4gmQ3j+A+g8kzzgB4Nk/SINjqn6+waqw3EgbVF2QKExkRxQ==", + "license": "MIT" }, "node_modules/which": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", - "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/which/-/which-5.0.0.tgz", + "integrity": "sha512-JEdGzHwwkrbWoGOlIHqQ5gtprKGOenpDHpxE9zVR1bWbOtYRyPPHMe9FaP6x61CmNaTThSkb0DAJte5jD+DmzQ==", "license": "ISC", "dependencies": { - "isexe": "^2.0.0" + "isexe": "^3.1.1" }, "bin": { - "node-which": "bin/node-which" + "node-which": "bin/which.js" }, "engines": { - "node": ">= 8" + "node": "^18.17.0 || >=20.5.0" } }, "node_modules/which-boxed-primitive": { @@ -14060,6 +13846,13 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/which-builtin-type/node_modules/isarray": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz", + "integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==", + "dev": true, + "license": "MIT" + }, "node_modules/which-collection": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/which-collection/-/which-collection-1.0.2.tgz", @@ -14080,16 +13873,17 @@ } }, "node_modules/which-typed-array": { - "version": "1.1.18", - "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.18.tgz", - "integrity": "sha512-qEcY+KJYlWyLH9vNbsr6/5j59AXk5ni5aakf8ldzBvGde6Iz4sxZGkJyWSAueTG7QhOvNRYb1lDdFmL5Td0QKA==", + "version": "1.1.19", + "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.19.tgz", + "integrity": "sha512-rEvr90Bck4WZt9HHFC4DJMsjvu7x+r6bImz0/BrbWb7A2djJ8hnZMrWnHo9F8ssv0OMErasDhftrfROTyqSDrw==", "dev": true, "license": "MIT", "dependencies": { "available-typed-arrays": "^1.0.7", "call-bind": "^1.0.8", - "call-bound": "^1.0.3", - "for-each": "^0.3.3", + "call-bound": "^1.0.4", + "for-each": "^0.3.5", + "get-proto": "^1.0.1", "gopd": "^1.2.0", "has-tostringtag": "^1.0.2" }, @@ -14283,9 +14077,9 @@ } }, "node_modules/yaml": { - "version": "2.6.1", - "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.6.1.tgz", - "integrity": "sha512-7r0XPzioN/Q9kXBro/XPnA6kznR73DHq+GXh5ON7ZozRO6aMjbmiBuKste2wslTFkC5d1dw0GooOCepZXJ2SAg==", + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.7.0.tgz", + "integrity": "sha512-+hSoy/QHluxmC9kCIJyL/uyFmLmc+e5CFR5Wa+bpIhIj85LVb9ZH2nVnqrHoSvKogwODv0ClqZkmiSSaIH5LTA==", "dev": true, "license": "ISC", "bin": { @@ -14370,9 +14164,9 @@ } }, "node_modules/yocto-queue": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-1.1.1.tgz", - "integrity": "sha512-b4JR1PFR10y1mKjhHY9LaGo6tmrgjit7hxVIeAmyMw3jegXR4dhYqLaQF5zMXZxY7tLpMyJeLjr1C4rLmkVe8g==", + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-1.2.0.tgz", + "integrity": "sha512-KHBC7z61OJeaMGnF3wqNZj+GGNXOyypZviiKpQeiHirG5Ib1ImwcLBH70rbMSkKfSmUNBsdf2PwaEJtKvgmkNw==", "dev": true, "license": "MIT", "engines": { @@ -14396,9 +14190,9 @@ } }, "node_modules/zod": { - "version": "3.24.1", - "resolved": "https://registry.npmjs.org/zod/-/zod-3.24.1.tgz", - "integrity": "sha512-muH7gBL9sI1nciMZV67X5fTKKBLtwpZ5VBp1vsOQzj1MhrBZ4wlVCm3gedKZWLp0Oyel8sIGfeiz54Su+OVT+A==", + "version": "3.24.2", + "resolved": "https://registry.npmjs.org/zod/-/zod-3.24.2.tgz", + "integrity": "sha512-lY7CDW43ECgW9u1TcT3IoXHflywfVqDYze4waEz812jR/bZ8FHDsl7pFQoSZTz5N+2NqRXs8GBwnAwo3ZNxqhQ==", "license": "MIT", "funding": { "url": "https://github.com/sponsors/colinhacks" diff --git a/package.json b/package.json index c3001e9..e780f61 100644 --- a/package.json +++ b/package.json @@ -6,7 +6,6 @@ "main": "index.js", "types": "src/index.ts", "scripts": { - "postinstall": "patch-package", "audit": "better-npm-audit audit", "format": "prettier --write .", "lint": "eslint \"src/**/*.ts\" \"tests/**/*.ts\" \"examples/**/*.ts\"", @@ -22,49 +21,53 @@ "test": "vitest run", "test:coverage": "vitest run --coverage", "test:ci": "vitest run --coverage --reporter junit --outputFile test-results.xml", - "build-examples": "rollup --config examples/rollup.config.ts --configPlugin typescript" + "script:documentation": "typedoc", + "script:build-examples": "rollup --config examples/rollup.config.ts --configPlugin typescript", + "script:compile-examples": "puya-ts build --out-dir data ./examples/*/", + "script:refresh-test-artifacts": "puya-ts build --out-dir data ./tests/artifacts/*/" }, "devDependencies": { - "@algorandfoundation/algokit-utils": "^8.0.3", - "@commitlint/cli": "^19.5.0", - "@commitlint/config-conventional": "^19.5.0", - "@eslint/eslintrc": "3.1.0", - "@eslint/js": "9.12.0", + "@algorandfoundation/algokit-utils": "^8.2.2", + "@commitlint/cli": "^19.8.0", + "@commitlint/config-conventional": "^19.8.0", + "@eslint/eslintrc": "3.3.0", + "@eslint/js": "9.22.0", "@makerx/eslint-config": "4.0.0", "@makerx/prettier-config": "2.0.1", "@makerx/ts-toolkit": "4.0.0-beta.21", - "@rollup/plugin-commonjs": "28.0.0", + "@rollup/plugin-commonjs": "28.0.3", "@rollup/plugin-json": "6.1.0", - "@rollup/plugin-node-resolve": "15.3.0", - "@rollup/plugin-typescript": "^12.1.0", + "@rollup/plugin-node-resolve": "16.0.0", + "@rollup/plugin-typescript": "^12.1.2", "@tsconfig/node20": "20.1.4", "@types/elliptic": "^6.4.18", - "@types/node": "22.7.5", - "@typescript-eslint/eslint-plugin": "8.8.1", - "@typescript-eslint/parser": "8.8.1", - "@vitest/coverage-v8": "2.1.2", + "@types/node": "22.13.10", + "@typescript-eslint/eslint-plugin": "8.26.1", + "@typescript-eslint/parser": "8.26.1", + "@vitest/coverage-v8": "3.0.8", "better-npm-audit": "3.11.0", "conventional-changelog-conventionalcommits": "^8.0.0", "copyfiles": "2.4.1", - "eslint": "9.12.0", - "eslint-config-prettier": "^9.1.0", - "eslint-plugin-prettier": "^5.2.1", + "eslint": "9.22.0", + "eslint-config-prettier": "^10.1.1", + "eslint-plugin-prettier": "^5.2.3", + "glob": "^11.0.0", "npm-run-all": "4.1.5", - "patch-package": "^8.0.0", - "prettier": "3.3.3", + "polytype": "^0.17.0", + "prettier": "3.5.3", "rimraf": "6.0.1", - "rollup": "^4.24.0", - "semantic-release": "^24.1.2", - "tsx": "4.19.1", - "typescript": "^5.7.2", - "vitest": "2.1.2" - }, - "peerDependencies": { - "tslib": "^2.6.2" + "rollup": "^4.34.9", + "semantic-release": "^24.2.3", + "tsx": "4.19.3", + "typedoc": "^0.27.9", + "typedoc-plugin-markdown": "^4.4.2", + "typescript": "^5.8.2", + "upath": "^2.0.1", + "vitest": "3.0.8" }, "dependencies": { - "@algorandfoundation/algorand-typescript": "^0.0.1-alpha.24", - "@algorandfoundation/puya-ts": "^1.0.0-alpha.36", + "@algorandfoundation/algorand-typescript": "^1.0.0-beta.25", + "@algorandfoundation/puya-ts": "^1.0.0-beta.46", "elliptic": "^6.5.7", "js-sha256": "^0.11.0", "js-sha3": "^0.9.3", @@ -73,6 +76,7 @@ }, "overrides": { "cross-spawn": "7.0.6", - "npm": "10.9.1" + "npm": "10.9.1", + "esbuild": "0.25.0" } } diff --git a/patches/typescript+5.7.2.patch b/patches/typescript+5.7.2.patch deleted file mode 100644 index f28cd8b..0000000 --- a/patches/typescript+5.7.2.patch +++ /dev/null @@ -1,34 +0,0 @@ -diff --git a/node_modules/typescript/lib/typescript.d.ts b/node_modules/typescript/lib/typescript.d.ts -index 6780dd1..8700e72 100644 ---- a/node_modules/typescript/lib/typescript.d.ts -+++ b/node_modules/typescript/lib/typescript.d.ts -@@ -6159,6 +6159,7 @@ declare namespace ts { - getIndexInfoOfType(type: Type, kind: IndexKind): IndexInfo | undefined; - getIndexInfosOfType(type: Type): readonly IndexInfo[]; - getIndexInfosOfIndexSymbol: (indexSymbol: Symbol, siblingSymbols?: Symbol[] | undefined) => IndexInfo[]; -+ getTypeArgumentsForResolvedSignature(signature: Signature): readonly Type[] | undefined; - getSignaturesOfType(type: Type, kind: SignatureKind): readonly Signature[]; - getIndexTypeOfType(type: Type, kind: IndexKind): Type | undefined; - getBaseTypes(type: InterfaceType): BaseType[]; -diff --git a/node_modules/typescript/lib/typescript.js b/node_modules/typescript/lib/typescript.js -index 33387ea..a1f35b3 100644 ---- a/node_modules/typescript/lib/typescript.js -+++ b/node_modules/typescript/lib/typescript.js -@@ -50655,6 +50655,7 @@ function createTypeChecker(host) { - getGlobalDiagnostics, - getRecursionIdentity, - getUnmatchedProperties, -+ getTypeArgumentsForResolvedSignature, - getTypeOfSymbolAtLocation: (symbol, locationIn) => { - const location = getParseTreeNode(locationIn); - return location ? getTypeOfSymbolAtLocation(symbol, location) : errorType; -@@ -71776,6 +71777,9 @@ function createTypeChecker(host) { - } - } - } -+ function getTypeArgumentsForResolvedSignature(signature) { -+ return signature.mapper && instantiateTypes((signature.target ?? signature).typeParameters ?? [], signature.mapper); -+ } - function getUnmatchedProperty(source, target, requireOptionalProperties, matchDiscriminantProperties) { - return firstOrUndefinedIterator(getUnmatchedProperties(source, target, requireOptionalProperties, matchDiscriminantProperties)); - } diff --git a/readme.md b/readme.md deleted file mode 100644 index a18c1c1..0000000 --- a/readme.md +++ /dev/null @@ -1,8 +0,0 @@ -# @algorandfoundation/algorand-typescript-testing - -A library which allows you to execute Algorand TypeScript code locally under a test context either emulating or mocking AVM behaviour. - -## Getting started - -Install package -`npm i -D @algorandfoundation/algorand-typescript-testing` \ No newline at end of file diff --git a/rollup.config.ts b/rollup.config.ts index 22bda1b..7117aad 100644 --- a/rollup.config.ts +++ b/rollup.config.ts @@ -8,7 +8,11 @@ const config: RollupOptions = { input: { index: 'src/index.ts', 'runtime-helpers': 'src/runtime-helpers.ts', - 'test-transformer/index': 'src/test-transformer/index.ts', + 'internal/index': 'src/internal/index.ts', + 'internal/arc4': 'src/internal/arc4.ts', + 'internal/op': 'src/internal/op.ts', + 'test-transformer/vitest-transformer': 'src/test-transformer/vitest-transformer.ts', + 'test-transformer/jest-transformer': 'src/test-transformer/jest-transformer.ts', }, output: [ { diff --git a/src/abi-metadata.ts b/src/abi-metadata.ts index f31554f..28800e6 100644 --- a/src/abi-metadata.ts +++ b/src/abi-metadata.ts @@ -1,70 +1,63 @@ -import { BaseContract, Contract } from '@algorandfoundation/algorand-typescript' -import { AbiMethodConfig, BareMethodConfig, CreateOptions, OnCompleteActionStr } from '@algorandfoundation/algorand-typescript/arc4' -import { sha512_256 as js_sha512_256 } from 'js-sha512' -import { TypeInfo } from './encoders' +import type { OnCompleteActionStr } from '@algorandfoundation/algorand-typescript' +import type { CreateOptions } from '@algorandfoundation/algorand-typescript/arc4' +import js_sha512 from 'js-sha512' +import type { TypeInfo } from './encoders' +import { Arc4MethodConfigSymbol, Contract } from './impl/contract' import { getArc4TypeName as getArc4TypeNameForARC4Encoded } from './impl/encoded-types' -import { DeliberateAny } from './typescript-helpers' +import type { DeliberateAny } from './typescript-helpers' export interface AbiMetadata { methodName: string + name?: string methodSignature: string | undefined argTypes: string[] returnType: string onCreate?: CreateOptions allowActions?: OnCompleteActionStr[] } -const AbiMetaSymbol = Symbol('AbiMetadata') -export const isContractProxy = Symbol('isContractProxy') + +const metadataStore: WeakMap<{ new (): Contract }, Record> = new WeakMap() export const attachAbiMetadata = (contract: { new (): Contract }, methodName: string, metadata: AbiMetadata): void => { - const metadatas: Record = (AbiMetaSymbol in contract ? contract[AbiMetaSymbol] : {}) as Record - metadatas[methodName] = metadata - if (!(AbiMetaSymbol in contract)) { - Object.defineProperty(contract, AbiMetaSymbol, { - value: metadatas, - writable: true, - enumerable: false, - }) + if (!metadataStore.has(contract)) { + metadataStore.set(contract, {}) } + const metadatas: Record = metadataStore.get(contract) as Record + metadatas[methodName] = metadata } -export const copyAbiMetadatas = (sourceContract: T, targetContract: T): void => { - const metadatas = getContractAbiMetadata(sourceContract) - Object.defineProperty(targetContract, AbiMetaSymbol, { - value: metadatas, - writable: true, - enumerable: false, - }) -} +export const getContractAbiMetadata = (contract: T | { new (): T }): Record => { + // Initialize result object to store merged metadata + const result: Record = {} -export const captureMethodConfig = ( - contract: T, - methodName: string, - config?: AbiMethodConfig | BareMethodConfig, -): void => { - const metadata = getContractMethodAbiMetadata(contract, methodName) - metadata.onCreate = config?.onCreate ?? 'disallow' - metadata.allowActions = ([] as OnCompleteActionStr[]).concat(config?.allowActions ?? 'NoOp') -} + // Get the contract's class + let currentClass = contract instanceof Contract ? (contract.constructor as { new (): T }) : contract -export const hasAbiMetadata = (contract: T): boolean => { - const contractClass = contract.constructor as { new (): T } - return ( - Object.getOwnPropertySymbols(contractClass).some((s) => s.toString() === AbiMetaSymbol.toString()) || AbiMetaSymbol in contractClass - ) -} -export const getContractAbiMetadata = (contract: T): Record => { - if ((contract as DeliberateAny)[isContractProxy]) { - return (contract as DeliberateAny)[AbiMetaSymbol] as Record + // Walk up the prototype chain + while (currentClass && currentClass.prototype) { + // Find metadata for current class + const currentMetadata = metadataStore.get(currentClass) + + if (currentMetadata) { + // Merge metadata with existing result (don't override existing entries) + const classMetadata = currentMetadata + for (const [methodName, metadata] of Object.entries(classMetadata)) { + if (!(methodName in result)) { + result[methodName] = { + ...metadata, + ...(currentClass.prototype as DeliberateAny)?.[methodName]?.[Arc4MethodConfigSymbol], + } + } + } + } + + // Move up the prototype chain + currentClass = Object.getPrototypeOf(currentClass) } - const contractClass = contract.constructor as { new (): T } - const s = Object.getOwnPropertySymbols(contractClass).find((s) => s.toString() === AbiMetaSymbol.toString()) - const metadatas: Record = ( - s ? (contractClass as DeliberateAny)[s] : AbiMetaSymbol in contractClass ? contractClass[AbiMetaSymbol] : {} - ) as Record - return metadatas + + return result } -export const getContractMethodAbiMetadata = (contract: T, methodName: string): AbiMetadata => { +export const getContractMethodAbiMetadata = (contract: T, methodName: string): AbiMetadata => { const metadatas = getContractAbiMetadata(contract) return metadatas[methodName] } @@ -73,13 +66,13 @@ export const getArc4Signature = (metadata: AbiMetadata): string => { if (metadata.methodSignature === undefined) { const argTypes = metadata.argTypes.map((t) => JSON.parse(t) as TypeInfo).map(getArc4TypeName) const returnType = getArc4TypeName(JSON.parse(metadata.returnType) as TypeInfo) - metadata.methodSignature = `${metadata.methodName}(${argTypes.join(',')})${returnType}` + metadata.methodSignature = `${metadata.name ?? metadata.methodName}(${argTypes.join(',')})${returnType}` } return metadata.methodSignature } export const getArc4Selector = (metadata: AbiMetadata): Uint8Array => { - const hash = js_sha512_256.array(getArc4Signature(metadata)) + const hash = js_sha512.sha512_256.array(getArc4Signature(metadata)) return new Uint8Array(hash.slice(0, 4)) } diff --git a/src/collections/custom-key-map.ts b/src/collections/custom-key-map.ts index fe6043f..cd09fe9 100644 --- a/src/collections/custom-key-map.ts +++ b/src/collections/custom-key-map.ts @@ -1,5 +1,7 @@ -import { Account, internal } from '@algorandfoundation/algorand-typescript' -import { DeliberateAny } from '../typescript-helpers' +import type { Account } from '@algorandfoundation/algorand-typescript' +import { InternalError } from '../errors' +import type { StubBytesCompat, StubUint64Compat } from '../impl/primitives' +import type { DeliberateAny } from '../typescript-helpers' import { asBytesCls, asUint64Cls } from '../util' type Primitive = number | bigint | string | boolean @@ -28,7 +30,7 @@ export abstract class CustomKeyMap implements Map { getOrFail(key: TKey): TValue { const value = this.get(key) if (value === undefined) { - throw internal.errors.internalError('Key not found') + throw new InternalError('Key not found') } return value } @@ -73,13 +75,13 @@ export class AccountMap extends CustomKeyMap { } } -export class BytesMap extends CustomKeyMap { +export class BytesMap extends CustomKeyMap { constructor() { super((bytes) => asBytesCls(bytes).valueOf()) } } -export class Uint64Map extends CustomKeyMap { +export class Uint64Map extends CustomKeyMap { constructor() { super((uint64) => asUint64Cls(uint64).valueOf()) } diff --git a/src/constants.ts b/src/constants.ts index 20e9908..ddaa174 100644 --- a/src/constants.ts +++ b/src/constants.ts @@ -1,4 +1,4 @@ -import { Bytes } from '@algorandfoundation/algorand-typescript' +import { Bytes } from './impl/primitives' export const UINT64_SIZE = 64 export const UINT512_SIZE = 512 diff --git a/src/context-helpers/context-manager.ts b/src/context-helpers/context-manager.ts new file mode 100644 index 0000000..daa02de --- /dev/null +++ b/src/context-helpers/context-manager.ts @@ -0,0 +1,17 @@ +import type { TestExecutionContext } from '../test-execution-context' + +export class ContextManager { + private static _instance: TestExecutionContext | undefined + + static set instance(ctx: TestExecutionContext) { + if (this._instance !== undefined) throw new Error('Execution context has already been set') + this._instance = ctx + } + static get instance() { + if (this._instance === undefined) throw new Error('No execution context has been set') + return this._instance + } + static reset() { + this._instance = undefined + } +} diff --git a/src/context-helpers/context-util.ts b/src/context-helpers/context-util.ts index 7cfb006..9cdac4c 100644 --- a/src/context-helpers/context-util.ts +++ b/src/context-helpers/context-util.ts @@ -1,5 +1,6 @@ -import { internal, uint64 } from '@algorandfoundation/algorand-typescript' -import { AbiMetadata } from '../abi-metadata' +import type { uint64 } from '@algorandfoundation/algorand-typescript' +import type { AbiMetadata } from '../abi-metadata' +import { AssertError } from '../errors' import { ApplicationTransaction } from '../impl/transactions' import { lazyContext } from './internal-context' @@ -7,15 +8,13 @@ export const checkRoutingConditions = (appId: uint64, metadata: AbiMetadata) => const appData = lazyContext.getApplicationData(appId) const isCreating = appData.isCreating if (isCreating && metadata.onCreate === 'disallow') { - throw new internal.errors.CodeError('method can not be called while creating') + throw new AssertError('method can not be called while creating') } if (!isCreating && metadata.onCreate === 'require') { - throw new internal.errors.CodeError('method can only be called while creating') + throw new AssertError('method can only be called while creating') } const txn = lazyContext.activeGroup.activeTransaction if (txn instanceof ApplicationTransaction && metadata.allowActions && !metadata.allowActions.includes(txn.onCompletion)) { - throw new internal.errors.CodeError( - `method can only be called with one of the following on_completion values: ${metadata.allowActions.join(', ')}`, - ) + throw new AssertError(`method can only be called with one of the following on_completion values: ${metadata.allowActions.join(', ')}`) } } diff --git a/src/context-helpers/internal-context.ts b/src/context-helpers/internal-context.ts index e7b6e1d..b3df401 100644 --- a/src/context-helpers/internal-context.ts +++ b/src/context-helpers/internal-context.ts @@ -1,9 +1,13 @@ -import { Account, BaseContract, internal } from '@algorandfoundation/algorand-typescript' -import { AccountData } from '../impl/account' -import { ApplicationData } from '../impl/application' -import { AssetData } from '../impl/asset' -import { TransactionGroup } from '../subcontexts/transaction-context' -import { TestExecutionContext } from '../test-execution-context' +import type { Account } from '@algorandfoundation/algorand-typescript' +import { InternalError } from '../errors' +import { BaseContract } from '../impl/base-contract' +import type { StubUint64Compat } from '../impl/primitives' +import { Uint64Cls } from '../impl/primitives' +import type { AccountData, ApplicationData, AssetData } from '../impl/reference' +import type { VoterData } from '../impl/voter-params' +import type { TransactionGroup } from '../subcontexts/transaction-context' +import type { TestExecutionContext } from '../test-execution-context' +import { ContextManager } from './context-manager' /** * For accessing implementation specific functions, with a convenient single entry @@ -12,7 +16,7 @@ import { TestExecutionContext } from '../test-execution-context' */ class InternalContext { get value() { - return internal.ctxMgr.instance as TestExecutionContext + return ContextManager.instance as TestExecutionContext } get defaultSender() { @@ -46,26 +50,33 @@ class InternalContext { getAccountData(account: Account): AccountData { const data = this.ledger.accountDataMap.get(account) if (!data) { - throw internal.errors.internalError('Unknown account, check correct testing context is active') + throw new InternalError('Unknown account, check correct testing context is active') } return data } - getAssetData(id: internal.primitives.StubUint64Compat): AssetData { - const key = internal.primitives.Uint64Cls.fromCompat(id) + getAssetData(id: StubUint64Compat): AssetData { + const key = Uint64Cls.fromCompat(id) const data = this.ledger.assetDataMap.get(key.asBigInt()) if (!data) { - throw internal.errors.internalError('Unknown asset, check correct testing context is active') + throw new InternalError('Unknown asset, check correct testing context is active') } return data } - getApplicationData(id: internal.primitives.StubUint64Compat | BaseContract): ApplicationData { - const uint64Id = - id instanceof BaseContract ? this.ledger.getApplicationForContract(id).id : internal.primitives.Uint64Cls.fromCompat(id) + getApplicationData(id: StubUint64Compat | BaseContract): ApplicationData { + const uint64Id = id instanceof BaseContract ? this.ledger.getApplicationForContract(id).id : Uint64Cls.fromCompat(id) const data = this.ledger.applicationDataMap.get(uint64Id) if (!data) { - throw internal.errors.internalError('Unknown application, check correct testing context is active') + throw new InternalError('Unknown application, check correct testing context is active') + } + return data + } + + getVoterData(account: Account): VoterData { + const data = this.ledger.voterDataMap.get(account) + if (!data) { + throw new InternalError('Unknown voter, check correct testing context is active') } return data } diff --git a/src/decode-logs.ts b/src/decode-logs.ts index e020a27..6bd0f9b 100644 --- a/src/decode-logs.ts +++ b/src/decode-logs.ts @@ -1,5 +1,6 @@ -import { bytes, op } from '@algorandfoundation/algorand-typescript' +import type { bytes } from '@algorandfoundation/algorand-typescript' import { ABI_RETURN_VALUE_LOG_PREFIX } from './constants' +import { btoi } from './impl/pure' import { asNumber } from './util' export type LogDecoding = 'i' | 's' | 'b' @@ -17,7 +18,7 @@ export function decodeLogs(logs: bytes[], de : log switch (decoding[i]) { case 'i': - return op.btoi(value) + return btoi(value) case 's': return value.toString() default: diff --git a/src/encoders.ts b/src/encoders.ts index 2cf964c..08e09dd 100644 --- a/src/encoders.ts +++ b/src/encoders.ts @@ -1,11 +1,12 @@ -import { biguint, BigUint, bytes, internal, TransactionType, uint64, Uint64 } from '@algorandfoundation/algorand-typescript' -import { ARC4Encoded, OnCompleteAction } from '@algorandfoundation/algorand-typescript/arc4' -import { AccountCls } from './impl/account' -import { ApplicationCls } from './impl/application' -import { AssetCls } from './impl/asset' +import type { biguint, bytes, OnCompleteAction, TransactionType, uint64 } from '@algorandfoundation/algorand-typescript' +import { ARC4Encoded } from '@algorandfoundation/algorand-typescript/arc4' +import { encodingUtil } from '@algorandfoundation/puya-ts' +import { InternalError } from './errors' import { BytesBackedCls, Uint64BackedCls } from './impl/base' import { arc4Encoders, encodeArc4Impl, getArc4Encoder } from './impl/encoded-types' -import { DeliberateAny } from './typescript-helpers' +import { BigUint, Uint64, type StubBytesCompat } from './impl/primitives' +import { AccountCls, ApplicationCls, AssetCls } from './impl/reference' +import type { DeliberateAny } from './typescript-helpers' import { asBytes, asMaybeBigUintCls, asMaybeBytesCls, asMaybeUint64Cls, asUint64Cls, asUint8Array, nameOfType } from './util' export type TypeInfo = { @@ -13,14 +14,14 @@ export type TypeInfo = { genericArgs?: TypeInfo[] | Record } -export type fromBytes = (val: Uint8Array | internal.primitives.StubBytesCompat, typeInfo: TypeInfo, prefix?: 'none' | 'log') => T +export type fromBytes = (val: Uint8Array | StubBytesCompat, typeInfo: TypeInfo, prefix?: 'none' | 'log') => T const booleanFromBytes: fromBytes = (val) => { - return internal.encodingUtil.uint8ArrayToBigInt(asUint8Array(val)) > 0n + return encodingUtil.uint8ArrayToBigInt(asUint8Array(val)) > 0n } const bigUintFromBytes: fromBytes = (val) => { - return BigUint(internal.encodingUtil.uint8ArrayToBigInt(asUint8Array(val))) + return BigUint(encodingUtil.uint8ArrayToBigInt(asUint8Array(val))) } const bytesFromBytes: fromBytes = (val) => { @@ -32,15 +33,15 @@ const stringFromBytes: fromBytes = (val) => { } const uint64FromBytes: fromBytes = (val) => { - return Uint64(internal.encodingUtil.uint8ArrayToBigInt(asUint8Array(val))) + return Uint64(encodingUtil.uint8ArrayToBigInt(asUint8Array(val))) } const onCompletionFromBytes: fromBytes = (val) => { - return Uint64(internal.encodingUtil.uint8ArrayToBigInt(asUint8Array(val))) as OnCompleteAction + return Uint64(encodingUtil.uint8ArrayToBigInt(asUint8Array(val))) as OnCompleteAction } const transactionTypeFromBytes: fromBytes = (val) => { - return Uint64(internal.encodingUtil.uint8ArrayToBigInt(asUint8Array(val))) as TransactionType + return Uint64(encodingUtil.uint8ArrayToBigInt(asUint8Array(val))) as TransactionType } export const encoders: Record> = { @@ -86,5 +87,5 @@ export const toBytes = (val: unknown): bytes => { if (Array.isArray(val) || typeof val === 'object') { return encodeArc4Impl('', val) } - internal.errors.internalError(`Invalid type for bytes: ${nameOfType(val)}`) + throw new InternalError(`Invalid type for bytes: ${nameOfType(val)}`) } diff --git a/src/errors.ts b/src/errors.ts index abb462c..afa9387 100644 --- a/src/errors.ts +++ b/src/errors.ts @@ -1,4 +1,47 @@ -import { internal } from '@algorandfoundation/algorand-typescript' +/** + * Raised when an `err` op is encountered, or when the testing VM is asked to do something that would cause + * the AVM to fail. + */ +export class AvmError extends Error { + constructor(message: string) { + super(message) + } +} +export function avmError(message: string): never { + throw new AvmError(message) +} + +export function avmInvariant(condition: unknown, message: string): asserts condition { + if (!condition) { + throw new AvmError(message) + } +} +/** + * Raised when an assertion fails + */ +export class AssertError extends AvmError { + constructor(message: string) { + super(message) + } +} + +/** + * Raised when testing code errors + */ +export class InternalError extends Error { + constructor(message: string, options?: ErrorOptions) { + super(message, options) + } +} + +/** + * Raised when unsupported user code is encountered + */ +export class CodeError extends Error { + constructor(message: string, options?: ErrorOptions) { + super(message, options) + } +} export class NotImplementedError extends Error { constructor(feature: string) { @@ -6,12 +49,8 @@ export class NotImplementedError extends Error { } } -export function notImplementedError(feature: string): never { - throw new NotImplementedError(feature) -} - export function testInvariant(condition: unknown, message: string): asserts condition { if (!condition) { - throw new internal.errors.InternalError(message) + throw new InternalError(message) } } diff --git a/src/impl/account.ts b/src/impl/account.ts deleted file mode 100644 index 614d8a8..0000000 --- a/src/impl/account.ts +++ /dev/null @@ -1,102 +0,0 @@ -import { Account, Application, Asset, bytes, internal, uint64 } from '@algorandfoundation/algorand-typescript' -import { Uint64Map } from '../collections/custom-key-map' -import { DEFAULT_ACCOUNT_MIN_BALANCE, ZERO_ADDRESS } from '../constants' -import { lazyContext } from '../context-helpers/internal-context' -import { Mutable } from '../typescript-helpers' -import { asUint64, asUint64Cls } from '../util' -import { ApplicationCls } from './application' -import { AssetCls } from './asset' -import { BytesBackedCls } from './base' - -export class AssetHolding { - balance: uint64 - frozen: boolean - constructor(balance: internal.primitives.StubUint64Compat, frozen: boolean) { - this.balance = asUint64(balance) - this.frozen = frozen - } -} - -export class AccountData { - optedAssets = new Uint64Map() - optedApplications = new Uint64Map() - account: Mutable> - - constructor() { - this.account = { - totalAppsCreated: 0, - totalAppsOptedIn: 0, - totalAssets: 0, - totalAssetsCreated: 0, - totalBoxBytes: 0, - totalBoxes: 0, - totalExtraAppPages: 0, - totalNumByteSlice: 0, - totalNumUint: 0, - minBalance: DEFAULT_ACCOUNT_MIN_BALANCE, - balance: 0, - authAddress: Account(), - } - } -} - -export class AccountCls extends BytesBackedCls implements Account { - constructor(address?: bytes) { - const addressBytes = address ?? ZERO_ADDRESS - if (![32n, 36n].includes(asUint64Cls(addressBytes.length).valueOf())) { - throw new internal.errors.AvmError('Address must be 32 bytes long, or 36 bytes including checksum') - } - super(addressBytes.slice(0, 32)) - } - - private get data(): AccountData { - return lazyContext.getAccountData(this) - } - - get balance(): uint64 { - return this.data.account.balance - } - get minBalance(): uint64 { - return this.data.account.minBalance - } - get authAddress(): Account { - return this.data.account.authAddress - } - get totalNumUint(): uint64 { - return this.data.account.totalNumUint - } - get totalNumByteSlice(): uint64 { - return this.data.account.totalNumByteSlice - } - get totalExtraAppPages(): uint64 { - return this.data.account.totalExtraAppPages - } - get totalAppsCreated(): uint64 { - return this.data.account.totalAppsCreated - } - get totalAppsOptedIn(): uint64 { - return this.data.account.totalAppsOptedIn - } - get totalAssetsCreated(): uint64 { - return this.data.account.totalAssetsCreated - } - get totalAssets(): uint64 { - return this.data.account.totalAssets - } - get totalBoxes(): uint64 { - return this.data.account.totalBoxes - } - get totalBoxBytes(): uint64 { - return this.data.account.totalBoxBytes - } - - isOptedIn(assetOrApp: Asset | Application): boolean { - if (assetOrApp instanceof AssetCls) { - return this.data.optedAssets.has(assetOrApp.id) - } - if (assetOrApp instanceof ApplicationCls) { - return this.data.optedApplications.has(asUint64Cls(assetOrApp.id).asBigInt()) - } - throw new internal.errors.InternalError('Invalid argument type. Must be an `Asset` or `Application` instance.') - } -} diff --git a/src/impl/acct-params.ts b/src/impl/acct-params.ts index 9042446..085975f 100644 --- a/src/impl/acct-params.ts +++ b/src/impl/acct-params.ts @@ -1,9 +1,11 @@ -import { Account, Application, gtxn, internal, uint64 } from '@algorandfoundation/algorand-typescript' +import type { Account, Application, gtxn, op, uint64 } from '@algorandfoundation/algorand-typescript' import { lazyContext } from '../context-helpers/internal-context' import { asMaybeUint64Cls } from '../util' import { getApp } from './app-params' +import { Global } from './global' +import type { StubUint64Compat } from './primitives' -export const getAccount = (acct: Account | internal.primitives.StubUint64Compat): Account => { +export const getAccount = (acct: Account | StubUint64Compat): Account => { const acctId = asMaybeUint64Cls(acct) if (acctId !== undefined) { const activeTxn = lazyContext.activeGroup.activeTransaction @@ -12,20 +14,17 @@ export const getAccount = (acct: Account | internal.primitives.StubUint64Compat) return acct as Account } -export const balance = (a: Account | internal.primitives.StubUint64Compat): uint64 => { +export const balance = (a: Account | StubUint64Compat): uint64 => { const acct = getAccount(a) return acct.balance } -export const minBalance = (a: Account | internal.primitives.StubUint64Compat): uint64 => { +export const minBalance = (a: Account | StubUint64Compat): uint64 => { const acct = getAccount(a) return acct.minBalance } -export const appOptedIn = ( - a: Account | internal.primitives.StubUint64Compat, - b: Application | internal.primitives.StubUint64Compat, -): boolean => { +export const appOptedIn = (a: Account | StubUint64Compat, b: Application | StubUint64Compat): boolean => { const account = getAccount(a) const app = getApp(b) @@ -35,63 +34,68 @@ export const appOptedIn = ( return account.isOptedIn(app) } -export const AcctParams: internal.opTypes.AcctParamsType = { - acctBalance(a: Account | internal.primitives.StubUint64Compat): readonly [uint64, boolean] { +export const AcctParams: typeof op.AcctParams = { + acctBalance(a: Account | StubUint64Compat): readonly [uint64, boolean] { const acct = getAccount(a) return [acct.balance, acct.balance !== 0] }, - acctMinBalance(a: Account | internal.primitives.StubUint64Compat): readonly [uint64, boolean] { + acctMinBalance(a: Account | StubUint64Compat): readonly [uint64, boolean] { const acct = getAccount(a) return [acct.minBalance, acct.balance !== 0] }, - acctAuthAddr(a: Account | internal.primitives.StubUint64Compat): readonly [Account, boolean] { + acctAuthAddr(a: Account | StubUint64Compat): readonly [Account, boolean] { const acct = getAccount(a) return [acct.authAddress, acct.balance !== 0] }, - acctTotalNumUint(a: Account | internal.primitives.StubUint64Compat): readonly [uint64, boolean] { + acctTotalNumUint(a: Account | StubUint64Compat): readonly [uint64, boolean] { const acct = getAccount(a) return [acct.totalNumUint, acct.balance !== 0] }, - acctTotalNumByteSlice(a: Account | internal.primitives.StubUint64Compat): readonly [uint64, boolean] { + acctTotalNumByteSlice(a: Account | StubUint64Compat): readonly [uint64, boolean] { const acct = getAccount(a) return [acct.totalNumByteSlice, acct.balance !== 0] }, - acctTotalExtraAppPages(a: Account | internal.primitives.StubUint64Compat): readonly [uint64, boolean] { + acctTotalExtraAppPages(a: Account | StubUint64Compat): readonly [uint64, boolean] { const acct = getAccount(a) return [acct.totalExtraAppPages, acct.balance !== 0] }, - acctTotalAppsCreated(a: Account | internal.primitives.StubUint64Compat): readonly [uint64, boolean] { + acctTotalAppsCreated(a: Account | StubUint64Compat): readonly [uint64, boolean] { const acct = getAccount(a) return [acct.totalAppsCreated, acct.balance !== 0] }, - acctTotalAppsOptedIn(a: Account | internal.primitives.StubUint64Compat): readonly [uint64, boolean] { + acctTotalAppsOptedIn(a: Account | StubUint64Compat): readonly [uint64, boolean] { const acct = getAccount(a) return [acct.totalAppsOptedIn, acct.balance !== 0] }, - acctTotalAssetsCreated(a: Account | internal.primitives.StubUint64Compat): readonly [uint64, boolean] { + acctTotalAssetsCreated(a: Account | StubUint64Compat): readonly [uint64, boolean] { const acct = getAccount(a) return [acct.totalAssetsCreated, acct.balance !== 0] }, - acctTotalAssets(a: Account | internal.primitives.StubUint64Compat): readonly [uint64, boolean] { + acctTotalAssets(a: Account | StubUint64Compat): readonly [uint64, boolean] { const acct = getAccount(a) return [acct.totalAssets, acct.balance !== 0] }, - acctTotalBoxes(a: Account | internal.primitives.StubUint64Compat): readonly [uint64, boolean] { + acctTotalBoxes(a: Account | StubUint64Compat): readonly [uint64, boolean] { const acct = getAccount(a) return [acct.totalBoxes, acct.balance !== 0] }, - acctTotalBoxBytes(a: Account | internal.primitives.StubUint64Compat): readonly [uint64, boolean] { + acctTotalBoxBytes(a: Account | StubUint64Compat): readonly [uint64, boolean] { const acct = getAccount(a) return [acct.totalBoxBytes, acct.balance !== 0] }, - // TODO: implement v11 methods - acctIncentiveEligible: function (_a: Account | uint64): readonly [boolean, boolean] { - throw new Error('Function not implemented.') + acctIncentiveEligible: function (a: Account | StubUint64Compat): readonly [boolean, boolean] { + const acct = getAccount(a) + const accountData = lazyContext.ledger.accountDataMap.get(acct) + return [accountData?.incentiveEligible ?? false, acct.balance !== 0] }, - acctLastProposed: function (_a: Account | uint64): readonly [uint64, boolean] { - throw new Error('Function not implemented.') + acctLastProposed: function (a: Account | StubUint64Compat): readonly [uint64, boolean] { + const acct = getAccount(a) + const accountData = lazyContext.ledger.accountDataMap.get(acct) + return [accountData?.lastProposed ?? Global.round, acct.balance !== 0] }, - acctLastHeartbeat: function (_a: Account | uint64): readonly [uint64, boolean] { - throw new Error('Function not implemented.') + acctLastHeartbeat: function (a: Account | StubUint64Compat): readonly [uint64, boolean] { + const acct = getAccount(a) + const accountData = lazyContext.ledger.accountDataMap.get(acct) + return [accountData?.lastHeartbeat ?? Global.round, acct.balance !== 0] }, } diff --git a/src/impl/app-global.ts b/src/impl/app-global.ts index 6d04bb7..48ef86a 100644 --- a/src/impl/app-global.ts +++ b/src/impl/app-global.ts @@ -1,20 +1,21 @@ -import { Application, Bytes, bytes, internal, Uint64, uint64 } from '@algorandfoundation/algorand-typescript' +import type { Application, bytes, op, uint64 } from '@algorandfoundation/algorand-typescript' import { lazyContext } from '../context-helpers/internal-context' import { toBytes } from '../encoders' import { asBytes } from '../util' import { getApp } from './app-params' +import { Bytes, Uint64, type StubBytesCompat, type StubUint64Compat } from './primitives' -export const AppGlobal: internal.opTypes.AppGlobalType = { - delete(a: internal.primitives.StubBytesCompat): void { +export const AppGlobal: typeof op.AppGlobal = { + delete(a: StubBytesCompat): void { lazyContext.ledger.setGlobalState(lazyContext.activeApplication, a, undefined) }, - getBytes(a: internal.primitives.StubBytesCompat): bytes { + getBytes(a: StubBytesCompat): bytes { return this.getExBytes(0, asBytes(a))[0] }, - getUint64(a: internal.primitives.StubBytesCompat): uint64 { + getUint64(a: StubBytesCompat): uint64 { return this.getExUint64(0, asBytes(a))[0] }, - getExBytes(a: Application | internal.primitives.StubUint64Compat, b: internal.primitives.StubBytesCompat): readonly [bytes, boolean] { + getExBytes(a: Application | StubUint64Compat, b: StubBytesCompat): readonly [bytes, boolean] { const app = getApp(a) if (app === undefined) { return [Bytes(), false] @@ -25,7 +26,7 @@ export const AppGlobal: internal.opTypes.AppGlobalType = { } return [toBytes(state!.value), exists] }, - getExUint64(a: Application | internal.primitives.StubUint64Compat, b: internal.primitives.StubBytesCompat): readonly [uint64, boolean] { + getExUint64(a: Application | StubUint64Compat, b: StubBytesCompat): readonly [uint64, boolean] { const app = getApp(a) if (app === undefined) { return [Uint64(0), false] @@ -36,7 +37,7 @@ export const AppGlobal: internal.opTypes.AppGlobalType = { } return [state!.value as uint64, exists] }, - put(a: internal.primitives.StubBytesCompat, b: internal.primitives.StubUint64Compat | internal.primitives.StubBytesCompat): void { + put(a: StubBytesCompat, b: StubUint64Compat | StubBytesCompat): void { lazyContext.ledger.setGlobalState(lazyContext.activeApplication, a, b) }, } diff --git a/src/impl/app-local.ts b/src/impl/app-local.ts index c8329f6..6456016 100644 --- a/src/impl/app-local.ts +++ b/src/impl/app-local.ts @@ -1,29 +1,26 @@ -import { Account, Application, Bytes, bytes, internal, Uint64, uint64 } from '@algorandfoundation/algorand-typescript' +import type { Account, Application, bytes, op, uint64 } from '@algorandfoundation/algorand-typescript' import { lazyContext } from '../context-helpers/internal-context' import { toBytes } from '../encoders' import { asBytes } from '../util' import { getAccount } from './acct-params' import { getApp } from './app-params' +import { Bytes, Uint64, type StubBytesCompat, type StubUint64Compat } from './primitives' -export const AppLocal: internal.opTypes.AppLocalType = { - delete: function (a: Account | internal.primitives.StubUint64Compat, b: internal.primitives.StubBytesCompat): void { +export const AppLocal: typeof op.AppLocal = { + delete: function (a: Account | StubUint64Compat, b: StubBytesCompat): void { const app = lazyContext.activeApplication const account = getAccount(a) lazyContext.ledger.setLocalState(app, account, b, undefined) }, - getBytes: function (a: Account | internal.primitives.StubUint64Compat, b: internal.primitives.StubBytesCompat): bytes { + getBytes: function (a: Account | StubUint64Compat, b: StubBytesCompat): bytes { const account = getAccount(a) return this.getExBytes(account, 0, asBytes(b))[0] }, - getUint64: function (a: Account | internal.primitives.StubUint64Compat, b: internal.primitives.StubBytesCompat): uint64 { + getUint64: function (a: Account | StubUint64Compat, b: StubBytesCompat): uint64 { const account = getAccount(a) return this.getExUint64(account, 0, asBytes(b))[0] }, - getExBytes: function ( - a: Account | internal.primitives.StubUint64Compat, - b: Application | internal.primitives.StubUint64Compat, - c: internal.primitives.StubBytesCompat, - ): readonly [bytes, boolean] { + getExBytes: function (a: Account | StubUint64Compat, b: Application | StubUint64Compat, c: StubBytesCompat): readonly [bytes, boolean] { const app = getApp(b) const account = getAccount(a) if (app === undefined || account === undefined) { @@ -35,11 +32,7 @@ export const AppLocal: internal.opTypes.AppLocalType = { } return [toBytes(state!.value), exists] }, - getExUint64: function ( - a: Account | internal.primitives.StubUint64Compat, - b: Application | internal.primitives.StubUint64Compat, - c: internal.primitives.StubBytesCompat, - ): readonly [uint64, boolean] { + getExUint64: function (a: Account | StubUint64Compat, b: Application | StubUint64Compat, c: StubBytesCompat): readonly [uint64, boolean] { const app = getApp(b) const account = getAccount(a) if (app === undefined || account === undefined) { @@ -51,7 +44,7 @@ export const AppLocal: internal.opTypes.AppLocalType = { } return [state!.value as uint64, exists] }, - put: function (a: Account | internal.primitives.StubUint64Compat, b: internal.primitives.StubBytesCompat, c: uint64 | bytes): void { + put: function (a: Account | StubUint64Compat, b: StubBytesCompat, c: uint64 | bytes): void { const app = lazyContext.activeApplication const account = getAccount(a) lazyContext.ledger.setLocalState(app, account, b, c) diff --git a/src/impl/app-params.ts b/src/impl/app-params.ts index e1b339c..b700b04 100644 --- a/src/impl/app-params.ts +++ b/src/impl/app-params.ts @@ -1,8 +1,17 @@ -import { Account, Application, Bytes, bytes, gtxn, internal, Uint64, uint64 } from '@algorandfoundation/algorand-typescript' +import type { + Account as AccountType, + Application as ApplicationType, + bytes, + gtxn, + op, + uint64, +} from '@algorandfoundation/algorand-typescript' import { lazyContext } from '../context-helpers/internal-context' import { asMaybeUint64Cls, asUint64 } from '../util' +import { Bytes, Uint64, type StubUint64Compat } from './primitives' +import { Account } from './reference' -const resolveAppIndex = (appIdOrIndex: internal.primitives.StubUint64Compat): uint64 => { +const resolveAppIndex = (appIdOrIndex: StubUint64Compat): uint64 => { const input = asUint64(appIdOrIndex) if (input >= 1001) { return input @@ -11,52 +20,52 @@ const resolveAppIndex = (appIdOrIndex: internal.primitives.StubUint64Compat): ui return txn.apps(input).id } -export const getApp = (app: Application | internal.primitives.StubUint64Compat): Application | undefined => { +export const getApp = (app: ApplicationType | StubUint64Compat): ApplicationType | undefined => { try { const appId = asMaybeUint64Cls(app) if (appId !== undefined) { return lazyContext.ledger.getApplication(resolveAppIndex(appId)) } - return app as Application + return app as ApplicationType } catch { return undefined } } -export const AppParams: internal.opTypes.AppParamsType = { - appApprovalProgram(a: Application | internal.primitives.StubUint64Compat): readonly [bytes, boolean] { +export const AppParams: typeof op.AppParams = { + appApprovalProgram(a: ApplicationType | StubUint64Compat): readonly [bytes, boolean] { const app = getApp(a) return app === undefined ? [Bytes(), false] : [app.approvalProgram, true] }, - appClearStateProgram(a: Application | internal.primitives.StubUint64Compat): readonly [bytes, boolean] { + appClearStateProgram(a: ApplicationType | StubUint64Compat): readonly [bytes, boolean] { const app = getApp(a) return app === undefined ? [Bytes(), false] : [app.clearStateProgram, true] }, - appGlobalNumUint(a: Application | internal.primitives.StubUint64Compat): readonly [uint64, boolean] { + appGlobalNumUint(a: ApplicationType | StubUint64Compat): readonly [uint64, boolean] { const app = getApp(a) return app === undefined ? [Uint64(0), false] : [app.globalNumUint, true] }, - appGlobalNumByteSlice(a: Application | internal.primitives.StubUint64Compat): readonly [uint64, boolean] { + appGlobalNumByteSlice(a: ApplicationType | StubUint64Compat): readonly [uint64, boolean] { const app = getApp(a) return app === undefined ? [Uint64(0), false] : [app.globalNumBytes, true] }, - appLocalNumUint(a: Application | internal.primitives.StubUint64Compat): readonly [uint64, boolean] { + appLocalNumUint(a: ApplicationType | StubUint64Compat): readonly [uint64, boolean] { const app = getApp(a) return app === undefined ? [Uint64(0), false] : [app.localNumUint, true] }, - appLocalNumByteSlice(a: Application | internal.primitives.StubUint64Compat): readonly [uint64, boolean] { + appLocalNumByteSlice(a: ApplicationType | StubUint64Compat): readonly [uint64, boolean] { const app = getApp(a) return app === undefined ? [Uint64(0), false] : [app.localNumBytes, true] }, - appExtraProgramPages(a: Application | internal.primitives.StubUint64Compat): readonly [uint64, boolean] { + appExtraProgramPages(a: ApplicationType | StubUint64Compat): readonly [uint64, boolean] { const app = getApp(a) return app === undefined ? [Uint64(0), false] : [app.extraProgramPages, true] }, - appCreator(a: Application | internal.primitives.StubUint64Compat): readonly [Account, boolean] { + appCreator(a: ApplicationType | StubUint64Compat): readonly [AccountType, boolean] { const app = getApp(a) return app === undefined ? [Account(), false] : [app.creator, true] }, - appAddress(a: Application | internal.primitives.StubUint64Compat): readonly [Account, boolean] { + appAddress(a: ApplicationType | StubUint64Compat): readonly [AccountType, boolean] { const app = getApp(a) return app === undefined ? [Account(), false] : [app.address, true] }, diff --git a/src/impl/application.ts b/src/impl/application.ts deleted file mode 100644 index 9ae03cd..0000000 --- a/src/impl/application.ts +++ /dev/null @@ -1,80 +0,0 @@ -import { Account, Application, bytes, LocalState, uint64 } from '@algorandfoundation/algorand-typescript' -import { BytesMap } from '../collections/custom-key-map' -import { ALWAYS_APPROVE_TEAL_PROGRAM } from '../constants' -import { lazyContext } from '../context-helpers/internal-context' -import { Mutable } from '../typescript-helpers' -import { asUint64, getApplicationAddress } from '../util' -import { Uint64BackedCls } from './base' -import { GlobalStateCls } from './state' - -export class ApplicationData { - application: Mutable> & { - appLogs: bytes[] - globalStates: BytesMap> - localStates: BytesMap> - boxes: BytesMap - } - isCreating: boolean = false - - get appLogs() { - return this.application.appLogs - } - - constructor() { - this.application = { - approvalProgram: ALWAYS_APPROVE_TEAL_PROGRAM, - clearStateProgram: ALWAYS_APPROVE_TEAL_PROGRAM, - globalNumUint: 0, - globalNumBytes: 0, - localNumUint: 0, - localNumBytes: 0, - extraProgramPages: 0, - creator: lazyContext.defaultSender, - appLogs: [], - globalStates: new BytesMap(), - localStates: new BytesMap(), - boxes: new BytesMap(), - } - } -} - -export class ApplicationCls extends Uint64BackedCls implements Application { - get id() { - return this.uint64 - } - - constructor(id?: uint64) { - super(asUint64(id ?? 0)) - } - - private get data(): ApplicationData { - return lazyContext.getApplicationData(this.id) - } - get approvalProgram(): bytes { - return this.data.application.approvalProgram - } - get clearStateProgram(): bytes { - return this.data.application.clearStateProgram - } - get globalNumUint(): uint64 { - return this.data.application.globalNumUint - } - get globalNumBytes(): uint64 { - return this.data.application.globalNumBytes - } - get localNumUint(): uint64 { - return this.data.application.localNumUint - } - get localNumBytes(): uint64 { - return this.data.application.localNumBytes - } - get extraProgramPages(): uint64 { - return this.data.application.extraProgramPages - } - get creator(): Account { - return this.data.application.creator - } - get address(): Account { - return getApplicationAddress(this.id) - } -} diff --git a/src/impl/asset-holding.ts b/src/impl/asset-holding.ts index 1da7f3e..06256bf 100644 --- a/src/impl/asset-holding.ts +++ b/src/impl/asset-holding.ts @@ -1,13 +1,11 @@ -import { Account, Asset, internal, Uint64, uint64 } from '@algorandfoundation/algorand-typescript' +import type { Account, Asset, op, uint64 } from '@algorandfoundation/algorand-typescript' import { lazyContext } from '../context-helpers/internal-context' -import { AssetHolding as AssetHoldingData } from './account' import { getAccount } from './acct-params' import { getAsset } from './asset-params' +import { Uint64, type StubUint64Compat } from './primitives' +import type { AssetHolding as AssetHoldingData } from './reference' -const getAssetHolding = ( - acctOrIndex: Account | internal.primitives.StubUint64Compat, - assetOrIndex: Asset | internal.primitives.StubUint64Compat, -): AssetHoldingData | undefined => { +const getAssetHolding = (acctOrIndex: Account | StubUint64Compat, assetOrIndex: Asset | StubUint64Compat): AssetHoldingData | undefined => { const account = getAccount(acctOrIndex) const asset = getAsset(assetOrIndex) if (asset === undefined) { @@ -22,18 +20,12 @@ const getAssetHolding = ( return holding } -export const AssetHolding: internal.opTypes.AssetHoldingType = { - assetBalance( - a: Account | internal.primitives.StubUint64Compat, - b: Asset | internal.primitives.StubUint64Compat, - ): readonly [uint64, boolean] { +export const AssetHolding: typeof op.AssetHolding = { + assetBalance(a: Account | StubUint64Compat, b: Asset | StubUint64Compat): readonly [uint64, boolean] { const holding = getAssetHolding(a, b) return holding === undefined ? [Uint64(0), false] : [holding.balance, true] }, - assetFrozen( - a: Account | internal.primitives.StubUint64Compat, - b: Asset | internal.primitives.StubUint64Compat, - ): readonly [boolean, boolean] { + assetFrozen(a: Account | StubUint64Compat, b: Asset | StubUint64Compat): readonly [boolean, boolean] { const holding = getAssetHolding(a, b) return holding === undefined ? [false, false] : [holding.frozen, true] }, diff --git a/src/impl/asset-params.ts b/src/impl/asset-params.ts index 05a4129..a61a428 100644 --- a/src/impl/asset-params.ts +++ b/src/impl/asset-params.ts @@ -1,8 +1,10 @@ -import { Account, Asset, Bytes, bytes, gtxn, internal, Uint64, uint64 } from '@algorandfoundation/algorand-typescript' +import type { Account as AccountType, Asset as AssetType, bytes, gtxn, op, uint64 } from '@algorandfoundation/algorand-typescript' import { lazyContext } from '../context-helpers/internal-context' import { asMaybeUint64Cls, asUint64 } from '../util' +import { Bytes, Uint64, type StubUint64Compat } from './primitives' +import { Account } from './reference' -const resolveAssetIndex = (assetIdOrIndex: internal.primitives.StubUint64Compat): uint64 => { +const resolveAssetIndex = (assetIdOrIndex: StubUint64Compat): uint64 => { const input = asUint64(assetIdOrIndex) if (input >= 1001) { return input @@ -11,64 +13,64 @@ const resolveAssetIndex = (assetIdOrIndex: internal.primitives.StubUint64Compat) return txn.assets(input).id } -export const getAsset = (asset: Asset | internal.primitives.StubUint64Compat): Asset | undefined => { +export const getAsset = (asset: AssetType | StubUint64Compat): AssetType | undefined => { try { const assetId = asMaybeUint64Cls(asset) if (assetId !== undefined) { return lazyContext.ledger.getAsset(resolveAssetIndex(assetId)) } - return asset as Asset + return asset as AssetType } catch { return undefined } } -export const AssetParams: internal.opTypes.AssetParamsType = { - assetTotal(a: Asset | internal.primitives.StubUint64Compat): readonly [uint64, boolean] { +export const AssetParams: typeof op.AssetParams = { + assetTotal(a: AssetType | StubUint64Compat): readonly [uint64, boolean] { const asset = getAsset(a) return asset === undefined ? [Uint64(0), false] : [asset.total, true] }, - assetDecimals(a: Asset | internal.primitives.StubUint64Compat): readonly [uint64, boolean] { + assetDecimals(a: AssetType | StubUint64Compat): readonly [uint64, boolean] { const asset = getAsset(a) return asset === undefined ? [Uint64(0), false] : [asset.decimals, true] }, - assetDefaultFrozen(a: Asset | internal.primitives.StubUint64Compat): readonly [boolean, boolean] { + assetDefaultFrozen(a: AssetType | StubUint64Compat): readonly [boolean, boolean] { const asset = getAsset(a) return asset === undefined ? [false, false] : [asset.defaultFrozen, true] }, - assetUnitName(a: Asset | internal.primitives.StubUint64Compat): readonly [bytes, boolean] { + assetUnitName(a: AssetType | StubUint64Compat): readonly [bytes, boolean] { const asset = getAsset(a) return asset === undefined ? [Bytes(), false] : [asset.unitName, true] }, - assetName(a: Asset | internal.primitives.StubUint64Compat): readonly [bytes, boolean] { + assetName(a: AssetType | StubUint64Compat): readonly [bytes, boolean] { const asset = getAsset(a) return asset === undefined ? [Bytes(), false] : [asset.name, true] }, - assetUrl(a: Asset | internal.primitives.StubUint64Compat): readonly [bytes, boolean] { + assetUrl(a: AssetType | StubUint64Compat): readonly [bytes, boolean] { const asset = getAsset(a) return asset === undefined ? [Bytes(), false] : [asset.url, true] }, - assetMetadataHash(a: Asset | internal.primitives.StubUint64Compat): readonly [bytes, boolean] { + assetMetadataHash(a: AssetType | StubUint64Compat): readonly [bytes, boolean] { const asset = getAsset(a) return asset === undefined ? [Bytes(), false] : [asset.metadataHash, true] }, - assetManager(a: Asset | internal.primitives.StubUint64Compat): readonly [Account, boolean] { + assetManager(a: AssetType | StubUint64Compat): readonly [AccountType, boolean] { const asset = getAsset(a) return asset === undefined ? [Account(), false] : [asset.manager, true] }, - assetReserve(a: Asset | internal.primitives.StubUint64Compat): readonly [Account, boolean] { + assetReserve(a: AssetType | StubUint64Compat): readonly [AccountType, boolean] { const asset = getAsset(a) return asset === undefined ? [Account(), false] : [asset.reserve, true] }, - assetFreeze(a: Asset | internal.primitives.StubUint64Compat): readonly [Account, boolean] { + assetFreeze(a: AssetType | StubUint64Compat): readonly [AccountType, boolean] { const asset = getAsset(a) return asset === undefined ? [Account(), false] : [asset.freeze, true] }, - assetClawback(a: Asset | internal.primitives.StubUint64Compat): readonly [Account, boolean] { + assetClawback(a: AssetType | StubUint64Compat): readonly [AccountType, boolean] { const asset = getAsset(a) return asset === undefined ? [Account(), false] : [asset.clawback, true] }, - assetCreator(a: Asset | internal.primitives.StubUint64Compat): readonly [Account, boolean] { + assetCreator(a: AssetType | StubUint64Compat): readonly [AccountType, boolean] { const asset = getAsset(a) return asset === undefined ? [Account(), false] : [asset.creator, true] }, diff --git a/src/impl/asset.ts b/src/impl/asset.ts deleted file mode 100644 index 5eeb156..0000000 --- a/src/impl/asset.ts +++ /dev/null @@ -1,76 +0,0 @@ -import { Account, Asset, bytes, internal, uint64 } from '@algorandfoundation/algorand-typescript' -import { lazyContext } from '../context-helpers/internal-context' -import { Mutable } from '../typescript-helpers' -import { asUint64 } from '../util' -import { AssetHolding } from './account' -import { Uint64BackedCls } from './base' - -export type AssetData = Mutable> - -export class AssetCls extends Uint64BackedCls implements Asset { - get id(): uint64 { - return this.uint64 - } - - constructor(id?: internal.primitives.StubUint64Compat) { - super(asUint64(id ?? 0)) - } - - private get data(): AssetData { - return lazyContext.getAssetData(this.id) - } - - get total(): uint64 { - return this.data.total - } - get decimals(): uint64 { - return this.data.decimals - } - get defaultFrozen(): boolean { - return this.data.defaultFrozen - } - get unitName(): bytes { - return this.data.unitName - } - get name(): bytes { - return this.data.name - } - get url(): bytes { - return this.data.url - } - get metadataHash(): bytes { - return this.data.metadataHash - } - get manager(): Account { - return this.data.manager - } - get reserve(): Account { - return this.data.reserve - } - get freeze(): Account { - return this.data.freeze - } - get clawback(): Account { - return this.data.clawback - } - get creator(): Account { - return this.data.creator - } - balance(account: Account): uint64 { - return this.getAssetHolding(account).balance - } - frozen(account: Account): boolean { - return this.getAssetHolding(account).frozen - } - - private getAssetHolding(account: Account): AssetHolding { - const accountData = lazyContext.getAccountData(account) - const assetHolding = accountData.optedAssets.get(this.id) - if (assetHolding === undefined) { - internal.errors.internalError( - 'The asset is not opted into the account! Use `ctx.any.account(opted_asset_balances={{ASSET_ID: VALUE}})` to set emulated opted asset into the account.', - ) - } - return assetHolding - } -} diff --git a/src/impl/base-32.ts b/src/impl/base-32.ts new file mode 100644 index 0000000..1d345e7 --- /dev/null +++ b/src/impl/base-32.ts @@ -0,0 +1,54 @@ +const BASE32_ALPHABET = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ234567'.split('') + +const CHAR_TO_NUM = BASE32_ALPHABET.reduce((acc, cur, index) => ((acc[cur] = index), acc), {} as Record) + +export const base32ToUint8Array = (value: string): Uint8Array => { + let allChars = value + .split('') + .filter((c) => c !== '=') + .map((c) => { + const cUpper = c.toUpperCase() + if (cUpper in CHAR_TO_NUM) return CHAR_TO_NUM[cUpper] + throw new Error(`Invalid base32 char ${c}`) + }) + const bytes = new Array() + while (allChars.length) { + const [a, b, c, d, e, f, g, h, ...rest] = allChars + if (a === undefined || b === undefined) break + bytes.push(((a << 3) | (b >>> 2)) & 255) + if (c === undefined || d === undefined) break + bytes.push(((b << 6) | (c << 1) | (d >>> 4)) & 255) + if (e === undefined) break + bytes.push(((d << 4) | (e >>> 1)) & 255) + if (f === undefined || g === undefined) break + bytes.push(((e << 7) | (f << 2) | (g >>> 3)) & 255) + if (h === undefined) break + bytes.push(((g << 5) | h) & 255) + allChars = rest + } + return new Uint8Array(bytes) +} + +export const uint8ArrayToBase32 = (value: Uint8Array): string => { + let allBytes = Array.from(value) + let base32str = '' + while (allBytes.length) { + const [a, b, c, d, e, ...rest] = allBytes ?? [0, 0, 0, 0, 0] + + if (allBytes.length < 1) break + base32str += BASE32_ALPHABET[a >>> 3] + base32str += BASE32_ALPHABET[((a << 2) | ((b || 0) >>> 6)) & 31] + if (allBytes.length < 2) break + base32str += BASE32_ALPHABET[(b >>> 1) & 31] + base32str += BASE32_ALPHABET[((b << 4) | (c >>> 4)) & 31] + if (allBytes.length < 3) break + base32str += BASE32_ALPHABET[((c << 1) | (d >>> 7)) & 31] + if (allBytes.length < 4) break + base32str += BASE32_ALPHABET[(d >>> 2) & 31] + base32str += BASE32_ALPHABET[((d << 3) | (e >>> 5)) & 31] + if (allBytes.length < 5) break + base32str += BASE32_ALPHABET[e & 31] + allBytes = rest + } + return base32str +} diff --git a/src/impl/base-contract.ts b/src/impl/base-contract.ts new file mode 100644 index 0000000..b8429a3 --- /dev/null +++ b/src/impl/base-contract.ts @@ -0,0 +1,25 @@ +import type { contract as contractType, uint64 } from '@algorandfoundation/algorand-typescript' +import type { ConstructorFor } from '../typescript-helpers' + +export abstract class BaseContract { + static isArc4 = false + + public abstract approvalProgram(): boolean | uint64 + public clearStateProgram(): boolean | uint64 { + return true + } +} + +export const ContractOptionsSymbol = Symbol('ContractOptions') +export function contract(options: Parameters[0]) { + return >(contract: T, ctx: ClassDecoratorContext) => { + ctx.addInitializer(function () { + Object.defineProperty(this, ContractOptionsSymbol, { + value: options, + writable: false, + enumerable: false, + }) + }) + return contract + } +} diff --git a/src/impl/base.ts b/src/impl/base.ts index 45d4386..6c2b958 100644 --- a/src/impl/base.ts +++ b/src/impl/base.ts @@ -1,6 +1,8 @@ -import { bytes, internal, Uint64, uint64 } from '@algorandfoundation/algorand-typescript' +import type { bytes, uint64 } from '@algorandfoundation/algorand-typescript' import { encodingUtil } from '@algorandfoundation/puya-ts' import type { TypeInfo } from '../encoders' +import type { StubBytesCompat } from './primitives' +import { BytesCls, Uint64 } from './primitives' export abstract class BytesBackedCls { #value: bytes @@ -16,10 +18,10 @@ export abstract class BytesBackedCls { static fromBytes( this: { new (v: bytes, typeInfo?: TypeInfo): T }, - value: internal.primitives.StubBytesCompat | Uint8Array, + value: StubBytesCompat | Uint8Array, typeInfo?: TypeInfo, ) { - return new this(internal.primitives.BytesCls.fromCompat(value).asAlgoTs(), typeInfo) + return new this(BytesCls.fromCompat(value).asAlgoTs(), typeInfo) } } @@ -34,8 +36,8 @@ export abstract class Uint64BackedCls { this.#value = value } - static fromBytes(this: { new (v: uint64): T }, value: internal.primitives.StubBytesCompat | Uint8Array) { - const uint8ArrayValue = value instanceof Uint8Array ? value : internal.primitives.BytesCls.fromCompat(value).asUint8Array() + static fromBytes(this: { new (v: uint64): T }, value: StubBytesCompat | Uint8Array) { + const uint8ArrayValue = value instanceof Uint8Array ? value : BytesCls.fromCompat(value).asUint8Array() const uint64Value = Uint64(encodingUtil.uint8ArrayToBigInt(uint8ArrayValue)) return new this(uint64Value) } diff --git a/src/impl/block.ts b/src/impl/block.ts index 79e9069..e230c9d 100644 --- a/src/impl/block.ts +++ b/src/impl/block.ts @@ -1,38 +1,64 @@ -import { Account, bytes, internal, uint64 } from '@algorandfoundation/algorand-typescript' +import type { Account as AccountType, bytes, op, uint64 } from '@algorandfoundation/algorand-typescript' import { lazyContext } from '../context-helpers/internal-context' -import { asUint64 } from '../util' -import { itob } from './pure' +import { asUint64, getRandomBytes } from '../util' +import { Uint64, type StubUint64Compat } from './primitives' +import { Account } from './reference' -export const Block: internal.opTypes.BlockType = { - blkSeed: function (a: internal.primitives.StubUint64Compat): bytes { - return itob(lazyContext.ledger.getBlockContent(a).seed) +export class BlockData { + seed: bytes + timestamp: uint64 + proposer: AccountType + feesCollected: uint64 + bonus: uint64 + branch: bytes + feeSink: AccountType + protocol: bytes + txnCounter: uint64 + proposerPayout: uint64 + + constructor() { + this.seed = getRandomBytes(32).asAlgoTs() + this.timestamp = asUint64(Date.now()) + this.proposer = Account() + this.feesCollected = Uint64(0) + this.bonus = Uint64(0) + this.branch = getRandomBytes(32).asAlgoTs() + this.feeSink = Account() + this.protocol = getRandomBytes(32).asAlgoTs() + this.txnCounter = Uint64(0) + this.proposerPayout = Uint64(0) + } +} + +export const Block: typeof op.Block = { + blkSeed: function (a: StubUint64Compat): bytes { + return lazyContext.ledger.getBlockData(a).seed }, - blkTimestamp: function (a: internal.primitives.StubUint64Compat): uint64 { - return asUint64(lazyContext.ledger.getBlockContent(a).timestamp) + blkTimestamp: function (a: StubUint64Compat): uint64 { + return lazyContext.ledger.getBlockData(a).timestamp }, - // TODO: implement v11 methods - blkProposer: function (_a: uint64): Account { - throw new Error('Function not implemented.') + blkProposer: function (a: uint64): AccountType { + return lazyContext.ledger.getBlockData(a).proposer }, - blkFeesCollected: function (_a: uint64): uint64 { - throw new Error('Function not implemented.') + blkFeesCollected: function (a: uint64): uint64 { + return lazyContext.ledger.getBlockData(a).feesCollected }, - blkBonus: function (_a: uint64): uint64 { - throw new Error('Function not implemented.') + blkBonus: function (a: uint64): uint64 { + return lazyContext.ledger.getBlockData(a).bonus }, - blkBranch: function (_a: uint64): bytes { - throw new Error('Function not implemented.') + blkBranch: function (a: uint64): bytes { + return lazyContext.ledger.getBlockData(a).branch }, - blkFeeSink: function (_a: uint64): Account { - throw new Error('Function not implemented.') + blkFeeSink: function (a: uint64): AccountType { + return lazyContext.ledger.getBlockData(a).feeSink }, - blkProtocol: function (_a: uint64): bytes { - throw new Error('Function not implemented.') + blkProtocol: function (a: uint64): bytes { + return lazyContext.ledger.getBlockData(a).protocol }, - blkTxnCounter: function (_a: uint64): uint64 { - throw new Error('Function not implemented.') + blkTxnCounter: function (a: uint64): uint64 { + return lazyContext.ledger.getBlockData(a).txnCounter }, - blkProposerPayout: function (_a: uint64): uint64 { - throw new Error('Function not implemented.') + blkProposerPayout: function (a: uint64): uint64 { + return lazyContext.ledger.getBlockData(a).proposerPayout }, } diff --git a/src/impl/box.ts b/src/impl/box.ts index a7ffabe..33c6b01 100644 --- a/src/impl/box.ts +++ b/src/impl/box.ts @@ -1,15 +1,17 @@ -import { bytes, internal, uint64 } from '@algorandfoundation/algorand-typescript' +import type { bytes, op, uint64 } from '@algorandfoundation/algorand-typescript' import { MAX_BOX_SIZE } from '../constants' import { lazyContext } from '../context-helpers/internal-context' import { toBytes } from '../encoders' +import { AvmError, InternalError } from '../errors' import { asBytes, asBytesCls, asNumber, asUint8Array, conactUint8Arrays } from '../util' +import type { StubBytesCompat, StubUint64Compat } from './primitives' -export const Box: internal.opTypes.BoxType = { - create(a: internal.primitives.StubBytesCompat, b: internal.primitives.StubUint64Compat): boolean { +export const Box: typeof op.Box = { + create(a: StubBytesCompat, b: StubUint64Compat): boolean { const name = asBytes(a) const size = asNumber(b) if (name.length === 0 || size > MAX_BOX_SIZE) { - throw new internal.errors.InternalError('Invalid box name or size') + throw new AvmError('Invalid box name or size') } const app = lazyContext.activeApplication if (lazyContext.ledger.boxExists(app, name)) { @@ -18,7 +20,7 @@ export const Box: internal.opTypes.BoxType = { lazyContext.ledger.setBox(app, name, new Uint8Array(size)) return true }, - delete(a: internal.primitives.StubBytesCompat): boolean { + delete(a: StubBytesCompat): boolean { const name = asBytes(a) const app = lazyContext.activeApplication if (!lazyContext.ledger.boxExists(app, name)) { @@ -27,31 +29,31 @@ export const Box: internal.opTypes.BoxType = { lazyContext.ledger.deleteBox(app, name) return true }, - extract(a: internal.primitives.StubBytesCompat, b: internal.primitives.StubUint64Compat, c: internal.primitives.StubUint64Compat): bytes { + extract(a: StubBytesCompat, b: StubUint64Compat, c: StubUint64Compat): bytes { const name = asBytes(a) const start = asNumber(b) const length = asNumber(c) const app = lazyContext.activeApplication if (!lazyContext.ledger.boxExists(app, name)) { - throw new internal.errors.InternalError('Box does not exist') + throw new InternalError('Box does not exist') } const boxContent = lazyContext.ledger.getBox(app, name) return toBytes(boxContent.slice(start, start + length)) }, - get(a: internal.primitives.StubBytesCompat): readonly [bytes, boolean] { + get(a: StubBytesCompat): readonly [bytes, boolean] { const name = asBytes(a) const app = lazyContext.activeApplication const boxContent = lazyContext.ledger.getBox(app, name) return [toBytes(boxContent), lazyContext.ledger.boxExists(app, name)] }, - length(a: internal.primitives.StubBytesCompat): readonly [uint64, boolean] { + length(a: StubBytesCompat): readonly [uint64, boolean] { const name = asBytes(a) const app = lazyContext.activeApplication const boxContent = lazyContext.ledger.getBox(app, name) const exists = lazyContext.ledger.boxExists(app, name) return [boxContent.length, exists] }, - put(a: internal.primitives.StubBytesCompat, b: internal.primitives.StubBytesCompat): void { + put(a: StubBytesCompat, b: StubBytesCompat): void { const name = asBytes(a) const app = lazyContext.activeApplication const newContent = asBytesCls(b) @@ -59,32 +61,32 @@ export const Box: internal.opTypes.BoxType = { const boxContent = lazyContext.ledger.getBox(app, name) const length = boxContent.length if (asNumber(length) !== asNumber(newContent.length)) { - throw new internal.errors.InternalError('New content length does not match existing box length') + throw new InternalError('New content length does not match existing box length') } } lazyContext.ledger.setBox(app, name, newContent.asUint8Array()) }, - replace(a: internal.primitives.StubBytesCompat, b: internal.primitives.StubUint64Compat, c: internal.primitives.StubBytesCompat): void { + replace(a: StubBytesCompat, b: StubUint64Compat, c: StubBytesCompat): void { const name = asBytes(a) const start = asNumber(b) const newContent = asUint8Array(c) const app = lazyContext.activeApplication if (!lazyContext.ledger.boxExists(app, name)) { - throw new internal.errors.InternalError('Box does not exist') + throw new InternalError('Box does not exist') } const boxContent = lazyContext.ledger.getBox(app, name) if (start + newContent.length > boxContent.length) { - throw new internal.errors.InternalError('Replacement content exceeds box size') + throw new InternalError('Replacement content exceeds box size') } const updatedContent = conactUint8Arrays(boxContent.slice(0, start), newContent, boxContent.slice(start + newContent.length)) lazyContext.ledger.setBox(app, name, updatedContent) }, - resize(a: internal.primitives.StubBytesCompat, b: internal.primitives.StubUint64Compat): void { + resize(a: StubBytesCompat, b: StubUint64Compat): void { const name = asBytes(a) const newSize = asNumber(b) const app = lazyContext.activeApplication if (!lazyContext.ledger.boxExists(app, name)) { - throw new internal.errors.InternalError('Box does not exist') + throw new InternalError('Box does not exist') } const boxContent = lazyContext.ledger.getBox(app, name) const size = boxContent.length @@ -96,24 +98,19 @@ export const Box: internal.opTypes.BoxType = { } lazyContext.ledger.setBox(app, name, updatedContent) }, - splice( - a: internal.primitives.StubBytesCompat, - b: internal.primitives.StubUint64Compat, - c: internal.primitives.StubUint64Compat, - d: internal.primitives.StubBytesCompat, - ): void { + splice(a: StubBytesCompat, b: StubUint64Compat, c: StubUint64Compat, d: StubBytesCompat): void { const name = asBytes(a) const start = asNumber(b) const length = asNumber(c) const newContent = asUint8Array(d) const app = lazyContext.activeApplication if (!lazyContext.ledger.boxExists(app, name)) { - throw new internal.errors.InternalError('Box does not exist') + throw new InternalError('Box does not exist') } const boxContent = lazyContext.ledger.getBox(app, name) const size = boxContent.length if (start > size) { - throw new internal.errors.InternalError('Start index exceeds box size') + throw new InternalError('Start index exceeds box size') } const end = Math.min(start + length, size) let updatedContent = conactUint8Arrays(boxContent.slice(0, start), newContent, boxContent.slice(end)) diff --git a/src/impl/compiled.ts b/src/impl/compiled.ts index 71aa7a2..8575ecd 100644 --- a/src/impl/compiled.ts +++ b/src/impl/compiled.ts @@ -1,4 +1,4 @@ -import { +import type { Account, BaseContract, CompileContractOptions, @@ -8,8 +8,8 @@ import { LogicSig, } from '@algorandfoundation/algorand-typescript' import { lazyContext } from '../context-helpers/internal-context' -import { ConstructorFor } from '../typescript-helpers' -import { ApplicationData } from './application' +import type { ConstructorFor } from '../typescript-helpers' +import type { ApplicationData } from './reference' export function compileImpl( artefact: ConstructorFor | ConstructorFor, diff --git a/src/impl/contract.ts b/src/impl/contract.ts new file mode 100644 index 0000000..e09ff71 --- /dev/null +++ b/src/impl/contract.ts @@ -0,0 +1,38 @@ +import type { arc4, OnCompleteActionStr } from '@algorandfoundation/algorand-typescript' +import type { DeliberateAny } from '../typescript-helpers' +import { BaseContract } from './base-contract' + +export class Contract extends BaseContract { + static isArc4 = true + + override approvalProgram(): boolean { + return true + } +} + +export const Arc4MethodConfigSymbol = Symbol('Arc4MethodConfig') +export function abimethod(config?: arc4.AbiMethodConfig) { + return function ( + target: { [Arc4MethodConfigSymbol]: arc4.AbiMethodConfig } & ((this: TContract, ...args: TArgs) => TReturn), + ): (this: TContract, ...args: TArgs) => TReturn { + target[Arc4MethodConfigSymbol] = { + ...config, + onCreate: config?.onCreate ?? 'disallow', + allowActions: ([] as OnCompleteActionStr[]).concat(config?.allowActions ?? 'NoOp'), + } + return target + } +} + +export function baremethod(config?: arc4.BareMethodConfig) { + return function ( + target: { [Arc4MethodConfigSymbol]: arc4.AbiMethodConfig } & ((this: TContract, ...args: TArgs) => TReturn), + ): (this: TContract, ...args: TArgs) => TReturn { + target[Arc4MethodConfigSymbol] = { + ...config, + onCreate: config?.onCreate ?? 'disallow', + allowActions: ([] as OnCompleteActionStr[]).concat(config?.allowActions ?? 'NoOp'), + } + return target + } +} diff --git a/src/impl/crypto.ts b/src/impl/crypto.ts index 6089807..bcd3593 100644 --- a/src/impl/crypto.ts +++ b/src/impl/crypto.ts @@ -1,65 +1,60 @@ -import { arc4, bytes, Bytes, Ecdsa, gtxn, internal, VrfVerify } from '@algorandfoundation/algorand-typescript' -import { ec } from 'elliptic' -import { sha256 as js_sha256 } from 'js-sha256' -import { keccak256 as js_keccak256, sha3_256 as js_sha3_256 } from 'js-sha3' -import { sha512_256 as js_sha512_256 } from 'js-sha512' +import type { bytes, gtxn, MimcConfigurations, op, VrfVerify } from '@algorandfoundation/algorand-typescript' +import { Ecdsa, OnCompleteAction } from '@algorandfoundation/algorand-typescript' +import elliptic from 'elliptic' +import js_sha256 from 'js-sha256' +import js_sha3 from 'js-sha3' +import js_sha512 from 'js-sha512' import nacl from 'tweetnacl' import { LOGIC_DATA_PREFIX, PROGRAM_TAG } from '../constants' import { lazyContext } from '../context-helpers/internal-context' -import { notImplementedError } from '../errors' +import { InternalError, NotImplementedError } from '../errors' import { asBytes, asBytesCls, asUint8Array, conactUint8Arrays } from '../util' +import type { StubBytesCompat, StubUint64Compat } from './primitives' +import { Bytes, BytesCls, Uint64Cls } from './primitives' -export const sha256 = (a: internal.primitives.StubBytesCompat): bytes => { - const bytesA = internal.primitives.BytesCls.fromCompat(a) - const hashArray = js_sha256.create().update(bytesA.asUint8Array()).digest() - const hashBytes = internal.primitives.BytesCls.fromCompat(new Uint8Array(hashArray)) +export const sha256 = (a: StubBytesCompat): bytes => { + const bytesA = BytesCls.fromCompat(a) + const hashArray = js_sha256.sha256.create().update(bytesA.asUint8Array()).digest() + const hashBytes = BytesCls.fromCompat(new Uint8Array(hashArray)) return hashBytes.asAlgoTs() } -export const sha3_256 = (a: internal.primitives.StubBytesCompat): bytes => { - const bytesA = internal.primitives.BytesCls.fromCompat(a) - const hashArray = js_sha3_256.create().update(bytesA.asUint8Array()).digest() - const hashBytes = internal.primitives.BytesCls.fromCompat(new Uint8Array(hashArray)) +export const sha3_256 = (a: StubBytesCompat): bytes => { + const bytesA = BytesCls.fromCompat(a) + const hashArray = js_sha3.sha3_256.create().update(bytesA.asUint8Array()).digest() + const hashBytes = BytesCls.fromCompat(new Uint8Array(hashArray)) return hashBytes.asAlgoTs() } -export const keccak256 = (a: internal.primitives.StubBytesCompat): bytes => { - const bytesA = internal.primitives.BytesCls.fromCompat(a) - const hashArray = js_keccak256.create().update(bytesA.asUint8Array()).digest() - const hashBytes = internal.primitives.BytesCls.fromCompat(new Uint8Array(hashArray)) +export const keccak256 = (a: StubBytesCompat): bytes => { + const bytesA = BytesCls.fromCompat(a) + const hashArray = js_sha3.keccak256.create().update(bytesA.asUint8Array()).digest() + const hashBytes = BytesCls.fromCompat(new Uint8Array(hashArray)) return hashBytes.asAlgoTs() } -export const sha512_256 = (a: internal.primitives.StubBytesCompat): bytes => { - const bytesA = internal.primitives.BytesCls.fromCompat(a) - const hashArray = js_sha512_256.create().update(bytesA.asUint8Array()).digest() - const hashBytes = internal.primitives.BytesCls.fromCompat(new Uint8Array(hashArray)) +export const sha512_256 = (a: StubBytesCompat): bytes => { + const bytesA = BytesCls.fromCompat(a) + const hashArray = js_sha512.sha512_256.create().update(bytesA.asUint8Array()).digest() + const hashBytes = BytesCls.fromCompat(new Uint8Array(hashArray)) return hashBytes.asAlgoTs() } -export const ed25519verifyBare = ( - a: internal.primitives.StubBytesCompat, - b: internal.primitives.StubBytesCompat, - c: internal.primitives.StubBytesCompat, -): boolean => { - const bytesA = internal.primitives.BytesCls.fromCompat(a) - const bytesB = internal.primitives.BytesCls.fromCompat(b) - const bytesC = internal.primitives.BytesCls.fromCompat(c) +export const ed25519verifyBare = (a: StubBytesCompat, b: StubBytesCompat, c: StubBytesCompat): boolean => { + const bytesA = BytesCls.fromCompat(a) + const bytesB = BytesCls.fromCompat(b) + const bytesC = BytesCls.fromCompat(c) return nacl.sign.detached.verify(bytesA.asUint8Array(), bytesB.asUint8Array(), bytesC.asUint8Array()) } -export const ed25519verify = ( - a: internal.primitives.StubBytesCompat, - b: internal.primitives.StubBytesCompat, - c: internal.primitives.StubBytesCompat, -): boolean => { +export const ed25519verify = (a: StubBytesCompat, b: StubBytesCompat, c: StubBytesCompat): boolean => { const txn = lazyContext.activeGroup.activeTransaction as gtxn.ApplicationTxn const programBytes = asBytesCls( - txn.onCompletion == arc4.OnCompleteAction[arc4.OnCompleteAction.ClearState] ? txn.clearStateProgram : txn.approvalProgram, + txn.onCompletion == OnCompleteAction[OnCompleteAction.ClearState] ? txn.clearStateProgram : txn.approvalProgram, ) const logicSig = conactUint8Arrays(asUint8Array(PROGRAM_TAG), programBytes.asUint8Array()) - const logicSigAddress = js_sha512_256.array(logicSig) + const logicSigAddress = js_sha512.sha512_256.array(logicSig) const addressBytes = Bytes(logicSigAddress) const data = LOGIC_DATA_PREFIX.concat(addressBytes).concat(asBytes(a)) @@ -68,43 +63,43 @@ export const ed25519verify = ( export const ecdsaVerify = ( v: Ecdsa, - a: internal.primitives.StubBytesCompat, - b: internal.primitives.StubBytesCompat, - c: internal.primitives.StubBytesCompat, - d: internal.primitives.StubBytesCompat, - e: internal.primitives.StubBytesCompat, + a: StubBytesCompat, + b: StubBytesCompat, + c: StubBytesCompat, + d: StubBytesCompat, + e: StubBytesCompat, ): boolean => { - const dataBytes = internal.primitives.BytesCls.fromCompat(a) - const sigRBytes = internal.primitives.BytesCls.fromCompat(b) - const sigSBytes = internal.primitives.BytesCls.fromCompat(c) - const pubkeyXBytes = internal.primitives.BytesCls.fromCompat(d) - const pubkeyYBytes = internal.primitives.BytesCls.fromCompat(e) + const dataBytes = BytesCls.fromCompat(a) + const sigRBytes = BytesCls.fromCompat(b) + const sigSBytes = BytesCls.fromCompat(c) + const pubkeyXBytes = BytesCls.fromCompat(d) + const pubkeyYBytes = BytesCls.fromCompat(e) - const publicKey = internal.primitives.BytesCls.fromCompat(new Uint8Array([0x04])) + const publicKey = BytesCls.fromCompat(new Uint8Array([0x04])) .concat(pubkeyXBytes) .concat(pubkeyYBytes) - const ecdsa = new ec(curveMap[v]) + const ecdsa = new elliptic.ec(curveMap[v]) const keyPair = ecdsa.keyFromPublic(publicKey.asUint8Array()) return keyPair.verify(dataBytes.asUint8Array(), { r: sigRBytes.asUint8Array(), s: sigSBytes.asUint8Array() }) } export const ecdsaPkRecover = ( v: Ecdsa, - a: internal.primitives.StubBytesCompat, - b: internal.primitives.StubUint64Compat, - c: internal.primitives.StubBytesCompat, - d: internal.primitives.StubBytesCompat, + a: StubBytesCompat, + b: StubUint64Compat, + c: StubBytesCompat, + d: StubBytesCompat, ): readonly [bytes, bytes] => { if (v !== Ecdsa.Secp256k1) { - internal.errors.internalError(`Unsupported ECDSA curve: ${v}`) + throw new InternalError(`Unsupported ECDSA curve: ${v}`) } - const dataBytes = internal.primitives.BytesCls.fromCompat(a) - const rBytes = internal.primitives.BytesCls.fromCompat(c) - const sBytes = internal.primitives.BytesCls.fromCompat(d) - const recoveryId = internal.primitives.Uint64Cls.fromCompat(b) + const dataBytes = BytesCls.fromCompat(a) + const rBytes = BytesCls.fromCompat(c) + const sBytes = BytesCls.fromCompat(d) + const recoveryId = Uint64Cls.fromCompat(b) - const ecdsa = new ec(curveMap[v]) + const ecdsa = new elliptic.ec(curveMap[v]) const pubKey = ecdsa.recoverPubKey( dataBytes.asUint8Array(), { r: rBytes.asUint8Array(), s: sBytes.asUint8Array() }, @@ -116,10 +111,10 @@ export const ecdsaPkRecover = ( return [Bytes(x), Bytes(y)] } -export const ecdsaPkDecompress = (v: Ecdsa, a: internal.primitives.StubBytesCompat): readonly [bytes, bytes] => { - const bytesA = internal.primitives.BytesCls.fromCompat(a) +export const ecdsaPkDecompress = (v: Ecdsa, a: StubBytesCompat): readonly [bytes, bytes] => { + const bytesA = BytesCls.fromCompat(a) - const ecdsa = new ec(curveMap[v]) + const ecdsa = new elliptic.ec(curveMap[v]) const keyPair = ecdsa.keyFromPublic(bytesA.asUint8Array()) const pubKey = keyPair.getPublic() @@ -128,21 +123,20 @@ export const ecdsaPkDecompress = (v: Ecdsa, a: internal.primitives.StubBytesComp return [Bytes(new Uint8Array(x)), Bytes(new Uint8Array(y))] } -export const vrfVerify = ( - _s: VrfVerify, - _a: internal.primitives.StubBytesCompat, - _b: internal.primitives.StubBytesCompat, - _c: internal.primitives.StubBytesCompat, -): readonly [bytes, boolean] => { - notImplementedError('vrfVerify') +export const vrfVerify = (_s: VrfVerify, _a: StubBytesCompat, _b: StubBytesCompat, _c: StubBytesCompat): readonly [bytes, boolean] => { + throw new NotImplementedError('vrfVerify') } -export const EllipticCurve = new Proxy({} as internal.opTypes.EllipticCurveType, { +export const EllipticCurve = new Proxy({} as typeof op.EllipticCurve, { get: (_target, prop) => { - notImplementedError(`EllipticCurve.${prop.toString()}`) + throw new NotImplementedError(`EllipticCurve.${prop.toString()}`) }, }) +export const mimc = (_c: MimcConfigurations, _a: StubBytesCompat): bytes => { + throw new NotImplementedError('mimc') +} + const curveMap = { [Ecdsa.Secp256k1]: 'secp256k1', [Ecdsa.Secp256r1]: 'p256', diff --git a/src/impl/emit.ts b/src/impl/emit.ts index d5974ed..57eb3e1 100644 --- a/src/impl/emit.ts +++ b/src/impl/emit.ts @@ -1,8 +1,8 @@ -import { internal } from '@algorandfoundation/algorand-typescript' -import { lazyContext } from '../context-helpers/internal-context' -import { DeliberateAny } from '../typescript-helpers' +import { CodeError } from '../errors' +import type { DeliberateAny } from '../typescript-helpers' import { sha512_256 } from './crypto' import { getArc4Encoded, getArc4TypeName } from './encoded-types' +import { log } from './log' export function emitImpl(typeInfoString: string, event: T | string, ...eventProps: unknown[]) { let eventData @@ -14,7 +14,7 @@ export function emitImpl(typeInfoString: string, event: T | string, ...eventP if (eventName.indexOf('(') === -1) { eventName += argTypes } else if (event.indexOf(argTypes) === -1) { - throw internal.errors.codeError(`Event signature ${event} does not match arg types ${argTypes}`) + throw new CodeError(`Event signature ${event} does not match arg types ${argTypes}`) } } else { eventData = getArc4Encoded(event) @@ -24,5 +24,5 @@ export function emitImpl(typeInfoString: string, event: T | string, ...eventP } const eventHash = sha512_256(eventName) - lazyContext.value.log(eventHash.slice(0, 4).concat(eventData.bytes)) + log(eventHash.slice(0, 4).concat(eventData.bytes)) } diff --git a/src/impl/encoded-types.ts b/src/impl/encoded-types.ts index 1d50312..e8a5b16 100644 --- a/src/impl/encoded-types.ts +++ b/src/impl/encoded-types.ts @@ -1,8 +1,15 @@ -import { Account, BigUintCompat, Bytes, bytes, internal, StringCompat, uint64, Uint64Compat } from '@algorandfoundation/algorand-typescript' +import type { + Account as AccountType, + BigUintCompat, + bytes, + StringCompat, + uint64, + Uint64Compat, +} from '@algorandfoundation/algorand-typescript' +import type { BitSize } from '@algorandfoundation/algorand-typescript/arc4' import { Address, ARC4Encoded, - BitSize, Bool, Byte, DynamicArray, @@ -22,23 +29,36 @@ import { ALGORAND_ADDRESS_BYTE_LENGTH, ALGORAND_CHECKSUM_BYTE_LENGTH, BITS_IN_BYTE, + UINT512_SIZE, UINT64_SIZE, } from '../constants' import { lazyContext } from '../context-helpers/internal-context' -import { fromBytes, TypeInfo } from '../encoders' -import { DeliberateAny } from '../typescript-helpers' -import { asBigInt, asBigUint, asBigUintCls, asBytesCls, asUint64, asUint8Array, conactUint8Arrays, uint8ArrayToNumber } from '../util' -import { AccountCls } from './account' -import { ApplicationCls } from './application' -import { AssetCls } from './asset' -import { ApplicationTransaction } from './transactions' +import type { fromBytes, TypeInfo } from '../encoders' +import { AvmError, avmInvariant, CodeError } from '../errors' +import type { DeliberateAny } from '../typescript-helpers' +import { + asBigInt, + asBigUint, + asBigUintCls, + asBytes, + asBytesCls, + asUint64, + asUint8Array, + conactUint8Arrays, + uint8ArrayToNumber, +} from '../util' +import type { StubBytesCompat } from './primitives' +import { AlgoTsPrimitiveCls, arrayUtil, BigUintCls, Bytes, BytesCls, getUint8Array, isBytes, Uint64Cls } from './primitives' +import { Account, AccountCls, ApplicationCls, AssetCls } from './reference' +import type { ApplicationTransaction } from './transactions' const ABI_LENGTH_SIZE = 2 const maxBigIntValue = (bitSize: number) => 2n ** BigInt(bitSize) - 1n const maxBytesLength = (bitSize: number) => Math.floor(bitSize / BITS_IN_BYTE) -const encodeLength = (length: number) => new internal.primitives.BytesCls(encodingUtil.bigIntToUint8Array(BigInt(length), ABI_LENGTH_SIZE)) +const encodeLength = (length: number) => new BytesCls(encodingUtil.bigIntToUint8Array(BigInt(length), ABI_LENGTH_SIZE)) -type CompatForArc4Int = N extends 8 | 16 | 32 | 64 ? Uint64Compat : BigUintCompat +type CompatForArc4Int = N extends 8 | 16 | 24 | 32 | 40 | 48 | 56 | 64 ? Uint64Compat : BigUintCompat +const validBitSizes = [...Array(64).keys()].map((x) => (x + 1) * 8) export class UintNImpl extends UintN { private value: Uint8Array private bitSize: N @@ -49,7 +69,7 @@ export class UintNImpl extends UintN { this.typeInfo = typeof typeInfo === 'string' ? JSON.parse(typeInfo) : typeInfo this.bitSize = UintNImpl.getMaxBitsLength(this.typeInfo) as N - assert([8, 16, 32, 64, 128, 256, 512].includes(this.bitSize), `Invalid bit size ${this.bitSize}`) + assert(validBitSizes.includes(this.bitSize), `Invalid bit size ${this.bitSize}`) const bigIntValue = asBigUintCls(v ?? 0n).valueOf() const maxValue = maxBigIntValue(this.bitSize) @@ -69,13 +89,13 @@ export class UintNImpl extends UintN { equals(other: this): boolean { if (!(other instanceof UintNImpl) || JSON.stringify(this.typeInfo) !== JSON.stringify(other.typeInfo)) { - throw new internal.errors.CodeError(`Expected expression of type ${this.typeInfo.name}, got ${other.typeInfo.name}`) + throw new CodeError(`Expected expression of type ${this.typeInfo.name}, got ${other.typeInfo.name}`) } return this.bytes.equals(other.bytes) } static fromBytesImpl( - value: internal.primitives.StubBytesCompat | Uint8Array, + value: StubBytesCompat | Uint8Array, typeInfo: string | TypeInfo, prefix: 'none' | 'log' = 'none', ): UintNImpl { @@ -135,13 +155,13 @@ export class UFixedNxMImpl extends UFixedNx equals(other: this): boolean { if (!(other instanceof UFixedNxMImpl) || JSON.stringify(this.typeInfo) !== JSON.stringify(other.typeInfo)) { - throw new internal.errors.CodeError(`Expected expression of type ${this.typeInfo.name}, got ${other.typeInfo.name}`) + throw new CodeError(`Expected expression of type ${this.typeInfo.name}, got ${other.typeInfo.name}`) } return this.bytes.equals(other.bytes) } static fromBytesImpl( - value: internal.primitives.StubBytesCompat | Uint8Array, + value: StubBytesCompat | Uint8Array, typeInfo: string | TypeInfo, prefix: 'none' | 'log' = 'none', ): UFixedNxM { @@ -186,16 +206,12 @@ export class ByteImpl extends Byte { equals(other: this): boolean { if (!(other instanceof ByteImpl) || JSON.stringify(this.value.typeInfo) !== JSON.stringify(other.value.typeInfo)) { - throw new internal.errors.CodeError(`Expected expression of type ${this.value.typeInfo.name}, got ${other.value.typeInfo.name}`) + throw new CodeError(`Expected expression of type ${this.value.typeInfo.name}, got ${other.value.typeInfo.name}`) } return this.bytes.equals(other.bytes) } - static fromBytesImpl( - value: internal.primitives.StubBytesCompat | Uint8Array, - typeInfo: string | TypeInfo, - prefix: 'none' | 'log' = 'none', - ): ByteImpl { + static fromBytesImpl(value: StubBytesCompat | Uint8Array, typeInfo: string | TypeInfo, prefix: 'none' | 'log' = 'none'): ByteImpl { const uintNValue = UintNImpl.fromBytesImpl(value, typeInfo, prefix) as UintNImpl<8> const result = new ByteImpl(typeInfo) result.value = uintNValue @@ -228,16 +244,12 @@ export class StrImpl extends Str { equals(other: this): boolean { if (!(other instanceof StrImpl)) { - throw new internal.errors.CodeError(`Expected expression of type Str, got ${(other as object).constructor.name}`) + throw new CodeError(`Expected expression of type Str, got ${(other as object).constructor.name}`) } return this.bytes.equals(other.bytes) } - static fromBytesImpl( - value: internal.primitives.StubBytesCompat | Uint8Array, - typeInfo: string | TypeInfo, - prefix: 'none' | 'log' = 'none', - ): StrImpl { + static fromBytesImpl(value: StubBytesCompat | Uint8Array, typeInfo: string | TypeInfo, prefix: 'none' | 'log' = 'none'): StrImpl { let bytesValue = asBytesCls(value) if (prefix === 'log') { assert(bytesValue.slice(0, 4).equals(ABI_RETURN_VALUE_LOG_PREFIX), 'ABI return prefix not found') @@ -267,7 +279,7 @@ export class BoolImpl extends Bool { equals(other: this): boolean { if (!(other instanceof BoolImpl)) { - throw new internal.errors.CodeError(`Expected expression of type Bool, got ${(other as object).constructor.name}`) + throw new CodeError(`Expected expression of type Bool, got ${(other as object).constructor.name}`) } return this.bytes.equals(other.bytes) } @@ -276,11 +288,7 @@ export class BoolImpl extends Bool { return Bytes(this.value) } - static fromBytesImpl( - value: internal.primitives.StubBytesCompat | Uint8Array, - typeInfo: string | TypeInfo, - prefix: 'none' | 'log' = 'none', - ): BoolImpl { + static fromBytesImpl(value: StubBytesCompat | Uint8Array, typeInfo: string | TypeInfo, prefix: 'none' | 'log' = 'none'): BoolImpl { let bytesValue = asBytesCls(value) if (prefix === 'log') { assert(bytesValue.slice(0, 4).equals(ABI_RETURN_VALUE_LOG_PREFIX), 'ABI return prefix not found') @@ -303,15 +311,15 @@ const arrayProxyHandler = () => ({ get(target: { items: TItem[] }, prop: PropertyKey) { const idx = prop ? parseInt(prop.toString(), 10) : NaN if (!isNaN(idx)) { - if (idx < target.items.length) return target.items[idx] - internal.errors.avmError('Index out of bounds') + if (idx >= 0 && idx < target.items.length) return target.items[idx] + throw new AvmError('Index out of bounds') } else if (prop === Symbol.iterator) { return target.items[Symbol.iterator].bind(target.items) } else if (prop === 'entries') { return target.items.entries.bind(target.items) } else if (prop === 'at') { return (index: Uint64Compat): TItem => { - return internal.primitives.arrayUtil.arrayAt(target.items, index) + return arrayUtil.arrayAt(target.items, index) } } return Reflect.get(target, prop) @@ -319,11 +327,11 @@ const arrayProxyHandler = () => ({ set(target: { items: TItem[]; setItem: (index: number, value: TItem) => void }, prop: PropertyKey, value: TItem) { const idx = prop ? parseInt(prop.toString(), 10) : NaN if (!isNaN(idx)) { - if (idx < target.items.length) { + if (idx >= 0 && idx < target.items.length) { target.setItem(idx, value) return true } - internal.errors.avmError('Index out of bounds') + throw new AvmError('Index out of bounds') } return Reflect.set(target, prop, value) @@ -339,13 +347,13 @@ export class StaticArrayImpl constructor(typeInfo: TypeInfo | string, ...items: TItem[] & { length: TLength }) constructor(typeInfo: TypeInfo | string, ...items: TItem[]) constructor(typeInfo: TypeInfo | string, ...items: TItem[] & { length: TLength }) { - super(...items) + super(...(items as DeliberateAny)) this.typeInfo = typeof typeInfo === 'string' ? JSON.parse(typeInfo) : typeInfo this.genericArgs = this.typeInfo.genericArgs as StaticArrayGenericArgs this.size = parseInt(this.genericArgs.size.name, 10) if (items.length && items.length !== this.size) { - throw new internal.errors.CodeError(`expected ${this.size} items, not ${items.length}`) + throw new CodeError(`expected ${this.size} items, not ${items.length}`) } assert(areAllARC4Encoded(items), 'expected ARC4 type') @@ -365,7 +373,7 @@ export class StaticArrayImpl equals(other: this): boolean { if (!(other instanceof StaticArrayImpl) || JSON.stringify(this.typeInfo) !== JSON.stringify(other.typeInfo)) { - throw new internal.errors.CodeError(`Expected expression of type ${this.typeInfo.name}, got ${other.typeInfo.name}`) + throw new CodeError(`Expected expression of type ${this.typeInfo.name}, got ${other.typeInfo.name}`) } return this.bytes.equals(other.bytes) } @@ -384,7 +392,7 @@ export class StaticArrayImpl this.uint8ArrayValue = undefined return this.value } - throw new internal.errors.CodeError('value is not set') + throw new CodeError('value is not set') } setItem(index: number, value: TItem): void { @@ -395,12 +403,26 @@ export class StaticArrayImpl return StaticArrayImpl.fromBytesImpl(this.bytes, JSON.stringify(this.typeInfo)) as StaticArrayImpl } + concat(other: Parameters['concat']>[0]): DynamicArrayImpl { + const items = this.items + const otherEntries = other.entries() + let next = otherEntries.next() + while (!next.done) { + items.push(next.value[1] as TItem) + next = otherEntries.next() + } + return new DynamicArrayImpl( + { name: `DynamicArray<${this.genericArgs.elementType.name}>`, genericArgs: { elementType: this.genericArgs.elementType } }, + ...items, + ) + } + get native(): TItem[] { return this.items } static fromBytesImpl( - value: internal.primitives.StubBytesCompat | Uint8Array, + value: StubBytesCompat | Uint8Array, typeInfo: string | TypeInfo, prefix: 'none' | 'log' = 'none', ): StaticArrayImpl { @@ -420,7 +442,7 @@ export class StaticArrayImpl const childTypes = Array(arraySize).fill(genericArgs.elementType) let i = 0 let size = 0 - if (genericArgs.elementType.name === 'Bool') { + if (['Bool', 'boolean'].includes(genericArgs.elementType.name)) { while (i < childTypes.length) { const after = findBoolTypes(childTypes, i, 1) const boolNum = after + 1 @@ -444,19 +466,19 @@ export class AddressImpl extends Address { typeInfo: TypeInfo private value: StaticArrayImpl - constructor(typeInfo: TypeInfo | string, value?: Account | string | bytes) { + constructor(typeInfo: TypeInfo | string, value?: AccountType | string | bytes) { super(value) let uint8ArrayValue: Uint8Array if (value === undefined) { uint8ArrayValue = new Uint8Array(32) } else if (typeof value === 'string') { uint8ArrayValue = encodingUtil.base32ToUint8Array(value).slice(0, ALGORAND_ADDRESS_BYTE_LENGTH - ALGORAND_CHECKSUM_BYTE_LENGTH) - } else if (internal.primitives.isBytes(value)) { - uint8ArrayValue = internal.primitives.getUint8Array(value) + } else if (isBytes(value)) { + uint8ArrayValue = getUint8Array(value) } else { - uint8ArrayValue = internal.primitives.getUint8Array(value.bytes) + uint8ArrayValue = getUint8Array(value.bytes) } - internal.errors.avmInvariant(uint8ArrayValue.length === 32, 'Addresses should be 32 bytes') + avmInvariant(uint8ArrayValue.length === 32, 'Addresses should be 32 bytes') this.value = StaticArrayImpl.fromBytesImpl(uint8ArrayValue, typeInfo) as StaticArrayImpl this.typeInfo = typeof typeInfo === 'string' ? JSON.parse(typeInfo) : typeInfo @@ -469,7 +491,7 @@ export class AddressImpl extends Address { equals(other: this): boolean { if (!(other instanceof AddressImpl) || JSON.stringify(this.typeInfo) !== JSON.stringify(other.typeInfo)) { - throw new internal.errors.CodeError(`Expected expression of type ${this.typeInfo.name}, got ${other.typeInfo.name}`) + throw new CodeError(`Expected expression of type ${this.typeInfo.name}, got ${other.typeInfo.name}`) } return this.bytes.equals(other.bytes) } @@ -478,7 +500,7 @@ export class AddressImpl extends Address { return 32 } - get native(): Account { + get native(): AccountType { return Account(this.value.bytes) } @@ -487,14 +509,10 @@ export class AddressImpl extends Address { } setItem(_index: number, _value: ByteImpl): void { - throw new internal.errors.CodeError('Address is immutable') + throw new CodeError('Address is immutable') } - static fromBytesImpl( - value: internal.primitives.StubBytesCompat | Uint8Array, - typeInfo: string | TypeInfo, - prefix: 'none' | 'log' = 'none', - ): AddressImpl { + static fromBytesImpl(value: StubBytesCompat | Uint8Array, typeInfo: string | TypeInfo, prefix: 'none' | 'log' = 'none'): AddressImpl { const staticArrayValue = StaticArrayImpl.fromBytesImpl(value, typeInfo, prefix) as StaticArrayImpl const result = new AddressImpl(typeInfo) result.value = staticArrayValue @@ -519,7 +537,7 @@ export class DynamicArrayImpl extends DynamicArray extends DynamicArray extends DynamicArray extends DynamicArray['concat']>[0]): DynamicArrayImpl { + const items = this.items + const otherEntries = other.entries() + let next = otherEntries.next() + while (!next.done) { + items.push(next.value[1] as TItem) + next = otherEntries.next() + } + return new DynamicArrayImpl(this.typeInfo, ...items) + } + static fromBytesImpl( - value: internal.primitives.StubBytesCompat | Uint8Array, + value: StubBytesCompat | Uint8Array, typeInfo: string | TypeInfo, prefix: 'none' | 'log' = 'none', ): DynamicArrayImpl { @@ -637,7 +666,7 @@ export class TupleImpl extends T equals(other: this): boolean { if (!(other instanceof TupleImpl) || JSON.stringify(this.typeInfo) !== JSON.stringify(other.typeInfo)) { - throw new internal.errors.CodeError(`Expected expression of type ${this.typeInfo.name}, got ${other.typeInfo.name}`) + throw new CodeError(`Expected expression of type ${this.typeInfo.name}, got ${other.typeInfo.name}`) } return this.bytes.equals(other.bytes) } @@ -663,11 +692,11 @@ export class TupleImpl extends T this.uint8ArrayValue = undefined return this.value } - throw new internal.errors.CodeError('value is not set') + throw new CodeError('value is not set') } static fromBytesImpl( - value: internal.primitives.StubBytesCompat | Uint8Array, + value: StubBytesCompat | Uint8Array, typeInfo: string | TypeInfo, prefix: 'none' | 'log' = 'none', ): TupleImpl<[ARC4Encoded, ...ARC4Encoded[]]> { @@ -688,7 +717,7 @@ export class TupleImpl extends T while (i < genericArgs.length) { const childType = genericArgs[i] - if (childType.name === 'Bool') { + if (['Bool', 'boolean'].includes(childType.name)) { const after = findBoolTypes(genericArgs, i, 1) const boolNum = after + 1 size += Math.floor(boolNum / BITS_IN_BYTE) @@ -760,6 +789,10 @@ export class StructImpl extends (Struct { + return StructImpl.fromBytesImpl(this.bytes, JSON.stringify(this.typeInfo)) as StructImpl + } + private decodeAsProperties() { if (this.uint8ArrayValue) { const values = decode(this.uint8ArrayValue, Object.values(this.genericArgs)) @@ -771,7 +804,7 @@ export class StructImpl extends (Struct { @@ -789,6 +822,27 @@ export class StructImpl extends (Struct) return `(${genericArgs.map(getArc4TypeName).join(',')})` } + + static getMaxBytesLength(typeInfo: TypeInfo): number { + const genericArgs = Object.values(typeInfo.genericArgs as Record) + let i = 0 + let size = 0 + + while (i < genericArgs.length) { + const childType = genericArgs[i] + if (['Bool', 'boolean'].includes(childType.name)) { + const after = findBoolTypes(genericArgs, i, 1) + const boolNum = after + 1 + size += Math.floor(boolNum / BITS_IN_BYTE) + size += boolNum % BITS_IN_BYTE ? 1 : 0 + i += after + } else { + size += getMaxLengthOfStaticContentType(childType) + } + i += 1 + } + return size + } } export class DynamicBytesImpl extends DynamicBytes { @@ -809,7 +863,7 @@ export class DynamicBytesImpl extends DynamicBytes { equals(other: this): boolean { if (!(other instanceof DynamicBytesImpl) || JSON.stringify(this.typeInfo) !== JSON.stringify(other.typeInfo)) { - throw new internal.errors.CodeError(`Expected expression of type ${this.typeInfo.name}, got ${other.typeInfo.name}`) + throw new CodeError(`Expected expression of type ${this.typeInfo.name}, got ${other.typeInfo.name}`) } return this.bytes.equals(other.bytes) } @@ -827,11 +881,25 @@ export class DynamicBytesImpl extends DynamicBytes { } setItem(_index: number, _value: ByteImpl): void { - throw new internal.errors.CodeError('DynamicBytes is immutable') + throw new CodeError('DynamicBytes is immutable') + } + + concat(other: Parameters['concat']>[0]): DynamicBytesImpl { + const items = this.items + const otherEntries = other.entries() + let next = otherEntries.next() + while (!next.done) { + items.push(next.value[1] as ByteImpl) + next = otherEntries.next() + } + const concatenatedBytes = items + .map((item) => item.bytes) + .reduce((acc, curr) => conactUint8Arrays(acc, asUint8Array(curr)), new Uint8Array()) + return new DynamicBytesImpl(this.typeInfo, asBytes(concatenatedBytes)) } static fromBytesImpl( - value: internal.primitives.StubBytesCompat | Uint8Array, + value: StubBytesCompat | Uint8Array, typeInfo: string | TypeInfo, prefix: 'none' | 'log' = 'none', ): DynamicBytesImpl { @@ -864,7 +932,7 @@ export class StaticBytesImpl extends StaticBytes { equals(other: this): boolean { if (!(other instanceof StaticBytesImpl) || JSON.stringify(this.typeInfo) !== JSON.stringify(other.typeInfo)) { - throw new internal.errors.CodeError(`Expected expression of type ${this.typeInfo.name}, got ${other.typeInfo.name}`) + throw new CodeError(`Expected expression of type ${this.typeInfo.name}, got ${other.typeInfo.name}`) } return this.bytes.equals(other.bytes) } @@ -882,14 +950,24 @@ export class StaticBytesImpl extends StaticBytes { } setItem(_index: number, _value: ByteImpl): void { - throw new internal.errors.CodeError('StaticBytes is immutable') + throw new CodeError('StaticBytes is immutable') } - static fromBytesImpl( - value: internal.primitives.StubBytesCompat | Uint8Array, - typeInfo: string | TypeInfo, - prefix: 'none' | 'log' = 'none', - ): StaticBytesImpl { + concat(other: Parameters['concat']>[0]): DynamicBytesImpl { + const items = this.items + const otherEntries = other.entries() + let next = otherEntries.next() + while (!next.done) { + items.push(next.value[1] as ByteImpl) + next = otherEntries.next() + } + const concatenatedBytes = items + .map((item) => item.bytes) + .reduce((acc, curr) => conactUint8Arrays(acc, asUint8Array(curr)), new Uint8Array()) + return new DynamicBytesImpl(this.typeInfo, asBytes(concatenatedBytes)) + } + + static fromBytesImpl(value: StubBytesCompat | Uint8Array, typeInfo: string | TypeInfo, prefix: 'none' | 'log' = 'none'): StaticBytesImpl { const staticArrayValue = StaticArrayImpl.fromBytesImpl(value, typeInfo, prefix) as StaticArrayImpl const result = new StaticBytesImpl(typeInfo) result.value = staticArrayValue @@ -925,12 +1003,12 @@ const decode = (value: Uint8Array, childTypes: TypeInfo[]) => { dynamicSegments.push([dynamicIndex, -1]) valuePartitions.push(new Uint8Array()) arrayIndex += ABI_LENGTH_SIZE - } else if (childType.name === 'Bool') { + } else if (['Bool', 'boolean'].includes(childType.name)) { const before = findBoolTypes(childTypes, i, -1) let after = findBoolTypes(childTypes, i, 1) if (before % 8 != 0) { - throw new internal.errors.CodeError('"expected before index should have number of bool mod 8 equal 0"') + throw new CodeError('"expected before index should have number of bool mod 8 equal 0"') } after = Math.min(7, after) const bits = uint8ArrayToNumber(value.slice(arrayIndex, arrayIndex + 1)) @@ -951,7 +1029,7 @@ const decode = (value: Uint8Array, childTypes: TypeInfo[]) => { } if (arrayIndex >= value.length && i != childTypes.length - 1) { - throw new internal.errors.CodeError('input string is not long enough to be decoded') + throw new CodeError('input string is not long enough to be decoded') } i += 1 } @@ -961,7 +1039,7 @@ const decode = (value: Uint8Array, childTypes: TypeInfo[]) => { arrayIndex = value.length } if (arrayIndex < value.length) { - throw new internal.errors.CodeError('input string was not fully consumed') + throw new CodeError('input string was not fully consumed') } // Check dynamic element partitions @@ -987,7 +1065,7 @@ const findBoolTypes = (values: TypeInfo[], index: number, delta: number): number const length = values.length while (true) { const curr = index + delta * until - if (values[curr].name === 'Bool') { + if (['Bool', 'boolean'].includes(values[curr].name)) { if ((curr != length - 1 && delta > 0) || (curr > 0 && delta < 0)) { until += 1 } else { @@ -1003,6 +1081,12 @@ const findBoolTypes = (values: TypeInfo[], index: number, delta: number): number const getMaxLengthOfStaticContentType = (type: TypeInfo): number => { switch (trimGenericTypeName(type.name)) { + case 'uint64': + return UINT64_SIZE / BITS_IN_BYTE + case 'biguint': + return UINT512_SIZE / BITS_IN_BYTE + case 'boolean': + return 1 case 'Address': return AddressImpl.getMaxBytesLength(type) case 'Byte': @@ -1017,8 +1101,10 @@ const getMaxLengthOfStaticContentType = (type: TypeInfo): number => { return StaticBytesImpl.getMaxBytesLength(type) case 'Tuple': return TupleImpl.getMaxBytesLength(type) + case 'Struct': + return StructImpl.getMaxBytesLength(type) } - throw new internal.errors.CodeError(`unsupported type ${type.name}`) + throw new CodeError(`unsupported type ${type.name}`) } const encode = (values: ARC4Encoded[]) => { @@ -1040,7 +1126,7 @@ const encode = (values: ARC4Encoded[]) => { const before = findBool(values, i, -1) let after = findBool(values, i, 1) if (before % 8 != 0) { - throw new internal.errors.CodeError('"expected before index should have number of bool mod 8 equal 0"') + throw new CodeError('"expected before index should have number of bool mod 8 equal 0"') } after = Math.min(7, after) const consecutiveBools = values.slice(i, i + after + 1) as Bool[] @@ -1135,7 +1221,7 @@ const holdsDynamicLengthContent = (value: StaticArrayImpl | export function interpretAsArc4Impl( typeInfoString: string, - bytes: internal.primitives.StubBytesCompat, + bytes: StubBytesCompat, prefix: 'none' | 'log' = 'none', ): T { const typeInfo = JSON.parse(typeInfoString) @@ -1185,11 +1271,7 @@ export const getArc4TypeName = (typeInfo: TypeInfo): string | undefined => { return undefined } -export function decodeArc4Impl( - sourceTypeInfoString: string, - bytes: internal.primitives.StubBytesCompat, - prefix: 'none' | 'log' = 'none', -): T { +export function decodeArc4Impl(sourceTypeInfoString: string, bytes: StubBytesCompat, prefix: 'none' | 'log' = 'none'): T { const sourceTypeInfo = JSON.parse(sourceTypeInfoString) const encoder = getArc4Encoder(sourceTypeInfo) const source = encoder(bytes, sourceTypeInfo, prefix) @@ -1205,7 +1287,7 @@ const getNativeValue = (value: DeliberateAny): DeliberateAny => { const native = (value as DeliberateAny).native if (Array.isArray(native)) { return native.map((item) => getNativeValue(item)) - } else if (native instanceof internal.primitives.AlgoTsPrimitiveCls) { + } else if (native instanceof AlgoTsPrimitiveCls) { return native } else if (typeof native === 'object') { return Object.fromEntries(Object.entries(native).map(([key, value]) => [key, getNativeValue(value)])) @@ -1232,16 +1314,16 @@ export const getArc4Encoded = (value: DeliberateAny): ARC4Encoded => { if (typeof value === 'boolean') { return new BoolImpl({ name: 'Bool' }, value) } - if (value instanceof internal.primitives.Uint64Cls || typeof value === 'number') { + if (value instanceof Uint64Cls || typeof value === 'number') { return new UintNImpl({ name: 'UintN<64>', genericArgs: [{ name: '64' }] }, asBigInt(value)) } - if (value instanceof internal.primitives.BigUintCls) { + if (value instanceof BigUintCls) { return new UintNImpl({ name: 'UintN<512>', genericArgs: [{ name: '512' }] }, value.asBigInt()) } if (typeof value === 'bigint') { return new UintNImpl({ name: 'UintN<512>', genericArgs: [{ name: '512' }] }, value) } - if (value instanceof internal.primitives.BytesCls) { + if (value instanceof BytesCls) { return new DynamicBytesImpl( { name: 'DynamicBytes', genericArgs: { elementType: { name: 'Byte', genericArgs: [{ name: '8' }] } } }, value.asAlgoTs(), @@ -1270,5 +1352,10 @@ export const getArc4Encoded = (value: DeliberateAny): ARC4Encoded => { return new StructImpl(typeInfo, Object.fromEntries(Object.keys(value).map((x, i) => [x, result[i]]))) } - throw internal.errors.codeError(`Unsupported type for encoding: ${typeof value}`) + throw new CodeError(`Unsupported type for encoding: ${typeof value}`) +} + +export const arc4EncodedLengthImpl = (typeInfoString: string): uint64 => { + const typeInfo = JSON.parse(typeInfoString) + return getMaxLengthOfStaticContentType(typeInfo) } diff --git a/src/impl/ensure-budget.ts b/src/impl/ensure-budget.ts index 3ebb307..834d023 100644 --- a/src/impl/ensure-budget.ts +++ b/src/impl/ensure-budget.ts @@ -1,4 +1,5 @@ -import { OpUpFeeSource, uint64 } from '@algorandfoundation/algorand-typescript' +import type { uint64 } from '@algorandfoundation/algorand-typescript' +import { OpUpFeeSource } from '@algorandfoundation/algorand-typescript' export function ensureBudgetImpl(_budget: uint64, _feeSource: OpUpFeeSource = OpUpFeeSource.GroupCredit) { // ensureBudget function is emulated to be a no-op diff --git a/src/impl/global.ts b/src/impl/global.ts index 393cc88..61ecf41 100644 --- a/src/impl/global.ts +++ b/src/impl/global.ts @@ -1,4 +1,5 @@ -import { Account, Application, Bytes, bytes, internal, op, Uint64, uint64 } from '@algorandfoundation/algorand-typescript' +import type { Account as AccountType, Application as ApplicationType, bytes, op, uint64 } from '@algorandfoundation/algorand-typescript' +import { encodingUtil } from '@algorandfoundation/puya-ts' import { DEFAULT_ACCOUNT_MIN_BALANCE, DEFAULT_ASSET_CREATE_MIN_BALANCE, @@ -9,13 +10,17 @@ import { ZERO_ADDRESS, } from '../constants' import { lazyContext } from '../context-helpers/internal-context' -import { getApplicationAddress, getObjectReference } from '../util' +import { InternalError } from '../errors' +import { getObjectReference } from '../util' +import { sha256 } from './crypto' +import { Bytes, Uint64 } from './primitives' +import { Account, getApplicationAddress } from './reference' export class GlobalData { minTxnFee: uint64 minBalance: uint64 maxTxnLife: uint64 - zeroAddress: Account + zeroAddress: AccountType logicSigVersion?: uint64 round?: uint64 latestTimestamp?: uint64 @@ -25,6 +30,10 @@ export class GlobalData { assetOptInMinBalance: uint64 genesisHash: bytes opcodeBudget?: uint64 + payoutsEnabled: boolean + payoutsGoOnlineFee: uint64 + payoutsPercent: uint64 + payoutsMinBalance: uint64 constructor() { this.minTxnFee = Uint64(MIN_TXN_FEE) @@ -35,6 +44,10 @@ export class GlobalData { this.assetCreateMinBalance = Uint64(DEFAULT_ASSET_CREATE_MIN_BALANCE) this.assetOptInMinBalance = Uint64(DEFAULT_ASSET_OPT_IN_MIN_BALANCE) this.genesisHash = DEFAULT_GLOBAL_GENESIS_HASH + this.payoutsEnabled = false + this.payoutsGoOnlineFee = Uint64(0) + this.payoutsPercent = Uint64(0) + this.payoutsMinBalance = Uint64(0) } } const getGlobalData = (): GlobalData => { @@ -44,7 +57,7 @@ const getGlobalData = (): GlobalData => { const getMissingValueErrorMessage = (name: keyof GlobalData) => `'Global' object has no value set for attribute named '${name}'. Use \`context.ledger.patchGlobalData({${name}: your_value})\` to set the value in your test setup."` -export const Global: internal.opTypes.GlobalType = { +export const Global: typeof op.Global = { /** * microalgos */ @@ -69,7 +82,7 @@ export const Global: internal.opTypes.GlobalType = { /** * 32 byte address of all zero bytes */ - get zeroAddress(): Account { + get zeroAddress(): AccountType { return getGlobalData().zeroAddress }, @@ -87,11 +100,11 @@ export const Global: internal.opTypes.GlobalType = { get logicSigVersion(): uint64 { const data = getGlobalData() if (data.logicSigVersion !== undefined) return data.logicSigVersion - throw new internal.errors.InternalError(getMissingValueErrorMessage('logicSigVersion')) + throw new InternalError(getMissingValueErrorMessage('logicSigVersion')) }, /** - * Current round number. Application mode only. + * Current round number. ApplicationType mode only. */ get round(): uint64 { const data = getGlobalData() @@ -100,7 +113,7 @@ export const Global: internal.opTypes.GlobalType = { }, /** - * Last confirmed block UNIX timestamp. Fails if negative. Application mode only. + * Last confirmed block UNIX timestamp. Fails if negative. ApplicationType mode only. */ get latestTimestamp(): uint64 { const data = getGlobalData() @@ -109,24 +122,24 @@ export const Global: internal.opTypes.GlobalType = { }, /** - * ID of current application executing. Application mode only. + * ID of current application executing. ApplicationType mode only. */ - get currentApplicationId(): Application { + get currentApplicationId(): ApplicationType { return lazyContext.activeApplication }, /** - * Address of the creator of the current application. Application mode only. + * Address of the creator of the current application. ApplicationType mode only. */ - get creatorAddress(): Account { + get creatorAddress(): AccountType { const app = lazyContext.activeApplication return app.creator }, /** - * Address that the current application controls. Application mode only. + * Address that the current application controls. ApplicationType mode only. */ - get currentApplicationAddress(): Account { + get currentApplicationAddress(): AccountType { return this.currentApplicationId.address }, @@ -137,8 +150,8 @@ export const Global: internal.opTypes.GlobalType = { const data = getGlobalData() if (data.groupId !== undefined) return data.groupId const reference = getObjectReference(lazyContext.activeGroup) - const referenceBytes = Bytes(internal.encodingUtil.bigIntToUint8Array(reference)) - return op.sha256(referenceBytes) + const referenceBytes = Bytes(encodingUtil.bigIntToUint8Array(reference)) + return sha256(referenceBytes) }, /** @@ -147,20 +160,20 @@ export const Global: internal.opTypes.GlobalType = { get opcodeBudget(): uint64 { const data = getGlobalData() if (data.opcodeBudget !== undefined) return data.opcodeBudget - throw new internal.errors.InternalError(getMissingValueErrorMessage('opcodeBudget')) + throw new InternalError(getMissingValueErrorMessage('opcodeBudget')) }, /** - * The application ID of the application that called this application. 0 if this application is at the top-level. Application mode only. + * The application ID of the application that called this application. 0 if this application is at the top-level. ApplicationType mode only. */ get callerApplicationId(): uint64 { return getGlobalData().callerApplicationId }, /** - * The application address of the application that called this application. ZeroAddress if this application is at the top-level. Application mode only. + * The application address of the application that called this application. ZeroAddress if this application is at the top-level. ApplicationType mode only. */ - get callerApplicationAddress(): Account { + get callerApplicationAddress(): AccountType { return getApplicationAddress(this.callerApplicationId) }, @@ -184,10 +197,44 @@ export const Global: internal.opTypes.GlobalType = { get genesisHash(): bytes { return getGlobalData().genesisHash }, - payoutsEnabled: false, - // TODO: implement v11 fields - payoutsGoOnlineFee: 0, - payoutsPercent: 0, - payoutsMinBalance: 0, - payoutsMaxBalance: 0, + + /** + * Whether block proposal payouts are enabled. + * Min AVM version: 11 + */ + get payoutsEnabled(): boolean { + return getGlobalData().payoutsEnabled + }, + + /** + * The fee required in a keyreg transaction to make an account incentive eligible. + * Min AVM version: 11 + */ + get payoutsGoOnlineFee(): uint64 { + return getGlobalData().payoutsGoOnlineFee + }, + + /** + * The percentage of transaction fees in a block that can be paid to the block proposer. + * Min AVM version: 11 + */ + get payoutsPercent(): uint64 { + return getGlobalData().payoutsPercent + }, + + /** + * The minimum algo balance an account must have in the agreement round to receive block payouts in the proposal round. + * Min AVM version: 11 + */ + get payoutsMinBalance(): uint64 { + return getGlobalData().payoutsMinBalance + }, + + /** + * The maximum algo balance an account can have in the agreement round to receive block payouts in the proposal round. + * Min AVM version: 11 + */ + get payoutsMaxBalance(): uint64 { + return getGlobalData().payoutsMinBalance + }, } diff --git a/src/impl/gtxn.ts b/src/impl/gtxn.ts index fb491b1..636f45d 100644 --- a/src/impl/gtxn.ts +++ b/src/impl/gtxn.ts @@ -1,211 +1,221 @@ -import { Account, Application, arc4, Asset, bytes, internal, uint64 } from '@algorandfoundation/algorand-typescript' +import type { Account, Application, Asset, bytes, op, uint64 } from '@algorandfoundation/algorand-typescript' +import { OnCompleteAction } from '@algorandfoundation/algorand-typescript' import { lazyContext } from '../context-helpers/internal-context' import { asUint64, asUint64Cls } from '../util' +import type { StubUint64Compat } from './primitives' -export const GTxn: internal.opTypes.GTxnType = { - sender(t: internal.primitives.StubUint64Compat): Account { +export const GTxn: typeof op.GTxn = { + sender(t: StubUint64Compat): Account { return lazyContext.activeGroup.getTransaction(t).sender }, - fee(t: internal.primitives.StubUint64Compat): uint64 { + fee(t: StubUint64Compat): uint64 { return lazyContext.activeGroup.getTransaction(t).fee }, - firstValid(t: internal.primitives.StubUint64Compat): uint64 { + firstValid(t: StubUint64Compat): uint64 { return lazyContext.activeGroup.getTransaction(t).firstValid }, - firstValidTime(t: internal.primitives.StubUint64Compat): uint64 { + firstValidTime(t: StubUint64Compat): uint64 { return lazyContext.activeGroup.getTransaction(t).firstValidTime }, - lastValid(t: internal.primitives.StubUint64Compat): uint64 { + lastValid(t: StubUint64Compat): uint64 { return lazyContext.activeGroup.getTransaction(t).lastValid }, - note(t: internal.primitives.StubUint64Compat): bytes { + note(t: StubUint64Compat): bytes { return lazyContext.activeGroup.getTransaction(t).note }, - lease(t: internal.primitives.StubUint64Compat): bytes { + lease(t: StubUint64Compat): bytes { return lazyContext.activeGroup.getTransaction(t).lease }, - receiver(t: internal.primitives.StubUint64Compat): Account { + receiver(t: StubUint64Compat): Account { return lazyContext.activeGroup.getPaymentTransaction(t).receiver }, amount(t: uint64): uint64 { return lazyContext.activeGroup.getPaymentTransaction(t).amount }, - closeRemainderTo(t: internal.primitives.StubUint64Compat): Account { + closeRemainderTo(t: StubUint64Compat): Account { return lazyContext.activeGroup.getPaymentTransaction(t).closeRemainderTo }, - votePk(t: internal.primitives.StubUint64Compat): bytes { + votePk(t: StubUint64Compat): bytes { return lazyContext.activeGroup.getKeyRegistrationTransaction(t).voteKey }, - selectionPk(t: internal.primitives.StubUint64Compat): bytes { + selectionPk(t: StubUint64Compat): bytes { return lazyContext.activeGroup.getKeyRegistrationTransaction(t).selectionKey }, - voteFirst(t: internal.primitives.StubUint64Compat): uint64 { + voteFirst(t: StubUint64Compat): uint64 { return lazyContext.activeGroup.getKeyRegistrationTransaction(t).voteFirst }, - voteLast(t: internal.primitives.StubUint64Compat): uint64 { + voteLast(t: StubUint64Compat): uint64 { return lazyContext.activeGroup.getKeyRegistrationTransaction(t).voteLast }, - voteKeyDilution(t: internal.primitives.StubUint64Compat): uint64 { + voteKeyDilution(t: StubUint64Compat): uint64 { return lazyContext.activeGroup.getKeyRegistrationTransaction(t).voteKeyDilution }, - type(t: internal.primitives.StubUint64Compat): bytes { + type(t: StubUint64Compat): bytes { return asUint64Cls(lazyContext.activeGroup.getTransaction(t).type).toBytes().asAlgoTs() }, typeEnum(t: uint64): uint64 { return asUint64(lazyContext.activeGroup.getTransaction(t).type) }, - xferAsset(t: internal.primitives.StubUint64Compat): Asset { + xferAsset(t: StubUint64Compat): Asset { return lazyContext.activeGroup.getAssetTransferTransaction(t).xferAsset }, - assetAmount(t: internal.primitives.StubUint64Compat): uint64 { + assetAmount(t: StubUint64Compat): uint64 { return lazyContext.activeGroup.getAssetTransferTransaction(t).assetAmount }, - assetSender(t: internal.primitives.StubUint64Compat): Account { + assetSender(t: StubUint64Compat): Account { return lazyContext.activeGroup.getAssetTransferTransaction(t).assetSender }, - assetReceiver(t: internal.primitives.StubUint64Compat): Account { + assetReceiver(t: StubUint64Compat): Account { return lazyContext.activeGroup.getAssetTransferTransaction(t).assetReceiver }, - assetCloseTo(t: internal.primitives.StubUint64Compat): Account { + assetCloseTo(t: StubUint64Compat): Account { return lazyContext.activeGroup.getAssetTransferTransaction(t).assetCloseTo }, - groupIndex(t: internal.primitives.StubUint64Compat): uint64 { + groupIndex(t: StubUint64Compat): uint64 { return lazyContext.activeGroup.getTransaction(t).groupIndex }, - txId(t: internal.primitives.StubUint64Compat): bytes { + txId(t: StubUint64Compat): bytes { return lazyContext.activeGroup.getTransaction(t).txnId }, - applicationId(t: internal.primitives.StubUint64Compat): Application { + applicationId(t: StubUint64Compat): Application { return lazyContext.activeGroup.getApplicationTransaction(t).appId }, - onCompletion(t: internal.primitives.StubUint64Compat): uint64 { + onCompletion(t: StubUint64Compat): uint64 { const onCompletionStr = lazyContext.activeGroup.getApplicationTransaction(t).onCompletion - return asUint64(arc4.OnCompleteAction[onCompletionStr]) + return asUint64(OnCompleteAction[onCompletionStr]) }, - applicationArgs(a: internal.primitives.StubUint64Compat, b: internal.primitives.StubUint64Compat): bytes { + applicationArgs(a: StubUint64Compat, b: StubUint64Compat): bytes { return lazyContext.activeGroup.getApplicationTransaction(a).appArgs(asUint64(b)) }, - numAppArgs(t: internal.primitives.StubUint64Compat): uint64 { + numAppArgs(t: StubUint64Compat): uint64 { return lazyContext.activeGroup.getApplicationTransaction(t).numAppArgs }, - accounts(a: internal.primitives.StubUint64Compat, b: internal.primitives.StubUint64Compat): Account { + accounts(a: StubUint64Compat, b: StubUint64Compat): Account { return lazyContext.activeGroup.getApplicationTransaction(a).accounts(asUint64(b)) }, - numAccounts(t: internal.primitives.StubUint64Compat): uint64 { + numAccounts(t: StubUint64Compat): uint64 { return lazyContext.activeGroup.getApplicationTransaction(t).numAccounts }, - approvalProgram(t: internal.primitives.StubUint64Compat): bytes { + approvalProgram(t: StubUint64Compat): bytes { return lazyContext.activeGroup.getApplicationTransaction(t).approvalProgram }, - clearStateProgram(t: internal.primitives.StubUint64Compat): bytes { + clearStateProgram(t: StubUint64Compat): bytes { return lazyContext.activeGroup.getApplicationTransaction(t).clearStateProgram }, - rekeyTo(t: internal.primitives.StubUint64Compat): Account { + rekeyTo(t: StubUint64Compat): Account { return lazyContext.activeGroup.getTransaction(t).rekeyTo }, - configAsset(t: internal.primitives.StubUint64Compat): Asset { + configAsset(t: StubUint64Compat): Asset { return lazyContext.activeGroup.getAssetConfigTransaction(t).configAsset }, - configAssetTotal(t: internal.primitives.StubUint64Compat): uint64 { + configAssetTotal(t: StubUint64Compat): uint64 { return lazyContext.activeGroup.getAssetConfigTransaction(t).total }, - configAssetDecimals(t: internal.primitives.StubUint64Compat): uint64 { + configAssetDecimals(t: StubUint64Compat): uint64 { return lazyContext.activeGroup.getAssetConfigTransaction(t).decimals }, - configAssetDefaultFrozen(t: internal.primitives.StubUint64Compat): boolean { + configAssetDefaultFrozen(t: StubUint64Compat): boolean { return lazyContext.activeGroup.getAssetConfigTransaction(t).defaultFrozen }, - configAssetUnitName(t: internal.primitives.StubUint64Compat): bytes { + configAssetUnitName(t: StubUint64Compat): bytes { return lazyContext.activeGroup.getAssetConfigTransaction(t).unitName }, - configAssetName(t: internal.primitives.StubUint64Compat): bytes { + configAssetName(t: StubUint64Compat): bytes { return lazyContext.activeGroup.getAssetConfigTransaction(t).assetName }, - configAssetUrl(t: internal.primitives.StubUint64Compat): bytes { + configAssetUrl(t: StubUint64Compat): bytes { return lazyContext.activeGroup.getAssetConfigTransaction(t).url }, - configAssetMetadataHash(t: internal.primitives.StubUint64Compat): bytes { + configAssetMetadataHash(t: StubUint64Compat): bytes { return lazyContext.activeGroup.getAssetConfigTransaction(t).metadataHash }, - configAssetManager(t: internal.primitives.StubUint64Compat): Account { + configAssetManager(t: StubUint64Compat): Account { return lazyContext.activeGroup.getAssetConfigTransaction(t).manager }, - configAssetReserve(t: internal.primitives.StubUint64Compat): Account { + configAssetReserve(t: StubUint64Compat): Account { return lazyContext.activeGroup.getAssetConfigTransaction(t).reserve }, - configAssetFreeze(t: internal.primitives.StubUint64Compat): Account { + configAssetFreeze(t: StubUint64Compat): Account { return lazyContext.activeGroup.getAssetConfigTransaction(t).freeze }, - configAssetClawback(t: internal.primitives.StubUint64Compat): Account { + configAssetClawback(t: StubUint64Compat): Account { return lazyContext.activeGroup.getAssetConfigTransaction(t).clawback }, - freezeAsset(t: internal.primitives.StubUint64Compat): Asset { + freezeAsset(t: StubUint64Compat): Asset { return lazyContext.activeGroup.getAssetFreezeTransaction(t).freezeAsset }, - freezeAssetAccount(t: internal.primitives.StubUint64Compat): Account { + freezeAssetAccount(t: StubUint64Compat): Account { return lazyContext.activeGroup.getAssetFreezeTransaction(t).freezeAccount }, - freezeAssetFrozen(t: internal.primitives.StubUint64Compat): boolean { + freezeAssetFrozen(t: StubUint64Compat): boolean { return lazyContext.activeGroup.getAssetFreezeTransaction(t).frozen }, - assets(a: internal.primitives.StubUint64Compat, b: internal.primitives.StubUint64Compat): Asset { + assets(a: StubUint64Compat, b: StubUint64Compat): Asset { return lazyContext.activeGroup.getApplicationTransaction(a).assets(asUint64(b)) }, - numAssets(t: internal.primitives.StubUint64Compat): uint64 { + numAssets(t: StubUint64Compat): uint64 { return lazyContext.activeGroup.getApplicationTransaction(t).numAssets }, - applications(a: internal.primitives.StubUint64Compat, b: internal.primitives.StubUint64Compat): Application { + applications(a: StubUint64Compat, b: StubUint64Compat): Application { return lazyContext.activeGroup.getApplicationTransaction(a).apps(asUint64(b)) }, - numApplications(t: internal.primitives.StubUint64Compat): uint64 { + numApplications(t: StubUint64Compat): uint64 { return lazyContext.activeGroup.getApplicationTransaction(t).numApps }, - globalNumUint(t: internal.primitives.StubUint64Compat): uint64 { + globalNumUint(t: StubUint64Compat): uint64 { return lazyContext.activeGroup.getApplicationTransaction(t).globalNumUint }, - globalNumByteSlice(t: internal.primitives.StubUint64Compat): uint64 { + globalNumByteSlice(t: StubUint64Compat): uint64 { return lazyContext.activeGroup.getApplicationTransaction(t).globalNumBytes }, - localNumUint(t: internal.primitives.StubUint64Compat): uint64 { + localNumUint(t: StubUint64Compat): uint64 { return lazyContext.activeGroup.getApplicationTransaction(t).localNumUint }, - localNumByteSlice(t: internal.primitives.StubUint64Compat): uint64 { + localNumByteSlice(t: StubUint64Compat): uint64 { return lazyContext.activeGroup.getApplicationTransaction(t).localNumBytes }, - extraProgramPages(t: internal.primitives.StubUint64Compat): uint64 { + extraProgramPages(t: StubUint64Compat): uint64 { return lazyContext.activeGroup.getApplicationTransaction(t).extraProgramPages }, - nonparticipation(t: internal.primitives.StubUint64Compat): boolean { + nonparticipation(t: StubUint64Compat): boolean { return lazyContext.activeGroup.getKeyRegistrationTransaction(t).nonparticipation }, - logs(a: internal.primitives.StubUint64Compat, b: internal.primitives.StubUint64Compat): bytes { + logs(a: StubUint64Compat, b: StubUint64Compat): bytes { return lazyContext.activeGroup.getApplicationTransaction(a).logs(asUint64(b)) }, - numLogs(t: internal.primitives.StubUint64Compat): uint64 { + numLogs(t: StubUint64Compat): uint64 { return lazyContext.activeGroup.getApplicationTransaction(t).numLogs }, - createdAssetId(t: internal.primitives.StubUint64Compat): Asset { + createdAssetId(t: StubUint64Compat): Asset { return lazyContext.activeGroup.getAssetConfigTransaction(t).createdAsset }, - createdApplicationId(t: internal.primitives.StubUint64Compat): Application { + createdApplicationId(t: StubUint64Compat): Application { return lazyContext.activeGroup.getApplicationTransaction(t).createdApp }, - lastLog(t: internal.primitives.StubUint64Compat): bytes { + lastLog(t: StubUint64Compat): bytes { return lazyContext.activeGroup.getApplicationTransaction(t).lastLog }, - stateProofPk(t: internal.primitives.StubUint64Compat): bytes { + stateProofPk(t: StubUint64Compat): bytes { return lazyContext.activeGroup.getKeyRegistrationTransaction(t).stateProofKey }, - approvalProgramPages(a: internal.primitives.StubUint64Compat, b: internal.primitives.StubUint64Compat): bytes { + approvalProgramPages(a: StubUint64Compat, b: StubUint64Compat): bytes { return lazyContext.activeGroup.getApplicationTransaction(a).approvalProgramPages(asUint64(b)) }, - numApprovalProgramPages(t: internal.primitives.StubUint64Compat): uint64 { + numApprovalProgramPages(t: StubUint64Compat): uint64 { return lazyContext.activeGroup.getApplicationTransaction(t).numApprovalProgramPages }, - clearStateProgramPages(a: internal.primitives.StubUint64Compat, b: internal.primitives.StubUint64Compat): bytes { + clearStateProgramPages(a: StubUint64Compat, b: StubUint64Compat): bytes { return lazyContext.activeGroup.getApplicationTransaction(a).clearStateProgramPages(asUint64(b)) }, - numClearStateProgramPages(t: internal.primitives.StubUint64Compat): uint64 { + numClearStateProgramPages(t: StubUint64Compat): uint64 { return lazyContext.activeGroup.getApplicationTransaction(t).numClearStateProgramPages }, } + +export const Transaction = (index: uint64) => lazyContext.txn.activeGroup.getTransaction(index) +export const PaymentTxn = (index: uint64) => lazyContext.txn.activeGroup.getPaymentTransaction(index) +export const KeyRegistrationTxn = (index: uint64) => lazyContext.txn.activeGroup.getKeyRegistrationTransaction(index) +export const AssetConfigTxn = (index: uint64) => lazyContext.txn.activeGroup.getAssetConfigTransaction(index) +export const AssetTransferTxn = (index: uint64) => lazyContext.txn.activeGroup.getAssetTransferTransaction(index) +export const AssetFreezeTxn = (index: uint64) => lazyContext.txn.activeGroup.getAssetFreezeTransaction(index) +export const ApplicationTxn = (index: uint64) => lazyContext.txn.activeGroup.getApplicationTransaction(index) diff --git a/src/impl/index.ts b/src/impl/index.ts index 42bd62b..4ae52bd 100644 --- a/src/impl/index.ts +++ b/src/impl/index.ts @@ -11,6 +11,9 @@ export { Global } from './global' export { GTxn } from './gtxn' export { GITxn, ITxn, ITxnCreate } from './itxn' export { arg } from './logicSigArg' +export { onlineStake } from './online-stake' export * from './pure' export { gloadBytes, gloadUint64, Scratch } from './scratch' export { gaid, Txn } from './txn' +export { VoterParams } from './voter-params' +export { MutableArray } from './mutable-array' diff --git a/src/impl/inner-transactions.ts b/src/impl/inner-transactions.ts index 7ebe59f..1a07bcd 100644 --- a/src/impl/inner-transactions.ts +++ b/src/impl/inner-transactions.ts @@ -1,10 +1,22 @@ -import { Account, Application, arc4, Asset, bytes, internal, itxn, TransactionType, uint64 } from '@algorandfoundation/algorand-typescript' +import type { + Account as AccountType, + Application as ApplicationType, + Asset as AssetType, + bytes, + itxn, + OnCompleteActionStr, + uint64, +} from '@algorandfoundation/algorand-typescript' +import { OnCompleteAction, TransactionType } from '@algorandfoundation/algorand-typescript' import { lazyContext } from '../context-helpers/internal-context' -import { Mutable } from '../typescript-helpers' +import { InternalError } from '../errors' +import type { Mutable } from '../typescript-helpers' import { asBytes, asNumber } from '../util' import { getApp } from './app-params' import { getAsset } from './asset-params' -import { InnerTxn, InnerTxnFields } from './itxn' +import type { InnerTxn, InnerTxnFields } from './itxn' +import { Uint64Cls } from './primitives' +import { Account, asAccount, asApplication, asAsset } from './reference' import { ApplicationTransaction, AssetConfigTransaction, @@ -16,14 +28,13 @@ import { const mapCommonFields = ( fields: T, -): Omit & { sender?: Account; note?: bytes; rekeyTo?: Account } => { +): Omit & { sender?: AccountType; note?: bytes; rekeyTo?: AccountType } => { const { sender, note, rekeyTo, ...rest } = fields return { - sender: - sender instanceof Account ? sender : typeof sender === 'string' ? Account(asBytes(sender)) : lazyContext.activeApplication.address, + sender: asAccount(sender), note: note !== undefined ? asBytes(note) : undefined, - rekeyTo: rekeyTo instanceof Account ? rekeyTo : typeof rekeyTo === 'string' ? Account(asBytes(rekeyTo)) : undefined, + rekeyTo: asAccount(rekeyTo), ...rest, } } @@ -37,7 +48,11 @@ export class PaymentInnerTxn extends PaymentTransaction implements itxn.PaymentI /* @internal */ constructor(fields: itxn.PaymentFields) { - super(mapCommonFields(fields)) + super({ + ...mapCommonFields(fields), + receiver: asAccount(fields.receiver), + closeRemainderTo: asAccount(fields.closeRemainderTo), + }) } } @@ -65,13 +80,17 @@ export class AssetConfigInnerTxn extends AssetConfigTransaction implements itxn. /* @internal */ constructor(fields: itxn.AssetConfigFields) { - const { assetName, unitName, url, ...rest } = mapCommonFields(fields) + const { assetName, unitName, url, manager, reserve, freeze, clawback, configAsset, ...rest } = mapCommonFields(fields) const createdAsset = - !rest.configAsset || !asNumber(rest.configAsset.id) + !configAsset || !asNumber(asAsset(configAsset)!.id) ? lazyContext.any.asset({ name: typeof assetName === 'string' ? asBytes(assetName) : assetName, unitName: typeof unitName === 'string' ? asBytes(unitName) : unitName, url: typeof url === 'string' ? asBytes(url) : url, + manager: asAccount(manager), + reserve: asAccount(reserve), + freeze: asAccount(freeze), + clawback: asAccount(clawback), ...rest, }) : undefined @@ -80,6 +99,11 @@ export class AssetConfigInnerTxn extends AssetConfigTransaction implements itxn. assetName: typeof assetName === 'string' ? asBytes(assetName) : assetName, unitName: typeof unitName === 'string' ? asBytes(unitName) : unitName, url: typeof url === 'string' ? asBytes(url) : url, + manager: asAccount(manager), + reserve: asAccount(reserve), + freeze: asAccount(freeze), + clawback: asAccount(clawback), + configAsset: asAsset(configAsset), ...rest, createdAsset: createdAsset, }) @@ -99,7 +123,13 @@ export class AssetTransferInnerTxn extends AssetTransferTransaction implements i /* @internal */ constructor(fields: itxn.AssetTransferFields) { - super(mapCommonFields(fields)) + super({ + ...mapCommonFields(fields), + assetSender: asAccount(fields.assetSender), + assetReceiver: asAccount(fields.assetReceiver), + assetCloseTo: asAccount(fields.assetCloseTo), + xferAsset: asAsset(fields.xferAsset), + }) } } @@ -117,8 +147,9 @@ export class AssetFreezeInnerTxn extends AssetFreezeTransaction implements itxn. /* @internal */ constructor(fields: itxn.AssetFreezeFields) { const { freezeAsset, freezeAccount, ...rest } = mapCommonFields(fields) - const asset: Asset | undefined = freezeAsset instanceof internal.primitives.Uint64Cls ? getAsset(freezeAsset) : (freezeAsset as Asset) - const account: Account | undefined = typeof freezeAccount === 'string' ? Account(asBytes(freezeAccount)) : (freezeAccount as Account) + const asset: AssetType | undefined = freezeAsset instanceof Uint64Cls ? getAsset(freezeAsset) : (freezeAsset as AssetType) + const account: AccountType | undefined = + typeof freezeAccount === 'string' ? Account(asBytes(freezeAccount)) : (freezeAccount as AccountType) super({ freezeAsset: asset, freezeAccount: account, @@ -132,7 +163,7 @@ export class ApplicationInnerTxn extends ApplicationTransaction implements itxn. /* @internal */ static create( - fields: Omit & { onCompletion?: arc4.OnCompleteAction | uint64 | arc4.OnCompleteActionStr }, + fields: Omit & { onCompletion?: OnCompleteAction | uint64 | OnCompleteActionStr }, ) { return new ApplicationInnerTxn(fields as itxn.ApplicationCallFields) } @@ -145,26 +176,21 @@ export class ApplicationInnerTxn extends ApplicationTransaction implements itxn. ? lazyContext.ledger.getApplicationForApprovalProgram(approvalProgram) : undefined super({ - appId: - appId === undefined && compiledApp - ? compiledApp - : appId instanceof internal.primitives.Uint64Cls - ? getApp(appId) - : (appId as Application), + appId: appId === undefined && compiledApp ? compiledApp : appId instanceof Uint64Cls ? getApp(appId) : (appId as ApplicationType), onCompletion: typeof onCompletion === 'string' - ? (onCompletion as arc4.OnCompleteActionStr) + ? (onCompletion as OnCompleteActionStr) : onCompletion !== undefined - ? (arc4.OnCompleteAction[onCompletion] as arc4.OnCompleteActionStr) + ? (OnCompleteAction[onCompletion] as OnCompleteActionStr) : undefined, approvalProgram: Array.isArray(approvalProgram) ? undefined : (approvalProgram as bytes), approvalProgramPages: Array.isArray(approvalProgram) ? approvalProgram : undefined, clearStateProgram: Array.isArray(clearStateProgram) ? undefined : (clearStateProgram as bytes), clearStateProgramPages: Array.isArray(clearStateProgram) ? clearStateProgram : undefined, appArgs: appArgs?.map((x) => x), - accounts: accounts?.map((x) => x), - assets: assets?.map((x) => x), - apps: apps?.map((x) => x), + accounts: accounts?.map((x) => asAccount(x)!), + assets: assets?.map((x) => asAsset(x)!), + apps: apps?.map((x) => asApplication(x)!), createdApp: compiledApp, ...rest, }) @@ -186,7 +212,7 @@ export const createInnerTxn = (fields: TFields) case TransactionType.KeyRegistration: return new KeyRegistrationInnerTxn(fields) default: - throw new internal.errors.InternalError(`Invalid inner transaction type: ${fields.type}`) + throw new InternalError(`Invalid inner transaction type: ${fields.type}`) } } diff --git a/src/impl/itxn.ts b/src/impl/itxn.ts index 5a89368..c7a6aeb 100644 --- a/src/impl/itxn.ts +++ b/src/impl/itxn.ts @@ -1,8 +1,10 @@ -import { Account, Application, arc4, Asset, bytes, internal, itxn, TransactionType, uint64 } from '@algorandfoundation/algorand-typescript' +import type { Account, Application, Asset, bytes, itxn, op, TransactionType, uint64 } from '@algorandfoundation/algorand-typescript' +import { OnCompleteAction } from '@algorandfoundation/algorand-typescript' import { lazyContext } from '../context-helpers/internal-context' -import { asBytes, asBytesCls, asUint64, asUint64Cls } from '../util' +import { asBytes, asBytesCls, asNumber, asUint64, asUint64Cls } from '../util' import { getApp } from './app-params' import { getAsset } from './asset-params' +import type { StubBytesCompat, StubUint64Compat } from './primitives' export type InnerTxn = | itxn.PaymentInnerTxn @@ -21,214 +23,214 @@ export type InnerTxnFields = ( | itxn.ApplicationCallFields ) & { type?: TransactionType } -export const GITxn: internal.opTypes.GITxnType = { - sender: function (t: internal.primitives.StubUint64Compat): Account { +export const GITxn: typeof op.GITxn = { + sender: function (t: StubUint64Compat): Account { return lazyContext.activeGroup.getItxnGroup().getInnerTxn(t).sender }, - fee: function (t: internal.primitives.StubUint64Compat): uint64 { + fee: function (t: StubUint64Compat): uint64 { return lazyContext.activeGroup.getItxnGroup().getInnerTxn(t).fee }, - firstValid: function (t: internal.primitives.StubUint64Compat): uint64 { + firstValid: function (t: StubUint64Compat): uint64 { return lazyContext.activeGroup.getItxnGroup().getInnerTxn(t).firstValid }, - firstValidTime: function (t: internal.primitives.StubUint64Compat): uint64 { + firstValidTime: function (t: StubUint64Compat): uint64 { return lazyContext.activeGroup.getItxnGroup().getInnerTxn(t).firstValidTime }, - lastValid: function (t: internal.primitives.StubUint64Compat): uint64 { + lastValid: function (t: StubUint64Compat): uint64 { return lazyContext.activeGroup.getItxnGroup().getInnerTxn(t).lastValid }, - note: function (t: internal.primitives.StubUint64Compat): bytes { + note: function (t: StubUint64Compat): bytes { return lazyContext.activeGroup.getItxnGroup().getInnerTxn(t).note }, - lease: function (t: internal.primitives.StubUint64Compat): bytes { + lease: function (t: StubUint64Compat): bytes { return lazyContext.activeGroup.getItxnGroup().getInnerTxn(t).lease }, - receiver: function (t: internal.primitives.StubUint64Compat): Account { + receiver: function (t: StubUint64Compat): Account { return lazyContext.activeGroup.getItxnGroup().getPaymentInnerTxn(t).receiver }, - amount: function (t: internal.primitives.StubUint64Compat): uint64 { + amount: function (t: StubUint64Compat): uint64 { return lazyContext.activeGroup.getItxnGroup().getPaymentInnerTxn(t).amount }, - closeRemainderTo: function (t: internal.primitives.StubUint64Compat): Account { + closeRemainderTo: function (t: StubUint64Compat): Account { return lazyContext.activeGroup.getItxnGroup().getPaymentInnerTxn(t).closeRemainderTo }, - votePk: function (t: internal.primitives.StubUint64Compat): bytes { + votePk: function (t: StubUint64Compat): bytes { return lazyContext.activeGroup.getItxnGroup().getKeyRegistrationInnerTxn(t).voteKey }, - selectionPk: function (t: internal.primitives.StubUint64Compat): bytes { + selectionPk: function (t: StubUint64Compat): bytes { return lazyContext.activeGroup.getItxnGroup().getKeyRegistrationInnerTxn(t).selectionKey }, - voteFirst: function (t: internal.primitives.StubUint64Compat): uint64 { + voteFirst: function (t: StubUint64Compat): uint64 { return lazyContext.activeGroup.getItxnGroup().getKeyRegistrationInnerTxn(t).voteFirst }, - voteLast: function (t: internal.primitives.StubUint64Compat): uint64 { + voteLast: function (t: StubUint64Compat): uint64 { return lazyContext.activeGroup.getItxnGroup().getKeyRegistrationInnerTxn(t).voteLast }, - voteKeyDilution: function (t: internal.primitives.StubUint64Compat): uint64 { + voteKeyDilution: function (t: StubUint64Compat): uint64 { return lazyContext.activeGroup.getItxnGroup().getKeyRegistrationInnerTxn(t).voteKeyDilution }, - type: function (t: internal.primitives.StubUint64Compat): bytes { + type: function (t: StubUint64Compat): bytes { return asUint64Cls(lazyContext.activeGroup.getItxnGroup().getInnerTxn(t).type).toBytes().asAlgoTs() }, - typeEnum: function (t: internal.primitives.StubUint64Compat): uint64 { + typeEnum: function (t: StubUint64Compat): uint64 { return asUint64(lazyContext.activeGroup.getItxnGroup().getInnerTxn(t).type) }, - xferAsset: function (t: internal.primitives.StubUint64Compat): Asset { + xferAsset: function (t: StubUint64Compat): Asset { return lazyContext.activeGroup.getItxnGroup().getAssetTransferInnerTxn(t).xferAsset }, - assetAmount: function (t: internal.primitives.StubUint64Compat): uint64 { + assetAmount: function (t: StubUint64Compat): uint64 { return lazyContext.activeGroup.getItxnGroup().getAssetTransferInnerTxn(t).assetAmount }, - assetSender: function (t: internal.primitives.StubUint64Compat): Account { + assetSender: function (t: StubUint64Compat): Account { return lazyContext.activeGroup.getItxnGroup().getAssetTransferInnerTxn(t).assetSender }, - assetReceiver: function (t: internal.primitives.StubUint64Compat): Account { + assetReceiver: function (t: StubUint64Compat): Account { return lazyContext.activeGroup.getItxnGroup().getAssetTransferInnerTxn(t).assetReceiver }, - assetCloseTo: function (t: internal.primitives.StubUint64Compat): Account { + assetCloseTo: function (t: StubUint64Compat): Account { return lazyContext.activeGroup.getItxnGroup().getAssetTransferInnerTxn(t).assetCloseTo }, - groupIndex: function (t: internal.primitives.StubUint64Compat): uint64 { + groupIndex: function (t: StubUint64Compat): uint64 { return lazyContext.activeGroup.getItxnGroup().getInnerTxn(t).groupIndex }, - txId: function (t: internal.primitives.StubUint64Compat): bytes { + txId: function (t: StubUint64Compat): bytes { return lazyContext.activeGroup.getItxnGroup().getInnerTxn(t).txnId }, - applicationId: function (t: internal.primitives.StubUint64Compat): Application { + applicationId: function (t: StubUint64Compat): Application { return lazyContext.activeGroup.getItxnGroup().getApplicationInnerTxn(t).appId }, - onCompletion: function (t: internal.primitives.StubUint64Compat): uint64 { + onCompletion: function (t: StubUint64Compat): uint64 { const onCompletionStr = lazyContext.activeGroup.getItxnGroup().getApplicationInnerTxn(t).onCompletion - return asUint64(arc4.OnCompleteAction[onCompletionStr]) + return asUint64(OnCompleteAction[onCompletionStr]) }, - applicationArgs: function (t: internal.primitives.StubUint64Compat, a: internal.primitives.StubUint64Compat): bytes { + applicationArgs: function (t: StubUint64Compat, a: StubUint64Compat): bytes { return lazyContext.activeGroup.getItxnGroup().getApplicationInnerTxn(t).appArgs(asUint64(a)) }, - numAppArgs: function (t: internal.primitives.StubUint64Compat): uint64 { + numAppArgs: function (t: StubUint64Compat): uint64 { return lazyContext.activeGroup.getItxnGroup().getApplicationInnerTxn(t).numAppArgs }, - accounts: function (t: internal.primitives.StubUint64Compat, a: internal.primitives.StubUint64Compat): Account { + accounts: function (t: StubUint64Compat, a: StubUint64Compat): Account { return lazyContext.activeGroup.getItxnGroup().getApplicationInnerTxn(t).accounts(asUint64(a)) }, - numAccounts: function (t: internal.primitives.StubUint64Compat): uint64 { + numAccounts: function (t: StubUint64Compat): uint64 { return lazyContext.activeGroup.getItxnGroup().getApplicationInnerTxn(t).numAccounts }, - approvalProgram: function (t: internal.primitives.StubUint64Compat): bytes { + approvalProgram: function (t: StubUint64Compat): bytes { return lazyContext.activeGroup.getItxnGroup().getApplicationInnerTxn(t).approvalProgram }, - clearStateProgram: function (t: internal.primitives.StubUint64Compat): bytes { + clearStateProgram: function (t: StubUint64Compat): bytes { return lazyContext.activeGroup.getItxnGroup().getApplicationInnerTxn(t).clearStateProgram }, - rekeyTo: function (t: internal.primitives.StubUint64Compat): Account { + rekeyTo: function (t: StubUint64Compat): Account { return lazyContext.activeGroup.getItxnGroup().getInnerTxn(t).rekeyTo }, - configAsset: function (t: internal.primitives.StubUint64Compat): Asset { + configAsset: function (t: StubUint64Compat): Asset { return lazyContext.activeGroup.getItxnGroup().getAssetConfigInnerTxn(t).configAsset }, - configAssetTotal: function (t: internal.primitives.StubUint64Compat): uint64 { + configAssetTotal: function (t: StubUint64Compat): uint64 { return lazyContext.activeGroup.getItxnGroup().getAssetConfigInnerTxn(t).total }, - configAssetDecimals: function (t: internal.primitives.StubUint64Compat): uint64 { + configAssetDecimals: function (t: StubUint64Compat): uint64 { return lazyContext.activeGroup.getItxnGroup().getAssetConfigInnerTxn(t).decimals }, - configAssetDefaultFrozen: function (t: internal.primitives.StubUint64Compat): boolean { + configAssetDefaultFrozen: function (t: StubUint64Compat): boolean { return lazyContext.activeGroup.getItxnGroup().getAssetConfigInnerTxn(t).defaultFrozen }, - configAssetUnitName: function (t: internal.primitives.StubUint64Compat): bytes { + configAssetUnitName: function (t: StubUint64Compat): bytes { return lazyContext.activeGroup.getItxnGroup().getAssetConfigInnerTxn(t).unitName }, - configAssetName: function (t: internal.primitives.StubUint64Compat): bytes { + configAssetName: function (t: StubUint64Compat): bytes { return lazyContext.activeGroup.getItxnGroup().getAssetConfigInnerTxn(t).assetName }, - configAssetUrl: function (t: internal.primitives.StubUint64Compat): bytes { + configAssetUrl: function (t: StubUint64Compat): bytes { return lazyContext.activeGroup.getItxnGroup().getAssetConfigInnerTxn(t).url }, - configAssetMetadataHash: function (t: internal.primitives.StubUint64Compat): bytes { + configAssetMetadataHash: function (t: StubUint64Compat): bytes { return lazyContext.activeGroup.getItxnGroup().getAssetConfigInnerTxn(t).metadataHash }, - configAssetManager: function (t: internal.primitives.StubUint64Compat): Account { + configAssetManager: function (t: StubUint64Compat): Account { return lazyContext.activeGroup.getItxnGroup().getAssetConfigInnerTxn(t).manager }, - configAssetReserve: function (t: internal.primitives.StubUint64Compat): Account { + configAssetReserve: function (t: StubUint64Compat): Account { return lazyContext.activeGroup.getItxnGroup().getAssetConfigInnerTxn(t).reserve }, - configAssetFreeze: function (t: internal.primitives.StubUint64Compat): Account { + configAssetFreeze: function (t: StubUint64Compat): Account { return lazyContext.activeGroup.getItxnGroup().getAssetConfigInnerTxn(t).freeze }, - configAssetClawback: function (t: internal.primitives.StubUint64Compat): Account { + configAssetClawback: function (t: StubUint64Compat): Account { return lazyContext.activeGroup.getItxnGroup().getAssetConfigInnerTxn(t).clawback }, - freezeAsset: function (t: internal.primitives.StubUint64Compat): Asset { + freezeAsset: function (t: StubUint64Compat): Asset { return lazyContext.activeGroup.getItxnGroup().getAssetFreezeInnerTxn(t).freezeAsset }, - freezeAssetAccount: function (t: internal.primitives.StubUint64Compat): Account { + freezeAssetAccount: function (t: StubUint64Compat): Account { return lazyContext.activeGroup.getItxnGroup().getAssetFreezeInnerTxn(t).freezeAccount }, - freezeAssetFrozen: function (t: internal.primitives.StubUint64Compat): boolean { + freezeAssetFrozen: function (t: StubUint64Compat): boolean { return lazyContext.activeGroup.getItxnGroup().getAssetFreezeInnerTxn(t).frozen }, - assets: function (t: internal.primitives.StubUint64Compat, a: internal.primitives.StubUint64Compat): Asset { + assets: function (t: StubUint64Compat, a: StubUint64Compat): Asset { return lazyContext.activeGroup.getItxnGroup().getApplicationInnerTxn(t).assets(asUint64(a)) }, - numAssets: function (t: internal.primitives.StubUint64Compat): uint64 { + numAssets: function (t: StubUint64Compat): uint64 { return lazyContext.activeGroup.getItxnGroup().getApplicationInnerTxn(t).numAssets }, - applications: function (t: internal.primitives.StubUint64Compat, a: internal.primitives.StubUint64Compat): Application { + applications: function (t: StubUint64Compat, a: StubUint64Compat): Application { return lazyContext.activeGroup.getItxnGroup().getApplicationInnerTxn(t).apps(asUint64(a)) }, - numApplications: function (t: internal.primitives.StubUint64Compat): uint64 { + numApplications: function (t: StubUint64Compat): uint64 { return lazyContext.activeGroup.getItxnGroup().getApplicationInnerTxn(t).numApps }, - globalNumUint: function (t: internal.primitives.StubUint64Compat): uint64 { + globalNumUint: function (t: StubUint64Compat): uint64 { return lazyContext.activeGroup.getItxnGroup().getApplicationInnerTxn(t).globalNumUint }, - globalNumByteSlice: function (t: internal.primitives.StubUint64Compat): uint64 { + globalNumByteSlice: function (t: StubUint64Compat): uint64 { return lazyContext.activeGroup.getItxnGroup().getApplicationInnerTxn(t).globalNumBytes }, - localNumUint: function (t: internal.primitives.StubUint64Compat): uint64 { + localNumUint: function (t: StubUint64Compat): uint64 { return lazyContext.activeGroup.getItxnGroup().getApplicationInnerTxn(t).localNumUint }, - localNumByteSlice: function (t: internal.primitives.StubUint64Compat): uint64 { + localNumByteSlice: function (t: StubUint64Compat): uint64 { return lazyContext.activeGroup.getItxnGroup().getApplicationInnerTxn(t).localNumBytes }, - extraProgramPages: function (t: internal.primitives.StubUint64Compat): uint64 { + extraProgramPages: function (t: StubUint64Compat): uint64 { return lazyContext.activeGroup.getItxnGroup().getApplicationInnerTxn(t).extraProgramPages }, - nonparticipation: function (t: internal.primitives.StubUint64Compat): boolean { + nonparticipation: function (t: StubUint64Compat): boolean { return lazyContext.activeGroup.getItxnGroup().getKeyRegistrationInnerTxn(t).nonparticipation }, - logs: function (t: internal.primitives.StubUint64Compat, a: internal.primitives.StubUint64Compat): bytes { + logs: function (t: StubUint64Compat, a: StubUint64Compat): bytes { return lazyContext.activeGroup.getItxnGroup().getApplicationInnerTxn(t).logs(asUint64(a)) }, - numLogs: function (t: internal.primitives.StubUint64Compat): uint64 { + numLogs: function (t: StubUint64Compat): uint64 { return lazyContext.activeGroup.getItxnGroup().getApplicationInnerTxn(t).numLogs }, - createdAssetId: function (t: internal.primitives.StubUint64Compat): Asset { + createdAssetId: function (t: StubUint64Compat): Asset { return lazyContext.activeGroup.getItxnGroup().getAssetConfigInnerTxn(t).createdAsset }, - createdApplicationId: function (t: internal.primitives.StubUint64Compat): Application { + createdApplicationId: function (t: StubUint64Compat): Application { return lazyContext.activeGroup.getItxnGroup().getApplicationInnerTxn(t).createdApp }, - lastLog: function (t: internal.primitives.StubUint64Compat): bytes { + lastLog: function (t: StubUint64Compat): bytes { return lazyContext.activeGroup.getItxnGroup().getApplicationInnerTxn(t).lastLog }, - stateProofPk: function (t: internal.primitives.StubUint64Compat): bytes { + stateProofPk: function (t: StubUint64Compat): bytes { return lazyContext.activeGroup.getItxnGroup().getKeyRegistrationInnerTxn(t).stateProofKey }, - approvalProgramPages: function (t: internal.primitives.StubUint64Compat, a: internal.primitives.StubUint64Compat): bytes { + approvalProgramPages: function (t: StubUint64Compat, a: StubUint64Compat): bytes { return lazyContext.activeGroup.getItxnGroup().getApplicationInnerTxn(t).approvalProgramPages(asUint64(a)) }, - numApprovalProgramPages: function (t: internal.primitives.StubUint64Compat): uint64 { + numApprovalProgramPages: function (t: StubUint64Compat): uint64 { return lazyContext.activeGroup.getItxnGroup().getApplicationInnerTxn(t).numApprovalProgramPages }, - clearStateProgramPages: function (t: internal.primitives.StubUint64Compat, a: internal.primitives.StubUint64Compat): bytes { + clearStateProgramPages: function (t: StubUint64Compat, a: StubUint64Compat): bytes { return lazyContext.activeGroup.getItxnGroup().getApplicationInnerTxn(t).clearStateProgramPages(asUint64(a)) }, - numClearStateProgramPages: function (t: internal.primitives.StubUint64Compat): uint64 { + numClearStateProgramPages: function (t: StubUint64Compat): uint64 { return lazyContext.activeGroup.getItxnGroup().getApplicationInnerTxn(t).numClearStateProgramPages }, } -export const ITxn: internal.opTypes.ITxnType = { +export const ITxn: typeof op.ITxn = { /** * 32 byte address */ @@ -384,12 +386,12 @@ export const ITxn: internal.opTypes.ITxnType = { */ get onCompletion(): uint64 { const onCompletionStr = lazyContext.activeGroup.getItxnGroup().getApplicationInnerTxn().onCompletion - return asUint64(arc4.OnCompleteAction[onCompletionStr]) + return asUint64(OnCompleteAction[onCompletionStr]) }, /** * Arguments passed to the application in the ApplicationCall transaction */ - applicationArgs(a: internal.primitives.StubUint64Compat): bytes { + applicationArgs(a: StubUint64Compat): bytes { return lazyContext.activeGroup.getItxnGroup().getApplicationInnerTxn().appArgs(asUint64(a)) }, /** @@ -401,7 +403,7 @@ export const ITxn: internal.opTypes.ITxnType = { /** * Accounts listed in the ApplicationCall transaction */ - accounts(a: internal.primitives.StubUint64Compat): Account { + accounts(a: StubUint64Compat): Account { return lazyContext.activeGroup.getItxnGroup().getApplicationInnerTxn().accounts(asUint64(a)) }, /** @@ -521,7 +523,7 @@ export const ITxn: internal.opTypes.ITxnType = { /** * Foreign Assets listed in the ApplicationCall transaction */ - assets(a: internal.primitives.StubUint64Compat): Asset { + assets(a: StubUint64Compat): Asset { return lazyContext.activeGroup.getItxnGroup().getApplicationInnerTxn().assets(asUint64(a)) }, /** @@ -533,7 +535,7 @@ export const ITxn: internal.opTypes.ITxnType = { /** * Foreign Apps listed in the ApplicationCall transaction */ - applications(a: internal.primitives.StubUint64Compat): Application { + applications(a: StubUint64Compat): Application { return lazyContext.activeGroup.getItxnGroup().getApplicationInnerTxn().apps(asUint64(a)) }, /** @@ -581,7 +583,7 @@ export const ITxn: internal.opTypes.ITxnType = { /** * Log messages emitted by an application call (only with `itxn` in v5). Application mode only */ - logs(a: internal.primitives.StubUint64Compat): bytes { + logs(a: StubUint64Compat): bytes { return lazyContext.activeGroup.getItxnGroup().getApplicationInnerTxn().logs(asUint64(a)) }, /** @@ -617,7 +619,7 @@ export const ITxn: internal.opTypes.ITxnType = { /** * Approval Program as an array of pages */ - approvalProgramPages(a: internal.primitives.StubUint64Compat): bytes { + approvalProgramPages(a: StubUint64Compat): bytes { return lazyContext.activeGroup.getItxnGroup().getApplicationInnerTxn().approvalProgramPages(asUint64(a)) }, /** @@ -629,7 +631,7 @@ export const ITxn: internal.opTypes.ITxnType = { /** * ClearState Program as an array of pages */ - clearStateProgramPages(a: internal.primitives.StubUint64Compat): bytes { + clearStateProgramPages(a: StubUint64Compat): bytes { return lazyContext.activeGroup.getItxnGroup().getApplicationInnerTxn().clearStateProgramPages(asUint64(a)) }, /** @@ -648,53 +650,53 @@ const getConstructingItxn = (): T => { return lazyContext.activeGroup.constructingItxn as T } -export const ITxnCreate: internal.opTypes.ITxnCreateType = { +export const ITxnCreate: typeof op.ITxnCreate = { begin: function (): void { lazyContext.activeGroup.beginInnerTransactionGroup() }, setSender: function (a: Account): void { setConstructingItxnField({ sender: a }) }, - setFee: function (a: internal.primitives.StubUint64Compat): void { + setFee: function (a: StubUint64Compat): void { setConstructingItxnField({ fee: asUint64(a) }) }, - setNote: function (a: internal.primitives.StubBytesCompat): void { + setNote: function (a: StubBytesCompat): void { setConstructingItxnField({ note: asBytes(a) }) }, setReceiver: function (a: Account): void { setConstructingItxnField({ receiver: a }) }, - setAmount: function (a: internal.primitives.StubUint64Compat): void { + setAmount: function (a: StubUint64Compat): void { setConstructingItxnField({ amount: asUint64(a) }) }, setCloseRemainderTo: function (a: Account): void { setConstructingItxnField({ closeRemainderTo: a }) }, - setVotePk: function (a: internal.primitives.StubBytesCompat): void { + setVotePk: function (a: StubBytesCompat): void { setConstructingItxnField({ voteKey: asBytes(a) }) }, - setSelectionPk: function (a: internal.primitives.StubBytesCompat): void { + setSelectionPk: function (a: StubBytesCompat): void { setConstructingItxnField({ selectionKey: asBytes(a) }) }, - setVoteFirst: function (a: internal.primitives.StubUint64Compat): void { + setVoteFirst: function (a: StubUint64Compat): void { setConstructingItxnField({ voteFirst: asUint64(a) }) }, - setVoteLast: function (a: internal.primitives.StubUint64Compat): void { + setVoteLast: function (a: StubUint64Compat): void { setConstructingItxnField({ voteLast: asUint64(a) }) }, - setVoteKeyDilution: function (a: internal.primitives.StubUint64Compat): void { + setVoteKeyDilution: function (a: StubUint64Compat): void { setConstructingItxnField({ voteKeyDilution: asUint64(a) }) }, - setType: function (a: internal.primitives.StubBytesCompat): void { + setType: function (a: StubBytesCompat): void { setConstructingItxnField({ type: asBytesCls(a).toUint64().asNumber() as TransactionType }) }, - setTypeEnum: function (a: internal.primitives.StubUint64Compat): void { + setTypeEnum: function (a: StubUint64Compat): void { setConstructingItxnField({ type: asUint64Cls(a).asNumber() as TransactionType }) }, - setXferAsset: function (a: Asset | internal.primitives.StubUint64Compat): void { + setXferAsset: function (a: Asset | StubUint64Compat): void { setConstructingItxnField({ xferAsset: getAsset(a) }) }, - setAssetAmount: function (a: internal.primitives.StubUint64Compat): void { + setAssetAmount: function (a: StubUint64Compat): void { setConstructingItxnField({ assetAmount: asUint64(a) }) }, setAssetSender: function (a: Account): void { @@ -706,13 +708,13 @@ export const ITxnCreate: internal.opTypes.ITxnCreateType = { setAssetCloseTo: function (a: Account): void { setConstructingItxnField({ assetCloseTo: a }) }, - setApplicationId: function (a: Application | internal.primitives.StubUint64Compat): void { + setApplicationId: function (a: Application | StubUint64Compat): void { setConstructingItxnField({ appId: getApp(a) }) }, - setOnCompletion: function (a: internal.primitives.StubUint64Compat): void { - setConstructingItxnField({ onCompletion: asUint64(a) }) + setOnCompletion: function (a: StubUint64Compat): void { + setConstructingItxnField({ onCompletion: asNumber(a) }) }, - setApplicationArgs: function (a: internal.primitives.StubBytesCompat): void { + setApplicationArgs: function (a: StubBytesCompat): void { const appArgs = (getConstructingItxn().appArgs ?? []) as bytes[] appArgs.push(asBytes(a)) setConstructingItxnField({ appArgs }) @@ -722,37 +724,37 @@ export const ITxnCreate: internal.opTypes.ITxnCreateType = { accounts.push(a) setConstructingItxnField({ accounts }) }, - setApprovalProgram: function (a: internal.primitives.StubBytesCompat): void { + setApprovalProgram: function (a: StubBytesCompat): void { setConstructingItxnField({ approvalProgram: asBytes(a) }) }, - setClearStateProgram: function (a: internal.primitives.StubBytesCompat): void { + setClearStateProgram: function (a: StubBytesCompat): void { setConstructingItxnField({ clearStateProgram: asBytes(a) }) }, setRekeyTo: function (a: Account): void { setConstructingItxnField({ rekeyTo: a }) }, - setConfigAsset: function (a: Asset | internal.primitives.StubUint64Compat): void { + setConfigAsset: function (a: Asset | StubUint64Compat): void { setConstructingItxnField({ configAsset: getAsset(a) }) }, - setConfigAssetTotal: function (a: internal.primitives.StubUint64Compat): void { + setConfigAssetTotal: function (a: StubUint64Compat): void { setConstructingItxnField({ total: asUint64(a) }) }, - setConfigAssetDecimals: function (a: internal.primitives.StubUint64Compat): void { + setConfigAssetDecimals: function (a: StubUint64Compat): void { setConstructingItxnField({ decimals: asUint64(a) }) }, setConfigAssetDefaultFrozen: function (a: boolean): void { setConstructingItxnField({ defaultFrozen: a }) }, - setConfigAssetUnitName: function (a: internal.primitives.StubBytesCompat): void { + setConfigAssetUnitName: function (a: StubBytesCompat): void { setConstructingItxnField({ unitName: asBytes(a) }) }, - setConfigAssetName: function (a: internal.primitives.StubBytesCompat): void { + setConfigAssetName: function (a: StubBytesCompat): void { setConstructingItxnField({ assetName: asBytes(a) }) }, - setConfigAssetUrl: function (a: internal.primitives.StubBytesCompat): void { + setConfigAssetUrl: function (a: StubBytesCompat): void { setConstructingItxnField({ url: asBytes(a) }) }, - setConfigAssetMetadataHash: function (a: internal.primitives.StubBytesCompat): void { + setConfigAssetMetadataHash: function (a: StubBytesCompat): void { setConstructingItxnField({ metadataHash: asBytes(a) }) }, setConfigAssetManager: function (a: Account): void { @@ -767,7 +769,7 @@ export const ITxnCreate: internal.opTypes.ITxnCreateType = { setConfigAssetClawback: function (a: Account): void { setConstructingItxnField({ clawback: a }) }, - setFreezeAsset: function (a: Asset | internal.primitives.StubUint64Compat): void { + setFreezeAsset: function (a: Asset | StubUint64Compat): void { setConstructingItxnField({ freezeAsset: getAsset(a) }) }, setFreezeAssetAccount: function (a: Account): void { @@ -776,7 +778,7 @@ export const ITxnCreate: internal.opTypes.ITxnCreateType = { setFreezeAssetFrozen: function (a: boolean): void { setConstructingItxnField({ frozen: a }) }, - setAssets: function (a: internal.primitives.StubUint64Compat): void { + setAssets: function (a: StubUint64Compat): void { const asset = getAsset(a) if (asset) { const assets = (getConstructingItxn().assets ?? []) as Asset[] @@ -784,7 +786,7 @@ export const ITxnCreate: internal.opTypes.ITxnCreateType = { setConstructingItxnField({ assets }) } }, - setApplications: function (a: internal.primitives.StubUint64Compat): void { + setApplications: function (a: StubUint64Compat): void { const app = getApp(a) if (app) { const apps = (getConstructingItxn().apps ?? []) as Application[] @@ -792,28 +794,28 @@ export const ITxnCreate: internal.opTypes.ITxnCreateType = { setConstructingItxnField({ apps }) } }, - setGlobalNumUint: function (a: internal.primitives.StubUint64Compat): void { + setGlobalNumUint: function (a: StubUint64Compat): void { setConstructingItxnField({ globalNumUint: asUint64(a) }) }, - setGlobalNumByteSlice: function (a: internal.primitives.StubUint64Compat): void { + setGlobalNumByteSlice: function (a: StubUint64Compat): void { setConstructingItxnField({ globalNumBytes: asUint64(a) }) }, - setLocalNumUint: function (a: internal.primitives.StubUint64Compat): void { + setLocalNumUint: function (a: StubUint64Compat): void { setConstructingItxnField({ localNumUint: asUint64(a) }) }, - setLocalNumByteSlice: function (a: internal.primitives.StubUint64Compat): void { + setLocalNumByteSlice: function (a: StubUint64Compat): void { setConstructingItxnField({ localNumBytes: asUint64(a) }) }, - setExtraProgramPages: function (a: internal.primitives.StubUint64Compat): void { + setExtraProgramPages: function (a: StubUint64Compat): void { setConstructingItxnField({ extraProgramPages: asUint64(a) }) }, setNonparticipation: function (a: boolean): void { setConstructingItxnField({ nonparticipation: a }) }, - setStateProofPk: function (a: internal.primitives.StubBytesCompat): void { + setStateProofPk: function (a: StubBytesCompat): void { setConstructingItxnField({ stateProofKey: asBytes(a) }) }, - setApprovalProgramPages: function (a: internal.primitives.StubBytesCompat): void { + setApprovalProgramPages: function (a: StubBytesCompat): void { let pages = (getConstructingItxn().approvalProgram ?? []) as bytes[] if (!Array.isArray(pages)) { pages = [pages] @@ -821,7 +823,7 @@ export const ITxnCreate: internal.opTypes.ITxnCreateType = { pages.push(asBytes(a)) setConstructingItxnField({ approvalProgram: pages }) }, - setClearStateProgramPages: function (a: internal.primitives.StubBytesCompat): void { + setClearStateProgramPages: function (a: StubBytesCompat): void { let pages = (getConstructingItxn().clearStateProgram ?? []) as bytes[] if (!Array.isArray(pages)) { pages = [pages] diff --git a/src/impl/log.ts b/src/impl/log.ts new file mode 100644 index 0000000..e2bc175 --- /dev/null +++ b/src/impl/log.ts @@ -0,0 +1,27 @@ +import type { bytes, BytesBacked, StringCompat } from '@algorandfoundation/algorand-typescript' +import { ARC4Encoded } from '@algorandfoundation/algorand-typescript/arc4' +import { lazyContext } from '../context-helpers/internal-context' +import { InternalError } from '../errors' +import { nameOfType } from '../util' +import type { StubBigUintCompat, StubBytesCompat, StubUint64Compat } from './primitives' +import { AlgoTsPrimitiveCls, BigUintCls, BytesCls, Uint64Cls } from './primitives' + +const toBytes = (val: unknown): bytes => { + if (val instanceof AlgoTsPrimitiveCls) return val.toBytes().asAlgoTs() + if (val instanceof ARC4Encoded) return val.bytes + + switch (typeof val) { + case 'string': + return BytesCls.fromCompat(val).asAlgoTs() + case 'bigint': + return BigUintCls.fromCompat(val).toBytes().asAlgoTs() + case 'number': + return Uint64Cls.fromCompat(val).toBytes().asAlgoTs() + default: + throw new InternalError(`Unsupported arg type ${nameOfType(val)}`) + } +} + +export function log(...args: Array): void { + lazyContext.txn.appendLog(args.map(toBytes).reduce((left, right) => left.concat(right))) +} diff --git a/src/impl/logicSigArg.ts b/src/impl/logicSigArg.ts index 6d411fc..e96ec9c 100644 --- a/src/impl/logicSigArg.ts +++ b/src/impl/logicSigArg.ts @@ -1,8 +1,9 @@ -import { bytes, internal } from '@algorandfoundation/algorand-typescript' +import type { bytes } from '@algorandfoundation/algorand-typescript' import { lazyContext } from '../context-helpers/internal-context' import { asNumber } from '../util' +import type { StubUint64Compat } from './primitives' -export const arg = (a: internal.primitives.StubUint64Compat): bytes => { +export const arg = (a: StubUint64Compat): bytes => { const index = asNumber(a) return lazyContext.value.activeLogicSigArgs[index] } diff --git a/src/impl/match.ts b/src/impl/match.ts index 2ef59c6..c1c2c10 100644 --- a/src/impl/match.ts +++ b/src/impl/match.ts @@ -1,8 +1,10 @@ -import { assert, assertMatch, internal, match } from '@algorandfoundation/algorand-typescript' +import type { assertMatch, match } from '@algorandfoundation/algorand-typescript' import { ARC4Encoded } from '@algorandfoundation/algorand-typescript/arc4' -import { DeliberateAny } from '../typescript-helpers' -import { asBytes, asMaybeBigUintCls } from '../util' +import type { DeliberateAny } from '../typescript-helpers' +import { asBytes, asMaybeBigUintCls, assert } from '../util' import { BytesBackedCls, Uint64BackedCls } from './base' +import type { StubBytesCompat, Uint64Cls } from './primitives' +import { BytesCls } from './primitives' export const matchImpl: typeof match = (subject, test): boolean => { const bigIntSubjectValue = getBigIntValue(subject) @@ -22,16 +24,16 @@ export const matchImpl: typeof match = (subject, test): boolean => { const [start, end] = (test as DeliberateAny).between return bigIntSubjectValue >= getBigIntValue(start)! && bigIntSubjectValue <= getBigIntValue(end)! } - } else if (subject instanceof internal.primitives.BytesCls) { - return subject.equals(asBytes(test as unknown as internal.primitives.StubBytesCompat)) + } else if (subject instanceof BytesCls) { + return subject.equals(asBytes(test as unknown as StubBytesCompat)) } else if (typeof subject === 'string') { return subject === test } else if (subject instanceof BytesBackedCls) { return subject.bytes.equals((test as unknown as BytesBackedCls).bytes) } else if (subject instanceof Uint64BackedCls) { return ( - getBigIntValue(subject.uint64 as unknown as internal.primitives.Uint64Cls) === - getBigIntValue((test as unknown as Uint64BackedCls).uint64 as unknown as internal.primitives.Uint64Cls) + getBigIntValue(subject.uint64 as unknown as Uint64Cls) === + getBigIntValue((test as unknown as Uint64BackedCls).uint64 as unknown as Uint64Cls) ) } else if (test instanceof ARC4Encoded) { return (subject as unknown as ARC4Encoded).bytes.equals(test.bytes) diff --git a/src/impl/method-selector.ts b/src/impl/method-selector.ts new file mode 100644 index 0000000..eafde95 --- /dev/null +++ b/src/impl/method-selector.ts @@ -0,0 +1,18 @@ +import type { arc4, bytes } from '@algorandfoundation/algorand-typescript' +import { encodingUtil } from '@algorandfoundation/puya-ts' +import { getArc4Selector, getContractMethodAbiMetadata } from '../abi-metadata' +import type { Contract } from './contract' +import { sha512_256 } from './crypto' +import { Bytes } from './primitives' + +export const methodSelector = ( + methodSignature: Parameters[0], + contract?: TContract, +): bytes => { + if (typeof methodSignature === 'string') { + return sha512_256(Bytes(encodingUtil.utf8ToUint8Array(methodSignature))).slice(0, 4) + } else { + const abiMetadata = getContractMethodAbiMetadata(contract!, methodSignature.name) + return Bytes(getArc4Selector(abiMetadata)) + } +} diff --git a/src/impl/mutable-array.ts b/src/impl/mutable-array.ts new file mode 100644 index 0000000..e03a42d --- /dev/null +++ b/src/impl/mutable-array.ts @@ -0,0 +1,122 @@ +import type { uint64, Uint64Compat } from '@algorandfoundation/algorand-typescript' +import { AvmError } from '../errors' +import { asNumber } from '../util' + +export class MutableArray { + private _values: TItem[] + + constructor(...items: TItem[]) { + this._values = items + + return new Proxy(this, { + get(target, prop: PropertyKey) { + const idx = prop ? parseInt(prop.toString(), 10) : NaN + if (!isNaN(idx)) { + if (idx >= 0 && idx < target._values.length) return target._values[idx] + throw new AvmError('Index out of bounds') + } + return Reflect.get(target, prop) + }, + set(target, prop: PropertyKey, value: TItem) { + const idx = prop ? parseInt(prop.toString(), 10) : NaN + if (!isNaN(idx)) { + if (idx >= 0 && idx < target._values.length) { + target._values[idx] = value + return true + } + throw new AvmError('Index out of bounds') + } + + return Reflect.set(target, prop, value) + }, + }) + } + + /** + * Returns the current length of this array + */ + get length(): uint64 { + return this._values.length + } + + /** + * Returns the item at the given index. + * Negative indexes are taken from the end. + * @param index The index of the item to retrieve + */ + at(index: Uint64Compat): TItem { + return this._values[asNumber(index)] + } + + /** + * Create a new Dynamic array with all items from this array + * @internal Not supported yet + */ + slice(): MutableArray + /** + * Create a new MutableArray with all items up till `end`. + * Negative indexes are taken from the end. + * @param end An index in which to stop copying items. + * @internal Not supported yet + */ + slice(end: Uint64Compat): MutableArray + /** + * Create a new MutableArray with items from `start`, up until `end` + * Negative indexes are taken from the end. + * @param start An index in which to start copying items. + * @param end An index in which to stop copying items + * @internal Not supported yet + */ + slice(start: Uint64Compat, end: Uint64Compat): MutableArray + slice(start?: Uint64Compat, end?: Uint64Compat): MutableArray { + const startIndex = end === undefined ? 0 : asNumber(start ?? 0) + const endIndex = end === undefined ? asNumber(start ?? this._values.length) : asNumber(end) + return new MutableArray(...this._values.slice(startIndex, endIndex)) + } + + /** + * Returns an iterator for the items in this array + */ + [Symbol.iterator](): IterableIterator { + return this._values[Symbol.iterator]() + } + + /** + * Returns an iterator for a tuple of the indexes and items in this array + */ + entries(): IterableIterator { + return this._values.entries() + } + + /** + * Returns an iterator for the indexes in this array + */ + keys(): IterableIterator { + return this._values.keys() + } + + /** + * Get or set the item at the specified index. + * Negative indexes are not supported + */ + [index: uint64]: TItem + + /** + * Push a number of items into this array + * @param items The items to be added to this array + */ + push(...items: TItem[]): void { + this._values.push(...items) + } + + /** + * Pop a single item from this array + */ + pop(): TItem { + return this._values.pop()! + } + + copy(): MutableArray { + return new MutableArray(...this._values) + } +} diff --git a/src/impl/online-stake.ts b/src/impl/online-stake.ts new file mode 100644 index 0000000..4c47437 --- /dev/null +++ b/src/impl/online-stake.ts @@ -0,0 +1,6 @@ +import type { op } from '@algorandfoundation/algorand-typescript' +import { lazyContext } from '../context-helpers/internal-context' + +export const onlineStake: typeof op.onlineStake = () => { + return lazyContext.ledger.onlineStake +} diff --git a/src/impl/primitives.ts b/src/impl/primitives.ts new file mode 100644 index 0000000..83c882f --- /dev/null +++ b/src/impl/primitives.ts @@ -0,0 +1,590 @@ +import type { biguint, BigUintCompat, bytes, BytesCompat, uint64, Uint64Compat } from '@algorandfoundation/algorand-typescript' +import { encodingUtil } from '@algorandfoundation/puya-ts' +import { avmError, AvmError, avmInvariant, CodeError, InternalError } from '../errors' +import { nameOfType } from '../typescript-helpers' +import { base32ToUint8Array } from './base-32' + +const MAX_UINT8 = 2 ** 8 - 1 +const MAX_BYTES_SIZE = 4096 + +export type StubBigUintCompat = BigUintCompat | BigUintCls | Uint64Cls +export type StubBytesCompat = BytesCompat | BytesCls +export type StubUint64Compat = Uint64Compat | Uint64Cls + +/** + * Converts internal Algorand type representations to their external primitive values. + * + * @overload + * @param {uint64} val - A uint64 value to convert + * @returns {bigint} The uint64 value as a bigint + * + * @overload + * @param {biguint} val - A biguint value to convert + * @returns {bigint} The biguint value as a bigint + * + * @overload + * @param {bytes} val - A bytes value to convert + * @returns {Uint8Array} The bytes value as a Uint8Array + * + * @overload + * @param {string} val - A string value to pass through + * @returns {string} The original string value unchanged + * + * @example + * ```ts + * const uint64Val = Uint64(123n) + * toExternalValue(uint64Val) // returns 123n + * + * const bytesVal = Bytes.fromBase64("SGVsbG8="); + * toExternalValue(bytesVal) // returns Uint8Array([72, 101, 108, 108, 111]) + * ``` + */ +export function toExternalValue(val: uint64): bigint +export function toExternalValue(val: biguint): bigint +export function toExternalValue(val: bytes): Uint8Array +export function toExternalValue(val: string): string +export function toExternalValue(val: uint64 | biguint | bytes | string) { + const instance = val as unknown + if (instance instanceof BytesCls) return instance.asUint8Array() + if (instance instanceof Uint64Cls) return instance.asBigInt() + if (instance instanceof BigUintCls) return instance.asBigInt() + if (typeof val === 'string') return val +} + +/** + * Create a uint64 with the default value of 0 + */ +export function Uint64(): uint64 +/** + * Create a uint64 from a string literal + */ +export function Uint64(v: string): uint64 +/** + * Create a uint64 from a bigint literal + */ +export function Uint64(v: bigint): uint64 +/** + * Create a uint64 from a number literal + */ +export function Uint64(v: number): uint64 +/** + * Create a uint64 from a boolean value. True is 1, False is 0 + */ +export function Uint64(v: boolean): uint64 +export function Uint64(v?: Uint64Compat | string): uint64 { + if (typeof v === 'string') { + v = BigInt(v) + } + return Uint64Cls.fromCompat(v ?? 0).asAlgoTs() +} + +/** + * Create a biguint from a bigint literal + */ +export function BigUint(v: bigint): biguint +/** + * Create a biguint from a boolean value (true = 1, false = 0) + */ +export function BigUint(v: boolean): biguint +/** + * Create a biguint from a uint64 value + */ +export function BigUint(v: uint64): biguint +/** + * Create a biguint from a number literal + */ +export function BigUint(v: number): biguint +/** + * Create a biguint from a byte array interpreted as a big-endian number + */ +export function BigUint(v: bytes): biguint +/** + * Create a biguint from a string literal containing the decimal digits + */ +export function BigUint(v: string): biguint +/** + * Create a biguint with the default value of 0 + */ +export function BigUint(): biguint +export function BigUint(v?: BigUintCompat | string): biguint { + if (typeof v === 'string') v = BigInt(v) + else if (v === undefined) v = 0n + return BigUintCls.fromCompat(v).asAlgoTs() +} + +/** + * Create a byte array from a string interpolation template and compatible replacements + * @param value + * @param replacements + */ +export function Bytes(value: TemplateStringsArray, ...replacements: BytesCompat[]): bytes +/** + * Create a byte array from a utf8 string + */ +export function Bytes(value: string): bytes +/** + * No op, returns the provided byte array. + */ +export function Bytes(value: bytes): bytes +/** + * Create a byte array from a biguint value encoded as a variable length big-endian number + */ +export function Bytes(value: biguint): bytes +/** + * Create a byte array from a uint64 value encoded as a fixed length 64-bit number + */ +export function Bytes(value: uint64): bytes +/** + * Create a byte array from an Iterable where each item is interpreted as a single byte and must be between 0 and 255 inclusively + */ +export function Bytes(value: Iterable): bytes +/** + * Create an empty byte array + */ +export function Bytes(): bytes +export function Bytes( + value?: BytesCompat | TemplateStringsArray | biguint | uint64 | Iterable, + ...replacements: BytesCompat[] +): bytes { + if (isTemplateStringsArray(value)) { + return BytesCls.fromInterpolation(value, replacements).asAlgoTs() + } else if (typeof value === 'bigint' || value instanceof BigUintCls) { + return BigUintCls.fromCompat(value).toBytes().asAlgoTs() + } else if (typeof value === 'number' || value instanceof Uint64Cls) { + return Uint64Cls.fromCompat(value).toBytes().asAlgoTs() + } else if (typeof value === 'object' && Symbol.iterator in value) { + const valueItems = Array.from(value).map((v) => getNumber(v)) + const invalidValue = valueItems.find((v) => v < 0 && v > 255) + if (invalidValue) { + throw new CodeError(`Cannot convert ${invalidValue} to a byte`) + } + return new BytesCls(new Uint8Array(value)).asAlgoTs() + } else { + return BytesCls.fromCompat(value).asAlgoTs() + } +} + +/** + * Create a new bytes value from a hexadecimal encoded string + * @param hex + */ +Bytes.fromHex = (hex: string): bytes => { + return BytesCls.fromHex(hex).asAlgoTs() +} +/** + * Create a new bytes value from a base 64 encoded string + * @param b64 + */ +Bytes.fromBase64 = (b64: string): bytes => { + return BytesCls.fromBase64(b64).asAlgoTs() +} + +/** + * Create a new bytes value from a base 32 encoded string + * @param b32 + */ +Bytes.fromBase32 = (b32: string): bytes => { + return BytesCls.fromBase32(b32).asAlgoTs() +} + +/** + * Convert a StubUint64Compat value into a 'number' if possible. + * This value may be negative + * @param v + */ +export const getNumber = (v: StubUint64Compat): number => { + if (typeof v == 'boolean') return v ? 1 : 0 + if (typeof v == 'number') return v + if (typeof v == 'bigint') { + avmInvariant( + v <= BigInt(Number.MAX_SAFE_INTEGER) && v >= BigInt(Number.MIN_SAFE_INTEGER), + 'value cannot be safely converted to a number', + ) + return Number(v) + } + if (v instanceof Uint64Cls) return v.asNumber() + throw new InternalError(`Cannot convert ${v} to number`) +} + +export const getUint8Array = (v: StubBytesCompat): Uint8Array => { + return BytesCls.fromCompat(v).asUint8Array() +} + +export const isBytes = (v: unknown): v is StubBytesCompat => { + if (typeof v === 'string') return true + if (v instanceof BytesCls) return true + return v instanceof Uint8Array +} + +export const isUint64 = (v: unknown): v is StubUint64Compat => { + if (typeof v == 'number') return true + if (typeof v == 'bigint') return true + return v instanceof Uint64Cls +} + +export const checkUint64 = (v: bigint): bigint => { + const u64 = BigInt.asUintN(64, v) + if (u64 !== v) throw new AvmError(`Uint64 overflow or underflow`) + return u64 +} +export const checkBigUint = (v: bigint): bigint => { + const uBig = BigInt.asUintN(64 * 8, v) + if (uBig !== v) throw new AvmError(`BigUint overflow or underflow`) + return uBig +} + +export const checkBytes = (v: Uint8Array): Uint8Array => { + if (v.length > MAX_BYTES_SIZE) throw new AvmError(`Bytes length ${v.length} exceeds maximum length ${MAX_BYTES_SIZE}`) + return v +} + +/** + * Verifies that an object is an instance of a type based on its name rather than reference equality. + * + * This is useful in scenarios where a module loader has loaded a module twice and hence two instances of a + * type do not have reference equality on their constructors. + * @param subject The object to check + * @param typeCtor The ctor of the type + */ +function isInstanceOfTypeByName(subject: unknown, typeCtor: { name: string }): boolean { + if (subject === null || typeof subject !== 'object') return false + + let ctor = subject.constructor + while (typeof ctor === 'function') { + if (ctor.name === typeCtor.name) return true + ctor = Object.getPrototypeOf(ctor) + } + return false +} + +export abstract class AlgoTsPrimitiveCls { + static [Symbol.hasInstance](x: unknown): x is AlgoTsPrimitiveCls { + return isInstanceOfTypeByName(x, AlgoTsPrimitiveCls) + } + + abstract valueOf(): bigint | string + abstract toBytes(): BytesCls +} + +export function Uint64Impl(v?: Uint64Compat | string): uint64 { + if (typeof v === 'string') { + v = BigInt(v) + } + return Uint64Cls.fromCompat(v ?? 0).asAlgoTs() +} +export class Uint64Cls extends AlgoTsPrimitiveCls { + readonly #value: bigint + constructor(value: bigint | number | string) { + super() + this.#value = BigInt(value) + checkUint64(this.#value) + + Object.defineProperty(this, 'uint64', { + value: this.#value.toString(), + writable: false, + enumerable: true, + }) + } + static [Symbol.hasInstance](x: unknown): x is Uint64Cls { + return isInstanceOfTypeByName(x, Uint64Cls) + } + static fromCompat(v: StubUint64Compat): Uint64Cls { + if (typeof v == 'boolean') return new Uint64Cls(v ? 1n : 0n) + if (typeof v == 'number') return new Uint64Cls(BigInt(v)) + if (typeof v == 'bigint') return new Uint64Cls(v) + if (v instanceof Uint64Cls) return v + throw new InternalError(`Cannot convert ${v} to uint64`) + } + + valueOf(): bigint { + return this.#value + } + + toBytes(): BytesCls { + return new BytesCls(encodingUtil.bigIntToUint8Array(this.#value, 8)) + } + + asAlgoTs(): uint64 { + return this as unknown as uint64 + } + + asBigInt(): bigint { + return this.#value + } + asNumber(): number { + if (this.#value > Number.MAX_SAFE_INTEGER) { + throw new AvmError('value cannot be safely converted to a number') + } + return Number(this.#value) + } + toString(): string { + return this.#value.toString() + } +} + +export function BigUintImpl(v?: BigUintCompat | string): biguint { + if (typeof v === 'string') v = BigInt(v) + else if (v === undefined) v = 0n + return BigUintCls.fromCompat(v).asAlgoTs() +} +export class BigUintCls extends AlgoTsPrimitiveCls { + readonly #value: bigint + constructor(value: bigint) { + super() + this.#value = value + Object.defineProperty(this, 'biguint', { + value: value.toString(), + writable: false, + enumerable: true, + }) + } + valueOf(): bigint { + return this.#value + } + + toBytes(): BytesCls { + return new BytesCls(encodingUtil.bigIntToUint8Array(this.#value)) + } + + asAlgoTs(): biguint { + return this as unknown as biguint + } + + asBigInt(): bigint { + return this.#value + } + asNumber(): number { + if (this.#value > Number.MAX_SAFE_INTEGER) { + throw new AvmError('value cannot be safely converted to a number') + } + return Number(this.#value) + } + static [Symbol.hasInstance](x: unknown): x is BigUintCls { + return isInstanceOfTypeByName(x, BigUintCls) + } + static fromCompat(v: StubBigUintCompat): BigUintCls { + if (typeof v == 'boolean') return new BigUintCls(v ? 1n : 0n) + if (typeof v == 'number') return new BigUintCls(BigInt(v)) + if (typeof v == 'bigint') return new BigUintCls(v) + if (v instanceof Uint64Cls) return new BigUintCls(v.valueOf()) + if (v instanceof BytesCls) return v.toBigUint() + if (v instanceof BigUintCls) return v + throw new InternalError(`Cannot convert ${nameOfType(v)} to BigUint`) + } +} + +export function BytesImpl( + value?: BytesCompat | TemplateStringsArray | biguint | uint64 | Iterable, + ...replacements: BytesCompat[] +): bytes { + if (isTemplateStringsArray(value)) { + return BytesCls.fromInterpolation(value, replacements).asAlgoTs() + } else if (typeof value === 'bigint' || value instanceof BigUintCls) { + return BigUintCls.fromCompat(value).toBytes().asAlgoTs() + } else if (typeof value === 'number' || value instanceof Uint64Cls) { + return Uint64Cls.fromCompat(value).toBytes().asAlgoTs() + } else if (typeof value === 'object' && Symbol.iterator in value) { + const valueItems = Array.from(value).map((v) => getNumber(v)) + const invalidValue = valueItems.find((v) => v < 0 && v > 255) + if (invalidValue) { + throw new CodeError(`Cannot convert ${invalidValue} to a byte`) + } + return new BytesCls(new Uint8Array(value)).asAlgoTs() + } else { + return BytesCls.fromCompat(value).asAlgoTs() + } +} + +/** + * Create a new bytes value from a hexadecimal encoded string + * @param hex + */ +export const fromHexImpl = (hex: string): bytes => { + return BytesCls.fromHex(hex).asAlgoTs() +} +/** + * Create a new bytes value from a base 64 encoded string + * @param b64 + */ +export const fromBase64Impl = (b64: string): bytes => { + return BytesCls.fromBase64(b64).asAlgoTs() +} + +/** + * Create a new bytes value from a base 32 encoded string + * @param b32 + */ +export const fromBase32Impl = (b32: string): bytes => { + return BytesCls.fromBase32(b32).asAlgoTs() +} + +function isTemplateStringsArray(v: unknown): v is TemplateStringsArray { + return Boolean(v) && Array.isArray(v) && typeof v[0] === 'string' +} + +export class BytesCls extends AlgoTsPrimitiveCls { + readonly #v: Uint8Array + constructor(v: Uint8Array) { + super() + this.#v = v + checkBytes(this.#v) + // Add an enumerable property for debugging code to show + Object.defineProperty(this, 'bytes', { + value: encodingUtil.uint8ArrayToHex(this.#v), + writable: false, + enumerable: true, + }) + } + + get length() { + return new Uint64Cls(this.#v.length) + } + + toBytes(): BytesCls { + return this + } + + at(i: StubUint64Compat): BytesCls { + return new BytesCls(arrayUtil.arrayAt(this.#v, i)) + } + + slice(start?: StubUint64Compat, end?: StubUint64Compat): BytesCls { + const sliced = arrayUtil.arraySlice(this.#v, start, end) + return new BytesCls(sliced) + } + + concat(other: StubBytesCompat): BytesCls { + const otherArray = BytesCls.fromCompat(other).asUint8Array() + const mergedArray = new Uint8Array(this.#v.length + otherArray.length) + mergedArray.set(this.#v) + mergedArray.set(otherArray, this.#v.length) + return new BytesCls(mergedArray) + } + + bitwiseAnd(other: StubBytesCompat): BytesCls { + return this.bitwiseOp(other, (a, b) => a & b) + } + + bitwiseOr(other: StubBytesCompat): BytesCls { + return this.bitwiseOp(other, (a, b) => a | b) + } + + bitwiseXor(other: StubBytesCompat): BytesCls { + return this.bitwiseOp(other, (a, b) => a ^ b) + } + + bitwiseInvert(): BytesCls { + const result = new Uint8Array(this.#v.length) + this.#v.forEach((v, i) => { + result[i] = ~v & MAX_UINT8 + }) + return new BytesCls(result) + } + + equals(other: StubBytesCompat): boolean { + const otherArray = BytesCls.fromCompat(other).asUint8Array() + if (this.#v.length !== otherArray.length) return false + for (let i = 0; i < this.#v.length; i++) { + if (this.#v[i] !== otherArray[i]) return false + } + return true + } + + private bitwiseOp(other: StubBytesCompat, op: (a: number, b: number) => number): BytesCls { + const otherArray = BytesCls.fromCompat(other).asUint8Array() + const result = new Uint8Array(Math.max(this.#v.length, otherArray.length)) + for (let i = result.length - 1; i >= 0; i--) { + const thisIndex = i - (result.length - this.#v.length) + const otherIndex = i - (result.length - otherArray.length) + result[i] = op(this.#v[thisIndex] ?? 0, otherArray[otherIndex] ?? 0) + } + return new BytesCls(result) + } + + valueOf(): string { + return encodingUtil.uint8ArrayToHex(this.#v) + } + + static [Symbol.hasInstance](x: unknown): x is BytesCls { + return isInstanceOfTypeByName(x, BytesCls) + } + + static fromCompat(v: StubBytesCompat | Uint8Array | undefined): BytesCls { + if (v === undefined) return new BytesCls(new Uint8Array()) + if (typeof v === 'string') return new BytesCls(encodingUtil.utf8ToUint8Array(v)) + if (v instanceof BytesCls) return v + if (v instanceof Uint8Array) return new BytesCls(v) + throw new InternalError(`Cannot convert ${nameOfType(v)} to bytes`) + } + + static fromInterpolation(template: TemplateStringsArray, replacements: StubBytesCompat[]) { + return template + .flatMap((templateText, index) => { + const replacement = replacements[index] + if (replacement) { + return [BytesCls.fromCompat(templateText), BytesCls.fromCompat(replacement)] + } + return [BytesCls.fromCompat(templateText)] + }) + .reduce((a, b) => a.concat(b)) + } + + static fromHex(hex: string): BytesCls { + return new BytesCls(encodingUtil.hexToUint8Array(hex)) + } + + static fromBase64(b64: string): BytesCls { + return new BytesCls(encodingUtil.base64ToUint8Array(b64)) + } + + static fromBase32(b32: string): BytesCls { + return new BytesCls(base32ToUint8Array(b32)) + } + + toUint64(): Uint64Cls { + return new Uint64Cls(encodingUtil.uint8ArrayToBigInt(this.#v)) + } + + toBigUint(): BigUintCls { + return new BigUintCls(encodingUtil.uint8ArrayToBigInt(this.#v)) + } + + toString(): string { + return encodingUtil.uint8ArrayToUtf8(this.#v) + } + + asAlgoTs(): bytes { + return this as unknown as bytes + } + + asUint8Array(): Uint8Array { + return this.#v + } +} + +export const arrayUtil = new (class ArrayUtil { + arrayAt(arrayLike: Uint8Array, index: StubUint64Compat): Uint8Array + arrayAt(arrayLike: T[], index: StubUint64Compat): T + arrayAt(arrayLike: T[] | Uint8Array, index: StubUint64Compat): T | Uint8Array + arrayAt(arrayLike: T[] | Uint8Array, index: StubUint64Compat): T | Uint8Array { + const indexNum = getNumber(index) + if (arrayLike instanceof Uint8Array) { + const res = arrayLike.slice(indexNum, indexNum === -1 ? undefined : indexNum + 1) + avmInvariant(res.length, 'Index out of bounds') + return res + } + return arrayLike.at(indexNum) ?? avmError('Index out of bounds') + } + arraySlice(arrayLike: Uint8Array, start: undefined | StubUint64Compat, end: undefined | StubUint64Compat): Uint8Array + arraySlice(arrayLike: T[], start: undefined | StubUint64Compat, end: undefined | StubUint64Compat): T[] + arraySlice(arrayLike: T[] | Uint8Array, start: undefined | StubUint64Compat, end: undefined | StubUint64Compat): Uint8Array | T[] + arraySlice(arrayLike: T[] | Uint8Array, start: undefined | StubUint64Compat, end: undefined | StubUint64Compat) { + const startNum = start === undefined ? undefined : getNumber(start) + const endNum = end === undefined ? undefined : getNumber(end) + if (arrayLike instanceof Uint8Array) { + return arrayLike.slice(startNum, endNum) + } else { + return arrayLike.slice(startNum, endNum) + } + } +})() diff --git a/src/impl/pure.ts b/src/impl/pure.ts index c81a94b..72800ed 100644 --- a/src/impl/pure.ts +++ b/src/impl/pure.ts @@ -1,30 +1,33 @@ -import { Base64, biguint, Bytes, bytes, internal, Uint64, uint64 } from '@algorandfoundation/algorand-typescript' +import type { biguint, bytes, op, uint64 } from '@algorandfoundation/algorand-typescript' +import { Base64 } from '@algorandfoundation/algorand-typescript' import { BITS_IN_BYTE, MAX_BYTES_SIZE, MAX_UINT64, MAX_UINT8, UINT64_SIZE } from '../constants' -import { notImplementedError, testInvariant } from '../errors' +import { AvmError, CodeError, NotImplementedError, testInvariant } from '../errors' import { asBigUint, asBytes, asBytesCls, asMaybeBytesCls, asMaybeUint64Cls, asUint64Cls, binaryStringToBytes } from '../util' +import type { StubBigUintCompat, StubBytesCompat, StubUint64Compat } from './primitives' +import { BigUintCls, Bytes, BytesCls, checkBigUint, isUint64, Uint64, Uint64Cls } from './primitives' -export const addw = (a: internal.primitives.StubUint64Compat, b: internal.primitives.StubUint64Compat): readonly [uint64, uint64] => { - const uint64A = internal.primitives.Uint64Cls.fromCompat(a) - const uint64B = internal.primitives.Uint64Cls.fromCompat(b) +export const addw = (a: StubUint64Compat, b: StubUint64Compat): readonly [uint64, uint64] => { + const uint64A = Uint64Cls.fromCompat(a) + const uint64B = Uint64Cls.fromCompat(b) const sum = uint64A.asBigInt() + uint64B.asBigInt() return toUint128(sum) } -export const base64Decode = (e: Base64, a: internal.primitives.StubBytesCompat): bytes => { +export const base64Decode = (e: Base64, a: StubBytesCompat): bytes => { const encoding = e === Base64.StdEncoding ? 'base64' : 'base64url' - const bytesValue = internal.primitives.BytesCls.fromCompat(a) + const bytesValue = BytesCls.fromCompat(a) const stringValue = bytesValue.toString() const bufferResult = Buffer.from(stringValue, encoding) if (bufferResult.toString(encoding) !== stringValue) { - internal.errors.avmError('illegal base64 data') + throw new AvmError('illegal base64 data') } const uint8ArrayResult = new Uint8Array(bufferResult) return Bytes(uint8ArrayResult) } -export const bitLength = (a: internal.primitives.StubUint64Compat | internal.primitives.StubBytesCompat): uint64 => { +export const bitLength = (a: StubUint64Compat | StubBytesCompat): uint64 => { const uint64Cls = asMaybeUint64Cls(a) const bigUintCls = asMaybeBytesCls(a)?.toBigUint() const bigIntValue = (uint64Cls?.asBigInt() ?? bigUintCls?.asBigInt())! @@ -32,40 +35,40 @@ export const bitLength = (a: internal.primitives.StubUint64Compat | internal.pri return Uint64(binaryValue.length) } -export const bsqrt = (a: internal.primitives.StubBigUintCompat): biguint => { - const bigUintClsValue = internal.primitives.BigUintCls.fromCompat(a) - const bigintValue = internal.primitives.checkBigUint(bigUintClsValue.asBigInt()) +export const bsqrt = (a: StubBigUintCompat): biguint => { + const bigUintClsValue = BigUintCls.fromCompat(a) + const bigintValue = checkBigUint(bigUintClsValue.asBigInt()) const sqrtValue = squareroot(bigintValue) return asBigUint(sqrtValue) } -export const btoi = (a: internal.primitives.StubBytesCompat): uint64 => { - const bytesValue = internal.primitives.BytesCls.fromCompat(a) +export const btoi = (a: StubBytesCompat): uint64 => { + const bytesValue = BytesCls.fromCompat(a) if (bytesValue.length.asAlgoTs() > BITS_IN_BYTE) { - internal.errors.avmError(`btoi arg too long, got [${bytesValue.length.valueOf()}]bytes`) + throw new AvmError(`btoi arg too long, got [${bytesValue.length.valueOf()}]bytes`) } return bytesValue.toUint64().asAlgoTs() } -export const bzero = (a: internal.primitives.StubUint64Compat): bytes => { - const size = internal.primitives.Uint64Cls.fromCompat(a).asBigInt() +export const bzero = (a: StubUint64Compat): bytes => { + const size = Uint64Cls.fromCompat(a).asBigInt() if (size > MAX_BYTES_SIZE) { - internal.errors.avmError('bzero attempted to create a too large string') + throw new AvmError('bzero attempted to create a too large string') } return Bytes(new Uint8Array(Number(size))) } -export const concat = (a: internal.primitives.StubBytesCompat, b: internal.primitives.StubBytesCompat): bytes => { - const bytesA = internal.primitives.BytesCls.fromCompat(a) - const bytesB = internal.primitives.BytesCls.fromCompat(b) +export const concat = (a: StubBytesCompat, b: StubBytesCompat): bytes => { + const bytesA = BytesCls.fromCompat(a) + const bytesB = BytesCls.fromCompat(b) return bytesA.concat(bytesB).asAlgoTs() } export const divmodw = ( - a: internal.primitives.StubUint64Compat, - b: internal.primitives.StubUint64Compat, - c: internal.primitives.StubUint64Compat, - d: internal.primitives.StubUint64Compat, + a: StubUint64Compat, + b: StubUint64Compat, + c: StubUint64Compat, + d: StubUint64Compat, ): readonly [uint64, uint64, uint64, uint64] => { const i = uint128ToBigInt(a, b) const j = uint128ToBigInt(c, d) @@ -75,128 +78,112 @@ export const divmodw = ( return [...toUint128(div), ...toUint128(mod)] } -export const divw = ( - a: internal.primitives.StubUint64Compat, - b: internal.primitives.StubUint64Compat, - c: internal.primitives.StubUint64Compat, -): uint64 => { +export const divw = (a: StubUint64Compat, b: StubUint64Compat, c: StubUint64Compat): uint64 => { const i = uint128ToBigInt(a, b) - const j = internal.primitives.Uint64Cls.fromCompat(c).asBigInt() + const j = Uint64Cls.fromCompat(c).asBigInt() return Uint64(i / j) } -export const exp = (a: internal.primitives.StubUint64Compat, b: internal.primitives.StubUint64Compat): uint64 => { - const base = internal.primitives.Uint64Cls.fromCompat(a).asBigInt() - const exponent = internal.primitives.Uint64Cls.fromCompat(b).asBigInt() +export const exp = (a: StubUint64Compat, b: StubUint64Compat): uint64 => { + const base = Uint64Cls.fromCompat(a).asBigInt() + const exponent = Uint64Cls.fromCompat(b).asBigInt() if (base === 0n && exponent === 0n) { - throw internal.errors.codeError('0 ** 0 is undefined') + throw new CodeError('0 ** 0 is undefined') } return Uint64(base ** exponent) } -export const expw = (a: internal.primitives.StubUint64Compat, b: internal.primitives.StubUint64Compat): readonly [uint64, uint64] => { - const base = internal.primitives.Uint64Cls.fromCompat(a).asBigInt() - const exponent = internal.primitives.Uint64Cls.fromCompat(b).asBigInt() +export const expw = (a: StubUint64Compat, b: StubUint64Compat): readonly [uint64, uint64] => { + const base = Uint64Cls.fromCompat(a).asBigInt() + const exponent = Uint64Cls.fromCompat(b).asBigInt() if (base === 0n && exponent === 0n) { - throw internal.errors.codeError('0 ** 0 is undefined') + throw new CodeError('0 ** 0 is undefined') } return toUint128(base ** exponent) } -export const extract = ( - a: internal.primitives.StubBytesCompat, - b: internal.primitives.StubUint64Compat, - c: internal.primitives.StubUint64Compat, -): bytes => { - const bytesValue = internal.primitives.BytesCls.fromCompat(a) +type ExtractType = ((a: StubBytesCompat, b: StubUint64Compat) => bytes) & + ((a: StubBytesCompat, b: StubUint64Compat, c: StubUint64Compat) => bytes) +export const extract = ((a: StubBytesCompat, b: StubUint64Compat, c?: StubUint64Compat): bytes => { + const bytesValue = BytesCls.fromCompat(a) const bytesLength = bytesValue.length.asBigInt() - const start = internal.primitives.Uint64Cls.fromCompat(b).asBigInt() - const length = internal.primitives.Uint64Cls.fromCompat(c).asBigInt() - let end = start + length - if ((typeof b === 'number' || typeof b === 'bigint') && (typeof c === 'number' || typeof c === 'bigint') && length === 0n) { - end = bytesLength - } + const start = Uint64Cls.fromCompat(b).asBigInt() + const length = c !== undefined ? Uint64Cls.fromCompat(c).asBigInt() : undefined + const end = length !== undefined ? start + length : undefined if (start > bytesLength) { - internal.errors.codeError(`extraction start ${start} is beyond length`) + throw new CodeError(`extraction start ${start} is beyond length`) } - if (end > bytesLength) { - internal.errors.codeError(`extraction end ${end} is beyond length`) + if (end !== undefined && end > bytesLength) { + throw new CodeError(`extraction end ${end} is beyond length`) } return bytesValue.slice(start, end).asAlgoTs() -} +}) as ExtractType -export const extractUint16 = (a: internal.primitives.StubBytesCompat, b: internal.primitives.StubUint64Compat): uint64 => { +export const extractUint16 = (a: StubBytesCompat, b: StubUint64Compat): uint64 => { const result = extract(a, b, 2) - const bytesResult = internal.primitives.BytesCls.fromCompat(result) + const bytesResult = BytesCls.fromCompat(result) return bytesResult.toUint64().asAlgoTs() } -export const extractUint32 = (a: internal.primitives.StubBytesCompat, b: internal.primitives.StubUint64Compat): uint64 => { +export const extractUint32 = (a: StubBytesCompat, b: StubUint64Compat): uint64 => { const result = extract(a, b, 4) - const bytesResult = internal.primitives.BytesCls.fromCompat(result) + const bytesResult = BytesCls.fromCompat(result) return bytesResult.toUint64().asAlgoTs() } -export const extractUint64 = (a: internal.primitives.StubBytesCompat, b: internal.primitives.StubUint64Compat): uint64 => { +export const extractUint64 = (a: StubBytesCompat, b: StubUint64Compat): uint64 => { const result = extract(a, b, 8) - const bytesResult = internal.primitives.BytesCls.fromCompat(result) + const bytesResult = BytesCls.fromCompat(result) return bytesResult.toUint64().asAlgoTs() } -export const getBit = ( - a: internal.primitives.StubUint64Compat | internal.primitives.StubBytesCompat, - b: internal.primitives.StubUint64Compat, -): uint64 => { - const binaryString = toBinaryString(internal.primitives.isUint64(a) ? asUint64Cls(a).toBytes().asAlgoTs() : asBytes(a)) - const index = internal.primitives.Uint64Cls.fromCompat(b).asNumber() +export const getBit = (a: StubUint64Compat | StubBytesCompat, b: StubUint64Compat): uint64 => { + const binaryString = toBinaryString(isUint64(a) ? asUint64Cls(a).toBytes().asAlgoTs() : asBytes(a)) + const index = Uint64Cls.fromCompat(b).asNumber() const adjustedIndex = asMaybeUint64Cls(a) ? binaryString.length - index - 1 : index if (adjustedIndex < 0 || adjustedIndex >= binaryString.length) { - internal.errors.codeError(`getBit index ${index} is beyond length`) + throw new CodeError(`getBit index ${index} is beyond length`) } - return binaryString[adjustedIndex] === '1' ? Uint64(1) : Uint64(0) + return binaryString[adjustedIndex] === '1' ? 1 : 0 } -export const getByte = (a: internal.primitives.StubBytesCompat, b: internal.primitives.StubUint64Compat): uint64 => { - const bytesValue = internal.primitives.BytesCls.fromCompat(a) - const index = internal.primitives.Uint64Cls.fromCompat(b).asNumber() +export const getByte = (a: StubBytesCompat, b: StubUint64Compat): uint64 => { + const bytesValue = BytesCls.fromCompat(a) + const index = Uint64Cls.fromCompat(b).asNumber() if (index >= bytesValue.length.asNumber()) { - internal.errors.codeError(`getBytes index ${index} is beyond length`) + throw new CodeError(`getBytes index ${index} is beyond length`) } return bytesValue.at(index).toUint64().asAlgoTs() } -export const itob = (a: internal.primitives.StubUint64Compat): bytes => { +export const itob = (a: StubUint64Compat): bytes => { return asUint64Cls(a).toBytes().asAlgoTs() } -export const len = (a: internal.primitives.StubBytesCompat): uint64 => { +export const len = (a: StubBytesCompat): uint64 => { return asBytesCls(a).length.asAlgoTs() } -export const mulw = (a: internal.primitives.StubUint64Compat, b: internal.primitives.StubUint64Compat): readonly [uint64, uint64] => { - const uint64A = internal.primitives.Uint64Cls.fromCompat(a) - const uint64B = internal.primitives.Uint64Cls.fromCompat(b) +export const mulw = (a: StubUint64Compat, b: StubUint64Compat): readonly [uint64, uint64] => { + const uint64A = Uint64Cls.fromCompat(a) + const uint64B = Uint64Cls.fromCompat(b) const product = uint64A.asBigInt() * uint64B.asBigInt() return toUint128(product) } -export const replace = ( - a: internal.primitives.StubBytesCompat, - b: internal.primitives.StubUint64Compat, - c: internal.primitives.StubBytesCompat, -): bytes => { - const bytesValue = internal.primitives.BytesCls.fromCompat(a) - const index = internal.primitives.Uint64Cls.fromCompat(b).asNumber() - const replacement = internal.primitives.BytesCls.fromCompat(c) +export const replace = (a: StubBytesCompat, b: StubUint64Compat, c: StubBytesCompat): bytes => { + const bytesValue = BytesCls.fromCompat(a) + const index = Uint64Cls.fromCompat(b).asNumber() + const replacement = BytesCls.fromCompat(c) const valueLength = bytesValue.length.asNumber() const replacementLength = replacement.length.asNumber() if (index + replacementLength > valueLength) { - internal.errors.codeError(`expected value <= ${valueLength}, got: ${index + replacementLength}`) + throw new CodeError(`expected value <= ${valueLength}, got: ${index + replacementLength}`) } return bytesValue .slice(0, index) @@ -205,45 +192,29 @@ export const replace = ( .asAlgoTs() } -type selectType = (( - a: internal.primitives.StubBytesCompat, - b: internal.primitives.StubBytesCompat, - c: internal.primitives.StubUint64Compat, -) => bytes) & - ((a: internal.primitives.StubUint64Compat, b: internal.primitives.StubUint64Compat, c: internal.primitives.StubUint64Compat) => uint64) +type selectType = ((a: StubBytesCompat, b: StubBytesCompat, c: StubUint64Compat) => bytes) & + ((a: StubUint64Compat, b: StubUint64Compat, c: StubUint64Compat) => uint64) export const select = (( - a: internal.primitives.StubUint64Compat | internal.primitives.StubBytesCompat, - b: internal.primitives.StubUint64Compat | internal.primitives.StubBytesCompat, - c: internal.primitives.StubUint64Compat, + a: StubUint64Compat | StubBytesCompat, + b: StubUint64Compat | StubBytesCompat, + c: StubUint64Compat, ): uint64 | bytes => { const uint64A = asMaybeUint64Cls(a) const uint64B = asMaybeUint64Cls(b) const bytesA = asMaybeBytesCls(a) const bytesB = asMaybeBytesCls(b) - const bigIntC = internal.primitives.Uint64Cls.fromCompat(c).asBigInt() + const bigIntC = Uint64Cls.fromCompat(c).asBigInt() return (bigIntC !== 0n ? (uint64B ?? bytesB)! : (uint64A ?? bytesA)!).asAlgoTs() }) as selectType -type SetBitType = (( - target: internal.primitives.StubBytesCompat, - n: internal.primitives.StubUint64Compat, - c: internal.primitives.StubUint64Compat, -) => bytes) & - (( - target: internal.primitives.StubUint64Compat, - n: internal.primitives.StubUint64Compat, - c: internal.primitives.StubUint64Compat, - ) => uint64) - -export const setBit = (( - a: internal.primitives.StubUint64Compat | internal.primitives.StubBytesCompat, - b: internal.primitives.StubUint64Compat, - c: internal.primitives.StubUint64Compat, -) => { +type SetBitType = ((target: StubBytesCompat, n: StubUint64Compat, c: StubUint64Compat) => bytes) & + ((target: StubUint64Compat, n: StubUint64Compat, c: StubUint64Compat) => uint64) + +export const setBit = ((a: StubUint64Compat | StubBytesCompat, b: StubUint64Compat, c: StubUint64Compat) => { const uint64Cls = asMaybeUint64Cls(a) - const indexParam = internal.primitives.Uint64Cls.fromCompat(b).asNumber() - const bit = internal.primitives.Uint64Cls.fromCompat(c).asNumber() + const indexParam = Uint64Cls.fromCompat(b).asNumber() + const bit = Uint64Cls.fromCompat(c).asNumber() if (uint64Cls) { const binaryString = toBinaryString(uint64Cls?.toBytes().asAlgoTs()) const index = binaryString.length - indexParam - 1 @@ -258,80 +229,72 @@ export const setBit = (( } }) as SetBitType -export const setByte = ( - a: internal.primitives.StubBytesCompat, - b: internal.primitives.StubUint64Compat, - c: internal.primitives.StubUint64Compat, -): bytes => { - const binaryString = toBinaryString(internal.primitives.BytesCls.fromCompat(a).asAlgoTs()) +export const setByte = (a: StubBytesCompat, b: StubUint64Compat, c: StubUint64Compat): bytes => { + const binaryString = toBinaryString(BytesCls.fromCompat(a).asAlgoTs()) - const byteIndex = internal.primitives.Uint64Cls.fromCompat(b).asNumber() + const byteIndex = Uint64Cls.fromCompat(b).asNumber() const bitIndex = byteIndex * BITS_IN_BYTE - const replacementNumber = internal.primitives.Uint64Cls.fromCompat(c) + const replacementNumber = Uint64Cls.fromCompat(c) const replacement = toBinaryString(replacementNumber.toBytes().at(-1).asAlgoTs()) if (bitIndex >= binaryString.length) { - internal.errors.codeError(`setByte index ${byteIndex} is beyond length`) + throw new CodeError(`setByte index ${byteIndex} is beyond length`) } if (replacementNumber.valueOf() > MAX_UINT8) { - internal.errors.codeError(`setByte value ${replacementNumber.asNumber()} > ${MAX_UINT8}`) + throw new CodeError(`setByte value ${replacementNumber.asNumber()} > ${MAX_UINT8}`) } const updatedString = binaryString.slice(0, bitIndex) + replacement + binaryString.slice(bitIndex + replacement.length) const updatedBytes = binaryStringToBytes(updatedString) return updatedBytes.asAlgoTs() } -export const shl = (a: internal.primitives.StubUint64Compat, b: internal.primitives.StubUint64Compat): uint64 => { - const uint64A = internal.primitives.Uint64Cls.fromCompat(a) - const uint64B = internal.primitives.Uint64Cls.fromCompat(b) +export const shl = (a: StubUint64Compat, b: StubUint64Compat): uint64 => { + const uint64A = Uint64Cls.fromCompat(a) + const uint64B = Uint64Cls.fromCompat(b) const bigIntA = uint64A.asBigInt() const bigIntB = uint64B.asBigInt() if (bigIntB >= UINT64_SIZE) { - internal.errors.codeError(`shl value ${bigIntB} >= ${UINT64_SIZE}`) + throw new CodeError(`shl value ${bigIntB} >= ${UINT64_SIZE}`) } const shifted = (bigIntA * 2n ** bigIntB) % 2n ** BigInt(UINT64_SIZE) return Uint64(shifted) } -export const shr = (a: internal.primitives.StubUint64Compat, b: internal.primitives.StubUint64Compat): uint64 => { - const uint64A = internal.primitives.Uint64Cls.fromCompat(a) - const uint64B = internal.primitives.Uint64Cls.fromCompat(b) +export const shr = (a: StubUint64Compat, b: StubUint64Compat): uint64 => { + const uint64A = Uint64Cls.fromCompat(a) + const uint64B = Uint64Cls.fromCompat(b) const bigIntA = uint64A.asBigInt() const bigIntB = uint64B.asBigInt() if (bigIntB >= UINT64_SIZE) { - internal.errors.codeError(`shr value ${bigIntB} >= ${UINT64_SIZE}`) + throw new CodeError(`shr value ${bigIntB} >= ${UINT64_SIZE}`) } const shifted = bigIntA / 2n ** bigIntB return Uint64(shifted) } -export const sqrt = (a: internal.primitives.StubUint64Compat): uint64 => { - const bigIntValue = internal.primitives.Uint64Cls.fromCompat(a).asBigInt() +export const sqrt = (a: StubUint64Compat): uint64 => { + const bigIntValue = Uint64Cls.fromCompat(a).asBigInt() const sqrtValue = squareroot(bigIntValue) return Uint64(sqrtValue) } -export const substring = ( - a: internal.primitives.StubBytesCompat, - b: internal.primitives.StubUint64Compat, - c: internal.primitives.StubUint64Compat, -): bytes => { - const bytesValue = internal.primitives.BytesCls.fromCompat(a) - const start = internal.primitives.Uint64Cls.fromCompat(b).asBigInt() - const end = internal.primitives.Uint64Cls.fromCompat(c).asBigInt() +export const substring = (a: StubBytesCompat, b: StubUint64Compat, c: StubUint64Compat): bytes => { + const bytesValue = BytesCls.fromCompat(a) + const start = Uint64Cls.fromCompat(b).asBigInt() + const end = Uint64Cls.fromCompat(c).asBigInt() if (start > end) { - internal.errors.codeError('substring end before start') + throw new CodeError('substring end before start') } if (end > bytesValue.length.asNumber()) { - internal.errors.codeError('substring range beyond length of string') + throw new CodeError('substring range beyond length of string') } return bytesValue.slice(start, end).asAlgoTs() } -export const JsonRef = new Proxy({} as internal.opTypes.JsonRefType, { +export const JsonRef = new Proxy({} as typeof op.JsonRef, { get: (_target, prop) => { - notImplementedError(`JsonRef.${prop.toString()}`) + throw new NotImplementedError(`JsonRef.${prop.toString()}`) }, }) @@ -352,22 +315,22 @@ const toUint128 = (value: bigint): [uint64, uint64] => { return [Uint64(cf), Uint64(rest)] } -const uint128ToBigInt = (a: internal.primitives.StubUint64Compat, b: internal.primitives.StubUint64Compat): bigint => { - const bigIntA = internal.primitives.Uint64Cls.fromCompat(a).asBigInt() - const bigIntB = internal.primitives.Uint64Cls.fromCompat(b).asBigInt() +const uint128ToBigInt = (a: StubUint64Compat, b: StubUint64Compat): bigint => { + const bigIntA = Uint64Cls.fromCompat(a).asBigInt() + const bigIntB = Uint64Cls.fromCompat(b).asBigInt() return (bigIntA << 64n) + bigIntB } const toBinaryString = (a: bytes): string => { - return [...internal.primitives.BytesCls.fromCompat(a).asUint8Array()].map((x) => x.toString(2).padStart(BITS_IN_BYTE, '0')).join('') + return [...BytesCls.fromCompat(a).asUint8Array()].map((x) => x.toString(2).padStart(BITS_IN_BYTE, '0')).join('') } -const doSetBit = (binaryString: string, index: number, bit: number): internal.primitives.BytesCls => { +const doSetBit = (binaryString: string, index: number, bit: number): BytesCls => { if (index < 0 || index >= binaryString.length) { - internal.errors.codeError(`setBit index ${index < 0 ? binaryString.length - index : index} is beyond length`) + throw new CodeError(`setBit index ${index < 0 ? binaryString.length - index : index} is beyond length`) } if (bit !== 0 && bit !== 1) { - internal.errors.codeError(`setBit value > 1`) + throw new CodeError(`setBit value > 1`) } const updatedString = binaryString.slice(0, index) + bit.toString() + binaryString.slice(index + 1) return binaryStringToBytes(updatedString) diff --git a/src/impl/reference.ts b/src/impl/reference.ts new file mode 100644 index 0000000..44a574b --- /dev/null +++ b/src/impl/reference.ts @@ -0,0 +1,339 @@ +import type { + Account as AccountType, + Application as ApplicationType, + Asset as AssetType, + bytes, + LocalState, + uint64, +} from '@algorandfoundation/algorand-typescript' +import { encodingUtil } from '@algorandfoundation/puya-ts' +import js_sha512 from 'js-sha512' +import type { AccountMap } from '../collections/custom-key-map' +import { BytesMap, Uint64Map } from '../collections/custom-key-map' +import { + ALGORAND_ADDRESS_BYTE_LENGTH, + ALGORAND_ADDRESS_LENGTH, + ALGORAND_CHECKSUM_BYTE_LENGTH, + ALWAYS_APPROVE_TEAL_PROGRAM, + APP_ID_PREFIX, + DEFAULT_ACCOUNT_MIN_BALANCE, + HASH_BYTES_LENGTH, + ZERO_ADDRESS, +} from '../constants' +import { lazyContext } from '../context-helpers/internal-context' +import { AvmError, InternalError } from '../errors' +import type { DeliberateAny, Mutable } from '../typescript-helpers' +import { asBigInt, asBytes, asUint64, asUint64Cls, asUint8Array, conactUint8Arrays } from '../util' +import { BytesBackedCls, Uint64BackedCls } from './base' +import type { StubUint64Compat } from './primitives' +import { Bytes, BytesCls, Uint64Cls } from './primitives' +import type { GlobalStateCls, LocalStateCls } from './state' + +export class AssetHolding { + balance: uint64 + frozen: boolean + constructor(balance: StubUint64Compat, frozen: boolean) { + this.balance = asUint64(balance) + this.frozen = frozen + } +} + +export class AccountData { + optedAssets = new Uint64Map() + optedApplications = new Uint64Map() + incentiveEligible = false + lastProposed?: uint64 + lastHeartbeat?: uint64 + account: Mutable> + + constructor() { + this.account = { + totalAppsCreated: 0, + totalAppsOptedIn: 0, + totalAssets: 0, + totalAssetsCreated: 0, + totalBoxBytes: 0, + totalBoxes: 0, + totalExtraAppPages: 0, + totalNumByteSlice: 0, + totalNumUint: 0, + minBalance: DEFAULT_ACCOUNT_MIN_BALANCE, + balance: 0, + authAddress: Account(), + } + } +} + +export function Account(address?: bytes): AccountType { + return new AccountCls(address) +} + +export class AccountCls extends BytesBackedCls implements AccountType { + constructor(address?: bytes) { + const addressBytes = address ?? ZERO_ADDRESS + if (![32n, 36n].includes(asUint64Cls(addressBytes.length).valueOf())) { + throw new AvmError('Address must be 32 bytes long, or 36 bytes including checksum') + } + super(addressBytes.slice(0, 32)) + } + + private get data(): AccountData { + return lazyContext.getAccountData(this) + } + + get balance(): uint64 { + return this.data.account.balance + } + get minBalance(): uint64 { + return this.data.account.minBalance + } + get authAddress(): AccountType { + return this.data.account.authAddress + } + get totalNumUint(): uint64 { + return this.data.account.totalNumUint + } + get totalNumByteSlice(): uint64 { + return this.data.account.totalNumByteSlice + } + get totalExtraAppPages(): uint64 { + return this.data.account.totalExtraAppPages + } + get totalAppsCreated(): uint64 { + return this.data.account.totalAppsCreated + } + get totalAppsOptedIn(): uint64 { + return this.data.account.totalAppsOptedIn + } + get totalAssetsCreated(): uint64 { + return this.data.account.totalAssetsCreated + } + get totalAssets(): uint64 { + return this.data.account.totalAssets + } + get totalBoxes(): uint64 { + return this.data.account.totalBoxes + } + get totalBoxBytes(): uint64 { + return this.data.account.totalBoxBytes + } + + isOptedIn(assetOrApp: AssetType | ApplicationType): boolean { + if (assetOrApp instanceof AssetCls) { + return this.data.optedAssets.has(assetOrApp.id) + } + if (assetOrApp instanceof ApplicationCls) { + return this.data.optedApplications.has(asUint64Cls(assetOrApp.id).asBigInt()) + } + throw new InternalError('Invalid argument type. Must be an `Asset` or `Application` instance.') + } +} + +export class ApplicationData { + application: Mutable> & { + appLogs: bytes[] + globalStates: BytesMap> + localStates: BytesMap> + localStateMaps: BytesMap>> + boxes: BytesMap + materialisedBoxes: BytesMap + } + + isCreating: boolean = false + + constructor() { + this.application = { + approvalProgram: ALWAYS_APPROVE_TEAL_PROGRAM, + clearStateProgram: ALWAYS_APPROVE_TEAL_PROGRAM, + globalNumUint: 0, + globalNumBytes: 0, + localNumUint: 0, + localNumBytes: 0, + extraProgramPages: 0, + creator: lazyContext.defaultSender, + appLogs: [], + globalStates: new BytesMap(), + localStates: new BytesMap(), + localStateMaps: new BytesMap(), + boxes: new BytesMap(), + materialisedBoxes: new BytesMap(), + } + } +} + +export function Application(id?: uint64): ApplicationType { + return new ApplicationCls(id) +} + +export class ApplicationCls extends Uint64BackedCls implements ApplicationType { + get id() { + return this.uint64 + } + + constructor(id?: uint64) { + super(asUint64(id ?? 0)) + } + + private get data(): ApplicationData { + return lazyContext.getApplicationData(this.id) + } + get approvalProgram(): bytes { + return this.data.application.approvalProgram + } + get clearStateProgram(): bytes { + return this.data.application.clearStateProgram + } + get globalNumUint(): uint64 { + return this.data.application.globalNumUint + } + get globalNumBytes(): uint64 { + return this.data.application.globalNumBytes + } + get localNumUint(): uint64 { + return this.data.application.localNumUint + } + get localNumBytes(): uint64 { + return this.data.application.localNumBytes + } + get extraProgramPages(): uint64 { + return this.data.application.extraProgramPages + } + get creator(): AccountType { + return this.data.application.creator + } + get address(): AccountType { + const result = getApplicationAddress(this.id) + if (!lazyContext.ledger.accountDataMap.has(result)) { + lazyContext.any.account({ address: result.bytes }) + } + return result + } +} + +export type AssetData = Mutable> +export const getDefaultAssetData = (): AssetData => ({ + total: lazyContext.any.uint64(), + decimals: lazyContext.any.uint64(1, 6), + defaultFrozen: false, + unitName: lazyContext.any.bytes(4), + name: lazyContext.any.bytes(32), + url: lazyContext.any.bytes(10), + metadataHash: lazyContext.any.bytes(32), + manager: Account(ZERO_ADDRESS), + freeze: Account(ZERO_ADDRESS), + clawback: Account(ZERO_ADDRESS), + creator: lazyContext.defaultSender, + reserve: Account(ZERO_ADDRESS), +}) + +export function Asset(id?: uint64): AssetType { + return new AssetCls(id) +} + +export class AssetCls extends Uint64BackedCls implements AssetType { + get id(): uint64 { + return this.uint64 + } + + constructor(id?: StubUint64Compat) { + super(asUint64(id ?? 0)) + } + + private get data(): AssetData { + return lazyContext.getAssetData(this.id) + } + + get total(): uint64 { + return this.data.total + } + get decimals(): uint64 { + return this.data.decimals + } + get defaultFrozen(): boolean { + return this.data.defaultFrozen + } + get unitName(): bytes { + return this.data.unitName + } + get name(): bytes { + return this.data.name + } + get url(): bytes { + return this.data.url + } + get metadataHash(): bytes { + return this.data.metadataHash + } + get manager(): AccountType { + return this.data.manager + } + get reserve(): AccountType { + return this.data.reserve + } + get freeze(): AccountType { + return this.data.freeze + } + get clawback(): AccountType { + return this.data.clawback + } + get creator(): AccountType { + return this.data.creator + } + balance(account: AccountType): uint64 { + return this.getAssetHolding(account).balance + } + frozen(account: AccountType): boolean { + return this.getAssetHolding(account).frozen + } + + private getAssetHolding(account: AccountType): AssetHolding { + const accountData = lazyContext.getAccountData(account) + const assetHolding = accountData.optedAssets.get(this.id) + if (assetHolding === undefined) { + throw new InternalError( + 'The asset is not opted into the account! Use `ctx.any.account(opted_asset_balances={{ASSET_ID: VALUE}})` to set emulated opted asset into the account.', + ) + } + return assetHolding + } +} + +export const checksumFromPublicKey = (pk: Uint8Array): Uint8Array => { + return Uint8Array.from(js_sha512.sha512_256.array(pk).slice(HASH_BYTES_LENGTH - ALGORAND_CHECKSUM_BYTE_LENGTH, HASH_BYTES_LENGTH)) +} + +export const getApplicationAddress = (appId: StubUint64Compat): AccountType => { + const toBeSigned = conactUint8Arrays(asUint8Array(APP_ID_PREFIX), encodingUtil.bigIntToUint8Array(asBigInt(appId), 8)) + const appIdHash = js_sha512.sha512_256.array(toBeSigned) + const publicKey = Uint8Array.from(appIdHash) + const address = encodeAddress(publicKey) + return Account(Bytes.fromBase32(address)) +} + +export const encodeAddress = (address: Uint8Array): string => { + const checksum = checksumFromPublicKey(address) + return encodingUtil.uint8ArrayToBase32(conactUint8Arrays(address, checksum)).slice(0, ALGORAND_ADDRESS_LENGTH) +} + +export const decodePublicKey = (address: string): Uint8Array => { + const decoded = encodingUtil.base32ToUint8Array(address) + return decoded.slice(0, ALGORAND_ADDRESS_BYTE_LENGTH - ALGORAND_CHECKSUM_BYTE_LENGTH) +} + +export const asAccount = (val: AccountType | bytes | string | undefined): AccountType | undefined => { + return val instanceof AccountCls + ? val + : typeof val === 'string' + ? Account(asBytes(val)) + : val instanceof BytesCls + ? Account(val.asAlgoTs()) + : undefined +} + +export const asAsset = (val: AssetType | uint64 | undefined): AssetType | undefined => { + return val instanceof Uint64Cls ? Asset(val.asAlgoTs()) : val instanceof AssetCls ? val : undefined +} + +export const asApplication = (val: ApplicationType | uint64 | undefined): ApplicationType | undefined => { + return val instanceof Uint64Cls ? Application(val.asAlgoTs()) : val instanceof ApplicationCls ? val : undefined +} diff --git a/src/impl/scratch.ts b/src/impl/scratch.ts index facfb9a..4f48d8d 100644 --- a/src/impl/scratch.ts +++ b/src/impl/scratch.ts @@ -1,49 +1,43 @@ -import { bytes, internal, uint64 } from '@algorandfoundation/algorand-typescript' +import type { bytes, op, uint64 } from '@algorandfoundation/algorand-typescript' import { lazyContext } from '../context-helpers/internal-context' +import { InternalError } from '../errors' +import type { StubBytesCompat, StubUint64Compat } from './primitives' +import { BytesCls, Uint64Cls } from './primitives' -export const gloadUint64: internal.opTypes.GloadUint64Type = ( - a: internal.primitives.StubUint64Compat, - b: internal.primitives.StubUint64Compat, -): uint64 => { +export const gloadUint64: typeof op.gloadUint64 = (a: StubUint64Compat, b: StubUint64Compat): uint64 => { const txn = lazyContext.activeGroup.getTransaction(a) const result = txn.getScratchSlot(b) - if (result instanceof internal.primitives.Uint64Cls) { + if (result instanceof Uint64Cls) { return result.asAlgoTs() } - throw new internal.errors.InternalError('invalid scratch slot type') + throw new InternalError('invalid scratch slot type') } -export const gloadBytes: internal.opTypes.GloadBytesType = ( - a: internal.primitives.StubUint64Compat, - b: internal.primitives.StubUint64Compat, -): bytes => { +export const gloadBytes: typeof op.gloadBytes = (a: StubUint64Compat, b: StubUint64Compat): bytes => { const txn = lazyContext.activeGroup.getTransaction(a) const result = txn.getScratchSlot(b) - if (result instanceof internal.primitives.BytesCls) { + if (result instanceof BytesCls) { return result.asAlgoTs() } - throw new internal.errors.InternalError('invalid scratch slot type') + throw new InternalError('invalid scratch slot type') } -export const Scratch: internal.opTypes.ScratchType = { - loadBytes: function (a: internal.primitives.StubUint64Compat): bytes { +export const Scratch: typeof op.Scratch = { + loadBytes: function (a: StubUint64Compat): bytes { const result = lazyContext.activeGroup.activeTransaction.getScratchSlot(a) - if (result instanceof internal.primitives.BytesCls) { + if (result instanceof BytesCls) { return result as bytes } - throw new internal.errors.InternalError('invalid scratch slot type') + throw new InternalError('invalid scratch slot type') }, - loadUint64: function (a: internal.primitives.StubUint64Compat): uint64 { + loadUint64: function (a: StubUint64Compat): uint64 { const result = lazyContext.activeGroup.activeTransaction.getScratchSlot(a) - if (result instanceof internal.primitives.Uint64Cls) { + if (result instanceof Uint64Cls) { return result as uint64 } - throw new internal.errors.InternalError('invalid scratch slot type') + throw new InternalError('invalid scratch slot type') }, - store: function ( - a: internal.primitives.StubUint64Compat, - b: internal.primitives.StubUint64Compat | internal.primitives.StubBytesCompat, - ): void { + store: function (a: StubUint64Compat, b: StubUint64Compat | StubBytesCompat): void { lazyContext.activeGroup.activeTransaction.setScratchSlot(a, b) }, } diff --git a/src/impl/state.ts b/src/impl/state.ts index 2f14e79..130cb59 100644 --- a/src/impl/state.ts +++ b/src/impl/state.ts @@ -1,25 +1,26 @@ -import { +import type { Account, Application, BoxMap as BoxMapType, BoxRef as BoxRefType, Box as BoxType, - Bytes, bytes, GlobalStateOptions, GlobalState as GlobalStateType, - internal, LocalStateForAccount, LocalState as LocalStateType, uint64, - Uint64, } from '@algorandfoundation/algorand-typescript' import { AccountMap } from '../collections/custom-key-map' import { MAX_BOX_SIZE } from '../constants' import { lazyContext } from '../context-helpers/internal-context' -import { getEncoder, toBytes, TypeInfo } from '../encoders' +import type { TypeInfo } from '../encoders' +import { getEncoder, toBytes } from '../encoders' +import { AssertError, InternalError } from '../errors' import { getGenericTypeInfo } from '../runtime-helpers' import { asBytes, asBytesCls, asNumber, asUint8Array, conactUint8Arrays } from '../util' +import type { StubBytesCompat, StubUint64Compat } from './primitives' +import { Bytes, Uint64, Uint64Cls } from './primitives' export class GlobalStateCls { private readonly _type: string = GlobalStateCls.name @@ -32,7 +33,7 @@ export class GlobalStateCls { } delete: () => void = () => { - if (this.#value instanceof internal.primitives.Uint64Cls) { + if (this.#value instanceof Uint64Cls) { this.#value = Uint64(0) as ValueType } else { this.#value = undefined @@ -45,7 +46,7 @@ export class GlobalStateCls { get value(): ValueType { if (this.#value === undefined) { - throw new internal.errors.AssertError('value is not set') + throw new AssertError('value is not set') } return this.#value } @@ -67,7 +68,7 @@ export class GlobalStateCls { export class LocalStateCls { #value: ValueType | undefined delete: () => void = () => { - if (this.#value instanceof internal.primitives.Uint64Cls) { + if (this.#value instanceof Uint64Cls) { this.#value = Uint64(0) as ValueType } else { this.#value = undefined @@ -75,7 +76,7 @@ export class LocalStateCls { } get value(): ValueType { if (this.#value === undefined) { - throw new internal.errors.AssertError('value is not set') + throw new AssertError('value is not set') } return this.#value } @@ -90,13 +91,27 @@ export class LocalStateCls { } export class LocalStateMapCls { - #value = new AccountMap>() + private applicationId: uint64 - getValue(account: Account): LocalStateCls { - if (!this.#value.has(account)) { - this.#value.set(account, new LocalStateCls()) + constructor() { + this.applicationId = lazyContext.activeGroup.activeApplicationId + } + + getValue(key: string | bytes | undefined, account: Account): LocalStateCls { + const bytesKey = key === undefined ? Bytes() : asBytes(key) + const localStateMap = this.ensureApplicationLocalStateMap(bytesKey) + if (!localStateMap.has(account)) { + localStateMap.set(account, new LocalStateCls()) } - return this.#value.getOrFail(account)! + return localStateMap.getOrFail(account) as LocalStateCls + } + + private ensureApplicationLocalStateMap(key: bytes | string) { + const applicationData = lazyContext.ledger.applicationDataMap.getOrFail(this.applicationId)!.application + if (!applicationData.localStateMaps.has(key)) { + applicationData.localStateMaps.set(key, new AccountMap>()) + } + return applicationData.localStateMaps.getOrFail(key) } } @@ -106,7 +121,7 @@ export function GlobalState(options?: GlobalStateOptions): export function LocalState(options?: { key?: bytes | string }): LocalStateType { function localStateInternal(account: Account): LocalStateForAccount { - return localStateInternal.map.getValue(account) + return localStateInternal.map.getValue(localStateInternal.key, account) } localStateInternal.key = options?.key localStateInternal.hasKey = options?.key !== undefined && options.key.length > 0 @@ -117,6 +132,7 @@ export function LocalState(options?: { key?: bytes | string }): Local export class BoxCls { #key: bytes | undefined #app: Application + #valueType?: TypeInfo private readonly _type: string = BoxCls.name @@ -124,26 +140,33 @@ export class BoxCls { return x instanceof Object && '_type' in x && (x as { _type: string })['_type'] === BoxCls.name } - constructor(key?: internal.primitives.StubBytesCompat) { + constructor(key?: StubBytesCompat, app?: Application, valueType?: TypeInfo) { this.#key = key ? asBytes(key) : undefined - this.#app = lazyContext.activeApplication + this.#app = app ?? lazyContext.activeApplication + this.#valueType = valueType } private get fromBytes() { - const typeInfo = getGenericTypeInfo(this) - const valueType = (typeInfo!.genericArgs! as TypeInfo[])[0] + const valueType = this.#valueType ?? (getGenericTypeInfo(this)!.genericArgs! as TypeInfo[])[0] return (val: Uint8Array) => getEncoder(valueType)(val, valueType) } get value(): TValue { if (!this.exists) { - throw new internal.errors.InternalError('Box has not been created') + throw new InternalError('Box has not been created') } - - return this.fromBytes(lazyContext.ledger.getBox(this.#app, this.key)) + let materialised = lazyContext.ledger.getMaterialisedBox(this.#app, this.key) + if (materialised !== undefined) { + return materialised + } + const original = lazyContext.ledger.getBox(this.#app, this.key) + materialised = this.fromBytes(original) + lazyContext.ledger.setMatrialisedBox(this.#app, this.key, materialised) + return materialised } set value(v: TValue) { lazyContext.ledger.setBox(this.#app, this.key, asUint8Array(toBytes(v))) + lazyContext.ledger.setMatrialisedBox(this.#app, this.key, v) } get hasKey(): boolean { @@ -152,12 +175,12 @@ export class BoxCls { get key(): bytes { if (this.#key === undefined || this.#key.length === 0) { - throw new internal.errors.InternalError('Box key is empty') + throw new InternalError('Box key is empty') } return this.#key } - set key(key: internal.primitives.StubBytesCompat) { + set key(key: StubBytesCompat) { this.#key = asBytes(key) } @@ -167,7 +190,7 @@ export class BoxCls { get length(): uint64 { if (!this.exists) { - throw new internal.errors.InternalError('Box has not been created') + throw new InternalError('Box has not been created') } return toBytes(this.value).length } @@ -188,7 +211,7 @@ export class BoxCls { } export class BoxMapCls { - #keyPrefix: bytes | undefined + private _keyPrefix: bytes | undefined #app: Application private readonly _type: string = BoxMapCls.name @@ -197,60 +220,30 @@ export class BoxMapCls { return x instanceof Object && '_type' in x && (x as { _type: string })['_type'] === BoxMapCls.name } - private get fromBytes() { - const typeInfo = getGenericTypeInfo(this) - const valueType = (typeInfo!.genericArgs! as TypeInfo[])[1] - return (val: Uint8Array) => getEncoder(valueType)(val, valueType) - } - - constructor(keyPrefix?: internal.primitives.StubBytesCompat) { - this.#keyPrefix = keyPrefix ? asBytes(keyPrefix) : undefined + constructor() { this.#app = lazyContext.activeApplication } get hasKeyPrefix(): boolean { - return this.#keyPrefix !== undefined && this.#keyPrefix.length > 0 + return this._keyPrefix !== undefined && this._keyPrefix.length > 0 } get keyPrefix(): bytes { - if (this.#keyPrefix === undefined || this.#keyPrefix.length === 0) { - throw new internal.errors.InternalError('Box key prefix is empty') + if (this._keyPrefix === undefined || this._keyPrefix.length === 0) { + throw new InternalError('Box key prefix is empty') } - return this.#keyPrefix + return this._keyPrefix } - set keyPrefix(keyPrefix: internal.primitives.StubBytesCompat) { - this.#keyPrefix = asBytes(keyPrefix) + set keyPrefix(keyPrefix: StubBytesCompat) { + this._keyPrefix = asBytes(keyPrefix) } - get(key: TKey, options?: { default: TValue }): TValue { - const [value, exists] = this.maybe(key) - if (!exists && options === undefined) { - throw new internal.errors.InternalError('Box has not been created') - } - return exists ? value : options!.default - } - - set(key: TKey, value: TValue): void { - lazyContext.ledger.setBox(this.#app, this.getFullKey(key), asUint8Array(toBytes(value))) - } - - delete(key: TKey): boolean { - return lazyContext.ledger.deleteBox(this.#app, this.getFullKey(key)) - } - - has(key: TKey): boolean { - return lazyContext.ledger.boxExists(this.#app, this.getFullKey(key)) - } - - maybe(key: TKey): readonly [TValue, boolean] { - const fullKey = this.getFullKey(key) - const value = this.fromBytes(lazyContext.ledger.getBox(this.#app, fullKey)) - return [value, lazyContext.ledger.boxExists(this.#app, fullKey)] - } - - length(key: TKey): uint64 { - return toBytes(this.get(key)).length + call(key: TKey, proxy: (key: TKey) => BoxType): BoxType { + const typeInfo = getGenericTypeInfo(proxy) + const valueType = (typeInfo!.genericArgs! as TypeInfo[])[1] + const box = new BoxCls(this.getFullKey(key), this.#app, valueType) + return box } private getFullKey(key: TKey): bytes { @@ -268,7 +261,7 @@ export class BoxRefCls { return x instanceof Object && '_type' in x && (x as { _type: string })['_type'] === BoxRefCls.name } - constructor(key?: internal.primitives.StubBytesCompat) { + constructor(key?: StubBytesCompat) { this.#key = key ? asBytes(key) : undefined this.#app = lazyContext.activeApplication } @@ -279,27 +272,27 @@ export class BoxRefCls { get key(): bytes { if (this.#key === undefined || this.#key.length === 0) { - throw new internal.errors.InternalError('Box key is empty') + throw new InternalError('Box key is empty') } return this.#key } - set key(key: internal.primitives.StubBytesCompat) { + set key(key: StubBytesCompat) { this.#key = asBytes(key) } get value(): bytes { if (!this.exists) { - throw new internal.errors.InternalError('Box has not been created') + throw new InternalError('Box has not been created') } return toBytes(this.backingValue) } - set value(v: internal.primitives.StubBytesCompat) { + set value(v: StubBytesCompat) { const bytesValue = asBytesCls(v) const content = this.backingValue if (this.exists && content.length !== bytesValue.length.asNumber()) { - throw new internal.errors.InternalError('Box already exists with a different size') + throw new InternalError('Box already exists with a different size') } this.backingValue = bytesValue.asUint8Array() } @@ -308,14 +301,14 @@ export class BoxRefCls { return lazyContext.ledger.boxExists(this.#app, this.key) } - create(options: { size: internal.primitives.StubUint64Compat }): boolean { + create(options: { size: StubUint64Compat }): boolean { const size = asNumber(options.size) if (size > MAX_BOX_SIZE) { - throw new internal.errors.InternalError(`Box size cannot exceed ${MAX_BOX_SIZE}`) + throw new InternalError(`Box size cannot exceed ${MAX_BOX_SIZE}`) } const content = this.backingValue if (this.exists && content.length !== size) { - throw new internal.errors.InternalError('Box already exists with a different size') + throw new InternalError('Box already exists with a different size') } if (this.exists) { return false @@ -324,29 +317,25 @@ export class BoxRefCls { return true } - get(options: { default: internal.primitives.StubBytesCompat }): bytes { + get(options: { default: StubBytesCompat }): bytes { const [value, exists] = this.maybe() return exists ? value : asBytes(options.default) } - put(value: internal.primitives.StubBytesCompat): void { + put(value: StubBytesCompat): void { this.value = value } - splice( - start: internal.primitives.StubUint64Compat, - length: internal.primitives.StubUint64Compat, - value: internal.primitives.StubBytesCompat, - ): void { + splice(start: StubUint64Compat, length: StubUint64Compat, value: StubBytesCompat): void { const content = this.backingValue const startNumber = asNumber(start) const lengthNumber = asNumber(length) const valueBytes = asBytesCls(value) if (!this.exists) { - throw new internal.errors.InternalError('Box has not been created') + throw new InternalError('Box has not been created') } if (startNumber > content.length) { - throw new internal.errors.InternalError('Start index exceeds box size') + throw new InternalError('Start index exceeds box size') } const end = Math.min(startNumber + lengthNumber, content.length) let updatedContent = conactUint8Arrays(content.slice(0, startNumber), valueBytes.asUint8Array(), content.slice(end)) @@ -359,15 +348,15 @@ export class BoxRefCls { this.backingValue = updatedContent } - replace(start: internal.primitives.StubUint64Compat, value: internal.primitives.StubBytesCompat): void { + replace(start: StubUint64Compat, value: StubBytesCompat): void { const content = this.backingValue const startNumber = asNumber(start) const valueBytes = asBytesCls(value) if (!this.exists) { - throw new internal.errors.InternalError('Box has not been created') + throw new InternalError('Box has not been created') } if (startNumber + asNumber(valueBytes.length) > content.length) { - throw new internal.errors.InternalError('Replacement content exceeds box size') + throw new InternalError('Replacement content exceeds box size') } const updatedContent = conactUint8Arrays( content.slice(0, startNumber), @@ -377,15 +366,15 @@ export class BoxRefCls { this.backingValue = updatedContent } - extract(start: internal.primitives.StubUint64Compat, length: internal.primitives.StubUint64Compat): bytes { + extract(start: StubUint64Compat, length: StubUint64Compat): bytes { const content = this.backingValue const startNumber = asNumber(start) const lengthNumber = asNumber(length) if (!this.exists) { - throw new internal.errors.InternalError('Box has not been created') + throw new InternalError('Box has not been created') } if (startNumber + lengthNumber > content.length) { - throw new internal.errors.InternalError('Index out of bounds') + throw new InternalError('Index out of bounds') } return toBytes(content.slice(startNumber, startNumber + lengthNumber)) } @@ -396,11 +385,11 @@ export class BoxRefCls { resize(newSize: uint64): void { const newSizeNumber = asNumber(newSize) if (newSizeNumber > MAX_BOX_SIZE) { - throw new internal.errors.InternalError(`Box size cannot exceed ${MAX_BOX_SIZE}`) + throw new InternalError(`Box size cannot exceed ${MAX_BOX_SIZE}`) } const content = this.backingValue if (!this.exists) { - throw new internal.errors.InternalError('Box has not been created') + throw new InternalError('Box has not been created') } let updatedContent if (newSizeNumber > content.length) { @@ -417,7 +406,7 @@ export class BoxRefCls { get length(): uint64 { if (!this.exists) { - throw new internal.errors.InternalError('Box has not been created') + throw new InternalError('Box has not been created') } return this.backingValue.length } @@ -436,7 +425,13 @@ export function Box(options?: { key: bytes | string }): BoxType } export function BoxMap(options?: { keyPrefix: bytes | string }): BoxMapType { - return new BoxMapCls(options?.keyPrefix) + const boxMap = new BoxMapCls() + if (options?.keyPrefix !== undefined) { + boxMap.keyPrefix = options.keyPrefix + } + + const x = (key: TKey): BoxType => boxMap.call(key, x) + return Object.setPrototypeOf(x, boxMap) } export function BoxRef(options?: { key: bytes | string }): BoxRefType { diff --git a/src/impl/template-var.ts b/src/impl/template-var.ts index e49cfc4..578060b 100644 --- a/src/impl/template-var.ts +++ b/src/impl/template-var.ts @@ -1,11 +1,11 @@ -import { internal } from '@algorandfoundation/algorand-typescript' import { DEFAULT_TEMPLATE_VAR_PREFIX } from '../constants' import { lazyContext } from '../context-helpers/internal-context' +import { CodeError } from '../errors' export function TemplateVarImpl(variableName: string, prefix = DEFAULT_TEMPLATE_VAR_PREFIX): T { const key = prefix + variableName if (!Object.hasOwn(lazyContext.value.templateVars, key)) { - throw internal.errors.codeError(`Template variable ${key} not found in test context!`) + throw new CodeError(`Template variable ${key} not found in test context!`) } return lazyContext.value.templateVars[prefix + variableName] as T } diff --git a/src/impl/transactions.ts b/src/impl/transactions.ts index d2d7573..2bd9c9a 100644 --- a/src/impl/transactions.ts +++ b/src/impl/transactions.ts @@ -1,21 +1,21 @@ -import { - Account, - Application, - arc4, - Asset, +import type { + Account as AccountType, + Application as ApplicationType, + Asset as AssetType, bytes, - Bytes, gtxn, - internal, - TransactionType, + OnCompleteActionStr, uint64, - Uint64, } from '@algorandfoundation/algorand-typescript' +import { TransactionType } from '@algorandfoundation/algorand-typescript' import { ABI_RETURN_VALUE_LOG_PREFIX, MAX_ITEMS_IN_LOG } from '../constants' import { lazyContext } from '../context-helpers/internal-context' import { toBytes } from '../encoders' -import { Mutable, ObjectKeys } from '../typescript-helpers' +import { InternalError } from '../errors' +import type { Mutable, ObjectKeys } from '../typescript-helpers' import { asBytes, asMaybeBytesCls, asMaybeUint64Cls, asNumber, asUint64Cls, combineIntoMaxBytePages, getRandomBytes } from '../util' +import { Bytes, Uint64, type StubBytesCompat, type StubUint64Compat } from './primitives' +import { Account, Application, Asset } from './reference' const baseDefaultFields = () => ({ sender: lazyContext.defaultSender, @@ -48,7 +48,7 @@ abstract class TransactionBase { this.scratchSpace = Array(256).fill(Uint64(0)) } - readonly sender: Account + readonly sender: AccountType readonly fee: uint64 readonly firstValid: uint64 readonly firstValidTime: uint64 @@ -57,26 +57,23 @@ abstract class TransactionBase { readonly lease: bytes readonly groupIndex: uint64 readonly txnId: bytes - readonly rekeyTo: Account + readonly rekeyTo: AccountType readonly scratchSpace: Array - setScratchSlot( - index: internal.primitives.StubUint64Compat, - value: internal.primitives.StubBytesCompat | internal.primitives.StubUint64Compat, - ): void { + setScratchSlot(index: StubUint64Compat, value: StubBytesCompat | StubUint64Compat): void { const i = asNumber(index) if (i >= this.scratchSpace.length) { - throw internal.errors.internalError('invalid scratch slot') + throw new InternalError('invalid scratch slot') } const bytesValue = asMaybeBytesCls(value) const uint64Value = asMaybeUint64Cls(value) this.scratchSpace[i] = bytesValue?.asAlgoTs() ?? uint64Value?.asAlgoTs() ?? Uint64(0) } - getScratchSlot(index: internal.primitives.StubUint64Compat): bytes | uint64 { + getScratchSlot(index: StubUint64Compat): bytes | uint64 { const i = asNumber(index) if (i >= this.scratchSpace.length) { - throw internal.errors.internalError('invalid scratch slot') + throw new InternalError('invalid scratch slot') } return this.scratchSpace[i] } @@ -95,9 +92,9 @@ export class PaymentTransaction extends TransactionBase implements gtxn.PaymentT this.closeRemainderTo = fields.closeRemainderTo ?? Account() } - readonly receiver: Account + readonly receiver: AccountType readonly amount: uint64 - readonly closeRemainderTo: Account + readonly closeRemainderTo: AccountType readonly type: TransactionType.Payment = TransactionType.Payment readonly typeBytes: bytes = asUint64Cls(TransactionType.Payment).toBytes().asAlgoTs() } @@ -117,6 +114,12 @@ export class KeyRegistrationTransaction extends TransactionBase implements gtxn. this.voteKeyDilution = fields.voteKeyDilution ?? Uint64(0) this.nonparticipation = fields.nonparticipation ?? false this.stateProofKey = fields.stateProofKey ?? Bytes() + const globalData = lazyContext.ledger.globalData + if (this.fee >= globalData.payoutsGoOnlineFee && globalData.payoutsEnabled) { + lazyContext.ledger.patchAccountData(this.sender, { + incentiveEligible: true, + }) + } } readonly voteKey: bytes @@ -153,7 +156,7 @@ export class AssetConfigTransaction extends TransactionBase implements gtxn.Asse this.createdAsset = fields.createdAsset ?? Asset() } - readonly configAsset: Asset + readonly configAsset: AssetType readonly total: uint64 readonly decimals: uint64 readonly defaultFrozen: boolean @@ -161,11 +164,11 @@ export class AssetConfigTransaction extends TransactionBase implements gtxn.Asse readonly assetName: bytes readonly url: bytes readonly metadataHash: bytes - readonly manager: Account - readonly reserve: Account - readonly freeze: Account - readonly clawback: Account - readonly createdAsset: Asset + readonly manager: AccountType + readonly reserve: AccountType + readonly freeze: AccountType + readonly clawback: AccountType + readonly createdAsset: AssetType readonly type: TransactionType.AssetConfig = TransactionType.AssetConfig readonly typeBytes: bytes = asUint64Cls(TransactionType.AssetConfig).toBytes().asAlgoTs() } @@ -185,11 +188,11 @@ export class AssetTransferTransaction extends TransactionBase implements gtxn.As this.assetCloseTo = fields.assetCloseTo ?? Account() } - readonly xferAsset: Asset + readonly xferAsset: AssetType readonly assetAmount: uint64 - readonly assetSender: Account - readonly assetReceiver: Account - readonly assetCloseTo: Account + readonly assetSender: AccountType + readonly assetReceiver: AccountType + readonly assetCloseTo: AccountType readonly type: TransactionType.AssetTransfer = TransactionType.AssetTransfer readonly typeBytes: bytes = asUint64Cls(TransactionType.AssetTransfer).toBytes().asAlgoTs() @@ -208,8 +211,8 @@ export class AssetFreezeTransaction extends TransactionBase implements gtxn.Asse this.frozen = fields.frozen ?? false } - readonly freezeAsset: Asset - readonly freezeAccount: Account + readonly freezeAsset: AssetType + readonly freezeAccount: AccountType readonly frozen: boolean readonly type: TransactionType.AssetFreeze = TransactionType.AssetFreeze @@ -219,9 +222,9 @@ export class AssetFreezeTransaction extends TransactionBase implements gtxn.Asse export type ApplicationTransactionFields = TxnFields & Partial<{ appArgs: Array - accounts: Array - assets: Array - apps: Array + accounts: Array + assets: Array + apps: Array approvalProgramPages: Array clearStateProgramPages: Array appLogs: Array @@ -234,16 +237,17 @@ export class ApplicationTransaction extends TransactionBase implements gtxn.Appl return new ApplicationTransaction(fields) } #appArgs: Array - #accounts: Array - #assets: Array - #apps: Array + #accounts: Array + #assets: Array + #apps: Array #approvalProgramPages: Array #clearStateProgramPages: Array #appLogs: Array + #appId: ApplicationType protected constructor(fields: ApplicationTransactionFields) { super(fields) - this.appId = fields.appId ?? Application() + this.#appId = fields.appId ?? Application() this.onCompletion = fields.onCompletion ?? 'NoOp' this.globalNumUint = fields.globalNumUint ?? Uint64(0) this.globalNumBytes = fields.globalNumBytes ?? Uint64(0) @@ -261,14 +265,27 @@ export class ApplicationTransaction extends TransactionBase implements gtxn.Appl Object.entries(fields.scratchSpace ?? {}).forEach(([k, v]) => this.setScratchSlot(Number(k), v)) } - readonly appId: Application - readonly onCompletion: arc4.OnCompleteActionStr + get backingAppId(): ApplicationType { + return this.#appId + } + + get appId(): ApplicationType { + if (asNumber(this.#appId.id) === 0) { + return this.#appId + } + const appData = lazyContext.getApplicationData(this.#appId.id) + if (appData && appData.isCreating) { + return Application(0) + } + return this.#appId + } + readonly onCompletion: OnCompleteActionStr readonly globalNumUint: uint64 readonly globalNumBytes: uint64 readonly localNumUint: uint64 readonly localNumBytes: uint64 readonly extraProgramPages: uint64 - readonly createdApp: Application + readonly createdApp: ApplicationType get approvalProgram() { return this.approvalProgramPages(0) } @@ -294,10 +311,10 @@ export class ApplicationTransaction extends TransactionBase implements gtxn.Appl return Uint64(this.clearStateProgramPages.length) } get numLogs() { - return Uint64(this.#appLogs.length || lazyContext.getApplicationData(this.appId.id).appLogs.length) + return Uint64(this.#appLogs.length || lazyContext.getApplicationData(this.appId.id).application.appLogs!.length) } get lastLog() { - return this.#appLogs.at(-1) ?? lazyContext.getApplicationData(this.appId.id).appLogs.at(-1) ?? Bytes() + return this.#appLogs.at(-1) ?? lazyContext.getApplicationData(this.appId.id).application.appLogs!.at(-1) ?? Bytes() } get apat() { return this.#accounts @@ -308,27 +325,27 @@ export class ApplicationTransaction extends TransactionBase implements gtxn.Appl get apfa() { return this.#apps } - appArgs(index: internal.primitives.StubUint64Compat): bytes { + appArgs(index: StubUint64Compat): bytes { return toBytes(this.#appArgs[asNumber(index)]) } - accounts(index: internal.primitives.StubUint64Compat): Account { + accounts(index: StubUint64Compat): AccountType { return this.#accounts[asNumber(index)] } - assets(index: internal.primitives.StubUint64Compat): Asset { + assets(index: StubUint64Compat): AssetType { return this.#assets[asNumber(index)] } - apps(index: internal.primitives.StubUint64Compat): Application { + apps(index: StubUint64Compat): ApplicationType { return this.#apps[asNumber(index)] } - approvalProgramPages(index: internal.primitives.StubUint64Compat): bytes { + approvalProgramPages(index: StubUint64Compat): bytes { return combineIntoMaxBytePages(this.#approvalProgramPages)[asNumber(index)] } - clearStateProgramPages(index: internal.primitives.StubUint64Compat): bytes { + clearStateProgramPages(index: StubUint64Compat): bytes { return combineIntoMaxBytePages(this.#clearStateProgramPages)[asNumber(index)] } - logs(index: internal.primitives.StubUint64Compat): bytes { + logs(index: StubUint64Compat): bytes { const i = asNumber(index) - return this.#appLogs[i] ?? lazyContext.getApplicationData(this.appId.id).appLogs ?? Bytes() + return this.#appLogs[i] ?? lazyContext.getApplicationData(this.appId.id).application.appLogs ?? Bytes() } readonly type: TransactionType.ApplicationCall = TransactionType.ApplicationCall readonly typeBytes: bytes = asUint64Cls(TransactionType.ApplicationCall).toBytes().asAlgoTs() @@ -338,9 +355,9 @@ export class ApplicationTransaction extends TransactionBase implements gtxn.Appl return this.#appLogs } /* @internal */ - appendLog(value: internal.primitives.StubBytesCompat): void { + appendLog(value: StubBytesCompat): void { if (this.#appLogs.length + 1 > MAX_ITEMS_IN_LOG) { - throw internal.errors.internalError(`Too many log calls in program, up to ${MAX_ITEMS_IN_LOG} is allowed`) + throw new InternalError(`Too many log calls in program, up to ${MAX_ITEMS_IN_LOG} is allowed`) } this.#appLogs.push(asBytes(value)) } diff --git a/src/impl/txn.ts b/src/impl/txn.ts index 172224f..4fd54d8 100644 --- a/src/impl/txn.ts +++ b/src/impl/txn.ts @@ -1,8 +1,11 @@ -import { Account, Application, arc4, Asset, bytes, internal, TransactionType, uint64 } from '@algorandfoundation/algorand-typescript' +import type { Account, Application, Asset, bytes, op, uint64 } from '@algorandfoundation/algorand-typescript' +import { OnCompleteAction, TransactionType } from '@algorandfoundation/algorand-typescript' import { lazyContext } from '../context-helpers/internal-context' +import { InternalError } from '../errors' import { asNumber, asUint64, asUint64Cls } from '../util' +import type { StubUint64Compat } from './primitives' -export const gaid = (a: internal.primitives.StubUint64Compat): uint64 => { +export const gaid = (a: StubUint64Compat): uint64 => { const group = lazyContext.activeGroup const transaction = group.getTransaction(a) if (transaction.type === TransactionType.ApplicationCall) { @@ -10,11 +13,11 @@ export const gaid = (a: internal.primitives.StubUint64Compat): uint64 => { } else if (transaction.type === TransactionType.AssetConfig) { return transaction.createdAsset.id } else { - throw new internal.errors.InternalError(`transaction at index ${asNumber(a)} is not an Application Call or Asset Config`) + throw new InternalError(`transaction at index ${asNumber(a)} is not an Application Call or Asset Config`) } } -export const Txn: internal.opTypes.TxnType = { +export const Txn: typeof op.Txn = { get sender(): Account { return lazyContext.activeGroup.getTransaction().sender }, @@ -192,13 +195,13 @@ export const Txn: internal.opTypes.TxnType = { */ get onCompletion(): uint64 { const onCompletionStr = lazyContext.activeGroup.getApplicationTransaction().onCompletion - return asUint64(arc4.OnCompleteAction[onCompletionStr]) + return asUint64(OnCompleteAction[onCompletionStr]) }, /** * Arguments passed to the application in the ApplicationCall transaction */ - applicationArgs(a: internal.primitives.StubUint64Compat): bytes { + applicationArgs(a: StubUint64Compat): bytes { return lazyContext.activeGroup.getApplicationTransaction().appArgs(asUint64(a)) }, @@ -212,7 +215,7 @@ export const Txn: internal.opTypes.TxnType = { /** * Accounts listed in the ApplicationCall transaction */ - accounts(a: internal.primitives.StubUint64Compat): Account { + accounts(a: StubUint64Compat): Account { return lazyContext.activeGroup.getApplicationTransaction().accounts(asUint64(a)) }, @@ -352,7 +355,7 @@ export const Txn: internal.opTypes.TxnType = { /** * Foreign Assets listed in the ApplicationCall transaction */ - assets(a: internal.primitives.StubUint64Compat): Asset { + assets(a: StubUint64Compat): Asset { return lazyContext.activeGroup.getApplicationTransaction().assets(asUint64(a)) }, @@ -366,7 +369,7 @@ export const Txn: internal.opTypes.TxnType = { /** * Foreign Apps listed in the ApplicationCall transaction */ - applications(a: internal.primitives.StubUint64Compat): Application { + applications(a: StubUint64Compat): Application { return lazyContext.activeGroup.getApplicationTransaction().apps(asUint64(a)) }, @@ -422,7 +425,7 @@ export const Txn: internal.opTypes.TxnType = { /** * Log messages emitted by an application call (only with `itxn` in v5). Application mode only */ - logs(a: internal.primitives.StubUint64Compat): bytes { + logs(a: StubUint64Compat): bytes { return lazyContext.activeGroup.getApplicationTransaction().logs(asUint64(a)) }, @@ -464,7 +467,7 @@ export const Txn: internal.opTypes.TxnType = { /** * Approval Program as an array of pages */ - approvalProgramPages(a: internal.primitives.StubUint64Compat): bytes { + approvalProgramPages(a: StubUint64Compat): bytes { return lazyContext.activeGroup.getApplicationTransaction().approvalProgramPages(asUint64(a)) }, @@ -478,7 +481,7 @@ export const Txn: internal.opTypes.TxnType = { /** * ClearState Program as an array of pages */ - clearStateProgramPages(a: internal.primitives.StubUint64Compat): bytes { + clearStateProgramPages(a: StubUint64Compat): bytes { return lazyContext.activeGroup.getApplicationTransaction().clearStateProgramPages(asUint64(a)) }, diff --git a/src/impl/urange.ts b/src/impl/urange.ts index 647e786..3f00420 100644 --- a/src/impl/urange.ts +++ b/src/impl/urange.ts @@ -1,11 +1,7 @@ -import { internal } from '@algorandfoundation/algorand-typescript' import { asBigInt, asUint64 } from '../util' +import type { StubUint64Compat } from './primitives' -export function* urangeImpl( - a: internal.primitives.StubUint64Compat, - b?: internal.primitives.StubUint64Compat, - c?: internal.primitives.StubUint64Compat, -) { +export function* urangeImpl(a: StubUint64Compat, b?: StubUint64Compat, c?: StubUint64Compat) { const start = b ? asBigInt(a) : BigInt(0) const end = b ? asBigInt(b) : asBigInt(a) const step = c ? asBigInt(c) : BigInt(1) diff --git a/src/impl/voter-params.ts b/src/impl/voter-params.ts new file mode 100644 index 0000000..2f48522 --- /dev/null +++ b/src/impl/voter-params.ts @@ -0,0 +1,30 @@ +import type { Account, op, uint64 } from '@algorandfoundation/algorand-typescript' +import { lazyContext } from '../context-helpers/internal-context' +import { getAccount } from './acct-params' +import type { StubUint64Compat } from './primitives' + +export class VoterData { + balance: uint64 + incentiveEligible: boolean + + constructor() { + this.balance = 0 + this.incentiveEligible = false + } +} + +const getVoterData = (a: Account | StubUint64Compat): VoterData => { + const acct = getAccount(a) + return lazyContext.getVoterData(acct) +} + +export const VoterParams: typeof op.VoterParams = { + voterBalance: function (a: Account | StubUint64Compat): readonly [uint64, boolean] { + const data = getVoterData(a) + return [data.balance, data.balance !== 0] + }, + voterIncentiveEligible: function (a: Account | StubUint64Compat): readonly [boolean, boolean] { + const data = getVoterData(a) + return [data.incentiveEligible, data.balance !== 0] + }, +} diff --git a/src/index.ts b/src/index.ts index 9ff217f..440af86 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,7 +1,4 @@ -import { internal } from '@algorandfoundation/algorand-typescript' - +export { AssertError, AvmError, CodeError, InternalError, NotImplementedError } from './errors' +export { toExternalValue } from './impl/primitives' +export { addEqualityTesters } from './set-up' export { TestExecutionContext } from './test-execution-context' -export const encodingUtil = { - ...internal.encodingUtil, - toExternalValue: internal.primitives.toExternalValue, -} diff --git a/src/internal/arc4.ts b/src/internal/arc4.ts new file mode 100644 index 0000000..6edbc3f --- /dev/null +++ b/src/internal/arc4.ts @@ -0,0 +1,3 @@ +export * from '@algorandfoundation/algorand-typescript/arc4' +export { abimethod, baremethod, Contract } from '../impl/contract' +export { methodSelector } from '../impl/method-selector' diff --git a/src/internal/index.ts b/src/internal/index.ts new file mode 100644 index 0000000..d3d3fea --- /dev/null +++ b/src/internal/index.ts @@ -0,0 +1,39 @@ +export * from '@algorandfoundation/algorand-typescript' +export { BaseContract, contract } from '../impl/base-contract' +export { compileImpl as compile } from '../impl/compiled' +export { abimethod, baremethod, Contract } from '../impl/contract' +export { ensureBudgetImpl as ensureBudget } from '../impl/ensure-budget' +export { Global } from '../impl/global' +export { log } from '../impl/log' +export { assertMatchImpl as assertMatch, matchImpl as match } from '../impl/match' +export { MutableArray } from '../impl/mutable-array' +export { BigUint, Bytes, Uint64 } from '../impl/primitives' +export { Account, Application, Asset } from '../impl/reference' +export { Box, BoxMap, BoxRef, GlobalState, LocalState } from '../impl/state' +export { TemplateVarImpl as TemplateVar } from '../impl/template-var' +export { Txn } from '../impl/txn' +export { urangeImpl as urange } from '../impl/urange' +export { assert, err } from '../util' +export * as arc4 from './arc4' +export * as op from './op' +import { ApplicationTxn, AssetConfigTxn, AssetFreezeTxn, AssetTransferTxn, KeyRegistrationTxn, PaymentTxn, Transaction } from '../impl/gtxn' +export const gtxn = { + Transaction, + PaymentTxn, + KeyRegistrationTxn, + AssetConfigTxn, + AssetTransferTxn, + AssetFreezeTxn, + ApplicationTxn, +} + +import { applicationCall, assetConfig, assetFreeze, assetTransfer, keyRegistration, payment, submitGroup } from '../impl/inner-transactions' +export const itxn = { + submitGroup, + payment, + keyRegistration, + assetConfig, + assetTransfer, + assetFreeze, + applicationCall, +} diff --git a/src/internal/op.ts b/src/internal/op.ts new file mode 100644 index 0000000..b1fe52d --- /dev/null +++ b/src/internal/op.ts @@ -0,0 +1,62 @@ +export * from '@algorandfoundation/algorand-typescript/op' +export { AcctParams, appOptedIn, balance, minBalance } from '../impl/acct-params' +export { AppGlobal } from '../impl/app-global' +export { AppLocal } from '../impl/app-local' +export { AppParams } from '../impl/app-params' +export { AssetHolding } from '../impl/asset-holding' +export { AssetParams } from '../impl/asset-params' +export { Block } from '../impl/block' +export { Box } from '../impl/box' +export { + ecdsaPkDecompress, + ecdsaPkRecover, + ecdsaVerify, + ed25519verify, + ed25519verifyBare, + EllipticCurve, + keccak256, + mimc, + sha256, + sha3_256, + sha512_256, + vrfVerify, +} from '../impl/crypto' +export { Global } from '../impl/global' +export { GTxn } from '../impl/gtxn' +export { GITxn, ITxn, ITxnCreate } from '../impl/itxn' +export { arg } from '../impl/logicSigArg' +export { onlineStake } from '../impl/online-stake' +export { + addw, + base64Decode, + bitLength, + bsqrt, + btoi, + bzero, + concat, + divmodw, + divw, + exp, + expw, + extract, + extractUint16, + extractUint32, + extractUint64, + getBit, + getByte, + itob, + JsonRef, + len, + mulw, + replace, + select, + setBit, + setByte, + shl, + shr, + sqrt, + substring, +} from '../impl/pure' +export { gloadBytes, gloadUint64, Scratch } from '../impl/scratch' +export { gaid, Txn } from '../impl/txn' +export { VoterParams } from '../impl/voter-params' diff --git a/src/runtime-helpers.ts b/src/runtime-helpers.ts index 3d7c5bf..051dce1 100644 --- a/src/runtime-helpers.ts +++ b/src/runtime-helpers.ts @@ -1,28 +1,25 @@ -import { internal } from '@algorandfoundation/algorand-typescript' import { ARC4Encoded } from '@algorandfoundation/algorand-typescript/arc4' +import { encodingUtil } from '@algorandfoundation/puya-ts' import { MAX_UINT64 } from './constants' import type { TypeInfo } from './encoders' -import { AccountCls } from './impl/account' +import { AvmError, CodeError, InternalError } from './errors' import { Uint64BackedCls } from './impl/base' -import { DeliberateAny } from './typescript-helpers' +import { AlgoTsPrimitiveCls, BigUintCls, BytesCls, checkBigUint, checkBytes, Uint64Cls } from './impl/primitives' +import { AccountCls } from './impl/reference' +import type { DeliberateAny } from './typescript-helpers' import { nameOfType } from './util' export { attachAbiMetadata } from './abi-metadata' -export { compileImpl } from './impl/compiled' export { emitImpl } from './impl/emit' export * from './impl/encoded-types' -export { decodeArc4Impl, encodeArc4Impl } from './impl/encoded-types' -export { ensureBudgetImpl } from './impl/ensure-budget' -export { assertMatchImpl, matchImpl } from './impl/match' -export { TemplateVarImpl } from './impl/template-var' -export { urangeImpl } from './impl/urange' +export { arc4EncodedLengthImpl, decodeArc4Impl, encodeArc4Impl } from './impl/encoded-types' export function switchableValue(x: unknown): bigint | string | boolean { if (typeof x === 'boolean') return x if (typeof x === 'bigint') return x if (typeof x === 'string') return x - if (x instanceof internal.primitives.AlgoTsPrimitiveCls) return x.valueOf() - internal.errors.internalError(`Cannot convert ${nameOfType(x)} to switchable value`) + if (x instanceof AlgoTsPrimitiveCls) return x.valueOf() + throw new InternalError(`Cannot convert ${nameOfType(x)} to switchable value`) } // export function wrapLiteral(x: unknown) { // if (typeof x === 'boolean') return x @@ -37,8 +34,8 @@ type UnaryOps = '~' function tryGetBigInt(value: unknown): bigint | undefined { if (typeof value == 'bigint') return value if (typeof value == 'number' && Number.isInteger(value)) return BigInt(value) - if (value instanceof internal.primitives.Uint64Cls) return value.valueOf() - if (value instanceof internal.primitives.BigUintCls) return value.valueOf() + if (value instanceof Uint64Cls) return value.valueOf() + if (value instanceof BigUintCls) return value.valueOf() return undefined } @@ -52,13 +49,13 @@ export function binaryOp(left: unknown, right: unknown, op: BinaryOps) { if (left instanceof Uint64BackedCls && right instanceof Uint64BackedCls) { return uint64BackedClsBinaryOp(left, right, op) } - if (left instanceof internal.primitives.BigUintCls || right instanceof internal.primitives.BigUintCls) { + if (left instanceof BigUintCls || right instanceof BigUintCls) { return bigUintBinaryOp(left, right, op) } - if (left instanceof internal.primitives.Uint64Cls || right instanceof internal.primitives.Uint64Cls) { + if (left instanceof Uint64Cls || right instanceof Uint64Cls) { return uint64BinaryOp(left, right, op) } - if (left instanceof internal.primitives.BytesCls || right instanceof internal.primitives.BytesCls) { + if (left instanceof BytesCls || right instanceof BytesCls) { return bytesBinaryOp(left, right, op) } const lbi = tryGetBigInt(left) @@ -80,7 +77,7 @@ export function binaryOp(left: unknown, right: unknown, op: BinaryOps) { } export function unaryOp(operand: unknown, op: UnaryOps) { - if (operand instanceof internal.primitives.Uint64Cls) { + if (operand instanceof Uint64Cls) { return uint64UnaryOp(operand, op) } return defaultUnaryOp(operand, op) @@ -96,7 +93,7 @@ function arc4EncodedOp(left: ARC4Encoded, right: ARC4Encoded, op: BinaryOps): De case '!==': return !compareEquality(left, right) default: - internal.errors.internalError(`Unsupported operator ${op}`) + throw new InternalError(`Unsupported operator ${op}`) } } @@ -106,7 +103,7 @@ function accountBinaryOp(left: AccountCls, right: AccountCls, op: BinaryOps): De case '!==': return bytesBinaryOp(left.bytes, right.bytes, op) default: - internal.errors.internalError(`Unsupported operator ${op}`) + throw new InternalError(`Unsupported operator ${op}`) } } function uint64BackedClsBinaryOp(left: Uint64BackedCls, right: Uint64BackedCls, op: BinaryOps): DeliberateAny { @@ -115,12 +112,12 @@ function uint64BackedClsBinaryOp(left: Uint64BackedCls, right: Uint64BackedCls, case '!==': return uint64BinaryOp(left.uint64, right.uint64, op) default: - internal.errors.internalError(`Unsupported operator ${op}`) + throw new InternalError(`Unsupported operator ${op}`) } } function uint64BinaryOp(left: DeliberateAny, right: DeliberateAny, op: BinaryOps): DeliberateAny { - const lbi = internal.primitives.Uint64Cls.fromCompat(left).valueOf() - const rbi = internal.primitives.Uint64Cls.fromCompat(right).valueOf() + const lbi = Uint64Cls.fromCompat(left).valueOf() + const rbi = Uint64Cls.fromCompat(right).valueOf() const result = (function () { switch (op) { case '+': @@ -131,7 +128,7 @@ function uint64BinaryOp(left: DeliberateAny, right: DeliberateAny, op: BinaryOps return lbi * rbi case '**': if (lbi === 0n && rbi === 0n) { - throw internal.errors.codeError('0 ** 0 is undefined') + throw new CodeError('0 ** 0 is undefined') } return lbi ** rbi case '/': @@ -140,12 +137,12 @@ function uint64BinaryOp(left: DeliberateAny, right: DeliberateAny, op: BinaryOps return lbi % rbi case '>>': if (rbi > 63n) { - throw new internal.errors.CodeError('expected shift <= 63') + throw new CodeError('expected shift <= 63') } return (lbi >> rbi) & MAX_UINT64 case '<<': if (rbi > 63n) { - throw new internal.errors.CodeError('expected shift <= 63') + throw new CodeError('expected shift <= 63') } return (lbi << rbi) & MAX_UINT64 case '>': @@ -167,15 +164,15 @@ function uint64BinaryOp(left: DeliberateAny, right: DeliberateAny, op: BinaryOps case '^': return lbi ^ rbi default: - internal.errors.internalError(`Unsupported operator ${op}`) + throw new InternalError(`Unsupported operator ${op}`) } })() - return typeof result === 'boolean' ? result : new internal.primitives.Uint64Cls(result) + return typeof result === 'boolean' ? result : new Uint64Cls(result) } function bigUintBinaryOp(left: DeliberateAny, right: DeliberateAny, op: BinaryOps): DeliberateAny { - const lbi = internal.primitives.checkBigUint(internal.primitives.BigUintCls.fromCompat(left).valueOf()) - const rbi = internal.primitives.checkBigUint(internal.primitives.BigUintCls.fromCompat(right).valueOf()) + const lbi = checkBigUint(BigUintCls.fromCompat(left).valueOf()) + const rbi = checkBigUint(BigUintCls.fromCompat(right).valueOf()) const result = (function () { switch (op) { case '+': @@ -186,7 +183,7 @@ function bigUintBinaryOp(left: DeliberateAny, right: DeliberateAny, op: BinaryOp return lbi * rbi case '**': if (lbi === 0n && rbi === 0n) { - throw internal.errors.codeError('0 ** 0 is undefined') + throw new CodeError('0 ** 0 is undefined') } return lbi ** rbi case '/': @@ -194,9 +191,9 @@ function bigUintBinaryOp(left: DeliberateAny, right: DeliberateAny, op: BinaryOp case '%': return lbi % rbi case '>>': - throw new internal.errors.CodeError('BigUint does not support >> operator') + throw new CodeError('BigUint does not support >> operator') case '<<': - throw new internal.errors.CodeError('BigUint does not support << operator') + throw new CodeError('BigUint does not support << operator') case '>': return lbi > rbi case '<': @@ -216,7 +213,7 @@ function bigUintBinaryOp(left: DeliberateAny, right: DeliberateAny, op: BinaryOp case '^': return lbi ^ rbi default: - internal.errors.internalError(`Unsupported operator ${op}`) + throw new InternalError(`Unsupported operator ${op}`) } })() if (typeof result === 'boolean') { @@ -224,16 +221,16 @@ function bigUintBinaryOp(left: DeliberateAny, right: DeliberateAny, op: BinaryOp } if (result < 0) { - internal.errors.avmError('BigUint underflow') + throw new AvmError('BigUint underflow') } - return new internal.primitives.BigUintCls(result) + return new BigUintCls(result) } function bytesBinaryOp(left: DeliberateAny, right: DeliberateAny, op: BinaryOps): DeliberateAny { - const lbb = internal.primitives.checkBytes(internal.primitives.BytesCls.fromCompat(left).asUint8Array()) - const rbb = internal.primitives.checkBytes(internal.primitives.BytesCls.fromCompat(right).asUint8Array()) - const lbi = internal.encodingUtil.uint8ArrayToBigInt(lbb) - const rbi = internal.encodingUtil.uint8ArrayToBigInt(rbb) + const lbb = checkBytes(BytesCls.fromCompat(left).asUint8Array()) + const rbb = checkBytes(BytesCls.fromCompat(right).asUint8Array()) + const lbi = encodingUtil.uint8ArrayToBigInt(lbb) + const rbi = encodingUtil.uint8ArrayToBigInt(rbb) const result = (function () { switch (op) { @@ -250,7 +247,7 @@ function bytesBinaryOp(left: DeliberateAny, right: DeliberateAny, op: BinaryOps) case '!==': return lbi !== rbi default: - internal.errors.internalError(`Unsupported operator ${op}`) + throw new InternalError(`Unsupported operator ${op}`) } })() return result @@ -266,7 +263,7 @@ function defaultBinaryOp(left: DeliberateAny, right: DeliberateAny, op: BinaryOp return left * right case '**': if (left === 0n && right === 0n) { - throw new internal.errors.CodeError('0 ** 0 is undefined') + throw new CodeError('0 ** 0 is undefined') } return left ** right case '/': @@ -276,7 +273,7 @@ function defaultBinaryOp(left: DeliberateAny, right: DeliberateAny, op: BinaryOp case '>>': if (typeof left === 'bigint' && typeof right === 'bigint') { if (right > 63n) { - throw new internal.errors.CodeError('expected shift <= 63') + throw new CodeError('expected shift <= 63') } return (left >> right) & MAX_UINT64 } @@ -284,7 +281,7 @@ function defaultBinaryOp(left: DeliberateAny, right: DeliberateAny, op: BinaryOp case '<<': if (typeof left === 'bigint' && typeof right === 'bigint') { if (right > 63n) { - throw new internal.errors.CodeError('expected shift <= 63') + throw new CodeError('expected shift <= 63') } return (left << right) & MAX_UINT64 } @@ -308,22 +305,22 @@ function defaultBinaryOp(left: DeliberateAny, right: DeliberateAny, op: BinaryOp case '^': return left ^ right default: - internal.errors.internalError(`Unsupported operator ${op}`) + throw new InternalError(`Unsupported operator ${op}`) } } function uint64UnaryOp(operand: DeliberateAny, op: UnaryOps): DeliberateAny { - const obi = internal.primitives.Uint64Cls.fromCompat(operand).valueOf() + const obi = Uint64Cls.fromCompat(operand).valueOf() switch (op) { case '~': return ~obi & MAX_UINT64 default: - internal.errors.internalError(`Unsupported operator ${op}`) + throw new InternalError(`Unsupported operator ${op}`) } } function defaultUnaryOp(_operand: DeliberateAny, op: UnaryOps): DeliberateAny { - internal.errors.internalError(`Unsupported operator ${op}`) + throw new InternalError(`Unsupported operator ${op}`) } const genericTypeMap = new WeakMap() diff --git a/src/set-up.ts b/src/set-up.ts index b368ebb..f1dc26a 100644 --- a/src/set-up.ts +++ b/src/set-up.ts @@ -1,7 +1,7 @@ -import { internal } from '@algorandfoundation/algorand-typescript' import { Address } from '@algorandfoundation/algorand-typescript/arc4' import { encodingUtil } from '@algorandfoundation/puya-ts' -import { AccountCls } from './impl/account' +import { AlgoTsPrimitiveCls, BigUintCls, BytesCls, Uint64Cls } from './impl/primitives' +import { AccountCls } from './impl/reference' type Tester = (this: TesterContext, a: unknown, b: unknown, customTesters: Array) => boolean | undefined interface TesterContext { @@ -11,11 +11,11 @@ interface ExpectObj { addEqualityTesters: (testers: Array) => void } -function addEqualityTesters(expectObj: ExpectObj) { +function doAddEqualityTesters(expectObj: ExpectObj) { expectObj.addEqualityTesters([ function IsSamePrimitiveTypeAndValue(this: TesterContext, subject, test, customTesters): boolean | undefined { - const subjectIsPrimitive = subject instanceof internal.primitives.AlgoTsPrimitiveCls - const testIsPrimitive = test instanceof internal.primitives.AlgoTsPrimitiveCls + const subjectIsPrimitive = subject instanceof AlgoTsPrimitiveCls + const testIsPrimitive = test instanceof AlgoTsPrimitiveCls const isSamePrimitive = subjectIsPrimitive && test instanceof Object.getPrototypeOf(subject).constructor if (subjectIsPrimitive && testIsPrimitive) { if (!isSamePrimitive) return false @@ -25,7 +25,7 @@ function addEqualityTesters(expectObj: ExpectObj) { return undefined }, function NumericPrimitiveIsNumericLiteral(this: TesterContext, subject, test, customTesters): boolean | undefined { - if (subject instanceof internal.primitives.Uint64Cls || subject instanceof internal.primitives.BigUintCls) { + if (subject instanceof Uint64Cls || subject instanceof BigUintCls) { const testValue = typeof test === 'bigint' ? test : typeof test === 'number' ? BigInt(test) : undefined if (testValue !== undefined) return this.equals(subject.valueOf(), testValue, customTesters) return undefined @@ -34,7 +34,7 @@ function addEqualityTesters(expectObj: ExpectObj) { return undefined }, function BytesPrimitiveIsUint8Array(this: TesterContext, subject, test, customTesters): boolean | undefined { - if (subject instanceof internal.primitives.BytesCls) { + if (subject instanceof BytesCls) { const testValue = test instanceof Uint8Array ? test : undefined if (testValue !== undefined) return this.equals(subject.asUint8Array(), testValue, customTesters) return undefined @@ -43,8 +43,9 @@ function addEqualityTesters(expectObj: ExpectObj) { return undefined }, function BytesPrimitiveIsArray(this: TesterContext, subject, test, customTesters): boolean | undefined { - if (subject instanceof internal.primitives.BytesCls) { - const testValue = Array.isArray(test) && test.every((i) => typeof i === 'number') ? new Uint8Array(test) : undefined + if (subject instanceof BytesCls) { + const testValue = + Array.isArray(test) && test.every((i) => typeof i === 'number' && i >= 0 && i < 256) ? new Uint8Array(test) : undefined if (testValue !== undefined) return this.equals(subject.asUint8Array(), testValue, customTesters) return undefined } @@ -52,7 +53,7 @@ function addEqualityTesters(expectObj: ExpectObj) { return undefined }, function BytesPrimitiveIsString(this: TesterContext, subject, test, customTesters): boolean | undefined { - if (subject instanceof internal.primitives.BytesCls) { + if (subject instanceof BytesCls) { const testValue = typeof test === 'string' ? encodingUtil.utf8ToUint8Array(test) : undefined if (testValue !== undefined) return this.equals(subject.asUint8Array(), testValue, customTesters) return undefined @@ -60,6 +61,15 @@ function addEqualityTesters(expectObj: ExpectObj) { // Defer to other testers return undefined }, + function Uint8ArrayIsBytesPrimitive(this: TesterContext, subject, test, customTesters): boolean | undefined { + if (subject instanceof Uint8Array) { + const testValue = test instanceof BytesCls ? test : undefined + if (testValue !== undefined) return this.equals(subject, testValue.asUint8Array(), customTesters) + return undefined + } + // Defer to other testers + return undefined + }, function AccountIsAddressStr(this: TesterContext, subject, test, customTesters): boolean | undefined { if (subject instanceof AccountCls) { const testValue = typeof test === 'string' ? encodingUtil.base32ToUint8Array(test).slice(0, 32) : undefined @@ -71,7 +81,7 @@ function addEqualityTesters(expectObj: ExpectObj) { }, function AccountIsAddressBytes(this: TesterContext, subject, test, customTesters): boolean | undefined { if (subject instanceof AccountCls) { - const testValue = test instanceof internal.primitives.BytesCls ? test.asUint8Array().slice(0, 32) : undefined + const testValue = test instanceof BytesCls ? test.asUint8Array().slice(0, 32) : undefined if (testValue !== undefined) return this.equals(subject.bytes, testValue, customTesters) return undefined } @@ -89,7 +99,7 @@ function addEqualityTesters(expectObj: ExpectObj) { }, function AddressIsAccountBytes(this: TesterContext, subject, test, customTesters): boolean | undefined { if (subject instanceof Address) { - const testValue = test instanceof internal.primitives.BytesCls ? test.asUint8Array().slice(0, 32) : undefined + const testValue = test instanceof BytesCls ? test.asUint8Array().slice(0, 32) : undefined if (testValue !== undefined) return this.equals(subject.native.bytes, testValue, customTesters) return undefined } @@ -105,9 +115,47 @@ function addEqualityTesters(expectObj: ExpectObj) { // Defer to other testers return undefined }, + function BigIntIsNumber(this: TesterContext, subject, test, customTesters): boolean | undefined { + if (typeof subject === 'bigint') { + const testValue = typeof test === 'number' ? test : undefined + if (testValue !== undefined) return this.equals(subject, BigInt(testValue), customTesters) + return undefined + } + // Defer to other testers + return undefined + }, + function NumberIsBigInt(this: TesterContext, subject, test, customTesters): boolean | undefined { + if (typeof subject === 'number') { + const testValue = typeof test === 'bigint' ? test : undefined + if (testValue !== undefined) return this.equals(BigInt(subject), testValue, customTesters) + return undefined + } + // Defer to other testers + return undefined + }, ]) } -export function setUpTests({ expect }: { expect: ExpectObj }) { - addEqualityTesters(expect) +/** + * Adds custom equality testers for Algorand types to vitest's expect function. + * This allows vitest to properly compare Algorand types such as uint64, biguint, and bytes + * against JS native types such as number, bigint and Uint8Array, in tests. + * + * @param {Object} params - The parameters object + * @param {ExpectObj} params.expect - vitest's expect object to extend with custom equality testers + * + * @example + * ```ts + * import { beforeAll, expect } from 'vitest' + * import { addEqualityTesters } from '@algorandfoundation/algorand-typescript-testing'; + * + * beforeAll(() => { + * addEqualityTesters({ expect }); + * }); + * ``` + * + * @returns {void} + */ +export function addEqualityTesters({ expect }: { expect: ExpectObj }) { + doAddEqualityTesters(expect) } diff --git a/src/subcontexts/contract-context.ts b/src/subcontexts/contract-context.ts index 4603e5b..f53e053 100644 --- a/src/subcontexts/contract-context.ts +++ b/src/subcontexts/contract-context.ts @@ -1,31 +1,19 @@ -import { - Account, - Application, - Asset, - BaseContract, - Bytes, - bytes, - Contract, - contract, - internal, - LocalState, -} from '@algorandfoundation/algorand-typescript' -import { - AbiMetadata, - copyAbiMetadatas, - getArc4Selector, - getContractAbiMetadata, - getContractMethodAbiMetadata, - isContractProxy, -} from '../abi-metadata' +import type { Account, Application, Asset, contract, LocalState } from '@algorandfoundation/algorand-typescript' +import type { ARC4Encoded } from '@algorandfoundation/algorand-typescript/arc4' +import type { AbiMetadata } from '../abi-metadata' +import { getArc4Selector, getContractAbiMetadata, getContractMethodAbiMetadata } from '../abi-metadata' import { BytesMap } from '../collections/custom-key-map' import { checkRoutingConditions } from '../context-helpers/context-util' import { lazyContext } from '../context-helpers/internal-context' -import { toBytes, type TypeInfo } from '../encoders' -import { AccountCls } from '../impl/account' -import { ApplicationCls } from '../impl/application' -import { AssetCls } from '../impl/asset' +import { type TypeInfo } from '../encoders' +import { CodeError } from '../errors' +import { BaseContract, ContractOptionsSymbol } from '../impl/base-contract' +import { Contract } from '../impl/contract' +import { getArc4Encoded, UintNImpl } from '../impl/encoded-types' +import { Bytes } from '../impl/primitives' +import { AccountCls, ApplicationCls, AssetCls } from '../impl/reference' import { BoxCls, BoxMapCls, BoxRefCls, GlobalStateCls } from '../impl/state' +import type { Transaction } from '../impl/transactions' import { ApplicationTransaction, AssetConfigTransaction, @@ -33,11 +21,9 @@ import { AssetTransferTransaction, KeyRegistrationTransaction, PaymentTransaction, - Transaction, } from '../impl/transactions' import { getGenericTypeInfo } from '../runtime-helpers' -import { DeliberateAny, IConstructor } from '../typescript-helpers' - +import type { DeliberateAny, IConstructor } from '../typescript-helpers' type ContractOptionsParameter = Parameters[0] type StateTotals = Pick @@ -95,28 +81,43 @@ const extractStates = (contract: BaseContract, contractOptions: ContractOptionsP return states } +const getUintN8Impl = (value: number) => new UintNImpl({ name: 'UintN<8>', genericArgs: [{ name: '8' }] }, value) + const extractArraysFromArgs = (app: Application, methodSelector: Uint8Array, args: DeliberateAny[]) => { const transactions: Transaction[] = [] - const accounts: Account[] = [] + const accounts: Account[] = [lazyContext.defaultSender] const apps: Application[] = [app] const assets: Asset[] = [] - const appArgs: bytes[] = [] + let appArgs: ARC4Encoded[] = [] for (const arg of args) { if (isTransaction(arg)) { transactions.push(arg) } else if (arg instanceof AccountCls) { - appArgs.push(toBytes(accounts.length)) + appArgs.push(getUintN8Impl(accounts.length)) accounts.push(arg as Account) } else if (arg instanceof ApplicationCls) { - appArgs.push(toBytes(apps.length)) + appArgs.push(getUintN8Impl(apps.length)) apps.push(arg as Application) } else if (arg instanceof AssetCls) { - appArgs.push(toBytes(assets.length)) + appArgs.push(getUintN8Impl(assets.length)) assets.push(arg as Asset) + } else { + appArgs.push(arg) } } - return { accounts, apps, assets, transactions, appArgs: [Bytes(methodSelector), ...appArgs] } + + if (appArgs.length > 15) { + const packed = getArc4Encoded(appArgs.slice(14)) + appArgs = [...appArgs.slice(0, 14), packed] + } + return { + accounts, + apps, + assets, + transactions, + appArgs: [Bytes(methodSelector), ...appArgs.filter((a) => a !== undefined).map((a) => a.bytes)], + } } function isTransaction(obj: unknown): obj is Transaction { @@ -130,12 +131,44 @@ function isTransaction(obj: unknown): obj is Transaction { ) } +/** + * Provides a context for creating contracts and registering created contract instances + * with test execution context. + */ export class ContractContext { + /** + * Creates a new contract instance and register the created instance with test execution context. + * + * @template T Type of contract extending BaseContract + * @param {IConstructor} type The contract class constructor + * @param {...any[]} args Constructor arguments for the contract + * @returns {T} Proxied instance of the contract + * @example + * const ctx = new TestExecutionContext(); + * const contract = ctx.contract.create(MyContract); + */ create(type: IConstructor, ...args: DeliberateAny[]): T { const proxy = new Proxy(type, this.getContractProxyHandler(this.isArc4(type))) return new proxy(...args) } + /** + * Creates an array of transactions for calling a contract method. + * + * @internal + * @template TParams Array of parameter types + * @param {BaseContract} contract The contract instance + * @param {AbiMetadata | undefined} abiMetadata ABI metadata for the method + * @param {...TParams} args Method arguments + * @returns {Transaction[]} Array of transactions needed to execute the method + * @example + * const txns = ContractContext.createMethodCallTxns( + * myContract, + * methodAbiMetadata, + * arg1, + * arg2 + * ); + */ static createMethodCallTxns( contract: BaseContract, abiMetadata: AbiMetadata | undefined, @@ -155,13 +188,20 @@ export class ContractContext { } private isArc4(type: IConstructor): boolean { + const result = (type as DeliberateAny as typeof BaseContract).isArc4 + if (result !== undefined && result !== null) { + return result + } + // TODO: uncomment the following line once version puya-ts 1.0.0 is released and delete the rest of the function + // throw new internal.errors.CodeError('Cannot create a contract for class as it does not extend Contract or BaseContract') + const proto = Object.getPrototypeOf(type) if (proto === BaseContract) { return false } else if (proto === Contract) { return true - } else if (proto === Object) { - throw new Error('Cannot create a contract for class as it does not extend Contract or BaseContract') + } else if (proto === Object || proto === null) { + throw new CodeError('Cannot create a contract for class as it does not extend Contract or BaseContract') } return this.isArc4(proto) } @@ -189,14 +229,12 @@ export class ContractContext { lazyContext.txn.ensureScope([txn]).execute(() => { t = new target(...args) }) - appData.isCreating = hasCreateMethods(t!) + appData.isCreating = isArc4 && hasCreateMethods(t! as Contract) const instance = new Proxy(t!, { get(target, prop, receiver) { - if (prop === isContractProxy) { - return true - } const orig = Reflect.get(target, prop, receiver) - const abiMetadata = getContractMethodAbiMetadata(target, prop as string) + const abiMetadata = + isArc4 && typeof orig === 'function' ? getContractMethodAbiMetadata(target as Contract, orig.name) : undefined const isProgramMethod = prop === 'approvalProgram' || prop === 'clearStateProgram' const isAbiMethod = isArc4 && abiMetadata if (isAbiMethod || isProgramMethod) { @@ -221,8 +259,6 @@ export class ContractContext { onConstructed(application, instance, getContractOptions(t!)) - copyAbiMetadatas(t!, instance) - return instance }, } @@ -231,10 +267,10 @@ export class ContractContext { const getContractOptions = (contract: BaseContract): ContractOptionsParameter | undefined => { const contractClass = contract.constructor as DeliberateAny - return contractClass[internal.ContractOptionsSymbol] as ContractOptionsParameter + return contractClass[ContractOptionsSymbol] as ContractOptionsParameter } -const hasCreateMethods = (contract: BaseContract) => { +const hasCreateMethods = (contract: Contract) => { const metadatas = getContractAbiMetadata(contract) return Object.values(metadatas).some((metadata) => (metadata.onCreate ?? 'disallow') !== 'disallow') } diff --git a/src/subcontexts/ledger-context.ts b/src/subcontexts/ledger-context.ts index 1a1b0e0..c8fb887 100644 --- a/src/subcontexts/ledger-context.ts +++ b/src/subcontexts/ledger-context.ts @@ -1,17 +1,34 @@ -import { Account, Application, Asset, BaseContract, bytes, internal, LocalStateForAccount } from '@algorandfoundation/algorand-typescript' +import type { + Account as AccountType, + Application as ApplicationType, + Asset as AssetType, + BaseContract, + bytes, + LocalStateForAccount, + uint64, +} from '@algorandfoundation/algorand-typescript' import { AccountMap, Uint64Map } from '../collections/custom-key-map' import { MAX_UINT64 } from '../constants' -import { AccountData, AssetHolding } from '../impl/account' -import { ApplicationData } from '../impl/application' -import { AssetData } from '../impl/asset' +import { toBytes } from '../encoders' +import { InternalError } from '../errors' +import { BlockData } from '../impl/block' import { GlobalData } from '../impl/global' -import { GlobalStateCls } from '../impl/state' -import { asBigInt, asMaybeBytesCls, asMaybeUint64Cls, asUint64, asUint64Cls, iterBigInt } from '../util' - -interface BlockData { - seed: bigint - timestamp: bigint -} +import { Uint64Cls, type StubBytesCompat, type StubUint64Compat } from '../impl/primitives' +import type { AssetData } from '../impl/reference' +import { + AccountCls, + AccountData, + Application, + ApplicationCls, + ApplicationData, + Asset, + AssetHolding, + getDefaultAssetData, +} from '../impl/reference' +import { GlobalStateCls, LocalStateCls } from '../impl/state' +import { VoterData } from '../impl/voter-params' +import type { PickPartial } from '../typescript-helpers' +import { asBigInt, asBytes, asMaybeBytesCls, asMaybeUint64Cls, asUint64, asUint64Cls, asUint8Array, iterBigInt } from '../util' export class LedgerContext { appIdIter = iterBigInt(1001n, MAX_UINT64) @@ -20,36 +37,63 @@ export class LedgerContext { appIdContractMap = new Uint64Map() accountDataMap = new AccountMap() assetDataMap = new Uint64Map() + voterDataMap = new AccountMap() blocks = new Uint64Map() globalData = new GlobalData() + onlineStake = 0 - /* @internal */ - addAppIdContractMap(appId: internal.primitives.StubUint64Compat, contract: BaseContract): void { + /** + * Adds a contract to the application ID contract map. + * @internal + * @param appId - The application ID. + * @param contract - The contract to add. + */ + addAppIdContractMap(appId: StubUint64Compat, contract: BaseContract): void { this.appIdContractMap.set(appId, contract) } - getAccount(address: Account): Account { - if (this.accountDataMap.has(address)) { - return Account(address.bytes) - } - throw internal.errors.internalError('Unknown account, check correct testing context is active') + /** + * Retrieves an account by address. + * @param address - The account address. + * @returns The account. + */ + getAccount(address: AccountType | StubBytesCompat): AccountType { + return new AccountCls(address instanceof AccountCls ? address.bytes : asBytes(address as StubBytesCompat)) } - getAsset(assetId: internal.primitives.StubUint64Compat): Asset { + /** + * Retrieves an asset by asset ID. + * @param assetId - The asset ID. + * @returns The asset. + * @throws If the asset is unknown. + */ + getAsset(assetId: StubUint64Compat): AssetType { if (this.assetDataMap.has(assetId)) { return Asset(asUint64(assetId)) } - throw internal.errors.internalError('Unknown asset, check correct testing context is active') + throw new InternalError('Unknown asset, check correct testing context is active') } - getApplication(applicationId: internal.primitives.StubUint64Compat): Application { + /** + * Retrieves an application by application ID. + * @param applicationId - The application ID. + * @returns The application. + * @throws If the application is unknown. + */ + getApplication(applicationId: StubUint64Compat): ApplicationType { if (this.applicationDataMap.has(applicationId)) { return Application(asUint64(applicationId)) } - throw internal.errors.internalError('Unknown application, check correct testing context is active') + throw new InternalError('Unknown application, check correct testing context is active') } - getApplicationForContract(contract: BaseContract): Application { + /** + * Retrieves an application for a given contract. + * @param contract - The contract. + * @returns The application. + * @throws If the contract is unknown. + */ + getApplicationForContract(contract: BaseContract): ApplicationType { for (const [appId, c] of this.appIdContractMap) { if (c === contract) { if (this.applicationDataMap.has(appId)) { @@ -57,10 +101,15 @@ export class LedgerContext { } } } - throw internal.errors.internalError('Unknown contract, check correct testing context is active') + throw new InternalError('Unknown contract, check correct testing context is active') } - getApplicationForApprovalProgram(approvalProgram: bytes | readonly bytes[] | undefined): Application | undefined { + /** + * Retrieves an application for a given approval program. + * @param approvalProgram - The approval program. + * @returns The application or undefined if not found. + */ + getApplicationForApprovalProgram(approvalProgram: bytes | readonly bytes[] | undefined): ApplicationType | undefined { if (approvalProgram === undefined) { return undefined } @@ -84,19 +133,14 @@ export class LedgerContext { /** * Update asset holdings for account, only specified values will be updated. - * Account will also be opted-in to asset + * AccountType will also be opted-in to asset * @param account * @param assetId * @param balance * @param frozen */ - updateAssetHolding( - account: Account, - assetId: internal.primitives.StubUint64Compat | Asset, - balance?: internal.primitives.StubUint64Compat, - frozen?: boolean, - ): void { - const id = asMaybeUint64Cls(assetId) ?? asUint64Cls((assetId as Asset).id) + updateAssetHolding(account: AccountType, assetId: StubUint64Compat | AssetType, balance?: StubUint64Compat, frozen?: boolean): void { + const id = asMaybeUint64Cls(assetId) ?? asUint64Cls((assetId as AssetType).id) const accountData = this.accountDataMap.get(account)! const asset = this.assetDataMap.get(id)! const holding = accountData.optedAssets.get(id) ?? new AssetHolding(0n, asset.defaultFrozen) @@ -105,6 +149,10 @@ export class LedgerContext { accountData.optedAssets.set(id, holding) } + /** + * Patches global data with the provided partial data. + * @param data - The partial global data. + */ patchGlobalData(data: Partial) { this.globalData = { ...this.globalData, @@ -112,70 +160,171 @@ export class LedgerContext { } } - setBlock( - index: internal.primitives.StubUint64Compat, - seed: internal.primitives.StubUint64Compat, - timestamp: internal.primitives.StubUint64Compat, + /** + * Patches account data with the provided partial data. + * @param account - The account. + * @param data - The partial account data. + */ + patchAccountData(account: AccountType, data: Partial> & Partial>): void { + const accountData = this.accountDataMap.get(account) ?? new AccountData() + this.accountDataMap.set(account, { + ...accountData, + ...data, + account: { + ...accountData.account, + ...data.account, + }, + }) + } + + /** + * Patches application data with the provided partial data. + * @param app - The application. + * @param data - The partial application data. + */ + patchApplicationData( + app: ApplicationType, + data: Partial> & Partial>, ): void { - const i = asBigInt(index) - const s = asBigInt(seed) - const t = asBigInt(timestamp) + const applicationData = this.applicationDataMap.get(app.id) ?? new ApplicationData() + this.applicationDataMap.set(app.id, { + ...applicationData, + ...data, + application: { + ...applicationData.application, + ...data.application, + }, + }) + } + + /** + * Patches asset data with the provided partial data. + * @param account - The asset. + * @param data - The partial asset data. + */ + patchAssetData(asset: AssetType, data: Partial) { + const assetData = this.assetDataMap.get(asset.id) ?? getDefaultAssetData() + this.assetDataMap.set(asset.id, { + ...assetData, + ...data, + }) + } + + /** + * Patches voter data with the provided partial data. + * @param account - The account. + * @param data - The partial voter data. + */ + patchVoterData(account: AccountType, data: Partial) { + const voterData = this.voterDataMap.get(account) ?? new VoterData() + this.voterDataMap.set(account, { + ...voterData, + ...data, + }) + } - this.blocks.set(i, { seed: s, timestamp: t }) + /** + * Patches block data with the provided partial data. + * @param index - The block index. + * @param data - The partial block data. + */ + patchBlockData(index: StubUint64Compat, data: Partial): void { + const i = asUint64(index) + const blockData = this.blocks.get(i) ?? new BlockData() + this.blocks.set(i, { + ...blockData, + ...data, + }) } - getBlockContent(index: internal.primitives.StubUint64Compat): BlockData { + /** + * Retrieves block data by index. + * @param index - The block index. + * @returns The block data. + * @throws If the block is not set. + */ + getBlockData(index: StubUint64Compat): BlockData { const i = asBigInt(index) if (this.blocks.has(i)) { return this.blocks.get(i)! } - throw internal.errors.internalError(`Block ${i} not set`) + throw new InternalError(`Block ${i} not set`) } - getGlobalState(app: Application, key: internal.primitives.StubBytesCompat): [GlobalStateCls, true] | [undefined, false] { - const appData = this.applicationDataMap.get(app.id) + /** + * Retrieves global state for an application by key. + * @param app - The application. + * @param key - The key. + * @returns The global state and a boolean indicating if it was found. + */ + getGlobalState(app: ApplicationType | BaseContract, key: StubBytesCompat): [GlobalStateCls, true] | [undefined, false] { + const appId = this.getAppId(app) + const appData = this.applicationDataMap.get(appId) if (!appData?.application.globalStates.has(key)) { return [undefined, false] } return [appData.application.globalStates.getOrFail(key), true] } - setGlobalState( - app: Application, - key: internal.primitives.StubBytesCompat, - value: internal.primitives.StubUint64Compat | internal.primitives.StubBytesCompat | undefined, - ): void { - const appData = this.applicationDataMap.getOrFail(app.id) - const globalState = appData.application.globalStates.getOrFail(key) + /** + * Sets global state for an application by key. + * @param app - The application. + * @param key - The key. + * @param value - The value (optional). + */ + setGlobalState(app: ApplicationType | BaseContract, key: StubBytesCompat, value: StubUint64Compat | StubBytesCompat | undefined): void { + const appId = this.getAppId(app) + const appData = this.applicationDataMap.getOrFail(appId) + const globalState = appData.application.globalStates.get(key) if (value === undefined) { - globalState.delete() + globalState?.delete() + } else if (globalState === undefined) { + appData.application.globalStates.set(key, new GlobalStateCls(asBytes(key), asMaybeUint64Cls(value) ?? asMaybeBytesCls(value))) } else { globalState.value = asMaybeUint64Cls(value) ?? asMaybeBytesCls(value) } } + /** + * Retrieves local state for an application and account by key. + * @param app - The application. + * @param account - The account. + * @param key - The key. + * @returns The local state and a boolean indicating if it was found. + */ getLocalState( - app: Application, - account: Account, - key: internal.primitives.StubBytesCompat, + app: ApplicationType | BaseContract | uint64, + account: AccountType, + key: StubBytesCompat, ): [LocalStateForAccount, true] | [undefined, false] { - const appData = this.applicationDataMap.get(app.id) + const appId = app instanceof Uint64Cls ? app : this.getAppId(app as ApplicationType | BaseContract) + const appData = this.applicationDataMap.get(appId) if (!appData?.application.localStates.has(key)) { return [undefined, false] } - const localState = appData.application.localStates.getOrFail(key) - return [localState(account), true] + const localState = appData.application.localStateMaps.getOrFail(key) + const accountLocalState = localState.get(account) + return [accountLocalState as LocalStateForAccount, true] } - setLocalState( - app: Application, - account: Account, - key: internal.primitives.StubBytesCompat, - value: internal.primitives.StubUint64Compat | internal.primitives.StubBytesCompat | undefined, - ): void { - const appData = this.applicationDataMap.getOrFail(app.id) - const localState = appData.application.localStates.getOrFail(key) - const accountLocalState = localState(account) + /** + * Sets local state for an application and account by key. + * @param app - The application. + * @param account - The account. + * @param key - The key. + * @param value - The value (optional). + */ + setLocalState(app: ApplicationType | BaseContract | uint64, account: AccountType, key: StubBytesCompat, value: T | undefined): void { + const appId = app instanceof Uint64Cls ? app : this.getAppId(app as ApplicationType | BaseContract) + const appData = this.applicationDataMap.getOrFail(appId) + if (!appData.application.localStateMaps.has(key)) { + appData.application.localStateMaps.set(key, new AccountMap()) + } + const localState = appData.application.localStateMaps.getOrFail(key) + if (!localState.has(account)) { + localState.set(account, new LocalStateCls()) + } + const accountLocalState = localState.getOrFail(account) if (value === undefined) { accountLocalState.delete() } else { @@ -183,23 +332,89 @@ export class LedgerContext { } } - getBox(app: Application, key: internal.primitives.StubBytesCompat): Uint8Array { - const appData = this.applicationDataMap.getOrFail(app.id) + /** + * Retrieves a box for an application by key. + * @param app - The application. + * @param key - The key. + * @returns The box data. + */ + getBox(app: ApplicationType | BaseContract, key: StubBytesCompat): Uint8Array { + const appId = this.getAppId(app) + const appData = this.applicationDataMap.getOrFail(appId) + const materialised = appData.application.materialisedBoxes.get(key) + if (materialised !== undefined) { + return asUint8Array(toBytes(materialised)) + } return appData.application.boxes.get(key) ?? new Uint8Array() } - setBox(app: Application, key: internal.primitives.StubBytesCompat, value: Uint8Array): void { - const appData = this.applicationDataMap.getOrFail(app.id) - appData.application.boxes.set(key, value) + /** + * Retrieves a materialised box for an application by key. + * @internal + * @param app - The application. + * @param key - The key. + * @returns The materialised box data if exists or undefined. + */ + getMaterialisedBox(app: ApplicationType | BaseContract, key: StubBytesCompat): T | undefined { + const appId = this.getAppId(app) + const appData = this.applicationDataMap.getOrFail(appId) + return appData.application.materialisedBoxes.get(key) as T | undefined + } + + /** + * Sets a box for an application by key. + * @param app - The application. + * @param key - The key. + * @param value - The box data. + */ + setBox(app: ApplicationType | BaseContract, key: StubBytesCompat, value: StubBytesCompat | Uint8Array): void { + const appId = this.getAppId(app) + const appData = this.applicationDataMap.getOrFail(appId) + const uint8ArrayValue = value instanceof Uint8Array ? value : asUint8Array(value) + appData.application.boxes.set(key, uint8ArrayValue) + appData.application.materialisedBoxes.set(key, undefined) + } + + /** + + * Cache the materialised box for an application by key. +* @internal + * @param app - The application. + * @param key - The key. + * @param value - The box data. + */ + setMatrialisedBox(app: ApplicationType | BaseContract, key: StubBytesCompat, value: TValue | undefined): void { + const appId = this.getAppId(app) + const appData = this.applicationDataMap.getOrFail(appId) + appData.application.materialisedBoxes.set(key, value) } - deleteBox(app: Application, key: internal.primitives.StubBytesCompat): boolean { - const appData = this.applicationDataMap.getOrFail(app.id) + /** + * Deletes a box for an application by key. + * @param app - The application. + * @param key - The key. + * @returns True if the box was deleted, false otherwise. + */ + deleteBox(app: ApplicationType | BaseContract, key: StubBytesCompat): boolean { + const appId = this.getAppId(app) + const appData = this.applicationDataMap.getOrFail(appId) + appData.application.materialisedBoxes.delete(key) return appData.application.boxes.delete(key) } - boxExists(app: Application, key: internal.primitives.StubBytesCompat): boolean { - const appData = this.applicationDataMap.getOrFail(app.id) + /** + * Checks if a box exists for an application by key. + * @param app - The application. + * @param key - The key. + * @returns True if the box exists, false otherwise. + */ + boxExists(app: ApplicationType | BaseContract, key: StubBytesCompat): boolean { + const appId = this.getAppId(app) + const appData = this.applicationDataMap.getOrFail(appId) return appData.application.boxes.has(key) } + + private getAppId(app: ApplicationType | BaseContract): uint64 { + return app instanceof ApplicationCls ? app.id : this.getApplicationForContract(app as BaseContract).id + } } diff --git a/src/subcontexts/transaction-context.ts b/src/subcontexts/transaction-context.ts index 3b9a119..17b130b 100644 --- a/src/subcontexts/transaction-context.ts +++ b/src/subcontexts/transaction-context.ts @@ -1,21 +1,24 @@ -import { bytes, Contract, internal, TransactionType, uint64 } from '@algorandfoundation/algorand-typescript' -import { AbiMetadata, getContractMethodAbiMetadata } from '../abi-metadata' +import type { bytes, Contract, uint64 } from '@algorandfoundation/algorand-typescript' +import { TransactionType } from '@algorandfoundation/algorand-typescript' +import { getContractAbiMetadata, type AbiMetadata } from '../abi-metadata' import { TRANSACTION_GROUP_MAX_SIZE } from '../constants' import { checkRoutingConditions } from '../context-helpers/context-util' import { lazyContext } from '../context-helpers/internal-context' -import { DecodedLogs, decodeLogs, LogDecoding } from '../decode-logs' -import { testInvariant } from '../errors' -import { +import type { DecodedLogs, LogDecoding } from '../decode-logs' +import { decodeLogs } from '../decode-logs' +import { InternalError, testInvariant } from '../errors' +import type { ApplicationInnerTxn, AssetConfigInnerTxn, AssetFreezeInnerTxn, AssetTransferInnerTxn, - createInnerTxn, KeyRegistrationInnerTxn, PaymentInnerTxn, } from '../impl/inner-transactions' -import { InnerTxn, InnerTxnFields } from '../impl/itxn' -import { +import { createInnerTxn } from '../impl/inner-transactions' +import type { InnerTxn, InnerTxnFields } from '../impl/itxn' +import type { StubBytesCompat, StubUint64Compat } from '../impl/primitives' +import type { AllTransactionFields, ApplicationTransaction, AssetConfigTransaction, @@ -25,7 +28,7 @@ import { PaymentTransaction, Transaction, } from '../impl/transactions' -import { FunctionKeys } from '../typescript-helpers' +import type { DeliberateAny, FunctionKeys } from '../typescript-helpers' import { asBigInt, asNumber, asUint64 } from '../util' import { ContractContext } from './contract-context' @@ -50,6 +53,9 @@ interface ExecutionScope { execute: (body: () => TReturn) => TReturn } +/** + * Represents a deferred application call. + */ export class DeferredAppCall { constructor( private readonly appId: uint64, @@ -59,19 +65,45 @@ export class DeferredAppCall { private readonly args: TParams, ) {} + /** + * Submits the deferred application call. + * @returns The result of the application call. + */ submit(): TReturn { checkRoutingConditions(this.appId, this.abiMetadata) return this.method(...this.args) } } +/** + * Manages transaction contexts and groups. + */ export class TransactionContext { readonly groups: TransactionGroup[] = [] #activeGroup: TransactionGroup | undefined - createScope(group: Array>, activeTransactionIndex?: number): ExecutionScope { + /** + * Creates a new execution scope for a group of transactions. + * @param group The group of transactions or deferred application calls. + * @param activeTransactionIndex The index of the active transaction. + * @returns The execution scope. + */ + createScope( + group: Array>, + activeTransactionIndex?: number, + ): ExecutionScope { + let activeIndex = activeTransactionIndex const transactions = group.map((t) => (t instanceof DeferredAppCall ? t.txns : [t])).flat() - const transactionGroup = new TransactionGroup(transactions, activeTransactionIndex) + if (activeIndex === undefined) { + const lastAppCall = group + .filter((t) => t instanceof DeferredAppCall) + .at(-1) + ?.txns.at(-1) + if (lastAppCall) { + activeIndex = transactions.indexOf(lastAppCall) + } + } + const transactionGroup = new TransactionGroup(transactions, activeIndex) this.#activeGroup = transactionGroup @@ -90,7 +122,13 @@ export class TransactionContext { } } - /* internal */ + /** + * Ensures that a scope is created for the given group of transactions. + * @internal + * @param group The group of transactions. + * @param activeTransactionIndex The index of the active transaction. + * @returns The execution scope. + */ ensureScope(group: Transaction[], activeTransactionIndex?: number): ExecutionScope { if (!this.#activeGroup || !this.#activeGroup.transactions.length) { return this.createScope(group, activeTransactionIndex) @@ -102,33 +140,60 @@ export class TransactionContext { } } + /** + * Gets the active transaction group. + * @returns The active transaction group. + * @throws If there is no active transaction group. + */ get activeGroup(): TransactionGroup { if (this.#activeGroup) { return this.#activeGroup } - throw internal.errors.internalError('no active txn group') + throw new InternalError('no active txn group') } + /** + * Gets the last transaction group. + * @returns The last transaction group. + * @throws If there are no transaction groups. + */ get lastGroup(): TransactionGroup { if (this.groups.length === 0) { - internal.errors.internalError('No group transactions found!') + throw new InternalError('No group transactions found!') } return this.groups.at(-1)! } + /** + * Gets the last active transaction. + * @returns The last active transaction. + */ get lastActive(): Transaction { return this.lastGroup.activeTransaction } - /* internal */ - appendLog(value: internal.primitives.StubBytesCompat): void { + /** + * Appends a log to the active transaction. + * @internal + * @param value The log value. + * @throws If the active transaction is not an application call. + */ + appendLog(value: StubBytesCompat): void { const activeTransaction = this.activeGroup.activeTransaction if (activeTransaction.type !== TransactionType.ApplicationCall) { - throw internal.errors.internalError('Can only add logs to ApplicationCallTransaction!') + throw new InternalError('Can only add logs to ApplicationCallTransaction!') } activeTransaction.appendLog(value) } + /** + * Defers an application call. + * @param contract The contract. + * @param method The method to call. + * @param methodName The name of the method. + * @param args The arguments for the method. + * @returns The deferred application call. + */ deferAppCall( contract: TContract, method: (...args: TParams) => TReturn, @@ -136,11 +201,17 @@ export class TransactionContext { ...args: TParams ): DeferredAppCall { const appId = lazyContext.ledger.getApplicationForContract(contract) - const abiMetadata = getContractMethodAbiMetadata(contract, methodName as string) + const abiMetadata = getContractAbiMetadata(contract)[methodName as string] const txns = ContractContext.createMethodCallTxns(contract, abiMetadata, ...args) return new DeferredAppCall(appId.id, txns, method, abiMetadata, args) } + /** + * Exports logs for the given application ID. + * @param appId The application ID. + * @param decoding The log decoding. + * @returns The decoded logs. + */ exportLogs(appId: uint64, ...decoding: T): DecodedLogs { const transaction = this.lastGroup.transactions .filter((t) => t.type === TransactionType.ApplicationCall) @@ -149,13 +220,16 @@ export class TransactionContext { if (transaction) { logs = transaction.appLogs } else { - logs = lazyContext.getApplicationData(appId).appLogs + logs = lazyContext.getApplicationData(appId).application.appLogs } return decodeLogs(logs, decoding) } } +/** + * Represents a group of transactions. + */ export class TransactionGroup { activeTransactionIndex: number latestTimestamp: number @@ -166,79 +240,118 @@ export class TransactionGroup { constructor(transactions: Transaction[], activeTransactionIndex?: number) { this.latestTimestamp = Date.now() if (transactions.length > TRANSACTION_GROUP_MAX_SIZE) { - internal.errors.internalError(`Transaction group can have at most ${TRANSACTION_GROUP_MAX_SIZE} transactions, as per AVM limits.`) + throw new InternalError(`Transaction group can have at most ${TRANSACTION_GROUP_MAX_SIZE} transactions, as per AVM limits.`) } transactions.forEach((txn, index) => Object.assign(txn, { groupIndex: asUint64(index) })) this.activeTransactionIndex = activeTransactionIndex === undefined ? transactions.length - 1 : activeTransactionIndex this.transactions = transactions } + /** + * Gets the active transaction. + * @returns The active transaction. + */ get activeTransaction() { return this.transactions[this.activeTransactionIndex] } + /** + * Gets the active application ID. + * @returns The active application ID. + * @throws If there are no transactions in the group or the active transaction is not an application call. + */ get activeApplicationId() { + // this should return the true app_id and not 0 if the app is in the creation phase if (this.transactions.length === 0) { - internal.errors.internalError('No transactions in the group') + throw new InternalError('No transactions in the group') } testInvariant(this.activeTransaction.type === TransactionType.ApplicationCall, 'No app_id found in the active transaction') - return this.activeTransaction.appId.id + return (this.activeTransaction as ApplicationTransaction).backingAppId.id } - /* internal */ + /* @internal */ get constructingItxn() { if (!this.constructingItxnGroup.length) { - internal.errors.internalError('itxn field without itxn begin') + throw new InternalError('itxn field without itxn begin') } return this.constructingItxnGroup.at(-1)! } + /** + * Gets the scratch space of the active transaction. + * @returns The scratch space. + */ getScratchSpace() { return this.activeTransaction.scratchSpace } - getScratchSlot(index: internal.primitives.StubUint64Compat): bytes | uint64 { + /** + * Gets the scratch slot of the active transaction. + * @param index The index of the scratch slot. + * @returns The scratch slot value. + */ + getScratchSlot(index: StubUint64Compat): bytes | uint64 { return this.activeTransaction.getScratchSlot(index) } + /** + * Patches the fields of the active transaction. + * @param fields The fields to patch. + */ patchActiveTransactionFields(fields: AllTransactionFields) { const activeTransaction = this.activeTransaction as unknown as AllTransactionFields const filteredFields = Object.fromEntries(Object.entries(fields).filter(([_, value]) => value !== undefined)) Object.assign(activeTransaction, filteredFields) } - /* internal */ + /** + * Adds a group of inner transactions. + * @internal + * @param itxns The inner transactions. + */ addInnerTransactionGroup(...itxns: InnerTxn[]) { this.itxnGroups.push(new ItxnGroup(itxns)) } - /* internal */ + /** + * Begins a new inner transaction group. + * @internal + * @throws If there is already an inner transaction group being constructed or the active transaction is not an application call. + */ beginInnerTransactionGroup() { if (this.constructingItxnGroup.length) { - internal.errors.internalError('itxn begin without itxn submit') + throw new InternalError('itxn begin without itxn submit') } testInvariant(this.activeTransaction.type === TransactionType.ApplicationCall, 'No active application call transaction') if (this.activeTransaction.onCompletion === 'ClearState') { - internal.errors.internalError('Cannot begin inner transaction group in a clear state call') + throw new InternalError('Cannot begin inner transaction group in a clear state call') } this.constructingItxnGroup.push({} as InnerTxnFields) } - /* internal */ + /** + * Appends a new inner transaction to the current group. + * @internal + * @throws If there is no inner transaction group being constructed. + */ appendInnerTransactionGroup() { if (!this.constructingItxnGroup.length) { - internal.errors.internalError('itxn next without itxn begin') + throw new InternalError('itxn next without itxn begin') } this.constructingItxnGroup.push({ type: TransactionType.Payment } as InnerTxnFields) } - /* internal */ + /** + * Submits the current inner transaction group. + * @internal + * @throws If there is no inner transaction group being constructed or the group exceeds the maximum size. + */ submitInnerTransactionGroup() { if (!this.constructingItxnGroup.length) { - internal.errors.internalError('itxn submit without itxn begin') + throw new InternalError('itxn submit without itxn begin') } if (this.constructingItxnGroup.length > TRANSACTION_GROUP_MAX_SIZE) { - internal.errors.internalError(`Cannot submit more than ${TRANSACTION_GROUP_MAX_SIZE} inner transactions at once`) + throw new InternalError(`Cannot submit more than ${TRANSACTION_GROUP_MAX_SIZE} inner transactions at once`) } const itxns = this.constructingItxnGroup.map((t) => createInnerTxn(t)) itxns.forEach((itxn, index) => Object.assign(itxn, { groupIndex: asUint64(index) })) @@ -246,53 +359,106 @@ export class TransactionGroup { this.constructingItxnGroup = [] } + /** + * Gets the last inner transaction group. + * @returns The last inner transaction group. + */ lastItxnGroup() { return this.getItxnGroup() } - getItxnGroup(index?: internal.primitives.StubUint64Compat): ItxnGroup { + + /** + * Gets an inner transaction group by index. + * @param index The index of the group. If not provided, the last group is returned. + * @returns The inner transaction group. + * @throws If the index is invalid or there are no previous inner transactions. + */ + getItxnGroup(index?: StubUint64Compat): ItxnGroup { const i = index !== undefined ? asNumber(index) : undefined testInvariant(this.itxnGroups.length > 0, 'no previous inner transactions') if (i !== undefined && i >= this.itxnGroups.length) { - throw new internal.errors.InternalError('Invalid group index') + throw new InternalError('Invalid group index') } const group = i !== undefined ? this.itxnGroups[i] : this.itxnGroups.at(-1)! testInvariant(group.itxns.length > 0, 'no previous inner transactions') return group } - getApplicationTransaction(index?: internal.primitives.StubUint64Compat): ApplicationTransaction { + + /** + * Gets an application transaction by index. + * @param index The index of the transaction. + * @returns The application transaction. + */ + getApplicationTransaction(index?: StubUint64Compat): ApplicationTransaction { return this.getTransactionImpl({ type: TransactionType.ApplicationCall, index }) as ApplicationTransaction } - getAssetConfigTransaction(index?: internal.primitives.StubUint64Compat): AssetConfigTransaction { + + /** + * Gets an asset configuration transaction by index. + * @param index The index of the transaction. + * @returns The asset configuration transaction. + */ + getAssetConfigTransaction(index?: StubUint64Compat): AssetConfigTransaction { return this.getTransactionImpl({ type: TransactionType.AssetConfig, index }) as AssetConfigTransaction } - getAssetTransferTransaction(index?: internal.primitives.StubUint64Compat): AssetTransferTransaction { + + /** + * Gets an asset transfer transaction by index. + * @param index The index of the transaction. + * @returns The asset transfer transaction. + */ + getAssetTransferTransaction(index?: StubUint64Compat): AssetTransferTransaction { return this.getTransactionImpl({ type: TransactionType.AssetTransfer, index }) as AssetTransferTransaction } - getAssetFreezeTransaction(index?: internal.primitives.StubUint64Compat): AssetFreezeTransaction { + + /** + * Gets an asset freeze transaction by index. + * @param index The index of the transaction. + * @returns The asset freeze transaction. + */ + getAssetFreezeTransaction(index?: StubUint64Compat): AssetFreezeTransaction { return this.getTransactionImpl({ type: TransactionType.AssetFreeze, index }) as AssetFreezeTransaction } - getKeyRegistrationTransaction(index?: internal.primitives.StubUint64Compat): KeyRegistrationTransaction { + + /** + * Gets a key registration transaction by index. + * @param index The index of the transaction. + * @returns The key registration transaction. + */ + getKeyRegistrationTransaction(index?: StubUint64Compat): KeyRegistrationTransaction { return this.getTransactionImpl({ type: TransactionType.KeyRegistration, index }) as KeyRegistrationTransaction } - getPaymentTransaction(index?: internal.primitives.StubUint64Compat): PaymentTransaction { + + /** + * Gets a payment transaction by index. + * @param index The index of the transaction. + * @returns The payment transaction. + */ + getPaymentTransaction(index?: StubUint64Compat): PaymentTransaction { return this.getTransactionImpl({ type: TransactionType.Payment, index }) as PaymentTransaction } - getTransaction(index?: internal.primitives.StubUint64Compat): Transaction { + + /** + * Gets a transaction by index. + * @param index The index of the transaction. + * @returns The transaction. + */ + getTransaction(index?: StubUint64Compat): Transaction { return this.getTransactionImpl({ index }) } - private getTransactionImpl({ type, index }: { type?: TransactionType; index?: internal.primitives.StubUint64Compat }) { + private getTransactionImpl({ type, index }: { type?: TransactionType; index?: StubUint64Compat }) { const i = index !== undefined ? asNumber(index) : undefined if (i !== undefined && i >= lazyContext.activeGroup.transactions.length) { - throw new internal.errors.InternalError('Invalid group index') + throw new InternalError('Invalid group index') } const transaction = i !== undefined ? lazyContext.activeGroup.transactions[i] : lazyContext.activeGroup.activeTransaction if (type === undefined) { return transaction } if (transaction.type !== type) { - throw new internal.errors.InternalError(`Invalid transaction type: ${transaction.type}`) + throw new InternalError(`Invalid transaction type: ${transaction.type}`) } switch (type) { case TransactionType.ApplicationCall: @@ -308,51 +474,95 @@ export class TransactionGroup { case TransactionType.KeyRegistration: return transaction as KeyRegistrationTransaction default: - throw new internal.errors.InternalError(`Invalid transaction type: ${type}`) + throw new InternalError(`Invalid transaction type: ${type}`) } } } +/** + * Represents a group of inner transactions. + */ export class ItxnGroup { itxns: InnerTxn[] = [] constructor(itxns: InnerTxn[]) { this.itxns = itxns } - getApplicationInnerTxn(index?: internal.primitives.StubUint64Compat): ApplicationInnerTxn { + /** + * Gets an application inner transaction by index. + * @param index The index of the transaction. + * @returns The application inner transaction. + */ + getApplicationInnerTxn(index?: StubUint64Compat): ApplicationInnerTxn { return this.getInnerTxnImpl({ type: TransactionType.ApplicationCall, index }) as ApplicationInnerTxn } - getAssetConfigInnerTxn(index?: internal.primitives.StubUint64Compat): AssetConfigInnerTxn { + + /** + * Gets an asset configuration inner transaction by index. + * @param index The index of the transaction. + * @returns The asset configuration inner transaction. + */ + getAssetConfigInnerTxn(index?: StubUint64Compat): AssetConfigInnerTxn { return this.getInnerTxnImpl({ type: TransactionType.AssetConfig, index }) as AssetConfigInnerTxn } - getAssetTransferInnerTxn(index?: internal.primitives.StubUint64Compat): AssetTransferInnerTxn { + + /** + * Gets an asset transfer inner transaction by index. + * @param index The index of the transaction. + * @returns The asset transfer inner transaction. + */ + getAssetTransferInnerTxn(index?: StubUint64Compat): AssetTransferInnerTxn { return this.getInnerTxnImpl({ type: TransactionType.AssetTransfer, index }) as AssetTransferInnerTxn } - getAssetFreezeInnerTxn(index?: internal.primitives.StubUint64Compat): AssetFreezeInnerTxn { + + /** + * Gets an asset freeze inner transaction by index. + * @param index The index of the transaction. + * @returns The asset freeze inner transaction. + */ + getAssetFreezeInnerTxn(index?: StubUint64Compat): AssetFreezeInnerTxn { return this.getInnerTxnImpl({ type: TransactionType.AssetFreeze, index }) as AssetFreezeInnerTxn } - getKeyRegistrationInnerTxn(index?: internal.primitives.StubUint64Compat): KeyRegistrationInnerTxn { + + /** + * Gets a key registration inner transaction by index. + * @param index The index of the transaction. + * @returns The key registration inner transaction. + */ + getKeyRegistrationInnerTxn(index?: StubUint64Compat): KeyRegistrationInnerTxn { return this.getInnerTxnImpl({ type: TransactionType.KeyRegistration, index }) as KeyRegistrationInnerTxn } - getPaymentInnerTxn(index?: internal.primitives.StubUint64Compat): PaymentInnerTxn { + + /** + * Gets a payment inner transaction by index. + * @param index The index of the transaction. + * @returns The payment inner transaction. + */ + getPaymentInnerTxn(index?: StubUint64Compat): PaymentInnerTxn { return this.getInnerTxnImpl({ type: TransactionType.Payment, index }) as PaymentInnerTxn } - getInnerTxn(index?: internal.primitives.StubUint64Compat): InnerTxn { + + /** + * Gets an inner transaction by index. + * @param index The index of the transaction. + * @returns The inner transaction. + */ + getInnerTxn(index?: StubUint64Compat): InnerTxn { return this.getInnerTxnImpl({ index }) } - private getInnerTxnImpl({ type, index }: { type?: TransactionType; index?: internal.primitives.StubUint64Compat }) { + private getInnerTxnImpl({ type, index }: { type?: TransactionType; index?: StubUint64Compat }) { testInvariant(this.itxns.length > 0, 'no previous inner transactions') const i = index !== undefined ? asNumber(index) : undefined if (i !== undefined && i >= this.itxns.length) { - throw new internal.errors.InternalError('Invalid group index') + throw new InternalError('Invalid group index') } const transaction = i !== undefined ? this.itxns[i] : this.itxns.at(-1)! if (type === undefined) { return transaction } if (transaction.type !== type) { - throw new internal.errors.InternalError(`Invalid transaction type: ${transaction.type}`) + throw new InternalError(`Invalid transaction type: ${transaction.type}`) } switch (type) { case TransactionType.ApplicationCall: @@ -368,7 +578,7 @@ export class ItxnGroup { case TransactionType.KeyRegistration: return transaction as KeyRegistrationInnerTxn default: - throw new internal.errors.InternalError(`Invalid transaction type: ${type}`) + throw new InternalError(`Invalid transaction type: ${type}`) } } } diff --git a/src/test-execution-context.ts b/src/test-execution-context.ts index 2ab676c..da267cb 100644 --- a/src/test-execution-context.ts +++ b/src/test-execution-context.ts @@ -1,149 +1,139 @@ -import { Account, Application, Asset, BaseContract, bytes, internal, LogicSig, uint64 } from '@algorandfoundation/algorand-typescript' -import { captureMethodConfig } from './abi-metadata' +import type { Account as AccountType, BaseContract, bytes, LogicSig, uint64 } from '@algorandfoundation/algorand-typescript' import { DEFAULT_TEMPLATE_VAR_PREFIX } from './constants' -import { DecodedLogs, LogDecoding } from './decode-logs' -import * as ops from './impl' -import { AccountCls } from './impl/account' -import { ApplicationCls } from './impl/application' -import { AssetCls } from './impl/asset' -import { - applicationCall as itxnApplicationCall, - assetConfig as itxnAssetConfig, - assetFreeze as itxnAssetFreeze, - assetTransfer as itxnAssetTransfer, - keyRegistration as itxnKeyRegistration, - payment as itxnPayment, - submitGroup as itxnSubmitGroup, -} from './impl/inner-transactions' -import { Box, BoxMap, BoxRef, GlobalState, LocalState } from './impl/state' +import { ContextManager } from './context-helpers/context-manager' +import type { DecodedLogs, LogDecoding } from './decode-logs' +import { Account, AccountCls } from './impl/reference' import { ContractContext } from './subcontexts/contract-context' import { LedgerContext } from './subcontexts/ledger-context' import { TransactionContext } from './subcontexts/transaction-context' -import { ConstructorFor, DeliberateAny } from './typescript-helpers' +import type { ConstructorFor, DeliberateAny } from './typescript-helpers' import { getRandomBytes } from './util' import { ValueGenerator } from './value-generators' -export class TestExecutionContext implements internal.ExecutionContext { +/** + * The `TestExecutionContext` class provides a context for executing tests in an Algorand environment. + * It manages various contexts such as contract, ledger, and transaction contexts, and provides utilities + * for generating values, managing accounts, and handling logic signatures. + * + * @class + */ +export class TestExecutionContext { #contractContext: ContractContext #ledgerContext: LedgerContext #txnContext: TransactionContext #valueGenerator: ValueGenerator - #defaultSender: Account + #defaultSender: AccountType #activeLogicSigArgs: bytes[] #template_vars: Record = {} #compiledApps: Array<[ConstructorFor, uint64]> = [] - #compiledLogicSigs: Array<[ConstructorFor, Account]> = [] + #compiledLogicSigs: Array<[ConstructorFor, AccountType]> = [] + /** + * Creates an instance of `TestExecutionContext`. + * + * @param {bytes} [defaultSenderAddress] - The default sender address. + */ constructor(defaultSenderAddress?: bytes) { - internal.ctxMgr.instance = this + ContextManager.instance = this this.#contractContext = new ContractContext() this.#ledgerContext = new LedgerContext() this.#txnContext = new TransactionContext() this.#valueGenerator = new ValueGenerator() - this.#defaultSender = Account(defaultSenderAddress ?? getRandomBytes(32).asAlgoTs()) + this.#defaultSender = this.any.account({ address: defaultSenderAddress ?? getRandomBytes(32).asAlgoTs() }) this.#activeLogicSigArgs = [] } - /* @internal */ - account(address?: bytes): Account { - return new AccountCls(address) - } - - /* @internal */ - application(id?: uint64): Application { - return new ApplicationCls(id) - } - - /* @internal */ - asset(id?: uint64): Asset { - return new AssetCls(id) - } - - /* @internal */ - log(value: bytes): void { - this.txn.appendLog(value) - } - + /** + * Exports logs for a given application ID and decoding. + * + * @template T + * @param {uint64} appId - The application ID. + * @param {...T} decoding - The log decoding. + * @returns {DecodedLogs} + */ exportLogs(appId: uint64, ...decoding: T): DecodedLogs { return this.txn.exportLogs(appId, ...decoding) } - /* @internal */ - get op() { - return ops - } + /** + * Returns the contract context. + * + * @type {ContractContext} + */ get contract() { return this.#contractContext } + /** + * Returns the ledger context. + * + * @type {LedgerContext} + */ get ledger() { return this.#ledgerContext } + /** + * Returns the transaction context. + * + * @type {TransactionContext} + */ get txn() { return this.#txnContext } + /** + * Returns the value generator. + * + * @type {ValueGenerator} + */ get any() { return this.#valueGenerator } - get defaultSender(): Account { + /** + * Returns the default sender account. + * + * @type {Account} + */ + get defaultSender(): AccountType { return this.#defaultSender } - /* @internal */ - get abiMetadata() { - return { - captureMethodConfig, - } - } - - /* @internal */ - get gtxn() { - return { - Transaction: (index: uint64) => this.txn.activeGroup.getTransaction(index), - PaymentTxn: (index: uint64) => this.txn.activeGroup.getPaymentTransaction(index), - KeyRegistrationTxn: (index: uint64) => this.txn.activeGroup.getKeyRegistrationTransaction(index), - AssetConfigTxn: (index: uint64) => this.txn.activeGroup.getAssetConfigTransaction(index), - AssetTransferTxn: (index: uint64) => this.txn.activeGroup.getAssetTransferTransaction(index), - AssetFreezeTxn: (index: uint64) => this.txn.activeGroup.getAssetFreezeTransaction(index), - ApplicationTxn: (index: uint64) => this.txn.activeGroup.getApplicationTransaction(index), - } - } - - /* @internal */ - get itxn() { - return { - submitGroup: itxnSubmitGroup, - payment: itxnPayment, - keyRegistration: itxnKeyRegistration, - assetConfig: itxnAssetConfig, - assetTransfer: itxnAssetTransfer, - assetFreeze: itxnAssetFreeze, - applicationCall: itxnApplicationCall, - } - } - - /* @internal */ - get state() { - return { - GlobalState, - LocalState, - Box, - BoxMap, - BoxRef, - } + /** + * Sets the default sender account. + * + * @param {bytes | AccountType} val - The default sender account. + */ + set defaultSender(val: bytes | AccountType) { + this.#defaultSender = val instanceof AccountCls ? val : Account(val as bytes) } + /** + * Returns the active logic signature arguments. + * + * @type {bytes[]} + */ get activeLogicSigArgs(): bytes[] { return this.#activeLogicSigArgs } + /** + * Returns the template variables. + * + * @type {Record} + */ get templateVars(): Record { return this.#template_vars } + /** + * Executes a logic signature with the given arguments. + * + * @param {LogicSig} logicSig - The logic signature to execute. + * @param {...bytes[]} args - The arguments for the logic signature. + * @returns {boolean | uint64} + */ executeLogicSig(logicSig: LogicSig, ...args: bytes[]): boolean | uint64 { this.#activeLogicSigArgs = args try { @@ -153,14 +143,33 @@ export class TestExecutionContext implements internal.ExecutionContext { } } + /** + * Sets a template variable. + * + * @param {string} name - The name of the template variable. + * @param {DeliberateAny} value - The value of the template variable. + * @param {string} [prefix] - The prefix for the template variable. + */ setTemplateVar(name: string, value: DeliberateAny, prefix?: string) { this.#template_vars[(prefix ?? DEFAULT_TEMPLATE_VAR_PREFIX) + name] = value } + /** + * Gets a compiled application by contract. + * + * @param {ConstructorFor} contract - The contract class. + * @returns {[ConstructorFor, uint64] | undefined} + */ getCompiledApp(contract: ConstructorFor) { return this.#compiledApps.find(([c, _]) => c === contract) } + /** + * Sets a compiled application. + * + * @param {ConstructorFor} c - The contract class. + * @param {uint64} appId - The application ID. + */ setCompiledApp(c: ConstructorFor, appId: uint64) { const existing = this.getCompiledApp(c) if (existing) { @@ -170,11 +179,23 @@ export class TestExecutionContext implements internal.ExecutionContext { } } + /** + * Gets a compiled logic signature. + * + * @param {ConstructorFor} logicsig - The logic signature class. + * @returns {[ConstructorFor, Account] | undefined} + */ getCompiledLogicSig(logicsig: ConstructorFor) { return this.#compiledLogicSigs.find(([c, _]) => c === logicsig) } - setCompiledLogicSig(c: ConstructorFor, account: Account) { + /** + * Sets a compiled logic signature. + * + * @param {ConstructorFor} c - The logic signature class. + * @param {Account} account - The account associated with the logic signature. + */ + setCompiledLogicSig(c: ConstructorFor, account: AccountType) { const existing = this.getCompiledLogicSig(c) if (existing) { existing[1] = account @@ -183,6 +204,10 @@ export class TestExecutionContext implements internal.ExecutionContext { } } + /** + * Reinitializes the execution context, clearing all state variables and resetting internal components. + * Invoked between test cases to ensure isolation. + */ reset() { this.#contractContext = new ContractContext() this.#ledgerContext = new LedgerContext() @@ -190,7 +215,7 @@ export class TestExecutionContext implements internal.ExecutionContext { this.#activeLogicSigArgs = [] this.#template_vars = {} this.#compiledApps = [] - internal.ctxMgr.reset() - internal.ctxMgr.instance = this + ContextManager.reset() + ContextManager.instance = this } } diff --git a/src/test-transformer/index.ts b/src/test-transformer/index.ts deleted file mode 100644 index 6b79f8e..0000000 --- a/src/test-transformer/index.ts +++ /dev/null @@ -1,40 +0,0 @@ -import { registerPTypes, typeRegistry } from '@algorandfoundation/puya-ts' -import type ts from 'typescript' -import type { DeliberateAny } from '../typescript-helpers' -import { SourceFileVisitor } from './visitors' - -export interface TransformerConfig { - includeExt: string[] - testingPackageName: string -} -const defaultTransformerConfig: TransformerConfig = { - includeExt: ['.algo.ts', '.spec.ts'], - testingPackageName: '@algorandfoundation/algorand-typescript-testing', -} - -const createProgramFactory = (config: TransformerConfig) => { - function programFactory(program: ts.Program): ts.TransformerFactory { - registerPTypes(typeRegistry) - return (context) => { - return (sourceFile) => { - if (!config.includeExt.some((i) => sourceFile.fileName.endsWith(i))) return sourceFile - return new SourceFileVisitor(context, sourceFile, program, config).result() - } - } - } - return programFactory -} - -function programTransformer(config: Partial) { - return { - type: 'program', - factory: createProgramFactory({ ...defaultTransformerConfig, ...config }), - } -} -programTransformer.type = 'program' -programTransformer.factory = createProgramFactory(defaultTransformerConfig) - -// Typescript.d.ts typings require a TransformerFactory however rollup plugin supports a program transformer -// https://github.com/rollup/plugins/blob/master/packages/typescript/src/customTransformers.ts -export const puyaTsTransformer: ts.TransformerFactory & - ((config: Partial) => ts.TransformerFactory) = programTransformer as DeliberateAny diff --git a/src/test-transformer/jest-transformer.ts b/src/test-transformer/jest-transformer.ts new file mode 100644 index 0000000..1c6dad0 --- /dev/null +++ b/src/test-transformer/jest-transformer.ts @@ -0,0 +1,49 @@ +import type ts from 'typescript' +import type { TransformerConfig } from './program-factory' +import { defaultTransformerConfig, programFactory } from './program-factory' + +const createProgramFactory = (config: TransformerConfig) => { + // ts-jest passes a TsCompilerInstance as program parameter + // https://github.com/kulshekhar/ts-jest/tree/main/src/transformers#transformer + return (compilerInstance: { program: ts.Program }): ts.TransformerFactory => { + return programFactory(config, compilerInstance.program) + } +} + +// exporting values needed by ts-jest for a transformer to work +// https://github.com/kulshekhar/ts-jest/tree/main/src/transformers#transformer +export const name = 'puyaTsTransformer' +export const version = '0.1.0' + +/** + * Factory function that creates TypeScript program transformers for Jest. + * Used by ts-jest to transform TypeScript files during test execution. + * Initialized with default transformer configuration. + * + * @type {(tsJestConfig?: TsJestTransformerOptions) => TsJestTransformer;} + * + * @example + * ```ts + * // Use as before stage transformer with custom config in jest.config.ts + * import { createDefaultEsmPreset, type JestConfigWithTsJest } from 'ts-jest' + * + * const presetConfig = createDefaultEsmPreset({}) + * const jestConfig: JestConfigWithTsJest = { + * ...presetConfig, + * transform: { + * '^.+\\.tsx?$': [ + * 'ts-jest', + * { + * useESM: true, + * astTransformers: { + * before: ['node_modules/@algorandfoundation/algorand-typescript-testing/test-transformer/jest-transformer.mjs'], + * }, + * }, + * ], + * }, + * extensionsToTreatAsEsm: ['.ts'], + * } + * export default jestConfig + * ``` + */ +export const factory = createProgramFactory(defaultTransformerConfig) diff --git a/src/test-transformer/node-factory.ts b/src/test-transformer/node-factory.ts index 4014221..708c3fb 100644 --- a/src/test-transformer/node-factory.ts +++ b/src/test-transformer/node-factory.ts @@ -1,6 +1,6 @@ -import { ptypes } from '@algorandfoundation/puya-ts' +import type { ptypes } from '@algorandfoundation/puya-ts' import ts from 'typescript' -import { TypeInfo } from '../encoders' +import type { TypeInfo } from '../encoders' import type { DeliberateAny } from '../typescript-helpers' import { getPropertyNameAsString, trimGenericTypeName } from './helpers' @@ -107,4 +107,16 @@ export const nodeFactory = { [typeInfoArg, ...(node.arguments ?? [])].filter((arg) => !!arg), ) }, + + callMethodSelectorFunction(node: ts.CallExpression) { + if ( + node.arguments.length === 1 && + ts.isPropertyAccessExpression(node.arguments[0]) && + ts.isPropertyAccessExpression(node.arguments[0].expression) + ) { + const contractIdenifier = node.arguments[0].expression.expression + return factory.updateCallExpression(node, node.expression, node.typeArguments, [...node.arguments, contractIdenifier]) + } + return node + }, } satisfies Record ts.Node> diff --git a/src/test-transformer/program-factory.ts b/src/test-transformer/program-factory.ts new file mode 100644 index 0000000..a436039 --- /dev/null +++ b/src/test-transformer/program-factory.ts @@ -0,0 +1,22 @@ +import { registerPTypes, typeRegistry } from '@algorandfoundation/puya-ts' +import type ts from 'typescript' +import { SourceFileVisitor } from './visitors' + +export interface TransformerConfig { + includeExt: string[] + testingPackageName: string +} +export const defaultTransformerConfig: TransformerConfig = { + includeExt: ['.algo.ts', '.spec.ts', '.test.ts'], + testingPackageName: '@algorandfoundation/algorand-typescript-testing', +} + +export function programFactory(config: TransformerConfig, program: ts.Program): ts.TransformerFactory { + registerPTypes(typeRegistry) + return (context) => { + return (sourceFile) => { + if (!config.includeExt.some((i) => sourceFile.fileName.endsWith(i))) return sourceFile + return new SourceFileVisitor(context, sourceFile, program, config).result() + } + } +} diff --git a/src/test-transformer/visitors.ts b/src/test-transformer/visitors.ts index d4571b2..8d69c4b 100644 --- a/src/test-transformer/visitors.ts +++ b/src/test-transformer/visitors.ts @@ -1,10 +1,10 @@ -import { ptypes, SourceLocation, TypeResolver } from '@algorandfoundation/puya-ts' +import { LoggingContext, ptypes, SourceLocation, TypeResolver } from '@algorandfoundation/puya-ts' import path from 'path' import ts from 'typescript' import type { TypeInfo } from '../encoders' import { instanceOfAny } from '../typescript-helpers' -import { TransformerConfig } from './index' import { nodeFactory } from './node-factory' +import type { TransformerConfig } from './program-factory' import { supportedAugmentedAssignmentBinaryOpString, supportedBinaryOpString, @@ -13,8 +13,12 @@ import { const { factory } = ts +const algotsModuleRegExp = new RegExp(/^("|')@algorandfoundation\/algorand-typescript(\/|"|')/) +const algotsModuleSpecifier = '@algorandfoundation/algorand-typescript' +const testingInternalModuleSpecifier = (testingPackageName: string) => `${testingPackageName}/internal` const algotsModulePaths = [ - `@algorandfoundation${path.sep}algorand-typescript`, + algotsModuleSpecifier, + '/puya-ts/packages/algo-ts/', `${path.sep}puya-ts${path.sep}packages${path.sep}algo-ts${path.sep}`, ] @@ -28,6 +32,7 @@ type VisitorHelper = { export class SourceFileVisitor { private helper: VisitorHelper + constructor( private context: ts.TransformationContext, private sourceFile: ts.SourceFile, @@ -35,18 +40,19 @@ export class SourceFileVisitor { private config: TransformerConfig, ) { const typeChecker = program.getTypeChecker() + const loggingContext = LoggingContext.create() const typeResolver = new TypeResolver(typeChecker, program.getCurrentDirectory()) this.helper = { additionalStatements: [], resolveType(node: ts.Node): ptypes.PType { try { - return typeResolver.resolve(node, this.sourceLocation(node)) + return loggingContext.run(() => typeResolver.resolve(node, this.sourceLocation(node))) } catch { return ptypes.anyPType } }, resolveTypeParameters(node: ts.CallExpression) { - return typeResolver.resolveTypeParameters(node, this.sourceLocation(node)) + return loggingContext.run(() => typeResolver.resolveTypeParameters(node, this.sourceLocation(node))) }, tryGetSymbol(node: ts.Node): ts.Symbol | undefined { const s = typeChecker.getSymbolAtLocation(node) @@ -68,6 +74,9 @@ export class SourceFileVisitor { } private visit = (node: ts.Node): ts.Node => { + if (ts.isImportDeclaration(node)) { + return new ImportDeclarationVisitor(this.context, this.helper, this.config, node).result() + } if (ts.isFunctionLike(node)) { return new FunctionLikeDecVisitor(this.context, this.helper, node).result() } @@ -85,6 +94,37 @@ export class SourceFileVisitor { } } +class ImportDeclarationVisitor { + constructor( + private context: ts.TransformationContext, + private helper: VisitorHelper, + private config: TransformerConfig, + private declarationNode: ts.ImportDeclaration, + ) {} + + public result(): ts.ImportDeclaration { + const moduleSpecifier = this.declarationNode.moduleSpecifier.getText() + if (this.declarationNode.importClause?.isTypeOnly || !algotsModuleRegExp.test(moduleSpecifier)) return this.declarationNode + + const namedBindings = this.declarationNode.importClause?.namedBindings + const nonTypeNamedBindings = + namedBindings && ts.isNamedImports(namedBindings) ? (namedBindings as ts.NamedImports).elements.filter((e) => !e.isTypeOnly) : [] + return factory.createImportDeclaration( + this.declarationNode.modifiers, + nonTypeNamedBindings.length + ? factory.createImportClause(false, this.declarationNode.importClause?.name, factory.createNamedImports(nonTypeNamedBindings)) + : this.declarationNode.importClause, + factory.createStringLiteral( + moduleSpecifier + .replace(algotsModuleSpecifier, testingInternalModuleSpecifier(this.config.testingPackageName)) + .replace(/^("|')/, '') + .replace(/("|')$/, ''), + ), + this.declarationNode.attributes, + ) + } +} + class ExpressionVisitor { constructor( private context: ts.TransformationContext, @@ -122,13 +162,19 @@ class ExpressionVisitor { let infoArg = info if (isCallingEmit(stubbedFunctionName)) { infoArg = this.helper.resolveTypeParameters(updatedNode).map(getGenericTypeInfo)[0] - } - if (isCallingDecodeArc4(stubbedFunctionName)) { + } else if (isCallingDecodeArc4(stubbedFunctionName)) { const targetType = ptypes.ptypeToArc4EncodedType(type, this.helper.sourceLocation(node)) const targetTypeInfo = getGenericTypeInfo(targetType) infoArg = targetTypeInfo + } else if (isCallingArc4EncodedLength(stubbedFunctionName)) { + infoArg = this.helper.resolveTypeParameters(updatedNode).map(getGenericTypeInfo)[0] } - updatedNode = stubbedFunctionName ? nodeFactory.callStubbedFunction(stubbedFunctionName, updatedNode, infoArg) : updatedNode + + updatedNode = stubbedFunctionName + ? isCallingMethodSelector(stubbedFunctionName) + ? nodeFactory.callMethodSelectorFunction(updatedNode) + : nodeFactory.callStubbedFunction(stubbedFunctionName, updatedNode, infoArg) + : updatedNode } return needsToCaptureTypeInfo ? nodeFactory.captureGenericTypeInfo(ts.visitEachChild(updatedNode, this.visit, this.context), JSON.stringify(info)) @@ -164,7 +210,6 @@ class FunctionOrMethodVisitor { constructor( protected context: ts.TransformationContext, protected helper: VisitorHelper, - private isFunction?: boolean, ) {} protected visit = (node: ts.Node): ts.Node => { return ts.visitEachChild(this.updateNode(node), this.visit, this.context) @@ -239,7 +284,7 @@ class FunctionLikeDecVisitor extends FunctionOrMethodVisitor { helper: VisitorHelper, private funcNode: ts.SignatureDeclaration, ) { - super(context, helper, true) + super(context, helper) } public result(): ts.SignatureDeclaration { @@ -325,8 +370,8 @@ const isArc4EncodedType = (type: ptypes.PType): boolean => ptypes.UFixedNxMType, ptypes.UintNType, ) || - type === ptypes.ARC4StringType || - type === ptypes.ARC4BooleanType + type === ptypes.arc4StringType || + type === ptypes.arc4BooleanType const getGenericTypeInfo = (type: ptypes.PType): TypeInfo => { let typeName = type?.name ?? type?.toString() ?? 'unknown' @@ -377,20 +422,11 @@ const tryGetStubbedFunctionName = (node: ts.CallExpression, helper: VisitorHelpe if (sourceFileName && !algotsModulePaths.some((s) => sourceFileName.includes(s))) return undefined } const functionName = functionSymbol?.getName() ?? identityExpression.text - const stubbedFunctionNames = [ - 'interpretAsArc4', - 'decodeArc4', - 'encodeArc4', - 'TemplateVar', - 'ensureBudget', - 'emit', - 'compile', - 'urange', - 'match', - 'assertMatch', - ] + const stubbedFunctionNames = ['interpretAsArc4', 'decodeArc4', 'encodeArc4', 'emit', 'methodSelector', 'arc4EncodedLength'] return stubbedFunctionNames.includes(functionName) ? functionName : undefined } const isCallingDecodeArc4 = (functionName: string | undefined): boolean => ['decodeArc4', 'encodeArc4'].includes(functionName ?? '') +const isCallingArc4EncodedLength = (functionName: string | undefined): boolean => 'arc4EncodedLength' === (functionName ?? '') const isCallingEmit = (functionName: string | undefined): boolean => 'emit' === (functionName ?? '') +const isCallingMethodSelector = (functionName: string | undefined): boolean => 'methodSelector' === (functionName ?? '') diff --git a/src/test-transformer/vitest-transformer.ts b/src/test-transformer/vitest-transformer.ts new file mode 100644 index 0000000..c088c72 --- /dev/null +++ b/src/test-transformer/vitest-transformer.ts @@ -0,0 +1,55 @@ +import type ts from 'typescript' +import type { DeliberateAny } from '../typescript-helpers' +import type { TransformerConfig } from './program-factory' +import { defaultTransformerConfig, programFactory } from './program-factory' + +const createProgramFactory = (config: TransformerConfig) => { + return (program: ts.Program): ts.TransformerFactory => { + return programFactory(config, program) + } +} + +// Typescript.d.ts typings require a TransformerFactory however rollup plugin supports a program transformer +// https://github.com/rollup/plugins/blob/master/packages/typescript/src/customTransformers.ts +function programTransformer(config: Partial) { + return { + type: 'program', + factory: createProgramFactory({ ...defaultTransformerConfig, ...config }), + } +} +programTransformer.type = 'program' +programTransformer.factory = createProgramFactory(defaultTransformerConfig) + +/** + * TypeScript transformer for Algorand TypeScript smart contracts and testing files + * which is mainly responsilbe for swapping in stub implementations of op codes, + * and capturing TypeScript type information for the Node.js runtime. + * + ** @type {ts.TransformerFactory & ((config: Partial) => ts.TransformerFactory)} + * + * @param {Partial} [config] Configuration options + * @param {string[]} [config.includeExt=['.algo.ts', '.spec.ts']] File extensions to process + * @param {string} [config.testingPackageName='@algorandfoundation/algorand-typescript-testing'] Package name for testing imports + * + * @example + * ```ts + * // Use as before stage transformer with custom config in vitest.config.mts + * import typescript from '@rollup/plugin-typescript' + * import { defineConfig } from 'vitest/config' + * import { puyaTsTransformer } from '@algorandfoundation/algorand-typescript-testing/vitest-transformer' + * + * export default defineConfig({ + * esbuild: {}, + * plugins: [ + * typescript({ + * tsconfig: './tsconfig.json', + * transformers: { + * before: [puyaTsTransformer], + * }, + * }), + * ], + * }) + * ``` + */ +export const puyaTsTransformer: ts.TransformerFactory & + ((config: Partial) => ts.TransformerFactory) = programTransformer as DeliberateAny diff --git a/src/typescript-helpers.ts b/src/typescript-helpers.ts index 82a9fd1..2136047 100644 --- a/src/typescript-helpers.ts +++ b/src/typescript-helpers.ts @@ -30,3 +30,16 @@ export function instanceOfAny { new (...args: DeliberateAny[]): T } + +export type PickPartial = { [P in K]: Partial } + +export const nameOfType = (x: unknown) => { + if (typeof x === 'object') { + if (x === null) return 'Null' + if (x === undefined) return 'undefined' + if ('constructor' in x) { + return x.constructor.name + } + } + return typeof x +} diff --git a/src/util.ts b/src/util.ts index babf8f0..197a877 100644 --- a/src/util.ts +++ b/src/util.ts @@ -1,20 +1,10 @@ -import { Account, Bytes, bytes, internal } from '@algorandfoundation/algorand-typescript' -import { encodingUtil } from '@algorandfoundation/puya-ts' +import type { bytes } from '@algorandfoundation/algorand-typescript' import { randomBytes } from 'crypto' -import { sha512_256 as js_sha512_256 } from 'js-sha512' -import { - ALGORAND_ADDRESS_BYTE_LENGTH, - ALGORAND_ADDRESS_LENGTH, - ALGORAND_CHECKSUM_BYTE_LENGTH, - APP_ID_PREFIX, - BITS_IN_BYTE, - HASH_BYTES_LENGTH, - MAX_BYTES_SIZE, - MAX_UINT512, - MAX_UINT8, - UINT512_SIZE, -} from './constants' -import { DeliberateAny } from './typescript-helpers' +import { BITS_IN_BYTE, MAX_BYTES_SIZE, MAX_UINT512, MAX_UINT8, UINT512_SIZE } from './constants' +import { AssertError, AvmError, InternalError } from './errors' +import type { StubBigUintCompat, StubBytesCompat, StubUint64Compat } from './impl/primitives' +import { BigUintCls, Bytes, BytesCls, Uint64Cls } from './impl/primitives' +import type { DeliberateAny } from './typescript-helpers' export const nameOfType = (x: unknown) => { if (typeof x === 'object') { @@ -33,32 +23,30 @@ export function* iterBigInt(start: bigint, end: bigint): Generator { } } -export const asBigInt = (v: internal.primitives.StubUint64Compat): bigint => asUint64Cls(v).asBigInt() +export const asBigInt = (v: StubUint64Compat): bigint => asUint64Cls(v).asBigInt() -export const asNumber = (v: internal.primitives.StubUint64Compat): number => asUint64Cls(v).asNumber() +export const asNumber = (v: StubUint64Compat): number => asUint64Cls(v).asNumber() -export const asUint64Cls = (val: internal.primitives.StubUint64Compat) => internal.primitives.Uint64Cls.fromCompat(val) +export const asUint64Cls = (val: StubUint64Compat) => Uint64Cls.fromCompat(val) -export const asBigUintCls = (val: internal.primitives.StubBigUintCompat | Uint8Array) => - internal.primitives.BigUintCls.fromCompat( - val instanceof Uint8Array ? asBytes(val) : Array.isArray(val) ? asBytes(new Uint8Array(val)) : val, - ) +export const asBigUintCls = (val: StubBigUintCompat | Uint8Array) => + BigUintCls.fromCompat(val instanceof Uint8Array ? asBytes(val) : Array.isArray(val) ? asBytes(new Uint8Array(val)) : val) -export const asBytesCls = (val: internal.primitives.StubBytesCompat | Uint8Array) => internal.primitives.BytesCls.fromCompat(val) +export const asBytesCls = (val: StubBytesCompat | Uint8Array) => BytesCls.fromCompat(val) -export const asUint64 = (val: internal.primitives.StubUint64Compat) => asUint64Cls(val).asAlgoTs() +export const asUint64 = (val: StubUint64Compat) => asUint64Cls(val).asAlgoTs() -export const asBigUint = (val: internal.primitives.StubBigUintCompat | Uint8Array) => asBigUintCls(val).asAlgoTs() +export const asBigUint = (val: StubBigUintCompat | Uint8Array) => asBigUintCls(val).asAlgoTs() -export const asBytes = (val: internal.primitives.StubBytesCompat | Uint8Array) => asBytesCls(val).asAlgoTs() +export const asBytes = (val: StubBytesCompat | Uint8Array) => asBytesCls(val).asAlgoTs() -export const asUint8Array = (val: internal.primitives.StubBytesCompat | Uint8Array) => asBytesCls(val).asUint8Array() +export const asUint8Array = (val: StubBytesCompat | Uint8Array) => asBytesCls(val).asUint8Array() export const asMaybeUint64Cls = (val: DeliberateAny) => { try { - return internal.primitives.Uint64Cls.fromCompat(val) + return Uint64Cls.fromCompat(val) } catch (e) { - if (e instanceof internal.errors.InternalError) { + if (e instanceof InternalError) { // swallow error and return undefined } else { throw e @@ -69,9 +57,9 @@ export const asMaybeUint64Cls = (val: DeliberateAny) => { export const asMaybeBigUintCls = (val: DeliberateAny) => { try { - return internal.primitives.BigUintCls.fromCompat(val) + return BigUintCls.fromCompat(val) } catch (e) { - if (e instanceof internal.errors.InternalError) { + if (e instanceof InternalError) { // swallow error and return undefined } else { throw e @@ -81,9 +69,9 @@ export const asMaybeBigUintCls = (val: DeliberateAny) => { } export const asMaybeBytesCls = (val: DeliberateAny) => { try { - return internal.primitives.BytesCls.fromCompat(val) + return BytesCls.fromCompat(val) } catch (e) { - if (e instanceof internal.errors.InternalError) { + if (e instanceof InternalError) { // swallow error and return undefined } else { throw e @@ -92,8 +80,8 @@ export const asMaybeBytesCls = (val: DeliberateAny) => { return undefined } -export const binaryStringToBytes = (s: string): internal.primitives.BytesCls => - internal.primitives.BytesCls.fromCompat(new Uint8Array(s.match(/.{1,8}/g)!.map((x) => parseInt(x, 2)))) +export const binaryStringToBytes = (s: string): BytesCls => + BytesCls.fromCompat(new Uint8Array(s.match(/.{1,8}/g)!.map((x) => parseInt(x, 2)))) export const getRandomNumber = (min: number, max: number): number => { return Math.floor(Math.random() * (max - min + 1)) + min @@ -108,7 +96,7 @@ export const getRandomBigInt = (min: number | bigint, max: number | bigint): big return (randomValue % (bigIntMax - bigIntMin)) + bigIntMin } -export const getRandomBytes = (length: number): internal.primitives.BytesCls => asBytesCls(Bytes(randomBytes(length))) +export const getRandomBytes = (length: number): BytesCls => asBytesCls(Bytes(randomBytes(length))) const NoValue = Symbol('no-value') type LazyInstance = () => T @@ -171,24 +159,42 @@ export const uint8ArrayToNumber = (value: Uint8Array): number => { return value.reduce((acc, x) => acc * 256 + x, 0) } -export const checksumFromPublicKey = (pk: Uint8Array): Uint8Array => { - return Uint8Array.from(js_sha512_256.array(pk).slice(HASH_BYTES_LENGTH - ALGORAND_CHECKSUM_BYTE_LENGTH, HASH_BYTES_LENGTH)) -} - -export const getApplicationAddress = (appId: internal.primitives.StubUint64Compat): Account => { - const toBeSigned = conactUint8Arrays(asUint8Array(APP_ID_PREFIX), encodingUtil.bigIntToUint8Array(asBigInt(appId), 8)) - const appIdHash = js_sha512_256.array(toBeSigned) - const publicKey = Uint8Array.from(appIdHash) - const address = encodeAddress(publicKey) - return Account(Bytes.fromBase32(address)) -} - -export const encodeAddress = (address: Uint8Array): string => { - const checksum = checksumFromPublicKey(address) - return encodingUtil.uint8ArrayToBase32(conactUint8Arrays(address, checksum)).slice(0, ALGORAND_ADDRESS_LENGTH) +/** + * Runtime assertion function that throws if condition is falsy. + * + * @param {unknown} condition - The condition to assert + * @param {string} [message] - Optional error message if assertion fails + * @throws {AssertError} Throws if condition is falsy + * + * @example + * ```ts + * const value: string | undefined = "test"; + * assert(value !== undefined); + * + * assert(false, "This will throw"); // throws AssertError: This will throw + * ``` + */ +export function assert(condition: unknown, message?: string): asserts condition { + if (!condition) { + throw new AssertError(message ?? 'Assertion failed') + } } -export const decodePublicKey = (address: string): Uint8Array => { - const decoded = encodingUtil.base32ToUint8Array(address) - return decoded.slice(0, ALGORAND_ADDRESS_BYTE_LENGTH - ALGORAND_CHECKSUM_BYTE_LENGTH) +/** + * Simulates Algorand Virtual Machine's 'err' opcode by throwing an error. + * Used to halt program execution with an optional error message. + * + * @param {string} [message] - Optional error message. Defaults to "err opcode executed" + * @throws {AvmError} Always throws an AvmError + * @returns {never} Function never returns normally + * + * @example + * ```ts + * if (amount < 0) { + * err("Invalid amount"); // Throws AvmError: Invalid amount + * } + * ``` + */ +export function err(message?: string): never { + throw new AvmError(message ?? 'err opcode executed') } diff --git a/src/value-generators/arc4.ts b/src/value-generators/arc4.ts index 9b16093..13b2385 100644 --- a/src/value-generators/arc4.ts +++ b/src/value-generators/arc4.ts @@ -1,7 +1,7 @@ -import { arc4 } from '@algorandfoundation/algorand-typescript' +import type { arc4 } from '@algorandfoundation/algorand-typescript' import { BITS_IN_BYTE, MAX_UINT128, MAX_UINT16, MAX_UINT256, MAX_UINT32, MAX_UINT512, MAX_UINT64, MAX_UINT8 } from '../constants' import { AddressImpl, DynamicBytesImpl, StrImpl, UintNImpl } from '../impl/encoded-types' -import { getRandomBigInt, getRandomBytes, getRandomNumber } from '../util' +import { getRandomBigInt, getRandomBytes } from '../util' import { AvmValueGenerator } from './avm' export class Arc4ValueGenerator { @@ -21,71 +21,71 @@ export class Arc4ValueGenerator { /** * Generate a random UintN8 within the specified range. * @param minValue: Minimum value (inclusive). Defaults to 0. - * @param maxValue: Maximum value (inclusive). Defaults to MAX_UINT8. + * @param maxValue: Maximum value (inclusive). Defaults to 2 ** 8 - 1. * @returns: A random UintN8 value. * */ - uintN8(minValue = 0, maxValue = MAX_UINT8): arc4.UintN8 { - return new UintNImpl({ name: 'UintN', genericArgs: [{ name: '8' }] }, getRandomNumber(minValue, maxValue)) + uintN8(minValue: number | bigint = 0, maxValue: number | bigint = MAX_UINT8): arc4.UintN8 { + return new UintNImpl({ name: 'UintN', genericArgs: [{ name: '8' }] }, getRandomBigInt(minValue, maxValue)) as arc4.UintN8 } /** * Generate a random UintN16 within the specified range. * @param minValue: Minimum value (inclusive). Defaults to 0. - * @param maxValue: Maximum value (inclusive). Defaults to MAX_UINT16. + * @param maxValue: Maximum value (inclusive). Defaults to 2 ** 16 - 1. * @returns: A random UintN16 value. * */ - uintN16(minValue = 0, maxValue = MAX_UINT16): arc4.UintN16 { - return new UintNImpl({ name: 'UintN', genericArgs: [{ name: '16' }] }, getRandomNumber(minValue, maxValue)) + uintN16(minValue: number | bigint = 0, maxValue: number | bigint = MAX_UINT16): arc4.UintN16 { + return new UintNImpl({ name: 'UintN', genericArgs: [{ name: '16' }] }, getRandomBigInt(minValue, maxValue)) as arc4.UintN16 } /** * Generate a random UintN32 within the specified range. * @param minValue: Minimum value (inclusive). Defaults to 0. - * @param maxValue: Maximum value (inclusive). Defaults to MAX_UINT32. + * @param maxValue: Maximum value (inclusive). Defaults to 2 ** 32 - 1. * @returns: A random UintN32 value. * */ - uintN32(minValue = 0, maxValue = MAX_UINT32): arc4.UintN32 { - return new UintNImpl({ name: 'UintN', genericArgs: [{ name: '32' }] }, getRandomNumber(minValue, maxValue)) + uintN32(minValue: number | bigint = 0, maxValue: number | bigint = MAX_UINT32): arc4.UintN32 { + return new UintNImpl({ name: 'UintN', genericArgs: [{ name: '32' }] }, getRandomBigInt(minValue, maxValue)) as arc4.UintN32 } /** * Generate a random UintN64 within the specified range. * @param minValue: Minimum value (inclusive). Defaults to 0. - * @param maxValue: Maximum value (inclusive). Defaults to MAX_UINT64. + * @param maxValue: Maximum value (inclusive). Defaults to 2n ** 64n - 1n. * @returns: A random UintN64 value. * */ - uintN64(minValue = 0, maxValue = MAX_UINT64): arc4.UintN64 { - return new UintNImpl({ name: 'UintN', genericArgs: [{ name: '64' }] }, getRandomBigInt(minValue, maxValue)) + uintN64(minValue: number | bigint = 0, maxValue: number | bigint = MAX_UINT64): arc4.UintN64 { + return new UintNImpl({ name: 'UintN', genericArgs: [{ name: '64' }] }, getRandomBigInt(minValue, maxValue)) as arc4.UintN64 } /** * Generate a random UintN128 within the specified range. * @param minValue: Minimum value (inclusive). Defaults to 0. - * @param maxValue: Maximum value (inclusive). Defaults to MAX_UINT128. + * @param maxValue: Maximum value (inclusive). Defaults to 2n ** 128n - 1n. * @returns: A random UintN128 value. * */ - uintN128(minValue = 0, maxValue = MAX_UINT128): arc4.UintN128 { - return new UintNImpl({ name: 'UintN', genericArgs: [{ name: '128' }] }, getRandomBigInt(minValue, maxValue)) + uintN128(minValue: number | bigint = 0, maxValue: number | bigint = MAX_UINT128): arc4.UintN128 { + return new UintNImpl({ name: 'UintN', genericArgs: [{ name: '128' }] }, getRandomBigInt(minValue, maxValue)) as arc4.UintN128 } /** * Generate a random UintN256 within the specified range. * @param minValue: Minimum value (inclusive). Defaults to 0. - * @param maxValue: Maximum value (inclusive). Defaults to MAX_UINT256. + * @param maxValue: Maximum value (inclusive). Defaults to 2n ** 256n - 1n. * @returns: A random UintN256 value. * */ - uintN256(minValue = 0, maxValue = MAX_UINT256): arc4.UintN256 { - return new UintNImpl({ name: 'UintN', genericArgs: [{ name: '256' }] }, getRandomBigInt(minValue, maxValue)) + uintN256(minValue: number | bigint = 0, maxValue: number | bigint = MAX_UINT256): arc4.UintN256 { + return new UintNImpl({ name: 'UintN', genericArgs: [{ name: '256' }] }, getRandomBigInt(minValue, maxValue)) as arc4.UintN256 } /** * Generate a random UintN512 within the specified range. * @param minValue: Minimum value (inclusive). Defaults to 0. - * @param maxValue: Maximum value (inclusive). Defaults to MAX_UINT512. + * @param maxValue: Maximum value (inclusive). Defaults to 2n ** 512n - 1n. * @returns: A random UintN512 value. * */ - uintN512(minValue = 0, maxValue = MAX_UINT512): arc4.UintN<512> { - return new UintNImpl({ name: 'UintN', genericArgs: [{ name: '512' }] }, getRandomBigInt(minValue, maxValue)) + uintN512(minValue: number | bigint = 0, maxValue: number | bigint = MAX_UINT512): arc4.UintN<512> { + return new UintNImpl({ name: 'UintN', genericArgs: [{ name: '512' }] }, getRandomBigInt(minValue, maxValue)) as arc4.UintN<512> } /** @@ -112,6 +112,6 @@ export class Arc4ValueGenerator { // Generate random string const bytes = getRandomBytes(numChars) - return new StrImpl(JSON.stringify(undefined), bytes.toString()) + return new StrImpl(JSON.stringify(undefined), bytes.toString()) as unknown as arc4.Str } } diff --git a/src/value-generators/avm.ts b/src/value-generators/avm.ts index a3cca0f..526561c 100644 --- a/src/value-generators/avm.ts +++ b/src/value-generators/avm.ts @@ -1,42 +1,83 @@ -import { Account, Application, Asset, bytes, Bytes, internal, Uint64, uint64 } from '@algorandfoundation/algorand-typescript' +import type { + Account as AccountType, + Application as ApplicationType, + Asset as AssetType, + biguint, + bytes, + uint64, +} from '@algorandfoundation/algorand-typescript' import { randomBytes } from 'crypto' -import { MAX_BYTES_SIZE, MAX_UINT64, ZERO_ADDRESS } from '../constants' +import { MAX_BYTES_SIZE, MAX_UINT512, MAX_UINT64 } from '../constants' import { lazyContext } from '../context-helpers/internal-context' -import { AccountData } from '../impl/account' -import { ApplicationCls, ApplicationData } from '../impl/application' -import { AssetCls, AssetData } from '../impl/asset' -import { asBigInt, asUint64Cls, getRandomBigInt, getRandomBytes } from '../util' +import { InternalError } from '../errors' +import { BigUint, Bytes, Uint64, type StubBigUintCompat, type StubUint64Compat } from '../impl/primitives' +import type { AssetData } from '../impl/reference' +import { Account, AccountData, ApplicationCls, ApplicationData, AssetCls, getDefaultAssetData } from '../impl/reference' +import { asBigInt, asBigUintCls, asUint64Cls, getRandomBigInt, getRandomBytes } from '../util' type AccountContextData = Partial & { - address?: Account - optedAssetBalances?: Map - optedApplications?: Application[] + address?: bytes + incentiveEligible?: boolean + lastProposed?: uint64 + lastHeartbeat?: uint64 + optedAssetBalances?: Map + optedApplications?: ApplicationType[] } -type AssetContextData = Partial & { assetId?: internal.primitives.StubUint64Compat } +type AssetContextData = Partial & { assetId?: StubUint64Compat } -type ApplicationContextData = Partial & { applicationId?: internal.primitives.StubUint64Compat } +type ApplicationContextData = Partial & { applicationId?: StubUint64Compat } export class AvmValueGenerator { - uint64(minValue: internal.primitives.StubUint64Compat = 0n, maxValue: internal.primitives.StubUint64Compat = MAX_UINT64): uint64 { + /** + * Generates a random uint64 value within the specified range. + * @param {StubUint64Compat} [minValue=0n] - The minimum value (inclusive). + * @param {StubUint64Compat} [maxValue=MAX_UINT64] - The maximum value (inclusive). + * @returns {uint64} - A random uint64 value. + */ + uint64(minValue: StubUint64Compat = 0n, maxValue: StubUint64Compat = MAX_UINT64): uint64 { const min = asBigInt(minValue) const max = asBigInt(maxValue) if (max > MAX_UINT64) { - internal.errors.internalError('maxValue must be less than or equal to MAX_UINT64') + throw new InternalError('maxValue must be less than or equal to 2n ** 64n - 1n') } if (min > max) { - internal.errors.internalError('minValue must be less than or equal to maxValue') + throw new InternalError('minValue must be less than or equal to maxValue') } if (min < 0n || max < 0n) { - internal.errors.internalError('minValue and maxValue must be greater than or equal to 0') + throw new InternalError('minValue and maxValue must be greater than or equal to 0') } return Uint64(getRandomBigInt(min, max)) } + /** + * Generates a random biguint value within the specified range. + * @param {StubBigUintCompat} [minValue=0n] - The minimum value (inclusive). + * @returns {biguint} - A random biguint value. + */ + biguint(minValue: StubBigUintCompat = 0n): biguint { + const min = asBigUintCls(minValue).asBigInt() + if (min < 0n) { + throw new InternalError('minValue must be greater than or equal to 0') + } + + return BigUint(getRandomBigInt(min, MAX_UINT512)) + } + + /** + * Generates a random bytes of the specified length. + * @param {number} [length=MAX_BYTES_SIZE] - The length of the bytes. + * @returns {bytes} - A random bytes. + */ bytes(length = MAX_BYTES_SIZE): bytes { return Bytes(new Uint8Array(randomBytes(length))) } + /** + * Generates a random string of the specified length. + * @param {number} [length=11] - The length of the string. + * @returns {string} - A random string. + */ string(length = 11): string { const setLength = 11 return Array(Math.ceil(length / setLength)) @@ -46,17 +87,25 @@ export class AvmValueGenerator { .substring(0, length) } - account(input?: AccountContextData): Account { - const account = input?.address ?? Account(getRandomBytes(32).asAlgoTs()) + /** + * Generates a random account with the specified context data. + * @param {AccountContextData} [input] - The context data for the account. + * @returns {Account} - A random account. + */ + account(input?: AccountContextData): AccountType { + const account = input?.address ? Account(input.address) : Account(getRandomBytes(32).asAlgoTs()) if (input?.address && lazyContext.ledger.accountDataMap.has(account)) { - internal.errors.internalError( + throw new InternalError( 'Account with such address already exists in testing context. Use `context.ledger.getAccount(address)` to retrieve the existing account.', ) } const data = new AccountData() - const { address, optedAssetBalances, optedApplications, ...accountData } = input ?? {} + const { address, optedAssetBalances, optedApplications, incentiveEligible, lastProposed, lastHeartbeat, ...accountData } = input ?? {} + data.incentiveEligible = incentiveEligible ?? false + data.lastProposed = lastProposed + data.lastHeartbeat = lastHeartbeat data.account = { ...data.account, ...accountData, @@ -76,26 +125,18 @@ export class AvmValueGenerator { return account } - asset(input?: AssetContextData): Asset { + /** + * Generates a random asset with the specified context data. + * @param {AssetContextData} [input] - The context data for the asset. + * @returns {Asset} - A random asset. + */ + asset(input?: AssetContextData): AssetType { const id = input?.assetId if (id && lazyContext.ledger.assetDataMap.has(id)) { - internal.errors.internalError('Asset with such ID already exists in testing context!') + throw new InternalError('Asset with such ID already exists in testing context!') } const assetId = asUint64Cls(id ?? lazyContext.ledger.assetIdIter.next().value) - const defaultAssetData = { - total: lazyContext.any.uint64(), - decimals: lazyContext.any.uint64(1, 6), - defaultFrozen: false, - unitName: lazyContext.any.bytes(4), - name: lazyContext.any.bytes(32), - url: lazyContext.any.bytes(10), - metadataHash: lazyContext.any.bytes(32), - manager: Account(ZERO_ADDRESS), - freeze: Account(ZERO_ADDRESS), - clawback: Account(ZERO_ADDRESS), - creator: lazyContext.defaultSender, - reserve: Account(ZERO_ADDRESS), - } + const defaultAssetData = getDefaultAssetData() const { assetId: _, ...assetData } = input ?? {} lazyContext.ledger.assetDataMap.set(assetId, { ...defaultAssetData, @@ -104,10 +145,15 @@ export class AvmValueGenerator { return new AssetCls(assetId.asAlgoTs()) } - application(input?: ApplicationContextData): Application { + /** + * Generates a random application with the specified context data. + * @param {ApplicationContextData} [input] - The context data for the application. + * @returns {Application} - A random application. + */ + application(input?: ApplicationContextData): ApplicationType { const id = input?.applicationId if (id && lazyContext.ledger.applicationDataMap.has(id)) { - internal.errors.internalError('Application with such ID already exists in testing context!') + throw new InternalError('Application with such ID already exists in testing context!') } const applicationId = asUint64Cls(id ?? lazyContext.ledger.appIdIter.next().value) const data = new ApplicationData() diff --git a/src/value-generators/txn.ts b/src/value-generators/txn.ts index b8e3a3f..d8246ec 100644 --- a/src/value-generators/txn.ts +++ b/src/value-generators/txn.ts @@ -1,45 +1,85 @@ -import { gtxn, internal } from '@algorandfoundation/algorand-typescript' +import type { Application as ApplicationType, gtxn } from '@algorandfoundation/algorand-typescript' import { lazyContext } from '../context-helpers/internal-context' +import { InternalError } from '../errors' +import { BaseContract } from '../impl/base-contract' +import { ApplicationCls } from '../impl/reference' +import type { ApplicationTransactionFields, TxnFields } from '../impl/transactions' import { ApplicationTransaction, - ApplicationTransactionFields, AssetConfigTransaction, AssetFreezeTransaction, AssetTransferTransaction, KeyRegistrationTransaction, PaymentTransaction, - TxnFields, } from '../impl/transactions' export class TxnValueGenerator { - applicationCall(fields?: ApplicationTransactionFields): ApplicationTransaction { + /** + * Generates a random application call transaction with the specified fields. + * @param {ApplicationTransactionFields} [fields] - The fields for the application call transaction where `appId` value can be instance of Application or BaseContract. + * @returns {ApplicationTransaction} - A random application call transaction. + */ + applicationCall( + fields?: Partial & { appId: ApplicationType | BaseContract }>, + ): ApplicationTransaction { const params = fields ?? {} - if (params.appId && !lazyContext.ledger.applicationDataMap.has(params.appId.id)) { - internal.errors.internalError(`Application ID ${params.appId.id} not found in test context`) + let appId = + params.appId instanceof ApplicationCls + ? params.appId + : params.appId instanceof BaseContract + ? lazyContext.ledger.getApplicationForContract(params.appId) + : undefined + if (appId && !lazyContext.ledger.applicationDataMap.has(appId.id)) { + throw new InternalError(`Application ID ${appId.id} not found in test context`) } - if (!params.appId) { - params.appId = lazyContext.any.application() + if (!appId) { + appId = lazyContext.any.application() } - return ApplicationTransaction.create(params) + return ApplicationTransaction.create({ ...params, appId }) } + /** + * Generates a random payment transaction with the specified fields. + * @param {TxnFields} [fields] - The fields for the payment transaction. + * @returns {PaymentTransaction} - A random payment transaction. + */ payment(fields?: TxnFields): PaymentTransaction { return PaymentTransaction.create(fields ?? {}) } + /** + * Generates a random key registration transaction with the specified fields. + * @param {TxnFields} [fields] - The fields for the key registration transaction. + * @returns {KeyRegistrationTransaction} - A random key registration transaction. + */ keyRegistration(fields?: TxnFields): KeyRegistrationTransaction { return KeyRegistrationTransaction.create(fields ?? {}) } + /** + * Generates a random asset configuration transaction with the specified fields. + * @param {TxnFields} [fields] - The fields for the asset configuration transaction. + * @returns {AssetConfigTransaction} - A random asset configuration transaction. + */ assetConfig(fields?: TxnFields): AssetConfigTransaction { return AssetConfigTransaction.create(fields ?? {}) } + /** + * Generates a random asset transfer transaction with the specified fields. + * @param {TxnFields} [fields] - The fields for the asset transfer transaction. + * @returns {AssetTransferTransaction} - A random asset transfer transaction. + */ assetTransfer(fields?: TxnFields): AssetTransferTransaction { return AssetTransferTransaction.create(fields ?? {}) } + /** + * Generates a random asset freeze transaction with the specified fields. + * @param {TxnFields} [fields] - The fields for the asset freeze transaction. + * @returns {AssetFreezeTransaction} - A random asset freeze transaction. + */ assetFreeze(fields?: TxnFields): AssetFreezeTransaction { return AssetFreezeTransaction.create(fields ?? {}) } diff --git a/tests/arc4/address.spec.ts b/tests/arc4/address.spec.ts index c18c23b..6f632ec 100644 --- a/tests/arc4/address.spec.ts +++ b/tests/arc4/address.spec.ts @@ -4,7 +4,8 @@ import { TestExecutionContext } from '@algorandfoundation/algorand-typescript-te import { Address, interpretAsArc4 } from '@algorandfoundation/algorand-typescript/arc4' import { afterEach, describe, expect, test } from 'vitest' import { ABI_RETURN_VALUE_LOG_PREFIX } from '../../src/constants' -import { asUint8Array, encodeAddress } from '../../src/util' +import { encodeAddress } from '../../src/impl/reference' +import { asUint8Array } from '../../src/util' const abiTypeString = 'address' const testData = [ @@ -14,31 +15,31 @@ const testData = [ Bytes.fromHex(`${'00'.repeat(31)}ff`), ] -describe('arc4.Address', async () => { +describe('arc4.Address', () => { const ctx = new TestExecutionContext() - afterEach(async () => { + afterEach(() => { ctx.reset() }) - test.each(testData)('create address from bytes', async (value) => { + test.each(testData)('create address from bytes', (value) => { const sdkResult = getABIEncodedValue(asUint8Array(value), abiTypeString, {}) const result = new Address(value) expect(result.bytes).toEqual(sdkResult) }) - test.each(testData)('create address from str', async (value) => { + test.each(testData)('create address from str', (value) => { const stringValue = encodeAddress(asUint8Array(value)) const sdkResult = getABIEncodedValue(stringValue, abiTypeString, {}) const result = new Address(stringValue) expect(result.bytes).toEqual(sdkResult) }) - test.each(testData)('create address from Account', async (value) => { + test.each(testData)('create address from Account', (value) => { const accountValue = Account(value) const sdkResult = getABIEncodedValue(asUint8Array(accountValue.bytes), abiTypeString, {}) const result = new Address(accountValue) expect(result.bytes).toEqual(sdkResult) }) - test.each(testData)('get item from address created from bytes', async (value) => { + test.each(testData)('get item from address created from bytes', (value) => { const uint8ArrayValue = asUint8Array(value) const result = new Address(value) let i = 0 @@ -47,7 +48,7 @@ describe('arc4.Address', async () => { } expect(result.length).toEqual(uint8ArrayValue.length) }) - test.each(testData)('get item from address created from str', async (value) => { + test.each(testData)('get item from address created from str', (value) => { const uint8ArrayValue = asUint8Array(value) const stringValue = encodeAddress(uint8ArrayValue) const result = new Address(stringValue) @@ -57,7 +58,7 @@ describe('arc4.Address', async () => { } expect(result.length).toEqual(uint8ArrayValue.length) }) - test.each(testData)('get item from address created from Account', async (value) => { + test.each(testData)('get item from address created from Account', (value) => { const uint8ArrayValue = asUint8Array(value) const accountValue = Account(value) const result = new Address(accountValue) @@ -68,13 +69,13 @@ describe('arc4.Address', async () => { expect(result.length).toEqual(uint8ArrayValue.length) }) - test.each(testData)('fromBytes method', async (value) => { + test.each(testData)('fromBytes method', (value) => { const sdkResult = getABIEncodedValue(asUint8Array(value), abiTypeString, {}) const result = interpretAsArc4
(value) expect(result.bytes).toEqual(sdkResult) }) - test.each(testData)('fromLog method', async (value) => { + test.each(testData)('fromLog method', (value) => { const sdkResult = getABIEncodedValue(asUint8Array(value), abiTypeString, {}) const paddedValue = Bytes([...asUint8Array(ABI_RETURN_VALUE_LOG_PREFIX), ...asUint8Array(value)]) const result = interpretAsArc4
(paddedValue, 'log') diff --git a/tests/arc4/bool.spec.ts b/tests/arc4/bool.spec.ts index 2103d03..8cb3e4e 100644 --- a/tests/arc4/bool.spec.ts +++ b/tests/arc4/bool.spec.ts @@ -1,49 +1,66 @@ -import { AppSpec } from '@algorandfoundation/algokit-utils/types/app-spec' import { Bytes } from '@algorandfoundation/algorand-typescript' import { TestExecutionContext } from '@algorandfoundation/algorand-typescript-testing' import { Bool, interpretAsArc4 } from '@algorandfoundation/algorand-typescript/arc4' -import { afterEach, describe, expect, test } from 'vitest' +import { afterEach, beforeAll, describe, expect } from 'vitest' import { ABI_RETURN_VALUE_LOG_PREFIX } from '../../src/constants' import { asUint8Array } from '../../src/util' -import appSpecJson from '../artifacts/arc4-primitive-ops/data/Arc4PrimitiveOpsContract.arc32.json' -import { getAlgorandAppClient, getAvmResult } from '../avm-invoker' +import { getAvmResult } from '../avm-invoker' +import { createArc4TestFixture } from '../test-fixture' describe('arc4.Bool', async () => { - const appClient = await getAlgorandAppClient(appSpecJson as AppSpec) + const [test, localnetFixture] = createArc4TestFixture('tests/artifacts/arc4-primitive-ops/contract.algo.ts', { + Arc4PrimitiveOpsContract: { deployParams: { createParams: { extraProgramPages: undefined } } }, + }) const ctx = new TestExecutionContext() - afterEach(async () => { - ctx.reset() + beforeAll(async () => { + await localnetFixture.newScope() }) - test.each([true, false])('should be able to get bytes representation of %s', async (value) => { - const avmResult = await getAvmResult({ appClient }, 'verify_bool_bytes', value) - const result = new Bool(value) - expect(result.bytes).toEqual(avmResult) + afterEach(() => { + ctx.reset() }) - test.each([asUint8Array(Bytes.fromHex('00')), asUint8Array(Bytes.fromHex('80'))])('create Bool from bytes', async (value) => { - const avmResult = await getAvmResult({ appClient }, 'verify_bool_from_bytes', value) - const result = interpretAsArc4(Bytes(value)) - expect(result.native).toEqual(avmResult) - }) + test.for([true, false])( + 'should be able to get bytes representation of %s', + async (value, { appClientArc4PrimitiveOpsContract: appClient }) => { + const avmResult = await getAvmResult({ appClient }, 'verify_bool_bytes', value) + const result = new Bool(value) + expect(result.bytes).toEqual(avmResult) + }, + ) - test.each([asUint8Array(Bytes.fromHex('00')), asUint8Array(Bytes.fromHex('80'))])('create Bool from log', async (value) => { - const paddedValue = new Uint8Array([...asUint8Array(ABI_RETURN_VALUE_LOG_PREFIX), ...value]) - const avmResult = await getAvmResult({ appClient }, 'verify_bool_from_log', paddedValue) - const result = interpretAsArc4(Bytes(paddedValue), 'log') - expect(result.native).toEqual(avmResult) - }) + test.for([asUint8Array(Bytes.fromHex('00')), asUint8Array(Bytes.fromHex('80'))])( + 'create Bool from bytes', + async (value, { appClientArc4PrimitiveOpsContract: appClient }) => { + const avmResult = await getAvmResult({ appClient }, 'verify_bool_from_bytes', value) + const result = interpretAsArc4(Bytes(value)) + expect(result.native).toEqual(avmResult) + }, + ) + + test.for([asUint8Array(Bytes.fromHex('00')), asUint8Array(Bytes.fromHex('80'))])( + 'create Bool from log', + async (value, { appClientArc4PrimitiveOpsContract: appClient }) => { + const paddedValue = new Uint8Array([...asUint8Array(ABI_RETURN_VALUE_LOG_PREFIX), ...value]) + const avmResult = await getAvmResult({ appClient }, 'verify_bool_from_log', paddedValue) + const result = interpretAsArc4(Bytes(paddedValue), 'log') + expect(result.native).toEqual(avmResult) + }, + ) - test.each([ + test.for([ [asUint8Array(Bytes.fromHex('00')), asUint8Array('')], [asUint8Array(Bytes.fromHex('80')), asUint8Array(Bytes.fromHex('ff000102'))], [asUint8Array(Bytes.fromHex('00')), asUint8Array(ABI_RETURN_VALUE_LOG_PREFIX.slice(0, 3))], - ])('should throw error when log prefix is invalid for Bool', async (value, prefix) => { - const paddedValue = new Uint8Array([...prefix, ...value]) - await expect(() => getAvmResult({ appClient }, 'verify_bool_from_log', paddedValue)).rejects.toThrowError( - new RegExp('(assert failed)|(extraction start \\d+ is beyond length)'), - ) - expect(() => interpretAsArc4(Bytes(paddedValue), 'log')).toThrowError('ABI return prefix not found') - }) + ])( + 'should throw error when log prefix is invalid for Bool', + async ([value, prefix], { appClientArc4PrimitiveOpsContract: appClient }) => { + const paddedValue = new Uint8Array([...prefix, ...value]) + await expect(() => getAvmResult({ appClient }, 'verify_bool_from_log', paddedValue)).rejects.toThrowError( + new RegExp('(has valid prefix)|(extraction start \\d+ is beyond length)'), + ) + expect(() => interpretAsArc4(Bytes(paddedValue), 'log')).toThrowError('ABI return prefix not found') + }, + ) }) diff --git a/tests/arc4/byte.spec.ts b/tests/arc4/byte.spec.ts index 1cdcd1c..4a1a2cc 100644 --- a/tests/arc4/byte.spec.ts +++ b/tests/arc4/byte.spec.ts @@ -1,35 +1,44 @@ -import { AppSpec } from '@algorandfoundation/algokit-utils/types/app-spec' +import type { bytes } from '@algorandfoundation/algorand-typescript' import { Bytes } from '@algorandfoundation/algorand-typescript' import { TestExecutionContext } from '@algorandfoundation/algorand-typescript-testing' import { Byte, interpretAsArc4 } from '@algorandfoundation/algorand-typescript/arc4' import { encodingUtil } from '@algorandfoundation/puya-ts' -import { afterEach, describe, expect, it, test } from 'vitest' +import { afterEach, beforeAll, describe, expect } from 'vitest' import { ABI_RETURN_VALUE_LOG_PREFIX, MAX_UINT64 } from '../../src/constants' import { asBigUintCls, asUint8Array } from '../../src/util' -import appSpecJson from '../artifacts/arc4-primitive-ops/data/Arc4PrimitiveOpsContract.arc32.json' -import { getAlgorandAppClient, getAvmResult } from '../avm-invoker' +import { getAvmResult } from '../avm-invoker' +import { createArc4TestFixture } from '../test-fixture' const invalidBytesLengthError = 'byte string must be 1 byte long' describe('arc4.Byte', async () => { - const appClient = await getAlgorandAppClient(appSpecJson as AppSpec) + const [test, localnetFixture] = createArc4TestFixture('tests/artifacts/arc4-primitive-ops/contract.algo.ts', { + Arc4PrimitiveOpsContract: { deployParams: { createParams: { extraProgramPages: undefined } } }, + }) + const ctx = new TestExecutionContext() - afterEach(async () => { + beforeAll(async () => { + await localnetFixture.newScope() + }) + afterEach(() => { ctx.reset() }) - test.each([2 ** 8, MAX_UINT64])('instantiation should throw error as %s would overflow 8 bits', async (value) => { - const bytesValue = asBigUintCls(value).toBytes() + test.for([2 ** 8, MAX_UINT64])( + 'instantiation should throw error as %s would overflow 8 bits', + async (value, { appClientArc4PrimitiveOpsContract: appClient }) => { + const bytesValue = asBigUintCls(value).toBytes() - await expect(getAvmResult({ appClient }, 'verify_byte_init', asUint8Array(bytesValue))).rejects.toThrowError() - expect(() => new Byte(value)).toThrowError(`expected value <= ${2 ** 8 - 1}`) - }) + await expect(getAvmResult({ appClient }, 'verify_byte_init', asUint8Array(bytesValue))).rejects.toThrowError() + expect(() => new Byte(value)).toThrowError(`expected value <= ${2 ** 8 - 1}`) + }, + ) - test.each([ + test.for([ [0, 0], [255, 255], [2 ** 8 - 1, 2 ** 8 - 1], - ])('instantiating Byte should work for %s', async (value, expected) => { + ])('instantiating Byte should work for %s', async ([value, expected], { appClientArc4PrimitiveOpsContract: appClient }) => { const bytesValue = asBigUintCls(value).toBytes() const avmResult = await getAvmResult({ appClient }, 'verify_byte_init', asUint8Array(bytesValue)) @@ -39,7 +48,7 @@ describe('arc4.Byte', async () => { expect(avmResult).toEqual(expected) }) - test.each([0, 1, 255])('should be able to get bytes representation of %s', async (value) => { + test.for([0, 1, 255])('should be able to get bytes representation of %s', async (value) => { expect(new Byte(value).bytes).toEqual(encodingUtil.bigIntToUint8Array(BigInt(value), 1)) }) @@ -87,7 +96,7 @@ describe('arc4.Byte', async () => { throw new Error(`Unknown operator: ${op}`) } } - it(`${a} ${operator} ${b}`, async () => { + test(`${a} ${operator} ${b}`, async ({ appClientArc4PrimitiveOpsContract: appClient }) => { const bytesValueA = asBigUintCls(a).toBytes() const bytesValueB = asBigUintCls(b).toBytes() const avmResult = await getAvmResult({ appClient }, `verify_byte_byte_${op}`, asUint8Array(bytesValueA), asUint8Array(bytesValueB)) @@ -101,20 +110,20 @@ describe('arc4.Byte', async () => { }) }) - test.each([ + test.for([ encodingUtil.bigIntToUint8Array(0n, 1), encodingUtil.bigIntToUint8Array(42n, 1), encodingUtil.bigIntToUint8Array(2n ** 8n - 1n, 1), - ])('create Byte from bytes', async (value) => { + ])('create Byte from bytes', async (value, { appClientArc4PrimitiveOpsContract: appClient }) => { const avmResult = await getAvmResult({ appClient }, 'verify_byte_from_bytes', value) const result = interpretAsArc4(Bytes(value)) expect(result.native).toEqual(avmResult) }) - test.each([encodingUtil.bigIntToUint8Array(0n, 2), encodingUtil.bigIntToUint8Array(255n, 8)])( + test.for([encodingUtil.bigIntToUint8Array(0n, 2), encodingUtil.bigIntToUint8Array(255n, 8)])( 'sdk throws error when creating Byte from bytes with invalid length', - async (value) => { + async (value, { appClientArc4PrimitiveOpsContract: appClient }) => { await expect(getAvmResult({ appClient }, 'verify_byte_from_bytes', value)).rejects.toThrowError(invalidBytesLengthError) const result = interpretAsArc4(Bytes(value)) @@ -122,12 +131,12 @@ describe('arc4.Byte', async () => { }, ) - test.each([ + test.for([ [encodingUtil.bigIntToUint8Array(0n, 1), 0], [encodingUtil.bigIntToUint8Array(42n, 1), 42], [encodingUtil.bigIntToUint8Array(2n ** 8n - 1n, 1), 2 ** 8 - 1], - ])('create Byte from abi log', async (value, expected) => { - const logValue = asUint8Array(ABI_RETURN_VALUE_LOG_PREFIX.concat(Bytes(value))) + ])('create Byte from abi log', async ([value, expected], { appClientArc4PrimitiveOpsContract: appClient }) => { + const logValue = asUint8Array(ABI_RETURN_VALUE_LOG_PREFIX.concat(Bytes(value as Uint8Array))) const avmResult = await getAvmResult({ appClient }, 'verify_byte_from_log', logValue) const result = interpretAsArc4(Bytes(logValue), 'log') @@ -135,26 +144,32 @@ describe('arc4.Byte', async () => { expect(result.native).toEqual(expected) }) - test.each([ + test.for([ [encodingUtil.bigIntToUint8Array(255n, 1), Bytes()], [encodingUtil.bigIntToUint8Array(255n, 1), Bytes.fromHex('FF000102')], - ])('should throw error when log prefix is invalid for Byte', async (value, prefix) => { - const logValue = asUint8Array(Bytes(prefix).concat(Bytes(value))) - await expect(() => getAvmResult({ appClient }, 'verify_byte_from_log', logValue)).rejects.toThrowError( - new RegExp('(assert failed)|(extraction start \\d+ is beyond length)'), - ) - expect(() => interpretAsArc4(Bytes(logValue), 'log')).toThrowError('ABI return prefix not found') - }) + ])( + 'should throw error when log prefix is invalid for Byte', + async ([value, prefix], { appClientArc4PrimitiveOpsContract: appClient }) => { + const logValue = asUint8Array(Bytes(prefix as Uint8Array).concat(Bytes(value as bytes))) + await expect(() => getAvmResult({ appClient }, 'verify_byte_from_log', logValue)).rejects.toThrowError( + new RegExp('(has valid prefix)|(extraction start \\d+ is beyond length)'), + ) + expect(() => interpretAsArc4(Bytes(logValue), 'log')).toThrowError('ABI return prefix not found') + }, + ) - test.each([ + test.for([ encodingUtil.bigIntToUint8Array(0n, 2), encodingUtil.bigIntToUint8Array(42n, 8), encodingUtil.bigIntToUint8Array(2n ** 8n - 1n, 8), - ])('sdk throws error when creating Byte from log with invalid length', async (value) => { - const logValue = asUint8Array(ABI_RETURN_VALUE_LOG_PREFIX.concat(Bytes(value))) - await expect(() => getAvmResult({ appClient }, 'verify_byte_from_log', logValue)).rejects.toThrowError(invalidBytesLengthError) + ])( + 'sdk throws error when creating Byte from log with invalid length', + async (value, { appClientArc4PrimitiveOpsContract: appClient }) => { + const logValue = asUint8Array(ABI_RETURN_VALUE_LOG_PREFIX.concat(Bytes(value))) + await expect(() => getAvmResult({ appClient }, 'verify_byte_from_log', logValue)).rejects.toThrowError(invalidBytesLengthError) - const result = interpretAsArc4(Bytes(logValue), 'log') - expect(result.native).toEqual(encodingUtil.uint8ArrayToBigInt(value)) - }) + const result = interpretAsArc4(Bytes(logValue), 'log') + expect(result.native).toEqual(encodingUtil.uint8ArrayToBigInt(value)) + }, + ) }) diff --git a/tests/arc4/dynamic-array.spec.ts b/tests/arc4/dynamic-array.spec.ts index ee70df1..e470cc0 100644 --- a/tests/arc4/dynamic-array.spec.ts +++ b/tests/arc4/dynamic-array.spec.ts @@ -1,5 +1,5 @@ import { getABIEncodedValue } from '@algorandfoundation/algokit-utils/types/app-arc56' -import { Bytes, internal } from '@algorandfoundation/algorand-typescript' +import { Bytes } from '@algorandfoundation/algorand-typescript' import { TestExecutionContext } from '@algorandfoundation/algorand-typescript-testing' import { Address, @@ -15,8 +15,9 @@ import { } from '@algorandfoundation/algorand-typescript/arc4' import { encodingUtil } from '@algorandfoundation/puya-ts' import { afterEach, describe, expect, it, test } from 'vitest' -import { AccountCls } from '../../src/impl/account' -import { DeliberateAny } from '../../src/typescript-helpers' +import type { StubBytesCompat } from '../../src/impl/primitives' +import { AccountCls } from '../../src/impl/reference' +import type { DeliberateAny } from '../../src/typescript-helpers' import { asBytes, asUint8Array } from '../../src/util' const addressDynamicArray = { @@ -41,9 +42,15 @@ const addressDynamicArray = { array(isEmpty = false) { return isEmpty ? new DynamicArray
() : new DynamicArray
(...this.abiValues()) }, - create(value: internal.primitives.StubBytesCompat) { + create(value: StubBytesCompat) { return interpretAsArc4>(asBytes(value)) }, + concat() { + return this.array().concat(this.array()) + }, + concatABIValue() { + return getABIEncodedValue([...this.nativeValues(), ...this.nativeValues()], this.abiTypeString, {}) + }, } const boolDynamicArray = { abiTypeString: 'bool[]', @@ -56,9 +63,15 @@ const boolDynamicArray = { array(isEmpty = false) { return isEmpty ? new DynamicArray() : new DynamicArray(...this.abiValues()) }, - create(value: internal.primitives.StubBytesCompat) { + create(value: StubBytesCompat) { return interpretAsArc4>(asBytes(value)) }, + concat() { + return this.array().concat(this.array()) + }, + concatABIValue() { + return getABIEncodedValue([...this.nativeValues(), ...this.nativeValues()], this.abiTypeString, {}) + }, } const uint256DynamicArray = { abiTypeString: 'uint256[]', @@ -71,9 +84,15 @@ const uint256DynamicArray = { array(isEmpty = false) { return isEmpty ? new DynamicArray>() : new DynamicArray>(...this.abiValues()) }, - create(value: internal.primitives.StubBytesCompat) { + create(value: StubBytesCompat) { return interpretAsArc4>>(asBytes(value)) }, + concat() { + return this.array().concat(this.array()) + }, + concatABIValue() { + return getABIEncodedValue([...this.nativeValues(), ...this.nativeValues()], this.abiTypeString, {}) + }, } const ufixednxmDynamicArray = { abiTypeString: 'ufixed256x16[]', @@ -97,9 +116,15 @@ const ufixednxmDynamicArray = { array(isEmpty = false) { return isEmpty ? new DynamicArray>() : new DynamicArray>(...this.abiValues()) }, - create(value: internal.primitives.StubBytesCompat) { + create(value: StubBytesCompat) { return interpretAsArc4>>(asBytes(value)) }, + concat() { + return this.array().concat(this.array()) + }, + concatABIValue() { + return getABIEncodedValue([...this.nativeValues(), ...this.nativeValues()], this.abiTypeString, {}) + }, } const stringDynamicArray = { abiTypeString: 'string[]', @@ -123,9 +148,15 @@ const stringDynamicArray = { array(isEmpty = false) { return isEmpty ? new DynamicArray() : new DynamicArray(...this.abiValues()) }, - create(value: internal.primitives.StubBytesCompat) { + create(value: StubBytesCompat) { return interpretAsArc4>(asBytes(value)) }, + concat() { + return this.array().concat(this.array()) + }, + concatABIValue() { + return getABIEncodedValue([...this.nativeValues(), ...this.nativeValues()], this.abiTypeString, {}) + }, } const boolDynamicArrayOfArray = { abiTypeString: 'bool[][]', @@ -140,9 +171,15 @@ const boolDynamicArrayOfArray = { ? new DynamicArray>() : new DynamicArray>(...this.abiValues().map((a) => new DynamicArray(...a))) }, - create(value: internal.primitives.StubBytesCompat) { + create(value: StubBytesCompat) { return interpretAsArc4>>(asBytes(value)) }, + concat() { + return this.array().concat(this.array()) + }, + concatABIValue() { + return getABIEncodedValue([...this.nativeValues(), ...this.nativeValues()], this.abiTypeString, {}) + }, } const addressDynamicArrayOfArray = { abiTypeString: 'address[][]', @@ -157,9 +194,15 @@ const addressDynamicArrayOfArray = { ? new DynamicArray>() : new DynamicArray>(...this.abiValues().map((a) => new DynamicArray
(...a))) }, - create(value: internal.primitives.StubBytesCompat) { + create(value: StubBytesCompat) { return interpretAsArc4>>(asBytes(value)) }, + concat() { + return this.array().concat(this.array()) + }, + concatABIValue() { + return getABIEncodedValue([...this.nativeValues(), ...this.nativeValues()], this.abiTypeString, {}) + }, } const uint256DynamicArrayOfArray = { abiTypeString: 'uint256[][]', @@ -174,9 +217,15 @@ const uint256DynamicArrayOfArray = { ? new DynamicArray>>() : new DynamicArray>>(...this.abiValues().map((a) => new DynamicArray>(...a))) }, - create(value: internal.primitives.StubBytesCompat) { + create(value: StubBytesCompat) { return interpretAsArc4>>>(asBytes(value)) }, + concat() { + return this.array().concat(this.array()) + }, + concatABIValue() { + return getABIEncodedValue([...this.nativeValues(), ...this.nativeValues()], this.abiTypeString, {}) + }, } const uint256DynamicArrayOfStaticArray = { abiTypeString: 'uint256[10][]', @@ -184,16 +233,24 @@ const uint256DynamicArrayOfStaticArray = { return [uint256DynamicArray.nativeValues(), uint256DynamicArray.nativeValues().reverse()] }, abiValues() { - return this.nativeValues().map((a) => new StaticArray, 10>(...a.map((v) => new UintN<256>(v)))) + return this.nativeValues().map((a) => new StaticArray, 10>(...(a.map((v) => new UintN<256>(v)) as []))) }, array(isEmpty = false) { return isEmpty ? new DynamicArray, 10>>() - : new DynamicArray, 10>>(...this.abiValues().map((a) => new StaticArray, 10>(...a))) + : new DynamicArray, 10>>( + ...this.abiValues().map((a) => new StaticArray, 10>(...(a as DeliberateAny))), + ) }, - create(value: internal.primitives.StubBytesCompat) { + create(value: StubBytesCompat) { return interpretAsArc4, 10>>>(asBytes(value)) }, + concat() { + return this.array().concat(this.array()) + }, + concatABIValue() { + return getABIEncodedValue([...this.nativeValues(), ...this.nativeValues()], this.abiTypeString, {}) + }, } const stringDynamicArrayOfArray = { abiTypeString: 'string[][]', @@ -208,9 +265,15 @@ const stringDynamicArrayOfArray = { ? new DynamicArray>() : new DynamicArray>(...this.abiValues().map((a) => new DynamicArray(...a))) }, - create(value: internal.primitives.StubBytesCompat) { + create(value: StubBytesCompat) { return interpretAsArc4>>(asBytes(value)) }, + concat() { + return this.array().concat(this.array()) + }, + concatABIValue() { + return getABIEncodedValue([...this.nativeValues(), ...this.nativeValues()], this.abiTypeString, {}) + }, } const stringDynamicArrayOfArrayOfArray = { abiTypeString: 'string[][][]', @@ -230,9 +293,15 @@ const stringDynamicArrayOfArrayOfArray = { ? new DynamicArray>>() : new DynamicArray>>(...this.abiValues().map((x) => new DynamicArray>(...x))) }, - create(value: internal.primitives.StubBytesCompat) { + create(value: StubBytesCompat) { return interpretAsArc4>>>(asBytes(value)) }, + concat() { + return this.array().concat(this.array()) + }, + concatABIValue() { + return getABIEncodedValue([...this.nativeValues(), ...this.nativeValues()], this.abiTypeString, {}) + }, } const tupleDynamicArray = { abiTypeString: '(string[],(string[],string,uint256,address),bool,uint256[3])[]', @@ -261,7 +330,7 @@ const tupleDynamicArray = { addressDynamicArray.abiValues()[5], ), boolDynamicArray.abiValues()[3], - new StaticArray, 3>(...uint256DynamicArray.abiValues().slice(4, 7)), + new StaticArray, 3>(...(uint256DynamicArray.abiValues().slice(4, 7) as [])), ], ), ) @@ -275,11 +344,17 @@ const tupleDynamicArray = { Tuple<[DynamicArray, Tuple<[DynamicArray, Str, UintN<256>, Address]>, Bool, StaticArray, 3>]> >(...this.abiValues()) }, - create(value: internal.primitives.StubBytesCompat) { + create(value: StubBytesCompat) { return interpretAsArc4< DynamicArray, Tuple<[DynamicArray, Str, UintN<256>, Address]>, Bool, StaticArray, 3>]>> >(asBytes(value)) }, + concat() { + return this.array().concat(this.array()) + }, + concatABIValue() { + return getABIEncodedValue([...this.nativeValues(), ...this.nativeValues()], this.abiTypeString, {}) + }, } class Swapped extends Struct<{ b: UintN<256> @@ -328,14 +403,20 @@ const structDynamicArray = { array(isEmpty = false) { return isEmpty ? new DynamicArray() : new DynamicArray(...this.abiValues()) }, - create(value: internal.primitives.StubBytesCompat) { + create(value: StubBytesCompat) { return interpretAsArc4>(asBytes(value)) }, + concat() { + return this.array().concat(this.array()) + }, + concatABIValue() { + return getABIEncodedValue([...this.nativeValues(), ...this.nativeValues()], this.abiTypeString, {}) + }, } -describe('arc4.DynamicArray', async () => { +describe('arc4.DynamicArray', () => { const ctx = new TestExecutionContext() - afterEach(async () => { + afterEach(() => { ctx.reset() }) @@ -353,7 +434,7 @@ describe('arc4.DynamicArray', async () => { stringDynamicArrayOfArrayOfArray, tupleDynamicArray, structDynamicArray, - ])('should be able to get bytes representation', async (data) => { + ])('should be able to get bytes representation', (data) => { const sdkResult = getABIEncodedValue(data.nativeValues(), data.abiTypeString, {}) const result = data.array().bytes expect(result).toEqual(sdkResult) @@ -373,7 +454,7 @@ describe('arc4.DynamicArray', async () => { stringDynamicArrayOfArrayOfArray, tupleDynamicArray, structDynamicArray, - ])('copy dynamic array', async (data) => { + ])('copy dynamic array', (data) => { const sdkResult = getABIEncodedValue(data.nativeValues(), data.abiTypeString, {}) const original = data.array() const copy = original.copy() @@ -396,7 +477,31 @@ describe('arc4.DynamicArray', async () => { stringDynamicArrayOfArrayOfArray, tupleDynamicArray, structDynamicArray, - ])('get item from dynamic array', async (data) => { + ])('concat dynamic array', (data) => { + const sdkResult = data.concatABIValue() + const original = data.array() + const concatenated = data.concat() + const result = concatenated.bytes + + expect(concatenated.length).toEqual(original.length * 2) + expect(result).toEqual(asBytes(sdkResult)) + }) + + test.each([ + addressDynamicArray, + boolDynamicArray, + uint256DynamicArray, + ufixednxmDynamicArray, + stringDynamicArray, + addressDynamicArrayOfArray, + boolDynamicArrayOfArray, + uint256DynamicArrayOfArray, + uint256DynamicArrayOfStaticArray, + stringDynamicArrayOfArray, + stringDynamicArrayOfArrayOfArray, + tupleDynamicArray, + structDynamicArray, + ])('get item from dynamic array', (data) => { const dynamicArray = data.array() const nativeValues = data.nativeValues() for (let i = 0; i < dynamicArray.length; i++) { @@ -419,7 +524,7 @@ describe('arc4.DynamicArray', async () => { stringDynamicArrayOfArrayOfArray, tupleDynamicArray, structDynamicArray, - ])('set item in dynamic array', async (data) => { + ])('set item in dynamic array', (data) => { const nativeValues = data.nativeValues() const nativeValuesCopy = [...nativeValues] const nativeTemp = nativeValuesCopy.at(-1)! @@ -451,7 +556,7 @@ describe('arc4.DynamicArray', async () => { stringDynamicArrayOfArrayOfArray, tupleDynamicArray, structDynamicArray, - ])('create dynamic array from bytes', async (data) => { + ])('create dynamic array from bytes', (data) => { const sdkEncodedBytes = getABIEncodedValue(data.nativeValues(), data.abiTypeString, {}) const result = data.create(Bytes(sdkEncodedBytes)) const nativeValues = data.nativeValues() @@ -474,7 +579,7 @@ describe('arc4.DynamicArray', async () => { stringDynamicArrayOfArrayOfArray, tupleDynamicArray, structDynamicArray, - ])('push item to dynamic array', async (data) => { + ])('push item to dynamic array', (data) => { const nativeValues = data.nativeValues() const nativeValuesCopy = [...nativeValues] nativeValuesCopy.push(nativeValues.at(-1)!) @@ -503,7 +608,7 @@ describe('arc4.DynamicArray', async () => { stringDynamicArrayOfArrayOfArray, tupleDynamicArray, structDynamicArray, - ])('push item to empty dynamic array', async (data) => { + ])('push item to empty dynamic array', (data) => { const nativeValues = data.nativeValues() const sdkResult = getABIEncodedValue(nativeValues, data.abiTypeString, {}) @@ -527,7 +632,7 @@ describe('arc4.DynamicArray', async () => { stringDynamicArrayOfArrayOfArray, tupleDynamicArray, structDynamicArray, - ])('push item to empty dynamic array created from bytes', async (data) => { + ])('push item to empty dynamic array created from bytes', (data) => { const nativeValues = data.nativeValues() const sdkResult = getABIEncodedValue(nativeValues, data.abiTypeString, {}) @@ -551,7 +656,7 @@ describe('arc4.DynamicArray', async () => { stringDynamicArrayOfArrayOfArray, tupleDynamicArray, structDynamicArray, - ])('pop item from dynamic array', async (data) => { + ])('pop item from dynamic array', (data) => { const nativeValues = data.nativeValues() const nativeValuesCopy = [...nativeValues] const nativeValue1 = nativeValuesCopy.pop() @@ -570,7 +675,7 @@ describe('arc4.DynamicArray', async () => { expect(result).toEqual(Bytes(sdkResult)) }) - it('set item in nested dynamic array', async () => { + it('set item in nested dynamic array', () => { const data = stringDynamicArrayOfArrayOfArray const nativeValues = data.nativeValues() nativeValues[0][0][0] = 'new value' @@ -583,7 +688,7 @@ describe('arc4.DynamicArray', async () => { expect(result).toEqual(Bytes(sdkResult)) }) - it('set item in nested dynamic array created from bytes', async () => { + it('set item in nested dynamic array created from bytes', () => { const data = stringDynamicArrayOfArrayOfArray const nativeValues = data.nativeValues() nativeValues[0][0][0] = 'new value' diff --git a/tests/arc4/dynamic-bytes.spec.ts b/tests/arc4/dynamic-bytes.spec.ts index 4935f31..933158f 100644 --- a/tests/arc4/dynamic-bytes.spec.ts +++ b/tests/arc4/dynamic-bytes.spec.ts @@ -31,6 +31,12 @@ describe('arc4.DynamicBytes', async () => { expect(result).toEqual(Bytes(sdkResult)) }) + test.each(testData)('should be able to concat', async (data) => { + const sdkResult = getABIEncodedValue([...data.nativeValue(), ...data.nativeValue()], abiTypeString, {}) + const result = data.dynamicBytes().concat(data.dynamicBytes()).bytes + expect(result).toEqual(Bytes(sdkResult)) + }) + test.each(testData)('get item from dynamic bytes', async (data) => { const dynamicArray = data.dynamicBytes() const nativeValue = data.nativeValue() diff --git a/tests/arc4/emit.spec.ts b/tests/arc4/emit.spec.ts index be5af0b..789886e 100644 --- a/tests/arc4/emit.spec.ts +++ b/tests/arc4/emit.spec.ts @@ -1,12 +1,12 @@ -import { AppSpec } from '@algorandfoundation/algokit-utils/types/app-spec' -import { arc4, BigUint, biguint, Bytes, bytes, emit, Uint64, uint64 } from '@algorandfoundation/algorand-typescript' +import type { biguint, bytes, uint64 } from '@algorandfoundation/algorand-typescript' +import { arc4, BigUint, Bytes, emit, Uint64 } from '@algorandfoundation/algorand-typescript' import { TestExecutionContext } from '@algorandfoundation/algorand-typescript-testing' -import { afterEach, describe, expect, it } from 'vitest' +import { afterEach, beforeAll, describe, expect } from 'vitest' import { MAX_UINT512, MAX_UINT64 } from '../../src/constants' -import appSpecJson from '../artifacts/arc4-primitive-ops/data/Arc4PrimitiveOpsContract.arc32.json' -import { getAlgorandAppClient, getAvmResultLog } from '../avm-invoker' +import { getAvmResultLog } from '../avm-invoker' import { asBigUintCls, asNumber, asUint8Array } from '../../src/util' +import { createArc4TestFixture } from '../test-fixture' class Swapped { a: string @@ -41,14 +41,20 @@ class SwappedArc4 extends arc4.Struct<{ }> {} describe('arc4.emit', async () => { - const appClient = await getAlgorandAppClient(appSpecJson as AppSpec) + const [test, localnetFixture] = createArc4TestFixture('tests/artifacts/arc4-primitive-ops/contract.algo.ts', { + Arc4PrimitiveOpsContract: { deployParams: { createParams: { extraProgramPages: undefined } } }, + }) const ctx = new TestExecutionContext() - afterEach(async () => { + beforeAll(async () => { + await localnetFixture.newScope() + }) + + afterEach(() => { ctx.reset() }) - it('should emit the correct values', async () => { + test('should emit the correct values', async ({ appClientArc4PrimitiveOpsContract: appClient }) => { const test_data = new Swapped('hello', BigUint(MAX_UINT512), Uint64(MAX_UINT64), Bytes('world'), 16, false, Bytes('test'), 'greetings') const test_data_arc4 = new SwappedArc4({ diff --git a/tests/arc4/encode-decode-arc4.spec.ts b/tests/arc4/encode-decode-arc4.spec.ts index bf368fc..ed37439 100644 --- a/tests/arc4/encode-decode-arc4.spec.ts +++ b/tests/arc4/encode-decode-arc4.spec.ts @@ -1,8 +1,21 @@ -import { biguint, bytes, Bytes, internal, uint64 } from '@algorandfoundation/algorand-typescript' -import { Bool, decodeArc4, DynamicBytes, encodeArc4, Str, Struct, Tuple, UintN } from '@algorandfoundation/algorand-typescript/arc4' +import type { biguint, bytes, uint64 } from '@algorandfoundation/algorand-typescript' +import { Bytes } from '@algorandfoundation/algorand-typescript' +import type { Address, StaticArray, StaticBytes, UFixedNxM, UintN64 } from '@algorandfoundation/algorand-typescript/arc4' +import { + arc4EncodedLength, + Bool, + decodeArc4, + DynamicBytes, + encodeArc4, + Str, + Struct, + Tuple, + UintN, +} from '@algorandfoundation/algorand-typescript/arc4' import { describe, expect, test } from 'vitest' import { MAX_UINT128 } from '../../src/constants' -import { DeliberateAny } from '../../src/typescript-helpers' +import type { StubBytesCompat } from '../../src/impl/primitives' +import type { DeliberateAny } from '../../src/typescript-helpers' import { asBytes } from '../../src/util' const nativeString = 'hello' @@ -35,7 +48,7 @@ const testData = [ arc4Value() { return new Tuple<[UintN<64>, UintN<64>, UintN<512>, DynamicBytes]>(abiUint64, abiUint64, abiUint512, abiBytes) }, - decode(value: internal.primitives.StubBytesCompat) { + decode(value: StubBytesCompat) { return decodeArc4<[uint64, uint64, biguint, bytes]>(asBytes(value)) }, }, @@ -63,7 +76,7 @@ const testData = [ ...this.abiValues(), ) }, - decode(value: internal.primitives.StubBytesCompat) { + decode(value: StubBytesCompat) { return decodeArc4< [ [boolean, [string, boolean]], @@ -92,7 +105,7 @@ const testData = [ arc4Value() { return new Swapped1(this.abiValues()) }, - decode(value: internal.primitives.StubBytesCompat) { + decode(value: StubBytesCompat) { return decodeArc4<{ b: uint64; c: boolean; d: string; a: [uint64, boolean, boolean] }>(asBytes(value)) }, }, @@ -120,6 +133,27 @@ describe('encodeArc4', () => { }) }) +class StaticStruct extends Struct<{ + a: UintN64 + b: StaticArray + c: Bool + d: StaticBytes<32> + e: Address + f: StaticArray, 10> +}> {} +describe('arc4EncodedLength', () => { + test('should return the correct length', () => { + expect(arc4EncodedLength()).toEqual(8) + expect(arc4EncodedLength()).toEqual(64) + expect(arc4EncodedLength()).toEqual(1) + expect(arc4EncodedLength>()).toEqual(64) + expect(arc4EncodedLength<[uint64, uint64, boolean]>()).toEqual(17) + expect(arc4EncodedLength<[uint64, uint64, boolean, boolean]>()).toEqual(17) + expect(arc4EncodedLength, Bool]>>()).toEqual(3) + expect(arc4EncodedLength()).toEqual(395) + }) +}) + const compareNativeValues = (a: DeliberateAny, b: DeliberateAny) => { if (Array.isArray(a)) { for (let i = 0; i < a.length; i++) { diff --git a/tests/arc4/method-selector.spec.ts b/tests/arc4/method-selector.spec.ts new file mode 100644 index 0000000..6c68df6 --- /dev/null +++ b/tests/arc4/method-selector.spec.ts @@ -0,0 +1,307 @@ +import { AlgoAmount } from '@algorandfoundation/algokit-utils/types/amount' +import type { gtxn } from '@algorandfoundation/algorand-typescript' +import { arc4, Bytes, Global, Uint64 } from '@algorandfoundation/algorand-typescript' +import { TestExecutionContext } from '@algorandfoundation/algorand-typescript-testing' +import { DynamicArray, methodSelector } from '@algorandfoundation/algorand-typescript/arc4' +import { encodingUtil } from '@algorandfoundation/puya-ts' +import { afterEach, beforeAll, describe, expect } from 'vitest' +import { AnotherStruct, MyStruct, SignaturesContract } from '../artifacts/arc4-abi-method/contract.algo' +import { getAvmResult } from '../avm-invoker' +import { createArc4TestFixture } from '../test-fixture' + +const _FUNDED_ACCOUNT_SPENDING = Uint64(1234) + +describe('methodSelector', async () => { + const ctx = new TestExecutionContext() + const [test, localnetFixture] = createArc4TestFixture('tests/artifacts/arc4-abi-method/contract.algo.ts', { + SignaturesContract: { + deployParams: { createParams: { extraProgramPages: undefined, method: 'create' } }, + funding: new AlgoAmount({ microAlgos: Global.minBalance + _FUNDED_ACCOUNT_SPENDING }), + }, + }) + + beforeAll(async () => { + await localnetFixture.newScope() + }) + + afterEach(() => { + ctx.reset() + }) + + test('app args is correct with simple args', async ({ appClientSignaturesContract: appClient }) => { + // arrange + const contract = ctx.contract.create(SignaturesContract) + contract.create() + const arg1 = new arc4.Str('hello') + const arg2 = new arc4.DynamicArray(new arc4.UintN8(1), new arc4.UintN8(2)) + + // act + // ensure same execution in AVM runs without errors + await getAvmResult({ appClient }, 'sink', 'hello', [1, 2]) + // then run inside emulator + contract.sink(arg1, arg2) + + // assert + const txn = ctx.txn.lastActive as gtxn.ApplicationTxn + const appArgs = Array(Number(txn.numAppArgs)) + .fill(0) + .map((_, i) => txn.appArgs(i)) + expect(appArgs).toEqual([appClient.getABIMethod('sink(string,uint8[])void').getSelector(), arg1.bytes, arg2.bytes]) + expect(appArgs[0]).toEqual(arc4.methodSelector(SignaturesContract.prototype.sink)) + }) + + test('app args is correct with alias', async ({ appClientSignaturesContract: appClient }) => { + // arrange + const contract = ctx.contract.create(SignaturesContract) + contract.create() + const arg1 = new arc4.Str('hello') + const arg2 = new arc4.DynamicArray(new arc4.UintN8(1), new arc4.UintN8(2)) + + // act + // ensure same execution in AVM runs without errors + await getAvmResult({ appClient }, 'alias', 'hello', [1, 2]) + // then run inside emulator + contract.sink2(arg1, arg2) + + // assert + const txn = ctx.txn.lastActive as gtxn.ApplicationTxn + const appArgs = Array(Number(txn.numAppArgs)) + .fill(0) + .map((_, i) => txn.appArgs(i)) + expect(appArgs).toEqual([appClient.getABIMethod('alias(string,uint8[])void').getSelector(), arg1.bytes, arg2.bytes]) + expect(appArgs[0]).toEqual(arc4.methodSelector(SignaturesContract.prototype.sink2)) + }) + + test('app args is correct with txn', async ({ appClientSignaturesContract: appClient, algorand }) => { + // arrange + const contract = ctx.contract.create(SignaturesContract) + contract.create() + + const arg1 = new arc4.Str('hello') + const arg3 = new arc4.DynamicArray(new arc4.UintN8(1), new arc4.UintN8(2)) + const localnetCreator = await algorand.account.localNetDispenser() + const paymentTxn = await algorand.createTransaction.payment({ + sender: localnetCreator, + receiver: localnetCreator, + amount: new AlgoAmount({ microAlgo: 123 }), + signer: algorand.account.getSigner(localnetCreator), + }) + + // act + await getAvmResult({ appClient }, 'withTxn', 'hello', paymentTxn, [1, 2]) + contract.withTxn(arg1, ctx.any.txn.payment({ amount: Uint64(123) }), arg3) + + // asset + const txn = ctx.txn.lastActive as gtxn.ApplicationTxn + const appArgs = Array(Number(txn.numAppArgs)) + .fill(0) + .map((_, i) => txn.appArgs(i)) + expect(appArgs).toEqual([appClient.getABIMethod('withTxn(string,pay,uint8[])void').getSelector(), arg1.bytes, arg3.bytes]) + expect(appArgs[0]).toEqual(methodSelector(SignaturesContract.prototype.withTxn)) + }) + + test('app args is correct with asset', async ({ appClientSignaturesContract: appClient, algorand }) => { + // arrange + const contract = ctx.contract.create(SignaturesContract) + contract.create() + + const arg1 = new arc4.Str('hello') + const arg3 = new arc4.DynamicArray(new arc4.UintN8(1), new arc4.UintN8(2)) + const localnetCreator = await algorand.account.localNetDispenser() + const asaId = ( + await algorand.send.assetCreate({ + sender: localnetCreator, + total: 123n, + }) + ).confirmation.assetIndex + + // act + await getAvmResult({ appClient }, 'withAsset', 'hello', asaId, [1, 2]) + contract.withAsset(arg1, ctx.any.asset({ total: 123 }), arg3) + + // assert + const txn = ctx.txn.lastActive as gtxn.ApplicationTxn + const appArgs = Array(Number(txn.numAppArgs)) + .fill(0) + .map((_, i) => txn.appArgs(i)) + + expect(appArgs).toEqual([ + appClient.getABIMethod('withAsset(string,asset,uint8[])void').getSelector(), + arg1.bytes, + Bytes.fromHex('00'), + arg3.bytes, + ]) + expect(appArgs[0]).toEqual(methodSelector(SignaturesContract.prototype.withAsset)) + }) + + test('app args is correct with account', async ({ appClientSignaturesContract: appClient, algorand }) => { + // arrange + const contract = ctx.contract.create(SignaturesContract) + contract.create() + const arg1 = new arc4.Str('hello') + const arg3 = new arc4.DynamicArray(new arc4.UintN8(1), new arc4.UintN8(2)) + + const account = algorand.account.random() + await algorand.account.ensureFundedFromEnvironment(account, new AlgoAmount({ microAlgo: _FUNDED_ACCOUNT_SPENDING })) + // ensure context has the same account with matching balance + ctx.any.account({ + address: Bytes(account.publicKey), + balance: Global.minBalance + _FUNDED_ACCOUNT_SPENDING, + }) + + // act + contract.withAcc(arg1, ctx.ledger.getAccount(Bytes(account.publicKey)), arg3) + await getAvmResult({ appClient }, 'withAcc', 'hello', account.publicKey, [1, 2]) + + // assert + const txn = ctx.txn.lastActive as gtxn.ApplicationTxn + const appArgs = Array(Number(txn.numAppArgs)) + .fill(0) + .map((_, i) => txn.appArgs(i)) + expect(appArgs).toEqual([ + appClient.getABIMethod('withAcc(string,account,uint8[])void').getSelector(), + arg1.bytes, + Bytes.fromHex('01'), + arg3.bytes, + ]) + expect(appArgs[0]).toEqual(methodSelector(SignaturesContract.prototype.withAcc)) + }) + + test('app args is correct with application', async ({ appClientSignaturesContract: appClient, appFactorySignaturesContract }) => { + // arrange + const contract = ctx.contract.create(SignaturesContract) + contract.create() + const arg1 = new arc4.Str('hello') + const arg4 = new arc4.DynamicArray(new arc4.UintN8(1), new arc4.UintN8(2)) + + const selfApp = ctx.ledger.getApplicationForContract(contract) + const otherApp = await appFactorySignaturesContract.send.create({ method: 'create' }) + const otherAppId = otherApp.appClient.appId + ctx.any.application({ applicationId: otherAppId }) + + // act + await getAvmResult({ appClient }, 'withApp', 'hello', otherAppId, otherAppId, [1, 2]) + contract.withApp(arg1, ctx.ledger.getApplication(otherAppId), new arc4.UintN64(otherAppId), arg4) + + // assert + const txn = ctx.txn.lastActive as gtxn.ApplicationTxn + const appArgs = Array(Number(txn.numAppArgs)) + .fill(0) + .map((_, i) => txn.appArgs(i)) + const appForeignApps = Array(Number(txn.numApps)) + .fill(0) + .map((_, i) => txn.apps(i)) + + expect(appArgs).toEqual([ + appClient.getABIMethod('withApp(string,application,uint64,uint8[])void').getSelector(), + arg1.bytes, + Bytes.fromHex('01'), // 0th index is the app being called + encodingUtil.bigIntToUint8Array(otherAppId, 8), // app id as bytes + arg4.bytes, + ]) + expect(appArgs[0]).toEqual(methodSelector(SignaturesContract.prototype.withApp)) + expect(appForeignApps.map((a) => a.id)).toEqual([selfApp.id, otherAppId]) + }) + + test('app args is correct with complex', async ({ appClientSignaturesContract: appClient, algorand }) => { + // arrange + const contract = ctx.contract.create(SignaturesContract) + contract.create() + + const avmAccount = algorand.account.random() + await algorand.account.ensureFundedFromEnvironment(avmAccount, new AlgoAmount({ microAlgo: _FUNDED_ACCOUNT_SPENDING })) + // ensure context has the same account with matching balance + const account = ctx.any.account({ + address: Bytes(avmAccount.publicKey), + balance: Global.minBalance + _FUNDED_ACCOUNT_SPENDING, + }) + + const payment = ctx.any.txn.payment() + const struct = new MyStruct({ + three: new arc4.UintN128(3), + four: new arc4.UintN128(4), + anotherStruct: new AnotherStruct({ one: new arc4.UintN64(1), two: new arc4.Str('2') }), + anotherStructAlias: new AnotherStruct({ one: new arc4.UintN64(1), two: new arc4.Str('2') }), + }) + const five = new DynamicArray(new arc4.UintN8(5)) + + // act + const result = contract.complexSig(struct, payment, account, five) + + // assert + const txn = ctx.txn.lastActive as gtxn.ApplicationTxn + const appArgs = Array(Number(txn.numAppArgs)) + .fill(0) + .map((_, i) => txn.appArgs(i)) + + expect(appArgs).toEqual([ + appClient + .getABIMethod( + 'complexSig(((uint64,string),(uint64,string),uint128,uint128),pay,account,uint8[])((uint64,string),((uint64,string),(uint64,string),uint128,uint128))', + ) + .getSelector(), + struct.bytes, + Bytes.fromHex('01'), // 0th index is the sender + five.bytes, + ]) + expect(appArgs[0]).toEqual(methodSelector(SignaturesContract.prototype.complexSig)) + expect(result[0].bytes).toEqual(struct.anotherStruct.bytes) + expect(result[1].bytes).toEqual(struct.bytes) + }) + + test('prepare txns with complex', async ({ appClientSignaturesContract: appClient, algorand }) => { + // arrange + const contract = ctx.contract.create(SignaturesContract) + contract.create() + + const avmAccount = algorand.account.random() + await algorand.account.ensureFundedFromEnvironment(avmAccount, new AlgoAmount({ microAlgo: _FUNDED_ACCOUNT_SPENDING })) + // ensure context has the same account with matching balance + const account = ctx.any.account({ + address: Bytes(avmAccount.publicKey), + balance: Global.minBalance + _FUNDED_ACCOUNT_SPENDING, + }) + + const struct = new MyStruct({ + three: new arc4.UintN128(3), + four: new arc4.UintN128(4), + anotherStruct: new AnotherStruct({ one: new arc4.UintN64(1), two: new arc4.Str('2') }), + anotherStructAlias: new AnotherStruct({ one: new arc4.UintN64(1), two: new arc4.Str('2') }), + }) + const five = new DynamicArray(new arc4.UintN8(5)) + + const deferredAppCall = ctx.txn.deferAppCall(contract, contract.complexSig, 'complexSig', struct, ctx.any.txn.payment(), account, five) + const localnetCreator = await algorand.account.localNetDispenser() + const paymentTxn = await algorand.createTransaction.payment({ + sender: localnetCreator, + receiver: localnetCreator, + amount: new AlgoAmount({ microAlgo: 123 }), + signer: algorand.account.getSigner(localnetCreator), + }) + + // # act + await getAvmResult({ appClient }, 'complexSig', [[1, '2'], [1, '2'], 3, 4], paymentTxn, avmAccount.publicKey, [5]) + ctx.txn.createScope([ctx.any.txn.payment(), deferredAppCall, ctx.any.txn.payment()]).execute(() => { + const result = deferredAppCall.submit() + expect(result[0].bytes).toEqual(struct.anotherStruct.bytes) + expect(result[1].bytes).toEqual(struct.bytes) + }) + + // assert + const txn = ctx.txn.lastActive as gtxn.ApplicationTxn + const appArgs = Array(Number(txn.numAppArgs)) + .fill(0) + .map((_, i) => txn.appArgs(i)) + expect(appArgs).toEqual([ + appClient + .getABIMethod( + 'complexSig(((uint64,string),(uint64,string),uint128,uint128),pay,account,uint8[])((uint64,string),((uint64,string),(uint64,string),uint128,uint128))', + ) + .getSelector(), + struct.bytes, + Bytes.fromHex('01'), // 0th index is the sender + five.bytes, + ]) + expect(appArgs[0]).toEqual(methodSelector(SignaturesContract.prototype.complexSig)) + }) +}) diff --git a/tests/arc4/static-array.spec.ts b/tests/arc4/static-array.spec.ts index 53e6e4c..efcdea7 100644 --- a/tests/arc4/static-array.spec.ts +++ b/tests/arc4/static-array.spec.ts @@ -1,5 +1,5 @@ import { getABIEncodedValue } from '@algorandfoundation/algokit-utils/types/app-arc56' -import { Bytes, internal } from '@algorandfoundation/algorand-typescript' +import { Bytes } from '@algorandfoundation/algorand-typescript' import { TestExecutionContext } from '@algorandfoundation/algorand-typescript-testing' import { Address, @@ -15,8 +15,9 @@ import { } from '@algorandfoundation/algorand-typescript/arc4' import { encodingUtil } from '@algorandfoundation/puya-ts' import { afterEach, describe, expect, it, test } from 'vitest' -import { AccountCls } from '../../src/impl/account' -import { DeliberateAny } from '../../src/typescript-helpers' +import type { StubBytesCompat } from '../../src/impl/primitives' +import { AccountCls } from '../../src/impl/reference' +import type { DeliberateAny } from '../../src/typescript-helpers' import { asBytes, asUint8Array } from '../../src/util' const addressStaticArray = { @@ -39,11 +40,17 @@ const addressStaticArray = { return this.nativeValues().map((v) => new Address(Bytes(v))) }, array() { - return new StaticArray(...this.abiValues()) + return new StaticArray(...(this.abiValues() as [])) }, - create(value: internal.primitives.StubBytesCompat) { + create(value: StubBytesCompat) { return interpretAsArc4>(asBytes(value)) }, + concat() { + return this.array().concat(this.array()) + }, + concatABIValue() { + return getABIEncodedValue([...this.nativeValues(), ...this.nativeValues()], 'address[]', {}) + }, } const boolStaticArray = { abiTypeString: 'bool[10]', @@ -54,11 +61,17 @@ const boolStaticArray = { return this.nativeValues().map((v) => new Bool(v)) }, array() { - return new StaticArray(...this.abiValues()) + return new StaticArray(...(this.abiValues() as [])) }, - create(value: internal.primitives.StubBytesCompat) { + create(value: StubBytesCompat) { return interpretAsArc4>(asBytes(value)) }, + concat() { + return this.array().concat(this.array()) + }, + concatABIValue() { + return getABIEncodedValue([...this.nativeValues(), ...this.nativeValues()], 'bool[]', {}) + }, } const uint256StaticArray = { abiTypeString: 'uint256[10]', @@ -69,11 +82,17 @@ const uint256StaticArray = { return this.nativeValues().map((v) => new UintN<256>(v)) }, array() { - return new StaticArray, 10>(...this.abiValues()) + return new StaticArray, 10>(...(this.abiValues() as [])) }, - create(value: internal.primitives.StubBytesCompat) { + create(value: StubBytesCompat) { return interpretAsArc4, 10>>(asBytes(value)) }, + concat() { + return this.array().concat(this.array()) + }, + concatABIValue() { + return getABIEncodedValue([...this.nativeValues(), ...this.nativeValues()], 'uint256[]', {}) + }, } const ufixednxmStaticArray = { abiTypeString: 'ufixed256x16[10]', @@ -95,11 +114,17 @@ const ufixednxmStaticArray = { ] }, array() { - return new StaticArray, 10>(...this.abiValues()) + return new StaticArray, 10>(...(this.abiValues() as [])) }, - create(value: internal.primitives.StubBytesCompat) { + create(value: StubBytesCompat) { return interpretAsArc4, 10>>(asBytes(value)) }, + concat() { + return this.array().concat(this.array()) + }, + concatABIValue() { + return getABIEncodedValue([...this.nativeValues(), ...this.nativeValues()], 'ufixed256x16[]', {}) + }, } const stringStaticArray = { abiTypeString: 'string[10]', @@ -121,11 +146,17 @@ const stringStaticArray = { return this.nativeValues().map((v) => new Str(v)) }, array() { - return new StaticArray(...this.abiValues()) + return new StaticArray(...(this.abiValues() as [])) }, - create(value: internal.primitives.StubBytesCompat) { + create(value: StubBytesCompat) { return interpretAsArc4>(asBytes(value)) }, + concat() { + return this.array().concat(this.array()) + }, + concatABIValue() { + return getABIEncodedValue([...this.nativeValues(), ...this.nativeValues()], 'string[]', {}) + }, } const addressStaticArrayOfArray = { abiTypeString: 'address[10][2]', @@ -133,14 +164,22 @@ const addressStaticArrayOfArray = { return [addressStaticArray.nativeValues(), addressStaticArray.nativeValues().reverse()] }, abiValues() { - return this.nativeValues().map((a) => new StaticArray(...a.map((v) => new Address(Bytes(v))))) + return this.nativeValues().map((a) => new StaticArray(...(a.map((v) => new Address(Bytes(v))) as []))) }, array() { - return new StaticArray, 2>(...this.abiValues().map((a) => new StaticArray(...a))) + return new StaticArray, 2>( + ...(this.abiValues().map((a) => new StaticArray(...(a as DeliberateAny))) as []), + ) }, - create(value: internal.primitives.StubBytesCompat) { + create(value: StubBytesCompat) { return interpretAsArc4, 2>>(asBytes(value)) }, + concat() { + return this.array().concat(this.array()) + }, + concatABIValue() { + return getABIEncodedValue([...this.nativeValues(), ...this.nativeValues()], 'address[10][]', {}) + }, } const boolStaticArrayOfArray = { abiTypeString: 'bool[10][2]', @@ -148,14 +187,22 @@ const boolStaticArrayOfArray = { return [boolStaticArray.nativeValues(), boolStaticArray.nativeValues().reverse()] }, abiValues() { - return this.nativeValues().map((a) => new StaticArray(...a.map((v) => new Bool(v)))) + return this.nativeValues().map((a) => new StaticArray(...(a.map((v) => new Bool(v)) as []))) }, array() { - return new StaticArray, 2>(...this.abiValues().map((a) => new StaticArray(...a))) + return new StaticArray, 2>( + ...(this.abiValues().map((a) => new StaticArray(...(a as DeliberateAny))) as []), + ) }, - create(value: internal.primitives.StubBytesCompat) { + create(value: StubBytesCompat) { return interpretAsArc4, 2>>(asBytes(value)) }, + concat() { + return this.array().concat(this.array()) + }, + concatABIValue() { + return getABIEncodedValue([...this.nativeValues(), ...this.nativeValues()], 'bool[10][]', {}) + }, } const uint256StaticArrayOfArray = { abiTypeString: 'uint256[10][2]', @@ -163,14 +210,22 @@ const uint256StaticArrayOfArray = { return [uint256StaticArray.nativeValues(), uint256StaticArray.nativeValues().reverse()] }, abiValues() { - return this.nativeValues().map((a) => new StaticArray, 10>(...a.map((v) => new UintN<256>(v)))) + return this.nativeValues().map((a) => new StaticArray, 10>(...(a.map((v) => new UintN<256>(v)) as []))) }, array() { - return new StaticArray, 10>, 2>(...this.abiValues().map((a) => new StaticArray, 10>(...a))) + return new StaticArray, 10>, 2>( + ...(this.abiValues().map((a) => new StaticArray, 10>(...(a as DeliberateAny))) as []), + ) }, - create(value: internal.primitives.StubBytesCompat) { + create(value: StubBytesCompat) { return interpretAsArc4, 10>, 2>>(asBytes(value)) }, + concat() { + return this.array().concat(this.array()) + }, + concatABIValue() { + return getABIEncodedValue([...this.nativeValues(), ...this.nativeValues()], 'uint256[10][]', {}) + }, } const uint256StaticArrayOfDynamicArray = { abiTypeString: 'uint256[][2]', @@ -181,11 +236,17 @@ const uint256StaticArrayOfDynamicArray = { return this.nativeValues().map((a) => new DynamicArray>(...a.map((v) => new UintN<256>(v)))) }, array() { - return new StaticArray>, 2>(...this.abiValues().map((a) => new DynamicArray>(...a))) + return new StaticArray>, 2>(...(this.abiValues().map((a) => new DynamicArray>(...a)) as [])) }, - create(value: internal.primitives.StubBytesCompat) { + create(value: StubBytesCompat) { return interpretAsArc4>, 2>>(asBytes(value)) }, + concat() { + return this.array().concat(this.array()) + }, + concatABIValue() { + return getABIEncodedValue([...this.nativeValues(), ...this.nativeValues()], 'uint256[][]', {}) + }, } const stringStaticArrayOfArray = { abiTypeString: 'string[10][2]', @@ -193,14 +254,22 @@ const stringStaticArrayOfArray = { return [stringStaticArray.nativeValues(), stringStaticArray.nativeValues().reverse()] }, abiValues() { - return this.nativeValues().map((a) => new StaticArray(...a.map((v) => new Str(v)))) + return this.nativeValues().map((a) => new StaticArray(...(a.map((v) => new Str(v)) as []))) }, array() { - return new StaticArray, 2>(...this.abiValues().map((a) => new StaticArray(...a))) + return new StaticArray, 2>( + ...(this.abiValues().map((a) => new StaticArray(...(a as DeliberateAny))) as []), + ) }, - create(value: internal.primitives.StubBytesCompat) { + create(value: StubBytesCompat) { return interpretAsArc4, 2>>(asBytes(value)) }, + concat() { + return this.array().concat(this.array()) + }, + concatABIValue() { + return getABIEncodedValue([...this.nativeValues(), ...this.nativeValues()], 'string[10][]', {}) + }, } const stringStaticArrayOfArrayOfArray = { abiTypeString: 'string[10][3][2]', @@ -212,17 +281,24 @@ const stringStaticArrayOfArrayOfArray = { }, abiValues() { return this.nativeValues().map( - (x) => new StaticArray, 3>(...x.map((y) => new StaticArray(...y.map((v) => new Str(v))))), + (x) => + new StaticArray, 3>(...(x.map((y) => new StaticArray(...(y.map((v) => new Str(v)) as []))) as [])), ) }, array() { return new StaticArray, 3>, 2>( - ...this.abiValues().map((x) => new StaticArray, 3>(...x)), + ...(this.abiValues().map((x) => new StaticArray, 3>(...(x as DeliberateAny))) as []), ) }, - create(value: internal.primitives.StubBytesCompat) { + create(value: StubBytesCompat) { return interpretAsArc4, 3>, 2>>(asBytes(value)) }, + concat() { + return this.array().concat(this.array()) + }, + concatABIValue() { + return getABIEncodedValue([...this.nativeValues(), ...this.nativeValues()], 'string[10][3][]', {}) + }, } const tupleStaticArray = { abiTypeString: '(string[],(string[],string,uint256,address),bool,uint256[3])[2]', @@ -251,7 +327,7 @@ const tupleStaticArray = { addressStaticArray.abiValues()[5], ), boolStaticArray.abiValues()[3], - new StaticArray, 3>(...uint256StaticArray.abiValues().slice(4, 7)), + new StaticArray, 3>(...(uint256StaticArray.abiValues().slice(4, 7) as [])), ], ), ) @@ -260,13 +336,23 @@ const tupleStaticArray = { return new StaticArray< Tuple<[DynamicArray, Tuple<[DynamicArray, Str, UintN<256>, Address]>, Bool, StaticArray, 3>]>, 2 - >(...this.abiValues()) + >(...(this.abiValues() as [])) }, - create(value: internal.primitives.StubBytesCompat) { + create(value: StubBytesCompat) { return interpretAsArc4< StaticArray, Tuple<[DynamicArray, Str, UintN<256>, Address]>, Bool, StaticArray, 3>]>, 2> >(asBytes(value)) }, + concat() { + return this.array().concat(this.array()) + }, + concatABIValue() { + return getABIEncodedValue( + [...this.nativeValues(), ...this.nativeValues()], + '(string[],(string[],string,uint256,address),bool,uint256[3])[]', + {}, + ) + }, } class Swapped extends Struct<{ b: UintN<256> @@ -313,16 +399,26 @@ const structStaticArray = { ) }, array() { - return new StaticArray(...this.abiValues()) + return new StaticArray(...(this.abiValues() as [])) }, - create(value: internal.primitives.StubBytesCompat) { + create(value: StubBytesCompat) { return interpretAsArc4>(asBytes(value)) }, + concat() { + return this.array().concat(this.array()) + }, + concatABIValue() { + return getABIEncodedValue( + [...this.nativeValues(), ...this.nativeValues()], + '(uint256,bool,string,(string[],string[],string,uint256,bool,uint256[3]))[]', + {}, + ) + }, } -describe('arc4.StaticArray', async () => { +describe('arc4.StaticArray', () => { const ctx = new TestExecutionContext() - afterEach(async () => { + afterEach(() => { ctx.reset() }) @@ -340,7 +436,7 @@ describe('arc4.StaticArray', async () => { stringStaticArrayOfArrayOfArray, tupleStaticArray, structStaticArray, - ])('should be able to get bytes representation', async (data) => { + ])('should be able to get bytes representation', (data) => { const sdkResult = getABIEncodedValue(data.nativeValues(), data.abiTypeString, {}) const result = data.array().bytes expect(result).toEqual(Bytes(sdkResult)) @@ -360,7 +456,7 @@ describe('arc4.StaticArray', async () => { stringStaticArrayOfArrayOfArray, tupleStaticArray, structStaticArray, - ])('copy static array', async (data) => { + ])('copy static array', (data) => { const sdkResult = getABIEncodedValue(data.nativeValues(), data.abiTypeString, {}) const original = data.array() const copy = original.copy() @@ -383,7 +479,31 @@ describe('arc4.StaticArray', async () => { stringStaticArrayOfArrayOfArray, tupleStaticArray, structStaticArray, - ])('get item from static array', async (data) => { + ])('concat static array', (data) => { + const sdkResult = data.concatABIValue() + const original = data.array() + const concatenated = data.concat() + const result = concatenated.bytes + + expect(concatenated.length).toEqual(original.length * 2) + expect(result).toEqual(asBytes(sdkResult)) + }) + + test.each([ + addressStaticArray, + boolStaticArray, + uint256StaticArray, + ufixednxmStaticArray, + stringStaticArray, + addressStaticArrayOfArray, + boolStaticArrayOfArray, + uint256StaticArrayOfArray, + uint256StaticArrayOfDynamicArray, + stringStaticArrayOfArray, + stringStaticArrayOfArrayOfArray, + tupleStaticArray, + structStaticArray, + ])('get item from static array', (data) => { const staticArray = data.array() const nativeValues = data.nativeValues() for (let i = 0; i < staticArray.length; i++) { @@ -406,7 +526,7 @@ describe('arc4.StaticArray', async () => { stringStaticArrayOfArrayOfArray, tupleStaticArray, structStaticArray, - ])('set item in static array', async (data) => { + ])('set item in static array', (data) => { const nativeValues = data.nativeValues() const nativeValuesCopy = [...nativeValues] const nativeTemp = nativeValuesCopy.at(-1)! @@ -438,7 +558,7 @@ describe('arc4.StaticArray', async () => { stringStaticArrayOfArrayOfArray, tupleStaticArray, structStaticArray, - ])('create static array from bytes', async (data) => { + ])('create static array from bytes', (data) => { const sdkEncodedBytes = getABIEncodedValue(data.nativeValues(), data.abiTypeString, {}) const result = data.create(Bytes(sdkEncodedBytes)) const nativeValues = data.nativeValues() @@ -461,7 +581,7 @@ describe('arc4.StaticArray', async () => { stringStaticArrayOfArrayOfArray, tupleStaticArray, structStaticArray, - ])('get item from static array created from bytes', async (data) => { + ])('get item from static array created from bytes', (data) => { const nativeValues = data.nativeValues() const sdkEncodedBytes = getABIEncodedValue(data.nativeValues(), data.abiTypeString, {}) const staticArray = data.create(Bytes(sdkEncodedBytes)) @@ -485,7 +605,7 @@ describe('arc4.StaticArray', async () => { stringStaticArrayOfArrayOfArray, tupleStaticArray, structStaticArray, - ])('set item in static array created from bytes', async (data) => { + ])('set item in static array created from bytes', (data) => { const nativeValues = data.nativeValues() const nativeValuesCopy = [...nativeValues] const nativeTemp = nativeValuesCopy.at(-1)! @@ -504,7 +624,7 @@ describe('arc4.StaticArray', async () => { expect(result).toEqual(Bytes(sdkResult)) }) - it('set item in nested static array', async () => { + it('set item in nested static array', () => { const data = stringStaticArrayOfArrayOfArray const nativeValues = data.nativeValues() nativeValues[0][0][0] = 'new value' @@ -517,7 +637,7 @@ describe('arc4.StaticArray', async () => { expect(result).toEqual(Bytes(sdkResult)) }) - it('set item in nested static array create from bytes', async () => { + it('set item in nested static array create from bytes', () => { const data = stringStaticArrayOfArrayOfArray const nativeValues = data.nativeValues() nativeValues[0][0][0] = 'new value' diff --git a/tests/arc4/static-bytes.spec.ts b/tests/arc4/static-bytes.spec.ts index 6d8cfca..0d6565b 100644 --- a/tests/arc4/static-bytes.spec.ts +++ b/tests/arc4/static-bytes.spec.ts @@ -36,6 +36,12 @@ describe('arc4.StaticBytes', async () => { expect(result).toEqual(Bytes(sdkResult)) }) + test.each(testData)('should be able to concat', async (data) => { + const sdkResult = getABIEncodedValue([...data.nativeValue(), ...data.nativeValue()], 'byte[]', {}) + const result = data.staticBytes().concat(data.staticBytes()).bytes + expect(result).toEqual(Bytes(sdkResult)) + }) + test.each(testData)('get item from static bytes', async (data) => { const staticArray = data.staticBytes() const nativeValue = data.nativeValue() diff --git a/tests/arc4/str.spec.ts b/tests/arc4/str.spec.ts index a8e1b21..6076da0 100644 --- a/tests/arc4/str.spec.ts +++ b/tests/arc4/str.spec.ts @@ -1,36 +1,40 @@ -import { AppSpec } from '@algorandfoundation/algokit-utils/types/app-spec' import { Bytes } from '@algorandfoundation/algorand-typescript' import { TestExecutionContext } from '@algorandfoundation/algorand-typescript-testing' import { interpretAsArc4, Str } from '@algorandfoundation/algorand-typescript/arc4' import { encodingUtil } from '@algorandfoundation/puya-ts' -import { afterEach, describe, expect, test } from 'vitest' +import { afterEach, beforeAll, describe, expect } from 'vitest' import { ABI_RETURN_VALUE_LOG_PREFIX, MAX_LOG_SIZE } from '../../src/constants' import { asUint8Array } from '../../src/util' -import appSpecJson from '../artifacts/arc4-primitive-ops/data/Arc4PrimitiveOpsContract.arc32.json' -import { getAlgorandAppClient, getAvmResult } from '../avm-invoker' +import { getAvmResult } from '../avm-invoker' +import { createArc4TestFixture } from '../test-fixture' describe('arc4.Str', async () => { - const appClient = await getAlgorandAppClient(appSpecJson as AppSpec) + const [test, localnetFixture] = createArc4TestFixture('tests/artifacts/arc4-primitive-ops/contract.algo.ts', { + Arc4PrimitiveOpsContract: { deployParams: { createParams: { extraProgramPages: undefined } } }, + }) const ctx = new TestExecutionContext() - afterEach(async () => { + beforeAll(async () => { + await localnetFixture.newScope() + }) + afterEach(() => { ctx.reset() }) - test.each([ + test.for([ '', 'hello', '0'.repeat(MAX_LOG_SIZE - 13), // Max log size is 1024 - ])('instantiate Str with %s', async (value) => { + ])('instantiate Str with %s', async (value, { appClientArc4PrimitiveOpsContract: appClient }) => { const avmResult = await getAvmResult({ appClient }, 'verify_string_init', asUint8Array(value)) const result = new Str(`Hello, ${value}`) expect(result.native).toEqual(avmResult) }) - test.each([ + test.for([ ['hello', 'world', 'helloworld'], ['foo', 'bar', 'foobar'], - ])('add Str values', async (a, b, expected) => { + ])('add Str values', async ([a, b, expected], { appClientArc4PrimitiveOpsContract: appClient }) => { const avmResult = await getAvmResult({ appClient }, 'verify_string_add', asUint8Array(a), asUint8Array(b)) const aStr = new Str(a) const bStr = new Str(b) @@ -39,12 +43,12 @@ describe('arc4.Str', async () => { expect(result.native).toEqual(expected) }) - test.each([ + test.for([ ['', ''], ['hello', 'hello'], ['foo', 'Foo'], ['foo', 'bar'], - ])('%s equals %s', async (a, b) => { + ])('%s equals %s', async ([a, b], { appClientArc4PrimitiveOpsContract: appClient }) => { const avmResult = await getAvmResult({ appClient }, 'verify_string_eq', asUint8Array(a), asUint8Array(b)) const aStr = new Str(a) const bStr = new Str(b) @@ -52,32 +56,32 @@ describe('arc4.Str', async () => { expect(result).toEqual(avmResult) }) - test.each([ + test.for([ '', 'hello', '0'.repeat(MAX_LOG_SIZE - 8), // Max log size is 1024 - ])('should be able to get bytes representation of %s', async (value) => { + ])('should be able to get bytes representation of %s', async (value, { appClientArc4PrimitiveOpsContract: appClient }) => { const avmResult = await getAvmResult({ appClient }, 'verify_string_bytes', asUint8Array(value)) const result = new Str(value) expect(result.bytes).toEqual(avmResult) }) - test.each([ + test.for([ asUint8Array(''), asUint8Array('hello'), asUint8Array('0'.repeat(MAX_LOG_SIZE - 13)), // Max log size is 1024 - ])('create Str from bytes', async (value) => { + ])('create Str from bytes', async (value, { appClientArc4PrimitiveOpsContract: appClient }) => { const paddedValue = new Uint8Array([...encodingUtil.bigIntToUint8Array(BigInt(value.length), 2), ...value]) const avmResult = await getAvmResult({ appClient }, 'verify_string_from_bytes', paddedValue) const result = interpretAsArc4(Bytes(paddedValue)) expect(result.native).toEqual(avmResult) }) - test.each([ + test.for([ asUint8Array(''), asUint8Array('hello'), asUint8Array('0'.repeat(MAX_LOG_SIZE - 13)), // Max log size is 1024 - ])('create Str from log', async (value) => { + ])('create Str from log', async (value, { appClientArc4PrimitiveOpsContract: appClient }) => { const paddedValue = new Uint8Array([ ...asUint8Array(ABI_RETURN_VALUE_LOG_PREFIX), ...encodingUtil.bigIntToUint8Array(BigInt(value.length), 2), @@ -88,14 +92,14 @@ describe('arc4.Str', async () => { expect(result.native).toEqual(avmResult) }) - test.each([ + test.for([ [asUint8Array(''), asUint8Array('')], [asUint8Array('hello'), asUint8Array(Bytes.fromHex('ff000102'))], [asUint8Array('0'.repeat(MAX_LOG_SIZE - 13)), asUint8Array(ABI_RETURN_VALUE_LOG_PREFIX.slice(0, 3))], // Max log size is 1024 - ])('should throw error when log prefix is invalid for Str', async (value, prefix) => { + ])('should throw error when log prefix is invalid for Str', async ([value, prefix], { appClientArc4PrimitiveOpsContract: appClient }) => { const paddedValue = new Uint8Array([...prefix, ...value]) await expect(() => getAvmResult({ appClient }, 'verify_string_from_log', paddedValue)).rejects.toThrowError( - new RegExp('(assert failed)|(extraction start \\d+ is beyond length)'), + new RegExp('(has valid prefix)|(extraction start \\d+ is beyond length)'), ) expect(() => interpretAsArc4(Bytes(paddedValue), 'log')).toThrowError('ABI return prefix not found') }) diff --git a/tests/arc4/struct.spec.ts b/tests/arc4/struct.spec.ts index 64cdc04..04470a7 100644 --- a/tests/arc4/struct.spec.ts +++ b/tests/arc4/struct.spec.ts @@ -1,10 +1,11 @@ import { getABIEncodedValue } from '@algorandfoundation/algokit-utils/types/app-arc56' -import { Bytes, internal } from '@algorandfoundation/algorand-typescript' +import { Bytes } from '@algorandfoundation/algorand-typescript' import { Bool, DynamicArray, interpretAsArc4, StaticArray, Str, Struct, Tuple, UintN } from '@algorandfoundation/algorand-typescript/arc4' import { encodingUtil } from '@algorandfoundation/puya-ts' import { describe, expect, it, test } from 'vitest' -import { AccountCls } from '../../src/impl/account' -import { DeliberateAny } from '../../src/typescript-helpers' +import type { StubBytesCompat } from '../../src/impl/primitives' +import { AccountCls } from '../../src/impl/reference' +import type { DeliberateAny } from '../../src/typescript-helpers' import { asBytes } from '../../src/util' const nativeString = 'hello' @@ -69,7 +70,7 @@ const testData = [ struct() { return new Swapped1(this.abiValues()) }, - create(value: internal.primitives.StubBytesCompat) { + create(value: StubBytesCompat) { return interpretAsArc4(asBytes(value)) }, }, @@ -97,7 +98,7 @@ const testData = [ struct() { return new Swapped2(this.abiValues()) }, - create(value: internal.primitives.StubBytesCompat) { + create(value: StubBytesCompat) { return interpretAsArc4(asBytes(value)) }, }, @@ -136,7 +137,7 @@ const testData = [ struct() { return new Swapped3(this.abiValues()) }, - create(value: internal.primitives.StubBytesCompat) { + create(value: StubBytesCompat) { return interpretAsArc4(asBytes(value)) }, }, @@ -165,7 +166,7 @@ const testData = [ struct() { return new Swapped4(this.abiValues()) }, - create(value: internal.primitives.StubBytesCompat) { + create(value: StubBytesCompat) { return interpretAsArc4(asBytes(value)) }, }, @@ -196,7 +197,7 @@ const testData = [ struct() { return new Swapped5(this.abiValues()) }, - create(value: internal.primitives.StubBytesCompat) { + create(value: StubBytesCompat) { return interpretAsArc4(asBytes(value)) }, }, @@ -227,7 +228,7 @@ const testData = [ struct() { return new Swapped6(this.abiValues()) }, - create(value: internal.primitives.StubBytesCompat) { + create(value: StubBytesCompat) { return interpretAsArc4(asBytes(value)) }, }, @@ -254,12 +255,14 @@ describe('arc4.Struct', async () => { it('set item in struct', async () => { const data = testData[5] + const nativeValues = data.nativeValues() as DeliberateAny nativeValues[0] = 43 nativeValues[2] = 'world' nativeValues[3][0][1][0][1] = 'hello, world' nativeValues[3][0][1][0].push('test') nativeValues[3][1][1][0] = 24 + const sdkResult = getABIEncodedValue(nativeValues, data.abiTypeString, {}) const abiValues = data.struct() as Swapped6 @@ -281,9 +284,10 @@ describe('arc4.Struct', async () => { nativeValues[3][0][1][0][1] = 'hello, world' nativeValues[3][0][1][0].push('test') nativeValues[3][1][1][0] = 24 - const sdkResult = getABIEncodedValue(nativeValues, data.abiTypeString, {}) + const sdkResult = getABIEncodedValue(nativeValues, data.abiTypeString, {}) const bytes = Bytes(getABIEncodedValue(data.nativeValues(), data.abiTypeString, {})) + const abiValues = data.create(bytes) as Swapped6 abiValues.b = new UintN<64>(43) abiValues.d = new Str('world') diff --git a/tests/arc4/tuple.spec.ts b/tests/arc4/tuple.spec.ts index d4cc2a4..0ac3191 100644 --- a/tests/arc4/tuple.spec.ts +++ b/tests/arc4/tuple.spec.ts @@ -1,11 +1,12 @@ import { getABIEncodedValue } from '@algorandfoundation/algokit-utils/types/app-arc56' -import { Bytes, internal } from '@algorandfoundation/algorand-typescript' +import { Bytes } from '@algorandfoundation/algorand-typescript' import { TestExecutionContext } from '@algorandfoundation/algorand-typescript-testing' import { Address, Bool, DynamicArray, interpretAsArc4, StaticArray, Str, Tuple, UintN } from '@algorandfoundation/algorand-typescript/arc4' import { encodingUtil } from '@algorandfoundation/puya-ts' import { afterEach, describe, expect, test } from 'vitest' -import { AccountCls } from '../../src/impl/account' -import { DeliberateAny } from '../../src/typescript-helpers' +import type { StubBytesCompat } from '../../src/impl/primitives' +import { AccountCls } from '../../src/impl/reference' +import type { DeliberateAny } from '../../src/typescript-helpers' import { asBytes, asUint8Array } from '../../src/util' const nativeString = 'hello' @@ -25,6 +26,29 @@ const otherAbiString = new Str('hello') const otherAbiUint8 = new UintN<8>(42) const testData = [ + { + abiTypeString: '(bool[10],bool,bool)', + nativeValues() { + return [ + [nativeBool, nativeBool, nativeBool, nativeBool, nativeBool, nativeBool, nativeBool, nativeBool, nativeBool, nativeBool], + nativeBool, + nativeBool, + ] + }, + abiValues() { + return [ + new StaticArray(abiBool, abiBool, abiBool, abiBool, abiBool, abiBool, abiBool, abiBool, abiBool, abiBool), + abiBool, + abiBool, + ] as readonly [StaticArray, Bool, Bool] + }, + tuple() { + return new Tuple<[StaticArray, Bool, Bool]>(...this.abiValues()) + }, + create(value: StubBytesCompat) { + return interpretAsArc4, Bool, Bool]>>(asBytes(value)) + }, + }, { abiTypeString: '(uint8,bool,bool,address)', nativeValues() { @@ -36,7 +60,7 @@ const testData = [ tuple() { return new Tuple<[UintN<8>, Bool, Bool, Address]>(...this.abiValues()) }, - create(value: internal.primitives.StubBytesCompat) { + create(value: StubBytesCompat) { return interpretAsArc4, Bool, Bool, Address]>>(asBytes(value)) }, }, @@ -51,7 +75,7 @@ const testData = [ tuple() { return new Tuple<[Str, UintN<8>, Bool]>(...this.abiValues()) }, - create(value: internal.primitives.StubBytesCompat) { + create(value: StubBytesCompat) { return interpretAsArc4, Bool]>>(asBytes(value)) }, }, @@ -72,7 +96,7 @@ const testData = [ tuple() { return new Tuple<[Tuple<[UintN<8>, Bool, Bool]>, Tuple<[UintN<8>, Bool, Bool]>]>(...this.abiValues()) }, - create(value: internal.primitives.StubBytesCompat) { + create(value: StubBytesCompat) { return interpretAsArc4, Bool, Bool]>, Tuple<[UintN<8>, Bool, Bool]>]>>(asBytes(value)) }, }, @@ -101,7 +125,7 @@ const testData = [ tuple() { return new Tuple<[DynamicArray, DynamicArray, Str, UintN<8>, Bool, StaticArray, 3>]>(...this.abiValues()) }, - create(value: internal.primitives.StubBytesCompat) { + create(value: StubBytesCompat) { return interpretAsArc4, DynamicArray, Str, UintN<8>, Bool, StaticArray, 3>]>>(asBytes(value)) }, }, @@ -120,7 +144,7 @@ const testData = [ tuple() { return new Tuple<[Tuple<[Bool, DynamicArray, Str]>, UintN<8>, StaticArray, 3>]>(...this.abiValues()) }, - create(value: internal.primitives.StubBytesCompat) { + create(value: StubBytesCompat) { return interpretAsArc4, Str]>, UintN<8>, StaticArray, 3>]>>(asBytes(value)) }, }, @@ -141,7 +165,7 @@ const testData = [ tuple() { return new Tuple<[Tuple<[Bool, DynamicArray, Str]>, Tuple<[UintN<8>, StaticArray, 3>]>]>(...this.abiValues()) }, - create(value: internal.primitives.StubBytesCompat) { + create(value: StubBytesCompat) { return interpretAsArc4, Str]>, Tuple<[UintN<8>, StaticArray, 3>]>]>>(asBytes(value)) }, }, @@ -167,7 +191,7 @@ const testData = [ ...this.abiValues(), ) }, - create(value: internal.primitives.StubBytesCompat) { + create(value: StubBytesCompat) { return interpretAsArc4, Str, Address]>]>, Tuple<[UintN<8>, StaticArray, 3>]>]>>( asBytes(value), ) @@ -291,19 +315,19 @@ const testDataWithArray = [ }, ] -describe('arc4.Tuple', async () => { +describe('arc4.Tuple', () => { const ctx = new TestExecutionContext() - afterEach(async () => { + afterEach(() => { ctx.reset() }) - test.each(testData)('should be able to get bytes representation', async (data) => { + test.each(testData)('should be able to get bytes representation', (data) => { const sdkResult = getABIEncodedValue(data.nativeValues(), data.abiTypeString, {}) const result = data.tuple().bytes expect(result).toEqual(Bytes(sdkResult)) }) - test.each(testData)('should be able to get native representation', async (data) => { + test.each(testData)('should be able to get native representation', (data) => { const nativeValues = data.nativeValues() const result = data.tuple().native for (let i = 0; i < nativeValues.length; i++) { @@ -312,7 +336,7 @@ describe('arc4.Tuple', async () => { expect(result.length).toEqual(nativeValues.length) }) - test.each(testData)('create tuple from bytes', async (data) => { + test.each(testData)('create tuple from bytes', (data) => { const nativeValues = data.nativeValues() const sdkEncodedBytes = getABIEncodedValue(nativeValues, data.abiTypeString, {}) @@ -324,7 +348,7 @@ describe('arc4.Tuple', async () => { } }) - test.each(testDataWithArray)('update array values in tuple', async (data) => { + test.each(testDataWithArray)('update array values in tuple', (data) => { const sdkResult = getABIEncodedValue(data.updatedNativeValues(), data.abiTypeString, {}) const tuple = data.tuple() data.update(tuple as DeliberateAny) diff --git a/tests/arc4/ufixednxm.spec.ts b/tests/arc4/ufixednxm.spec.ts index cc9eb94..d8b6259 100644 --- a/tests/arc4/ufixednxm.spec.ts +++ b/tests/arc4/ufixednxm.spec.ts @@ -1,24 +1,29 @@ -import { AppSpec } from '@algorandfoundation/algokit-utils/types/app-spec' +import type { bytes } from '@algorandfoundation/algorand-typescript' import { Bytes } from '@algorandfoundation/algorand-typescript' import { TestExecutionContext } from '@algorandfoundation/algorand-typescript-testing' import { interpretAsArc4, UFixedNxM } from '@algorandfoundation/algorand-typescript/arc4' import { encodingUtil } from '@algorandfoundation/puya-ts' -import { afterEach, describe, expect, test } from 'vitest' +import { afterEach, beforeAll, describe, expect } from 'vitest' import { ABI_RETURN_VALUE_LOG_PREFIX } from '../../src/constants' import { asBigUint, asUint8Array } from '../../src/util' -import appSpecJson from '../artifacts/arc4-primitive-ops/data/Arc4PrimitiveOpsContract.arc32.json' -import { getAlgorandAppClient, getAvmResult } from '../avm-invoker' +import { getAvmResult } from '../avm-invoker' +import { createArc4TestFixture } from '../test-fixture' const invalidBytesLengthError = (length: number) => `byte string must correspond to a ufixed${length}` describe('arc4.UFixedNxM', async () => { - const appClient = await getAlgorandAppClient(appSpecJson as AppSpec) + const [test, localnetFixture] = createArc4TestFixture('tests/artifacts/arc4-primitive-ops/contract.algo.ts', { + Arc4PrimitiveOpsContract: { deployParams: { createParams: { extraProgramPages: undefined } } }, + }) const ctx = new TestExecutionContext() - afterEach(async () => { + beforeAll(async () => { + await localnetFixture.newScope() + }) + afterEach(() => { ctx.reset() }) - test.each(['-1', '42.9496729501', '255.01two'])( + test.for(['-1', '42.9496729501', '255.01two'])( 'should throw error when instantiating UFixedNxM<32,8> with invalid value %s', async (value) => { expect(() => new UFixedNxM<32, 8>(value as `${number}.${number}`)).toThrow( @@ -27,16 +32,16 @@ describe('arc4.UFixedNxM', async () => { }, ) - test.each(['42.94967296', (2n ** 32n).toString()])( + test.for(['42.94967296', (2n ** 32n).toString()])( 'should throw error when instantiating UFixedNxM<32,8> with overflowing value %s', async (value) => { expect(() => new UFixedNxM<32, 8>(value as `${number}.${number}`)).toThrow('expected value <=') }, ) - test.each(['0', '1', '25.5', '42.94967295', '42.9496729500'])( + test.for(['0', '1', '25.5', '42.94967295', '42.9496729500'])( 'should be able to get UFixedNxM<32,8> bytes representation of %s', - async (value) => { + async (value, { appClientArc4PrimitiveOpsContract: appClient }) => { const a = new UFixedNxM<32, 8>(value as `${number}.${number}`) const bigIntValue = asBigUint(a.bytes).valueOf() const avmResult = await getAvmResult({ appClient }, 'verify_ufixednxm_bytes', bigIntValue) @@ -44,9 +49,9 @@ describe('arc4.UFixedNxM', async () => { }, ) - test.each(['0', '1', '25.5', '42.94967295', '11579208923731619542357098500868790785326998466564056403945758.4007913129639935'])( + test.for(['0', '1', '25.5', '42.94967295', '11579208923731619542357098500868790785326998466564056403945758.4007913129639935'])( 'should be able to get UFixedNxM<256,16> bytes representation of %s', - async (value) => { + async (value, { appClientArc4PrimitiveOpsContract: appClient }) => { const a = new UFixedNxM<256, 16>(value as `${number}.${number}`) const bigIntValue = asBigUint(a.bytes).valueOf() const avmResult = await getAvmResult({ appClient }, 'verify_bigufixednxm_bytes', bigIntValue) @@ -54,38 +59,41 @@ describe('arc4.UFixedNxM', async () => { }, ) - test.each([ + test.for([ encodingUtil.bigIntToUint8Array(0n, 4), encodingUtil.bigIntToUint8Array(255n, 4), encodingUtil.bigIntToUint8Array(2n ** 16n, 4), encodingUtil.bigIntToUint8Array(2n ** 32n - 1n, 4), encodingUtil.bigIntToUint8Array(2n ** 32n - 1n), - ])('create UFixedNxM<32,8> from bytes', async (value) => { + ])('create UFixedNxM<32,8> from bytes', async (value, { appClientArc4PrimitiveOpsContract: appClient }) => { const avmResult = await getAvmResult({ appClient }, 'verify_ufixednxm_from_bytes', value) const result = interpretAsArc4>(Bytes(value)) expect(result.native).toEqual(avmResult) }) - test.each([ + test.for([ encodingUtil.bigIntToUint8Array(0n, 1), encodingUtil.bigIntToUint8Array(0n, 8), encodingUtil.bigIntToUint8Array(255n, 2), encodingUtil.bigIntToUint8Array(2n ** 32n - 1n, 8), - ])('sdk throws error when creating UFixedNxM<32,8> from bytes with invalid length', async (value) => { - await expect(getAvmResult({ appClient }, 'verify_ufixednxm_from_bytes', value)).rejects.toThrowError(invalidBytesLengthError(32)) + ])( + 'sdk throws error when creating UFixedNxM<32,8> from bytes with invalid length', + async (value, { appClientArc4PrimitiveOpsContract: appClient }) => { + await expect(getAvmResult({ appClient }, 'verify_ufixednxm_from_bytes', value)).rejects.toThrowError(invalidBytesLengthError(32)) - const result = interpretAsArc4>(Bytes(value)) - expect(result.bytes).toEqual(value) - }) + const result = interpretAsArc4>(Bytes(value)) + expect(result.bytes).toEqual(value) + }, + ) - test.each([ + test.for([ [encodingUtil.bigIntToUint8Array(0n, 4), 0n], [encodingUtil.bigIntToUint8Array(255n, 4), 255n], [encodingUtil.bigIntToUint8Array(2n ** 16n, 4), 2n ** 16n], [encodingUtil.bigIntToUint8Array(2n ** 32n - 1n, 4), 2n ** 32n - 1n], - ])('create UFixedNxM<32,8> from abi log', async (value, expected) => { - const logValue = asUint8Array(ABI_RETURN_VALUE_LOG_PREFIX.concat(Bytes(value))) + ])('create UFixedNxM<32,8> from abi log', async ([value, expected], { appClientArc4PrimitiveOpsContract: appClient }) => { + const logValue = asUint8Array(ABI_RETURN_VALUE_LOG_PREFIX.concat(Bytes(value as Uint8Array))) const avmResult = await getAvmResult({ appClient }, 'verify_ufixednxm_from_log', logValue) const result = interpretAsArc4>(Bytes(logValue), 'log') @@ -93,59 +101,70 @@ describe('arc4.UFixedNxM', async () => { expect(result.native).toEqual(expected) }) - test.each([ + test.for([ [encodingUtil.bigIntToUint8Array(255n, 4), Bytes()], [encodingUtil.bigIntToUint8Array(255n, 4), Bytes.fromHex('FF000102')], - ])('should throw error when log prefix is invalid for UFixedNxM<32,8>', async (value, prefix) => { - const logValue = asUint8Array(Bytes(prefix).concat(Bytes(value))) - await expect(() => getAvmResult({ appClient }, 'verify_ufixednxm_from_log', logValue)).rejects.toThrowError('assert failed') - expect(() => interpretAsArc4>(Bytes(logValue), 'log')).toThrowError('ABI return prefix not found') - }) + ])( + 'should throw error when log prefix is invalid for UFixedNxM<32,8>', + async ([value, prefix], { appClientArc4PrimitiveOpsContract: appClient }) => { + const logValue = asUint8Array(Bytes(prefix as Uint8Array).concat(Bytes(value as bytes))) + await expect(() => getAvmResult({ appClient }, 'verify_ufixednxm_from_log', logValue)).rejects.toThrowError('has valid prefix') + expect(() => interpretAsArc4>(Bytes(logValue), 'log')).toThrowError('ABI return prefix not found') + }, + ) - test.each([ + test.for([ encodingUtil.bigIntToUint8Array(0n, 1), encodingUtil.bigIntToUint8Array(0n, 8), encodingUtil.bigIntToUint8Array(255n, 2), encodingUtil.bigIntToUint8Array(2n ** 32n - 1n, 8), - ])('sdk throws error when creating UFixedNxM<32,8> from log with invalid length', async (value) => { - const logValue = asUint8Array(ABI_RETURN_VALUE_LOG_PREFIX.concat(Bytes(value))) - await expect(() => getAvmResult({ appClient }, 'verify_ufixednxm_from_log', logValue)).rejects.toThrowError(invalidBytesLengthError(32)) + ])( + 'sdk throws error when creating UFixedNxM<32,8> from log with invalid length', + async (value, { appClientArc4PrimitiveOpsContract: appClient }) => { + const logValue = asUint8Array(ABI_RETURN_VALUE_LOG_PREFIX.concat(Bytes(value))) + await expect(() => getAvmResult({ appClient }, 'verify_ufixednxm_from_log', logValue)).rejects.toThrowError( + invalidBytesLengthError(32), + ) - const result = interpretAsArc4>(Bytes(logValue), 'log') - expect(result.native).toEqual(encodingUtil.uint8ArrayToBigInt(value)) - }) + const result = interpretAsArc4>(Bytes(logValue), 'log') + expect(result.native).toEqual(encodingUtil.uint8ArrayToBigInt(value)) + }, + ) - test.each([ + test.for([ encodingUtil.bigIntToUint8Array(0n, 32), encodingUtil.bigIntToUint8Array(255n, 32), encodingUtil.bigIntToUint8Array(2n ** 256n - 1n, 32), encodingUtil.bigIntToUint8Array(2n ** 256n - 1n), - ])('create UFixedNxM<256,16> from bytes', async (value) => { + ])('create UFixedNxM<256,16> from bytes', async (value, { appClientArc4PrimitiveOpsContract: appClient }) => { const avmResult = await getAvmResult({ appClient }, 'verify_bigufixednxm_from_bytes', value) const result = interpretAsArc4>(Bytes(value)) expect(result.native).toEqual(avmResult) }) - test.each([ + test.for([ encodingUtil.bigIntToUint8Array(0n, 16), encodingUtil.bigIntToUint8Array(0n, 40), encodingUtil.bigIntToUint8Array(2n ** 128n - 1n, 16), encodingUtil.bigIntToUint8Array(2n ** 256n - 1n, 40), - ])('sdk throws error when creating UFixedNxM<256,16> from bytes with invalid length', async (value) => { - await expect(getAvmResult({ appClient }, 'verify_bigufixednxm_from_bytes', value)).rejects.toThrowError(invalidBytesLengthError(256)) + ])( + 'sdk throws error when creating UFixedNxM<256,16> from bytes with invalid length', + async (value, { appClientArc4PrimitiveOpsContract: appClient }) => { + await expect(getAvmResult({ appClient }, 'verify_bigufixednxm_from_bytes', value)).rejects.toThrowError(invalidBytesLengthError(256)) - const result = interpretAsArc4>(Bytes(value)) - expect(result.bytes).toEqual(value) - }) + const result = interpretAsArc4>(Bytes(value)) + expect(result.bytes).toEqual(value) + }, + ) - test.each([ + test.for([ [encodingUtil.bigIntToUint8Array(0n, 32), 0n], [encodingUtil.bigIntToUint8Array(255n, 32), 255n], [encodingUtil.bigIntToUint8Array(2n ** 16n, 32), 2n ** 16n], [encodingUtil.bigIntToUint8Array(2n ** 256n - 1n, 32), 2n ** 256n - 1n], - ])('create UFixedNxM<256,16> from abi log', async (value, expected) => { - const logValue = asUint8Array(ABI_RETURN_VALUE_LOG_PREFIX.concat(Bytes(value))) + ])('create UFixedNxM<256,16> from abi log', async ([value, expected], { appClientArc4PrimitiveOpsContract: appClient }) => { + const logValue = asUint8Array(ABI_RETURN_VALUE_LOG_PREFIX.concat(Bytes(value as Uint8Array))) const avmResult = await getAvmResult({ appClient }, 'verify_bigufixednxm_from_log', logValue) const result = interpretAsArc4>(Bytes(logValue), 'log') @@ -153,27 +172,33 @@ describe('arc4.UFixedNxM', async () => { expect(result.native).toEqual(expected) }) - test.each([ + test.for([ [encodingUtil.bigIntToUint8Array(255n, 32), Bytes()], [encodingUtil.bigIntToUint8Array(255n, 32), Bytes.fromHex('FF000102')], - ])('should throw error when log prefix is invalid for UFixedNxM<256,16>', async (value, prefix) => { - const logValue = asUint8Array(Bytes(prefix).concat(Bytes(value))) - await expect(() => getAvmResult({ appClient }, 'verify_bigufixednxm_from_log', logValue)).rejects.toThrowError('assert failed') - expect(() => interpretAsArc4>(Bytes(logValue), 'log')).toThrowError('ABI return prefix not found') - }) + ])( + 'should throw error when log prefix is invalid for UFixedNxM<256,16>', + async ([value, prefix], { appClientArc4PrimitiveOpsContract: appClient }) => { + const logValue = asUint8Array(Bytes(prefix as Uint8Array).concat(Bytes(value as bytes))) + await expect(() => getAvmResult({ appClient }, 'verify_bigufixednxm_from_log', logValue)).rejects.toThrowError('has valid prefix') + expect(() => interpretAsArc4>(Bytes(logValue), 'log')).toThrowError('ABI return prefix not found') + }, + ) - test.each([ + test.for([ encodingUtil.bigIntToUint8Array(0n, 16), encodingUtil.bigIntToUint8Array(0n, 40), encodingUtil.bigIntToUint8Array(2n ** 128n - 1n, 16), encodingUtil.bigIntToUint8Array(2n ** 256n - 1n, 40), - ])('sdk throws error when creating UFixedNxM<256,16> from log with invalid length', async (value) => { - const logValue = asUint8Array(ABI_RETURN_VALUE_LOG_PREFIX.concat(Bytes(value))) - await expect(() => getAvmResult({ appClient }, 'verify_bigufixednxm_from_log', logValue)).rejects.toThrowError( - invalidBytesLengthError(256), - ) + ])( + 'sdk throws error when creating UFixedNxM<256,16> from log with invalid length', + async (value, { appClientArc4PrimitiveOpsContract: appClient }) => { + const logValue = asUint8Array(ABI_RETURN_VALUE_LOG_PREFIX.concat(Bytes(value))) + await expect(() => getAvmResult({ appClient }, 'verify_bigufixednxm_from_log', logValue)).rejects.toThrowError( + invalidBytesLengthError(256), + ) - const result = interpretAsArc4>(Bytes(logValue), 'log') - expect(result.native).toEqual(encodingUtil.uint8ArrayToBigInt(value)) - }) + const result = interpretAsArc4>(Bytes(logValue), 'log') + expect(result.native).toEqual(encodingUtil.uint8ArrayToBigInt(value)) + }, + ) }) diff --git a/tests/arc4/uintn.spec.ts b/tests/arc4/uintn.spec.ts index a4c41be..3653f1c 100644 --- a/tests/arc4/uintn.spec.ts +++ b/tests/arc4/uintn.spec.ts @@ -1,42 +1,54 @@ -import { AppSpec } from '@algorandfoundation/algokit-utils/types/app-spec' +import type { bytes } from '@algorandfoundation/algorand-typescript' import { Bytes } from '@algorandfoundation/algorand-typescript' import { TestExecutionContext } from '@algorandfoundation/algorand-typescript-testing' -import { BitSize, interpretAsArc4, UintN, UintN16, UintN256, UintN32, UintN64, UintN8 } from '@algorandfoundation/algorand-typescript/arc4' +import type { BitSize } from '@algorandfoundation/algorand-typescript/arc4' +import { interpretAsArc4, UintN, UintN16, UintN256, UintN32, UintN64, UintN8 } from '@algorandfoundation/algorand-typescript/arc4' import { encodingUtil } from '@algorandfoundation/puya-ts' -import { afterEach, describe, expect, it, test } from 'vitest' +import { afterEach, beforeAll, describe, expect } from 'vitest' import { ABI_RETURN_VALUE_LOG_PREFIX, MAX_UINT512, MAX_UINT64 } from '../../src/constants' import { asBigUintCls, asUint8Array } from '../../src/util' -import appSpecJson from '../artifacts/arc4-primitive-ops/data/Arc4PrimitiveOpsContract.arc32.json' -import { getAlgorandAppClient, getAvmResult } from '../avm-invoker' +import { getAvmResult } from '../avm-invoker' +import { createArc4TestFixture } from '../test-fixture' const invalidBytesLengthError = (length: number) => `byte string must correspond to a uint${length}` describe('arc4.UintN', async () => { - const appClient = await getAlgorandAppClient(appSpecJson as AppSpec) + const [test, localnetFixture] = createArc4TestFixture('tests/artifacts/arc4-primitive-ops/contract.algo.ts', { + Arc4PrimitiveOpsContract: { deployParams: { createParams: { extraProgramPages: undefined } } }, + }) const ctx = new TestExecutionContext() - afterEach(async () => { + beforeAll(async () => { + await localnetFixture.newScope() + }) + afterEach(() => { ctx.reset() }) - test.each([2 ** 32, MAX_UINT64])('instantiation should throw error as %s would overflow 32 bits', async (value) => { - const bytesValue = asBigUintCls(value).toBytes() + test.for([2 ** 32, MAX_UINT64])( + 'instantiation should throw error as %s would overflow 32 bits', + async (value, { appClientArc4PrimitiveOpsContract: appClient }) => { + const bytesValue = asBigUintCls(value).toBytes() - await expect(getAvmResult({ appClient }, 'verify_uintn_init', asUint8Array(bytesValue))).rejects.toThrowError() - expect(() => new UintN32(value)).toThrowError(`expected value <= ${2 ** 32 - 1}`) - }) + await expect(getAvmResult({ appClient }, 'verify_uintn_init', asUint8Array(bytesValue))).rejects.toThrowError() + expect(() => new UintN32(value)).toThrowError(`expected value <= ${2 ** 32 - 1}`) + }, + ) - test.each([2 ** 256, MAX_UINT512])('instantiation should throw error as %s would overflow 256 bits', async (value) => { - const bytesValue = asBigUintCls(value).toBytes() + test.for([2 ** 256, MAX_UINT512])( + 'instantiation should throw error as %s would overflow 256 bits', + async (value, { appClientArc4PrimitiveOpsContract: appClient }) => { + const bytesValue = asBigUintCls(value).toBytes() - await expect(getAvmResult({ appClient }, 'verify_biguintn_init', asUint8Array(bytesValue))).rejects.toThrowError() - expect(() => new UintN256(value)).toThrowError(`expected value <= ${2 ** 256 - 1}`) - }) + await expect(getAvmResult({ appClient }, 'verify_biguintn_init', asUint8Array(bytesValue))).rejects.toThrowError() + expect(() => new UintN256(value)).toThrowError(`expected value <= ${2 ** 256 - 1}`) + }, + ) - test.each([ + test.for([ [0, 0], [255, 255], [2 ** 32 - 1, 2 ** 32 - 1], - ])('instantiating UintN<32> should work for %s', async (value, expected) => { + ])('instantiating UintN<32> should work for %s', async ([value, expected], { appClientArc4PrimitiveOpsContract: appClient }) => { const bytesValue = asBigUintCls(value).toBytes() const avmResult = await getAvmResult({ appClient }, 'verify_uintn_init', asUint8Array(bytesValue)) @@ -46,13 +58,13 @@ describe('arc4.UintN', async () => { expect(avmResult).toEqual(expected) }) - test.each([ + test.for([ [0, 0], [255, 255], [MAX_UINT64, MAX_UINT64], [2 ** 128, 2 ** 128], [2 ** 256 - 1, 2 ** 256 - 1], - ])('instantiating UintN<256> should work for %s', async (value, expected) => { + ])('instantiating UintN<256> should work for %s', async ([value, expected], { appClientArc4PrimitiveOpsContract: appClient }) => { const bytesValue = asBigUintCls(value).toBytes() const avmResult = await getAvmResult({ appClient }, 'verify_biguintn_init', asUint8Array(bytesValue)) @@ -62,7 +74,7 @@ describe('arc4.UintN', async () => { expect(avmResult).toEqual(BigInt(expected)) }) - test.each([0, 1, 255])('should be able to get bytes representation of %s', async (value) => { + test.for([0, 1, 255])('should be able to get bytes representation of %s', async (value) => { expect(new UintN8(value).bytes).toEqual(encodingUtil.bigIntToUint8Array(BigInt(value), 1)) expect(new UintN16(value).bytes).toEqual(encodingUtil.bigIntToUint8Array(BigInt(value), 2)) expect(new UintN64(value).bytes).toEqual(encodingUtil.bigIntToUint8Array(BigInt(value), 8)) @@ -118,7 +130,7 @@ describe('arc4.UintN', async () => { throw new Error(`Unknown operator: ${op}`) } } - it(`${a} ${operator} ${b}`, async () => { + test(`${a} ${operator} ${b}`, async ({ appClientArc4PrimitiveOpsContract: appClient }) => { const aType = a <= MAX_UINT64 ? 'uintn' : 'biguintn' const bType = b <= MAX_UINT64 ? 'uintn' : 'biguintn' const bytesValueA = asBigUintCls(a).toBytes() @@ -139,24 +151,24 @@ describe('arc4.UintN', async () => { }) }) - test.each([ + test.for([ [MAX_UINT64, MAX_UINT512], [0, MAX_UINT512], [1, MAX_UINT512], - ])('should throw error when comparing UinN with different bit sizes', async (a, b) => { + ])('should throw error when comparing UinN with different bit sizes', async ([a, b]) => { const encodedA = a <= MAX_UINT64 ? new UintN<64>(a) : new UintN<512>(a) const encodedB = b <= MAX_UINT64 ? new UintN<64>(b) : new UintN<512>(b) expect(() => encodedA === encodedB).toThrowError(/Expected expression of type UintN<\d+>, got UintN<\d+>/) expect(() => encodedA !== encodedB).toThrowError(/Expected expression of type UintN<\d+>, got UintN<\d+>/) }) - test.each([ + test.for([ encodingUtil.bigIntToUint8Array(0n, 4), encodingUtil.bigIntToUint8Array(255n, 4), encodingUtil.bigIntToUint8Array(2n ** 16n, 4), encodingUtil.bigIntToUint8Array(2n ** 32n - 1n, 4), encodingUtil.bigIntToUint8Array(2n ** 32n - 1n), - ])('create UintN<32> from bytes', async (value) => { + ])('create UintN<32> from bytes', async (value, { appClientArc4PrimitiveOpsContract: appClient }) => { const avmResult = await getAvmResult({ appClient }, 'verify_uintn_from_bytes', value) const result = interpretAsArc4(Bytes(value)) @@ -164,49 +176,55 @@ describe('arc4.UintN', async () => { expect(result.native).toEqual(avmResult) }) - test.each([ + test.for([ encodingUtil.bigIntToUint8Array(0n, 1), encodingUtil.bigIntToUint8Array(0n, 8), encodingUtil.bigIntToUint8Array(255n, 2), encodingUtil.bigIntToUint8Array(2n ** 32n - 1n, 8), - ])('sdk throws error when creating UintN<32> from bytes with invalid length', async (value) => { - await expect(getAvmResult({ appClient }, 'verify_uintn_from_bytes', value)).rejects.toThrowError(invalidBytesLengthError(32)) + ])( + 'sdk throws error when creating UintN<32> from bytes with invalid length', + async (value, { appClientArc4PrimitiveOpsContract: appClient }) => { + await expect(getAvmResult({ appClient }, 'verify_uintn_from_bytes', value)).rejects.toThrowError(invalidBytesLengthError(32)) - const result = interpretAsArc4(Bytes(value)) - expect(result.native).toEqual(encodingUtil.uint8ArrayToBigInt(value)) - }) + const result = interpretAsArc4(Bytes(value)) + expect(result.native).toEqual(encodingUtil.uint8ArrayToBigInt(value)) + }, + ) - test.each([ + test.for([ encodingUtil.bigIntToUint8Array(0n, 32), encodingUtil.bigIntToUint8Array(255n, 32), encodingUtil.bigIntToUint8Array(2n ** 256n - 1n, 32), encodingUtil.bigIntToUint8Array(2n ** 256n - 1n), - ])('create UintN<256> from bytes', async (value) => { + ])('create UintN<256> from bytes', async (value, { appClientArc4PrimitiveOpsContract: appClient }) => { const avmResult = await getAvmResult({ appClient }, 'verify_biguintn_from_bytes', value) const result = interpretAsArc4(Bytes(value)) expect(result.native).toEqual(avmResult) }) - test.each([ + test.for([ encodingUtil.bigIntToUint8Array(0n, 16), encodingUtil.bigIntToUint8Array(0n, 40), encodingUtil.bigIntToUint8Array(2n ** 128n - 1n, 16), encodingUtil.bigIntToUint8Array(2n ** 256n - 1n, 40), - ])('sdk throws error when creating UintN<256> from bytes with invalid length', async (value) => { - await expect(getAvmResult({ appClient }, 'verify_biguintn_from_bytes', value)).rejects.toThrowError(invalidBytesLengthError(256)) + ])( + 'sdk throws error when creating UintN<256> from bytes with invalid length', + async (value, { appClientArc4PrimitiveOpsContract: appClient }) => { + await expect(getAvmResult({ appClient }, 'verify_biguintn_from_bytes', value)).rejects.toThrowError(invalidBytesLengthError(256)) - const result = interpretAsArc4(Bytes(value)) - expect(result.native).toEqual(encodingUtil.uint8ArrayToBigInt(value)) - }) + const result = interpretAsArc4(Bytes(value)) + expect(result.native).toEqual(encodingUtil.uint8ArrayToBigInt(value)) + }, + ) - test.each([ + test.for([ [encodingUtil.bigIntToUint8Array(0n, 4), 0n], [encodingUtil.bigIntToUint8Array(255n, 4), 255n], [encodingUtil.bigIntToUint8Array(2n ** 16n, 4), 2n ** 16n], [encodingUtil.bigIntToUint8Array(2n ** 32n - 1n, 4), 2n ** 32n - 1n], - ])('create UintN<32> from abi log', async (value, expected) => { - const logValue = asUint8Array(ABI_RETURN_VALUE_LOG_PREFIX.concat(Bytes(value))) + ])('create UintN<32> from abi log', async ([value, expected], { appClientArc4PrimitiveOpsContract: appClient }) => { + const logValue = asUint8Array(ABI_RETURN_VALUE_LOG_PREFIX.concat(Bytes(value as Uint8Array))) const avmResult = await getAvmResult({ appClient }, 'verify_uintn_from_log', logValue) const result = interpretAsArc4>(Bytes(logValue), 'log') @@ -214,35 +232,41 @@ describe('arc4.UintN', async () => { expect(result.native).toEqual(expected) }) - test.each([ + test.for([ [encodingUtil.bigIntToUint8Array(255n, 4), Bytes()], [encodingUtil.bigIntToUint8Array(255n, 4), Bytes.fromHex('FF000102')], - ])('should throw error when log prefix is invalid for UintN<32>', async (value, prefix) => { - const logValue = asUint8Array(Bytes(prefix).concat(Bytes(value))) - await expect(() => getAvmResult({ appClient }, 'verify_uintn_from_log', logValue)).rejects.toThrowError('assert failed') - expect(() => interpretAsArc4>(Bytes(logValue), 'log')).toThrowError('ABI return prefix not found') - }) - - test.each([ + ])( + 'should throw error when log prefix is invalid for UintN<32>', + async ([value, prefix], { appClientArc4PrimitiveOpsContract: appClient }) => { + const logValue = asUint8Array(Bytes(prefix as Uint8Array).concat(Bytes(value as bytes))) + await expect(() => getAvmResult({ appClient }, 'verify_uintn_from_log', logValue)).rejects.toThrowError('has valid prefix') + expect(() => interpretAsArc4>(Bytes(logValue), 'log')).toThrowError('ABI return prefix not found') + }, + ) + + test.for([ encodingUtil.bigIntToUint8Array(0n, 1), encodingUtil.bigIntToUint8Array(0n, 8), encodingUtil.bigIntToUint8Array(255n, 2), encodingUtil.bigIntToUint8Array(2n ** 32n - 1n, 8), - ])('sdk throws error when creating UintN<32> from log with invalid length', async (value) => { - const logValue = asUint8Array(ABI_RETURN_VALUE_LOG_PREFIX.concat(Bytes(value))) - await expect(() => getAvmResult({ appClient }, 'verify_uintn_from_log', logValue)).rejects.toThrowError(invalidBytesLengthError(32)) - - const result = interpretAsArc4>(Bytes(logValue), 'log') - expect(result.native).toEqual(encodingUtil.uint8ArrayToBigInt(value)) - }) - - test.each([ + ])( + 'sdk throws error when creating UintN<32> from log with invalid length', + async (value, { appClientArc4PrimitiveOpsContract: appClient }) => { + const logValue = asUint8Array(ABI_RETURN_VALUE_LOG_PREFIX.concat(Bytes(value))) + await expect(() => getAvmResult({ appClient }, 'verify_uintn_from_log', logValue)).rejects.toThrowError(invalidBytesLengthError(32)) + + const result = interpretAsArc4>(Bytes(logValue), 'log') + expect(result.native).toEqual(encodingUtil.uint8ArrayToBigInt(value)) + }, + ) + + test.for([ [encodingUtil.bigIntToUint8Array(0n, 32), 0n], [encodingUtil.bigIntToUint8Array(255n, 32), 255n], [encodingUtil.bigIntToUint8Array(2n ** 16n, 32), 2n ** 16n], [encodingUtil.bigIntToUint8Array(2n ** 256n - 1n, 32), 2n ** 256n - 1n], - ])('create UintN<256> from abi log', async (value, expected) => { - const logValue = asUint8Array(ABI_RETURN_VALUE_LOG_PREFIX.concat(Bytes(value))) + ])('create UintN<256> from abi log', async ([value, expected], { appClientArc4PrimitiveOpsContract: appClient }) => { + const logValue = asUint8Array(ABI_RETURN_VALUE_LOG_PREFIX.concat(Bytes(value as Uint8Array))) const avmResult = await getAvmResult({ appClient }, 'verify_biguintn_from_log', logValue) const result = interpretAsArc4>(Bytes(logValue), 'log') @@ -250,25 +274,33 @@ describe('arc4.UintN', async () => { expect(result.native).toEqual(expected) }) - test.each([ + test.for([ [encodingUtil.bigIntToUint8Array(255n, 32), Bytes()], [encodingUtil.bigIntToUint8Array(255n, 32), Bytes.fromHex('FF000102')], - ])('should throw error when log prefix is invalid for UintN<256>', async (value, prefix) => { - const logValue = asUint8Array(Bytes(prefix).concat(Bytes(value))) - await expect(() => getAvmResult({ appClient }, 'verify_biguintn_from_log', logValue)).rejects.toThrowError('assert failed') - expect(() => interpretAsArc4>(Bytes(logValue), 'log')).toThrowError('ABI return prefix not found') - }) - - test.each([ + ])( + 'should throw error when log prefix is invalid for UintN<256>', + async ([value, prefix], { appClientArc4PrimitiveOpsContract: appClient }) => { + const logValue = asUint8Array(Bytes(prefix as Uint8Array).concat(Bytes(value as bytes))) + await expect(() => getAvmResult({ appClient }, 'verify_biguintn_from_log', logValue)).rejects.toThrowError('has valid prefix') + expect(() => interpretAsArc4>(Bytes(logValue), 'log')).toThrowError('ABI return prefix not found') + }, + ) + + test.for([ encodingUtil.bigIntToUint8Array(0n, 16), encodingUtil.bigIntToUint8Array(0n, 40), encodingUtil.bigIntToUint8Array(2n ** 128n - 1n, 16), encodingUtil.bigIntToUint8Array(2n ** 256n - 1n, 40), - ])('sdk throws error when creating UintN<256> from log with invalid length', async (value) => { - const logValue = asUint8Array(ABI_RETURN_VALUE_LOG_PREFIX.concat(Bytes(value))) - await expect(() => getAvmResult({ appClient }, 'verify_biguintn_from_log', logValue)).rejects.toThrowError(invalidBytesLengthError(256)) - - const result = interpretAsArc4>(Bytes(logValue), 'log') - expect(result.native).toEqual(encodingUtil.uint8ArrayToBigInt(value)) - }) + ])( + 'sdk throws error when creating UintN<256> from log with invalid length', + async (value, { appClientArc4PrimitiveOpsContract: appClient }) => { + const logValue = asUint8Array(ABI_RETURN_VALUE_LOG_PREFIX.concat(Bytes(value))) + await expect(() => getAvmResult({ appClient }, 'verify_biguintn_from_log', logValue)).rejects.toThrowError( + invalidBytesLengthError(256), + ) + + const result = interpretAsArc4>(Bytes(logValue), 'log') + expect(result.native).toEqual(encodingUtil.uint8ArrayToBigInt(value)) + }, + ) }) diff --git a/tests/artifacts/arc4-abi-method/contract.algo.ts b/tests/artifacts/arc4-abi-method/contract.algo.ts new file mode 100644 index 0000000..f5532b2 --- /dev/null +++ b/tests/artifacts/arc4-abi-method/contract.algo.ts @@ -0,0 +1,104 @@ +type UInt8Array = arc4.DynamicArray +type MyAlias = arc4.UintN<128> + +import type { Account, Application, Asset } from '@algorandfoundation/algorand-typescript' +import { arc4, assert, gtxn, op, Txn } from '@algorandfoundation/algorand-typescript' + +export class AnotherStruct extends arc4.Struct<{ + one: arc4.UintN64 + two: arc4.Str +}> {} + +type MyStructAlias = AnotherStruct + +export class MyStruct extends arc4.Struct<{ + anotherStruct: AnotherStruct + anotherStructAlias: MyStructAlias + three: arc4.UintN128 + four: MyAlias +}> {} + +export class SignaturesContract extends arc4.Contract { + @arc4.abimethod({ onCreate: 'require' }) + create() { + const appTxn = gtxn.ApplicationTxn(0) + assert(op.Global.currentApplicationId.id !== 0, 'expected global to have app id') + assert(op.Global.currentApplicationAddress !== op.Global.zeroAddress, 'expected global to have app address') + assert(appTxn.appId.id === 0, 'expected txn to have 0') + assert(Txn.applicationId.id === 0, 'expected txn to have 0') + } + + @arc4.abimethod() + sink(value: arc4.Str, arr: UInt8Array) { + assert(value.native) + assert(arr.length) + } + + @arc4.abimethod({ name: 'alias' }) + sink2(value: arc4.Str, arr: UInt8Array) { + assert(value.native) + assert(arr.length) + } + + @arc4.abimethod() + withTxn(value: arc4.Str, pay: gtxn.PaymentTxn, arr: UInt8Array) { + assert(value.native) + assert(arr.length) + assert(pay.groupIndex === 0) + assert(Txn.groupIndex === 1) + assert(pay.amount === 123) + } + + @arc4.abimethod() + withAsset(value: arc4.Str, asset: Asset, arr: UInt8Array) { + assert(value.native) + assert(arr.length) + assert(asset.total === 123) + assert(Txn.assets(0) === asset) + } + + @arc4.abimethod() + withApp(value: arc4.Str, app: Application, appId: arc4.UintN64, arr: UInt8Array) { + assert(value.native) + assert(arr.length) + assert(app.id === appId.native, 'expected app id to match provided app id') + assert(app.creator === op.Global.creatorAddress, 'expected other app to have same creator') + const appTxn = gtxn.ApplicationTxn(0) + assert(appTxn.apps(0) === op.Global.currentApplicationId) + assert(Txn.applications(0) === op.Global.currentApplicationId) + assert(appTxn.apps(1) === app) + assert(Txn.applications(1) === app) + } + + @arc4.abimethod() + withAcc(value: arc4.Str, acc: Account, arr: UInt8Array) { + assert(value.native) + assert(arr.length) + assert(acc.balance === acc.minBalance + 1234) + assert(Txn.accounts(0) === Txn.sender) + assert(Txn.accounts(1) === acc) + } + + @arc4.abimethod() + complexSig(struct1: MyStruct, txn: gtxn.PaymentTxn, acc: Account, five: UInt8Array): readonly [MyStructAlias, MyStruct] { + assert(Txn.numAppArgs === 4) + + // struct + assert(struct1.anotherStruct.one.native === 1) + assert(struct1.anotherStruct.two.native === '2') + assert(struct1.anotherStructAlias.one.native === 1) + assert(struct1.anotherStructAlias.two.native === '2') + assert(struct1.three.native === 3n) + assert(struct1.four.native === 4n) + + // txn + assert(txn.groupIndex === Txn.groupIndex - 1) + + // acc + assert(Txn.applicationArgs(2) === new arc4.UintN8(1).bytes) // acc array ref + assert(acc.balance === acc.minBalance + 1234) + assert(five[0].native === 5) + + return [struct1.anotherStruct.copy(), struct1.copy()] + } +} diff --git a/tests/artifacts/arc4-primitive-ops/contract.algo.ts b/tests/artifacts/arc4-primitive-ops/contract.algo.ts index 7e49aec..7922b5d 100644 --- a/tests/artifacts/arc4-primitive-ops/contract.algo.ts +++ b/tests/artifacts/arc4-primitive-ops/contract.algo.ts @@ -1,5 +1,7 @@ -import { arc4, BigUint, bytes, emit } from '@algorandfoundation/algorand-typescript' -import { Bool, Byte, Contract, interpretAsArc4, Str, UFixedNxM, UintN } from '@algorandfoundation/algorand-typescript/arc4' +import type { bytes } from '@algorandfoundation/algorand-typescript' +import { arc4, BigUint, emit } from '@algorandfoundation/algorand-typescript' +import type { Bool, UFixedNxM } from '@algorandfoundation/algorand-typescript/arc4' +import { Byte, Contract, interpretAsArc4, Str, UintN } from '@algorandfoundation/algorand-typescript/arc4' export class Arc4PrimitiveOpsContract extends Contract { @arc4.abimethod() diff --git a/tests/artifacts/arc4-primitive-ops/data/Arc4PrimitiveOpsContract.approval.teal b/tests/artifacts/arc4-primitive-ops/data/Arc4PrimitiveOpsContract.approval.teal deleted file mode 100644 index 7711262..0000000 --- a/tests/artifacts/arc4-primitive-ops/data/Arc4PrimitiveOpsContract.approval.teal +++ /dev/null @@ -1,2965 +0,0 @@ -#pragma version 10 -#pragma typetrack false - -// @algorandfoundation/algorand-typescript/arc4/index.d.ts::Contract.approvalProgram() -> uint64: -main: - intcblock 1 8 64 0 - bytecblock 0x151f7c75 0x00 - // tests/artifacts/arc4-primitive-ops/contract.algo.ts:4 - // export class Arc4PrimitiveOpsContract extends Contract { - txn NumAppArgs - bz main_bare_routing@60 - pushbytess 0x96f14116 0xed666096 0x2ca0352b 0x85907d40 0x4eb2af4a 0x2cbec45b 0x07666fd9 0x370babd3 0x2b6b3ef0 0x27e21a98 0x339da97c 0x7898ed97 0x1f130cec 0xc748664e 0xa2bac14b 0x7a460cb1 0xdcab1f01 0x97d9064d 0xce06c2a0 0x7c11e375 0xdcdbcee0 0x77a4b68d 0x4f540626 0x095aed41 0xdf78cdc6 0xe3b7e918 0x55337008 0x9bb1cd66 0x81484d9d 0x79e9cb03 0x9a03df10 0xd3f0e44b 0x673db2bd 0x982db233 0xaffbdf0e 0x8e4a30f7 0x288af76e 0x8bd84a04 0xfcd55e1f 0x0f1574fe 0xb2cb13be 0xd059eea7 0x4cc4c157 0x3d17ac6e 0xf7f3d5fc 0xf8c8f8d5 0x43f7162a 0x42e09075 0xd956f575 0x6c0160df 0xa890150b 0x0b2f4c3f 0x9db9d327 0xe4d950a1 0xb605e80c // method "verify_uintn_uintn_eq(byte[],byte[])bool", method "verify_biguintn_uintn_eq(byte[],byte[])bool", method "verify_uintn_biguintn_eq(byte[],byte[])bool", method "verify_biguintn_biguintn_eq(byte[],byte[])bool", method "verify_byte_byte_eq(byte[],byte[])bool", method "verify_uintn_uintn_ne(byte[],byte[])bool", method "verify_biguintn_uintn_ne(byte[],byte[])bool", method "verify_uintn_biguintn_ne(byte[],byte[])bool", method "verify_biguintn_biguintn_ne(byte[],byte[])bool", method "verify_byte_byte_ne(byte[],byte[])bool", method "verify_uintn_uintn_lt(byte[],byte[])bool", method "verify_biguintn_uintn_lt(byte[],byte[])bool", method "verify_uintn_biguintn_lt(byte[],byte[])bool", method "verify_biguintn_biguintn_lt(byte[],byte[])bool", method "verify_byte_byte_lt(byte[],byte[])bool", method "verify_uintn_uintn_le(byte[],byte[])bool", method "verify_biguintn_uintn_le(byte[],byte[])bool", method "verify_uintn_biguintn_le(byte[],byte[])bool", method "verify_biguintn_biguintn_le(byte[],byte[])bool", method "verify_byte_byte_le(byte[],byte[])bool", method "verify_uintn_uintn_gt(byte[],byte[])bool", method "verify_biguintn_uintn_gt(byte[],byte[])bool", method "verify_uintn_biguintn_gt(byte[],byte[])bool", method "verify_biguintn_biguintn_gt(byte[],byte[])bool", method "verify_byte_byte_gt(byte[],byte[])bool", method "verify_uintn_uintn_ge(byte[],byte[])bool", method "verify_biguintn_uintn_ge(byte[],byte[])bool", method "verify_uintn_biguintn_ge(byte[],byte[])bool", method "verify_biguintn_biguintn_ge(byte[],byte[])bool", method "verify_byte_byte_ge(byte[],byte[])bool", method "verify_uintn_init(byte[])uint32", method "verify_biguintn_init(byte[])uint256", method "verify_byte_init(byte[])byte", method "verify_uintn_from_bytes(byte[])uint32", method "verify_biguintn_from_bytes(byte[])uint256", method "verify_byte_from_bytes(byte[])byte", method "verify_uintn_from_log(byte[])uint32", method "verify_biguintn_from_log(byte[])uint256", method "verify_byte_from_log(byte[])byte", method "verify_ufixednxm_bytes(ufixed32x8)byte[]", method "verify_bigufixednxm_bytes(ufixed256x16)byte[]", method "verify_ufixednxm_from_bytes(byte[])ufixed32x8", method "verify_bigufixednxm_from_bytes(byte[])ufixed256x16", method "verify_ufixednxm_from_log(byte[])ufixed32x8", method "verify_bigufixednxm_from_log(byte[])ufixed256x16", method "verify_string_init(string)string", method "verify_string_add(string,string)string", method "verify_string_eq(string,string)bool", method "verify_string_bytes(string)byte[]", method "verify_string_from_bytes(byte[])string", method "verify_string_from_log(byte[])string", method "verify_bool_bytes(bool)byte[]", method "verify_bool_from_bytes(byte[])bool", method "verify_bool_from_log(byte[])bool", method "verify_emit(string,uint512,uint64,byte[],uint64,bool,byte[],string,uint64,uint256,ufixed32x8,ufixed256x16,bool,byte[],byte[],byte[])void" - txna ApplicationArgs 0 - match main_verify_uintn_uintn_eq_route@3 main_verify_biguintn_uintn_eq_route@4 main_verify_uintn_biguintn_eq_route@5 main_verify_biguintn_biguintn_eq_route@6 main_verify_byte_byte_eq_route@7 main_verify_uintn_uintn_ne_route@8 main_verify_biguintn_uintn_ne_route@9 main_verify_uintn_biguintn_ne_route@10 main_verify_biguintn_biguintn_ne_route@11 main_verify_byte_byte_ne_route@12 main_verify_uintn_uintn_lt_route@13 main_verify_biguintn_uintn_lt_route@14 main_verify_uintn_biguintn_lt_route@15 main_verify_biguintn_biguintn_lt_route@16 main_verify_byte_byte_lt_route@17 main_verify_uintn_uintn_le_route@18 main_verify_biguintn_uintn_le_route@19 main_verify_uintn_biguintn_le_route@20 main_verify_biguintn_biguintn_le_route@21 main_verify_byte_byte_le_route@22 main_verify_uintn_uintn_gt_route@23 main_verify_biguintn_uintn_gt_route@24 main_verify_uintn_biguintn_gt_route@25 main_verify_biguintn_biguintn_gt_route@26 main_verify_byte_byte_gt_route@27 main_verify_uintn_uintn_ge_route@28 main_verify_biguintn_uintn_ge_route@29 main_verify_uintn_biguintn_ge_route@30 main_verify_biguintn_biguintn_ge_route@31 main_verify_byte_byte_ge_route@32 main_verify_uintn_init_route@33 main_verify_biguintn_init_route@34 main_verify_byte_init_route@35 main_verify_uintn_from_bytes_route@36 main_verify_biguintn_from_bytes_route@37 main_verify_byte_from_bytes_route@38 main_verify_uintn_from_log_route@39 main_verify_biguintn_from_log_route@40 main_verify_byte_from_log_route@41 main_verify_ufixednxm_bytes_route@42 main_verify_bigufixednxm_bytes_route@43 main_verify_ufixednxm_from_bytes_route@44 main_verify_bigufixednxm_from_bytes_route@45 main_verify_ufixednxm_from_log_route@46 main_verify_bigufixednxm_from_log_route@47 main_verify_string_init_route@48 main_verify_string_add_route@49 main_verify_string_eq_route@50 main_verify_string_bytes_route@51 main_verify_string_from_bytes_route@52 main_verify_string_from_log_route@53 main_verify_bool_bytes_route@54 main_verify_bool_from_bytes_route@55 main_verify_bool_from_log_route@56 main_verify_emit_route@57 - -main_after_if_else@64: - // tests/artifacts/arc4-primitive-ops/contract.algo.ts:4 - // export class Arc4PrimitiveOpsContract extends Contract { - intc_3 // 0 - return - -main_verify_emit_route@57: - // tests/artifacts/arc4-primitive-ops/contract.algo.ts:349 - // @arc4.abimethod() - txn OnCompletion - ! - assert // OnCompletion is not NoOp - txn ApplicationID - assert // can only call when not creating - // tests/artifacts/arc4-primitive-ops/contract.algo.ts:4 - // export class Arc4PrimitiveOpsContract extends Contract { - txna ApplicationArgs 1 - txna ApplicationArgs 2 - txna ApplicationArgs 3 - txna ApplicationArgs 4 - txna ApplicationArgs 5 - txna ApplicationArgs 6 - txna ApplicationArgs 7 - txna ApplicationArgs 8 - txna ApplicationArgs 9 - txna ApplicationArgs 10 - txna ApplicationArgs 11 - txna ApplicationArgs 12 - txna ApplicationArgs 13 - txna ApplicationArgs 14 - extract 2 0 - txna ApplicationArgs 15 - dup - intc_3 // 0 - extract_uint16 - dig 1 - pushint 2 // 2 - extract_uint16 - substring3 - extract 2 0 - txna ApplicationArgs 15 - dup - pushint 2 // 2 - extract_uint16 - dig 1 - len - substring3 - extract 2 0 - // tests/artifacts/arc4-primitive-ops/contract.algo.ts:349 - // @arc4.abimethod() - callsub verify_emit - intc_0 // 1 - return - -main_verify_bool_from_log_route@56: - // tests/artifacts/arc4-primitive-ops/contract.algo.ts:343 - // @arc4.abimethod() - txn OnCompletion - ! - assert // OnCompletion is not NoOp - txn ApplicationID - assert // can only call when not creating - // tests/artifacts/arc4-primitive-ops/contract.algo.ts:4 - // export class Arc4PrimitiveOpsContract extends Contract { - txna ApplicationArgs 1 - extract 2 0 - // tests/artifacts/arc4-primitive-ops/contract.algo.ts:343 - // @arc4.abimethod() - callsub verify_bool_from_log - bytec_0 // 0x151f7c75 - swap - concat - log - intc_0 // 1 - return - -main_verify_bool_from_bytes_route@55: - // tests/artifacts/arc4-primitive-ops/contract.algo.ts:339 - // @arc4.abimethod() - txn OnCompletion - ! - assert // OnCompletion is not NoOp - txn ApplicationID - assert // can only call when not creating - // tests/artifacts/arc4-primitive-ops/contract.algo.ts:4 - // export class Arc4PrimitiveOpsContract extends Contract { - txna ApplicationArgs 1 - extract 2 0 - // tests/artifacts/arc4-primitive-ops/contract.algo.ts:339 - // @arc4.abimethod() - bytec_0 // 0x151f7c75 - swap - concat - log - intc_0 // 1 - return - -main_verify_bool_bytes_route@54: - // tests/artifacts/arc4-primitive-ops/contract.algo.ts:335 - // @arc4.abimethod() - txn OnCompletion - ! - assert // OnCompletion is not NoOp - txn ApplicationID - assert // can only call when not creating - // tests/artifacts/arc4-primitive-ops/contract.algo.ts:4 - // export class Arc4PrimitiveOpsContract extends Contract { - txna ApplicationArgs 1 - // tests/artifacts/arc4-primitive-ops/contract.algo.ts:335 - // @arc4.abimethod() - dup - len - itob - extract 6 2 - swap - concat - bytec_0 // 0x151f7c75 - swap - concat - log - intc_0 // 1 - return - -main_verify_string_from_log_route@53: - // tests/artifacts/arc4-primitive-ops/contract.algo.ts:331 - // @arc4.abimethod() - txn OnCompletion - ! - assert // OnCompletion is not NoOp - txn ApplicationID - assert // can only call when not creating - // tests/artifacts/arc4-primitive-ops/contract.algo.ts:4 - // export class Arc4PrimitiveOpsContract extends Contract { - txna ApplicationArgs 1 - extract 2 0 - // tests/artifacts/arc4-primitive-ops/contract.algo.ts:331 - // @arc4.abimethod() - callsub verify_string_from_log - bytec_0 // 0x151f7c75 - swap - concat - log - intc_0 // 1 - return - -main_verify_string_from_bytes_route@52: - // tests/artifacts/arc4-primitive-ops/contract.algo.ts:327 - // @arc4.abimethod() - txn OnCompletion - ! - assert // OnCompletion is not NoOp - txn ApplicationID - assert // can only call when not creating - // tests/artifacts/arc4-primitive-ops/contract.algo.ts:4 - // export class Arc4PrimitiveOpsContract extends Contract { - txna ApplicationArgs 1 - extract 2 0 - // tests/artifacts/arc4-primitive-ops/contract.algo.ts:327 - // @arc4.abimethod() - bytec_0 // 0x151f7c75 - swap - concat - log - intc_0 // 1 - return - -main_verify_string_bytes_route@51: - // tests/artifacts/arc4-primitive-ops/contract.algo.ts:322 - // @arc4.abimethod() - txn OnCompletion - ! - assert // OnCompletion is not NoOp - txn ApplicationID - assert // can only call when not creating - // tests/artifacts/arc4-primitive-ops/contract.algo.ts:4 - // export class Arc4PrimitiveOpsContract extends Contract { - txna ApplicationArgs 1 - extract 2 0 - // tests/artifacts/arc4-primitive-ops/contract.algo.ts:322 - // @arc4.abimethod() - callsub verify_string_bytes - dup - len - itob - extract 6 2 - swap - concat - bytec_0 // 0x151f7c75 - swap - concat - log - intc_0 // 1 - return - -main_verify_string_eq_route@50: - // tests/artifacts/arc4-primitive-ops/contract.algo.ts:318 - // @arc4.abimethod() - txn OnCompletion - ! - assert // OnCompletion is not NoOp - txn ApplicationID - assert // can only call when not creating - // tests/artifacts/arc4-primitive-ops/contract.algo.ts:4 - // export class Arc4PrimitiveOpsContract extends Contract { - txna ApplicationArgs 1 - txna ApplicationArgs 2 - // tests/artifacts/arc4-primitive-ops/contract.algo.ts:318 - // @arc4.abimethod() - callsub verify_string_eq - bytec_1 // 0x00 - intc_3 // 0 - uncover 2 - setbit - bytec_0 // 0x151f7c75 - swap - concat - log - intc_0 // 1 - return - -main_verify_string_add_route@49: - // tests/artifacts/arc4-primitive-ops/contract.algo.ts:313 - // @arc4.abimethod() - txn OnCompletion - ! - assert // OnCompletion is not NoOp - txn ApplicationID - assert // can only call when not creating - // tests/artifacts/arc4-primitive-ops/contract.algo.ts:4 - // export class Arc4PrimitiveOpsContract extends Contract { - txna ApplicationArgs 1 - txna ApplicationArgs 2 - // tests/artifacts/arc4-primitive-ops/contract.algo.ts:313 - // @arc4.abimethod() - callsub verify_string_add - bytec_0 // 0x151f7c75 - swap - concat - log - intc_0 // 1 - return - -main_verify_string_init_route@48: - // tests/artifacts/arc4-primitive-ops/contract.algo.ts:308 - // @arc4.abimethod() - txn OnCompletion - ! - assert // OnCompletion is not NoOp - txn ApplicationID - assert // can only call when not creating - // tests/artifacts/arc4-primitive-ops/contract.algo.ts:4 - // export class Arc4PrimitiveOpsContract extends Contract { - txna ApplicationArgs 1 - extract 2 0 - // tests/artifacts/arc4-primitive-ops/contract.algo.ts:308 - // @arc4.abimethod() - callsub verify_string_init - bytec_0 // 0x151f7c75 - swap - concat - log - intc_0 // 1 - return - -main_verify_bigufixednxm_from_log_route@47: - // tests/artifacts/arc4-primitive-ops/contract.algo.ts:304 - // @arc4.abimethod() - txn OnCompletion - ! - assert // OnCompletion is not NoOp - txn ApplicationID - assert // can only call when not creating - // tests/artifacts/arc4-primitive-ops/contract.algo.ts:4 - // export class Arc4PrimitiveOpsContract extends Contract { - txna ApplicationArgs 1 - extract 2 0 - // tests/artifacts/arc4-primitive-ops/contract.algo.ts:304 - // @arc4.abimethod() - callsub verify_bigufixednxm_from_log - bytec_0 // 0x151f7c75 - swap - concat - log - intc_0 // 1 - return - -main_verify_ufixednxm_from_log_route@46: - // tests/artifacts/arc4-primitive-ops/contract.algo.ts:300 - // @arc4.abimethod() - txn OnCompletion - ! - assert // OnCompletion is not NoOp - txn ApplicationID - assert // can only call when not creating - // tests/artifacts/arc4-primitive-ops/contract.algo.ts:4 - // export class Arc4PrimitiveOpsContract extends Contract { - txna ApplicationArgs 1 - extract 2 0 - // tests/artifacts/arc4-primitive-ops/contract.algo.ts:300 - // @arc4.abimethod() - callsub verify_ufixednxm_from_log - bytec_0 // 0x151f7c75 - swap - concat - log - intc_0 // 1 - return - -main_verify_bigufixednxm_from_bytes_route@45: - // tests/artifacts/arc4-primitive-ops/contract.algo.ts:296 - // @arc4.abimethod() - txn OnCompletion - ! - assert // OnCompletion is not NoOp - txn ApplicationID - assert // can only call when not creating - // tests/artifacts/arc4-primitive-ops/contract.algo.ts:4 - // export class Arc4PrimitiveOpsContract extends Contract { - txna ApplicationArgs 1 - extract 2 0 - // tests/artifacts/arc4-primitive-ops/contract.algo.ts:296 - // @arc4.abimethod() - bytec_0 // 0x151f7c75 - swap - concat - log - intc_0 // 1 - return - -main_verify_ufixednxm_from_bytes_route@44: - // tests/artifacts/arc4-primitive-ops/contract.algo.ts:292 - // @arc4.abimethod() - txn OnCompletion - ! - assert // OnCompletion is not NoOp - txn ApplicationID - assert // can only call when not creating - // tests/artifacts/arc4-primitive-ops/contract.algo.ts:4 - // export class Arc4PrimitiveOpsContract extends Contract { - txna ApplicationArgs 1 - extract 2 0 - // tests/artifacts/arc4-primitive-ops/contract.algo.ts:292 - // @arc4.abimethod() - bytec_0 // 0x151f7c75 - swap - concat - log - intc_0 // 1 - return - -main_verify_bigufixednxm_bytes_route@43: - // tests/artifacts/arc4-primitive-ops/contract.algo.ts:288 - // @arc4.abimethod() - txn OnCompletion - ! - assert // OnCompletion is not NoOp - txn ApplicationID - assert // can only call when not creating - // tests/artifacts/arc4-primitive-ops/contract.algo.ts:4 - // export class Arc4PrimitiveOpsContract extends Contract { - txna ApplicationArgs 1 - // tests/artifacts/arc4-primitive-ops/contract.algo.ts:288 - // @arc4.abimethod() - dup - len - itob - extract 6 2 - swap - concat - bytec_0 // 0x151f7c75 - swap - concat - log - intc_0 // 1 - return - -main_verify_ufixednxm_bytes_route@42: - // tests/artifacts/arc4-primitive-ops/contract.algo.ts:284 - // @arc4.abimethod() - txn OnCompletion - ! - assert // OnCompletion is not NoOp - txn ApplicationID - assert // can only call when not creating - // tests/artifacts/arc4-primitive-ops/contract.algo.ts:4 - // export class Arc4PrimitiveOpsContract extends Contract { - txna ApplicationArgs 1 - // tests/artifacts/arc4-primitive-ops/contract.algo.ts:284 - // @arc4.abimethod() - dup - len - itob - extract 6 2 - swap - concat - bytec_0 // 0x151f7c75 - swap - concat - log - intc_0 // 1 - return - -main_verify_byte_from_log_route@41: - // tests/artifacts/arc4-primitive-ops/contract.algo.ts:280 - // @arc4.abimethod() - txn OnCompletion - ! - assert // OnCompletion is not NoOp - txn ApplicationID - assert // can only call when not creating - // tests/artifacts/arc4-primitive-ops/contract.algo.ts:4 - // export class Arc4PrimitiveOpsContract extends Contract { - txna ApplicationArgs 1 - extract 2 0 - // tests/artifacts/arc4-primitive-ops/contract.algo.ts:280 - // @arc4.abimethod() - callsub verify_byte_from_log - bytec_0 // 0x151f7c75 - swap - concat - log - intc_0 // 1 - return - -main_verify_biguintn_from_log_route@40: - // tests/artifacts/arc4-primitive-ops/contract.algo.ts:276 - // @arc4.abimethod() - txn OnCompletion - ! - assert // OnCompletion is not NoOp - txn ApplicationID - assert // can only call when not creating - // tests/artifacts/arc4-primitive-ops/contract.algo.ts:4 - // export class Arc4PrimitiveOpsContract extends Contract { - txna ApplicationArgs 1 - extract 2 0 - // tests/artifacts/arc4-primitive-ops/contract.algo.ts:276 - // @arc4.abimethod() - callsub verify_biguintn_from_log - bytec_0 // 0x151f7c75 - swap - concat - log - intc_0 // 1 - return - -main_verify_uintn_from_log_route@39: - // tests/artifacts/arc4-primitive-ops/contract.algo.ts:272 - // @arc4.abimethod() - txn OnCompletion - ! - assert // OnCompletion is not NoOp - txn ApplicationID - assert // can only call when not creating - // tests/artifacts/arc4-primitive-ops/contract.algo.ts:4 - // export class Arc4PrimitiveOpsContract extends Contract { - txna ApplicationArgs 1 - extract 2 0 - // tests/artifacts/arc4-primitive-ops/contract.algo.ts:272 - // @arc4.abimethod() - callsub verify_uintn_from_log - bytec_0 // 0x151f7c75 - swap - concat - log - intc_0 // 1 - return - -main_verify_byte_from_bytes_route@38: - // tests/artifacts/arc4-primitive-ops/contract.algo.ts:268 - // @arc4.abimethod() - txn OnCompletion - ! - assert // OnCompletion is not NoOp - txn ApplicationID - assert // can only call when not creating - // tests/artifacts/arc4-primitive-ops/contract.algo.ts:4 - // export class Arc4PrimitiveOpsContract extends Contract { - txna ApplicationArgs 1 - extract 2 0 - // tests/artifacts/arc4-primitive-ops/contract.algo.ts:268 - // @arc4.abimethod() - bytec_0 // 0x151f7c75 - swap - concat - log - intc_0 // 1 - return - -main_verify_biguintn_from_bytes_route@37: - // tests/artifacts/arc4-primitive-ops/contract.algo.ts:264 - // @arc4.abimethod() - txn OnCompletion - ! - assert // OnCompletion is not NoOp - txn ApplicationID - assert // can only call when not creating - // tests/artifacts/arc4-primitive-ops/contract.algo.ts:4 - // export class Arc4PrimitiveOpsContract extends Contract { - txna ApplicationArgs 1 - extract 2 0 - // tests/artifacts/arc4-primitive-ops/contract.algo.ts:264 - // @arc4.abimethod() - bytec_0 // 0x151f7c75 - swap - concat - log - intc_0 // 1 - return - -main_verify_uintn_from_bytes_route@36: - // tests/artifacts/arc4-primitive-ops/contract.algo.ts:260 - // @arc4.abimethod() - txn OnCompletion - ! - assert // OnCompletion is not NoOp - txn ApplicationID - assert // can only call when not creating - // tests/artifacts/arc4-primitive-ops/contract.algo.ts:4 - // export class Arc4PrimitiveOpsContract extends Contract { - txna ApplicationArgs 1 - extract 2 0 - // tests/artifacts/arc4-primitive-ops/contract.algo.ts:260 - // @arc4.abimethod() - bytec_0 // 0x151f7c75 - swap - concat - log - intc_0 // 1 - return - -main_verify_byte_init_route@35: - // tests/artifacts/arc4-primitive-ops/contract.algo.ts:255 - // @arc4.abimethod() - txn OnCompletion - ! - assert // OnCompletion is not NoOp - txn ApplicationID - assert // can only call when not creating - // tests/artifacts/arc4-primitive-ops/contract.algo.ts:4 - // export class Arc4PrimitiveOpsContract extends Contract { - txna ApplicationArgs 1 - extract 2 0 - // tests/artifacts/arc4-primitive-ops/contract.algo.ts:255 - // @arc4.abimethod() - callsub verify_byte_init - bytec_0 // 0x151f7c75 - swap - concat - log - intc_0 // 1 - return - -main_verify_biguintn_init_route@34: - // tests/artifacts/arc4-primitive-ops/contract.algo.ts:250 - // @arc4.abimethod() - txn OnCompletion - ! - assert // OnCompletion is not NoOp - txn ApplicationID - assert // can only call when not creating - // tests/artifacts/arc4-primitive-ops/contract.algo.ts:4 - // export class Arc4PrimitiveOpsContract extends Contract { - txna ApplicationArgs 1 - extract 2 0 - // tests/artifacts/arc4-primitive-ops/contract.algo.ts:250 - // @arc4.abimethod() - callsub verify_biguintn_init - bytec_0 // 0x151f7c75 - swap - concat - log - intc_0 // 1 - return - -main_verify_uintn_init_route@33: - // tests/artifacts/arc4-primitive-ops/contract.algo.ts:245 - // @arc4.abimethod() - txn OnCompletion - ! - assert // OnCompletion is not NoOp - txn ApplicationID - assert // can only call when not creating - // tests/artifacts/arc4-primitive-ops/contract.algo.ts:4 - // export class Arc4PrimitiveOpsContract extends Contract { - txna ApplicationArgs 1 - extract 2 0 - // tests/artifacts/arc4-primitive-ops/contract.algo.ts:245 - // @arc4.abimethod() - callsub verify_uintn_init - bytec_0 // 0x151f7c75 - swap - concat - log - intc_0 // 1 - return - -main_verify_byte_byte_ge_route@32: - // tests/artifacts/arc4-primitive-ops/contract.algo.ts:237 - // @arc4.abimethod() - txn OnCompletion - ! - assert // OnCompletion is not NoOp - txn ApplicationID - assert // can only call when not creating - // tests/artifacts/arc4-primitive-ops/contract.algo.ts:4 - // export class Arc4PrimitiveOpsContract extends Contract { - txna ApplicationArgs 1 - extract 2 0 - txna ApplicationArgs 2 - extract 2 0 - // tests/artifacts/arc4-primitive-ops/contract.algo.ts:237 - // @arc4.abimethod() - callsub verify_byte_byte_ge - bytec_1 // 0x00 - intc_3 // 0 - uncover 2 - setbit - bytec_0 // 0x151f7c75 - swap - concat - log - intc_0 // 1 - return - -main_verify_biguintn_biguintn_ge_route@31: - // tests/artifacts/arc4-primitive-ops/contract.algo.ts:229 - // @arc4.abimethod() - txn OnCompletion - ! - assert // OnCompletion is not NoOp - txn ApplicationID - assert // can only call when not creating - // tests/artifacts/arc4-primitive-ops/contract.algo.ts:4 - // export class Arc4PrimitiveOpsContract extends Contract { - txna ApplicationArgs 1 - extract 2 0 - txna ApplicationArgs 2 - extract 2 0 - // tests/artifacts/arc4-primitive-ops/contract.algo.ts:229 - // @arc4.abimethod() - callsub verify_biguintn_biguintn_ge - bytec_1 // 0x00 - intc_3 // 0 - uncover 2 - setbit - bytec_0 // 0x151f7c75 - swap - concat - log - intc_0 // 1 - return - -main_verify_uintn_biguintn_ge_route@30: - // tests/artifacts/arc4-primitive-ops/contract.algo.ts:221 - // @arc4.abimethod() - txn OnCompletion - ! - assert // OnCompletion is not NoOp - txn ApplicationID - assert // can only call when not creating - // tests/artifacts/arc4-primitive-ops/contract.algo.ts:4 - // export class Arc4PrimitiveOpsContract extends Contract { - txna ApplicationArgs 1 - extract 2 0 - txna ApplicationArgs 2 - extract 2 0 - // tests/artifacts/arc4-primitive-ops/contract.algo.ts:221 - // @arc4.abimethod() - callsub verify_uintn_biguintn_ge - bytec_1 // 0x00 - intc_3 // 0 - uncover 2 - setbit - bytec_0 // 0x151f7c75 - swap - concat - log - intc_0 // 1 - return - -main_verify_biguintn_uintn_ge_route@29: - // tests/artifacts/arc4-primitive-ops/contract.algo.ts:213 - // @arc4.abimethod() - txn OnCompletion - ! - assert // OnCompletion is not NoOp - txn ApplicationID - assert // can only call when not creating - // tests/artifacts/arc4-primitive-ops/contract.algo.ts:4 - // export class Arc4PrimitiveOpsContract extends Contract { - txna ApplicationArgs 1 - extract 2 0 - txna ApplicationArgs 2 - extract 2 0 - // tests/artifacts/arc4-primitive-ops/contract.algo.ts:213 - // @arc4.abimethod() - callsub verify_biguintn_uintn_ge - bytec_1 // 0x00 - intc_3 // 0 - uncover 2 - setbit - bytec_0 // 0x151f7c75 - swap - concat - log - intc_0 // 1 - return - -main_verify_uintn_uintn_ge_route@28: - // tests/artifacts/arc4-primitive-ops/contract.algo.ts:205 - // @arc4.abimethod() - txn OnCompletion - ! - assert // OnCompletion is not NoOp - txn ApplicationID - assert // can only call when not creating - // tests/artifacts/arc4-primitive-ops/contract.algo.ts:4 - // export class Arc4PrimitiveOpsContract extends Contract { - txna ApplicationArgs 1 - extract 2 0 - txna ApplicationArgs 2 - extract 2 0 - // tests/artifacts/arc4-primitive-ops/contract.algo.ts:205 - // @arc4.abimethod() - callsub verify_uintn_uintn_ge - bytec_1 // 0x00 - intc_3 // 0 - uncover 2 - setbit - bytec_0 // 0x151f7c75 - swap - concat - log - intc_0 // 1 - return - -main_verify_byte_byte_gt_route@27: - // tests/artifacts/arc4-primitive-ops/contract.algo.ts:197 - // @arc4.abimethod() - txn OnCompletion - ! - assert // OnCompletion is not NoOp - txn ApplicationID - assert // can only call when not creating - // tests/artifacts/arc4-primitive-ops/contract.algo.ts:4 - // export class Arc4PrimitiveOpsContract extends Contract { - txna ApplicationArgs 1 - extract 2 0 - txna ApplicationArgs 2 - extract 2 0 - // tests/artifacts/arc4-primitive-ops/contract.algo.ts:197 - // @arc4.abimethod() - callsub verify_byte_byte_gt - bytec_1 // 0x00 - intc_3 // 0 - uncover 2 - setbit - bytec_0 // 0x151f7c75 - swap - concat - log - intc_0 // 1 - return - -main_verify_biguintn_biguintn_gt_route@26: - // tests/artifacts/arc4-primitive-ops/contract.algo.ts:189 - // @arc4.abimethod() - txn OnCompletion - ! - assert // OnCompletion is not NoOp - txn ApplicationID - assert // can only call when not creating - // tests/artifacts/arc4-primitive-ops/contract.algo.ts:4 - // export class Arc4PrimitiveOpsContract extends Contract { - txna ApplicationArgs 1 - extract 2 0 - txna ApplicationArgs 2 - extract 2 0 - // tests/artifacts/arc4-primitive-ops/contract.algo.ts:189 - // @arc4.abimethod() - callsub verify_biguintn_biguintn_gt - bytec_1 // 0x00 - intc_3 // 0 - uncover 2 - setbit - bytec_0 // 0x151f7c75 - swap - concat - log - intc_0 // 1 - return - -main_verify_uintn_biguintn_gt_route@25: - // tests/artifacts/arc4-primitive-ops/contract.algo.ts:181 - // @arc4.abimethod() - txn OnCompletion - ! - assert // OnCompletion is not NoOp - txn ApplicationID - assert // can only call when not creating - // tests/artifacts/arc4-primitive-ops/contract.algo.ts:4 - // export class Arc4PrimitiveOpsContract extends Contract { - txna ApplicationArgs 1 - extract 2 0 - txna ApplicationArgs 2 - extract 2 0 - // tests/artifacts/arc4-primitive-ops/contract.algo.ts:181 - // @arc4.abimethod() - callsub verify_uintn_biguintn_gt - bytec_1 // 0x00 - intc_3 // 0 - uncover 2 - setbit - bytec_0 // 0x151f7c75 - swap - concat - log - intc_0 // 1 - return - -main_verify_biguintn_uintn_gt_route@24: - // tests/artifacts/arc4-primitive-ops/contract.algo.ts:173 - // @arc4.abimethod() - txn OnCompletion - ! - assert // OnCompletion is not NoOp - txn ApplicationID - assert // can only call when not creating - // tests/artifacts/arc4-primitive-ops/contract.algo.ts:4 - // export class Arc4PrimitiveOpsContract extends Contract { - txna ApplicationArgs 1 - extract 2 0 - txna ApplicationArgs 2 - extract 2 0 - // tests/artifacts/arc4-primitive-ops/contract.algo.ts:173 - // @arc4.abimethod() - callsub verify_biguintn_uintn_gt - bytec_1 // 0x00 - intc_3 // 0 - uncover 2 - setbit - bytec_0 // 0x151f7c75 - swap - concat - log - intc_0 // 1 - return - -main_verify_uintn_uintn_gt_route@23: - // tests/artifacts/arc4-primitive-ops/contract.algo.ts:165 - // @arc4.abimethod() - txn OnCompletion - ! - assert // OnCompletion is not NoOp - txn ApplicationID - assert // can only call when not creating - // tests/artifacts/arc4-primitive-ops/contract.algo.ts:4 - // export class Arc4PrimitiveOpsContract extends Contract { - txna ApplicationArgs 1 - extract 2 0 - txna ApplicationArgs 2 - extract 2 0 - // tests/artifacts/arc4-primitive-ops/contract.algo.ts:165 - // @arc4.abimethod() - callsub verify_uintn_uintn_gt - bytec_1 // 0x00 - intc_3 // 0 - uncover 2 - setbit - bytec_0 // 0x151f7c75 - swap - concat - log - intc_0 // 1 - return - -main_verify_byte_byte_le_route@22: - // tests/artifacts/arc4-primitive-ops/contract.algo.ts:157 - // @arc4.abimethod() - txn OnCompletion - ! - assert // OnCompletion is not NoOp - txn ApplicationID - assert // can only call when not creating - // tests/artifacts/arc4-primitive-ops/contract.algo.ts:4 - // export class Arc4PrimitiveOpsContract extends Contract { - txna ApplicationArgs 1 - extract 2 0 - txna ApplicationArgs 2 - extract 2 0 - // tests/artifacts/arc4-primitive-ops/contract.algo.ts:157 - // @arc4.abimethod() - callsub verify_byte_byte_le - bytec_1 // 0x00 - intc_3 // 0 - uncover 2 - setbit - bytec_0 // 0x151f7c75 - swap - concat - log - intc_0 // 1 - return - -main_verify_biguintn_biguintn_le_route@21: - // tests/artifacts/arc4-primitive-ops/contract.algo.ts:149 - // @arc4.abimethod() - txn OnCompletion - ! - assert // OnCompletion is not NoOp - txn ApplicationID - assert // can only call when not creating - // tests/artifacts/arc4-primitive-ops/contract.algo.ts:4 - // export class Arc4PrimitiveOpsContract extends Contract { - txna ApplicationArgs 1 - extract 2 0 - txna ApplicationArgs 2 - extract 2 0 - // tests/artifacts/arc4-primitive-ops/contract.algo.ts:149 - // @arc4.abimethod() - callsub verify_biguintn_biguintn_le - bytec_1 // 0x00 - intc_3 // 0 - uncover 2 - setbit - bytec_0 // 0x151f7c75 - swap - concat - log - intc_0 // 1 - return - -main_verify_uintn_biguintn_le_route@20: - // tests/artifacts/arc4-primitive-ops/contract.algo.ts:141 - // @arc4.abimethod() - txn OnCompletion - ! - assert // OnCompletion is not NoOp - txn ApplicationID - assert // can only call when not creating - // tests/artifacts/arc4-primitive-ops/contract.algo.ts:4 - // export class Arc4PrimitiveOpsContract extends Contract { - txna ApplicationArgs 1 - extract 2 0 - txna ApplicationArgs 2 - extract 2 0 - // tests/artifacts/arc4-primitive-ops/contract.algo.ts:141 - // @arc4.abimethod() - callsub verify_uintn_biguintn_le - bytec_1 // 0x00 - intc_3 // 0 - uncover 2 - setbit - bytec_0 // 0x151f7c75 - swap - concat - log - intc_0 // 1 - return - -main_verify_biguintn_uintn_le_route@19: - // tests/artifacts/arc4-primitive-ops/contract.algo.ts:133 - // @arc4.abimethod() - txn OnCompletion - ! - assert // OnCompletion is not NoOp - txn ApplicationID - assert // can only call when not creating - // tests/artifacts/arc4-primitive-ops/contract.algo.ts:4 - // export class Arc4PrimitiveOpsContract extends Contract { - txna ApplicationArgs 1 - extract 2 0 - txna ApplicationArgs 2 - extract 2 0 - // tests/artifacts/arc4-primitive-ops/contract.algo.ts:133 - // @arc4.abimethod() - callsub verify_biguintn_uintn_le - bytec_1 // 0x00 - intc_3 // 0 - uncover 2 - setbit - bytec_0 // 0x151f7c75 - swap - concat - log - intc_0 // 1 - return - -main_verify_uintn_uintn_le_route@18: - // tests/artifacts/arc4-primitive-ops/contract.algo.ts:125 - // @arc4.abimethod() - txn OnCompletion - ! - assert // OnCompletion is not NoOp - txn ApplicationID - assert // can only call when not creating - // tests/artifacts/arc4-primitive-ops/contract.algo.ts:4 - // export class Arc4PrimitiveOpsContract extends Contract { - txna ApplicationArgs 1 - extract 2 0 - txna ApplicationArgs 2 - extract 2 0 - // tests/artifacts/arc4-primitive-ops/contract.algo.ts:125 - // @arc4.abimethod() - callsub verify_uintn_uintn_le - bytec_1 // 0x00 - intc_3 // 0 - uncover 2 - setbit - bytec_0 // 0x151f7c75 - swap - concat - log - intc_0 // 1 - return - -main_verify_byte_byte_lt_route@17: - // tests/artifacts/arc4-primitive-ops/contract.algo.ts:117 - // @arc4.abimethod() - txn OnCompletion - ! - assert // OnCompletion is not NoOp - txn ApplicationID - assert // can only call when not creating - // tests/artifacts/arc4-primitive-ops/contract.algo.ts:4 - // export class Arc4PrimitiveOpsContract extends Contract { - txna ApplicationArgs 1 - extract 2 0 - txna ApplicationArgs 2 - extract 2 0 - // tests/artifacts/arc4-primitive-ops/contract.algo.ts:117 - // @arc4.abimethod() - callsub verify_byte_byte_lt - bytec_1 // 0x00 - intc_3 // 0 - uncover 2 - setbit - bytec_0 // 0x151f7c75 - swap - concat - log - intc_0 // 1 - return - -main_verify_biguintn_biguintn_lt_route@16: - // tests/artifacts/arc4-primitive-ops/contract.algo.ts:109 - // @arc4.abimethod() - txn OnCompletion - ! - assert // OnCompletion is not NoOp - txn ApplicationID - assert // can only call when not creating - // tests/artifacts/arc4-primitive-ops/contract.algo.ts:4 - // export class Arc4PrimitiveOpsContract extends Contract { - txna ApplicationArgs 1 - extract 2 0 - txna ApplicationArgs 2 - extract 2 0 - // tests/artifacts/arc4-primitive-ops/contract.algo.ts:109 - // @arc4.abimethod() - callsub verify_biguintn_biguintn_lt - bytec_1 // 0x00 - intc_3 // 0 - uncover 2 - setbit - bytec_0 // 0x151f7c75 - swap - concat - log - intc_0 // 1 - return - -main_verify_uintn_biguintn_lt_route@15: - // tests/artifacts/arc4-primitive-ops/contract.algo.ts:101 - // @arc4.abimethod() - txn OnCompletion - ! - assert // OnCompletion is not NoOp - txn ApplicationID - assert // can only call when not creating - // tests/artifacts/arc4-primitive-ops/contract.algo.ts:4 - // export class Arc4PrimitiveOpsContract extends Contract { - txna ApplicationArgs 1 - extract 2 0 - txna ApplicationArgs 2 - extract 2 0 - // tests/artifacts/arc4-primitive-ops/contract.algo.ts:101 - // @arc4.abimethod() - callsub verify_uintn_biguintn_lt - bytec_1 // 0x00 - intc_3 // 0 - uncover 2 - setbit - bytec_0 // 0x151f7c75 - swap - concat - log - intc_0 // 1 - return - -main_verify_biguintn_uintn_lt_route@14: - // tests/artifacts/arc4-primitive-ops/contract.algo.ts:93 - // @arc4.abimethod() - txn OnCompletion - ! - assert // OnCompletion is not NoOp - txn ApplicationID - assert // can only call when not creating - // tests/artifacts/arc4-primitive-ops/contract.algo.ts:4 - // export class Arc4PrimitiveOpsContract extends Contract { - txna ApplicationArgs 1 - extract 2 0 - txna ApplicationArgs 2 - extract 2 0 - // tests/artifacts/arc4-primitive-ops/contract.algo.ts:93 - // @arc4.abimethod() - callsub verify_biguintn_uintn_lt - bytec_1 // 0x00 - intc_3 // 0 - uncover 2 - setbit - bytec_0 // 0x151f7c75 - swap - concat - log - intc_0 // 1 - return - -main_verify_uintn_uintn_lt_route@13: - // tests/artifacts/arc4-primitive-ops/contract.algo.ts:85 - // @arc4.abimethod() - txn OnCompletion - ! - assert // OnCompletion is not NoOp - txn ApplicationID - assert // can only call when not creating - // tests/artifacts/arc4-primitive-ops/contract.algo.ts:4 - // export class Arc4PrimitiveOpsContract extends Contract { - txna ApplicationArgs 1 - extract 2 0 - txna ApplicationArgs 2 - extract 2 0 - // tests/artifacts/arc4-primitive-ops/contract.algo.ts:85 - // @arc4.abimethod() - callsub verify_uintn_uintn_lt - bytec_1 // 0x00 - intc_3 // 0 - uncover 2 - setbit - bytec_0 // 0x151f7c75 - swap - concat - log - intc_0 // 1 - return - -main_verify_byte_byte_ne_route@12: - // tests/artifacts/arc4-primitive-ops/contract.algo.ts:77 - // @arc4.abimethod() - txn OnCompletion - ! - assert // OnCompletion is not NoOp - txn ApplicationID - assert // can only call when not creating - // tests/artifacts/arc4-primitive-ops/contract.algo.ts:4 - // export class Arc4PrimitiveOpsContract extends Contract { - txna ApplicationArgs 1 - extract 2 0 - txna ApplicationArgs 2 - extract 2 0 - // tests/artifacts/arc4-primitive-ops/contract.algo.ts:77 - // @arc4.abimethod() - callsub verify_byte_byte_ne - bytec_1 // 0x00 - intc_3 // 0 - uncover 2 - setbit - bytec_0 // 0x151f7c75 - swap - concat - log - intc_0 // 1 - return - -main_verify_biguintn_biguintn_ne_route@11: - // tests/artifacts/arc4-primitive-ops/contract.algo.ts:69 - // @arc4.abimethod() - txn OnCompletion - ! - assert // OnCompletion is not NoOp - txn ApplicationID - assert // can only call when not creating - // tests/artifacts/arc4-primitive-ops/contract.algo.ts:4 - // export class Arc4PrimitiveOpsContract extends Contract { - txna ApplicationArgs 1 - extract 2 0 - txna ApplicationArgs 2 - extract 2 0 - // tests/artifacts/arc4-primitive-ops/contract.algo.ts:69 - // @arc4.abimethod() - callsub verify_biguintn_biguintn_ne - bytec_1 // 0x00 - intc_3 // 0 - uncover 2 - setbit - bytec_0 // 0x151f7c75 - swap - concat - log - intc_0 // 1 - return - -main_verify_uintn_biguintn_ne_route@10: - // tests/artifacts/arc4-primitive-ops/contract.algo.ts:61 - // @arc4.abimethod() - txn OnCompletion - ! - assert // OnCompletion is not NoOp - txn ApplicationID - assert // can only call when not creating - // tests/artifacts/arc4-primitive-ops/contract.algo.ts:4 - // export class Arc4PrimitiveOpsContract extends Contract { - txna ApplicationArgs 1 - extract 2 0 - txna ApplicationArgs 2 - extract 2 0 - // tests/artifacts/arc4-primitive-ops/contract.algo.ts:61 - // @arc4.abimethod() - callsub verify_uintn_biguintn_ne - bytec_1 // 0x00 - intc_3 // 0 - uncover 2 - setbit - bytec_0 // 0x151f7c75 - swap - concat - log - intc_0 // 1 - return - -main_verify_biguintn_uintn_ne_route@9: - // tests/artifacts/arc4-primitive-ops/contract.algo.ts:53 - // @arc4.abimethod() - txn OnCompletion - ! - assert // OnCompletion is not NoOp - txn ApplicationID - assert // can only call when not creating - // tests/artifacts/arc4-primitive-ops/contract.algo.ts:4 - // export class Arc4PrimitiveOpsContract extends Contract { - txna ApplicationArgs 1 - extract 2 0 - txna ApplicationArgs 2 - extract 2 0 - // tests/artifacts/arc4-primitive-ops/contract.algo.ts:53 - // @arc4.abimethod() - callsub verify_biguintn_uintn_ne - bytec_1 // 0x00 - intc_3 // 0 - uncover 2 - setbit - bytec_0 // 0x151f7c75 - swap - concat - log - intc_0 // 1 - return - -main_verify_uintn_uintn_ne_route@8: - // tests/artifacts/arc4-primitive-ops/contract.algo.ts:45 - // @arc4.abimethod() - txn OnCompletion - ! - assert // OnCompletion is not NoOp - txn ApplicationID - assert // can only call when not creating - // tests/artifacts/arc4-primitive-ops/contract.algo.ts:4 - // export class Arc4PrimitiveOpsContract extends Contract { - txna ApplicationArgs 1 - extract 2 0 - txna ApplicationArgs 2 - extract 2 0 - // tests/artifacts/arc4-primitive-ops/contract.algo.ts:45 - // @arc4.abimethod() - callsub verify_uintn_uintn_ne - bytec_1 // 0x00 - intc_3 // 0 - uncover 2 - setbit - bytec_0 // 0x151f7c75 - swap - concat - log - intc_0 // 1 - return - -main_verify_byte_byte_eq_route@7: - // tests/artifacts/arc4-primitive-ops/contract.algo.ts:37 - // @arc4.abimethod() - txn OnCompletion - ! - assert // OnCompletion is not NoOp - txn ApplicationID - assert // can only call when not creating - // tests/artifacts/arc4-primitive-ops/contract.algo.ts:4 - // export class Arc4PrimitiveOpsContract extends Contract { - txna ApplicationArgs 1 - extract 2 0 - txna ApplicationArgs 2 - extract 2 0 - // tests/artifacts/arc4-primitive-ops/contract.algo.ts:37 - // @arc4.abimethod() - callsub verify_byte_byte_eq - bytec_1 // 0x00 - intc_3 // 0 - uncover 2 - setbit - bytec_0 // 0x151f7c75 - swap - concat - log - intc_0 // 1 - return - -main_verify_biguintn_biguintn_eq_route@6: - // tests/artifacts/arc4-primitive-ops/contract.algo.ts:29 - // @arc4.abimethod() - txn OnCompletion - ! - assert // OnCompletion is not NoOp - txn ApplicationID - assert // can only call when not creating - // tests/artifacts/arc4-primitive-ops/contract.algo.ts:4 - // export class Arc4PrimitiveOpsContract extends Contract { - txna ApplicationArgs 1 - extract 2 0 - txna ApplicationArgs 2 - extract 2 0 - // tests/artifacts/arc4-primitive-ops/contract.algo.ts:29 - // @arc4.abimethod() - callsub verify_biguintn_biguintn_eq - bytec_1 // 0x00 - intc_3 // 0 - uncover 2 - setbit - bytec_0 // 0x151f7c75 - swap - concat - log - intc_0 // 1 - return - -main_verify_uintn_biguintn_eq_route@5: - // tests/artifacts/arc4-primitive-ops/contract.algo.ts:21 - // @arc4.abimethod() - txn OnCompletion - ! - assert // OnCompletion is not NoOp - txn ApplicationID - assert // can only call when not creating - // tests/artifacts/arc4-primitive-ops/contract.algo.ts:4 - // export class Arc4PrimitiveOpsContract extends Contract { - txna ApplicationArgs 1 - extract 2 0 - txna ApplicationArgs 2 - extract 2 0 - // tests/artifacts/arc4-primitive-ops/contract.algo.ts:21 - // @arc4.abimethod() - callsub verify_uintn_biguintn_eq - bytec_1 // 0x00 - intc_3 // 0 - uncover 2 - setbit - bytec_0 // 0x151f7c75 - swap - concat - log - intc_0 // 1 - return - -main_verify_biguintn_uintn_eq_route@4: - // tests/artifacts/arc4-primitive-ops/contract.algo.ts:13 - // @arc4.abimethod() - txn OnCompletion - ! - assert // OnCompletion is not NoOp - txn ApplicationID - assert // can only call when not creating - // tests/artifacts/arc4-primitive-ops/contract.algo.ts:4 - // export class Arc4PrimitiveOpsContract extends Contract { - txna ApplicationArgs 1 - extract 2 0 - txna ApplicationArgs 2 - extract 2 0 - // tests/artifacts/arc4-primitive-ops/contract.algo.ts:13 - // @arc4.abimethod() - callsub verify_biguintn_uintn_eq - bytec_1 // 0x00 - intc_3 // 0 - uncover 2 - setbit - bytec_0 // 0x151f7c75 - swap - concat - log - intc_0 // 1 - return - -main_verify_uintn_uintn_eq_route@3: - // tests/artifacts/arc4-primitive-ops/contract.algo.ts:5 - // @arc4.abimethod() - txn OnCompletion - ! - assert // OnCompletion is not NoOp - txn ApplicationID - assert // can only call when not creating - // tests/artifacts/arc4-primitive-ops/contract.algo.ts:4 - // export class Arc4PrimitiveOpsContract extends Contract { - txna ApplicationArgs 1 - extract 2 0 - txna ApplicationArgs 2 - extract 2 0 - // tests/artifacts/arc4-primitive-ops/contract.algo.ts:5 - // @arc4.abimethod() - callsub verify_uintn_uintn_eq - bytec_1 // 0x00 - intc_3 // 0 - uncover 2 - setbit - bytec_0 // 0x151f7c75 - swap - concat - log - intc_0 // 1 - return - -main_bare_routing@60: - // tests/artifacts/arc4-primitive-ops/contract.algo.ts:4 - // export class Arc4PrimitiveOpsContract extends Contract { - txn OnCompletion - bnz main_after_if_else@64 - txn ApplicationID - ! - assert // can only call when creating - intc_0 // 1 - return - - -// tests/artifacts/arc4-primitive-ops/contract.algo.ts::Arc4PrimitiveOpsContract.verify_uintn_uintn_eq(a: bytes, b: bytes) -> uint64: -verify_uintn_uintn_eq: - // tests/artifacts/arc4-primitive-ops/contract.algo.ts:5-6 - // @arc4.abimethod() - // public verify_uintn_uintn_eq(a: bytes, b: bytes): boolean { - proto 2 1 - // tests/artifacts/arc4-primitive-ops/contract.algo.ts:9 - // const aUintN = new UintN<64>(aBiguint) - frame_dig -2 - len - intc_1 // 8 - <= - assert // overflow - intc_1 // 8 - bzero - frame_dig -2 - dig 1 - b| - // tests/artifacts/arc4-primitive-ops/contract.algo.ts:10 - // const bUintN = new UintN<64>(bBiguint) - frame_dig -1 - len - intc_1 // 8 - <= - assert // overflow - frame_dig -1 - uncover 2 - b| - // tests/artifacts/arc4-primitive-ops/contract.algo.ts:11 - // return aUintN === bUintN - == - retsub - - -// tests/artifacts/arc4-primitive-ops/contract.algo.ts::Arc4PrimitiveOpsContract.verify_biguintn_uintn_eq(a: bytes, b: bytes) -> uint64: -verify_biguintn_uintn_eq: - // tests/artifacts/arc4-primitive-ops/contract.algo.ts:13-14 - // @arc4.abimethod() - // public verify_biguintn_uintn_eq(a: bytes, b: bytes): boolean { - proto 2 1 - // tests/artifacts/arc4-primitive-ops/contract.algo.ts:17 - // const aUintN = new UintN<512>(aBiguint) - frame_dig -2 - len - intc_2 // 64 - <= - assert // overflow - intc_2 // 64 - bzero - frame_dig -2 - b| - // tests/artifacts/arc4-primitive-ops/contract.algo.ts:18 - // const bUintN = new UintN<64>(bBiguint) - frame_dig -1 - len - intc_1 // 8 - <= - assert // overflow - intc_1 // 8 - bzero - frame_dig -1 - b| - // tests/artifacts/arc4-primitive-ops/contract.algo.ts:19 - // return aUintN.bytes.equals(bUintN.bytes) - == - retsub - - -// tests/artifacts/arc4-primitive-ops/contract.algo.ts::Arc4PrimitiveOpsContract.verify_uintn_biguintn_eq(a: bytes, b: bytes) -> uint64: -verify_uintn_biguintn_eq: - // tests/artifacts/arc4-primitive-ops/contract.algo.ts:21-22 - // @arc4.abimethod() - // public verify_uintn_biguintn_eq(a: bytes, b: bytes): boolean { - proto 2 1 - // tests/artifacts/arc4-primitive-ops/contract.algo.ts:25 - // const aUintN = new UintN<64>(aBiguint) - frame_dig -2 - len - intc_1 // 8 - <= - assert // overflow - intc_1 // 8 - bzero - frame_dig -2 - b| - // tests/artifacts/arc4-primitive-ops/contract.algo.ts:26 - // const bUintN = new UintN<512>(bBiguint) - frame_dig -1 - len - intc_2 // 64 - <= - assert // overflow - intc_2 // 64 - bzero - frame_dig -1 - b| - // tests/artifacts/arc4-primitive-ops/contract.algo.ts:27 - // return aUintN.bytes.equals(bUintN.bytes) - == - retsub - - -// tests/artifacts/arc4-primitive-ops/contract.algo.ts::Arc4PrimitiveOpsContract.verify_biguintn_biguintn_eq(a: bytes, b: bytes) -> uint64: -verify_biguintn_biguintn_eq: - // tests/artifacts/arc4-primitive-ops/contract.algo.ts:29-30 - // @arc4.abimethod() - // public verify_biguintn_biguintn_eq(a: bytes, b: bytes): boolean { - proto 2 1 - // tests/artifacts/arc4-primitive-ops/contract.algo.ts:33 - // const aUintN = new UintN<512>(aBiguint) - frame_dig -2 - len - intc_2 // 64 - <= - assert // overflow - intc_2 // 64 - bzero - frame_dig -2 - dig 1 - b| - // tests/artifacts/arc4-primitive-ops/contract.algo.ts:34 - // const bUintN = new UintN<512>(bBiguint) - frame_dig -1 - len - intc_2 // 64 - <= - assert // overflow - frame_dig -1 - uncover 2 - b| - // tests/artifacts/arc4-primitive-ops/contract.algo.ts:35 - // return aUintN === bUintN - == - retsub - - -// tests/artifacts/arc4-primitive-ops/contract.algo.ts::Arc4PrimitiveOpsContract.verify_byte_byte_eq(a: bytes, b: bytes) -> uint64: -verify_byte_byte_eq: - // tests/artifacts/arc4-primitive-ops/contract.algo.ts:37-38 - // @arc4.abimethod() - // public verify_byte_byte_eq(a: bytes, b: bytes): boolean { - proto 2 1 - // tests/artifacts/arc4-primitive-ops/contract.algo.ts:41 - // const aByte = new Byte(aBiguint) - frame_dig -2 - len - intc_0 // 1 - <= - assert // overflow - intc_0 // 1 - bzero - frame_dig -2 - dig 1 - b| - // tests/artifacts/arc4-primitive-ops/contract.algo.ts:42 - // const bByte = new Byte(bBiguint) - frame_dig -1 - len - intc_0 // 1 - <= - assert // overflow - frame_dig -1 - uncover 2 - b| - // tests/artifacts/arc4-primitive-ops/contract.algo.ts:43 - // return aByte === bByte - == - retsub - - -// tests/artifacts/arc4-primitive-ops/contract.algo.ts::Arc4PrimitiveOpsContract.verify_uintn_uintn_ne(a: bytes, b: bytes) -> uint64: -verify_uintn_uintn_ne: - // tests/artifacts/arc4-primitive-ops/contract.algo.ts:45-46 - // @arc4.abimethod() - // public verify_uintn_uintn_ne(a: bytes, b: bytes): boolean { - proto 2 1 - // tests/artifacts/arc4-primitive-ops/contract.algo.ts:49 - // const aUintN = new UintN<64>(aBiguint) - frame_dig -2 - len - intc_1 // 8 - <= - assert // overflow - intc_1 // 8 - bzero - frame_dig -2 - dig 1 - b| - // tests/artifacts/arc4-primitive-ops/contract.algo.ts:50 - // const bUintN = new UintN<64>(bBiguint) - frame_dig -1 - len - intc_1 // 8 - <= - assert // overflow - frame_dig -1 - uncover 2 - b| - // tests/artifacts/arc4-primitive-ops/contract.algo.ts:51 - // return aUintN !== bUintN - != - retsub - - -// tests/artifacts/arc4-primitive-ops/contract.algo.ts::Arc4PrimitiveOpsContract.verify_biguintn_uintn_ne(a: bytes, b: bytes) -> uint64: -verify_biguintn_uintn_ne: - // tests/artifacts/arc4-primitive-ops/contract.algo.ts:53-54 - // @arc4.abimethod() - // public verify_biguintn_uintn_ne(a: bytes, b: bytes): boolean { - proto 2 1 - // tests/artifacts/arc4-primitive-ops/contract.algo.ts:57 - // const aUintN = new UintN<512>(aBiguint) - frame_dig -2 - len - intc_2 // 64 - <= - assert // overflow - intc_2 // 64 - bzero - frame_dig -2 - b| - // tests/artifacts/arc4-primitive-ops/contract.algo.ts:58 - // const bUintN = new UintN<64>(bBiguint) - frame_dig -1 - len - intc_1 // 8 - <= - assert // overflow - intc_1 // 8 - bzero - frame_dig -1 - b| - // tests/artifacts/arc4-primitive-ops/contract.algo.ts:59 - // return !aUintN.bytes.equals(bUintN.bytes) - == - ! - retsub - - -// tests/artifacts/arc4-primitive-ops/contract.algo.ts::Arc4PrimitiveOpsContract.verify_uintn_biguintn_ne(a: bytes, b: bytes) -> uint64: -verify_uintn_biguintn_ne: - // tests/artifacts/arc4-primitive-ops/contract.algo.ts:61-62 - // @arc4.abimethod() - // public verify_uintn_biguintn_ne(a: bytes, b: bytes): boolean { - proto 2 1 - // tests/artifacts/arc4-primitive-ops/contract.algo.ts:65 - // const aUintN = new UintN<64>(aBiguint) - frame_dig -2 - len - intc_1 // 8 - <= - assert // overflow - intc_1 // 8 - bzero - frame_dig -2 - b| - // tests/artifacts/arc4-primitive-ops/contract.algo.ts:66 - // const bUintN = new UintN<512>(bBiguint) - frame_dig -1 - len - intc_2 // 64 - <= - assert // overflow - intc_2 // 64 - bzero - frame_dig -1 - b| - // tests/artifacts/arc4-primitive-ops/contract.algo.ts:67 - // return !aUintN.bytes.equals(bUintN.bytes) - == - ! - retsub - - -// tests/artifacts/arc4-primitive-ops/contract.algo.ts::Arc4PrimitiveOpsContract.verify_biguintn_biguintn_ne(a: bytes, b: bytes) -> uint64: -verify_biguintn_biguintn_ne: - // tests/artifacts/arc4-primitive-ops/contract.algo.ts:69-70 - // @arc4.abimethod() - // public verify_biguintn_biguintn_ne(a: bytes, b: bytes): boolean { - proto 2 1 - // tests/artifacts/arc4-primitive-ops/contract.algo.ts:73 - // const aUintN = new UintN<512>(aBiguint) - frame_dig -2 - len - intc_2 // 64 - <= - assert // overflow - intc_2 // 64 - bzero - frame_dig -2 - dig 1 - b| - // tests/artifacts/arc4-primitive-ops/contract.algo.ts:74 - // const bUintN = new UintN<512>(bBiguint) - frame_dig -1 - len - intc_2 // 64 - <= - assert // overflow - frame_dig -1 - uncover 2 - b| - // tests/artifacts/arc4-primitive-ops/contract.algo.ts:75 - // return aUintN !== bUintN - != - retsub - - -// tests/artifacts/arc4-primitive-ops/contract.algo.ts::Arc4PrimitiveOpsContract.verify_byte_byte_ne(a: bytes, b: bytes) -> uint64: -verify_byte_byte_ne: - // tests/artifacts/arc4-primitive-ops/contract.algo.ts:77-78 - // @arc4.abimethod() - // public verify_byte_byte_ne(a: bytes, b: bytes): boolean { - proto 2 1 - // tests/artifacts/arc4-primitive-ops/contract.algo.ts:81 - // const aByte = new Byte(aBiguint) - frame_dig -2 - len - intc_0 // 1 - <= - assert // overflow - intc_0 // 1 - bzero - frame_dig -2 - dig 1 - b| - // tests/artifacts/arc4-primitive-ops/contract.algo.ts:82 - // const bByte = new Byte(bBiguint) - frame_dig -1 - len - intc_0 // 1 - <= - assert // overflow - frame_dig -1 - uncover 2 - b| - // tests/artifacts/arc4-primitive-ops/contract.algo.ts:83 - // return aByte !== bByte - != - retsub - - -// tests/artifacts/arc4-primitive-ops/contract.algo.ts::Arc4PrimitiveOpsContract.verify_uintn_uintn_lt(a: bytes, b: bytes) -> uint64: -verify_uintn_uintn_lt: - // tests/artifacts/arc4-primitive-ops/contract.algo.ts:85-86 - // @arc4.abimethod() - // public verify_uintn_uintn_lt(a: bytes, b: bytes): boolean { - proto 2 1 - // tests/artifacts/arc4-primitive-ops/contract.algo.ts:89 - // const aUintN = new UintN<64>(aBiguint) - frame_dig -2 - len - intc_1 // 8 - <= - assert // overflow - intc_1 // 8 - bzero - frame_dig -2 - dig 1 - b| - // tests/artifacts/arc4-primitive-ops/contract.algo.ts:90 - // const bUintN = new UintN<64>(bBiguint) - frame_dig -1 - len - intc_1 // 8 - <= - assert // overflow - frame_dig -1 - uncover 2 - b| - // tests/artifacts/arc4-primitive-ops/contract.algo.ts:91 - // return aUintN.native < bUintN.native - swap - btoi - swap - btoi - < - retsub - - -// tests/artifacts/arc4-primitive-ops/contract.algo.ts::Arc4PrimitiveOpsContract.verify_biguintn_uintn_lt(a: bytes, b: bytes) -> uint64: -verify_biguintn_uintn_lt: - // tests/artifacts/arc4-primitive-ops/contract.algo.ts:93-94 - // @arc4.abimethod() - // public verify_biguintn_uintn_lt(a: bytes, b: bytes): boolean { - proto 2 1 - // tests/artifacts/arc4-primitive-ops/contract.algo.ts:97 - // const aUintN = new UintN<512>(aBiguint) - frame_dig -2 - len - intc_2 // 64 - <= - assert // overflow - intc_2 // 64 - bzero - frame_dig -2 - b| - // tests/artifacts/arc4-primitive-ops/contract.algo.ts:98 - // const bUintN = new UintN<64>(bBiguint) - frame_dig -1 - len - intc_1 // 8 - <= - assert // overflow - intc_1 // 8 - bzero - frame_dig -1 - b| - // tests/artifacts/arc4-primitive-ops/contract.algo.ts:99 - // return aUintN.native < BigUint(bUintN.native) - btoi - itob - b< - retsub - - -// tests/artifacts/arc4-primitive-ops/contract.algo.ts::Arc4PrimitiveOpsContract.verify_uintn_biguintn_lt(a: bytes, b: bytes) -> uint64: -verify_uintn_biguintn_lt: - // tests/artifacts/arc4-primitive-ops/contract.algo.ts:101-102 - // @arc4.abimethod() - // public verify_uintn_biguintn_lt(a: bytes, b: bytes): boolean { - proto 2 1 - // tests/artifacts/arc4-primitive-ops/contract.algo.ts:105 - // const aUintN = new UintN<64>(aBiguint) - frame_dig -2 - len - intc_1 // 8 - <= - assert // overflow - intc_1 // 8 - bzero - frame_dig -2 - b| - // tests/artifacts/arc4-primitive-ops/contract.algo.ts:106 - // const bUintN = new UintN<512>(bBiguint) - frame_dig -1 - len - intc_2 // 64 - <= - assert // overflow - intc_2 // 64 - bzero - frame_dig -1 - b| - // tests/artifacts/arc4-primitive-ops/contract.algo.ts:107 - // return BigUint(aUintN.native) < bUintN.native - swap - btoi - itob - b> - retsub - - -// tests/artifacts/arc4-primitive-ops/contract.algo.ts::Arc4PrimitiveOpsContract.verify_biguintn_biguintn_lt(a: bytes, b: bytes) -> uint64: -verify_biguintn_biguintn_lt: - // tests/artifacts/arc4-primitive-ops/contract.algo.ts:109-110 - // @arc4.abimethod() - // public verify_biguintn_biguintn_lt(a: bytes, b: bytes): boolean { - proto 2 1 - // tests/artifacts/arc4-primitive-ops/contract.algo.ts:113 - // const aUintN = new UintN<512>(aBiguint) - frame_dig -2 - len - intc_2 // 64 - <= - assert // overflow - intc_2 // 64 - bzero - frame_dig -2 - dig 1 - b| - // tests/artifacts/arc4-primitive-ops/contract.algo.ts:114 - // const bUintN = new UintN<512>(bBiguint) - frame_dig -1 - len - intc_2 // 64 - <= - assert // overflow - frame_dig -1 - uncover 2 - b| - // tests/artifacts/arc4-primitive-ops/contract.algo.ts:115 - // return aUintN.native < bUintN.native - b< - retsub - - -// tests/artifacts/arc4-primitive-ops/contract.algo.ts::Arc4PrimitiveOpsContract.verify_byte_byte_lt(a: bytes, b: bytes) -> uint64: -verify_byte_byte_lt: - // tests/artifacts/arc4-primitive-ops/contract.algo.ts:117-118 - // @arc4.abimethod() - // public verify_byte_byte_lt(a: bytes, b: bytes): boolean { - proto 2 1 - // tests/artifacts/arc4-primitive-ops/contract.algo.ts:121 - // const aByte = new Byte(aBiguint) - frame_dig -2 - len - intc_0 // 1 - <= - assert // overflow - intc_0 // 1 - bzero - frame_dig -2 - dig 1 - b| - // tests/artifacts/arc4-primitive-ops/contract.algo.ts:122 - // const bByte = new Byte(bBiguint) - frame_dig -1 - len - intc_0 // 1 - <= - assert // overflow - frame_dig -1 - uncover 2 - b| - // tests/artifacts/arc4-primitive-ops/contract.algo.ts:123 - // return aByte.native < bByte.native - swap - btoi - swap - btoi - < - retsub - - -// tests/artifacts/arc4-primitive-ops/contract.algo.ts::Arc4PrimitiveOpsContract.verify_uintn_uintn_le(a: bytes, b: bytes) -> uint64: -verify_uintn_uintn_le: - // tests/artifacts/arc4-primitive-ops/contract.algo.ts:125-126 - // @arc4.abimethod() - // public verify_uintn_uintn_le(a: bytes, b: bytes): boolean { - proto 2 1 - // tests/artifacts/arc4-primitive-ops/contract.algo.ts:129 - // const aUintN = new UintN<64>(aBiguint) - frame_dig -2 - len - intc_1 // 8 - <= - assert // overflow - intc_1 // 8 - bzero - frame_dig -2 - dig 1 - b| - // tests/artifacts/arc4-primitive-ops/contract.algo.ts:130 - // const bUintN = new UintN<64>(bBiguint) - frame_dig -1 - len - intc_1 // 8 - <= - assert // overflow - frame_dig -1 - uncover 2 - b| - // tests/artifacts/arc4-primitive-ops/contract.algo.ts:131 - // return aUintN.native <= bUintN.native - swap - btoi - swap - btoi - <= - retsub - - -// tests/artifacts/arc4-primitive-ops/contract.algo.ts::Arc4PrimitiveOpsContract.verify_biguintn_uintn_le(a: bytes, b: bytes) -> uint64: -verify_biguintn_uintn_le: - // tests/artifacts/arc4-primitive-ops/contract.algo.ts:133-134 - // @arc4.abimethod() - // public verify_biguintn_uintn_le(a: bytes, b: bytes): boolean { - proto 2 1 - // tests/artifacts/arc4-primitive-ops/contract.algo.ts:137 - // const aUintN = new UintN<512>(aBiguint) - frame_dig -2 - len - intc_2 // 64 - <= - assert // overflow - intc_2 // 64 - bzero - frame_dig -2 - b| - // tests/artifacts/arc4-primitive-ops/contract.algo.ts:138 - // const bUintN = new UintN<64>(bBiguint) - frame_dig -1 - len - intc_1 // 8 - <= - assert // overflow - intc_1 // 8 - bzero - frame_dig -1 - b| - // tests/artifacts/arc4-primitive-ops/contract.algo.ts:139 - // return aUintN.native <= BigUint(bUintN.native) - btoi - itob - b<= - retsub - - -// tests/artifacts/arc4-primitive-ops/contract.algo.ts::Arc4PrimitiveOpsContract.verify_uintn_biguintn_le(a: bytes, b: bytes) -> uint64: -verify_uintn_biguintn_le: - // tests/artifacts/arc4-primitive-ops/contract.algo.ts:141-142 - // @arc4.abimethod() - // public verify_uintn_biguintn_le(a: bytes, b: bytes): boolean { - proto 2 1 - // tests/artifacts/arc4-primitive-ops/contract.algo.ts:145 - // const aUintN = new UintN<64>(aBiguint) - frame_dig -2 - len - intc_1 // 8 - <= - assert // overflow - intc_1 // 8 - bzero - frame_dig -2 - b| - // tests/artifacts/arc4-primitive-ops/contract.algo.ts:146 - // const bUintN = new UintN<512>(bBiguint) - frame_dig -1 - len - intc_2 // 64 - <= - assert // overflow - intc_2 // 64 - bzero - frame_dig -1 - b| - // tests/artifacts/arc4-primitive-ops/contract.algo.ts:147 - // return BigUint(aUintN.native) <= bUintN.native - swap - btoi - itob - b>= - retsub - - -// tests/artifacts/arc4-primitive-ops/contract.algo.ts::Arc4PrimitiveOpsContract.verify_biguintn_biguintn_le(a: bytes, b: bytes) -> uint64: -verify_biguintn_biguintn_le: - // tests/artifacts/arc4-primitive-ops/contract.algo.ts:149-150 - // @arc4.abimethod() - // public verify_biguintn_biguintn_le(a: bytes, b: bytes): boolean { - proto 2 1 - // tests/artifacts/arc4-primitive-ops/contract.algo.ts:153 - // const aUintN = new UintN<512>(aBiguint) - frame_dig -2 - len - intc_2 // 64 - <= - assert // overflow - intc_2 // 64 - bzero - frame_dig -2 - dig 1 - b| - // tests/artifacts/arc4-primitive-ops/contract.algo.ts:154 - // const bUintN = new UintN<512>(bBiguint) - frame_dig -1 - len - intc_2 // 64 - <= - assert // overflow - frame_dig -1 - uncover 2 - b| - // tests/artifacts/arc4-primitive-ops/contract.algo.ts:155 - // return aUintN.native <= bUintN.native - b<= - retsub - - -// tests/artifacts/arc4-primitive-ops/contract.algo.ts::Arc4PrimitiveOpsContract.verify_byte_byte_le(a: bytes, b: bytes) -> uint64: -verify_byte_byte_le: - // tests/artifacts/arc4-primitive-ops/contract.algo.ts:157-158 - // @arc4.abimethod() - // public verify_byte_byte_le(a: bytes, b: bytes): boolean { - proto 2 1 - // tests/artifacts/arc4-primitive-ops/contract.algo.ts:161 - // const aByte = new Byte(aBiguint) - frame_dig -2 - len - intc_0 // 1 - <= - assert // overflow - intc_0 // 1 - bzero - frame_dig -2 - dig 1 - b| - // tests/artifacts/arc4-primitive-ops/contract.algo.ts:162 - // const bByte = new Byte(bBiguint) - frame_dig -1 - len - intc_0 // 1 - <= - assert // overflow - frame_dig -1 - uncover 2 - b| - // tests/artifacts/arc4-primitive-ops/contract.algo.ts:163 - // return aByte.native <= bByte.native - swap - btoi - swap - btoi - <= - retsub - - -// tests/artifacts/arc4-primitive-ops/contract.algo.ts::Arc4PrimitiveOpsContract.verify_uintn_uintn_gt(a: bytes, b: bytes) -> uint64: -verify_uintn_uintn_gt: - // tests/artifacts/arc4-primitive-ops/contract.algo.ts:165-166 - // @arc4.abimethod() - // public verify_uintn_uintn_gt(a: bytes, b: bytes): boolean { - proto 2 1 - // tests/artifacts/arc4-primitive-ops/contract.algo.ts:169 - // const aUintN = new UintN<64>(aBiguint) - frame_dig -2 - len - intc_1 // 8 - <= - assert // overflow - intc_1 // 8 - bzero - frame_dig -2 - dig 1 - b| - // tests/artifacts/arc4-primitive-ops/contract.algo.ts:170 - // const bUintN = new UintN<64>(bBiguint) - frame_dig -1 - len - intc_1 // 8 - <= - assert // overflow - frame_dig -1 - uncover 2 - b| - // tests/artifacts/arc4-primitive-ops/contract.algo.ts:171 - // return aUintN.native > bUintN.native - swap - btoi - swap - btoi - > - retsub - - -// tests/artifacts/arc4-primitive-ops/contract.algo.ts::Arc4PrimitiveOpsContract.verify_biguintn_uintn_gt(a: bytes, b: bytes) -> uint64: -verify_biguintn_uintn_gt: - // tests/artifacts/arc4-primitive-ops/contract.algo.ts:173-174 - // @arc4.abimethod() - // public verify_biguintn_uintn_gt(a: bytes, b: bytes): boolean { - proto 2 1 - // tests/artifacts/arc4-primitive-ops/contract.algo.ts:177 - // const aUintN = new UintN<512>(aBiguint) - frame_dig -2 - len - intc_2 // 64 - <= - assert // overflow - intc_2 // 64 - bzero - frame_dig -2 - b| - // tests/artifacts/arc4-primitive-ops/contract.algo.ts:178 - // const bUintN = new UintN<64>(bBiguint) - frame_dig -1 - len - intc_1 // 8 - <= - assert // overflow - intc_1 // 8 - bzero - frame_dig -1 - b| - // tests/artifacts/arc4-primitive-ops/contract.algo.ts:179 - // return aUintN.native > BigUint(bUintN.native) - btoi - itob - b> - retsub - - -// tests/artifacts/arc4-primitive-ops/contract.algo.ts::Arc4PrimitiveOpsContract.verify_uintn_biguintn_gt(a: bytes, b: bytes) -> uint64: -verify_uintn_biguintn_gt: - // tests/artifacts/arc4-primitive-ops/contract.algo.ts:181-182 - // @arc4.abimethod() - // public verify_uintn_biguintn_gt(a: bytes, b: bytes): boolean { - proto 2 1 - // tests/artifacts/arc4-primitive-ops/contract.algo.ts:185 - // const aUintN = new UintN<64>(aBiguint) - frame_dig -2 - len - intc_1 // 8 - <= - assert // overflow - intc_1 // 8 - bzero - frame_dig -2 - b| - // tests/artifacts/arc4-primitive-ops/contract.algo.ts:186 - // const bUintN = new UintN<512>(bBiguint) - frame_dig -1 - len - intc_2 // 64 - <= - assert // overflow - intc_2 // 64 - bzero - frame_dig -1 - b| - // tests/artifacts/arc4-primitive-ops/contract.algo.ts:187 - // return BigUint(aUintN.native) > bUintN.native - swap - btoi - itob - b< - retsub - - -// tests/artifacts/arc4-primitive-ops/contract.algo.ts::Arc4PrimitiveOpsContract.verify_biguintn_biguintn_gt(a: bytes, b: bytes) -> uint64: -verify_biguintn_biguintn_gt: - // tests/artifacts/arc4-primitive-ops/contract.algo.ts:189-190 - // @arc4.abimethod() - // public verify_biguintn_biguintn_gt(a: bytes, b: bytes): boolean { - proto 2 1 - // tests/artifacts/arc4-primitive-ops/contract.algo.ts:193 - // const aUintN = new UintN<512>(aBiguint) - frame_dig -2 - len - intc_2 // 64 - <= - assert // overflow - intc_2 // 64 - bzero - frame_dig -2 - dig 1 - b| - // tests/artifacts/arc4-primitive-ops/contract.algo.ts:194 - // const bUintN = new UintN<512>(bBiguint) - frame_dig -1 - len - intc_2 // 64 - <= - assert // overflow - frame_dig -1 - uncover 2 - b| - // tests/artifacts/arc4-primitive-ops/contract.algo.ts:195 - // return aUintN.native > bUintN.native - b> - retsub - - -// tests/artifacts/arc4-primitive-ops/contract.algo.ts::Arc4PrimitiveOpsContract.verify_byte_byte_gt(a: bytes, b: bytes) -> uint64: -verify_byte_byte_gt: - // tests/artifacts/arc4-primitive-ops/contract.algo.ts:197-198 - // @arc4.abimethod() - // public verify_byte_byte_gt(a: bytes, b: bytes): boolean { - proto 2 1 - // tests/artifacts/arc4-primitive-ops/contract.algo.ts:201 - // const aByte = new Byte(aBiguint) - frame_dig -2 - len - intc_0 // 1 - <= - assert // overflow - intc_0 // 1 - bzero - frame_dig -2 - dig 1 - b| - // tests/artifacts/arc4-primitive-ops/contract.algo.ts:202 - // const bByte = new Byte(bBiguint) - frame_dig -1 - len - intc_0 // 1 - <= - assert // overflow - frame_dig -1 - uncover 2 - b| - // tests/artifacts/arc4-primitive-ops/contract.algo.ts:203 - // return aByte.native > bByte.native - swap - btoi - swap - btoi - > - retsub - - -// tests/artifacts/arc4-primitive-ops/contract.algo.ts::Arc4PrimitiveOpsContract.verify_uintn_uintn_ge(a: bytes, b: bytes) -> uint64: -verify_uintn_uintn_ge: - // tests/artifacts/arc4-primitive-ops/contract.algo.ts:205-206 - // @arc4.abimethod() - // public verify_uintn_uintn_ge(a: bytes, b: bytes): boolean { - proto 2 1 - // tests/artifacts/arc4-primitive-ops/contract.algo.ts:209 - // const aUintN = new UintN<64>(aBiguint) - frame_dig -2 - len - intc_1 // 8 - <= - assert // overflow - intc_1 // 8 - bzero - frame_dig -2 - dig 1 - b| - // tests/artifacts/arc4-primitive-ops/contract.algo.ts:210 - // const bUintN = new UintN<64>(bBiguint) - frame_dig -1 - len - intc_1 // 8 - <= - assert // overflow - frame_dig -1 - uncover 2 - b| - // tests/artifacts/arc4-primitive-ops/contract.algo.ts:211 - // return aUintN.native >= bUintN.native - swap - btoi - swap - btoi - >= - retsub - - -// tests/artifacts/arc4-primitive-ops/contract.algo.ts::Arc4PrimitiveOpsContract.verify_biguintn_uintn_ge(a: bytes, b: bytes) -> uint64: -verify_biguintn_uintn_ge: - // tests/artifacts/arc4-primitive-ops/contract.algo.ts:213-214 - // @arc4.abimethod() - // public verify_biguintn_uintn_ge(a: bytes, b: bytes): boolean { - proto 2 1 - // tests/artifacts/arc4-primitive-ops/contract.algo.ts:217 - // const aUintN = new UintN<512>(aBiguint) - frame_dig -2 - len - intc_2 // 64 - <= - assert // overflow - intc_2 // 64 - bzero - frame_dig -2 - b| - // tests/artifacts/arc4-primitive-ops/contract.algo.ts:218 - // const bUintN = new UintN<64>(bBiguint) - frame_dig -1 - len - intc_1 // 8 - <= - assert // overflow - intc_1 // 8 - bzero - frame_dig -1 - b| - // tests/artifacts/arc4-primitive-ops/contract.algo.ts:219 - // return aUintN.native >= BigUint(bUintN.native) - btoi - itob - b>= - retsub - - -// tests/artifacts/arc4-primitive-ops/contract.algo.ts::Arc4PrimitiveOpsContract.verify_uintn_biguintn_ge(a: bytes, b: bytes) -> uint64: -verify_uintn_biguintn_ge: - // tests/artifacts/arc4-primitive-ops/contract.algo.ts:221-222 - // @arc4.abimethod() - // public verify_uintn_biguintn_ge(a: bytes, b: bytes): boolean { - proto 2 1 - // tests/artifacts/arc4-primitive-ops/contract.algo.ts:225 - // const aUintN = new UintN<64>(aBiguint) - frame_dig -2 - len - intc_1 // 8 - <= - assert // overflow - intc_1 // 8 - bzero - frame_dig -2 - b| - // tests/artifacts/arc4-primitive-ops/contract.algo.ts:226 - // const bUintN = new UintN<512>(bBiguint) - frame_dig -1 - len - intc_2 // 64 - <= - assert // overflow - intc_2 // 64 - bzero - frame_dig -1 - b| - // tests/artifacts/arc4-primitive-ops/contract.algo.ts:227 - // return BigUint(aUintN.native) >= bUintN.native - swap - btoi - itob - b<= - retsub - - -// tests/artifacts/arc4-primitive-ops/contract.algo.ts::Arc4PrimitiveOpsContract.verify_biguintn_biguintn_ge(a: bytes, b: bytes) -> uint64: -verify_biguintn_biguintn_ge: - // tests/artifacts/arc4-primitive-ops/contract.algo.ts:229-230 - // @arc4.abimethod() - // public verify_biguintn_biguintn_ge(a: bytes, b: bytes): boolean { - proto 2 1 - // tests/artifacts/arc4-primitive-ops/contract.algo.ts:233 - // const aUintN = new UintN<512>(aBiguint) - frame_dig -2 - len - intc_2 // 64 - <= - assert // overflow - intc_2 // 64 - bzero - frame_dig -2 - dig 1 - b| - // tests/artifacts/arc4-primitive-ops/contract.algo.ts:234 - // const bUintN = new UintN<512>(bBiguint) - frame_dig -1 - len - intc_2 // 64 - <= - assert // overflow - frame_dig -1 - uncover 2 - b| - // tests/artifacts/arc4-primitive-ops/contract.algo.ts:235 - // return aUintN.native >= bUintN.native - b>= - retsub - - -// tests/artifacts/arc4-primitive-ops/contract.algo.ts::Arc4PrimitiveOpsContract.verify_byte_byte_ge(a: bytes, b: bytes) -> uint64: -verify_byte_byte_ge: - // tests/artifacts/arc4-primitive-ops/contract.algo.ts:237-238 - // @arc4.abimethod() - // public verify_byte_byte_ge(a: bytes, b: bytes): boolean { - proto 2 1 - // tests/artifacts/arc4-primitive-ops/contract.algo.ts:241 - // const aByte = new Byte(aBiguint) - frame_dig -2 - len - intc_0 // 1 - <= - assert // overflow - intc_0 // 1 - bzero - frame_dig -2 - dig 1 - b| - // tests/artifacts/arc4-primitive-ops/contract.algo.ts:242 - // const bByte = new Byte(bBiguint) - frame_dig -1 - len - intc_0 // 1 - <= - assert // overflow - frame_dig -1 - uncover 2 - b| - // tests/artifacts/arc4-primitive-ops/contract.algo.ts:243 - // return aByte.native >= bByte.native - swap - btoi - swap - btoi - >= - retsub - - -// tests/artifacts/arc4-primitive-ops/contract.algo.ts::Arc4PrimitiveOpsContract.verify_uintn_init(a: bytes) -> bytes: -verify_uintn_init: - // tests/artifacts/arc4-primitive-ops/contract.algo.ts:245-246 - // @arc4.abimethod() - // public verify_uintn_init(a: bytes): UintN<32> { - proto 1 1 - // tests/artifacts/arc4-primitive-ops/contract.algo.ts:248 - // return new UintN<32>(aBiguint) - frame_dig -1 - len - pushint 4 // 4 - <= - assert // overflow - pushint 4 // 4 - bzero - frame_dig -1 - b| - retsub - - -// tests/artifacts/arc4-primitive-ops/contract.algo.ts::Arc4PrimitiveOpsContract.verify_biguintn_init(a: bytes) -> bytes: -verify_biguintn_init: - // tests/artifacts/arc4-primitive-ops/contract.algo.ts:250-251 - // @arc4.abimethod() - // public verify_biguintn_init(a: bytes): UintN<256> { - proto 1 1 - // tests/artifacts/arc4-primitive-ops/contract.algo.ts:253 - // return new UintN<256>(aBiguint) - frame_dig -1 - len - pushint 32 // 32 - <= - assert // overflow - pushint 32 // 32 - bzero - frame_dig -1 - b| - retsub - - -// tests/artifacts/arc4-primitive-ops/contract.algo.ts::Arc4PrimitiveOpsContract.verify_byte_init(a: bytes) -> bytes: -verify_byte_init: - // tests/artifacts/arc4-primitive-ops/contract.algo.ts:255-256 - // @arc4.abimethod() - // public verify_byte_init(a: bytes): Byte { - proto 1 1 - // tests/artifacts/arc4-primitive-ops/contract.algo.ts:258 - // return new Byte(aBiguint) - frame_dig -1 - len - intc_0 // 1 - <= - assert // overflow - intc_0 // 1 - bzero - frame_dig -1 - b| - retsub - - -// tests/artifacts/arc4-primitive-ops/contract.algo.ts::Arc4PrimitiveOpsContract.verify_uintn_from_log(a: bytes) -> bytes: -verify_uintn_from_log: - // tests/artifacts/arc4-primitive-ops/contract.algo.ts:272-273 - // @arc4.abimethod() - // public verify_uintn_from_log(a: bytes): UintN<32> { - proto 1 1 - // tests/artifacts/arc4-primitive-ops/contract.algo.ts:274 - // return interpretAsArc4>(a, 'log') - frame_dig -1 - extract 4 0 - frame_dig -1 - extract 0 4 - bytec_0 // 0x151f7c75 - == - assert // Bytes has valid prefix - retsub - - -// tests/artifacts/arc4-primitive-ops/contract.algo.ts::Arc4PrimitiveOpsContract.verify_biguintn_from_log(a: bytes) -> bytes: -verify_biguintn_from_log: - // tests/artifacts/arc4-primitive-ops/contract.algo.ts:276-277 - // @arc4.abimethod() - // public verify_biguintn_from_log(a: bytes): UintN<256> { - proto 1 1 - // tests/artifacts/arc4-primitive-ops/contract.algo.ts:278 - // return interpretAsArc4>(a, 'log') - frame_dig -1 - extract 4 0 - frame_dig -1 - extract 0 4 - bytec_0 // 0x151f7c75 - == - assert // Bytes has valid prefix - retsub - - -// tests/artifacts/arc4-primitive-ops/contract.algo.ts::Arc4PrimitiveOpsContract.verify_byte_from_log(a: bytes) -> bytes: -verify_byte_from_log: - // tests/artifacts/arc4-primitive-ops/contract.algo.ts:280-281 - // @arc4.abimethod() - // public verify_byte_from_log(a: bytes): Byte { - proto 1 1 - // tests/artifacts/arc4-primitive-ops/contract.algo.ts:282 - // return interpretAsArc4(a, 'log') - frame_dig -1 - extract 4 0 - frame_dig -1 - extract 0 4 - bytec_0 // 0x151f7c75 - == - assert // Bytes has valid prefix - retsub - - -// tests/artifacts/arc4-primitive-ops/contract.algo.ts::Arc4PrimitiveOpsContract.verify_ufixednxm_from_log(a: bytes) -> bytes: -verify_ufixednxm_from_log: - // tests/artifacts/arc4-primitive-ops/contract.algo.ts:300-301 - // @arc4.abimethod() - // public verify_ufixednxm_from_log(a: bytes): UFixedNxM<32, 8> { - proto 1 1 - // tests/artifacts/arc4-primitive-ops/contract.algo.ts:302 - // return interpretAsArc4>(a, 'log') - frame_dig -1 - extract 4 0 - frame_dig -1 - extract 0 4 - bytec_0 // 0x151f7c75 - == - assert // Bytes has valid prefix - retsub - - -// tests/artifacts/arc4-primitive-ops/contract.algo.ts::Arc4PrimitiveOpsContract.verify_bigufixednxm_from_log(a: bytes) -> bytes: -verify_bigufixednxm_from_log: - // tests/artifacts/arc4-primitive-ops/contract.algo.ts:304-305 - // @arc4.abimethod() - // public verify_bigufixednxm_from_log(a: bytes): UFixedNxM<256, 16> { - proto 1 1 - // tests/artifacts/arc4-primitive-ops/contract.algo.ts:306 - // return interpretAsArc4>(a, 'log') - frame_dig -1 - extract 4 0 - frame_dig -1 - extract 0 4 - bytec_0 // 0x151f7c75 - == - assert // Bytes has valid prefix - retsub - - -// tests/artifacts/arc4-primitive-ops/contract.algo.ts::Arc4PrimitiveOpsContract.verify_string_init(a: bytes) -> bytes: -verify_string_init: - // tests/artifacts/arc4-primitive-ops/contract.algo.ts:308-309 - // @arc4.abimethod() - // public verify_string_init(a: string): Str { - proto 1 1 - // tests/artifacts/arc4-primitive-ops/contract.algo.ts:310 - // const result = new Str(`Hello, ${a}`) - pushbytes "Hello, " - frame_dig -1 - concat - dup - len - itob - extract 6 2 - swap - concat - // tests/artifacts/arc4-primitive-ops/contract.algo.ts:311 - // return result - retsub - - -// tests/artifacts/arc4-primitive-ops/contract.algo.ts::Arc4PrimitiveOpsContract.verify_string_add(a: bytes, b: bytes) -> bytes: -verify_string_add: - // tests/artifacts/arc4-primitive-ops/contract.algo.ts:313-314 - // @arc4.abimethod() - // public verify_string_add(a: Str, b: Str): Str { - proto 2 1 - // tests/artifacts/arc4-primitive-ops/contract.algo.ts:315 - // const result = a.native.concat(b.native) - frame_dig -2 - extract 2 0 - frame_dig -1 - extract 2 0 - concat - // tests/artifacts/arc4-primitive-ops/contract.algo.ts:316 - // return new Str(result) - dup - len - itob - extract 6 2 - swap - concat - retsub - - -// tests/artifacts/arc4-primitive-ops/contract.algo.ts::Arc4PrimitiveOpsContract.verify_string_eq(a: bytes, b: bytes) -> uint64: -verify_string_eq: - // tests/artifacts/arc4-primitive-ops/contract.algo.ts:318-319 - // @arc4.abimethod() - // public verify_string_eq(a: Str, b: Str): boolean { - proto 2 1 - // tests/artifacts/arc4-primitive-ops/contract.algo.ts:320 - // return a === b - frame_dig -2 - frame_dig -1 - == - retsub - - -// tests/artifacts/arc4-primitive-ops/contract.algo.ts::Arc4PrimitiveOpsContract.verify_string_bytes(a: bytes) -> bytes: -verify_string_bytes: - // tests/artifacts/arc4-primitive-ops/contract.algo.ts:322-323 - // @arc4.abimethod() - // public verify_string_bytes(a: string): bytes { - proto 1 1 - // tests/artifacts/arc4-primitive-ops/contract.algo.ts:324 - // const result = new Str(a) - frame_dig -1 - len - itob - extract 6 2 - frame_dig -1 - concat - // tests/artifacts/arc4-primitive-ops/contract.algo.ts:325 - // return result.bytes - retsub - - -// tests/artifacts/arc4-primitive-ops/contract.algo.ts::Arc4PrimitiveOpsContract.verify_string_from_log(a: bytes) -> bytes: -verify_string_from_log: - // tests/artifacts/arc4-primitive-ops/contract.algo.ts:331-332 - // @arc4.abimethod() - // public verify_string_from_log(a: bytes): Str { - proto 1 1 - // tests/artifacts/arc4-primitive-ops/contract.algo.ts:333 - // return interpretAsArc4(a, 'log') - frame_dig -1 - extract 4 0 - frame_dig -1 - extract 0 4 - bytec_0 // 0x151f7c75 - == - assert // Bytes has valid prefix - retsub - - -// tests/artifacts/arc4-primitive-ops/contract.algo.ts::Arc4PrimitiveOpsContract.verify_bool_from_log(a: bytes) -> bytes: -verify_bool_from_log: - // tests/artifacts/arc4-primitive-ops/contract.algo.ts:343-344 - // @arc4.abimethod() - // public verify_bool_from_log(a: bytes): Bool { - proto 1 1 - // tests/artifacts/arc4-primitive-ops/contract.algo.ts:345 - // return interpretAsArc4(a, 'log') - frame_dig -1 - extract 4 0 - frame_dig -1 - extract 0 4 - bytec_0 // 0x151f7c75 - == - assert // Bytes has valid prefix - retsub - - -// tests/artifacts/arc4-primitive-ops/contract.algo.ts::Arc4PrimitiveOpsContract.verify_emit(a: bytes, b: bytes, c: bytes, d: bytes, e: bytes, f: bytes, g: bytes, h: bytes, m: bytes, n: bytes, o: bytes, p: bytes, q: bytes, r: bytes, s: bytes, t: bytes) -> void: -verify_emit: - // tests/artifacts/arc4-primitive-ops/contract.algo.ts:349-367 - // @arc4.abimethod() - // public verify_emit( - // a: arc4.Str, - // b: arc4.UintN<512>, - // c: arc4.UintN64, - // d: arc4.DynamicBytes, - // e: arc4.UintN64, - // f: arc4.Bool, - // g: arc4.DynamicBytes, - // h: arc4.Str, - // m: arc4.UintN<64>, - // n: arc4.UintN<256>, - // o: arc4.UFixedNxM<32, 8>, - // p: arc4.UFixedNxM<256, 16>, - // q: arc4.Bool, - // r: bytes, - // s: bytes, - // t: bytes, - // ): void { - proto 16 0 - // tests/artifacts/arc4-primitive-ops/contract.algo.ts:372 - // emit(new SwappedArc4({ m, n, o, p, q, r: arc4_r, s: arc4_s, t: arc4_t })) - frame_dig -8 - frame_dig -7 - concat - frame_dig -6 - concat - frame_dig -5 - concat - frame_dig -4 - concat - frame_dig -3 - concat - pushbytes 0x0054 - concat - frame_dig -2 - len - pushint 84 // 84 - dig 1 - + - itob - extract 6 2 - uncover 2 - swap - concat - frame_dig -2 - concat - frame_dig -1 - concat - pushbytes 0x66bb0333 // method "SwappedArc4(uint64,uint256,ufixed32x8,ufixed256x16,bool,uint8[3],uint16[],(uint32,uint64,string))" - swap - concat - log - // tests/artifacts/arc4-primitive-ops/contract.algo.ts:373 - // emit('Swapped', a, b, c, d, e, f, g, h, m, n, o, p, q, arc4_r.copy(), arc4_s.copy(), arc4_t) - frame_dig -16 - len - pushint 173 // 173 - + - pushbytes 0x00ad - frame_dig -15 - concat - frame_dig -14 - concat - dig 1 - itob - extract 6 2 - concat - frame_dig -13 - len - uncover 2 - + - swap - frame_dig -12 - concat - frame_dig -11 - concat - dig 1 - itob - extract 6 2 - concat - frame_dig -10 - len - uncover 2 - + - dup - itob - extract 6 2 - uncover 2 - swap - concat - frame_dig -9 - len - uncover 2 - + - swap - frame_dig -8 - concat - frame_dig -7 - concat - frame_dig -6 - concat - frame_dig -5 - concat - frame_dig -4 - concat - frame_dig -3 - concat - dig 1 - itob - extract 6 2 - concat - swap - uncover 2 - + - itob - extract 6 2 - concat - frame_dig -16 - concat - frame_dig -13 - concat - frame_dig -10 - concat - frame_dig -9 - concat - frame_dig -2 - concat - frame_dig -1 - concat - pushbytes 0xec3319bb // method "Swapped(string,uint512,uint64,byte[],uint64,bool,byte[],string,uint64,uint256,ufixed32x8,ufixed256x16,bool,uint8[3],uint16[],(uint32,uint64,string))" - dig 1 - concat - log - // tests/artifacts/arc4-primitive-ops/contract.algo.ts:374-392 - // emit( - // 'Swapped(string,uint512,uint64,byte[],uint64,bool,byte[],string,uint64,uint256,ufixed32x8,ufixed256x16,bool,uint8[3],uint16[],(uint32,uint64,string))', - // a, - // b, - // c, - // d, - // e, - // f, - // g, - // h, - // m, - // n, - // o, - // p, - // q, - // arc4_r.copy(), - // arc4_s.copy(), - // arc4_t, - // ) - pushbytes 0xec3319bb // method "Swapped(string,uint512,uint64,byte[],uint64,bool,byte[],string,uint64,uint256,ufixed32x8,ufixed256x16,bool,uint8[3],uint16[],(uint32,uint64,string))" - swap - concat - log - retsub diff --git a/tests/artifacts/arc4-primitive-ops/data/Arc4PrimitiveOpsContract.arc32.json b/tests/artifacts/arc4-primitive-ops/data/Arc4PrimitiveOpsContract.arc32.json deleted file mode 100644 index 5da0118..0000000 --- a/tests/artifacts/arc4-primitive-ops/data/Arc4PrimitiveOpsContract.arc32.json +++ /dev/null @@ -1,1215 +0,0 @@ -{ - "hints": { - "verify_uintn_uintn_eq(byte[],byte[])bool": { - "call_config": { - "no_op": "CALL" - } - }, - "verify_biguintn_uintn_eq(byte[],byte[])bool": { - "call_config": { - "no_op": "CALL" - } - }, - "verify_uintn_biguintn_eq(byte[],byte[])bool": { - "call_config": { - "no_op": "CALL" - } - }, - "verify_biguintn_biguintn_eq(byte[],byte[])bool": { - "call_config": { - "no_op": "CALL" - } - }, - "verify_byte_byte_eq(byte[],byte[])bool": { - "call_config": { - "no_op": "CALL" - } - }, - "verify_uintn_uintn_ne(byte[],byte[])bool": { - "call_config": { - "no_op": "CALL" - } - }, - "verify_biguintn_uintn_ne(byte[],byte[])bool": { - "call_config": { - "no_op": "CALL" - } - }, - "verify_uintn_biguintn_ne(byte[],byte[])bool": { - "call_config": { - "no_op": "CALL" - } - }, - "verify_biguintn_biguintn_ne(byte[],byte[])bool": { - "call_config": { - "no_op": "CALL" - } - }, - "verify_byte_byte_ne(byte[],byte[])bool": { - "call_config": { - "no_op": "CALL" - } - }, - "verify_uintn_uintn_lt(byte[],byte[])bool": { - "call_config": { - "no_op": "CALL" - } - }, - "verify_biguintn_uintn_lt(byte[],byte[])bool": { - "call_config": { - "no_op": "CALL" - } - }, - "verify_uintn_biguintn_lt(byte[],byte[])bool": { - "call_config": { - "no_op": "CALL" - } - }, - "verify_biguintn_biguintn_lt(byte[],byte[])bool": { - "call_config": { - "no_op": "CALL" - } - }, - "verify_byte_byte_lt(byte[],byte[])bool": { - "call_config": { - "no_op": "CALL" - } - }, - "verify_uintn_uintn_le(byte[],byte[])bool": { - "call_config": { - "no_op": "CALL" - } - }, - "verify_biguintn_uintn_le(byte[],byte[])bool": { - "call_config": { - "no_op": "CALL" - } - }, - "verify_uintn_biguintn_le(byte[],byte[])bool": { - "call_config": { - "no_op": "CALL" - } - }, - "verify_biguintn_biguintn_le(byte[],byte[])bool": { - "call_config": { - "no_op": "CALL" - } - }, - "verify_byte_byte_le(byte[],byte[])bool": { - "call_config": { - "no_op": "CALL" - } - }, - "verify_uintn_uintn_gt(byte[],byte[])bool": { - "call_config": { - "no_op": "CALL" - } - }, - "verify_biguintn_uintn_gt(byte[],byte[])bool": { - "call_config": { - "no_op": "CALL" - } - }, - "verify_uintn_biguintn_gt(byte[],byte[])bool": { - "call_config": { - "no_op": "CALL" - } - }, - "verify_biguintn_biguintn_gt(byte[],byte[])bool": { - "call_config": { - "no_op": "CALL" - } - }, - "verify_byte_byte_gt(byte[],byte[])bool": { - "call_config": { - "no_op": "CALL" - } - }, - "verify_uintn_uintn_ge(byte[],byte[])bool": { - "call_config": { - "no_op": "CALL" - } - }, - "verify_biguintn_uintn_ge(byte[],byte[])bool": { - "call_config": { - "no_op": "CALL" - } - }, - "verify_uintn_biguintn_ge(byte[],byte[])bool": { - "call_config": { - "no_op": "CALL" - } - }, - "verify_biguintn_biguintn_ge(byte[],byte[])bool": { - "call_config": { - "no_op": "CALL" - } - }, - "verify_byte_byte_ge(byte[],byte[])bool": { - "call_config": { - "no_op": "CALL" - } - }, - "verify_uintn_init(byte[])uint32": { - "call_config": { - "no_op": "CALL" - } - }, - "verify_biguintn_init(byte[])uint256": { - "call_config": { - "no_op": "CALL" - } - }, - "verify_byte_init(byte[])byte": { - "call_config": { - "no_op": "CALL" - } - }, - "verify_uintn_from_bytes(byte[])uint32": { - "call_config": { - "no_op": "CALL" - } - }, - "verify_biguintn_from_bytes(byte[])uint256": { - "call_config": { - "no_op": "CALL" - } - }, - "verify_byte_from_bytes(byte[])byte": { - "call_config": { - "no_op": "CALL" - } - }, - "verify_uintn_from_log(byte[])uint32": { - "call_config": { - "no_op": "CALL" - } - }, - "verify_biguintn_from_log(byte[])uint256": { - "call_config": { - "no_op": "CALL" - } - }, - "verify_byte_from_log(byte[])byte": { - "call_config": { - "no_op": "CALL" - } - }, - "verify_ufixednxm_bytes(ufixed32x8)byte[]": { - "call_config": { - "no_op": "CALL" - } - }, - "verify_bigufixednxm_bytes(ufixed256x16)byte[]": { - "call_config": { - "no_op": "CALL" - } - }, - "verify_ufixednxm_from_bytes(byte[])ufixed32x8": { - "call_config": { - "no_op": "CALL" - } - }, - "verify_bigufixednxm_from_bytes(byte[])ufixed256x16": { - "call_config": { - "no_op": "CALL" - } - }, - "verify_ufixednxm_from_log(byte[])ufixed32x8": { - "call_config": { - "no_op": "CALL" - } - }, - "verify_bigufixednxm_from_log(byte[])ufixed256x16": { - "call_config": { - "no_op": "CALL" - } - }, - "verify_string_init(string)string": { - "call_config": { - "no_op": "CALL" - } - }, - "verify_string_add(string,string)string": { - "call_config": { - "no_op": "CALL" - } - }, - "verify_string_eq(string,string)bool": { - "call_config": { - "no_op": "CALL" - } - }, - "verify_string_bytes(string)byte[]": { - "call_config": { - "no_op": "CALL" - } - }, - "verify_string_from_bytes(byte[])string": { - "call_config": { - "no_op": "CALL" - } - }, - "verify_string_from_log(byte[])string": { - "call_config": { - "no_op": "CALL" - } - }, - "verify_bool_bytes(bool)byte[]": { - "call_config": { - "no_op": "CALL" - } - }, - "verify_bool_from_bytes(byte[])bool": { - "call_config": { - "no_op": "CALL" - } - }, - "verify_bool_from_log(byte[])bool": { - "call_config": { - "no_op": "CALL" - } - }, - "verify_emit(string,uint512,uint64,byte[],uint64,bool,byte[],string,uint64,uint256,ufixed32x8,ufixed256x16,bool,byte[],byte[],byte[])void": { - "call_config": { - "no_op": "CALL" - } - } - }, - "source": { - "approval": "I3ByYWdtYSB2ZXJzaW9uIDEwCiNwcmFnbWEgdHlwZXRyYWNrIGZhbHNlCgovLyBAYWxnb3JhbmRmb3VuZGF0aW9uL2FsZ29yYW5kLXR5cGVzY3JpcHQvYXJjNC9pbmRleC5kLnRzOjpDb250cmFjdC5hcHByb3ZhbFByb2dyYW0oKSAtPiB1aW50NjQ6Cm1haW46CiAgICBpbnRjYmxvY2sgMSA4IDY0IDAKICAgIGJ5dGVjYmxvY2sgMHgxNTFmN2M3NSAweDAwCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NAogICAgLy8gZXhwb3J0IGNsYXNzIEFyYzRQcmltaXRpdmVPcHNDb250cmFjdCBleHRlbmRzIENvbnRyYWN0IHsKICAgIHR4biBOdW1BcHBBcmdzCiAgICBieiBtYWluX2JhcmVfcm91dGluZ0A2MAogICAgcHVzaGJ5dGVzcyAweDk2ZjE0MTE2IDB4ZWQ2NjYwOTYgMHgyY2EwMzUyYiAweDg1OTA3ZDQwIDB4NGViMmFmNGEgMHgyY2JlYzQ1YiAweDA3NjY2ZmQ5IDB4MzcwYmFiZDMgMHgyYjZiM2VmMCAweDI3ZTIxYTk4IDB4MzM5ZGE5N2MgMHg3ODk4ZWQ5NyAweDFmMTMwY2VjIDB4Yzc0ODY2NGUgMHhhMmJhYzE0YiAweDdhNDYwY2IxIDB4ZGNhYjFmMDEgMHg5N2Q5MDY0ZCAweGNlMDZjMmEwIDB4N2MxMWUzNzUgMHhkY2RiY2VlMCAweDc3YTRiNjhkIDB4NGY1NDA2MjYgMHgwOTVhZWQ0MSAweGRmNzhjZGM2IDB4ZTNiN2U5MTggMHg1NTMzNzAwOCAweDliYjFjZDY2IDB4ODE0ODRkOWQgMHg3OWU5Y2IwMyAweDlhMDNkZjEwIDB4ZDNmMGU0NGIgMHg2NzNkYjJiZCAweDk4MmRiMjMzIDB4YWZmYmRmMGUgMHg4ZTRhMzBmNyAweDI4OGFmNzZlIDB4OGJkODRhMDQgMHhmY2Q1NWUxZiAweDBmMTU3NGZlIDB4YjJjYjEzYmUgMHhkMDU5ZWVhNyAweDRjYzRjMTU3IDB4M2QxN2FjNmUgMHhmN2YzZDVmYyAweGY4YzhmOGQ1IDB4NDNmNzE2MmEgMHg0MmUwOTA3NSAweGQ5NTZmNTc1IDB4NmMwMTYwZGYgMHhhODkwMTUwYiAweDBiMmY0YzNmIDB4OWRiOWQzMjcgMHhlNGQ5NTBhMSAweGI2MDVlODBjIC8vIG1ldGhvZCAidmVyaWZ5X3VpbnRuX3VpbnRuX2VxKGJ5dGVbXSxieXRlW10pYm9vbCIsIG1ldGhvZCAidmVyaWZ5X2JpZ3VpbnRuX3VpbnRuX2VxKGJ5dGVbXSxieXRlW10pYm9vbCIsIG1ldGhvZCAidmVyaWZ5X3VpbnRuX2JpZ3VpbnRuX2VxKGJ5dGVbXSxieXRlW10pYm9vbCIsIG1ldGhvZCAidmVyaWZ5X2JpZ3VpbnRuX2JpZ3VpbnRuX2VxKGJ5dGVbXSxieXRlW10pYm9vbCIsIG1ldGhvZCAidmVyaWZ5X2J5dGVfYnl0ZV9lcShieXRlW10sYnl0ZVtdKWJvb2wiLCBtZXRob2QgInZlcmlmeV91aW50bl91aW50bl9uZShieXRlW10sYnl0ZVtdKWJvb2wiLCBtZXRob2QgInZlcmlmeV9iaWd1aW50bl91aW50bl9uZShieXRlW10sYnl0ZVtdKWJvb2wiLCBtZXRob2QgInZlcmlmeV91aW50bl9iaWd1aW50bl9uZShieXRlW10sYnl0ZVtdKWJvb2wiLCBtZXRob2QgInZlcmlmeV9iaWd1aW50bl9iaWd1aW50bl9uZShieXRlW10sYnl0ZVtdKWJvb2wiLCBtZXRob2QgInZlcmlmeV9ieXRlX2J5dGVfbmUoYnl0ZVtdLGJ5dGVbXSlib29sIiwgbWV0aG9kICJ2ZXJpZnlfdWludG5fdWludG5fbHQoYnl0ZVtdLGJ5dGVbXSlib29sIiwgbWV0aG9kICJ2ZXJpZnlfYmlndWludG5fdWludG5fbHQoYnl0ZVtdLGJ5dGVbXSlib29sIiwgbWV0aG9kICJ2ZXJpZnlfdWludG5fYmlndWludG5fbHQoYnl0ZVtdLGJ5dGVbXSlib29sIiwgbWV0aG9kICJ2ZXJpZnlfYmlndWludG5fYmlndWludG5fbHQoYnl0ZVtdLGJ5dGVbXSlib29sIiwgbWV0aG9kICJ2ZXJpZnlfYnl0ZV9ieXRlX2x0KGJ5dGVbXSxieXRlW10pYm9vbCIsIG1ldGhvZCAidmVyaWZ5X3VpbnRuX3VpbnRuX2xlKGJ5dGVbXSxieXRlW10pYm9vbCIsIG1ldGhvZCAidmVyaWZ5X2JpZ3VpbnRuX3VpbnRuX2xlKGJ5dGVbXSxieXRlW10pYm9vbCIsIG1ldGhvZCAidmVyaWZ5X3VpbnRuX2JpZ3VpbnRuX2xlKGJ5dGVbXSxieXRlW10pYm9vbCIsIG1ldGhvZCAidmVyaWZ5X2JpZ3VpbnRuX2JpZ3VpbnRuX2xlKGJ5dGVbXSxieXRlW10pYm9vbCIsIG1ldGhvZCAidmVyaWZ5X2J5dGVfYnl0ZV9sZShieXRlW10sYnl0ZVtdKWJvb2wiLCBtZXRob2QgInZlcmlmeV91aW50bl91aW50bl9ndChieXRlW10sYnl0ZVtdKWJvb2wiLCBtZXRob2QgInZlcmlmeV9iaWd1aW50bl91aW50bl9ndChieXRlW10sYnl0ZVtdKWJvb2wiLCBtZXRob2QgInZlcmlmeV91aW50bl9iaWd1aW50bl9ndChieXRlW10sYnl0ZVtdKWJvb2wiLCBtZXRob2QgInZlcmlmeV9iaWd1aW50bl9iaWd1aW50bl9ndChieXRlW10sYnl0ZVtdKWJvb2wiLCBtZXRob2QgInZlcmlmeV9ieXRlX2J5dGVfZ3QoYnl0ZVtdLGJ5dGVbXSlib29sIiwgbWV0aG9kICJ2ZXJpZnlfdWludG5fdWludG5fZ2UoYnl0ZVtdLGJ5dGVbXSlib29sIiwgbWV0aG9kICJ2ZXJpZnlfYmlndWludG5fdWludG5fZ2UoYnl0ZVtdLGJ5dGVbXSlib29sIiwgbWV0aG9kICJ2ZXJpZnlfdWludG5fYmlndWludG5fZ2UoYnl0ZVtdLGJ5dGVbXSlib29sIiwgbWV0aG9kICJ2ZXJpZnlfYmlndWludG5fYmlndWludG5fZ2UoYnl0ZVtdLGJ5dGVbXSlib29sIiwgbWV0aG9kICJ2ZXJpZnlfYnl0ZV9ieXRlX2dlKGJ5dGVbXSxieXRlW10pYm9vbCIsIG1ldGhvZCAidmVyaWZ5X3VpbnRuX2luaXQoYnl0ZVtdKXVpbnQzMiIsIG1ldGhvZCAidmVyaWZ5X2JpZ3VpbnRuX2luaXQoYnl0ZVtdKXVpbnQyNTYiLCBtZXRob2QgInZlcmlmeV9ieXRlX2luaXQoYnl0ZVtdKWJ5dGUiLCBtZXRob2QgInZlcmlmeV91aW50bl9mcm9tX2J5dGVzKGJ5dGVbXSl1aW50MzIiLCBtZXRob2QgInZlcmlmeV9iaWd1aW50bl9mcm9tX2J5dGVzKGJ5dGVbXSl1aW50MjU2IiwgbWV0aG9kICJ2ZXJpZnlfYnl0ZV9mcm9tX2J5dGVzKGJ5dGVbXSlieXRlIiwgbWV0aG9kICJ2ZXJpZnlfdWludG5fZnJvbV9sb2coYnl0ZVtdKXVpbnQzMiIsIG1ldGhvZCAidmVyaWZ5X2JpZ3VpbnRuX2Zyb21fbG9nKGJ5dGVbXSl1aW50MjU2IiwgbWV0aG9kICJ2ZXJpZnlfYnl0ZV9mcm9tX2xvZyhieXRlW10pYnl0ZSIsIG1ldGhvZCAidmVyaWZ5X3VmaXhlZG54bV9ieXRlcyh1Zml4ZWQzMng4KWJ5dGVbXSIsIG1ldGhvZCAidmVyaWZ5X2JpZ3VmaXhlZG54bV9ieXRlcyh1Zml4ZWQyNTZ4MTYpYnl0ZVtdIiwgbWV0aG9kICJ2ZXJpZnlfdWZpeGVkbnhtX2Zyb21fYnl0ZXMoYnl0ZVtdKXVmaXhlZDMyeDgiLCBtZXRob2QgInZlcmlmeV9iaWd1Zml4ZWRueG1fZnJvbV9ieXRlcyhieXRlW10pdWZpeGVkMjU2eDE2IiwgbWV0aG9kICJ2ZXJpZnlfdWZpeGVkbnhtX2Zyb21fbG9nKGJ5dGVbXSl1Zml4ZWQzMng4IiwgbWV0aG9kICJ2ZXJpZnlfYmlndWZpeGVkbnhtX2Zyb21fbG9nKGJ5dGVbXSl1Zml4ZWQyNTZ4MTYiLCBtZXRob2QgInZlcmlmeV9zdHJpbmdfaW5pdChzdHJpbmcpc3RyaW5nIiwgbWV0aG9kICJ2ZXJpZnlfc3RyaW5nX2FkZChzdHJpbmcsc3RyaW5nKXN0cmluZyIsIG1ldGhvZCAidmVyaWZ5X3N0cmluZ19lcShzdHJpbmcsc3RyaW5nKWJvb2wiLCBtZXRob2QgInZlcmlmeV9zdHJpbmdfYnl0ZXMoc3RyaW5nKWJ5dGVbXSIsIG1ldGhvZCAidmVyaWZ5X3N0cmluZ19mcm9tX2J5dGVzKGJ5dGVbXSlzdHJpbmciLCBtZXRob2QgInZlcmlmeV9zdHJpbmdfZnJvbV9sb2coYnl0ZVtdKXN0cmluZyIsIG1ldGhvZCAidmVyaWZ5X2Jvb2xfYnl0ZXMoYm9vbClieXRlW10iLCBtZXRob2QgInZlcmlmeV9ib29sX2Zyb21fYnl0ZXMoYnl0ZVtdKWJvb2wiLCBtZXRob2QgInZlcmlmeV9ib29sX2Zyb21fbG9nKGJ5dGVbXSlib29sIiwgbWV0aG9kICJ2ZXJpZnlfZW1pdChzdHJpbmcsdWludDUxMix1aW50NjQsYnl0ZVtdLHVpbnQ2NCxib29sLGJ5dGVbXSxzdHJpbmcsdWludDY0LHVpbnQyNTYsdWZpeGVkMzJ4OCx1Zml4ZWQyNTZ4MTYsYm9vbCxieXRlW10sYnl0ZVtdLGJ5dGVbXSl2b2lkIgogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMAogICAgbWF0Y2ggbWFpbl92ZXJpZnlfdWludG5fdWludG5fZXFfcm91dGVAMyBtYWluX3ZlcmlmeV9iaWd1aW50bl91aW50bl9lcV9yb3V0ZUA0IG1haW5fdmVyaWZ5X3VpbnRuX2JpZ3VpbnRuX2VxX3JvdXRlQDUgbWFpbl92ZXJpZnlfYmlndWludG5fYmlndWludG5fZXFfcm91dGVANiBtYWluX3ZlcmlmeV9ieXRlX2J5dGVfZXFfcm91dGVANyBtYWluX3ZlcmlmeV91aW50bl91aW50bl9uZV9yb3V0ZUA4IG1haW5fdmVyaWZ5X2JpZ3VpbnRuX3VpbnRuX25lX3JvdXRlQDkgbWFpbl92ZXJpZnlfdWludG5fYmlndWludG5fbmVfcm91dGVAMTAgbWFpbl92ZXJpZnlfYmlndWludG5fYmlndWludG5fbmVfcm91dGVAMTEgbWFpbl92ZXJpZnlfYnl0ZV9ieXRlX25lX3JvdXRlQDEyIG1haW5fdmVyaWZ5X3VpbnRuX3VpbnRuX2x0X3JvdXRlQDEzIG1haW5fdmVyaWZ5X2JpZ3VpbnRuX3VpbnRuX2x0X3JvdXRlQDE0IG1haW5fdmVyaWZ5X3VpbnRuX2JpZ3VpbnRuX2x0X3JvdXRlQDE1IG1haW5fdmVyaWZ5X2JpZ3VpbnRuX2JpZ3VpbnRuX2x0X3JvdXRlQDE2IG1haW5fdmVyaWZ5X2J5dGVfYnl0ZV9sdF9yb3V0ZUAxNyBtYWluX3ZlcmlmeV91aW50bl91aW50bl9sZV9yb3V0ZUAxOCBtYWluX3ZlcmlmeV9iaWd1aW50bl91aW50bl9sZV9yb3V0ZUAxOSBtYWluX3ZlcmlmeV91aW50bl9iaWd1aW50bl9sZV9yb3V0ZUAyMCBtYWluX3ZlcmlmeV9iaWd1aW50bl9iaWd1aW50bl9sZV9yb3V0ZUAyMSBtYWluX3ZlcmlmeV9ieXRlX2J5dGVfbGVfcm91dGVAMjIgbWFpbl92ZXJpZnlfdWludG5fdWludG5fZ3Rfcm91dGVAMjMgbWFpbl92ZXJpZnlfYmlndWludG5fdWludG5fZ3Rfcm91dGVAMjQgbWFpbl92ZXJpZnlfdWludG5fYmlndWludG5fZ3Rfcm91dGVAMjUgbWFpbl92ZXJpZnlfYmlndWludG5fYmlndWludG5fZ3Rfcm91dGVAMjYgbWFpbl92ZXJpZnlfYnl0ZV9ieXRlX2d0X3JvdXRlQDI3IG1haW5fdmVyaWZ5X3VpbnRuX3VpbnRuX2dlX3JvdXRlQDI4IG1haW5fdmVyaWZ5X2JpZ3VpbnRuX3VpbnRuX2dlX3JvdXRlQDI5IG1haW5fdmVyaWZ5X3VpbnRuX2JpZ3VpbnRuX2dlX3JvdXRlQDMwIG1haW5fdmVyaWZ5X2JpZ3VpbnRuX2JpZ3VpbnRuX2dlX3JvdXRlQDMxIG1haW5fdmVyaWZ5X2J5dGVfYnl0ZV9nZV9yb3V0ZUAzMiBtYWluX3ZlcmlmeV91aW50bl9pbml0X3JvdXRlQDMzIG1haW5fdmVyaWZ5X2JpZ3VpbnRuX2luaXRfcm91dGVAMzQgbWFpbl92ZXJpZnlfYnl0ZV9pbml0X3JvdXRlQDM1IG1haW5fdmVyaWZ5X3VpbnRuX2Zyb21fYnl0ZXNfcm91dGVAMzYgbWFpbl92ZXJpZnlfYmlndWludG5fZnJvbV9ieXRlc19yb3V0ZUAzNyBtYWluX3ZlcmlmeV9ieXRlX2Zyb21fYnl0ZXNfcm91dGVAMzggbWFpbl92ZXJpZnlfdWludG5fZnJvbV9sb2dfcm91dGVAMzkgbWFpbl92ZXJpZnlfYmlndWludG5fZnJvbV9sb2dfcm91dGVANDAgbWFpbl92ZXJpZnlfYnl0ZV9mcm9tX2xvZ19yb3V0ZUA0MSBtYWluX3ZlcmlmeV91Zml4ZWRueG1fYnl0ZXNfcm91dGVANDIgbWFpbl92ZXJpZnlfYmlndWZpeGVkbnhtX2J5dGVzX3JvdXRlQDQzIG1haW5fdmVyaWZ5X3VmaXhlZG54bV9mcm9tX2J5dGVzX3JvdXRlQDQ0IG1haW5fdmVyaWZ5X2JpZ3VmaXhlZG54bV9mcm9tX2J5dGVzX3JvdXRlQDQ1IG1haW5fdmVyaWZ5X3VmaXhlZG54bV9mcm9tX2xvZ19yb3V0ZUA0NiBtYWluX3ZlcmlmeV9iaWd1Zml4ZWRueG1fZnJvbV9sb2dfcm91dGVANDcgbWFpbl92ZXJpZnlfc3RyaW5nX2luaXRfcm91dGVANDggbWFpbl92ZXJpZnlfc3RyaW5nX2FkZF9yb3V0ZUA0OSBtYWluX3ZlcmlmeV9zdHJpbmdfZXFfcm91dGVANTAgbWFpbl92ZXJpZnlfc3RyaW5nX2J5dGVzX3JvdXRlQDUxIG1haW5fdmVyaWZ5X3N0cmluZ19mcm9tX2J5dGVzX3JvdXRlQDUyIG1haW5fdmVyaWZ5X3N0cmluZ19mcm9tX2xvZ19yb3V0ZUA1MyBtYWluX3ZlcmlmeV9ib29sX2J5dGVzX3JvdXRlQDU0IG1haW5fdmVyaWZ5X2Jvb2xfZnJvbV9ieXRlc19yb3V0ZUA1NSBtYWluX3ZlcmlmeV9ib29sX2Zyb21fbG9nX3JvdXRlQDU2IG1haW5fdmVyaWZ5X2VtaXRfcm91dGVANTcKCm1haW5fYWZ0ZXJfaWZfZWxzZUA2NDoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo0CiAgICAvLyBleHBvcnQgY2xhc3MgQXJjNFByaW1pdGl2ZU9wc0NvbnRyYWN0IGV4dGVuZHMgQ29udHJhY3QgewogICAgaW50Y18zIC8vIDAKICAgIHJldHVybgoKbWFpbl92ZXJpZnlfZW1pdF9yb3V0ZUA1NzoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czozNDkKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIG5vdCBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGNhbiBvbmx5IGNhbGwgd2hlbiBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo0CiAgICAvLyBleHBvcnQgY2xhc3MgQXJjNFByaW1pdGl2ZU9wc0NvbnRyYWN0IGV4dGVuZHMgQ29udHJhY3QgewogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMgogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMwogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgNAogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgNQogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgNgogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgNwogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgOAogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgOQogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMTAKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDExCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxMgogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMTMKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDE0CiAgICBleHRyYWN0IDIgMAogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMTUKICAgIGR1cAogICAgaW50Y18zIC8vIDAKICAgIGV4dHJhY3RfdWludDE2CiAgICBkaWcgMQogICAgcHVzaGludCAyIC8vIDIKICAgIGV4dHJhY3RfdWludDE2CiAgICBzdWJzdHJpbmczCiAgICBleHRyYWN0IDIgMAogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMTUKICAgIGR1cAogICAgcHVzaGludCAyIC8vIDIKICAgIGV4dHJhY3RfdWludDE2CiAgICBkaWcgMQogICAgbGVuCiAgICBzdWJzdHJpbmczCiAgICBleHRyYWN0IDIgMAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjM0OQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X2VtaXQKICAgIGludGNfMCAvLyAxCiAgICByZXR1cm4KCm1haW5fdmVyaWZ5X2Jvb2xfZnJvbV9sb2dfcm91dGVANTY6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MzQzCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBub3QgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBjYW4gb25seSBjYWxsIHdoZW4gbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NAogICAgLy8gZXhwb3J0IGNsYXNzIEFyYzRQcmltaXRpdmVPcHNDb250cmFjdCBleHRlbmRzIENvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGV4dHJhY3QgMiAwCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MzQzCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfYm9vbF9mcm9tX2xvZwogICAgYnl0ZWNfMCAvLyAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50Y18wIC8vIDEKICAgIHJldHVybgoKbWFpbl92ZXJpZnlfYm9vbF9mcm9tX2J5dGVzX3JvdXRlQDU1OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjMzOQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgbm90IE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gY2FuIG9ubHkgY2FsbCB3aGVuIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjQKICAgIC8vIGV4cG9ydCBjbGFzcyBBcmM0UHJpbWl0aXZlT3BzQ29udHJhY3QgZXh0ZW5kcyBDb250cmFjdCB7CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBleHRyYWN0IDIgMAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjMzOQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGJ5dGVjXzAgLy8gMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludGNfMCAvLyAxCiAgICByZXR1cm4KCm1haW5fdmVyaWZ5X2Jvb2xfYnl0ZXNfcm91dGVANTQ6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MzM1CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBub3QgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBjYW4gb25seSBjYWxsIHdoZW4gbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NAogICAgLy8gZXhwb3J0IGNsYXNzIEFyYzRQcmltaXRpdmVPcHNDb250cmFjdCBleHRlbmRzIENvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czozMzUKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBkdXAKICAgIGxlbgogICAgaXRvYgogICAgZXh0cmFjdCA2IDIKICAgIHN3YXAKICAgIGNvbmNhdAogICAgYnl0ZWNfMCAvLyAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50Y18wIC8vIDEKICAgIHJldHVybgoKbWFpbl92ZXJpZnlfc3RyaW5nX2Zyb21fbG9nX3JvdXRlQDUzOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjMzMQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgbm90IE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gY2FuIG9ubHkgY2FsbCB3aGVuIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjQKICAgIC8vIGV4cG9ydCBjbGFzcyBBcmM0UHJpbWl0aXZlT3BzQ29udHJhY3QgZXh0ZW5kcyBDb250cmFjdCB7CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBleHRyYWN0IDIgMAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjMzMQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X3N0cmluZ19mcm9tX2xvZwogICAgYnl0ZWNfMCAvLyAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50Y18wIC8vIDEKICAgIHJldHVybgoKbWFpbl92ZXJpZnlfc3RyaW5nX2Zyb21fYnl0ZXNfcm91dGVANTI6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MzI3CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBub3QgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBjYW4gb25seSBjYWxsIHdoZW4gbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NAogICAgLy8gZXhwb3J0IGNsYXNzIEFyYzRQcmltaXRpdmVPcHNDb250cmFjdCBleHRlbmRzIENvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGV4dHJhY3QgMiAwCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MzI3CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgYnl0ZWNfMCAvLyAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50Y18wIC8vIDEKICAgIHJldHVybgoKbWFpbl92ZXJpZnlfc3RyaW5nX2J5dGVzX3JvdXRlQDUxOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjMyMgogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgbm90IE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gY2FuIG9ubHkgY2FsbCB3aGVuIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjQKICAgIC8vIGV4cG9ydCBjbGFzcyBBcmM0UHJpbWl0aXZlT3BzQ29udHJhY3QgZXh0ZW5kcyBDb250cmFjdCB7CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBleHRyYWN0IDIgMAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjMyMgogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X3N0cmluZ19ieXRlcwogICAgZHVwCiAgICBsZW4KICAgIGl0b2IKICAgIGV4dHJhY3QgNiAyCiAgICBzd2FwCiAgICBjb25jYXQKICAgIGJ5dGVjXzAgLy8gMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludGNfMCAvLyAxCiAgICByZXR1cm4KCm1haW5fdmVyaWZ5X3N0cmluZ19lcV9yb3V0ZUA1MDoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czozMTgKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIG5vdCBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGNhbiBvbmx5IGNhbGwgd2hlbiBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo0CiAgICAvLyBleHBvcnQgY2xhc3MgQXJjNFByaW1pdGl2ZU9wc0NvbnRyYWN0IGV4dGVuZHMgQ29udHJhY3QgewogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjMxOAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X3N0cmluZ19lcQogICAgYnl0ZWNfMSAvLyAweDAwCiAgICBpbnRjXzMgLy8gMAogICAgdW5jb3ZlciAyCiAgICBzZXRiaXQKICAgIGJ5dGVjXzAgLy8gMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludGNfMCAvLyAxCiAgICByZXR1cm4KCm1haW5fdmVyaWZ5X3N0cmluZ19hZGRfcm91dGVANDk6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MzEzCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBub3QgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBjYW4gb25seSBjYWxsIHdoZW4gbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NAogICAgLy8gZXhwb3J0IGNsYXNzIEFyYzRQcmltaXRpdmVPcHNDb250cmFjdCBleHRlbmRzIENvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDIKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czozMTMKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV9zdHJpbmdfYWRkCiAgICBieXRlY18wIC8vIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnRjXzAgLy8gMQogICAgcmV0dXJuCgptYWluX3ZlcmlmeV9zdHJpbmdfaW5pdF9yb3V0ZUA0ODoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czozMDgKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIG5vdCBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGNhbiBvbmx5IGNhbGwgd2hlbiBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo0CiAgICAvLyBleHBvcnQgY2xhc3MgQXJjNFByaW1pdGl2ZU9wc0NvbnRyYWN0IGV4dGVuZHMgQ29udHJhY3QgewogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgZXh0cmFjdCAyIDAKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czozMDgKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV9zdHJpbmdfaW5pdAogICAgYnl0ZWNfMCAvLyAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50Y18wIC8vIDEKICAgIHJldHVybgoKbWFpbl92ZXJpZnlfYmlndWZpeGVkbnhtX2Zyb21fbG9nX3JvdXRlQDQ3OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjMwNAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgbm90IE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gY2FuIG9ubHkgY2FsbCB3aGVuIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjQKICAgIC8vIGV4cG9ydCBjbGFzcyBBcmM0UHJpbWl0aXZlT3BzQ29udHJhY3QgZXh0ZW5kcyBDb250cmFjdCB7CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBleHRyYWN0IDIgMAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjMwNAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X2JpZ3VmaXhlZG54bV9mcm9tX2xvZwogICAgYnl0ZWNfMCAvLyAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50Y18wIC8vIDEKICAgIHJldHVybgoKbWFpbl92ZXJpZnlfdWZpeGVkbnhtX2Zyb21fbG9nX3JvdXRlQDQ2OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjMwMAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgbm90IE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gY2FuIG9ubHkgY2FsbCB3aGVuIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjQKICAgIC8vIGV4cG9ydCBjbGFzcyBBcmM0UHJpbWl0aXZlT3BzQ29udHJhY3QgZXh0ZW5kcyBDb250cmFjdCB7CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBleHRyYWN0IDIgMAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjMwMAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X3VmaXhlZG54bV9mcm9tX2xvZwogICAgYnl0ZWNfMCAvLyAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50Y18wIC8vIDEKICAgIHJldHVybgoKbWFpbl92ZXJpZnlfYmlndWZpeGVkbnhtX2Zyb21fYnl0ZXNfcm91dGVANDU6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6Mjk2CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBub3QgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBjYW4gb25seSBjYWxsIHdoZW4gbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NAogICAgLy8gZXhwb3J0IGNsYXNzIEFyYzRQcmltaXRpdmVPcHNDb250cmFjdCBleHRlbmRzIENvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGV4dHJhY3QgMiAwCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6Mjk2CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgYnl0ZWNfMCAvLyAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50Y18wIC8vIDEKICAgIHJldHVybgoKbWFpbl92ZXJpZnlfdWZpeGVkbnhtX2Zyb21fYnl0ZXNfcm91dGVANDQ6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MjkyCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBub3QgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBjYW4gb25seSBjYWxsIHdoZW4gbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NAogICAgLy8gZXhwb3J0IGNsYXNzIEFyYzRQcmltaXRpdmVPcHNDb250cmFjdCBleHRlbmRzIENvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGV4dHJhY3QgMiAwCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MjkyCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgYnl0ZWNfMCAvLyAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50Y18wIC8vIDEKICAgIHJldHVybgoKbWFpbl92ZXJpZnlfYmlndWZpeGVkbnhtX2J5dGVzX3JvdXRlQDQzOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjI4OAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgbm90IE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gY2FuIG9ubHkgY2FsbCB3aGVuIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjQKICAgIC8vIGV4cG9ydCBjbGFzcyBBcmM0UHJpbWl0aXZlT3BzQ29udHJhY3QgZXh0ZW5kcyBDb250cmFjdCB7CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6Mjg4CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgZHVwCiAgICBsZW4KICAgIGl0b2IKICAgIGV4dHJhY3QgNiAyCiAgICBzd2FwCiAgICBjb25jYXQKICAgIGJ5dGVjXzAgLy8gMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludGNfMCAvLyAxCiAgICByZXR1cm4KCm1haW5fdmVyaWZ5X3VmaXhlZG54bV9ieXRlc19yb3V0ZUA0MjoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoyODQKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIG5vdCBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGNhbiBvbmx5IGNhbGwgd2hlbiBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo0CiAgICAvLyBleHBvcnQgY2xhc3MgQXJjNFByaW1pdGl2ZU9wc0NvbnRyYWN0IGV4dGVuZHMgQ29udHJhY3QgewogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjI4NAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGR1cAogICAgbGVuCiAgICBpdG9iCiAgICBleHRyYWN0IDYgMgogICAgc3dhcAogICAgY29uY2F0CiAgICBieXRlY18wIC8vIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnRjXzAgLy8gMQogICAgcmV0dXJuCgptYWluX3ZlcmlmeV9ieXRlX2Zyb21fbG9nX3JvdXRlQDQxOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjI4MAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgbm90IE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gY2FuIG9ubHkgY2FsbCB3aGVuIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjQKICAgIC8vIGV4cG9ydCBjbGFzcyBBcmM0UHJpbWl0aXZlT3BzQ29udHJhY3QgZXh0ZW5kcyBDb250cmFjdCB7CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBleHRyYWN0IDIgMAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjI4MAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X2J5dGVfZnJvbV9sb2cKICAgIGJ5dGVjXzAgLy8gMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludGNfMCAvLyAxCiAgICByZXR1cm4KCm1haW5fdmVyaWZ5X2JpZ3VpbnRuX2Zyb21fbG9nX3JvdXRlQDQwOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjI3NgogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgbm90IE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gY2FuIG9ubHkgY2FsbCB3aGVuIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjQKICAgIC8vIGV4cG9ydCBjbGFzcyBBcmM0UHJpbWl0aXZlT3BzQ29udHJhY3QgZXh0ZW5kcyBDb250cmFjdCB7CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBleHRyYWN0IDIgMAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjI3NgogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X2JpZ3VpbnRuX2Zyb21fbG9nCiAgICBieXRlY18wIC8vIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnRjXzAgLy8gMQogICAgcmV0dXJuCgptYWluX3ZlcmlmeV91aW50bl9mcm9tX2xvZ19yb3V0ZUAzOToKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoyNzIKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIG5vdCBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGNhbiBvbmx5IGNhbGwgd2hlbiBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo0CiAgICAvLyBleHBvcnQgY2xhc3MgQXJjNFByaW1pdGl2ZU9wc0NvbnRyYWN0IGV4dGVuZHMgQ29udHJhY3QgewogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgZXh0cmFjdCAyIDAKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoyNzIKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV91aW50bl9mcm9tX2xvZwogICAgYnl0ZWNfMCAvLyAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50Y18wIC8vIDEKICAgIHJldHVybgoKbWFpbl92ZXJpZnlfYnl0ZV9mcm9tX2J5dGVzX3JvdXRlQDM4OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjI2OAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgbm90IE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gY2FuIG9ubHkgY2FsbCB3aGVuIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjQKICAgIC8vIGV4cG9ydCBjbGFzcyBBcmM0UHJpbWl0aXZlT3BzQ29udHJhY3QgZXh0ZW5kcyBDb250cmFjdCB7CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBleHRyYWN0IDIgMAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjI2OAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGJ5dGVjXzAgLy8gMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludGNfMCAvLyAxCiAgICByZXR1cm4KCm1haW5fdmVyaWZ5X2JpZ3VpbnRuX2Zyb21fYnl0ZXNfcm91dGVAMzc6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MjY0CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBub3QgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBjYW4gb25seSBjYWxsIHdoZW4gbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NAogICAgLy8gZXhwb3J0IGNsYXNzIEFyYzRQcmltaXRpdmVPcHNDb250cmFjdCBleHRlbmRzIENvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGV4dHJhY3QgMiAwCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MjY0CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgYnl0ZWNfMCAvLyAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50Y18wIC8vIDEKICAgIHJldHVybgoKbWFpbl92ZXJpZnlfdWludG5fZnJvbV9ieXRlc19yb3V0ZUAzNjoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoyNjAKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIG5vdCBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGNhbiBvbmx5IGNhbGwgd2hlbiBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo0CiAgICAvLyBleHBvcnQgY2xhc3MgQXJjNFByaW1pdGl2ZU9wc0NvbnRyYWN0IGV4dGVuZHMgQ29udHJhY3QgewogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgZXh0cmFjdCAyIDAKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoyNjAKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBieXRlY18wIC8vIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnRjXzAgLy8gMQogICAgcmV0dXJuCgptYWluX3ZlcmlmeV9ieXRlX2luaXRfcm91dGVAMzU6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MjU1CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBub3QgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBjYW4gb25seSBjYWxsIHdoZW4gbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NAogICAgLy8gZXhwb3J0IGNsYXNzIEFyYzRQcmltaXRpdmVPcHNDb250cmFjdCBleHRlbmRzIENvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGV4dHJhY3QgMiAwCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MjU1CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfYnl0ZV9pbml0CiAgICBieXRlY18wIC8vIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnRjXzAgLy8gMQogICAgcmV0dXJuCgptYWluX3ZlcmlmeV9iaWd1aW50bl9pbml0X3JvdXRlQDM0OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjI1MAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgbm90IE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gY2FuIG9ubHkgY2FsbCB3aGVuIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjQKICAgIC8vIGV4cG9ydCBjbGFzcyBBcmM0UHJpbWl0aXZlT3BzQ29udHJhY3QgZXh0ZW5kcyBDb250cmFjdCB7CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBleHRyYWN0IDIgMAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjI1MAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X2JpZ3VpbnRuX2luaXQKICAgIGJ5dGVjXzAgLy8gMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludGNfMCAvLyAxCiAgICByZXR1cm4KCm1haW5fdmVyaWZ5X3VpbnRuX2luaXRfcm91dGVAMzM6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MjQ1CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBub3QgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBjYW4gb25seSBjYWxsIHdoZW4gbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NAogICAgLy8gZXhwb3J0IGNsYXNzIEFyYzRQcmltaXRpdmVPcHNDb250cmFjdCBleHRlbmRzIENvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGV4dHJhY3QgMiAwCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MjQ1CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfdWludG5faW5pdAogICAgYnl0ZWNfMCAvLyAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50Y18wIC8vIDEKICAgIHJldHVybgoKbWFpbl92ZXJpZnlfYnl0ZV9ieXRlX2dlX3JvdXRlQDMyOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjIzNwogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgbm90IE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gY2FuIG9ubHkgY2FsbCB3aGVuIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjQKICAgIC8vIGV4cG9ydCBjbGFzcyBBcmM0UHJpbWl0aXZlT3BzQ29udHJhY3QgZXh0ZW5kcyBDb250cmFjdCB7CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBleHRyYWN0IDIgMAogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMgogICAgZXh0cmFjdCAyIDAKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoyMzcKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV9ieXRlX2J5dGVfZ2UKICAgIGJ5dGVjXzEgLy8gMHgwMAogICAgaW50Y18zIC8vIDAKICAgIHVuY292ZXIgMgogICAgc2V0Yml0CiAgICBieXRlY18wIC8vIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnRjXzAgLy8gMQogICAgcmV0dXJuCgptYWluX3ZlcmlmeV9iaWd1aW50bl9iaWd1aW50bl9nZV9yb3V0ZUAzMToKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoyMjkKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIG5vdCBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGNhbiBvbmx5IGNhbGwgd2hlbiBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo0CiAgICAvLyBleHBvcnQgY2xhc3MgQXJjNFByaW1pdGl2ZU9wc0NvbnRyYWN0IGV4dGVuZHMgQ29udHJhY3QgewogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgZXh0cmFjdCAyIDAKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDIKICAgIGV4dHJhY3QgMiAwCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MjI5CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfYmlndWludG5fYmlndWludG5fZ2UKICAgIGJ5dGVjXzEgLy8gMHgwMAogICAgaW50Y18zIC8vIDAKICAgIHVuY292ZXIgMgogICAgc2V0Yml0CiAgICBieXRlY18wIC8vIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnRjXzAgLy8gMQogICAgcmV0dXJuCgptYWluX3ZlcmlmeV91aW50bl9iaWd1aW50bl9nZV9yb3V0ZUAzMDoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoyMjEKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIG5vdCBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGNhbiBvbmx5IGNhbGwgd2hlbiBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo0CiAgICAvLyBleHBvcnQgY2xhc3MgQXJjNFByaW1pdGl2ZU9wc0NvbnRyYWN0IGV4dGVuZHMgQ29udHJhY3QgewogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgZXh0cmFjdCAyIDAKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDIKICAgIGV4dHJhY3QgMiAwCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MjIxCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfdWludG5fYmlndWludG5fZ2UKICAgIGJ5dGVjXzEgLy8gMHgwMAogICAgaW50Y18zIC8vIDAKICAgIHVuY292ZXIgMgogICAgc2V0Yml0CiAgICBieXRlY18wIC8vIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnRjXzAgLy8gMQogICAgcmV0dXJuCgptYWluX3ZlcmlmeV9iaWd1aW50bl91aW50bl9nZV9yb3V0ZUAyOToKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoyMTMKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIG5vdCBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGNhbiBvbmx5IGNhbGwgd2hlbiBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo0CiAgICAvLyBleHBvcnQgY2xhc3MgQXJjNFByaW1pdGl2ZU9wc0NvbnRyYWN0IGV4dGVuZHMgQ29udHJhY3QgewogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgZXh0cmFjdCAyIDAKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDIKICAgIGV4dHJhY3QgMiAwCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MjEzCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfYmlndWludG5fdWludG5fZ2UKICAgIGJ5dGVjXzEgLy8gMHgwMAogICAgaW50Y18zIC8vIDAKICAgIHVuY292ZXIgMgogICAgc2V0Yml0CiAgICBieXRlY18wIC8vIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnRjXzAgLy8gMQogICAgcmV0dXJuCgptYWluX3ZlcmlmeV91aW50bl91aW50bl9nZV9yb3V0ZUAyODoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoyMDUKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIG5vdCBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGNhbiBvbmx5IGNhbGwgd2hlbiBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo0CiAgICAvLyBleHBvcnQgY2xhc3MgQXJjNFByaW1pdGl2ZU9wc0NvbnRyYWN0IGV4dGVuZHMgQ29udHJhY3QgewogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgZXh0cmFjdCAyIDAKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDIKICAgIGV4dHJhY3QgMiAwCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MjA1CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfdWludG5fdWludG5fZ2UKICAgIGJ5dGVjXzEgLy8gMHgwMAogICAgaW50Y18zIC8vIDAKICAgIHVuY292ZXIgMgogICAgc2V0Yml0CiAgICBieXRlY18wIC8vIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnRjXzAgLy8gMQogICAgcmV0dXJuCgptYWluX3ZlcmlmeV9ieXRlX2J5dGVfZ3Rfcm91dGVAMjc6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTk3CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBub3QgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBjYW4gb25seSBjYWxsIHdoZW4gbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NAogICAgLy8gZXhwb3J0IGNsYXNzIEFyYzRQcmltaXRpdmVPcHNDb250cmFjdCBleHRlbmRzIENvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGV4dHJhY3QgMiAwCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAyCiAgICBleHRyYWN0IDIgMAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjE5NwogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X2J5dGVfYnl0ZV9ndAogICAgYnl0ZWNfMSAvLyAweDAwCiAgICBpbnRjXzMgLy8gMAogICAgdW5jb3ZlciAyCiAgICBzZXRiaXQKICAgIGJ5dGVjXzAgLy8gMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludGNfMCAvLyAxCiAgICByZXR1cm4KCm1haW5fdmVyaWZ5X2JpZ3VpbnRuX2JpZ3VpbnRuX2d0X3JvdXRlQDI2OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjE4OQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgbm90IE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gY2FuIG9ubHkgY2FsbCB3aGVuIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjQKICAgIC8vIGV4cG9ydCBjbGFzcyBBcmM0UHJpbWl0aXZlT3BzQ29udHJhY3QgZXh0ZW5kcyBDb250cmFjdCB7CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBleHRyYWN0IDIgMAogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMgogICAgZXh0cmFjdCAyIDAKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoxODkKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV9iaWd1aW50bl9iaWd1aW50bl9ndAogICAgYnl0ZWNfMSAvLyAweDAwCiAgICBpbnRjXzMgLy8gMAogICAgdW5jb3ZlciAyCiAgICBzZXRiaXQKICAgIGJ5dGVjXzAgLy8gMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludGNfMCAvLyAxCiAgICByZXR1cm4KCm1haW5fdmVyaWZ5X3VpbnRuX2JpZ3VpbnRuX2d0X3JvdXRlQDI1OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjE4MQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgbm90IE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gY2FuIG9ubHkgY2FsbCB3aGVuIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjQKICAgIC8vIGV4cG9ydCBjbGFzcyBBcmM0UHJpbWl0aXZlT3BzQ29udHJhY3QgZXh0ZW5kcyBDb250cmFjdCB7CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBleHRyYWN0IDIgMAogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMgogICAgZXh0cmFjdCAyIDAKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoxODEKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV91aW50bl9iaWd1aW50bl9ndAogICAgYnl0ZWNfMSAvLyAweDAwCiAgICBpbnRjXzMgLy8gMAogICAgdW5jb3ZlciAyCiAgICBzZXRiaXQKICAgIGJ5dGVjXzAgLy8gMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludGNfMCAvLyAxCiAgICByZXR1cm4KCm1haW5fdmVyaWZ5X2JpZ3VpbnRuX3VpbnRuX2d0X3JvdXRlQDI0OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjE3MwogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgbm90IE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gY2FuIG9ubHkgY2FsbCB3aGVuIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjQKICAgIC8vIGV4cG9ydCBjbGFzcyBBcmM0UHJpbWl0aXZlT3BzQ29udHJhY3QgZXh0ZW5kcyBDb250cmFjdCB7CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBleHRyYWN0IDIgMAogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMgogICAgZXh0cmFjdCAyIDAKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoxNzMKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV9iaWd1aW50bl91aW50bl9ndAogICAgYnl0ZWNfMSAvLyAweDAwCiAgICBpbnRjXzMgLy8gMAogICAgdW5jb3ZlciAyCiAgICBzZXRiaXQKICAgIGJ5dGVjXzAgLy8gMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludGNfMCAvLyAxCiAgICByZXR1cm4KCm1haW5fdmVyaWZ5X3VpbnRuX3VpbnRuX2d0X3JvdXRlQDIzOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjE2NQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgbm90IE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gY2FuIG9ubHkgY2FsbCB3aGVuIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjQKICAgIC8vIGV4cG9ydCBjbGFzcyBBcmM0UHJpbWl0aXZlT3BzQ29udHJhY3QgZXh0ZW5kcyBDb250cmFjdCB7CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBleHRyYWN0IDIgMAogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMgogICAgZXh0cmFjdCAyIDAKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoxNjUKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV91aW50bl91aW50bl9ndAogICAgYnl0ZWNfMSAvLyAweDAwCiAgICBpbnRjXzMgLy8gMAogICAgdW5jb3ZlciAyCiAgICBzZXRiaXQKICAgIGJ5dGVjXzAgLy8gMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludGNfMCAvLyAxCiAgICByZXR1cm4KCm1haW5fdmVyaWZ5X2J5dGVfYnl0ZV9sZV9yb3V0ZUAyMjoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoxNTcKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIG5vdCBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGNhbiBvbmx5IGNhbGwgd2hlbiBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo0CiAgICAvLyBleHBvcnQgY2xhc3MgQXJjNFByaW1pdGl2ZU9wc0NvbnRyYWN0IGV4dGVuZHMgQ29udHJhY3QgewogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgZXh0cmFjdCAyIDAKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDIKICAgIGV4dHJhY3QgMiAwCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTU3CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfYnl0ZV9ieXRlX2xlCiAgICBieXRlY18xIC8vIDB4MDAKICAgIGludGNfMyAvLyAwCiAgICB1bmNvdmVyIDIKICAgIHNldGJpdAogICAgYnl0ZWNfMCAvLyAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50Y18wIC8vIDEKICAgIHJldHVybgoKbWFpbl92ZXJpZnlfYmlndWludG5fYmlndWludG5fbGVfcm91dGVAMjE6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTQ5CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBub3QgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBjYW4gb25seSBjYWxsIHdoZW4gbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NAogICAgLy8gZXhwb3J0IGNsYXNzIEFyYzRQcmltaXRpdmVPcHNDb250cmFjdCBleHRlbmRzIENvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGV4dHJhY3QgMiAwCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAyCiAgICBleHRyYWN0IDIgMAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjE0OQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X2JpZ3VpbnRuX2JpZ3VpbnRuX2xlCiAgICBieXRlY18xIC8vIDB4MDAKICAgIGludGNfMyAvLyAwCiAgICB1bmNvdmVyIDIKICAgIHNldGJpdAogICAgYnl0ZWNfMCAvLyAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50Y18wIC8vIDEKICAgIHJldHVybgoKbWFpbl92ZXJpZnlfdWludG5fYmlndWludG5fbGVfcm91dGVAMjA6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTQxCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBub3QgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBjYW4gb25seSBjYWxsIHdoZW4gbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NAogICAgLy8gZXhwb3J0IGNsYXNzIEFyYzRQcmltaXRpdmVPcHNDb250cmFjdCBleHRlbmRzIENvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGV4dHJhY3QgMiAwCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAyCiAgICBleHRyYWN0IDIgMAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjE0MQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X3VpbnRuX2JpZ3VpbnRuX2xlCiAgICBieXRlY18xIC8vIDB4MDAKICAgIGludGNfMyAvLyAwCiAgICB1bmNvdmVyIDIKICAgIHNldGJpdAogICAgYnl0ZWNfMCAvLyAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50Y18wIC8vIDEKICAgIHJldHVybgoKbWFpbl92ZXJpZnlfYmlndWludG5fdWludG5fbGVfcm91dGVAMTk6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTMzCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBub3QgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBjYW4gb25seSBjYWxsIHdoZW4gbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NAogICAgLy8gZXhwb3J0IGNsYXNzIEFyYzRQcmltaXRpdmVPcHNDb250cmFjdCBleHRlbmRzIENvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGV4dHJhY3QgMiAwCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAyCiAgICBleHRyYWN0IDIgMAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjEzMwogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X2JpZ3VpbnRuX3VpbnRuX2xlCiAgICBieXRlY18xIC8vIDB4MDAKICAgIGludGNfMyAvLyAwCiAgICB1bmNvdmVyIDIKICAgIHNldGJpdAogICAgYnl0ZWNfMCAvLyAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50Y18wIC8vIDEKICAgIHJldHVybgoKbWFpbl92ZXJpZnlfdWludG5fdWludG5fbGVfcm91dGVAMTg6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTI1CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBub3QgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBjYW4gb25seSBjYWxsIHdoZW4gbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NAogICAgLy8gZXhwb3J0IGNsYXNzIEFyYzRQcmltaXRpdmVPcHNDb250cmFjdCBleHRlbmRzIENvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGV4dHJhY3QgMiAwCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAyCiAgICBleHRyYWN0IDIgMAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjEyNQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X3VpbnRuX3VpbnRuX2xlCiAgICBieXRlY18xIC8vIDB4MDAKICAgIGludGNfMyAvLyAwCiAgICB1bmNvdmVyIDIKICAgIHNldGJpdAogICAgYnl0ZWNfMCAvLyAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50Y18wIC8vIDEKICAgIHJldHVybgoKbWFpbl92ZXJpZnlfYnl0ZV9ieXRlX2x0X3JvdXRlQDE3OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjExNwogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgbm90IE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gY2FuIG9ubHkgY2FsbCB3aGVuIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjQKICAgIC8vIGV4cG9ydCBjbGFzcyBBcmM0UHJpbWl0aXZlT3BzQ29udHJhY3QgZXh0ZW5kcyBDb250cmFjdCB7CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBleHRyYWN0IDIgMAogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMgogICAgZXh0cmFjdCAyIDAKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoxMTcKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV9ieXRlX2J5dGVfbHQKICAgIGJ5dGVjXzEgLy8gMHgwMAogICAgaW50Y18zIC8vIDAKICAgIHVuY292ZXIgMgogICAgc2V0Yml0CiAgICBieXRlY18wIC8vIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnRjXzAgLy8gMQogICAgcmV0dXJuCgptYWluX3ZlcmlmeV9iaWd1aW50bl9iaWd1aW50bl9sdF9yb3V0ZUAxNjoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoxMDkKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIG5vdCBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGNhbiBvbmx5IGNhbGwgd2hlbiBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo0CiAgICAvLyBleHBvcnQgY2xhc3MgQXJjNFByaW1pdGl2ZU9wc0NvbnRyYWN0IGV4dGVuZHMgQ29udHJhY3QgewogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgZXh0cmFjdCAyIDAKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDIKICAgIGV4dHJhY3QgMiAwCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTA5CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfYmlndWludG5fYmlndWludG5fbHQKICAgIGJ5dGVjXzEgLy8gMHgwMAogICAgaW50Y18zIC8vIDAKICAgIHVuY292ZXIgMgogICAgc2V0Yml0CiAgICBieXRlY18wIC8vIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnRjXzAgLy8gMQogICAgcmV0dXJuCgptYWluX3ZlcmlmeV91aW50bl9iaWd1aW50bl9sdF9yb3V0ZUAxNToKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoxMDEKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIG5vdCBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGNhbiBvbmx5IGNhbGwgd2hlbiBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo0CiAgICAvLyBleHBvcnQgY2xhc3MgQXJjNFByaW1pdGl2ZU9wc0NvbnRyYWN0IGV4dGVuZHMgQ29udHJhY3QgewogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgZXh0cmFjdCAyIDAKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDIKICAgIGV4dHJhY3QgMiAwCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTAxCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfdWludG5fYmlndWludG5fbHQKICAgIGJ5dGVjXzEgLy8gMHgwMAogICAgaW50Y18zIC8vIDAKICAgIHVuY292ZXIgMgogICAgc2V0Yml0CiAgICBieXRlY18wIC8vIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnRjXzAgLy8gMQogICAgcmV0dXJuCgptYWluX3ZlcmlmeV9iaWd1aW50bl91aW50bl9sdF9yb3V0ZUAxNDoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo5MwogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgbm90IE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gY2FuIG9ubHkgY2FsbCB3aGVuIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjQKICAgIC8vIGV4cG9ydCBjbGFzcyBBcmM0UHJpbWl0aXZlT3BzQ29udHJhY3QgZXh0ZW5kcyBDb250cmFjdCB7CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBleHRyYWN0IDIgMAogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMgogICAgZXh0cmFjdCAyIDAKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo5MwogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X2JpZ3VpbnRuX3VpbnRuX2x0CiAgICBieXRlY18xIC8vIDB4MDAKICAgIGludGNfMyAvLyAwCiAgICB1bmNvdmVyIDIKICAgIHNldGJpdAogICAgYnl0ZWNfMCAvLyAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50Y18wIC8vIDEKICAgIHJldHVybgoKbWFpbl92ZXJpZnlfdWludG5fdWludG5fbHRfcm91dGVAMTM6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6ODUKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIG5vdCBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGNhbiBvbmx5IGNhbGwgd2hlbiBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo0CiAgICAvLyBleHBvcnQgY2xhc3MgQXJjNFByaW1pdGl2ZU9wc0NvbnRyYWN0IGV4dGVuZHMgQ29udHJhY3QgewogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgZXh0cmFjdCAyIDAKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDIKICAgIGV4dHJhY3QgMiAwCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6ODUKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV91aW50bl91aW50bl9sdAogICAgYnl0ZWNfMSAvLyAweDAwCiAgICBpbnRjXzMgLy8gMAogICAgdW5jb3ZlciAyCiAgICBzZXRiaXQKICAgIGJ5dGVjXzAgLy8gMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludGNfMCAvLyAxCiAgICByZXR1cm4KCm1haW5fdmVyaWZ5X2J5dGVfYnl0ZV9uZV9yb3V0ZUAxMjoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo3NwogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgbm90IE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gY2FuIG9ubHkgY2FsbCB3aGVuIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjQKICAgIC8vIGV4cG9ydCBjbGFzcyBBcmM0UHJpbWl0aXZlT3BzQ29udHJhY3QgZXh0ZW5kcyBDb250cmFjdCB7CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBleHRyYWN0IDIgMAogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMgogICAgZXh0cmFjdCAyIDAKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo3NwogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X2J5dGVfYnl0ZV9uZQogICAgYnl0ZWNfMSAvLyAweDAwCiAgICBpbnRjXzMgLy8gMAogICAgdW5jb3ZlciAyCiAgICBzZXRiaXQKICAgIGJ5dGVjXzAgLy8gMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludGNfMCAvLyAxCiAgICByZXR1cm4KCm1haW5fdmVyaWZ5X2JpZ3VpbnRuX2JpZ3VpbnRuX25lX3JvdXRlQDExOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjY5CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBub3QgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBjYW4gb25seSBjYWxsIHdoZW4gbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NAogICAgLy8gZXhwb3J0IGNsYXNzIEFyYzRQcmltaXRpdmVPcHNDb250cmFjdCBleHRlbmRzIENvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGV4dHJhY3QgMiAwCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAyCiAgICBleHRyYWN0IDIgMAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjY5CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfYmlndWludG5fYmlndWludG5fbmUKICAgIGJ5dGVjXzEgLy8gMHgwMAogICAgaW50Y18zIC8vIDAKICAgIHVuY292ZXIgMgogICAgc2V0Yml0CiAgICBieXRlY18wIC8vIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnRjXzAgLy8gMQogICAgcmV0dXJuCgptYWluX3ZlcmlmeV91aW50bl9iaWd1aW50bl9uZV9yb3V0ZUAxMDoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo2MQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgbm90IE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gY2FuIG9ubHkgY2FsbCB3aGVuIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjQKICAgIC8vIGV4cG9ydCBjbGFzcyBBcmM0UHJpbWl0aXZlT3BzQ29udHJhY3QgZXh0ZW5kcyBDb250cmFjdCB7CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBleHRyYWN0IDIgMAogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMgogICAgZXh0cmFjdCAyIDAKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo2MQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X3VpbnRuX2JpZ3VpbnRuX25lCiAgICBieXRlY18xIC8vIDB4MDAKICAgIGludGNfMyAvLyAwCiAgICB1bmNvdmVyIDIKICAgIHNldGJpdAogICAgYnl0ZWNfMCAvLyAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50Y18wIC8vIDEKICAgIHJldHVybgoKbWFpbl92ZXJpZnlfYmlndWludG5fdWludG5fbmVfcm91dGVAOToKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo1MwogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgbm90IE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gY2FuIG9ubHkgY2FsbCB3aGVuIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjQKICAgIC8vIGV4cG9ydCBjbGFzcyBBcmM0UHJpbWl0aXZlT3BzQ29udHJhY3QgZXh0ZW5kcyBDb250cmFjdCB7CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBleHRyYWN0IDIgMAogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMgogICAgZXh0cmFjdCAyIDAKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo1MwogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X2JpZ3VpbnRuX3VpbnRuX25lCiAgICBieXRlY18xIC8vIDB4MDAKICAgIGludGNfMyAvLyAwCiAgICB1bmNvdmVyIDIKICAgIHNldGJpdAogICAgYnl0ZWNfMCAvLyAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50Y18wIC8vIDEKICAgIHJldHVybgoKbWFpbl92ZXJpZnlfdWludG5fdWludG5fbmVfcm91dGVAODoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo0NQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgbm90IE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gY2FuIG9ubHkgY2FsbCB3aGVuIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjQKICAgIC8vIGV4cG9ydCBjbGFzcyBBcmM0UHJpbWl0aXZlT3BzQ29udHJhY3QgZXh0ZW5kcyBDb250cmFjdCB7CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBleHRyYWN0IDIgMAogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMgogICAgZXh0cmFjdCAyIDAKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo0NQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X3VpbnRuX3VpbnRuX25lCiAgICBieXRlY18xIC8vIDB4MDAKICAgIGludGNfMyAvLyAwCiAgICB1bmNvdmVyIDIKICAgIHNldGJpdAogICAgYnl0ZWNfMCAvLyAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50Y18wIC8vIDEKICAgIHJldHVybgoKbWFpbl92ZXJpZnlfYnl0ZV9ieXRlX2VxX3JvdXRlQDc6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MzcKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIG5vdCBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGNhbiBvbmx5IGNhbGwgd2hlbiBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo0CiAgICAvLyBleHBvcnQgY2xhc3MgQXJjNFByaW1pdGl2ZU9wc0NvbnRyYWN0IGV4dGVuZHMgQ29udHJhY3QgewogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgZXh0cmFjdCAyIDAKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDIKICAgIGV4dHJhY3QgMiAwCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MzcKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV9ieXRlX2J5dGVfZXEKICAgIGJ5dGVjXzEgLy8gMHgwMAogICAgaW50Y18zIC8vIDAKICAgIHVuY292ZXIgMgogICAgc2V0Yml0CiAgICBieXRlY18wIC8vIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnRjXzAgLy8gMQogICAgcmV0dXJuCgptYWluX3ZlcmlmeV9iaWd1aW50bl9iaWd1aW50bl9lcV9yb3V0ZUA2OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjI5CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBub3QgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBjYW4gb25seSBjYWxsIHdoZW4gbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NAogICAgLy8gZXhwb3J0IGNsYXNzIEFyYzRQcmltaXRpdmVPcHNDb250cmFjdCBleHRlbmRzIENvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGV4dHJhY3QgMiAwCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAyCiAgICBleHRyYWN0IDIgMAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjI5CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfYmlndWludG5fYmlndWludG5fZXEKICAgIGJ5dGVjXzEgLy8gMHgwMAogICAgaW50Y18zIC8vIDAKICAgIHVuY292ZXIgMgogICAgc2V0Yml0CiAgICBieXRlY18wIC8vIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnRjXzAgLy8gMQogICAgcmV0dXJuCgptYWluX3ZlcmlmeV91aW50bl9iaWd1aW50bl9lcV9yb3V0ZUA1OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjIxCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBub3QgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBjYW4gb25seSBjYWxsIHdoZW4gbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NAogICAgLy8gZXhwb3J0IGNsYXNzIEFyYzRQcmltaXRpdmVPcHNDb250cmFjdCBleHRlbmRzIENvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGV4dHJhY3QgMiAwCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAyCiAgICBleHRyYWN0IDIgMAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjIxCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfdWludG5fYmlndWludG5fZXEKICAgIGJ5dGVjXzEgLy8gMHgwMAogICAgaW50Y18zIC8vIDAKICAgIHVuY292ZXIgMgogICAgc2V0Yml0CiAgICBieXRlY18wIC8vIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnRjXzAgLy8gMQogICAgcmV0dXJuCgptYWluX3ZlcmlmeV9iaWd1aW50bl91aW50bl9lcV9yb3V0ZUA0OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjEzCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBub3QgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBjYW4gb25seSBjYWxsIHdoZW4gbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NAogICAgLy8gZXhwb3J0IGNsYXNzIEFyYzRQcmltaXRpdmVPcHNDb250cmFjdCBleHRlbmRzIENvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGV4dHJhY3QgMiAwCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAyCiAgICBleHRyYWN0IDIgMAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjEzCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfYmlndWludG5fdWludG5fZXEKICAgIGJ5dGVjXzEgLy8gMHgwMAogICAgaW50Y18zIC8vIDAKICAgIHVuY292ZXIgMgogICAgc2V0Yml0CiAgICBieXRlY18wIC8vIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnRjXzAgLy8gMQogICAgcmV0dXJuCgptYWluX3ZlcmlmeV91aW50bl91aW50bl9lcV9yb3V0ZUAzOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjUKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIG5vdCBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGNhbiBvbmx5IGNhbGwgd2hlbiBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo0CiAgICAvLyBleHBvcnQgY2xhc3MgQXJjNFByaW1pdGl2ZU9wc0NvbnRyYWN0IGV4dGVuZHMgQ29udHJhY3QgewogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgZXh0cmFjdCAyIDAKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDIKICAgIGV4dHJhY3QgMiAwCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X3VpbnRuX3VpbnRuX2VxCiAgICBieXRlY18xIC8vIDB4MDAKICAgIGludGNfMyAvLyAwCiAgICB1bmNvdmVyIDIKICAgIHNldGJpdAogICAgYnl0ZWNfMCAvLyAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50Y18wIC8vIDEKICAgIHJldHVybgoKbWFpbl9iYXJlX3JvdXRpbmdANjA6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NAogICAgLy8gZXhwb3J0IGNsYXNzIEFyYzRQcmltaXRpdmVPcHNDb250cmFjdCBleHRlbmRzIENvbnRyYWN0IHsKICAgIHR4biBPbkNvbXBsZXRpb24KICAgIGJueiBtYWluX2FmdGVyX2lmX2Vsc2VANjQKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICAhCiAgICBhc3NlcnQgLy8gY2FuIG9ubHkgY2FsbCB3aGVuIGNyZWF0aW5nCiAgICBpbnRjXzAgLy8gMQogICAgcmV0dXJuCgoKLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjpBcmM0UHJpbWl0aXZlT3BzQ29udHJhY3QudmVyaWZ5X3VpbnRuX3VpbnRuX2VxKGE6IGJ5dGVzLCBiOiBieXRlcykgLT4gdWludDY0Ogp2ZXJpZnlfdWludG5fdWludG5fZXE6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NS02CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gcHVibGljIHZlcmlmeV91aW50bl91aW50bl9lcShhOiBieXRlcywgYjogYnl0ZXMpOiBib29sZWFuIHsKICAgIHByb3RvIDIgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjkKICAgIC8vIGNvbnN0IGFVaW50TiA9IG5ldyBVaW50Tjw2ND4oYUJpZ3VpbnQpCiAgICBmcmFtZV9kaWcgLTIKICAgIGxlbgogICAgaW50Y18xIC8vIDgKICAgIDw9CiAgICBhc3NlcnQgLy8gb3ZlcmZsb3cKICAgIGludGNfMSAvLyA4CiAgICBiemVybwogICAgZnJhbWVfZGlnIC0yCiAgICBkaWcgMQogICAgYnwKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoxMAogICAgLy8gY29uc3QgYlVpbnROID0gbmV3IFVpbnROPDY0PihiQmlndWludCkKICAgIGZyYW1lX2RpZyAtMQogICAgbGVuCiAgICBpbnRjXzEgLy8gOAogICAgPD0KICAgIGFzc2VydCAvLyBvdmVyZmxvdwogICAgZnJhbWVfZGlnIC0xCiAgICB1bmNvdmVyIDIKICAgIGJ8CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTEKICAgIC8vIHJldHVybiBhVWludE4gPT09IGJVaW50TgogICAgPT0KICAgIHJldHN1YgoKCi8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo6QXJjNFByaW1pdGl2ZU9wc0NvbnRyYWN0LnZlcmlmeV9iaWd1aW50bl91aW50bl9lcShhOiBieXRlcywgYjogYnl0ZXMpIC0+IHVpbnQ2NDoKdmVyaWZ5X2JpZ3VpbnRuX3VpbnRuX2VxOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjEzLTE0CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gcHVibGljIHZlcmlmeV9iaWd1aW50bl91aW50bl9lcShhOiBieXRlcywgYjogYnl0ZXMpOiBib29sZWFuIHsKICAgIHByb3RvIDIgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjE3CiAgICAvLyBjb25zdCBhVWludE4gPSBuZXcgVWludE48NTEyPihhQmlndWludCkKICAgIGZyYW1lX2RpZyAtMgogICAgbGVuCiAgICBpbnRjXzIgLy8gNjQKICAgIDw9CiAgICBhc3NlcnQgLy8gb3ZlcmZsb3cKICAgIGludGNfMiAvLyA2NAogICAgYnplcm8KICAgIGZyYW1lX2RpZyAtMgogICAgYnwKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoxOAogICAgLy8gY29uc3QgYlVpbnROID0gbmV3IFVpbnROPDY0PihiQmlndWludCkKICAgIGZyYW1lX2RpZyAtMQogICAgbGVuCiAgICBpbnRjXzEgLy8gOAogICAgPD0KICAgIGFzc2VydCAvLyBvdmVyZmxvdwogICAgaW50Y18xIC8vIDgKICAgIGJ6ZXJvCiAgICBmcmFtZV9kaWcgLTEKICAgIGJ8CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTkKICAgIC8vIHJldHVybiBhVWludE4uYnl0ZXMuZXF1YWxzKGJVaW50Ti5ieXRlcykKICAgID09CiAgICByZXRzdWIKCgovLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OkFyYzRQcmltaXRpdmVPcHNDb250cmFjdC52ZXJpZnlfdWludG5fYmlndWludG5fZXEoYTogYnl0ZXMsIGI6IGJ5dGVzKSAtPiB1aW50NjQ6CnZlcmlmeV91aW50bl9iaWd1aW50bl9lcToKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoyMS0yMgogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIHB1YmxpYyB2ZXJpZnlfdWludG5fYmlndWludG5fZXEoYTogYnl0ZXMsIGI6IGJ5dGVzKTogYm9vbGVhbiB7CiAgICBwcm90byAyIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoyNQogICAgLy8gY29uc3QgYVVpbnROID0gbmV3IFVpbnROPDY0PihhQmlndWludCkKICAgIGZyYW1lX2RpZyAtMgogICAgbGVuCiAgICBpbnRjXzEgLy8gOAogICAgPD0KICAgIGFzc2VydCAvLyBvdmVyZmxvdwogICAgaW50Y18xIC8vIDgKICAgIGJ6ZXJvCiAgICBmcmFtZV9kaWcgLTIKICAgIGJ8CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MjYKICAgIC8vIGNvbnN0IGJVaW50TiA9IG5ldyBVaW50Tjw1MTI+KGJCaWd1aW50KQogICAgZnJhbWVfZGlnIC0xCiAgICBsZW4KICAgIGludGNfMiAvLyA2NAogICAgPD0KICAgIGFzc2VydCAvLyBvdmVyZmxvdwogICAgaW50Y18yIC8vIDY0CiAgICBiemVybwogICAgZnJhbWVfZGlnIC0xCiAgICBifAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjI3CiAgICAvLyByZXR1cm4gYVVpbnROLmJ5dGVzLmVxdWFscyhiVWludE4uYnl0ZXMpCiAgICA9PQogICAgcmV0c3ViCgoKLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjpBcmM0UHJpbWl0aXZlT3BzQ29udHJhY3QudmVyaWZ5X2JpZ3VpbnRuX2JpZ3VpbnRuX2VxKGE6IGJ5dGVzLCBiOiBieXRlcykgLT4gdWludDY0Ogp2ZXJpZnlfYmlndWludG5fYmlndWludG5fZXE6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MjktMzAKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBwdWJsaWMgdmVyaWZ5X2JpZ3VpbnRuX2JpZ3VpbnRuX2VxKGE6IGJ5dGVzLCBiOiBieXRlcyk6IGJvb2xlYW4gewogICAgcHJvdG8gMiAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MzMKICAgIC8vIGNvbnN0IGFVaW50TiA9IG5ldyBVaW50Tjw1MTI+KGFCaWd1aW50KQogICAgZnJhbWVfZGlnIC0yCiAgICBsZW4KICAgIGludGNfMiAvLyA2NAogICAgPD0KICAgIGFzc2VydCAvLyBvdmVyZmxvdwogICAgaW50Y18yIC8vIDY0CiAgICBiemVybwogICAgZnJhbWVfZGlnIC0yCiAgICBkaWcgMQogICAgYnwKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czozNAogICAgLy8gY29uc3QgYlVpbnROID0gbmV3IFVpbnROPDUxMj4oYkJpZ3VpbnQpCiAgICBmcmFtZV9kaWcgLTEKICAgIGxlbgogICAgaW50Y18yIC8vIDY0CiAgICA8PQogICAgYXNzZXJ0IC8vIG92ZXJmbG93CiAgICBmcmFtZV9kaWcgLTEKICAgIHVuY292ZXIgMgogICAgYnwKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czozNQogICAgLy8gcmV0dXJuIGFVaW50TiA9PT0gYlVpbnROCiAgICA9PQogICAgcmV0c3ViCgoKLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjpBcmM0UHJpbWl0aXZlT3BzQ29udHJhY3QudmVyaWZ5X2J5dGVfYnl0ZV9lcShhOiBieXRlcywgYjogYnl0ZXMpIC0+IHVpbnQ2NDoKdmVyaWZ5X2J5dGVfYnl0ZV9lcToKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czozNy0zOAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIHB1YmxpYyB2ZXJpZnlfYnl0ZV9ieXRlX2VxKGE6IGJ5dGVzLCBiOiBieXRlcyk6IGJvb2xlYW4gewogICAgcHJvdG8gMiAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NDEKICAgIC8vIGNvbnN0IGFCeXRlID0gbmV3IEJ5dGUoYUJpZ3VpbnQpCiAgICBmcmFtZV9kaWcgLTIKICAgIGxlbgogICAgaW50Y18wIC8vIDEKICAgIDw9CiAgICBhc3NlcnQgLy8gb3ZlcmZsb3cKICAgIGludGNfMCAvLyAxCiAgICBiemVybwogICAgZnJhbWVfZGlnIC0yCiAgICBkaWcgMQogICAgYnwKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo0MgogICAgLy8gY29uc3QgYkJ5dGUgPSBuZXcgQnl0ZShiQmlndWludCkKICAgIGZyYW1lX2RpZyAtMQogICAgbGVuCiAgICBpbnRjXzAgLy8gMQogICAgPD0KICAgIGFzc2VydCAvLyBvdmVyZmxvdwogICAgZnJhbWVfZGlnIC0xCiAgICB1bmNvdmVyIDIKICAgIGJ8CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NDMKICAgIC8vIHJldHVybiBhQnl0ZSA9PT0gYkJ5dGUKICAgID09CiAgICByZXRzdWIKCgovLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OkFyYzRQcmltaXRpdmVPcHNDb250cmFjdC52ZXJpZnlfdWludG5fdWludG5fbmUoYTogYnl0ZXMsIGI6IGJ5dGVzKSAtPiB1aW50NjQ6CnZlcmlmeV91aW50bl91aW50bl9uZToKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo0NS00NgogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIHB1YmxpYyB2ZXJpZnlfdWludG5fdWludG5fbmUoYTogYnl0ZXMsIGI6IGJ5dGVzKTogYm9vbGVhbiB7CiAgICBwcm90byAyIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo0OQogICAgLy8gY29uc3QgYVVpbnROID0gbmV3IFVpbnROPDY0PihhQmlndWludCkKICAgIGZyYW1lX2RpZyAtMgogICAgbGVuCiAgICBpbnRjXzEgLy8gOAogICAgPD0KICAgIGFzc2VydCAvLyBvdmVyZmxvdwogICAgaW50Y18xIC8vIDgKICAgIGJ6ZXJvCiAgICBmcmFtZV9kaWcgLTIKICAgIGRpZyAxCiAgICBifAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjUwCiAgICAvLyBjb25zdCBiVWludE4gPSBuZXcgVWludE48NjQ+KGJCaWd1aW50KQogICAgZnJhbWVfZGlnIC0xCiAgICBsZW4KICAgIGludGNfMSAvLyA4CiAgICA8PQogICAgYXNzZXJ0IC8vIG92ZXJmbG93CiAgICBmcmFtZV9kaWcgLTEKICAgIHVuY292ZXIgMgogICAgYnwKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo1MQogICAgLy8gcmV0dXJuIGFVaW50TiAhPT0gYlVpbnROCiAgICAhPQogICAgcmV0c3ViCgoKLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjpBcmM0UHJpbWl0aXZlT3BzQ29udHJhY3QudmVyaWZ5X2JpZ3VpbnRuX3VpbnRuX25lKGE6IGJ5dGVzLCBiOiBieXRlcykgLT4gdWludDY0Ogp2ZXJpZnlfYmlndWludG5fdWludG5fbmU6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NTMtNTQKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBwdWJsaWMgdmVyaWZ5X2JpZ3VpbnRuX3VpbnRuX25lKGE6IGJ5dGVzLCBiOiBieXRlcyk6IGJvb2xlYW4gewogICAgcHJvdG8gMiAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NTcKICAgIC8vIGNvbnN0IGFVaW50TiA9IG5ldyBVaW50Tjw1MTI+KGFCaWd1aW50KQogICAgZnJhbWVfZGlnIC0yCiAgICBsZW4KICAgIGludGNfMiAvLyA2NAogICAgPD0KICAgIGFzc2VydCAvLyBvdmVyZmxvdwogICAgaW50Y18yIC8vIDY0CiAgICBiemVybwogICAgZnJhbWVfZGlnIC0yCiAgICBifAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjU4CiAgICAvLyBjb25zdCBiVWludE4gPSBuZXcgVWludE48NjQ+KGJCaWd1aW50KQogICAgZnJhbWVfZGlnIC0xCiAgICBsZW4KICAgIGludGNfMSAvLyA4CiAgICA8PQogICAgYXNzZXJ0IC8vIG92ZXJmbG93CiAgICBpbnRjXzEgLy8gOAogICAgYnplcm8KICAgIGZyYW1lX2RpZyAtMQogICAgYnwKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo1OQogICAgLy8gcmV0dXJuICFhVWludE4uYnl0ZXMuZXF1YWxzKGJVaW50Ti5ieXRlcykKICAgID09CiAgICAhCiAgICByZXRzdWIKCgovLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OkFyYzRQcmltaXRpdmVPcHNDb250cmFjdC52ZXJpZnlfdWludG5fYmlndWludG5fbmUoYTogYnl0ZXMsIGI6IGJ5dGVzKSAtPiB1aW50NjQ6CnZlcmlmeV91aW50bl9iaWd1aW50bl9uZToKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo2MS02MgogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIHB1YmxpYyB2ZXJpZnlfdWludG5fYmlndWludG5fbmUoYTogYnl0ZXMsIGI6IGJ5dGVzKTogYm9vbGVhbiB7CiAgICBwcm90byAyIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo2NQogICAgLy8gY29uc3QgYVVpbnROID0gbmV3IFVpbnROPDY0PihhQmlndWludCkKICAgIGZyYW1lX2RpZyAtMgogICAgbGVuCiAgICBpbnRjXzEgLy8gOAogICAgPD0KICAgIGFzc2VydCAvLyBvdmVyZmxvdwogICAgaW50Y18xIC8vIDgKICAgIGJ6ZXJvCiAgICBmcmFtZV9kaWcgLTIKICAgIGJ8CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NjYKICAgIC8vIGNvbnN0IGJVaW50TiA9IG5ldyBVaW50Tjw1MTI+KGJCaWd1aW50KQogICAgZnJhbWVfZGlnIC0xCiAgICBsZW4KICAgIGludGNfMiAvLyA2NAogICAgPD0KICAgIGFzc2VydCAvLyBvdmVyZmxvdwogICAgaW50Y18yIC8vIDY0CiAgICBiemVybwogICAgZnJhbWVfZGlnIC0xCiAgICBifAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjY3CiAgICAvLyByZXR1cm4gIWFVaW50Ti5ieXRlcy5lcXVhbHMoYlVpbnROLmJ5dGVzKQogICAgPT0KICAgICEKICAgIHJldHN1YgoKCi8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo6QXJjNFByaW1pdGl2ZU9wc0NvbnRyYWN0LnZlcmlmeV9iaWd1aW50bl9iaWd1aW50bl9uZShhOiBieXRlcywgYjogYnl0ZXMpIC0+IHVpbnQ2NDoKdmVyaWZ5X2JpZ3VpbnRuX2JpZ3VpbnRuX25lOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjY5LTcwCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gcHVibGljIHZlcmlmeV9iaWd1aW50bl9iaWd1aW50bl9uZShhOiBieXRlcywgYjogYnl0ZXMpOiBib29sZWFuIHsKICAgIHByb3RvIDIgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjczCiAgICAvLyBjb25zdCBhVWludE4gPSBuZXcgVWludE48NTEyPihhQmlndWludCkKICAgIGZyYW1lX2RpZyAtMgogICAgbGVuCiAgICBpbnRjXzIgLy8gNjQKICAgIDw9CiAgICBhc3NlcnQgLy8gb3ZlcmZsb3cKICAgIGludGNfMiAvLyA2NAogICAgYnplcm8KICAgIGZyYW1lX2RpZyAtMgogICAgZGlnIDEKICAgIGJ8CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NzQKICAgIC8vIGNvbnN0IGJVaW50TiA9IG5ldyBVaW50Tjw1MTI+KGJCaWd1aW50KQogICAgZnJhbWVfZGlnIC0xCiAgICBsZW4KICAgIGludGNfMiAvLyA2NAogICAgPD0KICAgIGFzc2VydCAvLyBvdmVyZmxvdwogICAgZnJhbWVfZGlnIC0xCiAgICB1bmNvdmVyIDIKICAgIGJ8CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NzUKICAgIC8vIHJldHVybiBhVWludE4gIT09IGJVaW50TgogICAgIT0KICAgIHJldHN1YgoKCi8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo6QXJjNFByaW1pdGl2ZU9wc0NvbnRyYWN0LnZlcmlmeV9ieXRlX2J5dGVfbmUoYTogYnl0ZXMsIGI6IGJ5dGVzKSAtPiB1aW50NjQ6CnZlcmlmeV9ieXRlX2J5dGVfbmU6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NzctNzgKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBwdWJsaWMgdmVyaWZ5X2J5dGVfYnl0ZV9uZShhOiBieXRlcywgYjogYnl0ZXMpOiBib29sZWFuIHsKICAgIHByb3RvIDIgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjgxCiAgICAvLyBjb25zdCBhQnl0ZSA9IG5ldyBCeXRlKGFCaWd1aW50KQogICAgZnJhbWVfZGlnIC0yCiAgICBsZW4KICAgIGludGNfMCAvLyAxCiAgICA8PQogICAgYXNzZXJ0IC8vIG92ZXJmbG93CiAgICBpbnRjXzAgLy8gMQogICAgYnplcm8KICAgIGZyYW1lX2RpZyAtMgogICAgZGlnIDEKICAgIGJ8CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6ODIKICAgIC8vIGNvbnN0IGJCeXRlID0gbmV3IEJ5dGUoYkJpZ3VpbnQpCiAgICBmcmFtZV9kaWcgLTEKICAgIGxlbgogICAgaW50Y18wIC8vIDEKICAgIDw9CiAgICBhc3NlcnQgLy8gb3ZlcmZsb3cKICAgIGZyYW1lX2RpZyAtMQogICAgdW5jb3ZlciAyCiAgICBifAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjgzCiAgICAvLyByZXR1cm4gYUJ5dGUgIT09IGJCeXRlCiAgICAhPQogICAgcmV0c3ViCgoKLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjpBcmM0UHJpbWl0aXZlT3BzQ29udHJhY3QudmVyaWZ5X3VpbnRuX3VpbnRuX2x0KGE6IGJ5dGVzLCBiOiBieXRlcykgLT4gdWludDY0Ogp2ZXJpZnlfdWludG5fdWludG5fbHQ6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6ODUtODYKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBwdWJsaWMgdmVyaWZ5X3VpbnRuX3VpbnRuX2x0KGE6IGJ5dGVzLCBiOiBieXRlcyk6IGJvb2xlYW4gewogICAgcHJvdG8gMiAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6ODkKICAgIC8vIGNvbnN0IGFVaW50TiA9IG5ldyBVaW50Tjw2ND4oYUJpZ3VpbnQpCiAgICBmcmFtZV9kaWcgLTIKICAgIGxlbgogICAgaW50Y18xIC8vIDgKICAgIDw9CiAgICBhc3NlcnQgLy8gb3ZlcmZsb3cKICAgIGludGNfMSAvLyA4CiAgICBiemVybwogICAgZnJhbWVfZGlnIC0yCiAgICBkaWcgMQogICAgYnwKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo5MAogICAgLy8gY29uc3QgYlVpbnROID0gbmV3IFVpbnROPDY0PihiQmlndWludCkKICAgIGZyYW1lX2RpZyAtMQogICAgbGVuCiAgICBpbnRjXzEgLy8gOAogICAgPD0KICAgIGFzc2VydCAvLyBvdmVyZmxvdwogICAgZnJhbWVfZGlnIC0xCiAgICB1bmNvdmVyIDIKICAgIGJ8CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OTEKICAgIC8vIHJldHVybiBhVWludE4ubmF0aXZlIDwgYlVpbnROLm5hdGl2ZQogICAgc3dhcAogICAgYnRvaQogICAgc3dhcAogICAgYnRvaQogICAgPAogICAgcmV0c3ViCgoKLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjpBcmM0UHJpbWl0aXZlT3BzQ29udHJhY3QudmVyaWZ5X2JpZ3VpbnRuX3VpbnRuX2x0KGE6IGJ5dGVzLCBiOiBieXRlcykgLT4gdWludDY0Ogp2ZXJpZnlfYmlndWludG5fdWludG5fbHQ6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OTMtOTQKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBwdWJsaWMgdmVyaWZ5X2JpZ3VpbnRuX3VpbnRuX2x0KGE6IGJ5dGVzLCBiOiBieXRlcyk6IGJvb2xlYW4gewogICAgcHJvdG8gMiAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OTcKICAgIC8vIGNvbnN0IGFVaW50TiA9IG5ldyBVaW50Tjw1MTI+KGFCaWd1aW50KQogICAgZnJhbWVfZGlnIC0yCiAgICBsZW4KICAgIGludGNfMiAvLyA2NAogICAgPD0KICAgIGFzc2VydCAvLyBvdmVyZmxvdwogICAgaW50Y18yIC8vIDY0CiAgICBiemVybwogICAgZnJhbWVfZGlnIC0yCiAgICBifAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjk4CiAgICAvLyBjb25zdCBiVWludE4gPSBuZXcgVWludE48NjQ+KGJCaWd1aW50KQogICAgZnJhbWVfZGlnIC0xCiAgICBsZW4KICAgIGludGNfMSAvLyA4CiAgICA8PQogICAgYXNzZXJ0IC8vIG92ZXJmbG93CiAgICBpbnRjXzEgLy8gOAogICAgYnplcm8KICAgIGZyYW1lX2RpZyAtMQogICAgYnwKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo5OQogICAgLy8gcmV0dXJuIGFVaW50Ti5uYXRpdmUgPCBCaWdVaW50KGJVaW50Ti5uYXRpdmUpCiAgICBidG9pCiAgICBpdG9iCiAgICBiPAogICAgcmV0c3ViCgoKLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjpBcmM0UHJpbWl0aXZlT3BzQ29udHJhY3QudmVyaWZ5X3VpbnRuX2JpZ3VpbnRuX2x0KGE6IGJ5dGVzLCBiOiBieXRlcykgLT4gdWludDY0Ogp2ZXJpZnlfdWludG5fYmlndWludG5fbHQ6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTAxLTEwMgogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIHB1YmxpYyB2ZXJpZnlfdWludG5fYmlndWludG5fbHQoYTogYnl0ZXMsIGI6IGJ5dGVzKTogYm9vbGVhbiB7CiAgICBwcm90byAyIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoxMDUKICAgIC8vIGNvbnN0IGFVaW50TiA9IG5ldyBVaW50Tjw2ND4oYUJpZ3VpbnQpCiAgICBmcmFtZV9kaWcgLTIKICAgIGxlbgogICAgaW50Y18xIC8vIDgKICAgIDw9CiAgICBhc3NlcnQgLy8gb3ZlcmZsb3cKICAgIGludGNfMSAvLyA4CiAgICBiemVybwogICAgZnJhbWVfZGlnIC0yCiAgICBifAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjEwNgogICAgLy8gY29uc3QgYlVpbnROID0gbmV3IFVpbnROPDUxMj4oYkJpZ3VpbnQpCiAgICBmcmFtZV9kaWcgLTEKICAgIGxlbgogICAgaW50Y18yIC8vIDY0CiAgICA8PQogICAgYXNzZXJ0IC8vIG92ZXJmbG93CiAgICBpbnRjXzIgLy8gNjQKICAgIGJ6ZXJvCiAgICBmcmFtZV9kaWcgLTEKICAgIGJ8CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTA3CiAgICAvLyByZXR1cm4gQmlnVWludChhVWludE4ubmF0aXZlKSA8IGJVaW50Ti5uYXRpdmUKICAgIHN3YXAKICAgIGJ0b2kKICAgIGl0b2IKICAgIGI+CiAgICByZXRzdWIKCgovLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OkFyYzRQcmltaXRpdmVPcHNDb250cmFjdC52ZXJpZnlfYmlndWludG5fYmlndWludG5fbHQoYTogYnl0ZXMsIGI6IGJ5dGVzKSAtPiB1aW50NjQ6CnZlcmlmeV9iaWd1aW50bl9iaWd1aW50bl9sdDoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoxMDktMTEwCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gcHVibGljIHZlcmlmeV9iaWd1aW50bl9iaWd1aW50bl9sdChhOiBieXRlcywgYjogYnl0ZXMpOiBib29sZWFuIHsKICAgIHByb3RvIDIgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjExMwogICAgLy8gY29uc3QgYVVpbnROID0gbmV3IFVpbnROPDUxMj4oYUJpZ3VpbnQpCiAgICBmcmFtZV9kaWcgLTIKICAgIGxlbgogICAgaW50Y18yIC8vIDY0CiAgICA8PQogICAgYXNzZXJ0IC8vIG92ZXJmbG93CiAgICBpbnRjXzIgLy8gNjQKICAgIGJ6ZXJvCiAgICBmcmFtZV9kaWcgLTIKICAgIGRpZyAxCiAgICBifAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjExNAogICAgLy8gY29uc3QgYlVpbnROID0gbmV3IFVpbnROPDUxMj4oYkJpZ3VpbnQpCiAgICBmcmFtZV9kaWcgLTEKICAgIGxlbgogICAgaW50Y18yIC8vIDY0CiAgICA8PQogICAgYXNzZXJ0IC8vIG92ZXJmbG93CiAgICBmcmFtZV9kaWcgLTEKICAgIHVuY292ZXIgMgogICAgYnwKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoxMTUKICAgIC8vIHJldHVybiBhVWludE4ubmF0aXZlIDwgYlVpbnROLm5hdGl2ZQogICAgYjwKICAgIHJldHN1YgoKCi8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo6QXJjNFByaW1pdGl2ZU9wc0NvbnRyYWN0LnZlcmlmeV9ieXRlX2J5dGVfbHQoYTogYnl0ZXMsIGI6IGJ5dGVzKSAtPiB1aW50NjQ6CnZlcmlmeV9ieXRlX2J5dGVfbHQ6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTE3LTExOAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIHB1YmxpYyB2ZXJpZnlfYnl0ZV9ieXRlX2x0KGE6IGJ5dGVzLCBiOiBieXRlcyk6IGJvb2xlYW4gewogICAgcHJvdG8gMiAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTIxCiAgICAvLyBjb25zdCBhQnl0ZSA9IG5ldyBCeXRlKGFCaWd1aW50KQogICAgZnJhbWVfZGlnIC0yCiAgICBsZW4KICAgIGludGNfMCAvLyAxCiAgICA8PQogICAgYXNzZXJ0IC8vIG92ZXJmbG93CiAgICBpbnRjXzAgLy8gMQogICAgYnplcm8KICAgIGZyYW1lX2RpZyAtMgogICAgZGlnIDEKICAgIGJ8CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTIyCiAgICAvLyBjb25zdCBiQnl0ZSA9IG5ldyBCeXRlKGJCaWd1aW50KQogICAgZnJhbWVfZGlnIC0xCiAgICBsZW4KICAgIGludGNfMCAvLyAxCiAgICA8PQogICAgYXNzZXJ0IC8vIG92ZXJmbG93CiAgICBmcmFtZV9kaWcgLTEKICAgIHVuY292ZXIgMgogICAgYnwKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoxMjMKICAgIC8vIHJldHVybiBhQnl0ZS5uYXRpdmUgPCBiQnl0ZS5uYXRpdmUKICAgIHN3YXAKICAgIGJ0b2kKICAgIHN3YXAKICAgIGJ0b2kKICAgIDwKICAgIHJldHN1YgoKCi8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo6QXJjNFByaW1pdGl2ZU9wc0NvbnRyYWN0LnZlcmlmeV91aW50bl91aW50bl9sZShhOiBieXRlcywgYjogYnl0ZXMpIC0+IHVpbnQ2NDoKdmVyaWZ5X3VpbnRuX3VpbnRuX2xlOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjEyNS0xMjYKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBwdWJsaWMgdmVyaWZ5X3VpbnRuX3VpbnRuX2xlKGE6IGJ5dGVzLCBiOiBieXRlcyk6IGJvb2xlYW4gewogICAgcHJvdG8gMiAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTI5CiAgICAvLyBjb25zdCBhVWludE4gPSBuZXcgVWludE48NjQ+KGFCaWd1aW50KQogICAgZnJhbWVfZGlnIC0yCiAgICBsZW4KICAgIGludGNfMSAvLyA4CiAgICA8PQogICAgYXNzZXJ0IC8vIG92ZXJmbG93CiAgICBpbnRjXzEgLy8gOAogICAgYnplcm8KICAgIGZyYW1lX2RpZyAtMgogICAgZGlnIDEKICAgIGJ8CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTMwCiAgICAvLyBjb25zdCBiVWludE4gPSBuZXcgVWludE48NjQ+KGJCaWd1aW50KQogICAgZnJhbWVfZGlnIC0xCiAgICBsZW4KICAgIGludGNfMSAvLyA4CiAgICA8PQogICAgYXNzZXJ0IC8vIG92ZXJmbG93CiAgICBmcmFtZV9kaWcgLTEKICAgIHVuY292ZXIgMgogICAgYnwKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoxMzEKICAgIC8vIHJldHVybiBhVWludE4ubmF0aXZlIDw9IGJVaW50Ti5uYXRpdmUKICAgIHN3YXAKICAgIGJ0b2kKICAgIHN3YXAKICAgIGJ0b2kKICAgIDw9CiAgICByZXRzdWIKCgovLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OkFyYzRQcmltaXRpdmVPcHNDb250cmFjdC52ZXJpZnlfYmlndWludG5fdWludG5fbGUoYTogYnl0ZXMsIGI6IGJ5dGVzKSAtPiB1aW50NjQ6CnZlcmlmeV9iaWd1aW50bl91aW50bl9sZToKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoxMzMtMTM0CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gcHVibGljIHZlcmlmeV9iaWd1aW50bl91aW50bl9sZShhOiBieXRlcywgYjogYnl0ZXMpOiBib29sZWFuIHsKICAgIHByb3RvIDIgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjEzNwogICAgLy8gY29uc3QgYVVpbnROID0gbmV3IFVpbnROPDUxMj4oYUJpZ3VpbnQpCiAgICBmcmFtZV9kaWcgLTIKICAgIGxlbgogICAgaW50Y18yIC8vIDY0CiAgICA8PQogICAgYXNzZXJ0IC8vIG92ZXJmbG93CiAgICBpbnRjXzIgLy8gNjQKICAgIGJ6ZXJvCiAgICBmcmFtZV9kaWcgLTIKICAgIGJ8CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTM4CiAgICAvLyBjb25zdCBiVWludE4gPSBuZXcgVWludE48NjQ+KGJCaWd1aW50KQogICAgZnJhbWVfZGlnIC0xCiAgICBsZW4KICAgIGludGNfMSAvLyA4CiAgICA8PQogICAgYXNzZXJ0IC8vIG92ZXJmbG93CiAgICBpbnRjXzEgLy8gOAogICAgYnplcm8KICAgIGZyYW1lX2RpZyAtMQogICAgYnwKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoxMzkKICAgIC8vIHJldHVybiBhVWludE4ubmF0aXZlIDw9IEJpZ1VpbnQoYlVpbnROLm5hdGl2ZSkKICAgIGJ0b2kKICAgIGl0b2IKICAgIGI8PQogICAgcmV0c3ViCgoKLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjpBcmM0UHJpbWl0aXZlT3BzQ29udHJhY3QudmVyaWZ5X3VpbnRuX2JpZ3VpbnRuX2xlKGE6IGJ5dGVzLCBiOiBieXRlcykgLT4gdWludDY0Ogp2ZXJpZnlfdWludG5fYmlndWludG5fbGU6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTQxLTE0MgogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIHB1YmxpYyB2ZXJpZnlfdWludG5fYmlndWludG5fbGUoYTogYnl0ZXMsIGI6IGJ5dGVzKTogYm9vbGVhbiB7CiAgICBwcm90byAyIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoxNDUKICAgIC8vIGNvbnN0IGFVaW50TiA9IG5ldyBVaW50Tjw2ND4oYUJpZ3VpbnQpCiAgICBmcmFtZV9kaWcgLTIKICAgIGxlbgogICAgaW50Y18xIC8vIDgKICAgIDw9CiAgICBhc3NlcnQgLy8gb3ZlcmZsb3cKICAgIGludGNfMSAvLyA4CiAgICBiemVybwogICAgZnJhbWVfZGlnIC0yCiAgICBifAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjE0NgogICAgLy8gY29uc3QgYlVpbnROID0gbmV3IFVpbnROPDUxMj4oYkJpZ3VpbnQpCiAgICBmcmFtZV9kaWcgLTEKICAgIGxlbgogICAgaW50Y18yIC8vIDY0CiAgICA8PQogICAgYXNzZXJ0IC8vIG92ZXJmbG93CiAgICBpbnRjXzIgLy8gNjQKICAgIGJ6ZXJvCiAgICBmcmFtZV9kaWcgLTEKICAgIGJ8CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTQ3CiAgICAvLyByZXR1cm4gQmlnVWludChhVWludE4ubmF0aXZlKSA8PSBiVWludE4ubmF0aXZlCiAgICBzd2FwCiAgICBidG9pCiAgICBpdG9iCiAgICBiPj0KICAgIHJldHN1YgoKCi8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo6QXJjNFByaW1pdGl2ZU9wc0NvbnRyYWN0LnZlcmlmeV9iaWd1aW50bl9iaWd1aW50bl9sZShhOiBieXRlcywgYjogYnl0ZXMpIC0+IHVpbnQ2NDoKdmVyaWZ5X2JpZ3VpbnRuX2JpZ3VpbnRuX2xlOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjE0OS0xNTAKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBwdWJsaWMgdmVyaWZ5X2JpZ3VpbnRuX2JpZ3VpbnRuX2xlKGE6IGJ5dGVzLCBiOiBieXRlcyk6IGJvb2xlYW4gewogICAgcHJvdG8gMiAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTUzCiAgICAvLyBjb25zdCBhVWludE4gPSBuZXcgVWludE48NTEyPihhQmlndWludCkKICAgIGZyYW1lX2RpZyAtMgogICAgbGVuCiAgICBpbnRjXzIgLy8gNjQKICAgIDw9CiAgICBhc3NlcnQgLy8gb3ZlcmZsb3cKICAgIGludGNfMiAvLyA2NAogICAgYnplcm8KICAgIGZyYW1lX2RpZyAtMgogICAgZGlnIDEKICAgIGJ8CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTU0CiAgICAvLyBjb25zdCBiVWludE4gPSBuZXcgVWludE48NTEyPihiQmlndWludCkKICAgIGZyYW1lX2RpZyAtMQogICAgbGVuCiAgICBpbnRjXzIgLy8gNjQKICAgIDw9CiAgICBhc3NlcnQgLy8gb3ZlcmZsb3cKICAgIGZyYW1lX2RpZyAtMQogICAgdW5jb3ZlciAyCiAgICBifAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjE1NQogICAgLy8gcmV0dXJuIGFVaW50Ti5uYXRpdmUgPD0gYlVpbnROLm5hdGl2ZQogICAgYjw9CiAgICByZXRzdWIKCgovLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OkFyYzRQcmltaXRpdmVPcHNDb250cmFjdC52ZXJpZnlfYnl0ZV9ieXRlX2xlKGE6IGJ5dGVzLCBiOiBieXRlcykgLT4gdWludDY0Ogp2ZXJpZnlfYnl0ZV9ieXRlX2xlOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjE1Ny0xNTgKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBwdWJsaWMgdmVyaWZ5X2J5dGVfYnl0ZV9sZShhOiBieXRlcywgYjogYnl0ZXMpOiBib29sZWFuIHsKICAgIHByb3RvIDIgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjE2MQogICAgLy8gY29uc3QgYUJ5dGUgPSBuZXcgQnl0ZShhQmlndWludCkKICAgIGZyYW1lX2RpZyAtMgogICAgbGVuCiAgICBpbnRjXzAgLy8gMQogICAgPD0KICAgIGFzc2VydCAvLyBvdmVyZmxvdwogICAgaW50Y18wIC8vIDEKICAgIGJ6ZXJvCiAgICBmcmFtZV9kaWcgLTIKICAgIGRpZyAxCiAgICBifAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjE2MgogICAgLy8gY29uc3QgYkJ5dGUgPSBuZXcgQnl0ZShiQmlndWludCkKICAgIGZyYW1lX2RpZyAtMQogICAgbGVuCiAgICBpbnRjXzAgLy8gMQogICAgPD0KICAgIGFzc2VydCAvLyBvdmVyZmxvdwogICAgZnJhbWVfZGlnIC0xCiAgICB1bmNvdmVyIDIKICAgIGJ8CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTYzCiAgICAvLyByZXR1cm4gYUJ5dGUubmF0aXZlIDw9IGJCeXRlLm5hdGl2ZQogICAgc3dhcAogICAgYnRvaQogICAgc3dhcAogICAgYnRvaQogICAgPD0KICAgIHJldHN1YgoKCi8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo6QXJjNFByaW1pdGl2ZU9wc0NvbnRyYWN0LnZlcmlmeV91aW50bl91aW50bl9ndChhOiBieXRlcywgYjogYnl0ZXMpIC0+IHVpbnQ2NDoKdmVyaWZ5X3VpbnRuX3VpbnRuX2d0OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjE2NS0xNjYKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBwdWJsaWMgdmVyaWZ5X3VpbnRuX3VpbnRuX2d0KGE6IGJ5dGVzLCBiOiBieXRlcyk6IGJvb2xlYW4gewogICAgcHJvdG8gMiAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTY5CiAgICAvLyBjb25zdCBhVWludE4gPSBuZXcgVWludE48NjQ+KGFCaWd1aW50KQogICAgZnJhbWVfZGlnIC0yCiAgICBsZW4KICAgIGludGNfMSAvLyA4CiAgICA8PQogICAgYXNzZXJ0IC8vIG92ZXJmbG93CiAgICBpbnRjXzEgLy8gOAogICAgYnplcm8KICAgIGZyYW1lX2RpZyAtMgogICAgZGlnIDEKICAgIGJ8CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTcwCiAgICAvLyBjb25zdCBiVWludE4gPSBuZXcgVWludE48NjQ+KGJCaWd1aW50KQogICAgZnJhbWVfZGlnIC0xCiAgICBsZW4KICAgIGludGNfMSAvLyA4CiAgICA8PQogICAgYXNzZXJ0IC8vIG92ZXJmbG93CiAgICBmcmFtZV9kaWcgLTEKICAgIHVuY292ZXIgMgogICAgYnwKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoxNzEKICAgIC8vIHJldHVybiBhVWludE4ubmF0aXZlID4gYlVpbnROLm5hdGl2ZQogICAgc3dhcAogICAgYnRvaQogICAgc3dhcAogICAgYnRvaQogICAgPgogICAgcmV0c3ViCgoKLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjpBcmM0UHJpbWl0aXZlT3BzQ29udHJhY3QudmVyaWZ5X2JpZ3VpbnRuX3VpbnRuX2d0KGE6IGJ5dGVzLCBiOiBieXRlcykgLT4gdWludDY0Ogp2ZXJpZnlfYmlndWludG5fdWludG5fZ3Q6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTczLTE3NAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIHB1YmxpYyB2ZXJpZnlfYmlndWludG5fdWludG5fZ3QoYTogYnl0ZXMsIGI6IGJ5dGVzKTogYm9vbGVhbiB7CiAgICBwcm90byAyIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoxNzcKICAgIC8vIGNvbnN0IGFVaW50TiA9IG5ldyBVaW50Tjw1MTI+KGFCaWd1aW50KQogICAgZnJhbWVfZGlnIC0yCiAgICBsZW4KICAgIGludGNfMiAvLyA2NAogICAgPD0KICAgIGFzc2VydCAvLyBvdmVyZmxvdwogICAgaW50Y18yIC8vIDY0CiAgICBiemVybwogICAgZnJhbWVfZGlnIC0yCiAgICBifAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjE3OAogICAgLy8gY29uc3QgYlVpbnROID0gbmV3IFVpbnROPDY0PihiQmlndWludCkKICAgIGZyYW1lX2RpZyAtMQogICAgbGVuCiAgICBpbnRjXzEgLy8gOAogICAgPD0KICAgIGFzc2VydCAvLyBvdmVyZmxvdwogICAgaW50Y18xIC8vIDgKICAgIGJ6ZXJvCiAgICBmcmFtZV9kaWcgLTEKICAgIGJ8CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTc5CiAgICAvLyByZXR1cm4gYVVpbnROLm5hdGl2ZSA+IEJpZ1VpbnQoYlVpbnROLm5hdGl2ZSkKICAgIGJ0b2kKICAgIGl0b2IKICAgIGI+CiAgICByZXRzdWIKCgovLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OkFyYzRQcmltaXRpdmVPcHNDb250cmFjdC52ZXJpZnlfdWludG5fYmlndWludG5fZ3QoYTogYnl0ZXMsIGI6IGJ5dGVzKSAtPiB1aW50NjQ6CnZlcmlmeV91aW50bl9iaWd1aW50bl9ndDoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoxODEtMTgyCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gcHVibGljIHZlcmlmeV91aW50bl9iaWd1aW50bl9ndChhOiBieXRlcywgYjogYnl0ZXMpOiBib29sZWFuIHsKICAgIHByb3RvIDIgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjE4NQogICAgLy8gY29uc3QgYVVpbnROID0gbmV3IFVpbnROPDY0PihhQmlndWludCkKICAgIGZyYW1lX2RpZyAtMgogICAgbGVuCiAgICBpbnRjXzEgLy8gOAogICAgPD0KICAgIGFzc2VydCAvLyBvdmVyZmxvdwogICAgaW50Y18xIC8vIDgKICAgIGJ6ZXJvCiAgICBmcmFtZV9kaWcgLTIKICAgIGJ8CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTg2CiAgICAvLyBjb25zdCBiVWludE4gPSBuZXcgVWludE48NTEyPihiQmlndWludCkKICAgIGZyYW1lX2RpZyAtMQogICAgbGVuCiAgICBpbnRjXzIgLy8gNjQKICAgIDw9CiAgICBhc3NlcnQgLy8gb3ZlcmZsb3cKICAgIGludGNfMiAvLyA2NAogICAgYnplcm8KICAgIGZyYW1lX2RpZyAtMQogICAgYnwKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoxODcKICAgIC8vIHJldHVybiBCaWdVaW50KGFVaW50Ti5uYXRpdmUpID4gYlVpbnROLm5hdGl2ZQogICAgc3dhcAogICAgYnRvaQogICAgaXRvYgogICAgYjwKICAgIHJldHN1YgoKCi8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo6QXJjNFByaW1pdGl2ZU9wc0NvbnRyYWN0LnZlcmlmeV9iaWd1aW50bl9iaWd1aW50bl9ndChhOiBieXRlcywgYjogYnl0ZXMpIC0+IHVpbnQ2NDoKdmVyaWZ5X2JpZ3VpbnRuX2JpZ3VpbnRuX2d0OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjE4OS0xOTAKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBwdWJsaWMgdmVyaWZ5X2JpZ3VpbnRuX2JpZ3VpbnRuX2d0KGE6IGJ5dGVzLCBiOiBieXRlcyk6IGJvb2xlYW4gewogICAgcHJvdG8gMiAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTkzCiAgICAvLyBjb25zdCBhVWludE4gPSBuZXcgVWludE48NTEyPihhQmlndWludCkKICAgIGZyYW1lX2RpZyAtMgogICAgbGVuCiAgICBpbnRjXzIgLy8gNjQKICAgIDw9CiAgICBhc3NlcnQgLy8gb3ZlcmZsb3cKICAgIGludGNfMiAvLyA2NAogICAgYnplcm8KICAgIGZyYW1lX2RpZyAtMgogICAgZGlnIDEKICAgIGJ8CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTk0CiAgICAvLyBjb25zdCBiVWludE4gPSBuZXcgVWludE48NTEyPihiQmlndWludCkKICAgIGZyYW1lX2RpZyAtMQogICAgbGVuCiAgICBpbnRjXzIgLy8gNjQKICAgIDw9CiAgICBhc3NlcnQgLy8gb3ZlcmZsb3cKICAgIGZyYW1lX2RpZyAtMQogICAgdW5jb3ZlciAyCiAgICBifAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjE5NQogICAgLy8gcmV0dXJuIGFVaW50Ti5uYXRpdmUgPiBiVWludE4ubmF0aXZlCiAgICBiPgogICAgcmV0c3ViCgoKLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjpBcmM0UHJpbWl0aXZlT3BzQ29udHJhY3QudmVyaWZ5X2J5dGVfYnl0ZV9ndChhOiBieXRlcywgYjogYnl0ZXMpIC0+IHVpbnQ2NDoKdmVyaWZ5X2J5dGVfYnl0ZV9ndDoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoxOTctMTk4CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gcHVibGljIHZlcmlmeV9ieXRlX2J5dGVfZ3QoYTogYnl0ZXMsIGI6IGJ5dGVzKTogYm9vbGVhbiB7CiAgICBwcm90byAyIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoyMDEKICAgIC8vIGNvbnN0IGFCeXRlID0gbmV3IEJ5dGUoYUJpZ3VpbnQpCiAgICBmcmFtZV9kaWcgLTIKICAgIGxlbgogICAgaW50Y18wIC8vIDEKICAgIDw9CiAgICBhc3NlcnQgLy8gb3ZlcmZsb3cKICAgIGludGNfMCAvLyAxCiAgICBiemVybwogICAgZnJhbWVfZGlnIC0yCiAgICBkaWcgMQogICAgYnwKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoyMDIKICAgIC8vIGNvbnN0IGJCeXRlID0gbmV3IEJ5dGUoYkJpZ3VpbnQpCiAgICBmcmFtZV9kaWcgLTEKICAgIGxlbgogICAgaW50Y18wIC8vIDEKICAgIDw9CiAgICBhc3NlcnQgLy8gb3ZlcmZsb3cKICAgIGZyYW1lX2RpZyAtMQogICAgdW5jb3ZlciAyCiAgICBifAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjIwMwogICAgLy8gcmV0dXJuIGFCeXRlLm5hdGl2ZSA+IGJCeXRlLm5hdGl2ZQogICAgc3dhcAogICAgYnRvaQogICAgc3dhcAogICAgYnRvaQogICAgPgogICAgcmV0c3ViCgoKLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjpBcmM0UHJpbWl0aXZlT3BzQ29udHJhY3QudmVyaWZ5X3VpbnRuX3VpbnRuX2dlKGE6IGJ5dGVzLCBiOiBieXRlcykgLT4gdWludDY0Ogp2ZXJpZnlfdWludG5fdWludG5fZ2U6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MjA1LTIwNgogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIHB1YmxpYyB2ZXJpZnlfdWludG5fdWludG5fZ2UoYTogYnl0ZXMsIGI6IGJ5dGVzKTogYm9vbGVhbiB7CiAgICBwcm90byAyIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoyMDkKICAgIC8vIGNvbnN0IGFVaW50TiA9IG5ldyBVaW50Tjw2ND4oYUJpZ3VpbnQpCiAgICBmcmFtZV9kaWcgLTIKICAgIGxlbgogICAgaW50Y18xIC8vIDgKICAgIDw9CiAgICBhc3NlcnQgLy8gb3ZlcmZsb3cKICAgIGludGNfMSAvLyA4CiAgICBiemVybwogICAgZnJhbWVfZGlnIC0yCiAgICBkaWcgMQogICAgYnwKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoyMTAKICAgIC8vIGNvbnN0IGJVaW50TiA9IG5ldyBVaW50Tjw2ND4oYkJpZ3VpbnQpCiAgICBmcmFtZV9kaWcgLTEKICAgIGxlbgogICAgaW50Y18xIC8vIDgKICAgIDw9CiAgICBhc3NlcnQgLy8gb3ZlcmZsb3cKICAgIGZyYW1lX2RpZyAtMQogICAgdW5jb3ZlciAyCiAgICBifAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjIxMQogICAgLy8gcmV0dXJuIGFVaW50Ti5uYXRpdmUgPj0gYlVpbnROLm5hdGl2ZQogICAgc3dhcAogICAgYnRvaQogICAgc3dhcAogICAgYnRvaQogICAgPj0KICAgIHJldHN1YgoKCi8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo6QXJjNFByaW1pdGl2ZU9wc0NvbnRyYWN0LnZlcmlmeV9iaWd1aW50bl91aW50bl9nZShhOiBieXRlcywgYjogYnl0ZXMpIC0+IHVpbnQ2NDoKdmVyaWZ5X2JpZ3VpbnRuX3VpbnRuX2dlOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjIxMy0yMTQKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBwdWJsaWMgdmVyaWZ5X2JpZ3VpbnRuX3VpbnRuX2dlKGE6IGJ5dGVzLCBiOiBieXRlcyk6IGJvb2xlYW4gewogICAgcHJvdG8gMiAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MjE3CiAgICAvLyBjb25zdCBhVWludE4gPSBuZXcgVWludE48NTEyPihhQmlndWludCkKICAgIGZyYW1lX2RpZyAtMgogICAgbGVuCiAgICBpbnRjXzIgLy8gNjQKICAgIDw9CiAgICBhc3NlcnQgLy8gb3ZlcmZsb3cKICAgIGludGNfMiAvLyA2NAogICAgYnplcm8KICAgIGZyYW1lX2RpZyAtMgogICAgYnwKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoyMTgKICAgIC8vIGNvbnN0IGJVaW50TiA9IG5ldyBVaW50Tjw2ND4oYkJpZ3VpbnQpCiAgICBmcmFtZV9kaWcgLTEKICAgIGxlbgogICAgaW50Y18xIC8vIDgKICAgIDw9CiAgICBhc3NlcnQgLy8gb3ZlcmZsb3cKICAgIGludGNfMSAvLyA4CiAgICBiemVybwogICAgZnJhbWVfZGlnIC0xCiAgICBifAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjIxOQogICAgLy8gcmV0dXJuIGFVaW50Ti5uYXRpdmUgPj0gQmlnVWludChiVWludE4ubmF0aXZlKQogICAgYnRvaQogICAgaXRvYgogICAgYj49CiAgICByZXRzdWIKCgovLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OkFyYzRQcmltaXRpdmVPcHNDb250cmFjdC52ZXJpZnlfdWludG5fYmlndWludG5fZ2UoYTogYnl0ZXMsIGI6IGJ5dGVzKSAtPiB1aW50NjQ6CnZlcmlmeV91aW50bl9iaWd1aW50bl9nZToKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoyMjEtMjIyCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gcHVibGljIHZlcmlmeV91aW50bl9iaWd1aW50bl9nZShhOiBieXRlcywgYjogYnl0ZXMpOiBib29sZWFuIHsKICAgIHByb3RvIDIgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjIyNQogICAgLy8gY29uc3QgYVVpbnROID0gbmV3IFVpbnROPDY0PihhQmlndWludCkKICAgIGZyYW1lX2RpZyAtMgogICAgbGVuCiAgICBpbnRjXzEgLy8gOAogICAgPD0KICAgIGFzc2VydCAvLyBvdmVyZmxvdwogICAgaW50Y18xIC8vIDgKICAgIGJ6ZXJvCiAgICBmcmFtZV9kaWcgLTIKICAgIGJ8CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MjI2CiAgICAvLyBjb25zdCBiVWludE4gPSBuZXcgVWludE48NTEyPihiQmlndWludCkKICAgIGZyYW1lX2RpZyAtMQogICAgbGVuCiAgICBpbnRjXzIgLy8gNjQKICAgIDw9CiAgICBhc3NlcnQgLy8gb3ZlcmZsb3cKICAgIGludGNfMiAvLyA2NAogICAgYnplcm8KICAgIGZyYW1lX2RpZyAtMQogICAgYnwKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoyMjcKICAgIC8vIHJldHVybiBCaWdVaW50KGFVaW50Ti5uYXRpdmUpID49IGJVaW50Ti5uYXRpdmUKICAgIHN3YXAKICAgIGJ0b2kKICAgIGl0b2IKICAgIGI8PQogICAgcmV0c3ViCgoKLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjpBcmM0UHJpbWl0aXZlT3BzQ29udHJhY3QudmVyaWZ5X2JpZ3VpbnRuX2JpZ3VpbnRuX2dlKGE6IGJ5dGVzLCBiOiBieXRlcykgLT4gdWludDY0Ogp2ZXJpZnlfYmlndWludG5fYmlndWludG5fZ2U6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MjI5LTIzMAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIHB1YmxpYyB2ZXJpZnlfYmlndWludG5fYmlndWludG5fZ2UoYTogYnl0ZXMsIGI6IGJ5dGVzKTogYm9vbGVhbiB7CiAgICBwcm90byAyIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoyMzMKICAgIC8vIGNvbnN0IGFVaW50TiA9IG5ldyBVaW50Tjw1MTI+KGFCaWd1aW50KQogICAgZnJhbWVfZGlnIC0yCiAgICBsZW4KICAgIGludGNfMiAvLyA2NAogICAgPD0KICAgIGFzc2VydCAvLyBvdmVyZmxvdwogICAgaW50Y18yIC8vIDY0CiAgICBiemVybwogICAgZnJhbWVfZGlnIC0yCiAgICBkaWcgMQogICAgYnwKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoyMzQKICAgIC8vIGNvbnN0IGJVaW50TiA9IG5ldyBVaW50Tjw1MTI+KGJCaWd1aW50KQogICAgZnJhbWVfZGlnIC0xCiAgICBsZW4KICAgIGludGNfMiAvLyA2NAogICAgPD0KICAgIGFzc2VydCAvLyBvdmVyZmxvdwogICAgZnJhbWVfZGlnIC0xCiAgICB1bmNvdmVyIDIKICAgIGJ8CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MjM1CiAgICAvLyByZXR1cm4gYVVpbnROLm5hdGl2ZSA+PSBiVWludE4ubmF0aXZlCiAgICBiPj0KICAgIHJldHN1YgoKCi8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo6QXJjNFByaW1pdGl2ZU9wc0NvbnRyYWN0LnZlcmlmeV9ieXRlX2J5dGVfZ2UoYTogYnl0ZXMsIGI6IGJ5dGVzKSAtPiB1aW50NjQ6CnZlcmlmeV9ieXRlX2J5dGVfZ2U6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MjM3LTIzOAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIHB1YmxpYyB2ZXJpZnlfYnl0ZV9ieXRlX2dlKGE6IGJ5dGVzLCBiOiBieXRlcyk6IGJvb2xlYW4gewogICAgcHJvdG8gMiAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MjQxCiAgICAvLyBjb25zdCBhQnl0ZSA9IG5ldyBCeXRlKGFCaWd1aW50KQogICAgZnJhbWVfZGlnIC0yCiAgICBsZW4KICAgIGludGNfMCAvLyAxCiAgICA8PQogICAgYXNzZXJ0IC8vIG92ZXJmbG93CiAgICBpbnRjXzAgLy8gMQogICAgYnplcm8KICAgIGZyYW1lX2RpZyAtMgogICAgZGlnIDEKICAgIGJ8CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MjQyCiAgICAvLyBjb25zdCBiQnl0ZSA9IG5ldyBCeXRlKGJCaWd1aW50KQogICAgZnJhbWVfZGlnIC0xCiAgICBsZW4KICAgIGludGNfMCAvLyAxCiAgICA8PQogICAgYXNzZXJ0IC8vIG92ZXJmbG93CiAgICBmcmFtZV9kaWcgLTEKICAgIHVuY292ZXIgMgogICAgYnwKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoyNDMKICAgIC8vIHJldHVybiBhQnl0ZS5uYXRpdmUgPj0gYkJ5dGUubmF0aXZlCiAgICBzd2FwCiAgICBidG9pCiAgICBzd2FwCiAgICBidG9pCiAgICA+PQogICAgcmV0c3ViCgoKLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjpBcmM0UHJpbWl0aXZlT3BzQ29udHJhY3QudmVyaWZ5X3VpbnRuX2luaXQoYTogYnl0ZXMpIC0+IGJ5dGVzOgp2ZXJpZnlfdWludG5faW5pdDoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoyNDUtMjQ2CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gcHVibGljIHZlcmlmeV91aW50bl9pbml0KGE6IGJ5dGVzKTogVWludE48MzI+IHsKICAgIHByb3RvIDEgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjI0OAogICAgLy8gcmV0dXJuIG5ldyBVaW50TjwzMj4oYUJpZ3VpbnQpCiAgICBmcmFtZV9kaWcgLTEKICAgIGxlbgogICAgcHVzaGludCA0IC8vIDQKICAgIDw9CiAgICBhc3NlcnQgLy8gb3ZlcmZsb3cKICAgIHB1c2hpbnQgNCAvLyA0CiAgICBiemVybwogICAgZnJhbWVfZGlnIC0xCiAgICBifAogICAgcmV0c3ViCgoKLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjpBcmM0UHJpbWl0aXZlT3BzQ29udHJhY3QudmVyaWZ5X2JpZ3VpbnRuX2luaXQoYTogYnl0ZXMpIC0+IGJ5dGVzOgp2ZXJpZnlfYmlndWludG5faW5pdDoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoyNTAtMjUxCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gcHVibGljIHZlcmlmeV9iaWd1aW50bl9pbml0KGE6IGJ5dGVzKTogVWludE48MjU2PiB7CiAgICBwcm90byAxIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoyNTMKICAgIC8vIHJldHVybiBuZXcgVWludE48MjU2PihhQmlndWludCkKICAgIGZyYW1lX2RpZyAtMQogICAgbGVuCiAgICBwdXNoaW50IDMyIC8vIDMyCiAgICA8PQogICAgYXNzZXJ0IC8vIG92ZXJmbG93CiAgICBwdXNoaW50IDMyIC8vIDMyCiAgICBiemVybwogICAgZnJhbWVfZGlnIC0xCiAgICBifAogICAgcmV0c3ViCgoKLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjpBcmM0UHJpbWl0aXZlT3BzQ29udHJhY3QudmVyaWZ5X2J5dGVfaW5pdChhOiBieXRlcykgLT4gYnl0ZXM6CnZlcmlmeV9ieXRlX2luaXQ6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MjU1LTI1NgogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIHB1YmxpYyB2ZXJpZnlfYnl0ZV9pbml0KGE6IGJ5dGVzKTogQnl0ZSB7CiAgICBwcm90byAxIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoyNTgKICAgIC8vIHJldHVybiBuZXcgQnl0ZShhQmlndWludCkKICAgIGZyYW1lX2RpZyAtMQogICAgbGVuCiAgICBpbnRjXzAgLy8gMQogICAgPD0KICAgIGFzc2VydCAvLyBvdmVyZmxvdwogICAgaW50Y18wIC8vIDEKICAgIGJ6ZXJvCiAgICBmcmFtZV9kaWcgLTEKICAgIGJ8CiAgICByZXRzdWIKCgovLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OkFyYzRQcmltaXRpdmVPcHNDb250cmFjdC52ZXJpZnlfdWludG5fZnJvbV9sb2coYTogYnl0ZXMpIC0+IGJ5dGVzOgp2ZXJpZnlfdWludG5fZnJvbV9sb2c6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MjcyLTI3MwogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIHB1YmxpYyB2ZXJpZnlfdWludG5fZnJvbV9sb2coYTogYnl0ZXMpOiBVaW50TjwzMj4gewogICAgcHJvdG8gMSAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6Mjc0CiAgICAvLyByZXR1cm4gaW50ZXJwcmV0QXNBcmM0PFVpbnROPDMyPj4oYSwgJ2xvZycpCiAgICBmcmFtZV9kaWcgLTEKICAgIGV4dHJhY3QgNCAwCiAgICBmcmFtZV9kaWcgLTEKICAgIGV4dHJhY3QgMCA0CiAgICBieXRlY18wIC8vIDB4MTUxZjdjNzUKICAgID09CiAgICBhc3NlcnQgLy8gQnl0ZXMgaGFzIHZhbGlkIHByZWZpeAogICAgcmV0c3ViCgoKLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjpBcmM0UHJpbWl0aXZlT3BzQ29udHJhY3QudmVyaWZ5X2JpZ3VpbnRuX2Zyb21fbG9nKGE6IGJ5dGVzKSAtPiBieXRlczoKdmVyaWZ5X2JpZ3VpbnRuX2Zyb21fbG9nOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjI3Ni0yNzcKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBwdWJsaWMgdmVyaWZ5X2JpZ3VpbnRuX2Zyb21fbG9nKGE6IGJ5dGVzKTogVWludE48MjU2PiB7CiAgICBwcm90byAxIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoyNzgKICAgIC8vIHJldHVybiBpbnRlcnByZXRBc0FyYzQ8VWludE48MjU2Pj4oYSwgJ2xvZycpCiAgICBmcmFtZV9kaWcgLTEKICAgIGV4dHJhY3QgNCAwCiAgICBmcmFtZV9kaWcgLTEKICAgIGV4dHJhY3QgMCA0CiAgICBieXRlY18wIC8vIDB4MTUxZjdjNzUKICAgID09CiAgICBhc3NlcnQgLy8gQnl0ZXMgaGFzIHZhbGlkIHByZWZpeAogICAgcmV0c3ViCgoKLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjpBcmM0UHJpbWl0aXZlT3BzQ29udHJhY3QudmVyaWZ5X2J5dGVfZnJvbV9sb2coYTogYnl0ZXMpIC0+IGJ5dGVzOgp2ZXJpZnlfYnl0ZV9mcm9tX2xvZzoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoyODAtMjgxCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gcHVibGljIHZlcmlmeV9ieXRlX2Zyb21fbG9nKGE6IGJ5dGVzKTogQnl0ZSB7CiAgICBwcm90byAxIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoyODIKICAgIC8vIHJldHVybiBpbnRlcnByZXRBc0FyYzQ8Qnl0ZT4oYSwgJ2xvZycpCiAgICBmcmFtZV9kaWcgLTEKICAgIGV4dHJhY3QgNCAwCiAgICBmcmFtZV9kaWcgLTEKICAgIGV4dHJhY3QgMCA0CiAgICBieXRlY18wIC8vIDB4MTUxZjdjNzUKICAgID09CiAgICBhc3NlcnQgLy8gQnl0ZXMgaGFzIHZhbGlkIHByZWZpeAogICAgcmV0c3ViCgoKLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjpBcmM0UHJpbWl0aXZlT3BzQ29udHJhY3QudmVyaWZ5X3VmaXhlZG54bV9mcm9tX2xvZyhhOiBieXRlcykgLT4gYnl0ZXM6CnZlcmlmeV91Zml4ZWRueG1fZnJvbV9sb2c6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MzAwLTMwMQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIHB1YmxpYyB2ZXJpZnlfdWZpeGVkbnhtX2Zyb21fbG9nKGE6IGJ5dGVzKTogVUZpeGVkTnhNPDMyLCA4PiB7CiAgICBwcm90byAxIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czozMDIKICAgIC8vIHJldHVybiBpbnRlcnByZXRBc0FyYzQ8VUZpeGVkTnhNPDMyLCA4Pj4oYSwgJ2xvZycpCiAgICBmcmFtZV9kaWcgLTEKICAgIGV4dHJhY3QgNCAwCiAgICBmcmFtZV9kaWcgLTEKICAgIGV4dHJhY3QgMCA0CiAgICBieXRlY18wIC8vIDB4MTUxZjdjNzUKICAgID09CiAgICBhc3NlcnQgLy8gQnl0ZXMgaGFzIHZhbGlkIHByZWZpeAogICAgcmV0c3ViCgoKLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjpBcmM0UHJpbWl0aXZlT3BzQ29udHJhY3QudmVyaWZ5X2JpZ3VmaXhlZG54bV9mcm9tX2xvZyhhOiBieXRlcykgLT4gYnl0ZXM6CnZlcmlmeV9iaWd1Zml4ZWRueG1fZnJvbV9sb2c6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MzA0LTMwNQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIHB1YmxpYyB2ZXJpZnlfYmlndWZpeGVkbnhtX2Zyb21fbG9nKGE6IGJ5dGVzKTogVUZpeGVkTnhNPDI1NiwgMTY+IHsKICAgIHByb3RvIDEgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjMwNgogICAgLy8gcmV0dXJuIGludGVycHJldEFzQXJjNDxVRml4ZWROeE08MjU2LCAxNj4+KGEsICdsb2cnKQogICAgZnJhbWVfZGlnIC0xCiAgICBleHRyYWN0IDQgMAogICAgZnJhbWVfZGlnIC0xCiAgICBleHRyYWN0IDAgNAogICAgYnl0ZWNfMCAvLyAweDE1MWY3Yzc1CiAgICA9PQogICAgYXNzZXJ0IC8vIEJ5dGVzIGhhcyB2YWxpZCBwcmVmaXgKICAgIHJldHN1YgoKCi8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo6QXJjNFByaW1pdGl2ZU9wc0NvbnRyYWN0LnZlcmlmeV9zdHJpbmdfaW5pdChhOiBieXRlcykgLT4gYnl0ZXM6CnZlcmlmeV9zdHJpbmdfaW5pdDoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czozMDgtMzA5CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gcHVibGljIHZlcmlmeV9zdHJpbmdfaW5pdChhOiBzdHJpbmcpOiBTdHIgewogICAgcHJvdG8gMSAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MzEwCiAgICAvLyBjb25zdCByZXN1bHQgPSBuZXcgU3RyKGBIZWxsbywgJHthfWApCiAgICBwdXNoYnl0ZXMgIkhlbGxvLCAiCiAgICBmcmFtZV9kaWcgLTEKICAgIGNvbmNhdAogICAgZHVwCiAgICBsZW4KICAgIGl0b2IKICAgIGV4dHJhY3QgNiAyCiAgICBzd2FwCiAgICBjb25jYXQKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czozMTEKICAgIC8vIHJldHVybiByZXN1bHQKICAgIHJldHN1YgoKCi8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo6QXJjNFByaW1pdGl2ZU9wc0NvbnRyYWN0LnZlcmlmeV9zdHJpbmdfYWRkKGE6IGJ5dGVzLCBiOiBieXRlcykgLT4gYnl0ZXM6CnZlcmlmeV9zdHJpbmdfYWRkOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjMxMy0zMTQKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBwdWJsaWMgdmVyaWZ5X3N0cmluZ19hZGQoYTogU3RyLCBiOiBTdHIpOiBTdHIgewogICAgcHJvdG8gMiAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MzE1CiAgICAvLyBjb25zdCByZXN1bHQgPSBhLm5hdGl2ZS5jb25jYXQoYi5uYXRpdmUpCiAgICBmcmFtZV9kaWcgLTIKICAgIGV4dHJhY3QgMiAwCiAgICBmcmFtZV9kaWcgLTEKICAgIGV4dHJhY3QgMiAwCiAgICBjb25jYXQKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czozMTYKICAgIC8vIHJldHVybiBuZXcgU3RyKHJlc3VsdCkKICAgIGR1cAogICAgbGVuCiAgICBpdG9iCiAgICBleHRyYWN0IDYgMgogICAgc3dhcAogICAgY29uY2F0CiAgICByZXRzdWIKCgovLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OkFyYzRQcmltaXRpdmVPcHNDb250cmFjdC52ZXJpZnlfc3RyaW5nX2VxKGE6IGJ5dGVzLCBiOiBieXRlcykgLT4gdWludDY0Ogp2ZXJpZnlfc3RyaW5nX2VxOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjMxOC0zMTkKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBwdWJsaWMgdmVyaWZ5X3N0cmluZ19lcShhOiBTdHIsIGI6IFN0cik6IGJvb2xlYW4gewogICAgcHJvdG8gMiAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MzIwCiAgICAvLyByZXR1cm4gYSA9PT0gYgogICAgZnJhbWVfZGlnIC0yCiAgICBmcmFtZV9kaWcgLTEKICAgID09CiAgICByZXRzdWIKCgovLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OkFyYzRQcmltaXRpdmVPcHNDb250cmFjdC52ZXJpZnlfc3RyaW5nX2J5dGVzKGE6IGJ5dGVzKSAtPiBieXRlczoKdmVyaWZ5X3N0cmluZ19ieXRlczoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czozMjItMzIzCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gcHVibGljIHZlcmlmeV9zdHJpbmdfYnl0ZXMoYTogc3RyaW5nKTogYnl0ZXMgewogICAgcHJvdG8gMSAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MzI0CiAgICAvLyBjb25zdCByZXN1bHQgPSBuZXcgU3RyKGEpCiAgICBmcmFtZV9kaWcgLTEKICAgIGxlbgogICAgaXRvYgogICAgZXh0cmFjdCA2IDIKICAgIGZyYW1lX2RpZyAtMQogICAgY29uY2F0CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MzI1CiAgICAvLyByZXR1cm4gcmVzdWx0LmJ5dGVzCiAgICByZXRzdWIKCgovLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OkFyYzRQcmltaXRpdmVPcHNDb250cmFjdC52ZXJpZnlfc3RyaW5nX2Zyb21fbG9nKGE6IGJ5dGVzKSAtPiBieXRlczoKdmVyaWZ5X3N0cmluZ19mcm9tX2xvZzoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czozMzEtMzMyCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gcHVibGljIHZlcmlmeV9zdHJpbmdfZnJvbV9sb2coYTogYnl0ZXMpOiBTdHIgewogICAgcHJvdG8gMSAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MzMzCiAgICAvLyByZXR1cm4gaW50ZXJwcmV0QXNBcmM0PFN0cj4oYSwgJ2xvZycpCiAgICBmcmFtZV9kaWcgLTEKICAgIGV4dHJhY3QgNCAwCiAgICBmcmFtZV9kaWcgLTEKICAgIGV4dHJhY3QgMCA0CiAgICBieXRlY18wIC8vIDB4MTUxZjdjNzUKICAgID09CiAgICBhc3NlcnQgLy8gQnl0ZXMgaGFzIHZhbGlkIHByZWZpeAogICAgcmV0c3ViCgoKLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjpBcmM0UHJpbWl0aXZlT3BzQ29udHJhY3QudmVyaWZ5X2Jvb2xfZnJvbV9sb2coYTogYnl0ZXMpIC0+IGJ5dGVzOgp2ZXJpZnlfYm9vbF9mcm9tX2xvZzoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czozNDMtMzQ0CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gcHVibGljIHZlcmlmeV9ib29sX2Zyb21fbG9nKGE6IGJ5dGVzKTogQm9vbCB7CiAgICBwcm90byAxIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czozNDUKICAgIC8vIHJldHVybiBpbnRlcnByZXRBc0FyYzQ8Qm9vbD4oYSwgJ2xvZycpCiAgICBmcmFtZV9kaWcgLTEKICAgIGV4dHJhY3QgNCAwCiAgICBmcmFtZV9kaWcgLTEKICAgIGV4dHJhY3QgMCA0CiAgICBieXRlY18wIC8vIDB4MTUxZjdjNzUKICAgID09CiAgICBhc3NlcnQgLy8gQnl0ZXMgaGFzIHZhbGlkIHByZWZpeAogICAgcmV0c3ViCgoKLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjpBcmM0UHJpbWl0aXZlT3BzQ29udHJhY3QudmVyaWZ5X2VtaXQoYTogYnl0ZXMsIGI6IGJ5dGVzLCBjOiBieXRlcywgZDogYnl0ZXMsIGU6IGJ5dGVzLCBmOiBieXRlcywgZzogYnl0ZXMsIGg6IGJ5dGVzLCBtOiBieXRlcywgbjogYnl0ZXMsIG86IGJ5dGVzLCBwOiBieXRlcywgcTogYnl0ZXMsIHI6IGJ5dGVzLCBzOiBieXRlcywgdDogYnl0ZXMpIC0+IHZvaWQ6CnZlcmlmeV9lbWl0OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjM0OS0zNjcKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBwdWJsaWMgdmVyaWZ5X2VtaXQoCiAgICAvLyAgIGE6IGFyYzQuU3RyLAogICAgLy8gICBiOiBhcmM0LlVpbnROPDUxMj4sCiAgICAvLyAgIGM6IGFyYzQuVWludE42NCwKICAgIC8vICAgZDogYXJjNC5EeW5hbWljQnl0ZXMsCiAgICAvLyAgIGU6IGFyYzQuVWludE42NCwKICAgIC8vICAgZjogYXJjNC5Cb29sLAogICAgLy8gICBnOiBhcmM0LkR5bmFtaWNCeXRlcywKICAgIC8vICAgaDogYXJjNC5TdHIsCiAgICAvLyAgIG06IGFyYzQuVWludE48NjQ+LAogICAgLy8gICBuOiBhcmM0LlVpbnROPDI1Nj4sCiAgICAvLyAgIG86IGFyYzQuVUZpeGVkTnhNPDMyLCA4PiwKICAgIC8vICAgcDogYXJjNC5VRml4ZWROeE08MjU2LCAxNj4sCiAgICAvLyAgIHE6IGFyYzQuQm9vbCwKICAgIC8vICAgcjogYnl0ZXMsCiAgICAvLyAgIHM6IGJ5dGVzLAogICAgLy8gICB0OiBieXRlcywKICAgIC8vICk6IHZvaWQgewogICAgcHJvdG8gMTYgMAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjM3MgogICAgLy8gZW1pdChuZXcgU3dhcHBlZEFyYzQoeyBtLCBuLCBvLCBwLCBxLCByOiBhcmM0X3IsIHM6IGFyYzRfcywgdDogYXJjNF90IH0pKQogICAgZnJhbWVfZGlnIC04CiAgICBmcmFtZV9kaWcgLTcKICAgIGNvbmNhdAogICAgZnJhbWVfZGlnIC02CiAgICBjb25jYXQKICAgIGZyYW1lX2RpZyAtNQogICAgY29uY2F0CiAgICBmcmFtZV9kaWcgLTQKICAgIGNvbmNhdAogICAgZnJhbWVfZGlnIC0zCiAgICBjb25jYXQKICAgIHB1c2hieXRlcyAweDAwNTQKICAgIGNvbmNhdAogICAgZnJhbWVfZGlnIC0yCiAgICBsZW4KICAgIHB1c2hpbnQgODQgLy8gODQKICAgIGRpZyAxCiAgICArCiAgICBpdG9iCiAgICBleHRyYWN0IDYgMgogICAgdW5jb3ZlciAyCiAgICBzd2FwCiAgICBjb25jYXQKICAgIGZyYW1lX2RpZyAtMgogICAgY29uY2F0CiAgICBmcmFtZV9kaWcgLTEKICAgIGNvbmNhdAogICAgcHVzaGJ5dGVzIDB4NjZiYjAzMzMgLy8gbWV0aG9kICJTd2FwcGVkQXJjNCh1aW50NjQsdWludDI1Nix1Zml4ZWQzMng4LHVmaXhlZDI1NngxNixib29sLHVpbnQ4WzNdLHVpbnQxNltdLCh1aW50MzIsdWludDY0LHN0cmluZykpIgogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czozNzMKICAgIC8vIGVtaXQoJ1N3YXBwZWQnLCBhLCBiLCBjLCBkLCBlLCBmLCBnLCBoLCBtLCBuLCBvLCBwLCBxLCBhcmM0X3IuY29weSgpLCBhcmM0X3MuY29weSgpLCBhcmM0X3QpCiAgICBmcmFtZV9kaWcgLTE2CiAgICBsZW4KICAgIHB1c2hpbnQgMTczIC8vIDE3MwogICAgKwogICAgcHVzaGJ5dGVzIDB4MDBhZAogICAgZnJhbWVfZGlnIC0xNQogICAgY29uY2F0CiAgICBmcmFtZV9kaWcgLTE0CiAgICBjb25jYXQKICAgIGRpZyAxCiAgICBpdG9iCiAgICBleHRyYWN0IDYgMgogICAgY29uY2F0CiAgICBmcmFtZV9kaWcgLTEzCiAgICBsZW4KICAgIHVuY292ZXIgMgogICAgKwogICAgc3dhcAogICAgZnJhbWVfZGlnIC0xMgogICAgY29uY2F0CiAgICBmcmFtZV9kaWcgLTExCiAgICBjb25jYXQKICAgIGRpZyAxCiAgICBpdG9iCiAgICBleHRyYWN0IDYgMgogICAgY29uY2F0CiAgICBmcmFtZV9kaWcgLTEwCiAgICBsZW4KICAgIHVuY292ZXIgMgogICAgKwogICAgZHVwCiAgICBpdG9iCiAgICBleHRyYWN0IDYgMgogICAgdW5jb3ZlciAyCiAgICBzd2FwCiAgICBjb25jYXQKICAgIGZyYW1lX2RpZyAtOQogICAgbGVuCiAgICB1bmNvdmVyIDIKICAgICsKICAgIHN3YXAKICAgIGZyYW1lX2RpZyAtOAogICAgY29uY2F0CiAgICBmcmFtZV9kaWcgLTcKICAgIGNvbmNhdAogICAgZnJhbWVfZGlnIC02CiAgICBjb25jYXQKICAgIGZyYW1lX2RpZyAtNQogICAgY29uY2F0CiAgICBmcmFtZV9kaWcgLTQKICAgIGNvbmNhdAogICAgZnJhbWVfZGlnIC0zCiAgICBjb25jYXQKICAgIGRpZyAxCiAgICBpdG9iCiAgICBleHRyYWN0IDYgMgogICAgY29uY2F0CiAgICBzd2FwCiAgICB1bmNvdmVyIDIKICAgICsKICAgIGl0b2IKICAgIGV4dHJhY3QgNiAyCiAgICBjb25jYXQKICAgIGZyYW1lX2RpZyAtMTYKICAgIGNvbmNhdAogICAgZnJhbWVfZGlnIC0xMwogICAgY29uY2F0CiAgICBmcmFtZV9kaWcgLTEwCiAgICBjb25jYXQKICAgIGZyYW1lX2RpZyAtOQogICAgY29uY2F0CiAgICBmcmFtZV9kaWcgLTIKICAgIGNvbmNhdAogICAgZnJhbWVfZGlnIC0xCiAgICBjb25jYXQKICAgIHB1c2hieXRlcyAweGVjMzMxOWJiIC8vIG1ldGhvZCAiU3dhcHBlZChzdHJpbmcsdWludDUxMix1aW50NjQsYnl0ZVtdLHVpbnQ2NCxib29sLGJ5dGVbXSxzdHJpbmcsdWludDY0LHVpbnQyNTYsdWZpeGVkMzJ4OCx1Zml4ZWQyNTZ4MTYsYm9vbCx1aW50OFszXSx1aW50MTZbXSwodWludDMyLHVpbnQ2NCxzdHJpbmcpKSIKICAgIGRpZyAxCiAgICBjb25jYXQKICAgIGxvZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjM3NC0zOTIKICAgIC8vIGVtaXQoCiAgICAvLyAgICdTd2FwcGVkKHN0cmluZyx1aW50NTEyLHVpbnQ2NCxieXRlW10sdWludDY0LGJvb2wsYnl0ZVtdLHN0cmluZyx1aW50NjQsdWludDI1Nix1Zml4ZWQzMng4LHVmaXhlZDI1NngxNixib29sLHVpbnQ4WzNdLHVpbnQxNltdLCh1aW50MzIsdWludDY0LHN0cmluZykpJywKICAgIC8vICAgYSwKICAgIC8vICAgYiwKICAgIC8vICAgYywKICAgIC8vICAgZCwKICAgIC8vICAgZSwKICAgIC8vICAgZiwKICAgIC8vICAgZywKICAgIC8vICAgaCwKICAgIC8vICAgbSwKICAgIC8vICAgbiwKICAgIC8vICAgbywKICAgIC8vICAgcCwKICAgIC8vICAgcSwKICAgIC8vICAgYXJjNF9yLmNvcHkoKSwKICAgIC8vICAgYXJjNF9zLmNvcHkoKSwKICAgIC8vICAgYXJjNF90LAogICAgLy8gKQogICAgcHVzaGJ5dGVzIDB4ZWMzMzE5YmIgLy8gbWV0aG9kICJTd2FwcGVkKHN0cmluZyx1aW50NTEyLHVpbnQ2NCxieXRlW10sdWludDY0LGJvb2wsYnl0ZVtdLHN0cmluZyx1aW50NjQsdWludDI1Nix1Zml4ZWQzMng4LHVmaXhlZDI1NngxNixib29sLHVpbnQ4WzNdLHVpbnQxNltdLCh1aW50MzIsdWludDY0LHN0cmluZykpIgogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIHJldHN1Ygo=", - "clear": "I3ByYWdtYSB2ZXJzaW9uIDEwCiNwcmFnbWEgdHlwZXRyYWNrIGZhbHNlCgovLyBAYWxnb3JhbmRmb3VuZGF0aW9uL2FsZ29yYW5kLXR5cGVzY3JpcHQvYmFzZS1jb250cmFjdC5kLnRzOjpCYXNlQ29udHJhY3QuY2xlYXJTdGF0ZVByb2dyYW0oKSAtPiB1aW50NjQ6Cm1haW46CiAgICBwdXNoaW50IDEgLy8gMQogICAgcmV0dXJuCg==" - }, - "state": { - "global": { - "num_byte_slices": 0, - "num_uints": 0 - }, - "local": { - "num_byte_slices": 0, - "num_uints": 0 - } - }, - "schema": { - "global": { - "declared": {}, - "reserved": {} - }, - "local": { - "declared": {}, - "reserved": {} - } - }, - "contract": { - "name": "Arc4PrimitiveOpsContract", - "methods": [ - { - "name": "verify_uintn_uintn_eq", - "args": [ - { - "type": "byte[]", - "name": "a" - }, - { - "type": "byte[]", - "name": "b" - } - ], - "readonly": false, - "returns": { - "type": "bool" - } - }, - { - "name": "verify_biguintn_uintn_eq", - "args": [ - { - "type": "byte[]", - "name": "a" - }, - { - "type": "byte[]", - "name": "b" - } - ], - "readonly": false, - "returns": { - "type": "bool" - } - }, - { - "name": "verify_uintn_biguintn_eq", - "args": [ - { - "type": "byte[]", - "name": "a" - }, - { - "type": "byte[]", - "name": "b" - } - ], - "readonly": false, - "returns": { - "type": "bool" - } - }, - { - "name": "verify_biguintn_biguintn_eq", - "args": [ - { - "type": "byte[]", - "name": "a" - }, - { - "type": "byte[]", - "name": "b" - } - ], - "readonly": false, - "returns": { - "type": "bool" - } - }, - { - "name": "verify_byte_byte_eq", - "args": [ - { - "type": "byte[]", - "name": "a" - }, - { - "type": "byte[]", - "name": "b" - } - ], - "readonly": false, - "returns": { - "type": "bool" - } - }, - { - "name": "verify_uintn_uintn_ne", - "args": [ - { - "type": "byte[]", - "name": "a" - }, - { - "type": "byte[]", - "name": "b" - } - ], - "readonly": false, - "returns": { - "type": "bool" - } - }, - { - "name": "verify_biguintn_uintn_ne", - "args": [ - { - "type": "byte[]", - "name": "a" - }, - { - "type": "byte[]", - "name": "b" - } - ], - "readonly": false, - "returns": { - "type": "bool" - } - }, - { - "name": "verify_uintn_biguintn_ne", - "args": [ - { - "type": "byte[]", - "name": "a" - }, - { - "type": "byte[]", - "name": "b" - } - ], - "readonly": false, - "returns": { - "type": "bool" - } - }, - { - "name": "verify_biguintn_biguintn_ne", - "args": [ - { - "type": "byte[]", - "name": "a" - }, - { - "type": "byte[]", - "name": "b" - } - ], - "readonly": false, - "returns": { - "type": "bool" - } - }, - { - "name": "verify_byte_byte_ne", - "args": [ - { - "type": "byte[]", - "name": "a" - }, - { - "type": "byte[]", - "name": "b" - } - ], - "readonly": false, - "returns": { - "type": "bool" - } - }, - { - "name": "verify_uintn_uintn_lt", - "args": [ - { - "type": "byte[]", - "name": "a" - }, - { - "type": "byte[]", - "name": "b" - } - ], - "readonly": false, - "returns": { - "type": "bool" - } - }, - { - "name": "verify_biguintn_uintn_lt", - "args": [ - { - "type": "byte[]", - "name": "a" - }, - { - "type": "byte[]", - "name": "b" - } - ], - "readonly": false, - "returns": { - "type": "bool" - } - }, - { - "name": "verify_uintn_biguintn_lt", - "args": [ - { - "type": "byte[]", - "name": "a" - }, - { - "type": "byte[]", - "name": "b" - } - ], - "readonly": false, - "returns": { - "type": "bool" - } - }, - { - "name": "verify_biguintn_biguintn_lt", - "args": [ - { - "type": "byte[]", - "name": "a" - }, - { - "type": "byte[]", - "name": "b" - } - ], - "readonly": false, - "returns": { - "type": "bool" - } - }, - { - "name": "verify_byte_byte_lt", - "args": [ - { - "type": "byte[]", - "name": "a" - }, - { - "type": "byte[]", - "name": "b" - } - ], - "readonly": false, - "returns": { - "type": "bool" - } - }, - { - "name": "verify_uintn_uintn_le", - "args": [ - { - "type": "byte[]", - "name": "a" - }, - { - "type": "byte[]", - "name": "b" - } - ], - "readonly": false, - "returns": { - "type": "bool" - } - }, - { - "name": "verify_biguintn_uintn_le", - "args": [ - { - "type": "byte[]", - "name": "a" - }, - { - "type": "byte[]", - "name": "b" - } - ], - "readonly": false, - "returns": { - "type": "bool" - } - }, - { - "name": "verify_uintn_biguintn_le", - "args": [ - { - "type": "byte[]", - "name": "a" - }, - { - "type": "byte[]", - "name": "b" - } - ], - "readonly": false, - "returns": { - "type": "bool" - } - }, - { - "name": "verify_biguintn_biguintn_le", - "args": [ - { - "type": "byte[]", - "name": "a" - }, - { - "type": "byte[]", - "name": "b" - } - ], - "readonly": false, - "returns": { - "type": "bool" - } - }, - { - "name": "verify_byte_byte_le", - "args": [ - { - "type": "byte[]", - "name": "a" - }, - { - "type": "byte[]", - "name": "b" - } - ], - "readonly": false, - "returns": { - "type": "bool" - } - }, - { - "name": "verify_uintn_uintn_gt", - "args": [ - { - "type": "byte[]", - "name": "a" - }, - { - "type": "byte[]", - "name": "b" - } - ], - "readonly": false, - "returns": { - "type": "bool" - } - }, - { - "name": "verify_biguintn_uintn_gt", - "args": [ - { - "type": "byte[]", - "name": "a" - }, - { - "type": "byte[]", - "name": "b" - } - ], - "readonly": false, - "returns": { - "type": "bool" - } - }, - { - "name": "verify_uintn_biguintn_gt", - "args": [ - { - "type": "byte[]", - "name": "a" - }, - { - "type": "byte[]", - "name": "b" - } - ], - "readonly": false, - "returns": { - "type": "bool" - } - }, - { - "name": "verify_biguintn_biguintn_gt", - "args": [ - { - "type": "byte[]", - "name": "a" - }, - { - "type": "byte[]", - "name": "b" - } - ], - "readonly": false, - "returns": { - "type": "bool" - } - }, - { - "name": "verify_byte_byte_gt", - "args": [ - { - "type": "byte[]", - "name": "a" - }, - { - "type": "byte[]", - "name": "b" - } - ], - "readonly": false, - "returns": { - "type": "bool" - } - }, - { - "name": "verify_uintn_uintn_ge", - "args": [ - { - "type": "byte[]", - "name": "a" - }, - { - "type": "byte[]", - "name": "b" - } - ], - "readonly": false, - "returns": { - "type": "bool" - } - }, - { - "name": "verify_biguintn_uintn_ge", - "args": [ - { - "type": "byte[]", - "name": "a" - }, - { - "type": "byte[]", - "name": "b" - } - ], - "readonly": false, - "returns": { - "type": "bool" - } - }, - { - "name": "verify_uintn_biguintn_ge", - "args": [ - { - "type": "byte[]", - "name": "a" - }, - { - "type": "byte[]", - "name": "b" - } - ], - "readonly": false, - "returns": { - "type": "bool" - } - }, - { - "name": "verify_biguintn_biguintn_ge", - "args": [ - { - "type": "byte[]", - "name": "a" - }, - { - "type": "byte[]", - "name": "b" - } - ], - "readonly": false, - "returns": { - "type": "bool" - } - }, - { - "name": "verify_byte_byte_ge", - "args": [ - { - "type": "byte[]", - "name": "a" - }, - { - "type": "byte[]", - "name": "b" - } - ], - "readonly": false, - "returns": { - "type": "bool" - } - }, - { - "name": "verify_uintn_init", - "args": [ - { - "type": "byte[]", - "name": "a" - } - ], - "readonly": false, - "returns": { - "type": "uint32" - } - }, - { - "name": "verify_biguintn_init", - "args": [ - { - "type": "byte[]", - "name": "a" - } - ], - "readonly": false, - "returns": { - "type": "uint256" - } - }, - { - "name": "verify_byte_init", - "args": [ - { - "type": "byte[]", - "name": "a" - } - ], - "readonly": false, - "returns": { - "type": "byte" - } - }, - { - "name": "verify_uintn_from_bytes", - "args": [ - { - "type": "byte[]", - "name": "a" - } - ], - "readonly": false, - "returns": { - "type": "uint32" - } - }, - { - "name": "verify_biguintn_from_bytes", - "args": [ - { - "type": "byte[]", - "name": "a" - } - ], - "readonly": false, - "returns": { - "type": "uint256" - } - }, - { - "name": "verify_byte_from_bytes", - "args": [ - { - "type": "byte[]", - "name": "a" - } - ], - "readonly": false, - "returns": { - "type": "byte" - } - }, - { - "name": "verify_uintn_from_log", - "args": [ - { - "type": "byte[]", - "name": "a" - } - ], - "readonly": false, - "returns": { - "type": "uint32" - } - }, - { - "name": "verify_biguintn_from_log", - "args": [ - { - "type": "byte[]", - "name": "a" - } - ], - "readonly": false, - "returns": { - "type": "uint256" - } - }, - { - "name": "verify_byte_from_log", - "args": [ - { - "type": "byte[]", - "name": "a" - } - ], - "readonly": false, - "returns": { - "type": "byte" - } - }, - { - "name": "verify_ufixednxm_bytes", - "args": [ - { - "type": "ufixed32x8", - "name": "a" - } - ], - "readonly": false, - "returns": { - "type": "byte[]" - } - }, - { - "name": "verify_bigufixednxm_bytes", - "args": [ - { - "type": "ufixed256x16", - "name": "a" - } - ], - "readonly": false, - "returns": { - "type": "byte[]" - } - }, - { - "name": "verify_ufixednxm_from_bytes", - "args": [ - { - "type": "byte[]", - "name": "a" - } - ], - "readonly": false, - "returns": { - "type": "ufixed32x8" - } - }, - { - "name": "verify_bigufixednxm_from_bytes", - "args": [ - { - "type": "byte[]", - "name": "a" - } - ], - "readonly": false, - "returns": { - "type": "ufixed256x16" - } - }, - { - "name": "verify_ufixednxm_from_log", - "args": [ - { - "type": "byte[]", - "name": "a" - } - ], - "readonly": false, - "returns": { - "type": "ufixed32x8" - } - }, - { - "name": "verify_bigufixednxm_from_log", - "args": [ - { - "type": "byte[]", - "name": "a" - } - ], - "readonly": false, - "returns": { - "type": "ufixed256x16" - } - }, - { - "name": "verify_string_init", - "args": [ - { - "type": "string", - "name": "a" - } - ], - "readonly": false, - "returns": { - "type": "string" - } - }, - { - "name": "verify_string_add", - "args": [ - { - "type": "string", - "name": "a" - }, - { - "type": "string", - "name": "b" - } - ], - "readonly": false, - "returns": { - "type": "string" - } - }, - { - "name": "verify_string_eq", - "args": [ - { - "type": "string", - "name": "a" - }, - { - "type": "string", - "name": "b" - } - ], - "readonly": false, - "returns": { - "type": "bool" - } - }, - { - "name": "verify_string_bytes", - "args": [ - { - "type": "string", - "name": "a" - } - ], - "readonly": false, - "returns": { - "type": "byte[]" - } - }, - { - "name": "verify_string_from_bytes", - "args": [ - { - "type": "byte[]", - "name": "a" - } - ], - "readonly": false, - "returns": { - "type": "string" - } - }, - { - "name": "verify_string_from_log", - "args": [ - { - "type": "byte[]", - "name": "a" - } - ], - "readonly": false, - "returns": { - "type": "string" - } - }, - { - "name": "verify_bool_bytes", - "args": [ - { - "type": "bool", - "name": "a" - } - ], - "readonly": false, - "returns": { - "type": "byte[]" - } - }, - { - "name": "verify_bool_from_bytes", - "args": [ - { - "type": "byte[]", - "name": "a" - } - ], - "readonly": false, - "returns": { - "type": "bool" - } - }, - { - "name": "verify_bool_from_log", - "args": [ - { - "type": "byte[]", - "name": "a" - } - ], - "readonly": false, - "returns": { - "type": "bool" - } - }, - { - "name": "verify_emit", - "args": [ - { - "type": "string", - "name": "a" - }, - { - "type": "uint512", - "name": "b" - }, - { - "type": "uint64", - "name": "c" - }, - { - "type": "byte[]", - "name": "d" - }, - { - "type": "uint64", - "name": "e" - }, - { - "type": "bool", - "name": "f" - }, - { - "type": "byte[]", - "name": "g" - }, - { - "type": "string", - "name": "h" - }, - { - "type": "uint64", - "name": "m" - }, - { - "type": "uint256", - "name": "n" - }, - { - "type": "ufixed32x8", - "name": "o" - }, - { - "type": "ufixed256x16", - "name": "p" - }, - { - "type": "bool", - "name": "q" - }, - { - "type": "byte[]", - "name": "r" - }, - { - "type": "byte[]", - "name": "s" - }, - { - "type": "byte[]", - "name": "t" - } - ], - "readonly": false, - "returns": { - "type": "void" - } - } - ], - "networks": {} - }, - "bare_call_config": { - "no_op": "CREATE" - } -} diff --git a/tests/artifacts/arc4-primitive-ops/data/Arc4PrimitiveOpsContract.arc56.json b/tests/artifacts/arc4-primitive-ops/data/Arc4PrimitiveOpsContract.arc56.json deleted file mode 100644 index 392c060..0000000 --- a/tests/artifacts/arc4-primitive-ops/data/Arc4PrimitiveOpsContract.arc56.json +++ /dev/null @@ -1,1969 +0,0 @@ -{ - "name": "Arc4PrimitiveOpsContract", - "structs": {}, - "methods": [ - { - "name": "verify_uintn_uintn_eq", - "args": [ - { - "type": "byte[]", - "name": "a" - }, - { - "type": "byte[]", - "name": "b" - } - ], - "returns": { - "type": "bool" - }, - "actions": { - "create": [], - "call": [ - "NoOp" - ] - }, - "readonly": false, - "events": [], - "recommendations": {} - }, - { - "name": "verify_biguintn_uintn_eq", - "args": [ - { - "type": "byte[]", - "name": "a" - }, - { - "type": "byte[]", - "name": "b" - } - ], - "returns": { - "type": "bool" - }, - "actions": { - "create": [], - "call": [ - "NoOp" - ] - }, - "readonly": false, - "events": [], - "recommendations": {} - }, - { - "name": "verify_uintn_biguintn_eq", - "args": [ - { - "type": "byte[]", - "name": "a" - }, - { - "type": "byte[]", - "name": "b" - } - ], - "returns": { - "type": "bool" - }, - "actions": { - "create": [], - "call": [ - "NoOp" - ] - }, - "readonly": false, - "events": [], - "recommendations": {} - }, - { - "name": "verify_biguintn_biguintn_eq", - "args": [ - { - "type": "byte[]", - "name": "a" - }, - { - "type": "byte[]", - "name": "b" - } - ], - "returns": { - "type": "bool" - }, - "actions": { - "create": [], - "call": [ - "NoOp" - ] - }, - "readonly": false, - "events": [], - "recommendations": {} - }, - { - "name": "verify_byte_byte_eq", - "args": [ - { - "type": "byte[]", - "name": "a" - }, - { - "type": "byte[]", - "name": "b" - } - ], - "returns": { - "type": "bool" - }, - "actions": { - "create": [], - "call": [ - "NoOp" - ] - }, - "readonly": false, - "events": [], - "recommendations": {} - }, - { - "name": "verify_uintn_uintn_ne", - "args": [ - { - "type": "byte[]", - "name": "a" - }, - { - "type": "byte[]", - "name": "b" - } - ], - "returns": { - "type": "bool" - }, - "actions": { - "create": [], - "call": [ - "NoOp" - ] - }, - "readonly": false, - "events": [], - "recommendations": {} - }, - { - "name": "verify_biguintn_uintn_ne", - "args": [ - { - "type": "byte[]", - "name": "a" - }, - { - "type": "byte[]", - "name": "b" - } - ], - "returns": { - "type": "bool" - }, - "actions": { - "create": [], - "call": [ - "NoOp" - ] - }, - "readonly": false, - "events": [], - "recommendations": {} - }, - { - "name": "verify_uintn_biguintn_ne", - "args": [ - { - "type": "byte[]", - "name": "a" - }, - { - "type": "byte[]", - "name": "b" - } - ], - "returns": { - "type": "bool" - }, - "actions": { - "create": [], - "call": [ - "NoOp" - ] - }, - "readonly": false, - "events": [], - "recommendations": {} - }, - { - "name": "verify_biguintn_biguintn_ne", - "args": [ - { - "type": "byte[]", - "name": "a" - }, - { - "type": "byte[]", - "name": "b" - } - ], - "returns": { - "type": "bool" - }, - "actions": { - "create": [], - "call": [ - "NoOp" - ] - }, - "readonly": false, - "events": [], - "recommendations": {} - }, - { - "name": "verify_byte_byte_ne", - "args": [ - { - "type": "byte[]", - "name": "a" - }, - { - "type": "byte[]", - "name": "b" - } - ], - "returns": { - "type": "bool" - }, - "actions": { - "create": [], - "call": [ - "NoOp" - ] - }, - "readonly": false, - "events": [], - "recommendations": {} - }, - { - "name": "verify_uintn_uintn_lt", - "args": [ - { - "type": "byte[]", - "name": "a" - }, - { - "type": "byte[]", - "name": "b" - } - ], - "returns": { - "type": "bool" - }, - "actions": { - "create": [], - "call": [ - "NoOp" - ] - }, - "readonly": false, - "events": [], - "recommendations": {} - }, - { - "name": "verify_biguintn_uintn_lt", - "args": [ - { - "type": "byte[]", - "name": "a" - }, - { - "type": "byte[]", - "name": "b" - } - ], - "returns": { - "type": "bool" - }, - "actions": { - "create": [], - "call": [ - "NoOp" - ] - }, - "readonly": false, - "events": [], - "recommendations": {} - }, - { - "name": "verify_uintn_biguintn_lt", - "args": [ - { - "type": "byte[]", - "name": "a" - }, - { - "type": "byte[]", - "name": "b" - } - ], - "returns": { - "type": "bool" - }, - "actions": { - "create": [], - "call": [ - "NoOp" - ] - }, - "readonly": false, - "events": [], - "recommendations": {} - }, - { - "name": "verify_biguintn_biguintn_lt", - "args": [ - { - "type": "byte[]", - "name": "a" - }, - { - "type": "byte[]", - "name": "b" - } - ], - "returns": { - "type": "bool" - }, - "actions": { - "create": [], - "call": [ - "NoOp" - ] - }, - "readonly": false, - "events": [], - "recommendations": {} - }, - { - "name": "verify_byte_byte_lt", - "args": [ - { - "type": "byte[]", - "name": "a" - }, - { - "type": "byte[]", - "name": "b" - } - ], - "returns": { - "type": "bool" - }, - "actions": { - "create": [], - "call": [ - "NoOp" - ] - }, - "readonly": false, - "events": [], - "recommendations": {} - }, - { - "name": "verify_uintn_uintn_le", - "args": [ - { - "type": "byte[]", - "name": "a" - }, - { - "type": "byte[]", - "name": "b" - } - ], - "returns": { - "type": "bool" - }, - "actions": { - "create": [], - "call": [ - "NoOp" - ] - }, - "readonly": false, - "events": [], - "recommendations": {} - }, - { - "name": "verify_biguintn_uintn_le", - "args": [ - { - "type": "byte[]", - "name": "a" - }, - { - "type": "byte[]", - "name": "b" - } - ], - "returns": { - "type": "bool" - }, - "actions": { - "create": [], - "call": [ - "NoOp" - ] - }, - "readonly": false, - "events": [], - "recommendations": {} - }, - { - "name": "verify_uintn_biguintn_le", - "args": [ - { - "type": "byte[]", - "name": "a" - }, - { - "type": "byte[]", - "name": "b" - } - ], - "returns": { - "type": "bool" - }, - "actions": { - "create": [], - "call": [ - "NoOp" - ] - }, - "readonly": false, - "events": [], - "recommendations": {} - }, - { - "name": "verify_biguintn_biguintn_le", - "args": [ - { - "type": "byte[]", - "name": "a" - }, - { - "type": "byte[]", - "name": "b" - } - ], - "returns": { - "type": "bool" - }, - "actions": { - "create": [], - "call": [ - "NoOp" - ] - }, - "readonly": false, - "events": [], - "recommendations": {} - }, - { - "name": "verify_byte_byte_le", - "args": [ - { - "type": "byte[]", - "name": "a" - }, - { - "type": "byte[]", - "name": "b" - } - ], - "returns": { - "type": "bool" - }, - "actions": { - "create": [], - "call": [ - "NoOp" - ] - }, - "readonly": false, - "events": [], - "recommendations": {} - }, - { - "name": "verify_uintn_uintn_gt", - "args": [ - { - "type": "byte[]", - "name": "a" - }, - { - "type": "byte[]", - "name": "b" - } - ], - "returns": { - "type": "bool" - }, - "actions": { - "create": [], - "call": [ - "NoOp" - ] - }, - "readonly": false, - "events": [], - "recommendations": {} - }, - { - "name": "verify_biguintn_uintn_gt", - "args": [ - { - "type": "byte[]", - "name": "a" - }, - { - "type": "byte[]", - "name": "b" - } - ], - "returns": { - "type": "bool" - }, - "actions": { - "create": [], - "call": [ - "NoOp" - ] - }, - "readonly": false, - "events": [], - "recommendations": {} - }, - { - "name": "verify_uintn_biguintn_gt", - "args": [ - { - "type": "byte[]", - "name": "a" - }, - { - "type": "byte[]", - "name": "b" - } - ], - "returns": { - "type": "bool" - }, - "actions": { - "create": [], - "call": [ - "NoOp" - ] - }, - "readonly": false, - "events": [], - "recommendations": {} - }, - { - "name": "verify_biguintn_biguintn_gt", - "args": [ - { - "type": "byte[]", - "name": "a" - }, - { - "type": "byte[]", - "name": "b" - } - ], - "returns": { - "type": "bool" - }, - "actions": { - "create": [], - "call": [ - "NoOp" - ] - }, - "readonly": false, - "events": [], - "recommendations": {} - }, - { - "name": "verify_byte_byte_gt", - "args": [ - { - "type": "byte[]", - "name": "a" - }, - { - "type": "byte[]", - "name": "b" - } - ], - "returns": { - "type": "bool" - }, - "actions": { - "create": [], - "call": [ - "NoOp" - ] - }, - "readonly": false, - "events": [], - "recommendations": {} - }, - { - "name": "verify_uintn_uintn_ge", - "args": [ - { - "type": "byte[]", - "name": "a" - }, - { - "type": "byte[]", - "name": "b" - } - ], - "returns": { - "type": "bool" - }, - "actions": { - "create": [], - "call": [ - "NoOp" - ] - }, - "readonly": false, - "events": [], - "recommendations": {} - }, - { - "name": "verify_biguintn_uintn_ge", - "args": [ - { - "type": "byte[]", - "name": "a" - }, - { - "type": "byte[]", - "name": "b" - } - ], - "returns": { - "type": "bool" - }, - "actions": { - "create": [], - "call": [ - "NoOp" - ] - }, - "readonly": false, - "events": [], - "recommendations": {} - }, - { - "name": "verify_uintn_biguintn_ge", - "args": [ - { - "type": "byte[]", - "name": "a" - }, - { - "type": "byte[]", - "name": "b" - } - ], - "returns": { - "type": "bool" - }, - "actions": { - "create": [], - "call": [ - "NoOp" - ] - }, - "readonly": false, - "events": [], - "recommendations": {} - }, - { - "name": "verify_biguintn_biguintn_ge", - "args": [ - { - "type": "byte[]", - "name": "a" - }, - { - "type": "byte[]", - "name": "b" - } - ], - "returns": { - "type": "bool" - }, - "actions": { - "create": [], - "call": [ - "NoOp" - ] - }, - "readonly": false, - "events": [], - "recommendations": {} - }, - { - "name": "verify_byte_byte_ge", - "args": [ - { - "type": "byte[]", - "name": "a" - }, - { - "type": "byte[]", - "name": "b" - } - ], - "returns": { - "type": "bool" - }, - "actions": { - "create": [], - "call": [ - "NoOp" - ] - }, - "readonly": false, - "events": [], - "recommendations": {} - }, - { - "name": "verify_uintn_init", - "args": [ - { - "type": "byte[]", - "name": "a" - } - ], - "returns": { - "type": "uint32" - }, - "actions": { - "create": [], - "call": [ - "NoOp" - ] - }, - "readonly": false, - "events": [], - "recommendations": {} - }, - { - "name": "verify_biguintn_init", - "args": [ - { - "type": "byte[]", - "name": "a" - } - ], - "returns": { - "type": "uint256" - }, - "actions": { - "create": [], - "call": [ - "NoOp" - ] - }, - "readonly": false, - "events": [], - "recommendations": {} - }, - { - "name": "verify_byte_init", - "args": [ - { - "type": "byte[]", - "name": "a" - } - ], - "returns": { - "type": "byte" - }, - "actions": { - "create": [], - "call": [ - "NoOp" - ] - }, - "readonly": false, - "events": [], - "recommendations": {} - }, - { - "name": "verify_uintn_from_bytes", - "args": [ - { - "type": "byte[]", - "name": "a" - } - ], - "returns": { - "type": "uint32" - }, - "actions": { - "create": [], - "call": [ - "NoOp" - ] - }, - "readonly": false, - "events": [], - "recommendations": {} - }, - { - "name": "verify_biguintn_from_bytes", - "args": [ - { - "type": "byte[]", - "name": "a" - } - ], - "returns": { - "type": "uint256" - }, - "actions": { - "create": [], - "call": [ - "NoOp" - ] - }, - "readonly": false, - "events": [], - "recommendations": {} - }, - { - "name": "verify_byte_from_bytes", - "args": [ - { - "type": "byte[]", - "name": "a" - } - ], - "returns": { - "type": "byte" - }, - "actions": { - "create": [], - "call": [ - "NoOp" - ] - }, - "readonly": false, - "events": [], - "recommendations": {} - }, - { - "name": "verify_uintn_from_log", - "args": [ - { - "type": "byte[]", - "name": "a" - } - ], - "returns": { - "type": "uint32" - }, - "actions": { - "create": [], - "call": [ - "NoOp" - ] - }, - "readonly": false, - "events": [], - "recommendations": {} - }, - { - "name": "verify_biguintn_from_log", - "args": [ - { - "type": "byte[]", - "name": "a" - } - ], - "returns": { - "type": "uint256" - }, - "actions": { - "create": [], - "call": [ - "NoOp" - ] - }, - "readonly": false, - "events": [], - "recommendations": {} - }, - { - "name": "verify_byte_from_log", - "args": [ - { - "type": "byte[]", - "name": "a" - } - ], - "returns": { - "type": "byte" - }, - "actions": { - "create": [], - "call": [ - "NoOp" - ] - }, - "readonly": false, - "events": [], - "recommendations": {} - }, - { - "name": "verify_ufixednxm_bytes", - "args": [ - { - "type": "ufixed32x8", - "name": "a" - } - ], - "returns": { - "type": "byte[]" - }, - "actions": { - "create": [], - "call": [ - "NoOp" - ] - }, - "readonly": false, - "events": [], - "recommendations": {} - }, - { - "name": "verify_bigufixednxm_bytes", - "args": [ - { - "type": "ufixed256x16", - "name": "a" - } - ], - "returns": { - "type": "byte[]" - }, - "actions": { - "create": [], - "call": [ - "NoOp" - ] - }, - "readonly": false, - "events": [], - "recommendations": {} - }, - { - "name": "verify_ufixednxm_from_bytes", - "args": [ - { - "type": "byte[]", - "name": "a" - } - ], - "returns": { - "type": "ufixed32x8" - }, - "actions": { - "create": [], - "call": [ - "NoOp" - ] - }, - "readonly": false, - "events": [], - "recommendations": {} - }, - { - "name": "verify_bigufixednxm_from_bytes", - "args": [ - { - "type": "byte[]", - "name": "a" - } - ], - "returns": { - "type": "ufixed256x16" - }, - "actions": { - "create": [], - "call": [ - "NoOp" - ] - }, - "readonly": false, - "events": [], - "recommendations": {} - }, - { - "name": "verify_ufixednxm_from_log", - "args": [ - { - "type": "byte[]", - "name": "a" - } - ], - "returns": { - "type": "ufixed32x8" - }, - "actions": { - "create": [], - "call": [ - "NoOp" - ] - }, - "readonly": false, - "events": [], - "recommendations": {} - }, - { - "name": "verify_bigufixednxm_from_log", - "args": [ - { - "type": "byte[]", - "name": "a" - } - ], - "returns": { - "type": "ufixed256x16" - }, - "actions": { - "create": [], - "call": [ - "NoOp" - ] - }, - "readonly": false, - "events": [], - "recommendations": {} - }, - { - "name": "verify_string_init", - "args": [ - { - "type": "string", - "name": "a" - } - ], - "returns": { - "type": "string" - }, - "actions": { - "create": [], - "call": [ - "NoOp" - ] - }, - "readonly": false, - "events": [], - "recommendations": {} - }, - { - "name": "verify_string_add", - "args": [ - { - "type": "string", - "name": "a" - }, - { - "type": "string", - "name": "b" - } - ], - "returns": { - "type": "string" - }, - "actions": { - "create": [], - "call": [ - "NoOp" - ] - }, - "readonly": false, - "events": [], - "recommendations": {} - }, - { - "name": "verify_string_eq", - "args": [ - { - "type": "string", - "name": "a" - }, - { - "type": "string", - "name": "b" - } - ], - "returns": { - "type": "bool" - }, - "actions": { - "create": [], - "call": [ - "NoOp" - ] - }, - "readonly": false, - "events": [], - "recommendations": {} - }, - { - "name": "verify_string_bytes", - "args": [ - { - "type": "string", - "name": "a" - } - ], - "returns": { - "type": "byte[]" - }, - "actions": { - "create": [], - "call": [ - "NoOp" - ] - }, - "readonly": false, - "events": [], - "recommendations": {} - }, - { - "name": "verify_string_from_bytes", - "args": [ - { - "type": "byte[]", - "name": "a" - } - ], - "returns": { - "type": "string" - }, - "actions": { - "create": [], - "call": [ - "NoOp" - ] - }, - "readonly": false, - "events": [], - "recommendations": {} - }, - { - "name": "verify_string_from_log", - "args": [ - { - "type": "byte[]", - "name": "a" - } - ], - "returns": { - "type": "string" - }, - "actions": { - "create": [], - "call": [ - "NoOp" - ] - }, - "readonly": false, - "events": [], - "recommendations": {} - }, - { - "name": "verify_bool_bytes", - "args": [ - { - "type": "bool", - "name": "a" - } - ], - "returns": { - "type": "byte[]" - }, - "actions": { - "create": [], - "call": [ - "NoOp" - ] - }, - "readonly": false, - "events": [], - "recommendations": {} - }, - { - "name": "verify_bool_from_bytes", - "args": [ - { - "type": "byte[]", - "name": "a" - } - ], - "returns": { - "type": "bool" - }, - "actions": { - "create": [], - "call": [ - "NoOp" - ] - }, - "readonly": false, - "events": [], - "recommendations": {} - }, - { - "name": "verify_bool_from_log", - "args": [ - { - "type": "byte[]", - "name": "a" - } - ], - "returns": { - "type": "bool" - }, - "actions": { - "create": [], - "call": [ - "NoOp" - ] - }, - "readonly": false, - "events": [], - "recommendations": {} - }, - { - "name": "verify_emit", - "args": [ - { - "type": "string", - "name": "a" - }, - { - "type": "uint512", - "name": "b" - }, - { - "type": "uint64", - "name": "c" - }, - { - "type": "byte[]", - "name": "d" - }, - { - "type": "uint64", - "name": "e" - }, - { - "type": "bool", - "name": "f" - }, - { - "type": "byte[]", - "name": "g" - }, - { - "type": "string", - "name": "h" - }, - { - "type": "uint64", - "name": "m" - }, - { - "type": "uint256", - "name": "n" - }, - { - "type": "ufixed32x8", - "name": "o" - }, - { - "type": "ufixed256x16", - "name": "p" - }, - { - "type": "bool", - "name": "q" - }, - { - "type": "byte[]", - "name": "r" - }, - { - "type": "byte[]", - "name": "s" - }, - { - "type": "byte[]", - "name": "t" - } - ], - "returns": { - "type": "void" - }, - "actions": { - "create": [], - "call": [ - "NoOp" - ] - }, - "readonly": false, - "events": [ - { - "name": "SwappedArc4", - "args": [ - { - "type": "uint64", - "name": "m" - }, - { - "type": "uint256", - "name": "n" - }, - { - "type": "ufixed32x8", - "name": "o" - }, - { - "type": "ufixed256x16", - "name": "p" - }, - { - "type": "bool", - "name": "q" - }, - { - "type": "uint8[3]", - "name": "r" - }, - { - "type": "uint16[]", - "name": "s" - }, - { - "type": "(uint32,uint64,string)", - "name": "t" - } - ] - }, - { - "name": "Swapped", - "args": [ - { - "type": "string", - "name": "0" - }, - { - "type": "uint512", - "name": "1" - }, - { - "type": "uint64", - "name": "2" - }, - { - "type": "byte[]", - "name": "3" - }, - { - "type": "uint64", - "name": "4" - }, - { - "type": "bool", - "name": "5" - }, - { - "type": "byte[]", - "name": "6" - }, - { - "type": "string", - "name": "7" - }, - { - "type": "uint64", - "name": "8" - }, - { - "type": "uint256", - "name": "9" - }, - { - "type": "ufixed32x8", - "name": "10" - }, - { - "type": "ufixed256x16", - "name": "11" - }, - { - "type": "bool", - "name": "12" - }, - { - "type": "uint8[3]", - "name": "13" - }, - { - "type": "uint16[]", - "name": "14" - }, - { - "type": "(uint32,uint64,string)", - "name": "15" - } - ] - }, - { - "name": "", - "args": [ - { - "type": "string", - "name": "0" - }, - { - "type": "uint512", - "name": "1" - }, - { - "type": "uint64", - "name": "2" - }, - { - "type": "byte[]", - "name": "3" - }, - { - "type": "uint64", - "name": "4" - }, - { - "type": "bool", - "name": "5" - }, - { - "type": "byte[]", - "name": "6" - }, - { - "type": "string", - "name": "7" - }, - { - "type": "uint64", - "name": "8" - }, - { - "type": "uint256", - "name": "9" - }, - { - "type": "ufixed32x8", - "name": "10" - }, - { - "type": "ufixed256x16", - "name": "11" - }, - { - "type": "bool", - "name": "12" - }, - { - "type": "uint8[3]", - "name": "13" - }, - { - "type": "uint16[]", - "name": "14" - }, - { - "type": "(uint32,uint64,string)", - "name": "15" - } - ] - } - ], - "recommendations": {} - } - ], - "arcs": [ - 22, - 28 - ], - "networks": {}, - "state": { - "schema": { - "global": { - "ints": 0, - "bytes": 0 - }, - "local": { - "ints": 0, - "bytes": 0 - } - }, - "keys": { - "global": {}, - "local": {}, - "box": {} - }, - "maps": { - "global": {}, - "local": {}, - "box": {} - } - }, - "bareActions": { - "create": [ - "NoOp" - ], - "call": [] - }, - "sourceInfo": { - "approval": { - "sourceInfo": [ - { - "pc": [ - 2992, - 3009, - 3026, - 3043, - 3060, - 3147, - 3164 - ], - "errorMessage": "Bytes has valid prefix" - }, - { - "pc": [ - 418, - 504, - 526, - 545, - 569, - 591, - 610, - 640, - 667, - 689, - 711, - 733, - 755, - 774, - 793, - 817, - 841, - 863, - 885, - 907, - 926, - 945, - 964, - 986, - 1008, - 1030, - 1063, - 1096, - 1129, - 1162, - 1195, - 1228, - 1261, - 1294, - 1327, - 1360, - 1393, - 1426, - 1459, - 1492, - 1525, - 1558, - 1591, - 1624, - 1657, - 1690, - 1723, - 1756, - 1789, - 1822, - 1855, - 1888, - 1921, - 1954, - 1987 - ], - "errorMessage": "OnCompletion is not NoOp" - }, - { - "pc": [ - 2025 - ], - "errorMessage": "can only call when creating" - }, - { - "pc": [ - 421, - 507, - 529, - 548, - 572, - 594, - 613, - 643, - 670, - 692, - 714, - 736, - 758, - 777, - 796, - 820, - 844, - 866, - 888, - 910, - 929, - 948, - 967, - 989, - 1011, - 1033, - 1066, - 1099, - 1132, - 1165, - 1198, - 1231, - 1264, - 1297, - 1330, - 1363, - 1396, - 1429, - 1462, - 1495, - 1528, - 1561, - 1594, - 1627, - 1660, - 1693, - 1726, - 1759, - 1792, - 1825, - 1858, - 1891, - 1924, - 1957, - 1990 - ], - "errorMessage": "can only call when not creating" - }, - { - "pc": [ - 2036, - 2049, - 2065, - 2076, - 2092, - 2103, - 2119, - 2132, - 2148, - 2161, - 2177, - 2190, - 2206, - 2217, - 2234, - 2245, - 2262, - 2275, - 2291, - 2304, - 2320, - 2333, - 2353, - 2364, - 2382, - 2393, - 2412, - 2425, - 2441, - 2454, - 2474, - 2487, - 2507, - 2518, - 2536, - 2547, - 2566, - 2579, - 2595, - 2608, - 2628, - 2641, - 2661, - 2672, - 2690, - 2701, - 2720, - 2733, - 2749, - 2762, - 2782, - 2795, - 2815, - 2826, - 2844, - 2855, - 2874, - 2887, - 2903, - 2916, - 2937, - 2954, - 2970 - ], - "errorMessage": "overflow" - } - ], - "pcOffsetMethod": "none" - }, - "clear": { - "sourceInfo": [], - "pcOffsetMethod": "none" - } - }, - "source": { - "approval": "I3ByYWdtYSB2ZXJzaW9uIDEwCiNwcmFnbWEgdHlwZXRyYWNrIGZhbHNlCgovLyBAYWxnb3JhbmRmb3VuZGF0aW9uL2FsZ29yYW5kLXR5cGVzY3JpcHQvYXJjNC9pbmRleC5kLnRzOjpDb250cmFjdC5hcHByb3ZhbFByb2dyYW0oKSAtPiB1aW50NjQ6Cm1haW46CiAgICBpbnRjYmxvY2sgMSA4IDY0IDAKICAgIGJ5dGVjYmxvY2sgMHgxNTFmN2M3NSAweDAwCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NAogICAgLy8gZXhwb3J0IGNsYXNzIEFyYzRQcmltaXRpdmVPcHNDb250cmFjdCBleHRlbmRzIENvbnRyYWN0IHsKICAgIHR4biBOdW1BcHBBcmdzCiAgICBieiBtYWluX2JhcmVfcm91dGluZ0A2MAogICAgcHVzaGJ5dGVzcyAweDk2ZjE0MTE2IDB4ZWQ2NjYwOTYgMHgyY2EwMzUyYiAweDg1OTA3ZDQwIDB4NGViMmFmNGEgMHgyY2JlYzQ1YiAweDA3NjY2ZmQ5IDB4MzcwYmFiZDMgMHgyYjZiM2VmMCAweDI3ZTIxYTk4IDB4MzM5ZGE5N2MgMHg3ODk4ZWQ5NyAweDFmMTMwY2VjIDB4Yzc0ODY2NGUgMHhhMmJhYzE0YiAweDdhNDYwY2IxIDB4ZGNhYjFmMDEgMHg5N2Q5MDY0ZCAweGNlMDZjMmEwIDB4N2MxMWUzNzUgMHhkY2RiY2VlMCAweDc3YTRiNjhkIDB4NGY1NDA2MjYgMHgwOTVhZWQ0MSAweGRmNzhjZGM2IDB4ZTNiN2U5MTggMHg1NTMzNzAwOCAweDliYjFjZDY2IDB4ODE0ODRkOWQgMHg3OWU5Y2IwMyAweDlhMDNkZjEwIDB4ZDNmMGU0NGIgMHg2NzNkYjJiZCAweDk4MmRiMjMzIDB4YWZmYmRmMGUgMHg4ZTRhMzBmNyAweDI4OGFmNzZlIDB4OGJkODRhMDQgMHhmY2Q1NWUxZiAweDBmMTU3NGZlIDB4YjJjYjEzYmUgMHhkMDU5ZWVhNyAweDRjYzRjMTU3IDB4M2QxN2FjNmUgMHhmN2YzZDVmYyAweGY4YzhmOGQ1IDB4NDNmNzE2MmEgMHg0MmUwOTA3NSAweGQ5NTZmNTc1IDB4NmMwMTYwZGYgMHhhODkwMTUwYiAweDBiMmY0YzNmIDB4OWRiOWQzMjcgMHhlNGQ5NTBhMSAweGI2MDVlODBjIC8vIG1ldGhvZCAidmVyaWZ5X3VpbnRuX3VpbnRuX2VxKGJ5dGVbXSxieXRlW10pYm9vbCIsIG1ldGhvZCAidmVyaWZ5X2JpZ3VpbnRuX3VpbnRuX2VxKGJ5dGVbXSxieXRlW10pYm9vbCIsIG1ldGhvZCAidmVyaWZ5X3VpbnRuX2JpZ3VpbnRuX2VxKGJ5dGVbXSxieXRlW10pYm9vbCIsIG1ldGhvZCAidmVyaWZ5X2JpZ3VpbnRuX2JpZ3VpbnRuX2VxKGJ5dGVbXSxieXRlW10pYm9vbCIsIG1ldGhvZCAidmVyaWZ5X2J5dGVfYnl0ZV9lcShieXRlW10sYnl0ZVtdKWJvb2wiLCBtZXRob2QgInZlcmlmeV91aW50bl91aW50bl9uZShieXRlW10sYnl0ZVtdKWJvb2wiLCBtZXRob2QgInZlcmlmeV9iaWd1aW50bl91aW50bl9uZShieXRlW10sYnl0ZVtdKWJvb2wiLCBtZXRob2QgInZlcmlmeV91aW50bl9iaWd1aW50bl9uZShieXRlW10sYnl0ZVtdKWJvb2wiLCBtZXRob2QgInZlcmlmeV9iaWd1aW50bl9iaWd1aW50bl9uZShieXRlW10sYnl0ZVtdKWJvb2wiLCBtZXRob2QgInZlcmlmeV9ieXRlX2J5dGVfbmUoYnl0ZVtdLGJ5dGVbXSlib29sIiwgbWV0aG9kICJ2ZXJpZnlfdWludG5fdWludG5fbHQoYnl0ZVtdLGJ5dGVbXSlib29sIiwgbWV0aG9kICJ2ZXJpZnlfYmlndWludG5fdWludG5fbHQoYnl0ZVtdLGJ5dGVbXSlib29sIiwgbWV0aG9kICJ2ZXJpZnlfdWludG5fYmlndWludG5fbHQoYnl0ZVtdLGJ5dGVbXSlib29sIiwgbWV0aG9kICJ2ZXJpZnlfYmlndWludG5fYmlndWludG5fbHQoYnl0ZVtdLGJ5dGVbXSlib29sIiwgbWV0aG9kICJ2ZXJpZnlfYnl0ZV9ieXRlX2x0KGJ5dGVbXSxieXRlW10pYm9vbCIsIG1ldGhvZCAidmVyaWZ5X3VpbnRuX3VpbnRuX2xlKGJ5dGVbXSxieXRlW10pYm9vbCIsIG1ldGhvZCAidmVyaWZ5X2JpZ3VpbnRuX3VpbnRuX2xlKGJ5dGVbXSxieXRlW10pYm9vbCIsIG1ldGhvZCAidmVyaWZ5X3VpbnRuX2JpZ3VpbnRuX2xlKGJ5dGVbXSxieXRlW10pYm9vbCIsIG1ldGhvZCAidmVyaWZ5X2JpZ3VpbnRuX2JpZ3VpbnRuX2xlKGJ5dGVbXSxieXRlW10pYm9vbCIsIG1ldGhvZCAidmVyaWZ5X2J5dGVfYnl0ZV9sZShieXRlW10sYnl0ZVtdKWJvb2wiLCBtZXRob2QgInZlcmlmeV91aW50bl91aW50bl9ndChieXRlW10sYnl0ZVtdKWJvb2wiLCBtZXRob2QgInZlcmlmeV9iaWd1aW50bl91aW50bl9ndChieXRlW10sYnl0ZVtdKWJvb2wiLCBtZXRob2QgInZlcmlmeV91aW50bl9iaWd1aW50bl9ndChieXRlW10sYnl0ZVtdKWJvb2wiLCBtZXRob2QgInZlcmlmeV9iaWd1aW50bl9iaWd1aW50bl9ndChieXRlW10sYnl0ZVtdKWJvb2wiLCBtZXRob2QgInZlcmlmeV9ieXRlX2J5dGVfZ3QoYnl0ZVtdLGJ5dGVbXSlib29sIiwgbWV0aG9kICJ2ZXJpZnlfdWludG5fdWludG5fZ2UoYnl0ZVtdLGJ5dGVbXSlib29sIiwgbWV0aG9kICJ2ZXJpZnlfYmlndWludG5fdWludG5fZ2UoYnl0ZVtdLGJ5dGVbXSlib29sIiwgbWV0aG9kICJ2ZXJpZnlfdWludG5fYmlndWludG5fZ2UoYnl0ZVtdLGJ5dGVbXSlib29sIiwgbWV0aG9kICJ2ZXJpZnlfYmlndWludG5fYmlndWludG5fZ2UoYnl0ZVtdLGJ5dGVbXSlib29sIiwgbWV0aG9kICJ2ZXJpZnlfYnl0ZV9ieXRlX2dlKGJ5dGVbXSxieXRlW10pYm9vbCIsIG1ldGhvZCAidmVyaWZ5X3VpbnRuX2luaXQoYnl0ZVtdKXVpbnQzMiIsIG1ldGhvZCAidmVyaWZ5X2JpZ3VpbnRuX2luaXQoYnl0ZVtdKXVpbnQyNTYiLCBtZXRob2QgInZlcmlmeV9ieXRlX2luaXQoYnl0ZVtdKWJ5dGUiLCBtZXRob2QgInZlcmlmeV91aW50bl9mcm9tX2J5dGVzKGJ5dGVbXSl1aW50MzIiLCBtZXRob2QgInZlcmlmeV9iaWd1aW50bl9mcm9tX2J5dGVzKGJ5dGVbXSl1aW50MjU2IiwgbWV0aG9kICJ2ZXJpZnlfYnl0ZV9mcm9tX2J5dGVzKGJ5dGVbXSlieXRlIiwgbWV0aG9kICJ2ZXJpZnlfdWludG5fZnJvbV9sb2coYnl0ZVtdKXVpbnQzMiIsIG1ldGhvZCAidmVyaWZ5X2JpZ3VpbnRuX2Zyb21fbG9nKGJ5dGVbXSl1aW50MjU2IiwgbWV0aG9kICJ2ZXJpZnlfYnl0ZV9mcm9tX2xvZyhieXRlW10pYnl0ZSIsIG1ldGhvZCAidmVyaWZ5X3VmaXhlZG54bV9ieXRlcyh1Zml4ZWQzMng4KWJ5dGVbXSIsIG1ldGhvZCAidmVyaWZ5X2JpZ3VmaXhlZG54bV9ieXRlcyh1Zml4ZWQyNTZ4MTYpYnl0ZVtdIiwgbWV0aG9kICJ2ZXJpZnlfdWZpeGVkbnhtX2Zyb21fYnl0ZXMoYnl0ZVtdKXVmaXhlZDMyeDgiLCBtZXRob2QgInZlcmlmeV9iaWd1Zml4ZWRueG1fZnJvbV9ieXRlcyhieXRlW10pdWZpeGVkMjU2eDE2IiwgbWV0aG9kICJ2ZXJpZnlfdWZpeGVkbnhtX2Zyb21fbG9nKGJ5dGVbXSl1Zml4ZWQzMng4IiwgbWV0aG9kICJ2ZXJpZnlfYmlndWZpeGVkbnhtX2Zyb21fbG9nKGJ5dGVbXSl1Zml4ZWQyNTZ4MTYiLCBtZXRob2QgInZlcmlmeV9zdHJpbmdfaW5pdChzdHJpbmcpc3RyaW5nIiwgbWV0aG9kICJ2ZXJpZnlfc3RyaW5nX2FkZChzdHJpbmcsc3RyaW5nKXN0cmluZyIsIG1ldGhvZCAidmVyaWZ5X3N0cmluZ19lcShzdHJpbmcsc3RyaW5nKWJvb2wiLCBtZXRob2QgInZlcmlmeV9zdHJpbmdfYnl0ZXMoc3RyaW5nKWJ5dGVbXSIsIG1ldGhvZCAidmVyaWZ5X3N0cmluZ19mcm9tX2J5dGVzKGJ5dGVbXSlzdHJpbmciLCBtZXRob2QgInZlcmlmeV9zdHJpbmdfZnJvbV9sb2coYnl0ZVtdKXN0cmluZyIsIG1ldGhvZCAidmVyaWZ5X2Jvb2xfYnl0ZXMoYm9vbClieXRlW10iLCBtZXRob2QgInZlcmlmeV9ib29sX2Zyb21fYnl0ZXMoYnl0ZVtdKWJvb2wiLCBtZXRob2QgInZlcmlmeV9ib29sX2Zyb21fbG9nKGJ5dGVbXSlib29sIiwgbWV0aG9kICJ2ZXJpZnlfZW1pdChzdHJpbmcsdWludDUxMix1aW50NjQsYnl0ZVtdLHVpbnQ2NCxib29sLGJ5dGVbXSxzdHJpbmcsdWludDY0LHVpbnQyNTYsdWZpeGVkMzJ4OCx1Zml4ZWQyNTZ4MTYsYm9vbCxieXRlW10sYnl0ZVtdLGJ5dGVbXSl2b2lkIgogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMAogICAgbWF0Y2ggbWFpbl92ZXJpZnlfdWludG5fdWludG5fZXFfcm91dGVAMyBtYWluX3ZlcmlmeV9iaWd1aW50bl91aW50bl9lcV9yb3V0ZUA0IG1haW5fdmVyaWZ5X3VpbnRuX2JpZ3VpbnRuX2VxX3JvdXRlQDUgbWFpbl92ZXJpZnlfYmlndWludG5fYmlndWludG5fZXFfcm91dGVANiBtYWluX3ZlcmlmeV9ieXRlX2J5dGVfZXFfcm91dGVANyBtYWluX3ZlcmlmeV91aW50bl91aW50bl9uZV9yb3V0ZUA4IG1haW5fdmVyaWZ5X2JpZ3VpbnRuX3VpbnRuX25lX3JvdXRlQDkgbWFpbl92ZXJpZnlfdWludG5fYmlndWludG5fbmVfcm91dGVAMTAgbWFpbl92ZXJpZnlfYmlndWludG5fYmlndWludG5fbmVfcm91dGVAMTEgbWFpbl92ZXJpZnlfYnl0ZV9ieXRlX25lX3JvdXRlQDEyIG1haW5fdmVyaWZ5X3VpbnRuX3VpbnRuX2x0X3JvdXRlQDEzIG1haW5fdmVyaWZ5X2JpZ3VpbnRuX3VpbnRuX2x0X3JvdXRlQDE0IG1haW5fdmVyaWZ5X3VpbnRuX2JpZ3VpbnRuX2x0X3JvdXRlQDE1IG1haW5fdmVyaWZ5X2JpZ3VpbnRuX2JpZ3VpbnRuX2x0X3JvdXRlQDE2IG1haW5fdmVyaWZ5X2J5dGVfYnl0ZV9sdF9yb3V0ZUAxNyBtYWluX3ZlcmlmeV91aW50bl91aW50bl9sZV9yb3V0ZUAxOCBtYWluX3ZlcmlmeV9iaWd1aW50bl91aW50bl9sZV9yb3V0ZUAxOSBtYWluX3ZlcmlmeV91aW50bl9iaWd1aW50bl9sZV9yb3V0ZUAyMCBtYWluX3ZlcmlmeV9iaWd1aW50bl9iaWd1aW50bl9sZV9yb3V0ZUAyMSBtYWluX3ZlcmlmeV9ieXRlX2J5dGVfbGVfcm91dGVAMjIgbWFpbl92ZXJpZnlfdWludG5fdWludG5fZ3Rfcm91dGVAMjMgbWFpbl92ZXJpZnlfYmlndWludG5fdWludG5fZ3Rfcm91dGVAMjQgbWFpbl92ZXJpZnlfdWludG5fYmlndWludG5fZ3Rfcm91dGVAMjUgbWFpbl92ZXJpZnlfYmlndWludG5fYmlndWludG5fZ3Rfcm91dGVAMjYgbWFpbl92ZXJpZnlfYnl0ZV9ieXRlX2d0X3JvdXRlQDI3IG1haW5fdmVyaWZ5X3VpbnRuX3VpbnRuX2dlX3JvdXRlQDI4IG1haW5fdmVyaWZ5X2JpZ3VpbnRuX3VpbnRuX2dlX3JvdXRlQDI5IG1haW5fdmVyaWZ5X3VpbnRuX2JpZ3VpbnRuX2dlX3JvdXRlQDMwIG1haW5fdmVyaWZ5X2JpZ3VpbnRuX2JpZ3VpbnRuX2dlX3JvdXRlQDMxIG1haW5fdmVyaWZ5X2J5dGVfYnl0ZV9nZV9yb3V0ZUAzMiBtYWluX3ZlcmlmeV91aW50bl9pbml0X3JvdXRlQDMzIG1haW5fdmVyaWZ5X2JpZ3VpbnRuX2luaXRfcm91dGVAMzQgbWFpbl92ZXJpZnlfYnl0ZV9pbml0X3JvdXRlQDM1IG1haW5fdmVyaWZ5X3VpbnRuX2Zyb21fYnl0ZXNfcm91dGVAMzYgbWFpbl92ZXJpZnlfYmlndWludG5fZnJvbV9ieXRlc19yb3V0ZUAzNyBtYWluX3ZlcmlmeV9ieXRlX2Zyb21fYnl0ZXNfcm91dGVAMzggbWFpbl92ZXJpZnlfdWludG5fZnJvbV9sb2dfcm91dGVAMzkgbWFpbl92ZXJpZnlfYmlndWludG5fZnJvbV9sb2dfcm91dGVANDAgbWFpbl92ZXJpZnlfYnl0ZV9mcm9tX2xvZ19yb3V0ZUA0MSBtYWluX3ZlcmlmeV91Zml4ZWRueG1fYnl0ZXNfcm91dGVANDIgbWFpbl92ZXJpZnlfYmlndWZpeGVkbnhtX2J5dGVzX3JvdXRlQDQzIG1haW5fdmVyaWZ5X3VmaXhlZG54bV9mcm9tX2J5dGVzX3JvdXRlQDQ0IG1haW5fdmVyaWZ5X2JpZ3VmaXhlZG54bV9mcm9tX2J5dGVzX3JvdXRlQDQ1IG1haW5fdmVyaWZ5X3VmaXhlZG54bV9mcm9tX2xvZ19yb3V0ZUA0NiBtYWluX3ZlcmlmeV9iaWd1Zml4ZWRueG1fZnJvbV9sb2dfcm91dGVANDcgbWFpbl92ZXJpZnlfc3RyaW5nX2luaXRfcm91dGVANDggbWFpbl92ZXJpZnlfc3RyaW5nX2FkZF9yb3V0ZUA0OSBtYWluX3ZlcmlmeV9zdHJpbmdfZXFfcm91dGVANTAgbWFpbl92ZXJpZnlfc3RyaW5nX2J5dGVzX3JvdXRlQDUxIG1haW5fdmVyaWZ5X3N0cmluZ19mcm9tX2J5dGVzX3JvdXRlQDUyIG1haW5fdmVyaWZ5X3N0cmluZ19mcm9tX2xvZ19yb3V0ZUA1MyBtYWluX3ZlcmlmeV9ib29sX2J5dGVzX3JvdXRlQDU0IG1haW5fdmVyaWZ5X2Jvb2xfZnJvbV9ieXRlc19yb3V0ZUA1NSBtYWluX3ZlcmlmeV9ib29sX2Zyb21fbG9nX3JvdXRlQDU2IG1haW5fdmVyaWZ5X2VtaXRfcm91dGVANTcKCm1haW5fYWZ0ZXJfaWZfZWxzZUA2NDoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo0CiAgICAvLyBleHBvcnQgY2xhc3MgQXJjNFByaW1pdGl2ZU9wc0NvbnRyYWN0IGV4dGVuZHMgQ29udHJhY3QgewogICAgaW50Y18zIC8vIDAKICAgIHJldHVybgoKbWFpbl92ZXJpZnlfZW1pdF9yb3V0ZUA1NzoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czozNDkKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIG5vdCBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGNhbiBvbmx5IGNhbGwgd2hlbiBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo0CiAgICAvLyBleHBvcnQgY2xhc3MgQXJjNFByaW1pdGl2ZU9wc0NvbnRyYWN0IGV4dGVuZHMgQ29udHJhY3QgewogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMgogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMwogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgNAogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgNQogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgNgogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgNwogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgOAogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgOQogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMTAKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDExCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxMgogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMTMKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDE0CiAgICBleHRyYWN0IDIgMAogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMTUKICAgIGR1cAogICAgaW50Y18zIC8vIDAKICAgIGV4dHJhY3RfdWludDE2CiAgICBkaWcgMQogICAgcHVzaGludCAyIC8vIDIKICAgIGV4dHJhY3RfdWludDE2CiAgICBzdWJzdHJpbmczCiAgICBleHRyYWN0IDIgMAogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMTUKICAgIGR1cAogICAgcHVzaGludCAyIC8vIDIKICAgIGV4dHJhY3RfdWludDE2CiAgICBkaWcgMQogICAgbGVuCiAgICBzdWJzdHJpbmczCiAgICBleHRyYWN0IDIgMAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjM0OQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X2VtaXQKICAgIGludGNfMCAvLyAxCiAgICByZXR1cm4KCm1haW5fdmVyaWZ5X2Jvb2xfZnJvbV9sb2dfcm91dGVANTY6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MzQzCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBub3QgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBjYW4gb25seSBjYWxsIHdoZW4gbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NAogICAgLy8gZXhwb3J0IGNsYXNzIEFyYzRQcmltaXRpdmVPcHNDb250cmFjdCBleHRlbmRzIENvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGV4dHJhY3QgMiAwCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MzQzCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfYm9vbF9mcm9tX2xvZwogICAgYnl0ZWNfMCAvLyAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50Y18wIC8vIDEKICAgIHJldHVybgoKbWFpbl92ZXJpZnlfYm9vbF9mcm9tX2J5dGVzX3JvdXRlQDU1OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjMzOQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgbm90IE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gY2FuIG9ubHkgY2FsbCB3aGVuIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjQKICAgIC8vIGV4cG9ydCBjbGFzcyBBcmM0UHJpbWl0aXZlT3BzQ29udHJhY3QgZXh0ZW5kcyBDb250cmFjdCB7CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBleHRyYWN0IDIgMAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjMzOQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGJ5dGVjXzAgLy8gMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludGNfMCAvLyAxCiAgICByZXR1cm4KCm1haW5fdmVyaWZ5X2Jvb2xfYnl0ZXNfcm91dGVANTQ6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MzM1CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBub3QgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBjYW4gb25seSBjYWxsIHdoZW4gbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NAogICAgLy8gZXhwb3J0IGNsYXNzIEFyYzRQcmltaXRpdmVPcHNDb250cmFjdCBleHRlbmRzIENvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czozMzUKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBkdXAKICAgIGxlbgogICAgaXRvYgogICAgZXh0cmFjdCA2IDIKICAgIHN3YXAKICAgIGNvbmNhdAogICAgYnl0ZWNfMCAvLyAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50Y18wIC8vIDEKICAgIHJldHVybgoKbWFpbl92ZXJpZnlfc3RyaW5nX2Zyb21fbG9nX3JvdXRlQDUzOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjMzMQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgbm90IE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gY2FuIG9ubHkgY2FsbCB3aGVuIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjQKICAgIC8vIGV4cG9ydCBjbGFzcyBBcmM0UHJpbWl0aXZlT3BzQ29udHJhY3QgZXh0ZW5kcyBDb250cmFjdCB7CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBleHRyYWN0IDIgMAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjMzMQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X3N0cmluZ19mcm9tX2xvZwogICAgYnl0ZWNfMCAvLyAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50Y18wIC8vIDEKICAgIHJldHVybgoKbWFpbl92ZXJpZnlfc3RyaW5nX2Zyb21fYnl0ZXNfcm91dGVANTI6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MzI3CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBub3QgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBjYW4gb25seSBjYWxsIHdoZW4gbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NAogICAgLy8gZXhwb3J0IGNsYXNzIEFyYzRQcmltaXRpdmVPcHNDb250cmFjdCBleHRlbmRzIENvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGV4dHJhY3QgMiAwCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MzI3CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgYnl0ZWNfMCAvLyAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50Y18wIC8vIDEKICAgIHJldHVybgoKbWFpbl92ZXJpZnlfc3RyaW5nX2J5dGVzX3JvdXRlQDUxOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjMyMgogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgbm90IE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gY2FuIG9ubHkgY2FsbCB3aGVuIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjQKICAgIC8vIGV4cG9ydCBjbGFzcyBBcmM0UHJpbWl0aXZlT3BzQ29udHJhY3QgZXh0ZW5kcyBDb250cmFjdCB7CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBleHRyYWN0IDIgMAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjMyMgogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X3N0cmluZ19ieXRlcwogICAgZHVwCiAgICBsZW4KICAgIGl0b2IKICAgIGV4dHJhY3QgNiAyCiAgICBzd2FwCiAgICBjb25jYXQKICAgIGJ5dGVjXzAgLy8gMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludGNfMCAvLyAxCiAgICByZXR1cm4KCm1haW5fdmVyaWZ5X3N0cmluZ19lcV9yb3V0ZUA1MDoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czozMTgKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIG5vdCBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGNhbiBvbmx5IGNhbGwgd2hlbiBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo0CiAgICAvLyBleHBvcnQgY2xhc3MgQXJjNFByaW1pdGl2ZU9wc0NvbnRyYWN0IGV4dGVuZHMgQ29udHJhY3QgewogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjMxOAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X3N0cmluZ19lcQogICAgYnl0ZWNfMSAvLyAweDAwCiAgICBpbnRjXzMgLy8gMAogICAgdW5jb3ZlciAyCiAgICBzZXRiaXQKICAgIGJ5dGVjXzAgLy8gMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludGNfMCAvLyAxCiAgICByZXR1cm4KCm1haW5fdmVyaWZ5X3N0cmluZ19hZGRfcm91dGVANDk6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MzEzCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBub3QgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBjYW4gb25seSBjYWxsIHdoZW4gbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NAogICAgLy8gZXhwb3J0IGNsYXNzIEFyYzRQcmltaXRpdmVPcHNDb250cmFjdCBleHRlbmRzIENvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDIKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czozMTMKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV9zdHJpbmdfYWRkCiAgICBieXRlY18wIC8vIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnRjXzAgLy8gMQogICAgcmV0dXJuCgptYWluX3ZlcmlmeV9zdHJpbmdfaW5pdF9yb3V0ZUA0ODoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czozMDgKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIG5vdCBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGNhbiBvbmx5IGNhbGwgd2hlbiBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo0CiAgICAvLyBleHBvcnQgY2xhc3MgQXJjNFByaW1pdGl2ZU9wc0NvbnRyYWN0IGV4dGVuZHMgQ29udHJhY3QgewogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgZXh0cmFjdCAyIDAKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czozMDgKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV9zdHJpbmdfaW5pdAogICAgYnl0ZWNfMCAvLyAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50Y18wIC8vIDEKICAgIHJldHVybgoKbWFpbl92ZXJpZnlfYmlndWZpeGVkbnhtX2Zyb21fbG9nX3JvdXRlQDQ3OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjMwNAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgbm90IE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gY2FuIG9ubHkgY2FsbCB3aGVuIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjQKICAgIC8vIGV4cG9ydCBjbGFzcyBBcmM0UHJpbWl0aXZlT3BzQ29udHJhY3QgZXh0ZW5kcyBDb250cmFjdCB7CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBleHRyYWN0IDIgMAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjMwNAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X2JpZ3VmaXhlZG54bV9mcm9tX2xvZwogICAgYnl0ZWNfMCAvLyAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50Y18wIC8vIDEKICAgIHJldHVybgoKbWFpbl92ZXJpZnlfdWZpeGVkbnhtX2Zyb21fbG9nX3JvdXRlQDQ2OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjMwMAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgbm90IE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gY2FuIG9ubHkgY2FsbCB3aGVuIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjQKICAgIC8vIGV4cG9ydCBjbGFzcyBBcmM0UHJpbWl0aXZlT3BzQ29udHJhY3QgZXh0ZW5kcyBDb250cmFjdCB7CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBleHRyYWN0IDIgMAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjMwMAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X3VmaXhlZG54bV9mcm9tX2xvZwogICAgYnl0ZWNfMCAvLyAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50Y18wIC8vIDEKICAgIHJldHVybgoKbWFpbl92ZXJpZnlfYmlndWZpeGVkbnhtX2Zyb21fYnl0ZXNfcm91dGVANDU6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6Mjk2CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBub3QgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBjYW4gb25seSBjYWxsIHdoZW4gbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NAogICAgLy8gZXhwb3J0IGNsYXNzIEFyYzRQcmltaXRpdmVPcHNDb250cmFjdCBleHRlbmRzIENvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGV4dHJhY3QgMiAwCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6Mjk2CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgYnl0ZWNfMCAvLyAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50Y18wIC8vIDEKICAgIHJldHVybgoKbWFpbl92ZXJpZnlfdWZpeGVkbnhtX2Zyb21fYnl0ZXNfcm91dGVANDQ6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MjkyCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBub3QgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBjYW4gb25seSBjYWxsIHdoZW4gbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NAogICAgLy8gZXhwb3J0IGNsYXNzIEFyYzRQcmltaXRpdmVPcHNDb250cmFjdCBleHRlbmRzIENvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGV4dHJhY3QgMiAwCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MjkyCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgYnl0ZWNfMCAvLyAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50Y18wIC8vIDEKICAgIHJldHVybgoKbWFpbl92ZXJpZnlfYmlndWZpeGVkbnhtX2J5dGVzX3JvdXRlQDQzOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjI4OAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgbm90IE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gY2FuIG9ubHkgY2FsbCB3aGVuIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjQKICAgIC8vIGV4cG9ydCBjbGFzcyBBcmM0UHJpbWl0aXZlT3BzQ29udHJhY3QgZXh0ZW5kcyBDb250cmFjdCB7CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6Mjg4CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgZHVwCiAgICBsZW4KICAgIGl0b2IKICAgIGV4dHJhY3QgNiAyCiAgICBzd2FwCiAgICBjb25jYXQKICAgIGJ5dGVjXzAgLy8gMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludGNfMCAvLyAxCiAgICByZXR1cm4KCm1haW5fdmVyaWZ5X3VmaXhlZG54bV9ieXRlc19yb3V0ZUA0MjoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoyODQKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIG5vdCBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGNhbiBvbmx5IGNhbGwgd2hlbiBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo0CiAgICAvLyBleHBvcnQgY2xhc3MgQXJjNFByaW1pdGl2ZU9wc0NvbnRyYWN0IGV4dGVuZHMgQ29udHJhY3QgewogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjI4NAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGR1cAogICAgbGVuCiAgICBpdG9iCiAgICBleHRyYWN0IDYgMgogICAgc3dhcAogICAgY29uY2F0CiAgICBieXRlY18wIC8vIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnRjXzAgLy8gMQogICAgcmV0dXJuCgptYWluX3ZlcmlmeV9ieXRlX2Zyb21fbG9nX3JvdXRlQDQxOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjI4MAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgbm90IE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gY2FuIG9ubHkgY2FsbCB3aGVuIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjQKICAgIC8vIGV4cG9ydCBjbGFzcyBBcmM0UHJpbWl0aXZlT3BzQ29udHJhY3QgZXh0ZW5kcyBDb250cmFjdCB7CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBleHRyYWN0IDIgMAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjI4MAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X2J5dGVfZnJvbV9sb2cKICAgIGJ5dGVjXzAgLy8gMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludGNfMCAvLyAxCiAgICByZXR1cm4KCm1haW5fdmVyaWZ5X2JpZ3VpbnRuX2Zyb21fbG9nX3JvdXRlQDQwOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjI3NgogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgbm90IE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gY2FuIG9ubHkgY2FsbCB3aGVuIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjQKICAgIC8vIGV4cG9ydCBjbGFzcyBBcmM0UHJpbWl0aXZlT3BzQ29udHJhY3QgZXh0ZW5kcyBDb250cmFjdCB7CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBleHRyYWN0IDIgMAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjI3NgogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X2JpZ3VpbnRuX2Zyb21fbG9nCiAgICBieXRlY18wIC8vIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnRjXzAgLy8gMQogICAgcmV0dXJuCgptYWluX3ZlcmlmeV91aW50bl9mcm9tX2xvZ19yb3V0ZUAzOToKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoyNzIKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIG5vdCBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGNhbiBvbmx5IGNhbGwgd2hlbiBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo0CiAgICAvLyBleHBvcnQgY2xhc3MgQXJjNFByaW1pdGl2ZU9wc0NvbnRyYWN0IGV4dGVuZHMgQ29udHJhY3QgewogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgZXh0cmFjdCAyIDAKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoyNzIKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV91aW50bl9mcm9tX2xvZwogICAgYnl0ZWNfMCAvLyAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50Y18wIC8vIDEKICAgIHJldHVybgoKbWFpbl92ZXJpZnlfYnl0ZV9mcm9tX2J5dGVzX3JvdXRlQDM4OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjI2OAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgbm90IE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gY2FuIG9ubHkgY2FsbCB3aGVuIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjQKICAgIC8vIGV4cG9ydCBjbGFzcyBBcmM0UHJpbWl0aXZlT3BzQ29udHJhY3QgZXh0ZW5kcyBDb250cmFjdCB7CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBleHRyYWN0IDIgMAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjI2OAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGJ5dGVjXzAgLy8gMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludGNfMCAvLyAxCiAgICByZXR1cm4KCm1haW5fdmVyaWZ5X2JpZ3VpbnRuX2Zyb21fYnl0ZXNfcm91dGVAMzc6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MjY0CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBub3QgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBjYW4gb25seSBjYWxsIHdoZW4gbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NAogICAgLy8gZXhwb3J0IGNsYXNzIEFyYzRQcmltaXRpdmVPcHNDb250cmFjdCBleHRlbmRzIENvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGV4dHJhY3QgMiAwCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MjY0CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgYnl0ZWNfMCAvLyAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50Y18wIC8vIDEKICAgIHJldHVybgoKbWFpbl92ZXJpZnlfdWludG5fZnJvbV9ieXRlc19yb3V0ZUAzNjoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoyNjAKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIG5vdCBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGNhbiBvbmx5IGNhbGwgd2hlbiBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo0CiAgICAvLyBleHBvcnQgY2xhc3MgQXJjNFByaW1pdGl2ZU9wc0NvbnRyYWN0IGV4dGVuZHMgQ29udHJhY3QgewogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgZXh0cmFjdCAyIDAKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoyNjAKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBieXRlY18wIC8vIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnRjXzAgLy8gMQogICAgcmV0dXJuCgptYWluX3ZlcmlmeV9ieXRlX2luaXRfcm91dGVAMzU6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MjU1CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBub3QgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBjYW4gb25seSBjYWxsIHdoZW4gbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NAogICAgLy8gZXhwb3J0IGNsYXNzIEFyYzRQcmltaXRpdmVPcHNDb250cmFjdCBleHRlbmRzIENvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGV4dHJhY3QgMiAwCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MjU1CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfYnl0ZV9pbml0CiAgICBieXRlY18wIC8vIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnRjXzAgLy8gMQogICAgcmV0dXJuCgptYWluX3ZlcmlmeV9iaWd1aW50bl9pbml0X3JvdXRlQDM0OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjI1MAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgbm90IE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gY2FuIG9ubHkgY2FsbCB3aGVuIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjQKICAgIC8vIGV4cG9ydCBjbGFzcyBBcmM0UHJpbWl0aXZlT3BzQ29udHJhY3QgZXh0ZW5kcyBDb250cmFjdCB7CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBleHRyYWN0IDIgMAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjI1MAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X2JpZ3VpbnRuX2luaXQKICAgIGJ5dGVjXzAgLy8gMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludGNfMCAvLyAxCiAgICByZXR1cm4KCm1haW5fdmVyaWZ5X3VpbnRuX2luaXRfcm91dGVAMzM6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MjQ1CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBub3QgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBjYW4gb25seSBjYWxsIHdoZW4gbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NAogICAgLy8gZXhwb3J0IGNsYXNzIEFyYzRQcmltaXRpdmVPcHNDb250cmFjdCBleHRlbmRzIENvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGV4dHJhY3QgMiAwCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MjQ1CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfdWludG5faW5pdAogICAgYnl0ZWNfMCAvLyAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50Y18wIC8vIDEKICAgIHJldHVybgoKbWFpbl92ZXJpZnlfYnl0ZV9ieXRlX2dlX3JvdXRlQDMyOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjIzNwogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgbm90IE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gY2FuIG9ubHkgY2FsbCB3aGVuIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjQKICAgIC8vIGV4cG9ydCBjbGFzcyBBcmM0UHJpbWl0aXZlT3BzQ29udHJhY3QgZXh0ZW5kcyBDb250cmFjdCB7CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBleHRyYWN0IDIgMAogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMgogICAgZXh0cmFjdCAyIDAKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoyMzcKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV9ieXRlX2J5dGVfZ2UKICAgIGJ5dGVjXzEgLy8gMHgwMAogICAgaW50Y18zIC8vIDAKICAgIHVuY292ZXIgMgogICAgc2V0Yml0CiAgICBieXRlY18wIC8vIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnRjXzAgLy8gMQogICAgcmV0dXJuCgptYWluX3ZlcmlmeV9iaWd1aW50bl9iaWd1aW50bl9nZV9yb3V0ZUAzMToKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoyMjkKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIG5vdCBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGNhbiBvbmx5IGNhbGwgd2hlbiBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo0CiAgICAvLyBleHBvcnQgY2xhc3MgQXJjNFByaW1pdGl2ZU9wc0NvbnRyYWN0IGV4dGVuZHMgQ29udHJhY3QgewogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgZXh0cmFjdCAyIDAKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDIKICAgIGV4dHJhY3QgMiAwCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MjI5CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfYmlndWludG5fYmlndWludG5fZ2UKICAgIGJ5dGVjXzEgLy8gMHgwMAogICAgaW50Y18zIC8vIDAKICAgIHVuY292ZXIgMgogICAgc2V0Yml0CiAgICBieXRlY18wIC8vIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnRjXzAgLy8gMQogICAgcmV0dXJuCgptYWluX3ZlcmlmeV91aW50bl9iaWd1aW50bl9nZV9yb3V0ZUAzMDoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoyMjEKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIG5vdCBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGNhbiBvbmx5IGNhbGwgd2hlbiBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo0CiAgICAvLyBleHBvcnQgY2xhc3MgQXJjNFByaW1pdGl2ZU9wc0NvbnRyYWN0IGV4dGVuZHMgQ29udHJhY3QgewogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgZXh0cmFjdCAyIDAKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDIKICAgIGV4dHJhY3QgMiAwCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MjIxCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfdWludG5fYmlndWludG5fZ2UKICAgIGJ5dGVjXzEgLy8gMHgwMAogICAgaW50Y18zIC8vIDAKICAgIHVuY292ZXIgMgogICAgc2V0Yml0CiAgICBieXRlY18wIC8vIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnRjXzAgLy8gMQogICAgcmV0dXJuCgptYWluX3ZlcmlmeV9iaWd1aW50bl91aW50bl9nZV9yb3V0ZUAyOToKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoyMTMKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIG5vdCBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGNhbiBvbmx5IGNhbGwgd2hlbiBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo0CiAgICAvLyBleHBvcnQgY2xhc3MgQXJjNFByaW1pdGl2ZU9wc0NvbnRyYWN0IGV4dGVuZHMgQ29udHJhY3QgewogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgZXh0cmFjdCAyIDAKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDIKICAgIGV4dHJhY3QgMiAwCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MjEzCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfYmlndWludG5fdWludG5fZ2UKICAgIGJ5dGVjXzEgLy8gMHgwMAogICAgaW50Y18zIC8vIDAKICAgIHVuY292ZXIgMgogICAgc2V0Yml0CiAgICBieXRlY18wIC8vIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnRjXzAgLy8gMQogICAgcmV0dXJuCgptYWluX3ZlcmlmeV91aW50bl91aW50bl9nZV9yb3V0ZUAyODoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoyMDUKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIG5vdCBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGNhbiBvbmx5IGNhbGwgd2hlbiBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo0CiAgICAvLyBleHBvcnQgY2xhc3MgQXJjNFByaW1pdGl2ZU9wc0NvbnRyYWN0IGV4dGVuZHMgQ29udHJhY3QgewogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgZXh0cmFjdCAyIDAKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDIKICAgIGV4dHJhY3QgMiAwCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MjA1CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfdWludG5fdWludG5fZ2UKICAgIGJ5dGVjXzEgLy8gMHgwMAogICAgaW50Y18zIC8vIDAKICAgIHVuY292ZXIgMgogICAgc2V0Yml0CiAgICBieXRlY18wIC8vIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnRjXzAgLy8gMQogICAgcmV0dXJuCgptYWluX3ZlcmlmeV9ieXRlX2J5dGVfZ3Rfcm91dGVAMjc6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTk3CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBub3QgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBjYW4gb25seSBjYWxsIHdoZW4gbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NAogICAgLy8gZXhwb3J0IGNsYXNzIEFyYzRQcmltaXRpdmVPcHNDb250cmFjdCBleHRlbmRzIENvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGV4dHJhY3QgMiAwCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAyCiAgICBleHRyYWN0IDIgMAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjE5NwogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X2J5dGVfYnl0ZV9ndAogICAgYnl0ZWNfMSAvLyAweDAwCiAgICBpbnRjXzMgLy8gMAogICAgdW5jb3ZlciAyCiAgICBzZXRiaXQKICAgIGJ5dGVjXzAgLy8gMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludGNfMCAvLyAxCiAgICByZXR1cm4KCm1haW5fdmVyaWZ5X2JpZ3VpbnRuX2JpZ3VpbnRuX2d0X3JvdXRlQDI2OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjE4OQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgbm90IE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gY2FuIG9ubHkgY2FsbCB3aGVuIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjQKICAgIC8vIGV4cG9ydCBjbGFzcyBBcmM0UHJpbWl0aXZlT3BzQ29udHJhY3QgZXh0ZW5kcyBDb250cmFjdCB7CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBleHRyYWN0IDIgMAogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMgogICAgZXh0cmFjdCAyIDAKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoxODkKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV9iaWd1aW50bl9iaWd1aW50bl9ndAogICAgYnl0ZWNfMSAvLyAweDAwCiAgICBpbnRjXzMgLy8gMAogICAgdW5jb3ZlciAyCiAgICBzZXRiaXQKICAgIGJ5dGVjXzAgLy8gMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludGNfMCAvLyAxCiAgICByZXR1cm4KCm1haW5fdmVyaWZ5X3VpbnRuX2JpZ3VpbnRuX2d0X3JvdXRlQDI1OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjE4MQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgbm90IE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gY2FuIG9ubHkgY2FsbCB3aGVuIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjQKICAgIC8vIGV4cG9ydCBjbGFzcyBBcmM0UHJpbWl0aXZlT3BzQ29udHJhY3QgZXh0ZW5kcyBDb250cmFjdCB7CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBleHRyYWN0IDIgMAogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMgogICAgZXh0cmFjdCAyIDAKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoxODEKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV91aW50bl9iaWd1aW50bl9ndAogICAgYnl0ZWNfMSAvLyAweDAwCiAgICBpbnRjXzMgLy8gMAogICAgdW5jb3ZlciAyCiAgICBzZXRiaXQKICAgIGJ5dGVjXzAgLy8gMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludGNfMCAvLyAxCiAgICByZXR1cm4KCm1haW5fdmVyaWZ5X2JpZ3VpbnRuX3VpbnRuX2d0X3JvdXRlQDI0OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjE3MwogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgbm90IE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gY2FuIG9ubHkgY2FsbCB3aGVuIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjQKICAgIC8vIGV4cG9ydCBjbGFzcyBBcmM0UHJpbWl0aXZlT3BzQ29udHJhY3QgZXh0ZW5kcyBDb250cmFjdCB7CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBleHRyYWN0IDIgMAogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMgogICAgZXh0cmFjdCAyIDAKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoxNzMKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV9iaWd1aW50bl91aW50bl9ndAogICAgYnl0ZWNfMSAvLyAweDAwCiAgICBpbnRjXzMgLy8gMAogICAgdW5jb3ZlciAyCiAgICBzZXRiaXQKICAgIGJ5dGVjXzAgLy8gMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludGNfMCAvLyAxCiAgICByZXR1cm4KCm1haW5fdmVyaWZ5X3VpbnRuX3VpbnRuX2d0X3JvdXRlQDIzOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjE2NQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgbm90IE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gY2FuIG9ubHkgY2FsbCB3aGVuIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjQKICAgIC8vIGV4cG9ydCBjbGFzcyBBcmM0UHJpbWl0aXZlT3BzQ29udHJhY3QgZXh0ZW5kcyBDb250cmFjdCB7CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBleHRyYWN0IDIgMAogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMgogICAgZXh0cmFjdCAyIDAKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoxNjUKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV91aW50bl91aW50bl9ndAogICAgYnl0ZWNfMSAvLyAweDAwCiAgICBpbnRjXzMgLy8gMAogICAgdW5jb3ZlciAyCiAgICBzZXRiaXQKICAgIGJ5dGVjXzAgLy8gMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludGNfMCAvLyAxCiAgICByZXR1cm4KCm1haW5fdmVyaWZ5X2J5dGVfYnl0ZV9sZV9yb3V0ZUAyMjoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoxNTcKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIG5vdCBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGNhbiBvbmx5IGNhbGwgd2hlbiBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo0CiAgICAvLyBleHBvcnQgY2xhc3MgQXJjNFByaW1pdGl2ZU9wc0NvbnRyYWN0IGV4dGVuZHMgQ29udHJhY3QgewogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgZXh0cmFjdCAyIDAKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDIKICAgIGV4dHJhY3QgMiAwCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTU3CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfYnl0ZV9ieXRlX2xlCiAgICBieXRlY18xIC8vIDB4MDAKICAgIGludGNfMyAvLyAwCiAgICB1bmNvdmVyIDIKICAgIHNldGJpdAogICAgYnl0ZWNfMCAvLyAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50Y18wIC8vIDEKICAgIHJldHVybgoKbWFpbl92ZXJpZnlfYmlndWludG5fYmlndWludG5fbGVfcm91dGVAMjE6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTQ5CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBub3QgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBjYW4gb25seSBjYWxsIHdoZW4gbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NAogICAgLy8gZXhwb3J0IGNsYXNzIEFyYzRQcmltaXRpdmVPcHNDb250cmFjdCBleHRlbmRzIENvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGV4dHJhY3QgMiAwCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAyCiAgICBleHRyYWN0IDIgMAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjE0OQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X2JpZ3VpbnRuX2JpZ3VpbnRuX2xlCiAgICBieXRlY18xIC8vIDB4MDAKICAgIGludGNfMyAvLyAwCiAgICB1bmNvdmVyIDIKICAgIHNldGJpdAogICAgYnl0ZWNfMCAvLyAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50Y18wIC8vIDEKICAgIHJldHVybgoKbWFpbl92ZXJpZnlfdWludG5fYmlndWludG5fbGVfcm91dGVAMjA6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTQxCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBub3QgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBjYW4gb25seSBjYWxsIHdoZW4gbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NAogICAgLy8gZXhwb3J0IGNsYXNzIEFyYzRQcmltaXRpdmVPcHNDb250cmFjdCBleHRlbmRzIENvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGV4dHJhY3QgMiAwCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAyCiAgICBleHRyYWN0IDIgMAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjE0MQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X3VpbnRuX2JpZ3VpbnRuX2xlCiAgICBieXRlY18xIC8vIDB4MDAKICAgIGludGNfMyAvLyAwCiAgICB1bmNvdmVyIDIKICAgIHNldGJpdAogICAgYnl0ZWNfMCAvLyAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50Y18wIC8vIDEKICAgIHJldHVybgoKbWFpbl92ZXJpZnlfYmlndWludG5fdWludG5fbGVfcm91dGVAMTk6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTMzCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBub3QgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBjYW4gb25seSBjYWxsIHdoZW4gbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NAogICAgLy8gZXhwb3J0IGNsYXNzIEFyYzRQcmltaXRpdmVPcHNDb250cmFjdCBleHRlbmRzIENvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGV4dHJhY3QgMiAwCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAyCiAgICBleHRyYWN0IDIgMAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjEzMwogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X2JpZ3VpbnRuX3VpbnRuX2xlCiAgICBieXRlY18xIC8vIDB4MDAKICAgIGludGNfMyAvLyAwCiAgICB1bmNvdmVyIDIKICAgIHNldGJpdAogICAgYnl0ZWNfMCAvLyAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50Y18wIC8vIDEKICAgIHJldHVybgoKbWFpbl92ZXJpZnlfdWludG5fdWludG5fbGVfcm91dGVAMTg6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTI1CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBub3QgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBjYW4gb25seSBjYWxsIHdoZW4gbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NAogICAgLy8gZXhwb3J0IGNsYXNzIEFyYzRQcmltaXRpdmVPcHNDb250cmFjdCBleHRlbmRzIENvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGV4dHJhY3QgMiAwCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAyCiAgICBleHRyYWN0IDIgMAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjEyNQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X3VpbnRuX3VpbnRuX2xlCiAgICBieXRlY18xIC8vIDB4MDAKICAgIGludGNfMyAvLyAwCiAgICB1bmNvdmVyIDIKICAgIHNldGJpdAogICAgYnl0ZWNfMCAvLyAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50Y18wIC8vIDEKICAgIHJldHVybgoKbWFpbl92ZXJpZnlfYnl0ZV9ieXRlX2x0X3JvdXRlQDE3OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjExNwogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgbm90IE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gY2FuIG9ubHkgY2FsbCB3aGVuIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjQKICAgIC8vIGV4cG9ydCBjbGFzcyBBcmM0UHJpbWl0aXZlT3BzQ29udHJhY3QgZXh0ZW5kcyBDb250cmFjdCB7CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBleHRyYWN0IDIgMAogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMgogICAgZXh0cmFjdCAyIDAKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoxMTcKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV9ieXRlX2J5dGVfbHQKICAgIGJ5dGVjXzEgLy8gMHgwMAogICAgaW50Y18zIC8vIDAKICAgIHVuY292ZXIgMgogICAgc2V0Yml0CiAgICBieXRlY18wIC8vIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnRjXzAgLy8gMQogICAgcmV0dXJuCgptYWluX3ZlcmlmeV9iaWd1aW50bl9iaWd1aW50bl9sdF9yb3V0ZUAxNjoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoxMDkKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIG5vdCBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGNhbiBvbmx5IGNhbGwgd2hlbiBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo0CiAgICAvLyBleHBvcnQgY2xhc3MgQXJjNFByaW1pdGl2ZU9wc0NvbnRyYWN0IGV4dGVuZHMgQ29udHJhY3QgewogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgZXh0cmFjdCAyIDAKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDIKICAgIGV4dHJhY3QgMiAwCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTA5CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfYmlndWludG5fYmlndWludG5fbHQKICAgIGJ5dGVjXzEgLy8gMHgwMAogICAgaW50Y18zIC8vIDAKICAgIHVuY292ZXIgMgogICAgc2V0Yml0CiAgICBieXRlY18wIC8vIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnRjXzAgLy8gMQogICAgcmV0dXJuCgptYWluX3ZlcmlmeV91aW50bl9iaWd1aW50bl9sdF9yb3V0ZUAxNToKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoxMDEKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIG5vdCBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGNhbiBvbmx5IGNhbGwgd2hlbiBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo0CiAgICAvLyBleHBvcnQgY2xhc3MgQXJjNFByaW1pdGl2ZU9wc0NvbnRyYWN0IGV4dGVuZHMgQ29udHJhY3QgewogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgZXh0cmFjdCAyIDAKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDIKICAgIGV4dHJhY3QgMiAwCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTAxCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfdWludG5fYmlndWludG5fbHQKICAgIGJ5dGVjXzEgLy8gMHgwMAogICAgaW50Y18zIC8vIDAKICAgIHVuY292ZXIgMgogICAgc2V0Yml0CiAgICBieXRlY18wIC8vIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnRjXzAgLy8gMQogICAgcmV0dXJuCgptYWluX3ZlcmlmeV9iaWd1aW50bl91aW50bl9sdF9yb3V0ZUAxNDoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo5MwogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgbm90IE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gY2FuIG9ubHkgY2FsbCB3aGVuIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjQKICAgIC8vIGV4cG9ydCBjbGFzcyBBcmM0UHJpbWl0aXZlT3BzQ29udHJhY3QgZXh0ZW5kcyBDb250cmFjdCB7CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBleHRyYWN0IDIgMAogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMgogICAgZXh0cmFjdCAyIDAKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo5MwogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X2JpZ3VpbnRuX3VpbnRuX2x0CiAgICBieXRlY18xIC8vIDB4MDAKICAgIGludGNfMyAvLyAwCiAgICB1bmNvdmVyIDIKICAgIHNldGJpdAogICAgYnl0ZWNfMCAvLyAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50Y18wIC8vIDEKICAgIHJldHVybgoKbWFpbl92ZXJpZnlfdWludG5fdWludG5fbHRfcm91dGVAMTM6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6ODUKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIG5vdCBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGNhbiBvbmx5IGNhbGwgd2hlbiBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo0CiAgICAvLyBleHBvcnQgY2xhc3MgQXJjNFByaW1pdGl2ZU9wc0NvbnRyYWN0IGV4dGVuZHMgQ29udHJhY3QgewogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgZXh0cmFjdCAyIDAKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDIKICAgIGV4dHJhY3QgMiAwCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6ODUKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV91aW50bl91aW50bl9sdAogICAgYnl0ZWNfMSAvLyAweDAwCiAgICBpbnRjXzMgLy8gMAogICAgdW5jb3ZlciAyCiAgICBzZXRiaXQKICAgIGJ5dGVjXzAgLy8gMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludGNfMCAvLyAxCiAgICByZXR1cm4KCm1haW5fdmVyaWZ5X2J5dGVfYnl0ZV9uZV9yb3V0ZUAxMjoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo3NwogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgbm90IE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gY2FuIG9ubHkgY2FsbCB3aGVuIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjQKICAgIC8vIGV4cG9ydCBjbGFzcyBBcmM0UHJpbWl0aXZlT3BzQ29udHJhY3QgZXh0ZW5kcyBDb250cmFjdCB7CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBleHRyYWN0IDIgMAogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMgogICAgZXh0cmFjdCAyIDAKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo3NwogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X2J5dGVfYnl0ZV9uZQogICAgYnl0ZWNfMSAvLyAweDAwCiAgICBpbnRjXzMgLy8gMAogICAgdW5jb3ZlciAyCiAgICBzZXRiaXQKICAgIGJ5dGVjXzAgLy8gMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludGNfMCAvLyAxCiAgICByZXR1cm4KCm1haW5fdmVyaWZ5X2JpZ3VpbnRuX2JpZ3VpbnRuX25lX3JvdXRlQDExOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjY5CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBub3QgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBjYW4gb25seSBjYWxsIHdoZW4gbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NAogICAgLy8gZXhwb3J0IGNsYXNzIEFyYzRQcmltaXRpdmVPcHNDb250cmFjdCBleHRlbmRzIENvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGV4dHJhY3QgMiAwCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAyCiAgICBleHRyYWN0IDIgMAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjY5CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfYmlndWludG5fYmlndWludG5fbmUKICAgIGJ5dGVjXzEgLy8gMHgwMAogICAgaW50Y18zIC8vIDAKICAgIHVuY292ZXIgMgogICAgc2V0Yml0CiAgICBieXRlY18wIC8vIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnRjXzAgLy8gMQogICAgcmV0dXJuCgptYWluX3ZlcmlmeV91aW50bl9iaWd1aW50bl9uZV9yb3V0ZUAxMDoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo2MQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgbm90IE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gY2FuIG9ubHkgY2FsbCB3aGVuIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjQKICAgIC8vIGV4cG9ydCBjbGFzcyBBcmM0UHJpbWl0aXZlT3BzQ29udHJhY3QgZXh0ZW5kcyBDb250cmFjdCB7CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBleHRyYWN0IDIgMAogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMgogICAgZXh0cmFjdCAyIDAKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo2MQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X3VpbnRuX2JpZ3VpbnRuX25lCiAgICBieXRlY18xIC8vIDB4MDAKICAgIGludGNfMyAvLyAwCiAgICB1bmNvdmVyIDIKICAgIHNldGJpdAogICAgYnl0ZWNfMCAvLyAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50Y18wIC8vIDEKICAgIHJldHVybgoKbWFpbl92ZXJpZnlfYmlndWludG5fdWludG5fbmVfcm91dGVAOToKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo1MwogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgbm90IE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gY2FuIG9ubHkgY2FsbCB3aGVuIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjQKICAgIC8vIGV4cG9ydCBjbGFzcyBBcmM0UHJpbWl0aXZlT3BzQ29udHJhY3QgZXh0ZW5kcyBDb250cmFjdCB7CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBleHRyYWN0IDIgMAogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMgogICAgZXh0cmFjdCAyIDAKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo1MwogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X2JpZ3VpbnRuX3VpbnRuX25lCiAgICBieXRlY18xIC8vIDB4MDAKICAgIGludGNfMyAvLyAwCiAgICB1bmNvdmVyIDIKICAgIHNldGJpdAogICAgYnl0ZWNfMCAvLyAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50Y18wIC8vIDEKICAgIHJldHVybgoKbWFpbl92ZXJpZnlfdWludG5fdWludG5fbmVfcm91dGVAODoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo0NQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgbm90IE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gY2FuIG9ubHkgY2FsbCB3aGVuIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjQKICAgIC8vIGV4cG9ydCBjbGFzcyBBcmM0UHJpbWl0aXZlT3BzQ29udHJhY3QgZXh0ZW5kcyBDb250cmFjdCB7CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBleHRyYWN0IDIgMAogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMgogICAgZXh0cmFjdCAyIDAKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo0NQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X3VpbnRuX3VpbnRuX25lCiAgICBieXRlY18xIC8vIDB4MDAKICAgIGludGNfMyAvLyAwCiAgICB1bmNvdmVyIDIKICAgIHNldGJpdAogICAgYnl0ZWNfMCAvLyAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50Y18wIC8vIDEKICAgIHJldHVybgoKbWFpbl92ZXJpZnlfYnl0ZV9ieXRlX2VxX3JvdXRlQDc6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MzcKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIG5vdCBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGNhbiBvbmx5IGNhbGwgd2hlbiBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo0CiAgICAvLyBleHBvcnQgY2xhc3MgQXJjNFByaW1pdGl2ZU9wc0NvbnRyYWN0IGV4dGVuZHMgQ29udHJhY3QgewogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgZXh0cmFjdCAyIDAKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDIKICAgIGV4dHJhY3QgMiAwCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MzcKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV9ieXRlX2J5dGVfZXEKICAgIGJ5dGVjXzEgLy8gMHgwMAogICAgaW50Y18zIC8vIDAKICAgIHVuY292ZXIgMgogICAgc2V0Yml0CiAgICBieXRlY18wIC8vIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnRjXzAgLy8gMQogICAgcmV0dXJuCgptYWluX3ZlcmlmeV9iaWd1aW50bl9iaWd1aW50bl9lcV9yb3V0ZUA2OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjI5CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBub3QgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBjYW4gb25seSBjYWxsIHdoZW4gbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NAogICAgLy8gZXhwb3J0IGNsYXNzIEFyYzRQcmltaXRpdmVPcHNDb250cmFjdCBleHRlbmRzIENvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGV4dHJhY3QgMiAwCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAyCiAgICBleHRyYWN0IDIgMAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjI5CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfYmlndWludG5fYmlndWludG5fZXEKICAgIGJ5dGVjXzEgLy8gMHgwMAogICAgaW50Y18zIC8vIDAKICAgIHVuY292ZXIgMgogICAgc2V0Yml0CiAgICBieXRlY18wIC8vIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnRjXzAgLy8gMQogICAgcmV0dXJuCgptYWluX3ZlcmlmeV91aW50bl9iaWd1aW50bl9lcV9yb3V0ZUA1OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjIxCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBub3QgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBjYW4gb25seSBjYWxsIHdoZW4gbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NAogICAgLy8gZXhwb3J0IGNsYXNzIEFyYzRQcmltaXRpdmVPcHNDb250cmFjdCBleHRlbmRzIENvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGV4dHJhY3QgMiAwCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAyCiAgICBleHRyYWN0IDIgMAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjIxCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfdWludG5fYmlndWludG5fZXEKICAgIGJ5dGVjXzEgLy8gMHgwMAogICAgaW50Y18zIC8vIDAKICAgIHVuY292ZXIgMgogICAgc2V0Yml0CiAgICBieXRlY18wIC8vIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnRjXzAgLy8gMQogICAgcmV0dXJuCgptYWluX3ZlcmlmeV9iaWd1aW50bl91aW50bl9lcV9yb3V0ZUA0OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjEzCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBub3QgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBjYW4gb25seSBjYWxsIHdoZW4gbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NAogICAgLy8gZXhwb3J0IGNsYXNzIEFyYzRQcmltaXRpdmVPcHNDb250cmFjdCBleHRlbmRzIENvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGV4dHJhY3QgMiAwCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAyCiAgICBleHRyYWN0IDIgMAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjEzCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfYmlndWludG5fdWludG5fZXEKICAgIGJ5dGVjXzEgLy8gMHgwMAogICAgaW50Y18zIC8vIDAKICAgIHVuY292ZXIgMgogICAgc2V0Yml0CiAgICBieXRlY18wIC8vIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnRjXzAgLy8gMQogICAgcmV0dXJuCgptYWluX3ZlcmlmeV91aW50bl91aW50bl9lcV9yb3V0ZUAzOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjUKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIG5vdCBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGNhbiBvbmx5IGNhbGwgd2hlbiBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo0CiAgICAvLyBleHBvcnQgY2xhc3MgQXJjNFByaW1pdGl2ZU9wc0NvbnRyYWN0IGV4dGVuZHMgQ29udHJhY3QgewogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgZXh0cmFjdCAyIDAKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDIKICAgIGV4dHJhY3QgMiAwCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X3VpbnRuX3VpbnRuX2VxCiAgICBieXRlY18xIC8vIDB4MDAKICAgIGludGNfMyAvLyAwCiAgICB1bmNvdmVyIDIKICAgIHNldGJpdAogICAgYnl0ZWNfMCAvLyAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50Y18wIC8vIDEKICAgIHJldHVybgoKbWFpbl9iYXJlX3JvdXRpbmdANjA6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NAogICAgLy8gZXhwb3J0IGNsYXNzIEFyYzRQcmltaXRpdmVPcHNDb250cmFjdCBleHRlbmRzIENvbnRyYWN0IHsKICAgIHR4biBPbkNvbXBsZXRpb24KICAgIGJueiBtYWluX2FmdGVyX2lmX2Vsc2VANjQKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICAhCiAgICBhc3NlcnQgLy8gY2FuIG9ubHkgY2FsbCB3aGVuIGNyZWF0aW5nCiAgICBpbnRjXzAgLy8gMQogICAgcmV0dXJuCgoKLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjpBcmM0UHJpbWl0aXZlT3BzQ29udHJhY3QudmVyaWZ5X3VpbnRuX3VpbnRuX2VxKGE6IGJ5dGVzLCBiOiBieXRlcykgLT4gdWludDY0Ogp2ZXJpZnlfdWludG5fdWludG5fZXE6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NS02CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gcHVibGljIHZlcmlmeV91aW50bl91aW50bl9lcShhOiBieXRlcywgYjogYnl0ZXMpOiBib29sZWFuIHsKICAgIHByb3RvIDIgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjkKICAgIC8vIGNvbnN0IGFVaW50TiA9IG5ldyBVaW50Tjw2ND4oYUJpZ3VpbnQpCiAgICBmcmFtZV9kaWcgLTIKICAgIGxlbgogICAgaW50Y18xIC8vIDgKICAgIDw9CiAgICBhc3NlcnQgLy8gb3ZlcmZsb3cKICAgIGludGNfMSAvLyA4CiAgICBiemVybwogICAgZnJhbWVfZGlnIC0yCiAgICBkaWcgMQogICAgYnwKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoxMAogICAgLy8gY29uc3QgYlVpbnROID0gbmV3IFVpbnROPDY0PihiQmlndWludCkKICAgIGZyYW1lX2RpZyAtMQogICAgbGVuCiAgICBpbnRjXzEgLy8gOAogICAgPD0KICAgIGFzc2VydCAvLyBvdmVyZmxvdwogICAgZnJhbWVfZGlnIC0xCiAgICB1bmNvdmVyIDIKICAgIGJ8CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTEKICAgIC8vIHJldHVybiBhVWludE4gPT09IGJVaW50TgogICAgPT0KICAgIHJldHN1YgoKCi8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo6QXJjNFByaW1pdGl2ZU9wc0NvbnRyYWN0LnZlcmlmeV9iaWd1aW50bl91aW50bl9lcShhOiBieXRlcywgYjogYnl0ZXMpIC0+IHVpbnQ2NDoKdmVyaWZ5X2JpZ3VpbnRuX3VpbnRuX2VxOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjEzLTE0CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gcHVibGljIHZlcmlmeV9iaWd1aW50bl91aW50bl9lcShhOiBieXRlcywgYjogYnl0ZXMpOiBib29sZWFuIHsKICAgIHByb3RvIDIgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjE3CiAgICAvLyBjb25zdCBhVWludE4gPSBuZXcgVWludE48NTEyPihhQmlndWludCkKICAgIGZyYW1lX2RpZyAtMgogICAgbGVuCiAgICBpbnRjXzIgLy8gNjQKICAgIDw9CiAgICBhc3NlcnQgLy8gb3ZlcmZsb3cKICAgIGludGNfMiAvLyA2NAogICAgYnplcm8KICAgIGZyYW1lX2RpZyAtMgogICAgYnwKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoxOAogICAgLy8gY29uc3QgYlVpbnROID0gbmV3IFVpbnROPDY0PihiQmlndWludCkKICAgIGZyYW1lX2RpZyAtMQogICAgbGVuCiAgICBpbnRjXzEgLy8gOAogICAgPD0KICAgIGFzc2VydCAvLyBvdmVyZmxvdwogICAgaW50Y18xIC8vIDgKICAgIGJ6ZXJvCiAgICBmcmFtZV9kaWcgLTEKICAgIGJ8CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTkKICAgIC8vIHJldHVybiBhVWludE4uYnl0ZXMuZXF1YWxzKGJVaW50Ti5ieXRlcykKICAgID09CiAgICByZXRzdWIKCgovLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OkFyYzRQcmltaXRpdmVPcHNDb250cmFjdC52ZXJpZnlfdWludG5fYmlndWludG5fZXEoYTogYnl0ZXMsIGI6IGJ5dGVzKSAtPiB1aW50NjQ6CnZlcmlmeV91aW50bl9iaWd1aW50bl9lcToKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoyMS0yMgogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIHB1YmxpYyB2ZXJpZnlfdWludG5fYmlndWludG5fZXEoYTogYnl0ZXMsIGI6IGJ5dGVzKTogYm9vbGVhbiB7CiAgICBwcm90byAyIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoyNQogICAgLy8gY29uc3QgYVVpbnROID0gbmV3IFVpbnROPDY0PihhQmlndWludCkKICAgIGZyYW1lX2RpZyAtMgogICAgbGVuCiAgICBpbnRjXzEgLy8gOAogICAgPD0KICAgIGFzc2VydCAvLyBvdmVyZmxvdwogICAgaW50Y18xIC8vIDgKICAgIGJ6ZXJvCiAgICBmcmFtZV9kaWcgLTIKICAgIGJ8CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MjYKICAgIC8vIGNvbnN0IGJVaW50TiA9IG5ldyBVaW50Tjw1MTI+KGJCaWd1aW50KQogICAgZnJhbWVfZGlnIC0xCiAgICBsZW4KICAgIGludGNfMiAvLyA2NAogICAgPD0KICAgIGFzc2VydCAvLyBvdmVyZmxvdwogICAgaW50Y18yIC8vIDY0CiAgICBiemVybwogICAgZnJhbWVfZGlnIC0xCiAgICBifAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjI3CiAgICAvLyByZXR1cm4gYVVpbnROLmJ5dGVzLmVxdWFscyhiVWludE4uYnl0ZXMpCiAgICA9PQogICAgcmV0c3ViCgoKLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjpBcmM0UHJpbWl0aXZlT3BzQ29udHJhY3QudmVyaWZ5X2JpZ3VpbnRuX2JpZ3VpbnRuX2VxKGE6IGJ5dGVzLCBiOiBieXRlcykgLT4gdWludDY0Ogp2ZXJpZnlfYmlndWludG5fYmlndWludG5fZXE6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MjktMzAKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBwdWJsaWMgdmVyaWZ5X2JpZ3VpbnRuX2JpZ3VpbnRuX2VxKGE6IGJ5dGVzLCBiOiBieXRlcyk6IGJvb2xlYW4gewogICAgcHJvdG8gMiAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MzMKICAgIC8vIGNvbnN0IGFVaW50TiA9IG5ldyBVaW50Tjw1MTI+KGFCaWd1aW50KQogICAgZnJhbWVfZGlnIC0yCiAgICBsZW4KICAgIGludGNfMiAvLyA2NAogICAgPD0KICAgIGFzc2VydCAvLyBvdmVyZmxvdwogICAgaW50Y18yIC8vIDY0CiAgICBiemVybwogICAgZnJhbWVfZGlnIC0yCiAgICBkaWcgMQogICAgYnwKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czozNAogICAgLy8gY29uc3QgYlVpbnROID0gbmV3IFVpbnROPDUxMj4oYkJpZ3VpbnQpCiAgICBmcmFtZV9kaWcgLTEKICAgIGxlbgogICAgaW50Y18yIC8vIDY0CiAgICA8PQogICAgYXNzZXJ0IC8vIG92ZXJmbG93CiAgICBmcmFtZV9kaWcgLTEKICAgIHVuY292ZXIgMgogICAgYnwKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czozNQogICAgLy8gcmV0dXJuIGFVaW50TiA9PT0gYlVpbnROCiAgICA9PQogICAgcmV0c3ViCgoKLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjpBcmM0UHJpbWl0aXZlT3BzQ29udHJhY3QudmVyaWZ5X2J5dGVfYnl0ZV9lcShhOiBieXRlcywgYjogYnl0ZXMpIC0+IHVpbnQ2NDoKdmVyaWZ5X2J5dGVfYnl0ZV9lcToKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czozNy0zOAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIHB1YmxpYyB2ZXJpZnlfYnl0ZV9ieXRlX2VxKGE6IGJ5dGVzLCBiOiBieXRlcyk6IGJvb2xlYW4gewogICAgcHJvdG8gMiAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NDEKICAgIC8vIGNvbnN0IGFCeXRlID0gbmV3IEJ5dGUoYUJpZ3VpbnQpCiAgICBmcmFtZV9kaWcgLTIKICAgIGxlbgogICAgaW50Y18wIC8vIDEKICAgIDw9CiAgICBhc3NlcnQgLy8gb3ZlcmZsb3cKICAgIGludGNfMCAvLyAxCiAgICBiemVybwogICAgZnJhbWVfZGlnIC0yCiAgICBkaWcgMQogICAgYnwKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo0MgogICAgLy8gY29uc3QgYkJ5dGUgPSBuZXcgQnl0ZShiQmlndWludCkKICAgIGZyYW1lX2RpZyAtMQogICAgbGVuCiAgICBpbnRjXzAgLy8gMQogICAgPD0KICAgIGFzc2VydCAvLyBvdmVyZmxvdwogICAgZnJhbWVfZGlnIC0xCiAgICB1bmNvdmVyIDIKICAgIGJ8CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NDMKICAgIC8vIHJldHVybiBhQnl0ZSA9PT0gYkJ5dGUKICAgID09CiAgICByZXRzdWIKCgovLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OkFyYzRQcmltaXRpdmVPcHNDb250cmFjdC52ZXJpZnlfdWludG5fdWludG5fbmUoYTogYnl0ZXMsIGI6IGJ5dGVzKSAtPiB1aW50NjQ6CnZlcmlmeV91aW50bl91aW50bl9uZToKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo0NS00NgogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIHB1YmxpYyB2ZXJpZnlfdWludG5fdWludG5fbmUoYTogYnl0ZXMsIGI6IGJ5dGVzKTogYm9vbGVhbiB7CiAgICBwcm90byAyIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo0OQogICAgLy8gY29uc3QgYVVpbnROID0gbmV3IFVpbnROPDY0PihhQmlndWludCkKICAgIGZyYW1lX2RpZyAtMgogICAgbGVuCiAgICBpbnRjXzEgLy8gOAogICAgPD0KICAgIGFzc2VydCAvLyBvdmVyZmxvdwogICAgaW50Y18xIC8vIDgKICAgIGJ6ZXJvCiAgICBmcmFtZV9kaWcgLTIKICAgIGRpZyAxCiAgICBifAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjUwCiAgICAvLyBjb25zdCBiVWludE4gPSBuZXcgVWludE48NjQ+KGJCaWd1aW50KQogICAgZnJhbWVfZGlnIC0xCiAgICBsZW4KICAgIGludGNfMSAvLyA4CiAgICA8PQogICAgYXNzZXJ0IC8vIG92ZXJmbG93CiAgICBmcmFtZV9kaWcgLTEKICAgIHVuY292ZXIgMgogICAgYnwKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo1MQogICAgLy8gcmV0dXJuIGFVaW50TiAhPT0gYlVpbnROCiAgICAhPQogICAgcmV0c3ViCgoKLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjpBcmM0UHJpbWl0aXZlT3BzQ29udHJhY3QudmVyaWZ5X2JpZ3VpbnRuX3VpbnRuX25lKGE6IGJ5dGVzLCBiOiBieXRlcykgLT4gdWludDY0Ogp2ZXJpZnlfYmlndWludG5fdWludG5fbmU6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NTMtNTQKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBwdWJsaWMgdmVyaWZ5X2JpZ3VpbnRuX3VpbnRuX25lKGE6IGJ5dGVzLCBiOiBieXRlcyk6IGJvb2xlYW4gewogICAgcHJvdG8gMiAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NTcKICAgIC8vIGNvbnN0IGFVaW50TiA9IG5ldyBVaW50Tjw1MTI+KGFCaWd1aW50KQogICAgZnJhbWVfZGlnIC0yCiAgICBsZW4KICAgIGludGNfMiAvLyA2NAogICAgPD0KICAgIGFzc2VydCAvLyBvdmVyZmxvdwogICAgaW50Y18yIC8vIDY0CiAgICBiemVybwogICAgZnJhbWVfZGlnIC0yCiAgICBifAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjU4CiAgICAvLyBjb25zdCBiVWludE4gPSBuZXcgVWludE48NjQ+KGJCaWd1aW50KQogICAgZnJhbWVfZGlnIC0xCiAgICBsZW4KICAgIGludGNfMSAvLyA4CiAgICA8PQogICAgYXNzZXJ0IC8vIG92ZXJmbG93CiAgICBpbnRjXzEgLy8gOAogICAgYnplcm8KICAgIGZyYW1lX2RpZyAtMQogICAgYnwKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo1OQogICAgLy8gcmV0dXJuICFhVWludE4uYnl0ZXMuZXF1YWxzKGJVaW50Ti5ieXRlcykKICAgID09CiAgICAhCiAgICByZXRzdWIKCgovLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OkFyYzRQcmltaXRpdmVPcHNDb250cmFjdC52ZXJpZnlfdWludG5fYmlndWludG5fbmUoYTogYnl0ZXMsIGI6IGJ5dGVzKSAtPiB1aW50NjQ6CnZlcmlmeV91aW50bl9iaWd1aW50bl9uZToKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo2MS02MgogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIHB1YmxpYyB2ZXJpZnlfdWludG5fYmlndWludG5fbmUoYTogYnl0ZXMsIGI6IGJ5dGVzKTogYm9vbGVhbiB7CiAgICBwcm90byAyIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo2NQogICAgLy8gY29uc3QgYVVpbnROID0gbmV3IFVpbnROPDY0PihhQmlndWludCkKICAgIGZyYW1lX2RpZyAtMgogICAgbGVuCiAgICBpbnRjXzEgLy8gOAogICAgPD0KICAgIGFzc2VydCAvLyBvdmVyZmxvdwogICAgaW50Y18xIC8vIDgKICAgIGJ6ZXJvCiAgICBmcmFtZV9kaWcgLTIKICAgIGJ8CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NjYKICAgIC8vIGNvbnN0IGJVaW50TiA9IG5ldyBVaW50Tjw1MTI+KGJCaWd1aW50KQogICAgZnJhbWVfZGlnIC0xCiAgICBsZW4KICAgIGludGNfMiAvLyA2NAogICAgPD0KICAgIGFzc2VydCAvLyBvdmVyZmxvdwogICAgaW50Y18yIC8vIDY0CiAgICBiemVybwogICAgZnJhbWVfZGlnIC0xCiAgICBifAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjY3CiAgICAvLyByZXR1cm4gIWFVaW50Ti5ieXRlcy5lcXVhbHMoYlVpbnROLmJ5dGVzKQogICAgPT0KICAgICEKICAgIHJldHN1YgoKCi8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo6QXJjNFByaW1pdGl2ZU9wc0NvbnRyYWN0LnZlcmlmeV9iaWd1aW50bl9iaWd1aW50bl9uZShhOiBieXRlcywgYjogYnl0ZXMpIC0+IHVpbnQ2NDoKdmVyaWZ5X2JpZ3VpbnRuX2JpZ3VpbnRuX25lOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjY5LTcwCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gcHVibGljIHZlcmlmeV9iaWd1aW50bl9iaWd1aW50bl9uZShhOiBieXRlcywgYjogYnl0ZXMpOiBib29sZWFuIHsKICAgIHByb3RvIDIgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjczCiAgICAvLyBjb25zdCBhVWludE4gPSBuZXcgVWludE48NTEyPihhQmlndWludCkKICAgIGZyYW1lX2RpZyAtMgogICAgbGVuCiAgICBpbnRjXzIgLy8gNjQKICAgIDw9CiAgICBhc3NlcnQgLy8gb3ZlcmZsb3cKICAgIGludGNfMiAvLyA2NAogICAgYnplcm8KICAgIGZyYW1lX2RpZyAtMgogICAgZGlnIDEKICAgIGJ8CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NzQKICAgIC8vIGNvbnN0IGJVaW50TiA9IG5ldyBVaW50Tjw1MTI+KGJCaWd1aW50KQogICAgZnJhbWVfZGlnIC0xCiAgICBsZW4KICAgIGludGNfMiAvLyA2NAogICAgPD0KICAgIGFzc2VydCAvLyBvdmVyZmxvdwogICAgZnJhbWVfZGlnIC0xCiAgICB1bmNvdmVyIDIKICAgIGJ8CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NzUKICAgIC8vIHJldHVybiBhVWludE4gIT09IGJVaW50TgogICAgIT0KICAgIHJldHN1YgoKCi8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo6QXJjNFByaW1pdGl2ZU9wc0NvbnRyYWN0LnZlcmlmeV9ieXRlX2J5dGVfbmUoYTogYnl0ZXMsIGI6IGJ5dGVzKSAtPiB1aW50NjQ6CnZlcmlmeV9ieXRlX2J5dGVfbmU6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NzctNzgKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBwdWJsaWMgdmVyaWZ5X2J5dGVfYnl0ZV9uZShhOiBieXRlcywgYjogYnl0ZXMpOiBib29sZWFuIHsKICAgIHByb3RvIDIgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjgxCiAgICAvLyBjb25zdCBhQnl0ZSA9IG5ldyBCeXRlKGFCaWd1aW50KQogICAgZnJhbWVfZGlnIC0yCiAgICBsZW4KICAgIGludGNfMCAvLyAxCiAgICA8PQogICAgYXNzZXJ0IC8vIG92ZXJmbG93CiAgICBpbnRjXzAgLy8gMQogICAgYnplcm8KICAgIGZyYW1lX2RpZyAtMgogICAgZGlnIDEKICAgIGJ8CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6ODIKICAgIC8vIGNvbnN0IGJCeXRlID0gbmV3IEJ5dGUoYkJpZ3VpbnQpCiAgICBmcmFtZV9kaWcgLTEKICAgIGxlbgogICAgaW50Y18wIC8vIDEKICAgIDw9CiAgICBhc3NlcnQgLy8gb3ZlcmZsb3cKICAgIGZyYW1lX2RpZyAtMQogICAgdW5jb3ZlciAyCiAgICBifAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjgzCiAgICAvLyByZXR1cm4gYUJ5dGUgIT09IGJCeXRlCiAgICAhPQogICAgcmV0c3ViCgoKLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjpBcmM0UHJpbWl0aXZlT3BzQ29udHJhY3QudmVyaWZ5X3VpbnRuX3VpbnRuX2x0KGE6IGJ5dGVzLCBiOiBieXRlcykgLT4gdWludDY0Ogp2ZXJpZnlfdWludG5fdWludG5fbHQ6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6ODUtODYKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBwdWJsaWMgdmVyaWZ5X3VpbnRuX3VpbnRuX2x0KGE6IGJ5dGVzLCBiOiBieXRlcyk6IGJvb2xlYW4gewogICAgcHJvdG8gMiAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6ODkKICAgIC8vIGNvbnN0IGFVaW50TiA9IG5ldyBVaW50Tjw2ND4oYUJpZ3VpbnQpCiAgICBmcmFtZV9kaWcgLTIKICAgIGxlbgogICAgaW50Y18xIC8vIDgKICAgIDw9CiAgICBhc3NlcnQgLy8gb3ZlcmZsb3cKICAgIGludGNfMSAvLyA4CiAgICBiemVybwogICAgZnJhbWVfZGlnIC0yCiAgICBkaWcgMQogICAgYnwKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo5MAogICAgLy8gY29uc3QgYlVpbnROID0gbmV3IFVpbnROPDY0PihiQmlndWludCkKICAgIGZyYW1lX2RpZyAtMQogICAgbGVuCiAgICBpbnRjXzEgLy8gOAogICAgPD0KICAgIGFzc2VydCAvLyBvdmVyZmxvdwogICAgZnJhbWVfZGlnIC0xCiAgICB1bmNvdmVyIDIKICAgIGJ8CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OTEKICAgIC8vIHJldHVybiBhVWludE4ubmF0aXZlIDwgYlVpbnROLm5hdGl2ZQogICAgc3dhcAogICAgYnRvaQogICAgc3dhcAogICAgYnRvaQogICAgPAogICAgcmV0c3ViCgoKLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjpBcmM0UHJpbWl0aXZlT3BzQ29udHJhY3QudmVyaWZ5X2JpZ3VpbnRuX3VpbnRuX2x0KGE6IGJ5dGVzLCBiOiBieXRlcykgLT4gdWludDY0Ogp2ZXJpZnlfYmlndWludG5fdWludG5fbHQ6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OTMtOTQKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBwdWJsaWMgdmVyaWZ5X2JpZ3VpbnRuX3VpbnRuX2x0KGE6IGJ5dGVzLCBiOiBieXRlcyk6IGJvb2xlYW4gewogICAgcHJvdG8gMiAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OTcKICAgIC8vIGNvbnN0IGFVaW50TiA9IG5ldyBVaW50Tjw1MTI+KGFCaWd1aW50KQogICAgZnJhbWVfZGlnIC0yCiAgICBsZW4KICAgIGludGNfMiAvLyA2NAogICAgPD0KICAgIGFzc2VydCAvLyBvdmVyZmxvdwogICAgaW50Y18yIC8vIDY0CiAgICBiemVybwogICAgZnJhbWVfZGlnIC0yCiAgICBifAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjk4CiAgICAvLyBjb25zdCBiVWludE4gPSBuZXcgVWludE48NjQ+KGJCaWd1aW50KQogICAgZnJhbWVfZGlnIC0xCiAgICBsZW4KICAgIGludGNfMSAvLyA4CiAgICA8PQogICAgYXNzZXJ0IC8vIG92ZXJmbG93CiAgICBpbnRjXzEgLy8gOAogICAgYnplcm8KICAgIGZyYW1lX2RpZyAtMQogICAgYnwKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo5OQogICAgLy8gcmV0dXJuIGFVaW50Ti5uYXRpdmUgPCBCaWdVaW50KGJVaW50Ti5uYXRpdmUpCiAgICBidG9pCiAgICBpdG9iCiAgICBiPAogICAgcmV0c3ViCgoKLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjpBcmM0UHJpbWl0aXZlT3BzQ29udHJhY3QudmVyaWZ5X3VpbnRuX2JpZ3VpbnRuX2x0KGE6IGJ5dGVzLCBiOiBieXRlcykgLT4gdWludDY0Ogp2ZXJpZnlfdWludG5fYmlndWludG5fbHQ6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTAxLTEwMgogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIHB1YmxpYyB2ZXJpZnlfdWludG5fYmlndWludG5fbHQoYTogYnl0ZXMsIGI6IGJ5dGVzKTogYm9vbGVhbiB7CiAgICBwcm90byAyIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoxMDUKICAgIC8vIGNvbnN0IGFVaW50TiA9IG5ldyBVaW50Tjw2ND4oYUJpZ3VpbnQpCiAgICBmcmFtZV9kaWcgLTIKICAgIGxlbgogICAgaW50Y18xIC8vIDgKICAgIDw9CiAgICBhc3NlcnQgLy8gb3ZlcmZsb3cKICAgIGludGNfMSAvLyA4CiAgICBiemVybwogICAgZnJhbWVfZGlnIC0yCiAgICBifAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjEwNgogICAgLy8gY29uc3QgYlVpbnROID0gbmV3IFVpbnROPDUxMj4oYkJpZ3VpbnQpCiAgICBmcmFtZV9kaWcgLTEKICAgIGxlbgogICAgaW50Y18yIC8vIDY0CiAgICA8PQogICAgYXNzZXJ0IC8vIG92ZXJmbG93CiAgICBpbnRjXzIgLy8gNjQKICAgIGJ6ZXJvCiAgICBmcmFtZV9kaWcgLTEKICAgIGJ8CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTA3CiAgICAvLyByZXR1cm4gQmlnVWludChhVWludE4ubmF0aXZlKSA8IGJVaW50Ti5uYXRpdmUKICAgIHN3YXAKICAgIGJ0b2kKICAgIGl0b2IKICAgIGI+CiAgICByZXRzdWIKCgovLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OkFyYzRQcmltaXRpdmVPcHNDb250cmFjdC52ZXJpZnlfYmlndWludG5fYmlndWludG5fbHQoYTogYnl0ZXMsIGI6IGJ5dGVzKSAtPiB1aW50NjQ6CnZlcmlmeV9iaWd1aW50bl9iaWd1aW50bl9sdDoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoxMDktMTEwCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gcHVibGljIHZlcmlmeV9iaWd1aW50bl9iaWd1aW50bl9sdChhOiBieXRlcywgYjogYnl0ZXMpOiBib29sZWFuIHsKICAgIHByb3RvIDIgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjExMwogICAgLy8gY29uc3QgYVVpbnROID0gbmV3IFVpbnROPDUxMj4oYUJpZ3VpbnQpCiAgICBmcmFtZV9kaWcgLTIKICAgIGxlbgogICAgaW50Y18yIC8vIDY0CiAgICA8PQogICAgYXNzZXJ0IC8vIG92ZXJmbG93CiAgICBpbnRjXzIgLy8gNjQKICAgIGJ6ZXJvCiAgICBmcmFtZV9kaWcgLTIKICAgIGRpZyAxCiAgICBifAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjExNAogICAgLy8gY29uc3QgYlVpbnROID0gbmV3IFVpbnROPDUxMj4oYkJpZ3VpbnQpCiAgICBmcmFtZV9kaWcgLTEKICAgIGxlbgogICAgaW50Y18yIC8vIDY0CiAgICA8PQogICAgYXNzZXJ0IC8vIG92ZXJmbG93CiAgICBmcmFtZV9kaWcgLTEKICAgIHVuY292ZXIgMgogICAgYnwKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoxMTUKICAgIC8vIHJldHVybiBhVWludE4ubmF0aXZlIDwgYlVpbnROLm5hdGl2ZQogICAgYjwKICAgIHJldHN1YgoKCi8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo6QXJjNFByaW1pdGl2ZU9wc0NvbnRyYWN0LnZlcmlmeV9ieXRlX2J5dGVfbHQoYTogYnl0ZXMsIGI6IGJ5dGVzKSAtPiB1aW50NjQ6CnZlcmlmeV9ieXRlX2J5dGVfbHQ6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTE3LTExOAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIHB1YmxpYyB2ZXJpZnlfYnl0ZV9ieXRlX2x0KGE6IGJ5dGVzLCBiOiBieXRlcyk6IGJvb2xlYW4gewogICAgcHJvdG8gMiAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTIxCiAgICAvLyBjb25zdCBhQnl0ZSA9IG5ldyBCeXRlKGFCaWd1aW50KQogICAgZnJhbWVfZGlnIC0yCiAgICBsZW4KICAgIGludGNfMCAvLyAxCiAgICA8PQogICAgYXNzZXJ0IC8vIG92ZXJmbG93CiAgICBpbnRjXzAgLy8gMQogICAgYnplcm8KICAgIGZyYW1lX2RpZyAtMgogICAgZGlnIDEKICAgIGJ8CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTIyCiAgICAvLyBjb25zdCBiQnl0ZSA9IG5ldyBCeXRlKGJCaWd1aW50KQogICAgZnJhbWVfZGlnIC0xCiAgICBsZW4KICAgIGludGNfMCAvLyAxCiAgICA8PQogICAgYXNzZXJ0IC8vIG92ZXJmbG93CiAgICBmcmFtZV9kaWcgLTEKICAgIHVuY292ZXIgMgogICAgYnwKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoxMjMKICAgIC8vIHJldHVybiBhQnl0ZS5uYXRpdmUgPCBiQnl0ZS5uYXRpdmUKICAgIHN3YXAKICAgIGJ0b2kKICAgIHN3YXAKICAgIGJ0b2kKICAgIDwKICAgIHJldHN1YgoKCi8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo6QXJjNFByaW1pdGl2ZU9wc0NvbnRyYWN0LnZlcmlmeV91aW50bl91aW50bl9sZShhOiBieXRlcywgYjogYnl0ZXMpIC0+IHVpbnQ2NDoKdmVyaWZ5X3VpbnRuX3VpbnRuX2xlOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjEyNS0xMjYKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBwdWJsaWMgdmVyaWZ5X3VpbnRuX3VpbnRuX2xlKGE6IGJ5dGVzLCBiOiBieXRlcyk6IGJvb2xlYW4gewogICAgcHJvdG8gMiAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTI5CiAgICAvLyBjb25zdCBhVWludE4gPSBuZXcgVWludE48NjQ+KGFCaWd1aW50KQogICAgZnJhbWVfZGlnIC0yCiAgICBsZW4KICAgIGludGNfMSAvLyA4CiAgICA8PQogICAgYXNzZXJ0IC8vIG92ZXJmbG93CiAgICBpbnRjXzEgLy8gOAogICAgYnplcm8KICAgIGZyYW1lX2RpZyAtMgogICAgZGlnIDEKICAgIGJ8CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTMwCiAgICAvLyBjb25zdCBiVWludE4gPSBuZXcgVWludE48NjQ+KGJCaWd1aW50KQogICAgZnJhbWVfZGlnIC0xCiAgICBsZW4KICAgIGludGNfMSAvLyA4CiAgICA8PQogICAgYXNzZXJ0IC8vIG92ZXJmbG93CiAgICBmcmFtZV9kaWcgLTEKICAgIHVuY292ZXIgMgogICAgYnwKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoxMzEKICAgIC8vIHJldHVybiBhVWludE4ubmF0aXZlIDw9IGJVaW50Ti5uYXRpdmUKICAgIHN3YXAKICAgIGJ0b2kKICAgIHN3YXAKICAgIGJ0b2kKICAgIDw9CiAgICByZXRzdWIKCgovLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OkFyYzRQcmltaXRpdmVPcHNDb250cmFjdC52ZXJpZnlfYmlndWludG5fdWludG5fbGUoYTogYnl0ZXMsIGI6IGJ5dGVzKSAtPiB1aW50NjQ6CnZlcmlmeV9iaWd1aW50bl91aW50bl9sZToKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoxMzMtMTM0CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gcHVibGljIHZlcmlmeV9iaWd1aW50bl91aW50bl9sZShhOiBieXRlcywgYjogYnl0ZXMpOiBib29sZWFuIHsKICAgIHByb3RvIDIgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjEzNwogICAgLy8gY29uc3QgYVVpbnROID0gbmV3IFVpbnROPDUxMj4oYUJpZ3VpbnQpCiAgICBmcmFtZV9kaWcgLTIKICAgIGxlbgogICAgaW50Y18yIC8vIDY0CiAgICA8PQogICAgYXNzZXJ0IC8vIG92ZXJmbG93CiAgICBpbnRjXzIgLy8gNjQKICAgIGJ6ZXJvCiAgICBmcmFtZV9kaWcgLTIKICAgIGJ8CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTM4CiAgICAvLyBjb25zdCBiVWludE4gPSBuZXcgVWludE48NjQ+KGJCaWd1aW50KQogICAgZnJhbWVfZGlnIC0xCiAgICBsZW4KICAgIGludGNfMSAvLyA4CiAgICA8PQogICAgYXNzZXJ0IC8vIG92ZXJmbG93CiAgICBpbnRjXzEgLy8gOAogICAgYnplcm8KICAgIGZyYW1lX2RpZyAtMQogICAgYnwKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoxMzkKICAgIC8vIHJldHVybiBhVWludE4ubmF0aXZlIDw9IEJpZ1VpbnQoYlVpbnROLm5hdGl2ZSkKICAgIGJ0b2kKICAgIGl0b2IKICAgIGI8PQogICAgcmV0c3ViCgoKLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjpBcmM0UHJpbWl0aXZlT3BzQ29udHJhY3QudmVyaWZ5X3VpbnRuX2JpZ3VpbnRuX2xlKGE6IGJ5dGVzLCBiOiBieXRlcykgLT4gdWludDY0Ogp2ZXJpZnlfdWludG5fYmlndWludG5fbGU6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTQxLTE0MgogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIHB1YmxpYyB2ZXJpZnlfdWludG5fYmlndWludG5fbGUoYTogYnl0ZXMsIGI6IGJ5dGVzKTogYm9vbGVhbiB7CiAgICBwcm90byAyIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoxNDUKICAgIC8vIGNvbnN0IGFVaW50TiA9IG5ldyBVaW50Tjw2ND4oYUJpZ3VpbnQpCiAgICBmcmFtZV9kaWcgLTIKICAgIGxlbgogICAgaW50Y18xIC8vIDgKICAgIDw9CiAgICBhc3NlcnQgLy8gb3ZlcmZsb3cKICAgIGludGNfMSAvLyA4CiAgICBiemVybwogICAgZnJhbWVfZGlnIC0yCiAgICBifAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjE0NgogICAgLy8gY29uc3QgYlVpbnROID0gbmV3IFVpbnROPDUxMj4oYkJpZ3VpbnQpCiAgICBmcmFtZV9kaWcgLTEKICAgIGxlbgogICAgaW50Y18yIC8vIDY0CiAgICA8PQogICAgYXNzZXJ0IC8vIG92ZXJmbG93CiAgICBpbnRjXzIgLy8gNjQKICAgIGJ6ZXJvCiAgICBmcmFtZV9kaWcgLTEKICAgIGJ8CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTQ3CiAgICAvLyByZXR1cm4gQmlnVWludChhVWludE4ubmF0aXZlKSA8PSBiVWludE4ubmF0aXZlCiAgICBzd2FwCiAgICBidG9pCiAgICBpdG9iCiAgICBiPj0KICAgIHJldHN1YgoKCi8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo6QXJjNFByaW1pdGl2ZU9wc0NvbnRyYWN0LnZlcmlmeV9iaWd1aW50bl9iaWd1aW50bl9sZShhOiBieXRlcywgYjogYnl0ZXMpIC0+IHVpbnQ2NDoKdmVyaWZ5X2JpZ3VpbnRuX2JpZ3VpbnRuX2xlOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjE0OS0xNTAKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBwdWJsaWMgdmVyaWZ5X2JpZ3VpbnRuX2JpZ3VpbnRuX2xlKGE6IGJ5dGVzLCBiOiBieXRlcyk6IGJvb2xlYW4gewogICAgcHJvdG8gMiAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTUzCiAgICAvLyBjb25zdCBhVWludE4gPSBuZXcgVWludE48NTEyPihhQmlndWludCkKICAgIGZyYW1lX2RpZyAtMgogICAgbGVuCiAgICBpbnRjXzIgLy8gNjQKICAgIDw9CiAgICBhc3NlcnQgLy8gb3ZlcmZsb3cKICAgIGludGNfMiAvLyA2NAogICAgYnplcm8KICAgIGZyYW1lX2RpZyAtMgogICAgZGlnIDEKICAgIGJ8CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTU0CiAgICAvLyBjb25zdCBiVWludE4gPSBuZXcgVWludE48NTEyPihiQmlndWludCkKICAgIGZyYW1lX2RpZyAtMQogICAgbGVuCiAgICBpbnRjXzIgLy8gNjQKICAgIDw9CiAgICBhc3NlcnQgLy8gb3ZlcmZsb3cKICAgIGZyYW1lX2RpZyAtMQogICAgdW5jb3ZlciAyCiAgICBifAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjE1NQogICAgLy8gcmV0dXJuIGFVaW50Ti5uYXRpdmUgPD0gYlVpbnROLm5hdGl2ZQogICAgYjw9CiAgICByZXRzdWIKCgovLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OkFyYzRQcmltaXRpdmVPcHNDb250cmFjdC52ZXJpZnlfYnl0ZV9ieXRlX2xlKGE6IGJ5dGVzLCBiOiBieXRlcykgLT4gdWludDY0Ogp2ZXJpZnlfYnl0ZV9ieXRlX2xlOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjE1Ny0xNTgKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBwdWJsaWMgdmVyaWZ5X2J5dGVfYnl0ZV9sZShhOiBieXRlcywgYjogYnl0ZXMpOiBib29sZWFuIHsKICAgIHByb3RvIDIgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjE2MQogICAgLy8gY29uc3QgYUJ5dGUgPSBuZXcgQnl0ZShhQmlndWludCkKICAgIGZyYW1lX2RpZyAtMgogICAgbGVuCiAgICBpbnRjXzAgLy8gMQogICAgPD0KICAgIGFzc2VydCAvLyBvdmVyZmxvdwogICAgaW50Y18wIC8vIDEKICAgIGJ6ZXJvCiAgICBmcmFtZV9kaWcgLTIKICAgIGRpZyAxCiAgICBifAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjE2MgogICAgLy8gY29uc3QgYkJ5dGUgPSBuZXcgQnl0ZShiQmlndWludCkKICAgIGZyYW1lX2RpZyAtMQogICAgbGVuCiAgICBpbnRjXzAgLy8gMQogICAgPD0KICAgIGFzc2VydCAvLyBvdmVyZmxvdwogICAgZnJhbWVfZGlnIC0xCiAgICB1bmNvdmVyIDIKICAgIGJ8CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTYzCiAgICAvLyByZXR1cm4gYUJ5dGUubmF0aXZlIDw9IGJCeXRlLm5hdGl2ZQogICAgc3dhcAogICAgYnRvaQogICAgc3dhcAogICAgYnRvaQogICAgPD0KICAgIHJldHN1YgoKCi8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo6QXJjNFByaW1pdGl2ZU9wc0NvbnRyYWN0LnZlcmlmeV91aW50bl91aW50bl9ndChhOiBieXRlcywgYjogYnl0ZXMpIC0+IHVpbnQ2NDoKdmVyaWZ5X3VpbnRuX3VpbnRuX2d0OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjE2NS0xNjYKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBwdWJsaWMgdmVyaWZ5X3VpbnRuX3VpbnRuX2d0KGE6IGJ5dGVzLCBiOiBieXRlcyk6IGJvb2xlYW4gewogICAgcHJvdG8gMiAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTY5CiAgICAvLyBjb25zdCBhVWludE4gPSBuZXcgVWludE48NjQ+KGFCaWd1aW50KQogICAgZnJhbWVfZGlnIC0yCiAgICBsZW4KICAgIGludGNfMSAvLyA4CiAgICA8PQogICAgYXNzZXJ0IC8vIG92ZXJmbG93CiAgICBpbnRjXzEgLy8gOAogICAgYnplcm8KICAgIGZyYW1lX2RpZyAtMgogICAgZGlnIDEKICAgIGJ8CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTcwCiAgICAvLyBjb25zdCBiVWludE4gPSBuZXcgVWludE48NjQ+KGJCaWd1aW50KQogICAgZnJhbWVfZGlnIC0xCiAgICBsZW4KICAgIGludGNfMSAvLyA4CiAgICA8PQogICAgYXNzZXJ0IC8vIG92ZXJmbG93CiAgICBmcmFtZV9kaWcgLTEKICAgIHVuY292ZXIgMgogICAgYnwKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoxNzEKICAgIC8vIHJldHVybiBhVWludE4ubmF0aXZlID4gYlVpbnROLm5hdGl2ZQogICAgc3dhcAogICAgYnRvaQogICAgc3dhcAogICAgYnRvaQogICAgPgogICAgcmV0c3ViCgoKLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjpBcmM0UHJpbWl0aXZlT3BzQ29udHJhY3QudmVyaWZ5X2JpZ3VpbnRuX3VpbnRuX2d0KGE6IGJ5dGVzLCBiOiBieXRlcykgLT4gdWludDY0Ogp2ZXJpZnlfYmlndWludG5fdWludG5fZ3Q6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTczLTE3NAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIHB1YmxpYyB2ZXJpZnlfYmlndWludG5fdWludG5fZ3QoYTogYnl0ZXMsIGI6IGJ5dGVzKTogYm9vbGVhbiB7CiAgICBwcm90byAyIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoxNzcKICAgIC8vIGNvbnN0IGFVaW50TiA9IG5ldyBVaW50Tjw1MTI+KGFCaWd1aW50KQogICAgZnJhbWVfZGlnIC0yCiAgICBsZW4KICAgIGludGNfMiAvLyA2NAogICAgPD0KICAgIGFzc2VydCAvLyBvdmVyZmxvdwogICAgaW50Y18yIC8vIDY0CiAgICBiemVybwogICAgZnJhbWVfZGlnIC0yCiAgICBifAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjE3OAogICAgLy8gY29uc3QgYlVpbnROID0gbmV3IFVpbnROPDY0PihiQmlndWludCkKICAgIGZyYW1lX2RpZyAtMQogICAgbGVuCiAgICBpbnRjXzEgLy8gOAogICAgPD0KICAgIGFzc2VydCAvLyBvdmVyZmxvdwogICAgaW50Y18xIC8vIDgKICAgIGJ6ZXJvCiAgICBmcmFtZV9kaWcgLTEKICAgIGJ8CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTc5CiAgICAvLyByZXR1cm4gYVVpbnROLm5hdGl2ZSA+IEJpZ1VpbnQoYlVpbnROLm5hdGl2ZSkKICAgIGJ0b2kKICAgIGl0b2IKICAgIGI+CiAgICByZXRzdWIKCgovLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OkFyYzRQcmltaXRpdmVPcHNDb250cmFjdC52ZXJpZnlfdWludG5fYmlndWludG5fZ3QoYTogYnl0ZXMsIGI6IGJ5dGVzKSAtPiB1aW50NjQ6CnZlcmlmeV91aW50bl9iaWd1aW50bl9ndDoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoxODEtMTgyCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gcHVibGljIHZlcmlmeV91aW50bl9iaWd1aW50bl9ndChhOiBieXRlcywgYjogYnl0ZXMpOiBib29sZWFuIHsKICAgIHByb3RvIDIgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjE4NQogICAgLy8gY29uc3QgYVVpbnROID0gbmV3IFVpbnROPDY0PihhQmlndWludCkKICAgIGZyYW1lX2RpZyAtMgogICAgbGVuCiAgICBpbnRjXzEgLy8gOAogICAgPD0KICAgIGFzc2VydCAvLyBvdmVyZmxvdwogICAgaW50Y18xIC8vIDgKICAgIGJ6ZXJvCiAgICBmcmFtZV9kaWcgLTIKICAgIGJ8CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTg2CiAgICAvLyBjb25zdCBiVWludE4gPSBuZXcgVWludE48NTEyPihiQmlndWludCkKICAgIGZyYW1lX2RpZyAtMQogICAgbGVuCiAgICBpbnRjXzIgLy8gNjQKICAgIDw9CiAgICBhc3NlcnQgLy8gb3ZlcmZsb3cKICAgIGludGNfMiAvLyA2NAogICAgYnplcm8KICAgIGZyYW1lX2RpZyAtMQogICAgYnwKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoxODcKICAgIC8vIHJldHVybiBCaWdVaW50KGFVaW50Ti5uYXRpdmUpID4gYlVpbnROLm5hdGl2ZQogICAgc3dhcAogICAgYnRvaQogICAgaXRvYgogICAgYjwKICAgIHJldHN1YgoKCi8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo6QXJjNFByaW1pdGl2ZU9wc0NvbnRyYWN0LnZlcmlmeV9iaWd1aW50bl9iaWd1aW50bl9ndChhOiBieXRlcywgYjogYnl0ZXMpIC0+IHVpbnQ2NDoKdmVyaWZ5X2JpZ3VpbnRuX2JpZ3VpbnRuX2d0OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjE4OS0xOTAKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBwdWJsaWMgdmVyaWZ5X2JpZ3VpbnRuX2JpZ3VpbnRuX2d0KGE6IGJ5dGVzLCBiOiBieXRlcyk6IGJvb2xlYW4gewogICAgcHJvdG8gMiAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTkzCiAgICAvLyBjb25zdCBhVWludE4gPSBuZXcgVWludE48NTEyPihhQmlndWludCkKICAgIGZyYW1lX2RpZyAtMgogICAgbGVuCiAgICBpbnRjXzIgLy8gNjQKICAgIDw9CiAgICBhc3NlcnQgLy8gb3ZlcmZsb3cKICAgIGludGNfMiAvLyA2NAogICAgYnplcm8KICAgIGZyYW1lX2RpZyAtMgogICAgZGlnIDEKICAgIGJ8CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTk0CiAgICAvLyBjb25zdCBiVWludE4gPSBuZXcgVWludE48NTEyPihiQmlndWludCkKICAgIGZyYW1lX2RpZyAtMQogICAgbGVuCiAgICBpbnRjXzIgLy8gNjQKICAgIDw9CiAgICBhc3NlcnQgLy8gb3ZlcmZsb3cKICAgIGZyYW1lX2RpZyAtMQogICAgdW5jb3ZlciAyCiAgICBifAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjE5NQogICAgLy8gcmV0dXJuIGFVaW50Ti5uYXRpdmUgPiBiVWludE4ubmF0aXZlCiAgICBiPgogICAgcmV0c3ViCgoKLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjpBcmM0UHJpbWl0aXZlT3BzQ29udHJhY3QudmVyaWZ5X2J5dGVfYnl0ZV9ndChhOiBieXRlcywgYjogYnl0ZXMpIC0+IHVpbnQ2NDoKdmVyaWZ5X2J5dGVfYnl0ZV9ndDoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoxOTctMTk4CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gcHVibGljIHZlcmlmeV9ieXRlX2J5dGVfZ3QoYTogYnl0ZXMsIGI6IGJ5dGVzKTogYm9vbGVhbiB7CiAgICBwcm90byAyIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoyMDEKICAgIC8vIGNvbnN0IGFCeXRlID0gbmV3IEJ5dGUoYUJpZ3VpbnQpCiAgICBmcmFtZV9kaWcgLTIKICAgIGxlbgogICAgaW50Y18wIC8vIDEKICAgIDw9CiAgICBhc3NlcnQgLy8gb3ZlcmZsb3cKICAgIGludGNfMCAvLyAxCiAgICBiemVybwogICAgZnJhbWVfZGlnIC0yCiAgICBkaWcgMQogICAgYnwKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoyMDIKICAgIC8vIGNvbnN0IGJCeXRlID0gbmV3IEJ5dGUoYkJpZ3VpbnQpCiAgICBmcmFtZV9kaWcgLTEKICAgIGxlbgogICAgaW50Y18wIC8vIDEKICAgIDw9CiAgICBhc3NlcnQgLy8gb3ZlcmZsb3cKICAgIGZyYW1lX2RpZyAtMQogICAgdW5jb3ZlciAyCiAgICBifAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjIwMwogICAgLy8gcmV0dXJuIGFCeXRlLm5hdGl2ZSA+IGJCeXRlLm5hdGl2ZQogICAgc3dhcAogICAgYnRvaQogICAgc3dhcAogICAgYnRvaQogICAgPgogICAgcmV0c3ViCgoKLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjpBcmM0UHJpbWl0aXZlT3BzQ29udHJhY3QudmVyaWZ5X3VpbnRuX3VpbnRuX2dlKGE6IGJ5dGVzLCBiOiBieXRlcykgLT4gdWludDY0Ogp2ZXJpZnlfdWludG5fdWludG5fZ2U6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MjA1LTIwNgogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIHB1YmxpYyB2ZXJpZnlfdWludG5fdWludG5fZ2UoYTogYnl0ZXMsIGI6IGJ5dGVzKTogYm9vbGVhbiB7CiAgICBwcm90byAyIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoyMDkKICAgIC8vIGNvbnN0IGFVaW50TiA9IG5ldyBVaW50Tjw2ND4oYUJpZ3VpbnQpCiAgICBmcmFtZV9kaWcgLTIKICAgIGxlbgogICAgaW50Y18xIC8vIDgKICAgIDw9CiAgICBhc3NlcnQgLy8gb3ZlcmZsb3cKICAgIGludGNfMSAvLyA4CiAgICBiemVybwogICAgZnJhbWVfZGlnIC0yCiAgICBkaWcgMQogICAgYnwKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoyMTAKICAgIC8vIGNvbnN0IGJVaW50TiA9IG5ldyBVaW50Tjw2ND4oYkJpZ3VpbnQpCiAgICBmcmFtZV9kaWcgLTEKICAgIGxlbgogICAgaW50Y18xIC8vIDgKICAgIDw9CiAgICBhc3NlcnQgLy8gb3ZlcmZsb3cKICAgIGZyYW1lX2RpZyAtMQogICAgdW5jb3ZlciAyCiAgICBifAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjIxMQogICAgLy8gcmV0dXJuIGFVaW50Ti5uYXRpdmUgPj0gYlVpbnROLm5hdGl2ZQogICAgc3dhcAogICAgYnRvaQogICAgc3dhcAogICAgYnRvaQogICAgPj0KICAgIHJldHN1YgoKCi8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo6QXJjNFByaW1pdGl2ZU9wc0NvbnRyYWN0LnZlcmlmeV9iaWd1aW50bl91aW50bl9nZShhOiBieXRlcywgYjogYnl0ZXMpIC0+IHVpbnQ2NDoKdmVyaWZ5X2JpZ3VpbnRuX3VpbnRuX2dlOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjIxMy0yMTQKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBwdWJsaWMgdmVyaWZ5X2JpZ3VpbnRuX3VpbnRuX2dlKGE6IGJ5dGVzLCBiOiBieXRlcyk6IGJvb2xlYW4gewogICAgcHJvdG8gMiAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MjE3CiAgICAvLyBjb25zdCBhVWludE4gPSBuZXcgVWludE48NTEyPihhQmlndWludCkKICAgIGZyYW1lX2RpZyAtMgogICAgbGVuCiAgICBpbnRjXzIgLy8gNjQKICAgIDw9CiAgICBhc3NlcnQgLy8gb3ZlcmZsb3cKICAgIGludGNfMiAvLyA2NAogICAgYnplcm8KICAgIGZyYW1lX2RpZyAtMgogICAgYnwKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoyMTgKICAgIC8vIGNvbnN0IGJVaW50TiA9IG5ldyBVaW50Tjw2ND4oYkJpZ3VpbnQpCiAgICBmcmFtZV9kaWcgLTEKICAgIGxlbgogICAgaW50Y18xIC8vIDgKICAgIDw9CiAgICBhc3NlcnQgLy8gb3ZlcmZsb3cKICAgIGludGNfMSAvLyA4CiAgICBiemVybwogICAgZnJhbWVfZGlnIC0xCiAgICBifAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjIxOQogICAgLy8gcmV0dXJuIGFVaW50Ti5uYXRpdmUgPj0gQmlnVWludChiVWludE4ubmF0aXZlKQogICAgYnRvaQogICAgaXRvYgogICAgYj49CiAgICByZXRzdWIKCgovLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OkFyYzRQcmltaXRpdmVPcHNDb250cmFjdC52ZXJpZnlfdWludG5fYmlndWludG5fZ2UoYTogYnl0ZXMsIGI6IGJ5dGVzKSAtPiB1aW50NjQ6CnZlcmlmeV91aW50bl9iaWd1aW50bl9nZToKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoyMjEtMjIyCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gcHVibGljIHZlcmlmeV91aW50bl9iaWd1aW50bl9nZShhOiBieXRlcywgYjogYnl0ZXMpOiBib29sZWFuIHsKICAgIHByb3RvIDIgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjIyNQogICAgLy8gY29uc3QgYVVpbnROID0gbmV3IFVpbnROPDY0PihhQmlndWludCkKICAgIGZyYW1lX2RpZyAtMgogICAgbGVuCiAgICBpbnRjXzEgLy8gOAogICAgPD0KICAgIGFzc2VydCAvLyBvdmVyZmxvdwogICAgaW50Y18xIC8vIDgKICAgIGJ6ZXJvCiAgICBmcmFtZV9kaWcgLTIKICAgIGJ8CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MjI2CiAgICAvLyBjb25zdCBiVWludE4gPSBuZXcgVWludE48NTEyPihiQmlndWludCkKICAgIGZyYW1lX2RpZyAtMQogICAgbGVuCiAgICBpbnRjXzIgLy8gNjQKICAgIDw9CiAgICBhc3NlcnQgLy8gb3ZlcmZsb3cKICAgIGludGNfMiAvLyA2NAogICAgYnplcm8KICAgIGZyYW1lX2RpZyAtMQogICAgYnwKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoyMjcKICAgIC8vIHJldHVybiBCaWdVaW50KGFVaW50Ti5uYXRpdmUpID49IGJVaW50Ti5uYXRpdmUKICAgIHN3YXAKICAgIGJ0b2kKICAgIGl0b2IKICAgIGI8PQogICAgcmV0c3ViCgoKLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjpBcmM0UHJpbWl0aXZlT3BzQ29udHJhY3QudmVyaWZ5X2JpZ3VpbnRuX2JpZ3VpbnRuX2dlKGE6IGJ5dGVzLCBiOiBieXRlcykgLT4gdWludDY0Ogp2ZXJpZnlfYmlndWludG5fYmlndWludG5fZ2U6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MjI5LTIzMAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIHB1YmxpYyB2ZXJpZnlfYmlndWludG5fYmlndWludG5fZ2UoYTogYnl0ZXMsIGI6IGJ5dGVzKTogYm9vbGVhbiB7CiAgICBwcm90byAyIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoyMzMKICAgIC8vIGNvbnN0IGFVaW50TiA9IG5ldyBVaW50Tjw1MTI+KGFCaWd1aW50KQogICAgZnJhbWVfZGlnIC0yCiAgICBsZW4KICAgIGludGNfMiAvLyA2NAogICAgPD0KICAgIGFzc2VydCAvLyBvdmVyZmxvdwogICAgaW50Y18yIC8vIDY0CiAgICBiemVybwogICAgZnJhbWVfZGlnIC0yCiAgICBkaWcgMQogICAgYnwKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoyMzQKICAgIC8vIGNvbnN0IGJVaW50TiA9IG5ldyBVaW50Tjw1MTI+KGJCaWd1aW50KQogICAgZnJhbWVfZGlnIC0xCiAgICBsZW4KICAgIGludGNfMiAvLyA2NAogICAgPD0KICAgIGFzc2VydCAvLyBvdmVyZmxvdwogICAgZnJhbWVfZGlnIC0xCiAgICB1bmNvdmVyIDIKICAgIGJ8CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MjM1CiAgICAvLyByZXR1cm4gYVVpbnROLm5hdGl2ZSA+PSBiVWludE4ubmF0aXZlCiAgICBiPj0KICAgIHJldHN1YgoKCi8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo6QXJjNFByaW1pdGl2ZU9wc0NvbnRyYWN0LnZlcmlmeV9ieXRlX2J5dGVfZ2UoYTogYnl0ZXMsIGI6IGJ5dGVzKSAtPiB1aW50NjQ6CnZlcmlmeV9ieXRlX2J5dGVfZ2U6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MjM3LTIzOAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIHB1YmxpYyB2ZXJpZnlfYnl0ZV9ieXRlX2dlKGE6IGJ5dGVzLCBiOiBieXRlcyk6IGJvb2xlYW4gewogICAgcHJvdG8gMiAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MjQxCiAgICAvLyBjb25zdCBhQnl0ZSA9IG5ldyBCeXRlKGFCaWd1aW50KQogICAgZnJhbWVfZGlnIC0yCiAgICBsZW4KICAgIGludGNfMCAvLyAxCiAgICA8PQogICAgYXNzZXJ0IC8vIG92ZXJmbG93CiAgICBpbnRjXzAgLy8gMQogICAgYnplcm8KICAgIGZyYW1lX2RpZyAtMgogICAgZGlnIDEKICAgIGJ8CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MjQyCiAgICAvLyBjb25zdCBiQnl0ZSA9IG5ldyBCeXRlKGJCaWd1aW50KQogICAgZnJhbWVfZGlnIC0xCiAgICBsZW4KICAgIGludGNfMCAvLyAxCiAgICA8PQogICAgYXNzZXJ0IC8vIG92ZXJmbG93CiAgICBmcmFtZV9kaWcgLTEKICAgIHVuY292ZXIgMgogICAgYnwKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoyNDMKICAgIC8vIHJldHVybiBhQnl0ZS5uYXRpdmUgPj0gYkJ5dGUubmF0aXZlCiAgICBzd2FwCiAgICBidG9pCiAgICBzd2FwCiAgICBidG9pCiAgICA+PQogICAgcmV0c3ViCgoKLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjpBcmM0UHJpbWl0aXZlT3BzQ29udHJhY3QudmVyaWZ5X3VpbnRuX2luaXQoYTogYnl0ZXMpIC0+IGJ5dGVzOgp2ZXJpZnlfdWludG5faW5pdDoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoyNDUtMjQ2CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gcHVibGljIHZlcmlmeV91aW50bl9pbml0KGE6IGJ5dGVzKTogVWludE48MzI+IHsKICAgIHByb3RvIDEgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjI0OAogICAgLy8gcmV0dXJuIG5ldyBVaW50TjwzMj4oYUJpZ3VpbnQpCiAgICBmcmFtZV9kaWcgLTEKICAgIGxlbgogICAgcHVzaGludCA0IC8vIDQKICAgIDw9CiAgICBhc3NlcnQgLy8gb3ZlcmZsb3cKICAgIHB1c2hpbnQgNCAvLyA0CiAgICBiemVybwogICAgZnJhbWVfZGlnIC0xCiAgICBifAogICAgcmV0c3ViCgoKLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjpBcmM0UHJpbWl0aXZlT3BzQ29udHJhY3QudmVyaWZ5X2JpZ3VpbnRuX2luaXQoYTogYnl0ZXMpIC0+IGJ5dGVzOgp2ZXJpZnlfYmlndWludG5faW5pdDoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoyNTAtMjUxCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gcHVibGljIHZlcmlmeV9iaWd1aW50bl9pbml0KGE6IGJ5dGVzKTogVWludE48MjU2PiB7CiAgICBwcm90byAxIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoyNTMKICAgIC8vIHJldHVybiBuZXcgVWludE48MjU2PihhQmlndWludCkKICAgIGZyYW1lX2RpZyAtMQogICAgbGVuCiAgICBwdXNoaW50IDMyIC8vIDMyCiAgICA8PQogICAgYXNzZXJ0IC8vIG92ZXJmbG93CiAgICBwdXNoaW50IDMyIC8vIDMyCiAgICBiemVybwogICAgZnJhbWVfZGlnIC0xCiAgICBifAogICAgcmV0c3ViCgoKLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjpBcmM0UHJpbWl0aXZlT3BzQ29udHJhY3QudmVyaWZ5X2J5dGVfaW5pdChhOiBieXRlcykgLT4gYnl0ZXM6CnZlcmlmeV9ieXRlX2luaXQ6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MjU1LTI1NgogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIHB1YmxpYyB2ZXJpZnlfYnl0ZV9pbml0KGE6IGJ5dGVzKTogQnl0ZSB7CiAgICBwcm90byAxIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoyNTgKICAgIC8vIHJldHVybiBuZXcgQnl0ZShhQmlndWludCkKICAgIGZyYW1lX2RpZyAtMQogICAgbGVuCiAgICBpbnRjXzAgLy8gMQogICAgPD0KICAgIGFzc2VydCAvLyBvdmVyZmxvdwogICAgaW50Y18wIC8vIDEKICAgIGJ6ZXJvCiAgICBmcmFtZV9kaWcgLTEKICAgIGJ8CiAgICByZXRzdWIKCgovLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OkFyYzRQcmltaXRpdmVPcHNDb250cmFjdC52ZXJpZnlfdWludG5fZnJvbV9sb2coYTogYnl0ZXMpIC0+IGJ5dGVzOgp2ZXJpZnlfdWludG5fZnJvbV9sb2c6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MjcyLTI3MwogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIHB1YmxpYyB2ZXJpZnlfdWludG5fZnJvbV9sb2coYTogYnl0ZXMpOiBVaW50TjwzMj4gewogICAgcHJvdG8gMSAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6Mjc0CiAgICAvLyByZXR1cm4gaW50ZXJwcmV0QXNBcmM0PFVpbnROPDMyPj4oYSwgJ2xvZycpCiAgICBmcmFtZV9kaWcgLTEKICAgIGV4dHJhY3QgNCAwCiAgICBmcmFtZV9kaWcgLTEKICAgIGV4dHJhY3QgMCA0CiAgICBieXRlY18wIC8vIDB4MTUxZjdjNzUKICAgID09CiAgICBhc3NlcnQgLy8gQnl0ZXMgaGFzIHZhbGlkIHByZWZpeAogICAgcmV0c3ViCgoKLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjpBcmM0UHJpbWl0aXZlT3BzQ29udHJhY3QudmVyaWZ5X2JpZ3VpbnRuX2Zyb21fbG9nKGE6IGJ5dGVzKSAtPiBieXRlczoKdmVyaWZ5X2JpZ3VpbnRuX2Zyb21fbG9nOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjI3Ni0yNzcKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBwdWJsaWMgdmVyaWZ5X2JpZ3VpbnRuX2Zyb21fbG9nKGE6IGJ5dGVzKTogVWludE48MjU2PiB7CiAgICBwcm90byAxIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoyNzgKICAgIC8vIHJldHVybiBpbnRlcnByZXRBc0FyYzQ8VWludE48MjU2Pj4oYSwgJ2xvZycpCiAgICBmcmFtZV9kaWcgLTEKICAgIGV4dHJhY3QgNCAwCiAgICBmcmFtZV9kaWcgLTEKICAgIGV4dHJhY3QgMCA0CiAgICBieXRlY18wIC8vIDB4MTUxZjdjNzUKICAgID09CiAgICBhc3NlcnQgLy8gQnl0ZXMgaGFzIHZhbGlkIHByZWZpeAogICAgcmV0c3ViCgoKLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjpBcmM0UHJpbWl0aXZlT3BzQ29udHJhY3QudmVyaWZ5X2J5dGVfZnJvbV9sb2coYTogYnl0ZXMpIC0+IGJ5dGVzOgp2ZXJpZnlfYnl0ZV9mcm9tX2xvZzoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoyODAtMjgxCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gcHVibGljIHZlcmlmeV9ieXRlX2Zyb21fbG9nKGE6IGJ5dGVzKTogQnl0ZSB7CiAgICBwcm90byAxIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoyODIKICAgIC8vIHJldHVybiBpbnRlcnByZXRBc0FyYzQ8Qnl0ZT4oYSwgJ2xvZycpCiAgICBmcmFtZV9kaWcgLTEKICAgIGV4dHJhY3QgNCAwCiAgICBmcmFtZV9kaWcgLTEKICAgIGV4dHJhY3QgMCA0CiAgICBieXRlY18wIC8vIDB4MTUxZjdjNzUKICAgID09CiAgICBhc3NlcnQgLy8gQnl0ZXMgaGFzIHZhbGlkIHByZWZpeAogICAgcmV0c3ViCgoKLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjpBcmM0UHJpbWl0aXZlT3BzQ29udHJhY3QudmVyaWZ5X3VmaXhlZG54bV9mcm9tX2xvZyhhOiBieXRlcykgLT4gYnl0ZXM6CnZlcmlmeV91Zml4ZWRueG1fZnJvbV9sb2c6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MzAwLTMwMQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIHB1YmxpYyB2ZXJpZnlfdWZpeGVkbnhtX2Zyb21fbG9nKGE6IGJ5dGVzKTogVUZpeGVkTnhNPDMyLCA4PiB7CiAgICBwcm90byAxIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czozMDIKICAgIC8vIHJldHVybiBpbnRlcnByZXRBc0FyYzQ8VUZpeGVkTnhNPDMyLCA4Pj4oYSwgJ2xvZycpCiAgICBmcmFtZV9kaWcgLTEKICAgIGV4dHJhY3QgNCAwCiAgICBmcmFtZV9kaWcgLTEKICAgIGV4dHJhY3QgMCA0CiAgICBieXRlY18wIC8vIDB4MTUxZjdjNzUKICAgID09CiAgICBhc3NlcnQgLy8gQnl0ZXMgaGFzIHZhbGlkIHByZWZpeAogICAgcmV0c3ViCgoKLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjpBcmM0UHJpbWl0aXZlT3BzQ29udHJhY3QudmVyaWZ5X2JpZ3VmaXhlZG54bV9mcm9tX2xvZyhhOiBieXRlcykgLT4gYnl0ZXM6CnZlcmlmeV9iaWd1Zml4ZWRueG1fZnJvbV9sb2c6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MzA0LTMwNQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIHB1YmxpYyB2ZXJpZnlfYmlndWZpeGVkbnhtX2Zyb21fbG9nKGE6IGJ5dGVzKTogVUZpeGVkTnhNPDI1NiwgMTY+IHsKICAgIHByb3RvIDEgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjMwNgogICAgLy8gcmV0dXJuIGludGVycHJldEFzQXJjNDxVRml4ZWROeE08MjU2LCAxNj4+KGEsICdsb2cnKQogICAgZnJhbWVfZGlnIC0xCiAgICBleHRyYWN0IDQgMAogICAgZnJhbWVfZGlnIC0xCiAgICBleHRyYWN0IDAgNAogICAgYnl0ZWNfMCAvLyAweDE1MWY3Yzc1CiAgICA9PQogICAgYXNzZXJ0IC8vIEJ5dGVzIGhhcyB2YWxpZCBwcmVmaXgKICAgIHJldHN1YgoKCi8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo6QXJjNFByaW1pdGl2ZU9wc0NvbnRyYWN0LnZlcmlmeV9zdHJpbmdfaW5pdChhOiBieXRlcykgLT4gYnl0ZXM6CnZlcmlmeV9zdHJpbmdfaW5pdDoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czozMDgtMzA5CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gcHVibGljIHZlcmlmeV9zdHJpbmdfaW5pdChhOiBzdHJpbmcpOiBTdHIgewogICAgcHJvdG8gMSAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MzEwCiAgICAvLyBjb25zdCByZXN1bHQgPSBuZXcgU3RyKGBIZWxsbywgJHthfWApCiAgICBwdXNoYnl0ZXMgIkhlbGxvLCAiCiAgICBmcmFtZV9kaWcgLTEKICAgIGNvbmNhdAogICAgZHVwCiAgICBsZW4KICAgIGl0b2IKICAgIGV4dHJhY3QgNiAyCiAgICBzd2FwCiAgICBjb25jYXQKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czozMTEKICAgIC8vIHJldHVybiByZXN1bHQKICAgIHJldHN1YgoKCi8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo6QXJjNFByaW1pdGl2ZU9wc0NvbnRyYWN0LnZlcmlmeV9zdHJpbmdfYWRkKGE6IGJ5dGVzLCBiOiBieXRlcykgLT4gYnl0ZXM6CnZlcmlmeV9zdHJpbmdfYWRkOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjMxMy0zMTQKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBwdWJsaWMgdmVyaWZ5X3N0cmluZ19hZGQoYTogU3RyLCBiOiBTdHIpOiBTdHIgewogICAgcHJvdG8gMiAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MzE1CiAgICAvLyBjb25zdCByZXN1bHQgPSBhLm5hdGl2ZS5jb25jYXQoYi5uYXRpdmUpCiAgICBmcmFtZV9kaWcgLTIKICAgIGV4dHJhY3QgMiAwCiAgICBmcmFtZV9kaWcgLTEKICAgIGV4dHJhY3QgMiAwCiAgICBjb25jYXQKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czozMTYKICAgIC8vIHJldHVybiBuZXcgU3RyKHJlc3VsdCkKICAgIGR1cAogICAgbGVuCiAgICBpdG9iCiAgICBleHRyYWN0IDYgMgogICAgc3dhcAogICAgY29uY2F0CiAgICByZXRzdWIKCgovLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OkFyYzRQcmltaXRpdmVPcHNDb250cmFjdC52ZXJpZnlfc3RyaW5nX2VxKGE6IGJ5dGVzLCBiOiBieXRlcykgLT4gdWludDY0Ogp2ZXJpZnlfc3RyaW5nX2VxOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjMxOC0zMTkKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBwdWJsaWMgdmVyaWZ5X3N0cmluZ19lcShhOiBTdHIsIGI6IFN0cik6IGJvb2xlYW4gewogICAgcHJvdG8gMiAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MzIwCiAgICAvLyByZXR1cm4gYSA9PT0gYgogICAgZnJhbWVfZGlnIC0yCiAgICBmcmFtZV9kaWcgLTEKICAgID09CiAgICByZXRzdWIKCgovLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OkFyYzRQcmltaXRpdmVPcHNDb250cmFjdC52ZXJpZnlfc3RyaW5nX2J5dGVzKGE6IGJ5dGVzKSAtPiBieXRlczoKdmVyaWZ5X3N0cmluZ19ieXRlczoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czozMjItMzIzCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gcHVibGljIHZlcmlmeV9zdHJpbmdfYnl0ZXMoYTogc3RyaW5nKTogYnl0ZXMgewogICAgcHJvdG8gMSAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MzI0CiAgICAvLyBjb25zdCByZXN1bHQgPSBuZXcgU3RyKGEpCiAgICBmcmFtZV9kaWcgLTEKICAgIGxlbgogICAgaXRvYgogICAgZXh0cmFjdCA2IDIKICAgIGZyYW1lX2RpZyAtMQogICAgY29uY2F0CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MzI1CiAgICAvLyByZXR1cm4gcmVzdWx0LmJ5dGVzCiAgICByZXRzdWIKCgovLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OkFyYzRQcmltaXRpdmVPcHNDb250cmFjdC52ZXJpZnlfc3RyaW5nX2Zyb21fbG9nKGE6IGJ5dGVzKSAtPiBieXRlczoKdmVyaWZ5X3N0cmluZ19mcm9tX2xvZzoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czozMzEtMzMyCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gcHVibGljIHZlcmlmeV9zdHJpbmdfZnJvbV9sb2coYTogYnl0ZXMpOiBTdHIgewogICAgcHJvdG8gMSAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MzMzCiAgICAvLyByZXR1cm4gaW50ZXJwcmV0QXNBcmM0PFN0cj4oYSwgJ2xvZycpCiAgICBmcmFtZV9kaWcgLTEKICAgIGV4dHJhY3QgNCAwCiAgICBmcmFtZV9kaWcgLTEKICAgIGV4dHJhY3QgMCA0CiAgICBieXRlY18wIC8vIDB4MTUxZjdjNzUKICAgID09CiAgICBhc3NlcnQgLy8gQnl0ZXMgaGFzIHZhbGlkIHByZWZpeAogICAgcmV0c3ViCgoKLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjpBcmM0UHJpbWl0aXZlT3BzQ29udHJhY3QudmVyaWZ5X2Jvb2xfZnJvbV9sb2coYTogYnl0ZXMpIC0+IGJ5dGVzOgp2ZXJpZnlfYm9vbF9mcm9tX2xvZzoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czozNDMtMzQ0CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gcHVibGljIHZlcmlmeV9ib29sX2Zyb21fbG9nKGE6IGJ5dGVzKTogQm9vbCB7CiAgICBwcm90byAxIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czozNDUKICAgIC8vIHJldHVybiBpbnRlcnByZXRBc0FyYzQ8Qm9vbD4oYSwgJ2xvZycpCiAgICBmcmFtZV9kaWcgLTEKICAgIGV4dHJhY3QgNCAwCiAgICBmcmFtZV9kaWcgLTEKICAgIGV4dHJhY3QgMCA0CiAgICBieXRlY18wIC8vIDB4MTUxZjdjNzUKICAgID09CiAgICBhc3NlcnQgLy8gQnl0ZXMgaGFzIHZhbGlkIHByZWZpeAogICAgcmV0c3ViCgoKLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjpBcmM0UHJpbWl0aXZlT3BzQ29udHJhY3QudmVyaWZ5X2VtaXQoYTogYnl0ZXMsIGI6IGJ5dGVzLCBjOiBieXRlcywgZDogYnl0ZXMsIGU6IGJ5dGVzLCBmOiBieXRlcywgZzogYnl0ZXMsIGg6IGJ5dGVzLCBtOiBieXRlcywgbjogYnl0ZXMsIG86IGJ5dGVzLCBwOiBieXRlcywgcTogYnl0ZXMsIHI6IGJ5dGVzLCBzOiBieXRlcywgdDogYnl0ZXMpIC0+IHZvaWQ6CnZlcmlmeV9lbWl0OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjM0OS0zNjcKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBwdWJsaWMgdmVyaWZ5X2VtaXQoCiAgICAvLyAgIGE6IGFyYzQuU3RyLAogICAgLy8gICBiOiBhcmM0LlVpbnROPDUxMj4sCiAgICAvLyAgIGM6IGFyYzQuVWludE42NCwKICAgIC8vICAgZDogYXJjNC5EeW5hbWljQnl0ZXMsCiAgICAvLyAgIGU6IGFyYzQuVWludE42NCwKICAgIC8vICAgZjogYXJjNC5Cb29sLAogICAgLy8gICBnOiBhcmM0LkR5bmFtaWNCeXRlcywKICAgIC8vICAgaDogYXJjNC5TdHIsCiAgICAvLyAgIG06IGFyYzQuVWludE48NjQ+LAogICAgLy8gICBuOiBhcmM0LlVpbnROPDI1Nj4sCiAgICAvLyAgIG86IGFyYzQuVUZpeGVkTnhNPDMyLCA4PiwKICAgIC8vICAgcDogYXJjNC5VRml4ZWROeE08MjU2LCAxNj4sCiAgICAvLyAgIHE6IGFyYzQuQm9vbCwKICAgIC8vICAgcjogYnl0ZXMsCiAgICAvLyAgIHM6IGJ5dGVzLAogICAgLy8gICB0OiBieXRlcywKICAgIC8vICk6IHZvaWQgewogICAgcHJvdG8gMTYgMAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjM3MgogICAgLy8gZW1pdChuZXcgU3dhcHBlZEFyYzQoeyBtLCBuLCBvLCBwLCBxLCByOiBhcmM0X3IsIHM6IGFyYzRfcywgdDogYXJjNF90IH0pKQogICAgZnJhbWVfZGlnIC04CiAgICBmcmFtZV9kaWcgLTcKICAgIGNvbmNhdAogICAgZnJhbWVfZGlnIC02CiAgICBjb25jYXQKICAgIGZyYW1lX2RpZyAtNQogICAgY29uY2F0CiAgICBmcmFtZV9kaWcgLTQKICAgIGNvbmNhdAogICAgZnJhbWVfZGlnIC0zCiAgICBjb25jYXQKICAgIHB1c2hieXRlcyAweDAwNTQKICAgIGNvbmNhdAogICAgZnJhbWVfZGlnIC0yCiAgICBsZW4KICAgIHB1c2hpbnQgODQgLy8gODQKICAgIGRpZyAxCiAgICArCiAgICBpdG9iCiAgICBleHRyYWN0IDYgMgogICAgdW5jb3ZlciAyCiAgICBzd2FwCiAgICBjb25jYXQKICAgIGZyYW1lX2RpZyAtMgogICAgY29uY2F0CiAgICBmcmFtZV9kaWcgLTEKICAgIGNvbmNhdAogICAgcHVzaGJ5dGVzIDB4NjZiYjAzMzMgLy8gbWV0aG9kICJTd2FwcGVkQXJjNCh1aW50NjQsdWludDI1Nix1Zml4ZWQzMng4LHVmaXhlZDI1NngxNixib29sLHVpbnQ4WzNdLHVpbnQxNltdLCh1aW50MzIsdWludDY0LHN0cmluZykpIgogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czozNzMKICAgIC8vIGVtaXQoJ1N3YXBwZWQnLCBhLCBiLCBjLCBkLCBlLCBmLCBnLCBoLCBtLCBuLCBvLCBwLCBxLCBhcmM0X3IuY29weSgpLCBhcmM0X3MuY29weSgpLCBhcmM0X3QpCiAgICBmcmFtZV9kaWcgLTE2CiAgICBsZW4KICAgIHB1c2hpbnQgMTczIC8vIDE3MwogICAgKwogICAgcHVzaGJ5dGVzIDB4MDBhZAogICAgZnJhbWVfZGlnIC0xNQogICAgY29uY2F0CiAgICBmcmFtZV9kaWcgLTE0CiAgICBjb25jYXQKICAgIGRpZyAxCiAgICBpdG9iCiAgICBleHRyYWN0IDYgMgogICAgY29uY2F0CiAgICBmcmFtZV9kaWcgLTEzCiAgICBsZW4KICAgIHVuY292ZXIgMgogICAgKwogICAgc3dhcAogICAgZnJhbWVfZGlnIC0xMgogICAgY29uY2F0CiAgICBmcmFtZV9kaWcgLTExCiAgICBjb25jYXQKICAgIGRpZyAxCiAgICBpdG9iCiAgICBleHRyYWN0IDYgMgogICAgY29uY2F0CiAgICBmcmFtZV9kaWcgLTEwCiAgICBsZW4KICAgIHVuY292ZXIgMgogICAgKwogICAgZHVwCiAgICBpdG9iCiAgICBleHRyYWN0IDYgMgogICAgdW5jb3ZlciAyCiAgICBzd2FwCiAgICBjb25jYXQKICAgIGZyYW1lX2RpZyAtOQogICAgbGVuCiAgICB1bmNvdmVyIDIKICAgICsKICAgIHN3YXAKICAgIGZyYW1lX2RpZyAtOAogICAgY29uY2F0CiAgICBmcmFtZV9kaWcgLTcKICAgIGNvbmNhdAogICAgZnJhbWVfZGlnIC02CiAgICBjb25jYXQKICAgIGZyYW1lX2RpZyAtNQogICAgY29uY2F0CiAgICBmcmFtZV9kaWcgLTQKICAgIGNvbmNhdAogICAgZnJhbWVfZGlnIC0zCiAgICBjb25jYXQKICAgIGRpZyAxCiAgICBpdG9iCiAgICBleHRyYWN0IDYgMgogICAgY29uY2F0CiAgICBzd2FwCiAgICB1bmNvdmVyIDIKICAgICsKICAgIGl0b2IKICAgIGV4dHJhY3QgNiAyCiAgICBjb25jYXQKICAgIGZyYW1lX2RpZyAtMTYKICAgIGNvbmNhdAogICAgZnJhbWVfZGlnIC0xMwogICAgY29uY2F0CiAgICBmcmFtZV9kaWcgLTEwCiAgICBjb25jYXQKICAgIGZyYW1lX2RpZyAtOQogICAgY29uY2F0CiAgICBmcmFtZV9kaWcgLTIKICAgIGNvbmNhdAogICAgZnJhbWVfZGlnIC0xCiAgICBjb25jYXQKICAgIHB1c2hieXRlcyAweGVjMzMxOWJiIC8vIG1ldGhvZCAiU3dhcHBlZChzdHJpbmcsdWludDUxMix1aW50NjQsYnl0ZVtdLHVpbnQ2NCxib29sLGJ5dGVbXSxzdHJpbmcsdWludDY0LHVpbnQyNTYsdWZpeGVkMzJ4OCx1Zml4ZWQyNTZ4MTYsYm9vbCx1aW50OFszXSx1aW50MTZbXSwodWludDMyLHVpbnQ2NCxzdHJpbmcpKSIKICAgIGRpZyAxCiAgICBjb25jYXQKICAgIGxvZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjM3NC0zOTIKICAgIC8vIGVtaXQoCiAgICAvLyAgICdTd2FwcGVkKHN0cmluZyx1aW50NTEyLHVpbnQ2NCxieXRlW10sdWludDY0LGJvb2wsYnl0ZVtdLHN0cmluZyx1aW50NjQsdWludDI1Nix1Zml4ZWQzMng4LHVmaXhlZDI1NngxNixib29sLHVpbnQ4WzNdLHVpbnQxNltdLCh1aW50MzIsdWludDY0LHN0cmluZykpJywKICAgIC8vICAgYSwKICAgIC8vICAgYiwKICAgIC8vICAgYywKICAgIC8vICAgZCwKICAgIC8vICAgZSwKICAgIC8vICAgZiwKICAgIC8vICAgZywKICAgIC8vICAgaCwKICAgIC8vICAgbSwKICAgIC8vICAgbiwKICAgIC8vICAgbywKICAgIC8vICAgcCwKICAgIC8vICAgcSwKICAgIC8vICAgYXJjNF9yLmNvcHkoKSwKICAgIC8vICAgYXJjNF9zLmNvcHkoKSwKICAgIC8vICAgYXJjNF90LAogICAgLy8gKQogICAgcHVzaGJ5dGVzIDB4NzZiOTE4ZmEgLy8gbWV0aG9kICJTd2FwcGVkKHN0cmluZyx1aW50NTEyLHVpbnQ2NCxieXRlW10sdWludDY0LGJvb2wsYnl0ZVtdLHN0cmluZyx1aW50NjQsdWludDI1Nix1Zml4ZWQzMng4LHVmaXhlZDI1NngxNixib29sLHVpbnQ4WzNdLHVpbnQxNltdLCh1aW50MzIsdWludDY0LHN0cmluZykpKHN0cmluZyx1aW50NTEyLHVpbnQ2NCxieXRlW10sdWludDY0LGJvb2wsYnl0ZVtdLHN0cmluZyx1aW50NjQsdWludDI1Nix1Zml4ZWQzMng4LHVmaXhlZDI1NngxNixib29sLHVpbnQ4WzNdLHVpbnQxNltdLCh1aW50MzIsdWludDY0LHN0cmluZykpIgogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIHJldHN1Ygo=", - "clear": "I3ByYWdtYSB2ZXJzaW9uIDEwCiNwcmFnbWEgdHlwZXRyYWNrIGZhbHNlCgovLyBAYWxnb3JhbmRmb3VuZGF0aW9uL2FsZ29yYW5kLXR5cGVzY3JpcHQvYmFzZS1jb250cmFjdC5kLnRzOjpCYXNlQ29udHJhY3QuY2xlYXJTdGF0ZVByb2dyYW0oKSAtPiB1aW50NjQ6Cm1haW46CiAgICBwdXNoaW50IDEgLy8gMQogICAgcmV0dXJuCg==" - }, - "byteCode": { - "approval": "CiAEAQhAACYCBBUffHUBADEbQQfMgjcElvFBFgTtZmCWBCygNSsEhZB9QAROsq9KBCy+xFsEB2Zv2QQ3C6vTBCtrPvAEJ+IamAQznal8BHiY7ZcEHxMM7ATHSGZOBKK6wUsEekYMsQTcqx8BBJfZBk0EzgbCoAR8EeN1BNzbzuAEd6S2jQRPVAYmBAla7UEE33jNxgTjt+kYBFUzcAgEm7HNZgSBSE2dBHnpywMEmgPfEATT8ORLBGc9sr0EmC2yMwSv+98OBI5KMPcEKIr3bgSL2EoEBPzVXh8EDxV0/gSyyxO+BNBZ7qcETMTBVwQ9F6xuBPfz1fwE+Mj41QRD9xYqBELgkHUE2Vb1dQRsAWDfBKiQFQsECy9MPwSdudMnBOTZUKEEtgXoDDYaAI43BiMGAgXhBcAFnwV+BV0FPAUbBPoE2QS4BJcEdgRVBDQEEwPyA9EDsAOPA24DTQMsAwsC6gLJAqgChwJmAlACOgIkAhEB/gHrAdUBvwGpAZEBeQFmAVMBPQEnAREA+wDgAMIArwCZAIEAbgBYAAIlQzEZFEQxGEQ2GgE2GgI2GgM2GgQ2GgU2GgY2Ggc2Ggg2Ggk2Ggo2Ggs2Ggw2Gg02Gg5XAgA2Gg9JJVlLAYECWVJXAgA2Gg9JgQJZSwEVUlcCAIgKayJDMRkURDEYRDYaAVcCAIgKSChMULAiQzEZFEQxGEQ2GgFXAgAoTFCwIkMxGRREMRhENhoBSRUWVwYCTFAoTFCwIkMxGRREMRhENhoBVwIAiAn2KExQsCJDMRkURDEYRDYaAVcCAChMULAiQzEZFEQxGEQ2GgFXAgCICb9JFRZXBgJMUChMULAiQzEZFEQxGEQ2GgE2GgKICZgpJU8CVChMULAiQzEZFEQxGEQ2GgE2GgKICWYoTFCwIkMxGRREMRhENhoBVwIAiAk4KExQsCJDMRkURDEYRDYaAVcCAIgJEShMULAiQzEZFEQxGEQ2GgFXAgCICOooTFCwIkMxGRREMRhENhoBVwIAKExQsCJDMRkURDEYRDYaAVcCAChMULAiQzEZFEQxGEQ2GgFJFRZXBgJMUChMULAiQzEZFEQxGEQ2GgFJFRZXBgJMUChMULAiQzEZFEQxGEQ2GgFXAgCICG0oTFCwIkMxGRREMRhENhoBVwIAiAhGKExQsCJDMRkURDEYRDYaAVcCAIgIHyhMULAiQzEZFEQxGEQ2GgFXAgAoTFCwIkMxGRREMRhENhoBVwIAKExQsCJDMRkURDEYRDYaAVcCAChMULAiQzEZFEQxGEQ2GgFXAgCIB8EoTFCwIkMxGRREMRhENhoBVwIAiAeaKExQsCJDMRkURDEYRDYaAVcCAIgHcyhMULAiQzEZFEQxGEQ2GgFXAgA2GgJXAgCIBzYpJU8CVChMULAiQzEZFEQxGEQ2GgFXAgA2GgJXAgCIBvgpJU8CVChMULAiQzEZFEQxGEQ2GgFXAgA2GgJXAgCIBrkpJU8CVChMULAiQzEZFEQxGEQ2GgFXAgA2GgJXAgCIBnspJU8CVChMULAiQzEZFEQxGEQ2GgFXAgA2GgJXAgCIBjkpJU8CVChMULAiQzEZFEQxGEQ2GgFXAgA2GgJXAgCIBfcpJU8CVChMULAiQzEZFEQxGEQ2GgFXAgA2GgJXAgCIBbkpJU8CVChMULAiQzEZFEQxGEQ2GgFXAgA2GgJXAgCIBXopJU8CVChMULAiQzEZFEQxGEQ2GgFXAgA2GgJXAgCIBTwpJU8CVChMULAiQzEZFEQxGEQ2GgFXAgA2GgJXAgCIBPopJU8CVChMULAiQzEZFEQxGEQ2GgFXAgA2GgJXAgCIBLgpJU8CVChMULAiQzEZFEQxGEQ2GgFXAgA2GgJXAgCIBHopJU8CVChMULAiQzEZFEQxGEQ2GgFXAgA2GgJXAgCIBDspJU8CVChMULAiQzEZFEQxGEQ2GgFXAgA2GgJXAgCIA/0pJU8CVChMULAiQzEZFEQxGEQ2GgFXAgA2GgJXAgCIA7spJU8CVChMULAiQzEZFEQxGEQ2GgFXAgA2GgJXAgCIA3kpJU8CVChMULAiQzEZFEQxGEQ2GgFXAgA2GgJXAgCIAzspJU8CVChMULAiQzEZFEQxGEQ2GgFXAgA2GgJXAgCIAvwpJU8CVChMULAiQzEZFEQxGEQ2GgFXAgA2GgJXAgCIAr4pJU8CVChMULAiQzEZFEQxGEQ2GgFXAgA2GgJXAgCIAnwpJU8CVChMULAiQzEZFEQxGEQ2GgFXAgA2GgJXAgCIAj4pJU8CVChMULAiQzEZFEQxGEQ2GgFXAgA2GgJXAgCIAgApJU8CVChMULAiQzEZFEQxGEQ2GgFXAgA2GgJXAgCIAcMpJU8CVChMULAiQzEZFEQxGEQ2GgFXAgA2GgJXAgCIAYYpJU8CVChMULAiQzEZFEQxGEQ2GgFXAgA2GgJXAgCIAUgpJU8CVChMULAiQzEZFEQxGEQ2GgFXAgA2GgJXAgCIAQopJU8CVChMULAiQzEZFEQxGEQ2GgFXAgA2GgJXAgCIAMwpJU8CVChMULAiQzEZFEQxGEQ2GgFXAgA2GgJXAgCIAJApJU8CVChMULAiQzEZFEQxGEQ2GgFXAgA2GgJXAgCIAFQpJU8CVChMULAiQzEZFEQxGEQ2GgFXAgA2GgJXAgCIABYpJU8CVChMULAiQzEZQPm3MRgURCJDigIBi/4VIw5EI6+L/ksBq4v/FSMORIv/TwKrEomKAgGL/hUkDkQkr4v+q4v/FSMORCOvi/+rEomKAgGL/hUjDkQjr4v+q4v/FSQORCSvi/+rEomKAgGL/hUkDkQkr4v+SwGri/8VJA5Ei/9PAqsSiYoCAYv+FSIORCKvi/5LAauL/xUiDkSL/08CqxKJigIBi/4VIw5EI6+L/ksBq4v/FSMORIv/TwKrE4mKAgGL/hUkDkQkr4v+q4v/FSMORCOvi/+rEhSJigIBi/4VIw5EI6+L/quL/xUkDkQkr4v/qxIUiYoCAYv+FSQORCSvi/5LAauL/xUkDkSL/08CqxOJigIBi/4VIg5EIq+L/ksBq4v/FSIORIv/TwKrE4mKAgGL/hUjDkQjr4v+SwGri/8VIw5Ei/9PAqtMF0wXDImKAgGL/hUkDkQkr4v+q4v/FSMORCOvi/+rFxakiYoCAYv+FSMORCOvi/6ri/8VJA5EJK+L/6tMFxaliYoCAYv+FSQORCSvi/5LAauL/xUkDkSL/08Cq6SJigIBi/4VIg5EIq+L/ksBq4v/FSIORIv/TwKrTBdMFwyJigIBi/4VIw5EI6+L/ksBq4v/FSMORIv/TwKrTBdMFw6JigIBi/4VJA5EJK+L/quL/xUjDkQjr4v/qxcWpomKAgGL/hUjDkQjr4v+q4v/FSQORCSvi/+rTBcWp4mKAgGL/hUkDkQkr4v+SwGri/8VJA5Ei/9PAqumiYoCAYv+FSIORCKvi/5LAauL/xUiDkSL/08Cq0wXTBcOiYoCAYv+FSMORCOvi/5LAauL/xUjDkSL/08Cq0wXTBcNiYoCAYv+FSQORCSvi/6ri/8VIw5EI6+L/6sXFqWJigIBi/4VIw5EI6+L/quL/xUkDkQkr4v/q0wXFqSJigIBi/4VJA5EJK+L/ksBq4v/FSQORIv/TwKrpYmKAgGL/hUiDkQir4v+SwGri/8VIg5Ei/9PAqtMF0wXDYmKAgGL/hUjDkQjr4v+SwGri/8VIw5Ei/9PAqtMF0wXD4mKAgGL/hUkDkQkr4v+q4v/FSMORCOvi/+rFxaniYoCAYv+FSMORCOvi/6ri/8VJA5EJK+L/6tMFxamiYoCAYv+FSQORCSvi/5LAauL/xUkDkSL/08Cq6eJigIBi/4VIg5EIq+L/ksBq4v/FSIORIv/TwKrTBdMFw+JigEBi/8VgQQORIEEr4v/q4mKAQGL/xWBIA5EgSCvi/+riYoBAYv/FSIORCKvi/+riYoBAYv/VwQAi/9XAAQoEkSJigEBi/9XBACL/1cABCgSRImKAQGL/1cEAIv/VwAEKBJEiYoBAYv/VwQAi/9XAAQoEkSJigEBi/9XBACL/1cABCgSRImKAQGAB0hlbGxvLCCL/1BJFRZXBgJMUImKAgGL/lcCAIv/VwIAUEkVFlcGAkxQiYoCAYv+i/8SiYoBAYv/FRZXBgKL/1CJigEBi/9XBACL/1cABCgSRImKAQGL/1cEAIv/VwAEKBJEiYoQAIv4i/lQi/pQi/tQi/xQi/1QgAIAVFCL/hWBVEsBCBZXBgJPAkxQi/5Qi/9QgARmuwMzTFCwi/AVga0BCIACAK2L8VCL8lBLARZXBgJQi/MVTwIITIv0UIv1UEsBFlcGAlCL9hVPAghJFlcGAk8CTFCL9xVPAghMi/hQi/lQi/pQi/tQi/xQi/1QSwEWVwYCUExPAggWVwYCUIvwUIvzUIv2UIv3UIv+UIv/UIAE7DMZu0sBULCABHa5GPpMULCJ", - "clear": "CoEBQw==" - }, - "compilerInfo": { - "compiler": "puya", - "compilerVersion": { - "major": 4, - "minor": 0, - "patch": 0 - } - }, - "events": [ - { - "name": "SwappedArc4", - "args": [ - { - "type": "uint64", - "name": "m" - }, - { - "type": "uint256", - "name": "n" - }, - { - "type": "ufixed32x8", - "name": "o" - }, - { - "type": "ufixed256x16", - "name": "p" - }, - { - "type": "bool", - "name": "q" - }, - { - "type": "uint8[3]", - "name": "r" - }, - { - "type": "uint16[]", - "name": "s" - }, - { - "type": "(uint32,uint64,string)", - "name": "t" - } - ] - }, - { - "name": "Swapped", - "args": [ - { - "type": "string", - "name": "0" - }, - { - "type": "uint512", - "name": "1" - }, - { - "type": "uint64", - "name": "2" - }, - { - "type": "byte[]", - "name": "3" - }, - { - "type": "uint64", - "name": "4" - }, - { - "type": "bool", - "name": "5" - }, - { - "type": "byte[]", - "name": "6" - }, - { - "type": "string", - "name": "7" - }, - { - "type": "uint64", - "name": "8" - }, - { - "type": "uint256", - "name": "9" - }, - { - "type": "ufixed32x8", - "name": "10" - }, - { - "type": "ufixed256x16", - "name": "11" - }, - { - "type": "bool", - "name": "12" - }, - { - "type": "uint8[3]", - "name": "13" - }, - { - "type": "uint16[]", - "name": "14" - }, - { - "type": "(uint32,uint64,string)", - "name": "15" - } - ] - }, - { - "name": "", - "args": [ - { - "type": "string", - "name": "0" - }, - { - "type": "uint512", - "name": "1" - }, - { - "type": "uint64", - "name": "2" - }, - { - "type": "byte[]", - "name": "3" - }, - { - "type": "uint64", - "name": "4" - }, - { - "type": "bool", - "name": "5" - }, - { - "type": "byte[]", - "name": "6" - }, - { - "type": "string", - "name": "7" - }, - { - "type": "uint64", - "name": "8" - }, - { - "type": "uint256", - "name": "9" - }, - { - "type": "ufixed32x8", - "name": "10" - }, - { - "type": "ufixed256x16", - "name": "11" - }, - { - "type": "bool", - "name": "12" - }, - { - "type": "uint8[3]", - "name": "13" - }, - { - "type": "uint16[]", - "name": "14" - }, - { - "type": "(uint32,uint64,string)", - "name": "15" - } - ] - } - ], - "templateVariables": {} -} \ No newline at end of file diff --git a/tests/artifacts/arc4-primitive-ops/data/Arc4PrimitiveOpsContract.clear.teal b/tests/artifacts/arc4-primitive-ops/data/Arc4PrimitiveOpsContract.clear.teal deleted file mode 100644 index a4d5804..0000000 --- a/tests/artifacts/arc4-primitive-ops/data/Arc4PrimitiveOpsContract.clear.teal +++ /dev/null @@ -1,7 +0,0 @@ -#pragma version 10 -#pragma typetrack false - -// @algorandfoundation/algorand-typescript/base-contract.d.ts::BaseContract.clearStateProgram() -> uint64: -main: - pushint 1 // 1 - return diff --git a/tests/artifacts/box-contract/contract.algo.ts b/tests/artifacts/box-contract/contract.algo.ts index 0dbe673..7c0208b 100644 --- a/tests/artifacts/box-contract/contract.algo.ts +++ b/tests/artifacts/box-contract/contract.algo.ts @@ -1,13 +1,13 @@ -import { arc4, assert, Box, Bytes, op, TransactionType } from '@algorandfoundation/algorand-typescript' +import { arc4, assert, Box, Bytes, OnCompleteAction, op, TransactionType } from '@algorandfoundation/algorand-typescript' import { Tuple, UintN64 } from '@algorandfoundation/algorand-typescript/arc4' export class BoxContract extends arc4.Contract { - oca = Box({ key: Bytes('oca') }) + oca = Box({ key: Bytes('oca') }) txn = Box({ key: Bytes('txn') }) @arc4.abimethod() public storeEnums(): void { - this.oca.value = arc4.OnCompleteAction.OptIn + this.oca.value = OnCompleteAction.OptIn this.txn.value = TransactionType.ApplicationCall } diff --git a/tests/artifacts/created-app-asset/contract.algo.ts b/tests/artifacts/created-app-asset/contract.algo.ts index 6ec0344..ea10c1b 100644 --- a/tests/artifacts/created-app-asset/contract.algo.ts +++ b/tests/artifacts/created-app-asset/contract.algo.ts @@ -1,5 +1,7 @@ -import { arc4, assert, Global, gtxn, op, uint64 } from '@algorandfoundation/algorand-typescript' -import { interpretAsArc4, methodSelector, UintN64 } from '@algorandfoundation/algorand-typescript/arc4' +import type { gtxn, uint64 } from '@algorandfoundation/algorand-typescript' +import { arc4, assert, Global, op } from '@algorandfoundation/algorand-typescript' +import type { UintN64 } from '@algorandfoundation/algorand-typescript/arc4' +import { interpretAsArc4, methodSelector } from '@algorandfoundation/algorand-typescript/arc4' export class AppExpectingEffects extends arc4.Contract { @arc4.abimethod() diff --git a/tests/artifacts/crypto-ops/contract.algo.ts b/tests/artifacts/crypto-ops/contract.algo.ts index 01455a9..056d874 100644 --- a/tests/artifacts/crypto-ops/contract.algo.ts +++ b/tests/artifacts/crypto-ops/contract.algo.ts @@ -1,6 +1,17 @@ -import { arc4, bytes, Ecdsa, ensureBudget, op, OpUpFeeSource, uint64, VrfVerify } from '@algorandfoundation/algorand-typescript' +import type { bytes, uint64 } from '@algorandfoundation/algorand-typescript' +import { + arc4, + contract, + Ecdsa, + ensureBudget, + MimcConfigurations, + op, + OpUpFeeSource, + VrfVerify, +} from '@algorandfoundation/algorand-typescript' import { Bool } from '@algorandfoundation/algorand-typescript/arc4' +@contract({ name: 'CryptoOpsContract', avmVersion: 11 }) export class CryptoOpsContract extends arc4.Contract { @arc4.abimethod() public verify_sha256(a: bytes, pad_size: uint64): bytes { @@ -91,4 +102,11 @@ export class CryptoOpsContract extends arc4.Contract { const result = op.vrfVerify(VrfVerify.VrfAlgorand, a, b, c) return result } + + @arc4.abimethod() + public verify_mimc(a: bytes): bytes { + ensureBudget(5700, OpUpFeeSource.GroupCredit) + const result = op.mimc(MimcConfigurations.BN254Mp110, a) + return result + } } diff --git a/tests/artifacts/crypto-ops/data/CryptoOpsContract.approval.teal b/tests/artifacts/crypto-ops/data/CryptoOpsContract.approval.teal deleted file mode 100644 index 44fbc8e..0000000 --- a/tests/artifacts/crypto-ops/data/CryptoOpsContract.approval.teal +++ /dev/null @@ -1,841 +0,0 @@ -#pragma version 10 - -tests/artifacts/crypto-ops/contract.algo.ts::CryptoOpsContract.approvalProgram: - intcblock 0 1 4 3000 - bytecblock 0x151f7c75 0x00 0x0004 0x068101 - callsub __puya_arc4_router__ - return - - -// tests/artifacts/crypto-ops/contract.algo.ts::CryptoOpsContract.__puya_arc4_router__() -> uint64: -__puya_arc4_router__: - // tests/artifacts/crypto-ops/contract.algo.ts:3 - // export class CryptoOpsContract extends arc4.Contract { - proto 0 1 - txn NumAppArgs - bz __puya_arc4_router___bare_routing@17 - pushbytess 0x3456c4c3 0xe8442b84 0x65f567aa 0x258455b1 0x35af0f38 0x6582c997 0x6298ffbb 0x3885b54f 0x2164e0bf 0x755b79a5 0xf06bb077 0x133f8ccc 0x2f7c68a9 // method "verify_sha256(byte[],uint64)byte[]", method "verify_sha3_256(byte[],uint64)byte[]", method "verify_keccak_256(byte[],uint64)byte[]", method "verify_sha512_256(byte[],uint64)byte[]", method "verify_ed25519verify(byte[],byte[],byte[])bool", method "verify_ed25519verify_bare(byte[],byte[],byte[])bool", method "verify_ecdsa_verify_k1(byte[],byte[],byte[],byte[],byte[])bool", method "verify_ecdsa_verify_r1(byte[],byte[],byte[],byte[],byte[])bool", method "verify_ecdsa_recover_k1(byte[],uint64,byte[],byte[])(byte[],byte[])", method "verify_ecdsa_recover_r1(byte[],uint64,byte[],byte[])(byte[],byte[])", method "verify_ecdsa_decompress_k1(byte[])(byte[],byte[])", method "verify_ecdsa_decompress_r1(byte[])(byte[],byte[])", method "verify_vrf_verify(byte[],byte[],byte[])(byte[],bool)" - txna ApplicationArgs 0 - match __puya_arc4_router___verify_sha256_route@2 __puya_arc4_router___verify_sha3_256_route@3 __puya_arc4_router___verify_keccak_256_route@4 __puya_arc4_router___verify_sha512_256_route@5 __puya_arc4_router___verify_ed25519verify_route@6 __puya_arc4_router___verify_ed25519verify_bare_route@7 __puya_arc4_router___verify_ecdsa_verify_k1_route@8 __puya_arc4_router___verify_ecdsa_verify_r1_route@9 __puya_arc4_router___verify_ecdsa_recover_k1_route@10 __puya_arc4_router___verify_ecdsa_recover_r1_route@11 __puya_arc4_router___verify_ecdsa_decompress_k1_route@12 __puya_arc4_router___verify_ecdsa_decompress_r1_route@13 __puya_arc4_router___verify_vrf_verify_route@14 - intc_0 // 0 - retsub - -__puya_arc4_router___verify_sha256_route@2: - // tests/artifacts/crypto-ops/contract.algo.ts:4 - // @arc4.abimethod() - txn OnCompletion - ! - assert // OnCompletion is NoOp - txn ApplicationID - assert // is not creating - // tests/artifacts/crypto-ops/contract.algo.ts:3 - // export class CryptoOpsContract extends arc4.Contract { - txna ApplicationArgs 1 - extract 2 0 - txna ApplicationArgs 2 - btoi - // tests/artifacts/crypto-ops/contract.algo.ts:4 - // @arc4.abimethod() - callsub verify_sha256 - dup - len - itob - extract 6 2 - swap - concat - bytec_0 // 0x151f7c75 - swap - concat - log - intc_1 // 1 - retsub - -__puya_arc4_router___verify_sha3_256_route@3: - // tests/artifacts/crypto-ops/contract.algo.ts:11 - // @arc4.abimethod() - txn OnCompletion - ! - assert // OnCompletion is NoOp - txn ApplicationID - assert // is not creating - // tests/artifacts/crypto-ops/contract.algo.ts:3 - // export class CryptoOpsContract extends arc4.Contract { - txna ApplicationArgs 1 - extract 2 0 - txna ApplicationArgs 2 - btoi - // tests/artifacts/crypto-ops/contract.algo.ts:11 - // @arc4.abimethod() - callsub verify_sha3_256 - dup - len - itob - extract 6 2 - swap - concat - bytec_0 // 0x151f7c75 - swap - concat - log - intc_1 // 1 - retsub - -__puya_arc4_router___verify_keccak_256_route@4: - // tests/artifacts/crypto-ops/contract.algo.ts:18 - // @arc4.abimethod() - txn OnCompletion - ! - assert // OnCompletion is NoOp - txn ApplicationID - assert // is not creating - // tests/artifacts/crypto-ops/contract.algo.ts:3 - // export class CryptoOpsContract extends arc4.Contract { - txna ApplicationArgs 1 - extract 2 0 - txna ApplicationArgs 2 - btoi - // tests/artifacts/crypto-ops/contract.algo.ts:18 - // @arc4.abimethod() - callsub verify_keccak_256 - dup - len - itob - extract 6 2 - swap - concat - bytec_0 // 0x151f7c75 - swap - concat - log - intc_1 // 1 - retsub - -__puya_arc4_router___verify_sha512_256_route@5: - // tests/artifacts/crypto-ops/contract.algo.ts:25 - // @arc4.abimethod() - txn OnCompletion - ! - assert // OnCompletion is NoOp - txn ApplicationID - assert // is not creating - // tests/artifacts/crypto-ops/contract.algo.ts:3 - // export class CryptoOpsContract extends arc4.Contract { - txna ApplicationArgs 1 - extract 2 0 - txna ApplicationArgs 2 - btoi - // tests/artifacts/crypto-ops/contract.algo.ts:25 - // @arc4.abimethod() - callsub verify_sha512_256 - dup - len - itob - extract 6 2 - swap - concat - bytec_0 // 0x151f7c75 - swap - concat - log - intc_1 // 1 - retsub - -__puya_arc4_router___verify_ed25519verify_route@6: - // tests/artifacts/crypto-ops/contract.algo.ts:33 - // @arc4.abimethod() - txn OnCompletion - ! - assert // OnCompletion is NoOp - txn ApplicationID - assert // is not creating - // tests/artifacts/crypto-ops/contract.algo.ts:3 - // export class CryptoOpsContract extends arc4.Contract { - txna ApplicationArgs 1 - extract 2 0 - txna ApplicationArgs 2 - extract 2 0 - txna ApplicationArgs 3 - extract 2 0 - // tests/artifacts/crypto-ops/contract.algo.ts:33 - // @arc4.abimethod() - callsub verify_ed25519verify - bytec_1 // 0x00 - intc_0 // 0 - uncover 2 - setbit - bytec_0 // 0x151f7c75 - swap - concat - log - intc_1 // 1 - retsub - -__puya_arc4_router___verify_ed25519verify_bare_route@7: - // tests/artifacts/crypto-ops/contract.algo.ts:41 - // @arc4.abimethod() - txn OnCompletion - ! - assert // OnCompletion is NoOp - txn ApplicationID - assert // is not creating - // tests/artifacts/crypto-ops/contract.algo.ts:3 - // export class CryptoOpsContract extends arc4.Contract { - txna ApplicationArgs 1 - extract 2 0 - txna ApplicationArgs 2 - extract 2 0 - txna ApplicationArgs 3 - extract 2 0 - // tests/artifacts/crypto-ops/contract.algo.ts:41 - // @arc4.abimethod() - callsub verify_ed25519verify_bare - bytec_1 // 0x00 - intc_0 // 0 - uncover 2 - setbit - bytec_0 // 0x151f7c75 - swap - concat - log - intc_1 // 1 - retsub - -__puya_arc4_router___verify_ecdsa_verify_k1_route@8: - // tests/artifacts/crypto-ops/contract.algo.ts:48 - // @arc4.abimethod() - txn OnCompletion - ! - assert // OnCompletion is NoOp - txn ApplicationID - assert // is not creating - // tests/artifacts/crypto-ops/contract.algo.ts:3 - // export class CryptoOpsContract extends arc4.Contract { - txna ApplicationArgs 1 - extract 2 0 - txna ApplicationArgs 2 - extract 2 0 - txna ApplicationArgs 3 - extract 2 0 - txna ApplicationArgs 4 - extract 2 0 - txna ApplicationArgs 5 - extract 2 0 - // tests/artifacts/crypto-ops/contract.algo.ts:48 - // @arc4.abimethod() - callsub verify_ecdsa_verify_k1 - bytec_1 // 0x00 - intc_0 // 0 - uncover 2 - setbit - bytec_0 // 0x151f7c75 - swap - concat - log - intc_1 // 1 - retsub - -__puya_arc4_router___verify_ecdsa_verify_r1_route@9: - // tests/artifacts/crypto-ops/contract.algo.ts:55 - // @arc4.abimethod() - txn OnCompletion - ! - assert // OnCompletion is NoOp - txn ApplicationID - assert // is not creating - // tests/artifacts/crypto-ops/contract.algo.ts:3 - // export class CryptoOpsContract extends arc4.Contract { - txna ApplicationArgs 1 - extract 2 0 - txna ApplicationArgs 2 - extract 2 0 - txna ApplicationArgs 3 - extract 2 0 - txna ApplicationArgs 4 - extract 2 0 - txna ApplicationArgs 5 - extract 2 0 - // tests/artifacts/crypto-ops/contract.algo.ts:55 - // @arc4.abimethod() - callsub verify_ecdsa_verify_r1 - bytec_1 // 0x00 - intc_0 // 0 - uncover 2 - setbit - bytec_0 // 0x151f7c75 - swap - concat - log - intc_1 // 1 - retsub - -__puya_arc4_router___verify_ecdsa_recover_k1_route@10: - // tests/artifacts/crypto-ops/contract.algo.ts:62 - // @arc4.abimethod() - txn OnCompletion - ! - assert // OnCompletion is NoOp - txn ApplicationID - assert // is not creating - // tests/artifacts/crypto-ops/contract.algo.ts:3 - // export class CryptoOpsContract extends arc4.Contract { - txna ApplicationArgs 1 - extract 2 0 - txna ApplicationArgs 2 - btoi - txna ApplicationArgs 3 - extract 2 0 - txna ApplicationArgs 4 - extract 2 0 - // tests/artifacts/crypto-ops/contract.algo.ts:62 - // @arc4.abimethod() - callsub verify_ecdsa_recover_k1 - dig 1 - len - itob - extract 6 2 - uncover 2 - concat - dig 1 - len - itob - extract 6 2 - uncover 2 - concat - dig 1 - len - intc_2 // 4 - + - itob - extract 6 2 - bytec_2 // 0x0004 - swap - concat - uncover 2 - concat - swap - concat - bytec_0 // 0x151f7c75 - swap - concat - log - intc_1 // 1 - retsub - -__puya_arc4_router___verify_ecdsa_recover_r1_route@11: - // tests/artifacts/crypto-ops/contract.algo.ts:68 - // @arc4.abimethod() - txn OnCompletion - ! - assert // OnCompletion is NoOp - txn ApplicationID - assert // is not creating - // tests/artifacts/crypto-ops/contract.algo.ts:3 - // export class CryptoOpsContract extends arc4.Contract { - txna ApplicationArgs 1 - extract 2 0 - txna ApplicationArgs 2 - btoi - txna ApplicationArgs 3 - extract 2 0 - txna ApplicationArgs 4 - extract 2 0 - // tests/artifacts/crypto-ops/contract.algo.ts:68 - // @arc4.abimethod() - callsub verify_ecdsa_recover_r1 - dig 1 - len - itob - extract 6 2 - uncover 2 - concat - dig 1 - len - itob - extract 6 2 - uncover 2 - concat - dig 1 - len - intc_2 // 4 - + - itob - extract 6 2 - bytec_2 // 0x0004 - swap - concat - uncover 2 - concat - swap - concat - bytec_0 // 0x151f7c75 - swap - concat - log - intc_1 // 1 - retsub - -__puya_arc4_router___verify_ecdsa_decompress_k1_route@12: - // tests/artifacts/crypto-ops/contract.algo.ts:77 - // @arc4.abimethod() - txn OnCompletion - ! - assert // OnCompletion is NoOp - txn ApplicationID - assert // is not creating - // tests/artifacts/crypto-ops/contract.algo.ts:3 - // export class CryptoOpsContract extends arc4.Contract { - txna ApplicationArgs 1 - extract 2 0 - // tests/artifacts/crypto-ops/contract.algo.ts:77 - // @arc4.abimethod() - callsub verify_ecdsa_decompress_k1 - dig 1 - len - itob - extract 6 2 - uncover 2 - concat - dig 1 - len - itob - extract 6 2 - uncover 2 - concat - dig 1 - len - intc_2 // 4 - + - itob - extract 6 2 - bytec_2 // 0x0004 - swap - concat - uncover 2 - concat - swap - concat - bytec_0 // 0x151f7c75 - swap - concat - log - intc_1 // 1 - retsub - -__puya_arc4_router___verify_ecdsa_decompress_r1_route@13: - // tests/artifacts/crypto-ops/contract.algo.ts:83 - // @arc4.abimethod() - txn OnCompletion - ! - assert // OnCompletion is NoOp - txn ApplicationID - assert // is not creating - // tests/artifacts/crypto-ops/contract.algo.ts:3 - // export class CryptoOpsContract extends arc4.Contract { - txna ApplicationArgs 1 - extract 2 0 - // tests/artifacts/crypto-ops/contract.algo.ts:83 - // @arc4.abimethod() - callsub verify_ecdsa_decompress_r1 - dig 1 - len - itob - extract 6 2 - uncover 2 - concat - dig 1 - len - itob - extract 6 2 - uncover 2 - concat - dig 1 - len - intc_2 // 4 - + - itob - extract 6 2 - bytec_2 // 0x0004 - swap - concat - uncover 2 - concat - swap - concat - bytec_0 // 0x151f7c75 - swap - concat - log - intc_1 // 1 - retsub - -__puya_arc4_router___verify_vrf_verify_route@14: - // tests/artifacts/crypto-ops/contract.algo.ts:89 - // @arc4.abimethod() - txn OnCompletion - ! - assert // OnCompletion is NoOp - txn ApplicationID - assert // is not creating - // tests/artifacts/crypto-ops/contract.algo.ts:3 - // export class CryptoOpsContract extends arc4.Contract { - txna ApplicationArgs 1 - extract 2 0 - txna ApplicationArgs 2 - extract 2 0 - txna ApplicationArgs 3 - extract 2 0 - // tests/artifacts/crypto-ops/contract.algo.ts:89 - // @arc4.abimethod() - callsub verify_vrf_verify - dig 1 - len - itob - extract 6 2 - uncover 2 - concat - bytec_1 // 0x00 - intc_0 // 0 - uncover 3 - setbit - pushbytes 0x0003 - swap - concat - swap - concat - bytec_0 // 0x151f7c75 - swap - concat - log - intc_1 // 1 - retsub - -__puya_arc4_router___bare_routing@17: - // tests/artifacts/crypto-ops/contract.algo.ts:3 - // export class CryptoOpsContract extends arc4.Contract { - txn OnCompletion - bnz __puya_arc4_router___after_if_else@21 - txn ApplicationID - ! - assert // is creating - intc_1 // 1 - retsub - -__puya_arc4_router___after_if_else@21: - // tests/artifacts/crypto-ops/contract.algo.ts:3 - // export class CryptoOpsContract extends arc4.Contract { - intc_0 // 0 - retsub - - -// tests/artifacts/crypto-ops/contract.algo.ts::CryptoOpsContract.verify_sha256(a: bytes, pad_size: uint64) -> bytes: -verify_sha256: - // tests/artifacts/crypto-ops/contract.algo.ts:4-5 - // @arc4.abimethod() - // public verify_sha256(a: bytes, pad_size: uint64): bytes { - proto 2 1 - // tests/artifacts/crypto-ops/contract.algo.ts:6 - // const paddedA = op.bzero(pad_size).concat(a) - frame_dig -1 - bzero - frame_dig -2 - concat - // tests/artifacts/crypto-ops/contract.algo.ts:7 - // const result = op.sha256(paddedA) - sha256 - // tests/artifacts/crypto-ops/contract.algo.ts:8 - // return result - retsub - - -// tests/artifacts/crypto-ops/contract.algo.ts::CryptoOpsContract.verify_sha3_256(a: bytes, pad_size: uint64) -> bytes: -verify_sha3_256: - // tests/artifacts/crypto-ops/contract.algo.ts:11-12 - // @arc4.abimethod() - // public verify_sha3_256(a: bytes, pad_size: uint64): bytes { - proto 2 1 - // tests/artifacts/crypto-ops/contract.algo.ts:13 - // const paddedA = op.bzero(pad_size).concat(a) - frame_dig -1 - bzero - frame_dig -2 - concat - // tests/artifacts/crypto-ops/contract.algo.ts:14 - // const result = op.sha3_256(paddedA) - sha3_256 - // tests/artifacts/crypto-ops/contract.algo.ts:15 - // return result - retsub - - -// tests/artifacts/crypto-ops/contract.algo.ts::CryptoOpsContract.verify_keccak_256(a: bytes, pad_size: uint64) -> bytes: -verify_keccak_256: - // tests/artifacts/crypto-ops/contract.algo.ts:18-19 - // @arc4.abimethod() - // public verify_keccak_256(a: bytes, pad_size: uint64): bytes { - proto 2 1 - // tests/artifacts/crypto-ops/contract.algo.ts:20 - // const paddedA = op.bzero(pad_size).concat(a) - frame_dig -1 - bzero - frame_dig -2 - concat - // tests/artifacts/crypto-ops/contract.algo.ts:21 - // const result = op.keccak256(paddedA) - keccak256 - // tests/artifacts/crypto-ops/contract.algo.ts:22 - // return result - retsub - - -// tests/artifacts/crypto-ops/contract.algo.ts::CryptoOpsContract.verify_sha512_256(a: bytes, pad_size: uint64) -> bytes: -verify_sha512_256: - // tests/artifacts/crypto-ops/contract.algo.ts:25-26 - // @arc4.abimethod() - // public verify_sha512_256(a: bytes, pad_size: uint64): bytes { - proto 2 1 - // tests/artifacts/crypto-ops/contract.algo.ts:27 - // const paddedA = op.bzero(pad_size).concat(a) - frame_dig -1 - bzero - frame_dig -2 - concat - // tests/artifacts/crypto-ops/contract.algo.ts:28 - // const result = op.sha512_256(paddedA) - sha512_256 - // tests/artifacts/crypto-ops/contract.algo.ts:29 - // return result - retsub - - -// tests/artifacts/crypto-ops/contract.algo.ts::CryptoOpsContract.verify_ed25519verify(a: bytes, b: bytes, c: bytes) -> uint64: -verify_ed25519verify: - // tests/artifacts/crypto-ops/contract.algo.ts:33-34 - // @arc4.abimethod() - // public verify_ed25519verify(a: bytes, b: bytes, c: bytes): boolean { - proto 3 1 - // tests/artifacts/crypto-ops/contract.algo.ts:35 - // ensureBudget(1900, OpUpFeeSource.GroupCredit) - pushint 1900 // 1900 - intc_0 // 0 - callsub ensure_budget - // tests/artifacts/crypto-ops/contract.algo.ts:36 - // const result = op.ed25519verify(a, b, c) - frame_dig -3 - frame_dig -2 - frame_dig -1 - ed25519verify - // tests/artifacts/crypto-ops/contract.algo.ts:37 - // return result - retsub - - -// tests/artifacts/crypto-ops/contract.algo.ts::CryptoOpsContract.verify_ed25519verify_bare(a: bytes, b: bytes, c: bytes) -> uint64: -verify_ed25519verify_bare: - // tests/artifacts/crypto-ops/contract.algo.ts:41-42 - // @arc4.abimethod() - // public verify_ed25519verify_bare(a: bytes, b: bytes, c: bytes): boolean { - proto 3 1 - // tests/artifacts/crypto-ops/contract.algo.ts:43 - // ensureBudget(1900, OpUpFeeSource.GroupCredit) - pushint 1900 // 1900 - intc_0 // 0 - callsub ensure_budget - // tests/artifacts/crypto-ops/contract.algo.ts:44 - // const result = op.ed25519verifyBare(a, b, c) - frame_dig -3 - frame_dig -2 - frame_dig -1 - ed25519verify_bare - // tests/artifacts/crypto-ops/contract.algo.ts:45 - // return result - retsub - - -// tests/artifacts/crypto-ops/contract.algo.ts::CryptoOpsContract.verify_ecdsa_verify_k1(a: bytes, b: bytes, c: bytes, d: bytes, e: bytes) -> uint64: -verify_ecdsa_verify_k1: - // tests/artifacts/crypto-ops/contract.algo.ts:48-49 - // @arc4.abimethod() - // public verify_ecdsa_verify_k1(a: bytes, b: bytes, c: bytes, d: bytes, e: bytes): boolean { - proto 5 1 - // tests/artifacts/crypto-ops/contract.algo.ts:50 - // ensureBudget(3000, OpUpFeeSource.GroupCredit) - intc_3 // 3000 - intc_0 // 0 - callsub ensure_budget - // tests/artifacts/crypto-ops/contract.algo.ts:51 - // const result_k1 = op.ecdsaVerify(Ecdsa.Secp256k1, a, b, c, d, e) - frame_dig -5 - frame_dig -4 - frame_dig -3 - frame_dig -2 - frame_dig -1 - ecdsa_verify Secp256k1 - // tests/artifacts/crypto-ops/contract.algo.ts:52 - // return result_k1 - retsub - - -// tests/artifacts/crypto-ops/contract.algo.ts::CryptoOpsContract.verify_ecdsa_verify_r1(a: bytes, b: bytes, c: bytes, d: bytes, e: bytes) -> uint64: -verify_ecdsa_verify_r1: - // tests/artifacts/crypto-ops/contract.algo.ts:55-56 - // @arc4.abimethod() - // public verify_ecdsa_verify_r1(a: bytes, b: bytes, c: bytes, d: bytes, e: bytes): boolean { - proto 5 1 - // tests/artifacts/crypto-ops/contract.algo.ts:57 - // ensureBudget(3000, OpUpFeeSource.GroupCredit) - intc_3 // 3000 - intc_0 // 0 - callsub ensure_budget - // tests/artifacts/crypto-ops/contract.algo.ts:58 - // const result_r1 = op.ecdsaVerify(Ecdsa.Secp256r1, a, b, c, d, e) - frame_dig -5 - frame_dig -4 - frame_dig -3 - frame_dig -2 - frame_dig -1 - ecdsa_verify Secp256r1 - // tests/artifacts/crypto-ops/contract.algo.ts:59 - // return result_r1 - retsub - - -// tests/artifacts/crypto-ops/contract.algo.ts::CryptoOpsContract.verify_ecdsa_recover_k1(a: bytes, b: uint64, c: bytes, d: bytes) -> bytes, bytes: -verify_ecdsa_recover_k1: - // tests/artifacts/crypto-ops/contract.algo.ts:62-63 - // @arc4.abimethod() - // public verify_ecdsa_recover_k1(a: bytes, b: uint64, c: bytes, d: bytes): readonly [bytes, bytes] { - proto 4 2 - // tests/artifacts/crypto-ops/contract.algo.ts:64 - // ensureBudget(3000, OpUpFeeSource.GroupCredit) - intc_3 // 3000 - intc_0 // 0 - callsub ensure_budget - // tests/artifacts/crypto-ops/contract.algo.ts:65 - // return op.ecdsaPkRecover(Ecdsa.Secp256k1, a, b, c, d) - frame_dig -4 - frame_dig -3 - frame_dig -2 - frame_dig -1 - ecdsa_pk_recover Secp256k1 - retsub - - -// tests/artifacts/crypto-ops/contract.algo.ts::CryptoOpsContract.verify_ecdsa_recover_r1(a: bytes, b: uint64, c: bytes, d: bytes) -> bytes, bytes: -verify_ecdsa_recover_r1: - // tests/artifacts/crypto-ops/contract.algo.ts:68-69 - // @arc4.abimethod() - // public verify_ecdsa_recover_r1(a: bytes, b: uint64, c: bytes, d: bytes): readonly [bytes, bytes] { - proto 4 2 - // tests/artifacts/crypto-ops/contract.algo.ts:73 - // ensureBudget(3000, OpUpFeeSource.GroupCredit) - intc_3 // 3000 - intc_0 // 0 - callsub ensure_budget - // tests/artifacts/crypto-ops/contract.algo.ts:74 - // return op.ecdsaPkRecover(Ecdsa.Secp256r1, a, b, c, d) - frame_dig -4 - frame_dig -3 - frame_dig -2 - frame_dig -1 - ecdsa_pk_recover Secp256r1 - retsub - - -// tests/artifacts/crypto-ops/contract.algo.ts::CryptoOpsContract.verify_ecdsa_decompress_k1(a: bytes) -> bytes, bytes: -verify_ecdsa_decompress_k1: - // tests/artifacts/crypto-ops/contract.algo.ts:77-78 - // @arc4.abimethod() - // public verify_ecdsa_decompress_k1(a: bytes): readonly [bytes, bytes] { - proto 1 2 - // tests/artifacts/crypto-ops/contract.algo.ts:79 - // ensureBudget(700, OpUpFeeSource.GroupCredit) - pushint 700 // 700 - intc_0 // 0 - callsub ensure_budget - // tests/artifacts/crypto-ops/contract.algo.ts:80 - // return op.ecdsaPkDecompress(Ecdsa.Secp256k1, a) - frame_dig -1 - ecdsa_pk_decompress Secp256k1 - retsub - - -// tests/artifacts/crypto-ops/contract.algo.ts::CryptoOpsContract.verify_ecdsa_decompress_r1(a: bytes) -> bytes, bytes: -verify_ecdsa_decompress_r1: - // tests/artifacts/crypto-ops/contract.algo.ts:83-84 - // @arc4.abimethod() - // public verify_ecdsa_decompress_r1(a: bytes): readonly [bytes, bytes] { - proto 1 2 - // tests/artifacts/crypto-ops/contract.algo.ts:85 - // ensureBudget(700, OpUpFeeSource.GroupCredit) - pushint 700 // 700 - intc_0 // 0 - callsub ensure_budget - // tests/artifacts/crypto-ops/contract.algo.ts:86 - // return op.ecdsaPkDecompress(Ecdsa.Secp256r1, a) - frame_dig -1 - ecdsa_pk_decompress Secp256r1 - retsub - - -// tests/artifacts/crypto-ops/contract.algo.ts::CryptoOpsContract.verify_vrf_verify(a: bytes, b: bytes, c: bytes) -> bytes, uint64: -verify_vrf_verify: - // tests/artifacts/crypto-ops/contract.algo.ts:89-90 - // @arc4.abimethod() - // public verify_vrf_verify(a: bytes, b: bytes, c: bytes): readonly [bytes, boolean] { - proto 3 2 - // tests/artifacts/crypto-ops/contract.algo.ts:91 - // ensureBudget(5700, OpUpFeeSource.GroupCredit) - pushint 5700 // 5700 - intc_0 // 0 - callsub ensure_budget - // tests/artifacts/crypto-ops/contract.algo.ts:92 - // const result = op.vrfVerify(VrfVerify.VrfAlgorand, a, b, c) - frame_dig -3 - frame_dig -2 - frame_dig -1 - vrf_verify VrfAlgorand - // tests/artifacts/crypto-ops/contract.algo.ts:93 - // return result - retsub - - -// _puya_lib.util.ensure_budget(required_budget: uint64, fee_source: uint64) -> void: -ensure_budget: - proto 2 0 - frame_dig -2 - pushint 10 // 10 - + - -ensure_budget_while_top@1: - frame_dig 0 - global OpcodeBudget - > - bz ensure_budget_after_while@7 - itxn_begin - pushint 6 // appl - itxn_field TypeEnum - pushint 5 // DeleteApplication - itxn_field OnCompletion - bytec_3 // 0x068101 - itxn_field ApprovalProgram - bytec_3 // 0x068101 - itxn_field ClearStateProgram - frame_dig -1 - switch ensure_budget_switch_case_0@3 ensure_budget_switch_case_1@4 - b ensure_budget_switch_case_next@6 - -ensure_budget_switch_case_0@3: - intc_0 // 0 - itxn_field Fee - b ensure_budget_switch_case_next@6 - -ensure_budget_switch_case_1@4: - global MinTxnFee - itxn_field Fee - -ensure_budget_switch_case_next@6: - itxn_submit - b ensure_budget_while_top@1 - -ensure_budget_after_while@7: - retsub diff --git a/tests/artifacts/crypto-ops/data/CryptoOpsContract.arc32.json b/tests/artifacts/crypto-ops/data/CryptoOpsContract.arc32.json deleted file mode 100644 index e60b9a5..0000000 --- a/tests/artifacts/crypto-ops/data/CryptoOpsContract.arc32.json +++ /dev/null @@ -1,367 +0,0 @@ -{ - "hints": { - "verify_sha256(byte[],uint64)byte[]": { - "call_config": { - "no_op": "CALL" - } - }, - "verify_sha3_256(byte[],uint64)byte[]": { - "call_config": { - "no_op": "CALL" - } - }, - "verify_keccak_256(byte[],uint64)byte[]": { - "call_config": { - "no_op": "CALL" - } - }, - "verify_sha512_256(byte[],uint64)byte[]": { - "call_config": { - "no_op": "CALL" - } - }, - "verify_ed25519verify(byte[],byte[],byte[])bool": { - "call_config": { - "no_op": "CALL" - } - }, - "verify_ed25519verify_bare(byte[],byte[],byte[])bool": { - "call_config": { - "no_op": "CALL" - } - }, - "verify_ecdsa_verify_k1(byte[],byte[],byte[],byte[],byte[])bool": { - "call_config": { - "no_op": "CALL" - } - }, - "verify_ecdsa_verify_r1(byte[],byte[],byte[],byte[],byte[])bool": { - "call_config": { - "no_op": "CALL" - } - }, - "verify_ecdsa_recover_k1(byte[],uint64,byte[],byte[])(byte[],byte[])": { - "call_config": { - "no_op": "CALL" - } - }, - "verify_ecdsa_recover_r1(byte[],uint64,byte[],byte[])(byte[],byte[])": { - "call_config": { - "no_op": "CALL" - } - }, - "verify_ecdsa_decompress_k1(byte[])(byte[],byte[])": { - "call_config": { - "no_op": "CALL" - } - }, - "verify_ecdsa_decompress_r1(byte[])(byte[],byte[])": { - "call_config": { - "no_op": "CALL" - } - }, - "verify_vrf_verify(byte[],byte[],byte[])(byte[],bool)": { - "call_config": { - "no_op": "CALL" - } - } - }, - "source": { - "approval": "I3ByYWdtYSB2ZXJzaW9uIDEwCgp0ZXN0cy9hcnRpZmFjdHMvY3J5cHRvLW9wcy9jb250cmFjdC5hbGdvLnRzOjpDcnlwdG9PcHNDb250cmFjdC5hcHByb3ZhbFByb2dyYW06CiAgICBpbnRjYmxvY2sgMCAxIDQgMzAwMAogICAgYnl0ZWNibG9jayAweDE1MWY3Yzc1IDB4MDAgMHgwMDA0IDB4MDY4MTAxCiAgICBjYWxsc3ViIF9fcHV5YV9hcmM0X3JvdXRlcl9fCiAgICByZXR1cm4KCgovLyB0ZXN0cy9hcnRpZmFjdHMvY3J5cHRvLW9wcy9jb250cmFjdC5hbGdvLnRzOjpDcnlwdG9PcHNDb250cmFjdC5fX3B1eWFfYXJjNF9yb3V0ZXJfXygpIC0+IHVpbnQ2NDoKX19wdXlhX2FyYzRfcm91dGVyX186CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvY3J5cHRvLW9wcy9jb250cmFjdC5hbGdvLnRzOjMKICAgIC8vIGV4cG9ydCBjbGFzcyBDcnlwdG9PcHNDb250cmFjdCBleHRlbmRzIGFyYzQuQ29udHJhY3QgewogICAgcHJvdG8gMCAxCiAgICB0eG4gTnVtQXBwQXJncwogICAgYnogX19wdXlhX2FyYzRfcm91dGVyX19fYmFyZV9yb3V0aW5nQDE3CiAgICBwdXNoYnl0ZXNzIDB4MzQ1NmM0YzMgMHhlODQ0MmI4NCAweDY1ZjU2N2FhIDB4MjU4NDU1YjEgMHgzNWFmMGYzOCAweDY1ODJjOTk3IDB4NjI5OGZmYmIgMHgzODg1YjU0ZiAweDIxNjRlMGJmIDB4NzU1Yjc5YTUgMHhmMDZiYjA3NyAweDEzM2Y4Y2NjIDB4MmY3YzY4YTkgLy8gbWV0aG9kICJ2ZXJpZnlfc2hhMjU2KGJ5dGVbXSx1aW50NjQpYnl0ZVtdIiwgbWV0aG9kICJ2ZXJpZnlfc2hhM18yNTYoYnl0ZVtdLHVpbnQ2NClieXRlW10iLCBtZXRob2QgInZlcmlmeV9rZWNjYWtfMjU2KGJ5dGVbXSx1aW50NjQpYnl0ZVtdIiwgbWV0aG9kICJ2ZXJpZnlfc2hhNTEyXzI1NihieXRlW10sdWludDY0KWJ5dGVbXSIsIG1ldGhvZCAidmVyaWZ5X2VkMjU1MTl2ZXJpZnkoYnl0ZVtdLGJ5dGVbXSxieXRlW10pYm9vbCIsIG1ldGhvZCAidmVyaWZ5X2VkMjU1MTl2ZXJpZnlfYmFyZShieXRlW10sYnl0ZVtdLGJ5dGVbXSlib29sIiwgbWV0aG9kICJ2ZXJpZnlfZWNkc2FfdmVyaWZ5X2sxKGJ5dGVbXSxieXRlW10sYnl0ZVtdLGJ5dGVbXSxieXRlW10pYm9vbCIsIG1ldGhvZCAidmVyaWZ5X2VjZHNhX3ZlcmlmeV9yMShieXRlW10sYnl0ZVtdLGJ5dGVbXSxieXRlW10sYnl0ZVtdKWJvb2wiLCBtZXRob2QgInZlcmlmeV9lY2RzYV9yZWNvdmVyX2sxKGJ5dGVbXSx1aW50NjQsYnl0ZVtdLGJ5dGVbXSkoYnl0ZVtdLGJ5dGVbXSkiLCBtZXRob2QgInZlcmlmeV9lY2RzYV9yZWNvdmVyX3IxKGJ5dGVbXSx1aW50NjQsYnl0ZVtdLGJ5dGVbXSkoYnl0ZVtdLGJ5dGVbXSkiLCBtZXRob2QgInZlcmlmeV9lY2RzYV9kZWNvbXByZXNzX2sxKGJ5dGVbXSkoYnl0ZVtdLGJ5dGVbXSkiLCBtZXRob2QgInZlcmlmeV9lY2RzYV9kZWNvbXByZXNzX3IxKGJ5dGVbXSkoYnl0ZVtdLGJ5dGVbXSkiLCBtZXRob2QgInZlcmlmeV92cmZfdmVyaWZ5KGJ5dGVbXSxieXRlW10sYnl0ZVtdKShieXRlW10sYm9vbCkiCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAwCiAgICBtYXRjaCBfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfc2hhMjU2X3JvdXRlQDIgX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X3NoYTNfMjU2X3JvdXRlQDMgX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2tlY2Nha18yNTZfcm91dGVANCBfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfc2hhNTEyXzI1Nl9yb3V0ZUA1IF9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9lZDI1NTE5dmVyaWZ5X3JvdXRlQDYgX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2VkMjU1MTl2ZXJpZnlfYmFyZV9yb3V0ZUA3IF9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9lY2RzYV92ZXJpZnlfazFfcm91dGVAOCBfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfZWNkc2FfdmVyaWZ5X3IxX3JvdXRlQDkgX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2VjZHNhX3JlY292ZXJfazFfcm91dGVAMTAgX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2VjZHNhX3JlY292ZXJfcjFfcm91dGVAMTEgX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2VjZHNhX2RlY29tcHJlc3NfazFfcm91dGVAMTIgX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2VjZHNhX2RlY29tcHJlc3NfcjFfcm91dGVAMTMgX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X3ZyZl92ZXJpZnlfcm91dGVAMTQKICAgIGludGNfMCAvLyAwCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9zaGEyNTZfcm91dGVAMjoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9jcnlwdG8tb3BzL2NvbnRyYWN0LmFsZ28udHM6NAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBpcyBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9jcnlwdG8tb3BzL2NvbnRyYWN0LmFsZ28udHM6MwogICAgLy8gZXhwb3J0IGNsYXNzIENyeXB0b09wc0NvbnRyYWN0IGV4dGVuZHMgYXJjNC5Db250cmFjdCB7CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBleHRyYWN0IDIgMAogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMgogICAgYnRvaQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2NyeXB0by1vcHMvY29udHJhY3QuYWxnby50czo0CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfc2hhMjU2CiAgICBkdXAKICAgIGxlbgogICAgaXRvYgogICAgZXh0cmFjdCA2IDIKICAgIHN3YXAKICAgIGNvbmNhdAogICAgYnl0ZWNfMCAvLyAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50Y18xIC8vIDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X3NoYTNfMjU2X3JvdXRlQDM6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvY3J5cHRvLW9wcy9jb250cmFjdC5hbGdvLnRzOjExCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGlzIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2NyeXB0by1vcHMvY29udHJhY3QuYWxnby50czozCiAgICAvLyBleHBvcnQgY2xhc3MgQ3J5cHRvT3BzQ29udHJhY3QgZXh0ZW5kcyBhcmM0LkNvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGV4dHJhY3QgMiAwCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAyCiAgICBidG9pCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvY3J5cHRvLW9wcy9jb250cmFjdC5hbGdvLnRzOjExCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfc2hhM18yNTYKICAgIGR1cAogICAgbGVuCiAgICBpdG9iCiAgICBleHRyYWN0IDYgMgogICAgc3dhcAogICAgY29uY2F0CiAgICBieXRlY18wIC8vIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnRjXzEgLy8gMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfa2VjY2FrXzI1Nl9yb3V0ZUA0OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2NyeXB0by1vcHMvY29udHJhY3QuYWxnby50czoxOAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBpcyBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9jcnlwdG8tb3BzL2NvbnRyYWN0LmFsZ28udHM6MwogICAgLy8gZXhwb3J0IGNsYXNzIENyeXB0b09wc0NvbnRyYWN0IGV4dGVuZHMgYXJjNC5Db250cmFjdCB7CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBleHRyYWN0IDIgMAogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMgogICAgYnRvaQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2NyeXB0by1vcHMvY29udHJhY3QuYWxnby50czoxOAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X2tlY2Nha18yNTYKICAgIGR1cAogICAgbGVuCiAgICBpdG9iCiAgICBleHRyYWN0IDYgMgogICAgc3dhcAogICAgY29uY2F0CiAgICBieXRlY18wIC8vIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnRjXzEgLy8gMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfc2hhNTEyXzI1Nl9yb3V0ZUA1OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2NyeXB0by1vcHMvY29udHJhY3QuYWxnby50czoyNQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBpcyBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9jcnlwdG8tb3BzL2NvbnRyYWN0LmFsZ28udHM6MwogICAgLy8gZXhwb3J0IGNsYXNzIENyeXB0b09wc0NvbnRyYWN0IGV4dGVuZHMgYXJjNC5Db250cmFjdCB7CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBleHRyYWN0IDIgMAogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMgogICAgYnRvaQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2NyeXB0by1vcHMvY29udHJhY3QuYWxnby50czoyNQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X3NoYTUxMl8yNTYKICAgIGR1cAogICAgbGVuCiAgICBpdG9iCiAgICBleHRyYWN0IDYgMgogICAgc3dhcAogICAgY29uY2F0CiAgICBieXRlY18wIC8vIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnRjXzEgLy8gMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfZWQyNTUxOXZlcmlmeV9yb3V0ZUA2OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2NyeXB0by1vcHMvY29udHJhY3QuYWxnby50czozMwogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBpcyBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9jcnlwdG8tb3BzL2NvbnRyYWN0LmFsZ28udHM6MwogICAgLy8gZXhwb3J0IGNsYXNzIENyeXB0b09wc0NvbnRyYWN0IGV4dGVuZHMgYXJjNC5Db250cmFjdCB7CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBleHRyYWN0IDIgMAogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMgogICAgZXh0cmFjdCAyIDAKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDMKICAgIGV4dHJhY3QgMiAwCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvY3J5cHRvLW9wcy9jb250cmFjdC5hbGdvLnRzOjMzCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfZWQyNTUxOXZlcmlmeQogICAgYnl0ZWNfMSAvLyAweDAwCiAgICBpbnRjXzAgLy8gMAogICAgdW5jb3ZlciAyCiAgICBzZXRiaXQKICAgIGJ5dGVjXzAgLy8gMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludGNfMSAvLyAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9lZDI1NTE5dmVyaWZ5X2JhcmVfcm91dGVANzoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9jcnlwdG8tb3BzL2NvbnRyYWN0LmFsZ28udHM6NDEKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gaXMgbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvY3J5cHRvLW9wcy9jb250cmFjdC5hbGdvLnRzOjMKICAgIC8vIGV4cG9ydCBjbGFzcyBDcnlwdG9PcHNDb250cmFjdCBleHRlbmRzIGFyYzQuQ29udHJhY3QgewogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgZXh0cmFjdCAyIDAKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDIKICAgIGV4dHJhY3QgMiAwCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAzCiAgICBleHRyYWN0IDIgMAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2NyeXB0by1vcHMvY29udHJhY3QuYWxnby50czo0MQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X2VkMjU1MTl2ZXJpZnlfYmFyZQogICAgYnl0ZWNfMSAvLyAweDAwCiAgICBpbnRjXzAgLy8gMAogICAgdW5jb3ZlciAyCiAgICBzZXRiaXQKICAgIGJ5dGVjXzAgLy8gMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludGNfMSAvLyAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9lY2RzYV92ZXJpZnlfazFfcm91dGVAODoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9jcnlwdG8tb3BzL2NvbnRyYWN0LmFsZ28udHM6NDgKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gaXMgbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvY3J5cHRvLW9wcy9jb250cmFjdC5hbGdvLnRzOjMKICAgIC8vIGV4cG9ydCBjbGFzcyBDcnlwdG9PcHNDb250cmFjdCBleHRlbmRzIGFyYzQuQ29udHJhY3QgewogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgZXh0cmFjdCAyIDAKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDIKICAgIGV4dHJhY3QgMiAwCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAzCiAgICBleHRyYWN0IDIgMAogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgNAogICAgZXh0cmFjdCAyIDAKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDUKICAgIGV4dHJhY3QgMiAwCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvY3J5cHRvLW9wcy9jb250cmFjdC5hbGdvLnRzOjQ4CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfZWNkc2FfdmVyaWZ5X2sxCiAgICBieXRlY18xIC8vIDB4MDAKICAgIGludGNfMCAvLyAwCiAgICB1bmNvdmVyIDIKICAgIHNldGJpdAogICAgYnl0ZWNfMCAvLyAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50Y18xIC8vIDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2VjZHNhX3ZlcmlmeV9yMV9yb3V0ZUA5OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2NyeXB0by1vcHMvY29udHJhY3QuYWxnby50czo1NQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBpcyBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9jcnlwdG8tb3BzL2NvbnRyYWN0LmFsZ28udHM6MwogICAgLy8gZXhwb3J0IGNsYXNzIENyeXB0b09wc0NvbnRyYWN0IGV4dGVuZHMgYXJjNC5Db250cmFjdCB7CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBleHRyYWN0IDIgMAogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMgogICAgZXh0cmFjdCAyIDAKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDMKICAgIGV4dHJhY3QgMiAwCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyA0CiAgICBleHRyYWN0IDIgMAogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgNQogICAgZXh0cmFjdCAyIDAKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9jcnlwdG8tb3BzL2NvbnRyYWN0LmFsZ28udHM6NTUKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV9lY2RzYV92ZXJpZnlfcjEKICAgIGJ5dGVjXzEgLy8gMHgwMAogICAgaW50Y18wIC8vIDAKICAgIHVuY292ZXIgMgogICAgc2V0Yml0CiAgICBieXRlY18wIC8vIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnRjXzEgLy8gMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfZWNkc2FfcmVjb3Zlcl9rMV9yb3V0ZUAxMDoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9jcnlwdG8tb3BzL2NvbnRyYWN0LmFsZ28udHM6NjIKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gaXMgbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvY3J5cHRvLW9wcy9jb250cmFjdC5hbGdvLnRzOjMKICAgIC8vIGV4cG9ydCBjbGFzcyBDcnlwdG9PcHNDb250cmFjdCBleHRlbmRzIGFyYzQuQ29udHJhY3QgewogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgZXh0cmFjdCAyIDAKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDIKICAgIGJ0b2kKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDMKICAgIGV4dHJhY3QgMiAwCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyA0CiAgICBleHRyYWN0IDIgMAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2NyeXB0by1vcHMvY29udHJhY3QuYWxnby50czo2MgogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X2VjZHNhX3JlY292ZXJfazEKICAgIGRpZyAxCiAgICBsZW4KICAgIGl0b2IKICAgIGV4dHJhY3QgNiAyCiAgICB1bmNvdmVyIDIKICAgIGNvbmNhdAogICAgZGlnIDEKICAgIGxlbgogICAgaXRvYgogICAgZXh0cmFjdCA2IDIKICAgIHVuY292ZXIgMgogICAgY29uY2F0CiAgICBkaWcgMQogICAgbGVuCiAgICBpbnRjXzIgLy8gNAogICAgKwogICAgaXRvYgogICAgZXh0cmFjdCA2IDIKICAgIGJ5dGVjXzIgLy8gMHgwMDA0CiAgICBzd2FwCiAgICBjb25jYXQKICAgIHVuY292ZXIgMgogICAgY29uY2F0CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGJ5dGVjXzAgLy8gMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludGNfMSAvLyAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9lY2RzYV9yZWNvdmVyX3IxX3JvdXRlQDExOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2NyeXB0by1vcHMvY29udHJhY3QuYWxnby50czo2OAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBpcyBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9jcnlwdG8tb3BzL2NvbnRyYWN0LmFsZ28udHM6MwogICAgLy8gZXhwb3J0IGNsYXNzIENyeXB0b09wc0NvbnRyYWN0IGV4dGVuZHMgYXJjNC5Db250cmFjdCB7CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBleHRyYWN0IDIgMAogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMgogICAgYnRvaQogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMwogICAgZXh0cmFjdCAyIDAKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDQKICAgIGV4dHJhY3QgMiAwCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvY3J5cHRvLW9wcy9jb250cmFjdC5hbGdvLnRzOjY4CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfZWNkc2FfcmVjb3Zlcl9yMQogICAgZGlnIDEKICAgIGxlbgogICAgaXRvYgogICAgZXh0cmFjdCA2IDIKICAgIHVuY292ZXIgMgogICAgY29uY2F0CiAgICBkaWcgMQogICAgbGVuCiAgICBpdG9iCiAgICBleHRyYWN0IDYgMgogICAgdW5jb3ZlciAyCiAgICBjb25jYXQKICAgIGRpZyAxCiAgICBsZW4KICAgIGludGNfMiAvLyA0CiAgICArCiAgICBpdG9iCiAgICBleHRyYWN0IDYgMgogICAgYnl0ZWNfMiAvLyAweDAwMDQKICAgIHN3YXAKICAgIGNvbmNhdAogICAgdW5jb3ZlciAyCiAgICBjb25jYXQKICAgIHN3YXAKICAgIGNvbmNhdAogICAgYnl0ZWNfMCAvLyAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50Y18xIC8vIDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2VjZHNhX2RlY29tcHJlc3NfazFfcm91dGVAMTI6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvY3J5cHRvLW9wcy9jb250cmFjdC5hbGdvLnRzOjc3CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGlzIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2NyeXB0by1vcHMvY29udHJhY3QuYWxnby50czozCiAgICAvLyBleHBvcnQgY2xhc3MgQ3J5cHRvT3BzQ29udHJhY3QgZXh0ZW5kcyBhcmM0LkNvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGV4dHJhY3QgMiAwCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvY3J5cHRvLW9wcy9jb250cmFjdC5hbGdvLnRzOjc3CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfZWNkc2FfZGVjb21wcmVzc19rMQogICAgZGlnIDEKICAgIGxlbgogICAgaXRvYgogICAgZXh0cmFjdCA2IDIKICAgIHVuY292ZXIgMgogICAgY29uY2F0CiAgICBkaWcgMQogICAgbGVuCiAgICBpdG9iCiAgICBleHRyYWN0IDYgMgogICAgdW5jb3ZlciAyCiAgICBjb25jYXQKICAgIGRpZyAxCiAgICBsZW4KICAgIGludGNfMiAvLyA0CiAgICArCiAgICBpdG9iCiAgICBleHRyYWN0IDYgMgogICAgYnl0ZWNfMiAvLyAweDAwMDQKICAgIHN3YXAKICAgIGNvbmNhdAogICAgdW5jb3ZlciAyCiAgICBjb25jYXQKICAgIHN3YXAKICAgIGNvbmNhdAogICAgYnl0ZWNfMCAvLyAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50Y18xIC8vIDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2VjZHNhX2RlY29tcHJlc3NfcjFfcm91dGVAMTM6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvY3J5cHRvLW9wcy9jb250cmFjdC5hbGdvLnRzOjgzCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGlzIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2NyeXB0by1vcHMvY29udHJhY3QuYWxnby50czozCiAgICAvLyBleHBvcnQgY2xhc3MgQ3J5cHRvT3BzQ29udHJhY3QgZXh0ZW5kcyBhcmM0LkNvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGV4dHJhY3QgMiAwCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvY3J5cHRvLW9wcy9jb250cmFjdC5hbGdvLnRzOjgzCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfZWNkc2FfZGVjb21wcmVzc19yMQogICAgZGlnIDEKICAgIGxlbgogICAgaXRvYgogICAgZXh0cmFjdCA2IDIKICAgIHVuY292ZXIgMgogICAgY29uY2F0CiAgICBkaWcgMQogICAgbGVuCiAgICBpdG9iCiAgICBleHRyYWN0IDYgMgogICAgdW5jb3ZlciAyCiAgICBjb25jYXQKICAgIGRpZyAxCiAgICBsZW4KICAgIGludGNfMiAvLyA0CiAgICArCiAgICBpdG9iCiAgICBleHRyYWN0IDYgMgogICAgYnl0ZWNfMiAvLyAweDAwMDQKICAgIHN3YXAKICAgIGNvbmNhdAogICAgdW5jb3ZlciAyCiAgICBjb25jYXQKICAgIHN3YXAKICAgIGNvbmNhdAogICAgYnl0ZWNfMCAvLyAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50Y18xIC8vIDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X3ZyZl92ZXJpZnlfcm91dGVAMTQ6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvY3J5cHRvLW9wcy9jb250cmFjdC5hbGdvLnRzOjg5CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGlzIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2NyeXB0by1vcHMvY29udHJhY3QuYWxnby50czozCiAgICAvLyBleHBvcnQgY2xhc3MgQ3J5cHRvT3BzQ29udHJhY3QgZXh0ZW5kcyBhcmM0LkNvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGV4dHJhY3QgMiAwCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAyCiAgICBleHRyYWN0IDIgMAogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMwogICAgZXh0cmFjdCAyIDAKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9jcnlwdG8tb3BzL2NvbnRyYWN0LmFsZ28udHM6ODkKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV92cmZfdmVyaWZ5CiAgICBkaWcgMQogICAgbGVuCiAgICBpdG9iCiAgICBleHRyYWN0IDYgMgogICAgdW5jb3ZlciAyCiAgICBjb25jYXQKICAgIGJ5dGVjXzEgLy8gMHgwMAogICAgaW50Y18wIC8vIDAKICAgIHVuY292ZXIgMwogICAgc2V0Yml0CiAgICBwdXNoYnl0ZXMgMHgwMDAzCiAgICBzd2FwCiAgICBjb25jYXQKICAgIHN3YXAKICAgIGNvbmNhdAogICAgYnl0ZWNfMCAvLyAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50Y18xIC8vIDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fYmFyZV9yb3V0aW5nQDE3OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2NyeXB0by1vcHMvY29udHJhY3QuYWxnby50czozCiAgICAvLyBleHBvcnQgY2xhc3MgQ3J5cHRvT3BzQ29udHJhY3QgZXh0ZW5kcyBhcmM0LkNvbnRyYWN0IHsKICAgIHR4biBPbkNvbXBsZXRpb24KICAgIGJueiBfX3B1eWFfYXJjNF9yb3V0ZXJfX19hZnRlcl9pZl9lbHNlQDIxCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgIQogICAgYXNzZXJ0IC8vIGlzIGNyZWF0aW5nCiAgICBpbnRjXzEgLy8gMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX19hZnRlcl9pZl9lbHNlQDIxOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2NyeXB0by1vcHMvY29udHJhY3QuYWxnby50czozCiAgICAvLyBleHBvcnQgY2xhc3MgQ3J5cHRvT3BzQ29udHJhY3QgZXh0ZW5kcyBhcmM0LkNvbnRyYWN0IHsKICAgIGludGNfMCAvLyAwCiAgICByZXRzdWIKCgovLyB0ZXN0cy9hcnRpZmFjdHMvY3J5cHRvLW9wcy9jb250cmFjdC5hbGdvLnRzOjpDcnlwdG9PcHNDb250cmFjdC52ZXJpZnlfc2hhMjU2KGE6IGJ5dGVzLCBwYWRfc2l6ZTogdWludDY0KSAtPiBieXRlczoKdmVyaWZ5X3NoYTI1NjoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9jcnlwdG8tb3BzL2NvbnRyYWN0LmFsZ28udHM6NC01CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gcHVibGljIHZlcmlmeV9zaGEyNTYoYTogYnl0ZXMsIHBhZF9zaXplOiB1aW50NjQpOiBieXRlcyB7CiAgICBwcm90byAyIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9jcnlwdG8tb3BzL2NvbnRyYWN0LmFsZ28udHM6NgogICAgLy8gY29uc3QgcGFkZGVkQSA9IG9wLmJ6ZXJvKHBhZF9zaXplKS5jb25jYXQoYSkKICAgIGZyYW1lX2RpZyAtMQogICAgYnplcm8KICAgIGZyYW1lX2RpZyAtMgogICAgY29uY2F0CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvY3J5cHRvLW9wcy9jb250cmFjdC5hbGdvLnRzOjcKICAgIC8vIGNvbnN0IHJlc3VsdCA9IG9wLnNoYTI1NihwYWRkZWRBKQogICAgc2hhMjU2CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvY3J5cHRvLW9wcy9jb250cmFjdC5hbGdvLnRzOjgKICAgIC8vIHJldHVybiByZXN1bHQKICAgIHJldHN1YgoKCi8vIHRlc3RzL2FydGlmYWN0cy9jcnlwdG8tb3BzL2NvbnRyYWN0LmFsZ28udHM6OkNyeXB0b09wc0NvbnRyYWN0LnZlcmlmeV9zaGEzXzI1NihhOiBieXRlcywgcGFkX3NpemU6IHVpbnQ2NCkgLT4gYnl0ZXM6CnZlcmlmeV9zaGEzXzI1NjoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9jcnlwdG8tb3BzL2NvbnRyYWN0LmFsZ28udHM6MTEtMTIKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBwdWJsaWMgdmVyaWZ5X3NoYTNfMjU2KGE6IGJ5dGVzLCBwYWRfc2l6ZTogdWludDY0KTogYnl0ZXMgewogICAgcHJvdG8gMiAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvY3J5cHRvLW9wcy9jb250cmFjdC5hbGdvLnRzOjEzCiAgICAvLyBjb25zdCBwYWRkZWRBID0gb3AuYnplcm8ocGFkX3NpemUpLmNvbmNhdChhKQogICAgZnJhbWVfZGlnIC0xCiAgICBiemVybwogICAgZnJhbWVfZGlnIC0yCiAgICBjb25jYXQKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9jcnlwdG8tb3BzL2NvbnRyYWN0LmFsZ28udHM6MTQKICAgIC8vIGNvbnN0IHJlc3VsdCA9IG9wLnNoYTNfMjU2KHBhZGRlZEEpCiAgICBzaGEzXzI1NgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2NyeXB0by1vcHMvY29udHJhY3QuYWxnby50czoxNQogICAgLy8gcmV0dXJuIHJlc3VsdAogICAgcmV0c3ViCgoKLy8gdGVzdHMvYXJ0aWZhY3RzL2NyeXB0by1vcHMvY29udHJhY3QuYWxnby50czo6Q3J5cHRvT3BzQ29udHJhY3QudmVyaWZ5X2tlY2Nha18yNTYoYTogYnl0ZXMsIHBhZF9zaXplOiB1aW50NjQpIC0+IGJ5dGVzOgp2ZXJpZnlfa2VjY2FrXzI1NjoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9jcnlwdG8tb3BzL2NvbnRyYWN0LmFsZ28udHM6MTgtMTkKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBwdWJsaWMgdmVyaWZ5X2tlY2Nha18yNTYoYTogYnl0ZXMsIHBhZF9zaXplOiB1aW50NjQpOiBieXRlcyB7CiAgICBwcm90byAyIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9jcnlwdG8tb3BzL2NvbnRyYWN0LmFsZ28udHM6MjAKICAgIC8vIGNvbnN0IHBhZGRlZEEgPSBvcC5iemVybyhwYWRfc2l6ZSkuY29uY2F0KGEpCiAgICBmcmFtZV9kaWcgLTEKICAgIGJ6ZXJvCiAgICBmcmFtZV9kaWcgLTIKICAgIGNvbmNhdAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2NyeXB0by1vcHMvY29udHJhY3QuYWxnby50czoyMQogICAgLy8gY29uc3QgcmVzdWx0ID0gb3Aua2VjY2FrMjU2KHBhZGRlZEEpCiAgICBrZWNjYWsyNTYKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9jcnlwdG8tb3BzL2NvbnRyYWN0LmFsZ28udHM6MjIKICAgIC8vIHJldHVybiByZXN1bHQKICAgIHJldHN1YgoKCi8vIHRlc3RzL2FydGlmYWN0cy9jcnlwdG8tb3BzL2NvbnRyYWN0LmFsZ28udHM6OkNyeXB0b09wc0NvbnRyYWN0LnZlcmlmeV9zaGE1MTJfMjU2KGE6IGJ5dGVzLCBwYWRfc2l6ZTogdWludDY0KSAtPiBieXRlczoKdmVyaWZ5X3NoYTUxMl8yNTY6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvY3J5cHRvLW9wcy9jb250cmFjdC5hbGdvLnRzOjI1LTI2CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gcHVibGljIHZlcmlmeV9zaGE1MTJfMjU2KGE6IGJ5dGVzLCBwYWRfc2l6ZTogdWludDY0KTogYnl0ZXMgewogICAgcHJvdG8gMiAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvY3J5cHRvLW9wcy9jb250cmFjdC5hbGdvLnRzOjI3CiAgICAvLyBjb25zdCBwYWRkZWRBID0gb3AuYnplcm8ocGFkX3NpemUpLmNvbmNhdChhKQogICAgZnJhbWVfZGlnIC0xCiAgICBiemVybwogICAgZnJhbWVfZGlnIC0yCiAgICBjb25jYXQKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9jcnlwdG8tb3BzL2NvbnRyYWN0LmFsZ28udHM6MjgKICAgIC8vIGNvbnN0IHJlc3VsdCA9IG9wLnNoYTUxMl8yNTYocGFkZGVkQSkKICAgIHNoYTUxMl8yNTYKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9jcnlwdG8tb3BzL2NvbnRyYWN0LmFsZ28udHM6MjkKICAgIC8vIHJldHVybiByZXN1bHQKICAgIHJldHN1YgoKCi8vIHRlc3RzL2FydGlmYWN0cy9jcnlwdG8tb3BzL2NvbnRyYWN0LmFsZ28udHM6OkNyeXB0b09wc0NvbnRyYWN0LnZlcmlmeV9lZDI1NTE5dmVyaWZ5KGE6IGJ5dGVzLCBiOiBieXRlcywgYzogYnl0ZXMpIC0+IHVpbnQ2NDoKdmVyaWZ5X2VkMjU1MTl2ZXJpZnk6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvY3J5cHRvLW9wcy9jb250cmFjdC5hbGdvLnRzOjMzLTM0CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gcHVibGljIHZlcmlmeV9lZDI1NTE5dmVyaWZ5KGE6IGJ5dGVzLCBiOiBieXRlcywgYzogYnl0ZXMpOiBib29sZWFuIHsKICAgIHByb3RvIDMgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2NyeXB0by1vcHMvY29udHJhY3QuYWxnby50czozNQogICAgLy8gZW5zdXJlQnVkZ2V0KDE5MDAsIE9wVXBGZWVTb3VyY2UuR3JvdXBDcmVkaXQpCiAgICBwdXNoaW50IDE5MDAgLy8gMTkwMAogICAgaW50Y18wIC8vIDAKICAgIGNhbGxzdWIgZW5zdXJlX2J1ZGdldAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2NyeXB0by1vcHMvY29udHJhY3QuYWxnby50czozNgogICAgLy8gY29uc3QgcmVzdWx0ID0gb3AuZWQyNTUxOXZlcmlmeShhLCBiLCBjKQogICAgZnJhbWVfZGlnIC0zCiAgICBmcmFtZV9kaWcgLTIKICAgIGZyYW1lX2RpZyAtMQogICAgZWQyNTUxOXZlcmlmeQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2NyeXB0by1vcHMvY29udHJhY3QuYWxnby50czozNwogICAgLy8gcmV0dXJuIHJlc3VsdAogICAgcmV0c3ViCgoKLy8gdGVzdHMvYXJ0aWZhY3RzL2NyeXB0by1vcHMvY29udHJhY3QuYWxnby50czo6Q3J5cHRvT3BzQ29udHJhY3QudmVyaWZ5X2VkMjU1MTl2ZXJpZnlfYmFyZShhOiBieXRlcywgYjogYnl0ZXMsIGM6IGJ5dGVzKSAtPiB1aW50NjQ6CnZlcmlmeV9lZDI1NTE5dmVyaWZ5X2JhcmU6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvY3J5cHRvLW9wcy9jb250cmFjdC5hbGdvLnRzOjQxLTQyCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gcHVibGljIHZlcmlmeV9lZDI1NTE5dmVyaWZ5X2JhcmUoYTogYnl0ZXMsIGI6IGJ5dGVzLCBjOiBieXRlcyk6IGJvb2xlYW4gewogICAgcHJvdG8gMyAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvY3J5cHRvLW9wcy9jb250cmFjdC5hbGdvLnRzOjQzCiAgICAvLyBlbnN1cmVCdWRnZXQoMTkwMCwgT3BVcEZlZVNvdXJjZS5Hcm91cENyZWRpdCkKICAgIHB1c2hpbnQgMTkwMCAvLyAxOTAwCiAgICBpbnRjXzAgLy8gMAogICAgY2FsbHN1YiBlbnN1cmVfYnVkZ2V0CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvY3J5cHRvLW9wcy9jb250cmFjdC5hbGdvLnRzOjQ0CiAgICAvLyBjb25zdCByZXN1bHQgPSBvcC5lZDI1NTE5dmVyaWZ5QmFyZShhLCBiLCBjKQogICAgZnJhbWVfZGlnIC0zCiAgICBmcmFtZV9kaWcgLTIKICAgIGZyYW1lX2RpZyAtMQogICAgZWQyNTUxOXZlcmlmeV9iYXJlCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvY3J5cHRvLW9wcy9jb250cmFjdC5hbGdvLnRzOjQ1CiAgICAvLyByZXR1cm4gcmVzdWx0CiAgICByZXRzdWIKCgovLyB0ZXN0cy9hcnRpZmFjdHMvY3J5cHRvLW9wcy9jb250cmFjdC5hbGdvLnRzOjpDcnlwdG9PcHNDb250cmFjdC52ZXJpZnlfZWNkc2FfdmVyaWZ5X2sxKGE6IGJ5dGVzLCBiOiBieXRlcywgYzogYnl0ZXMsIGQ6IGJ5dGVzLCBlOiBieXRlcykgLT4gdWludDY0Ogp2ZXJpZnlfZWNkc2FfdmVyaWZ5X2sxOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2NyeXB0by1vcHMvY29udHJhY3QuYWxnby50czo0OC00OQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIHB1YmxpYyB2ZXJpZnlfZWNkc2FfdmVyaWZ5X2sxKGE6IGJ5dGVzLCBiOiBieXRlcywgYzogYnl0ZXMsIGQ6IGJ5dGVzLCBlOiBieXRlcyk6IGJvb2xlYW4gewogICAgcHJvdG8gNSAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvY3J5cHRvLW9wcy9jb250cmFjdC5hbGdvLnRzOjUwCiAgICAvLyBlbnN1cmVCdWRnZXQoMzAwMCwgT3BVcEZlZVNvdXJjZS5Hcm91cENyZWRpdCkKICAgIGludGNfMyAvLyAzMDAwCiAgICBpbnRjXzAgLy8gMAogICAgY2FsbHN1YiBlbnN1cmVfYnVkZ2V0CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvY3J5cHRvLW9wcy9jb250cmFjdC5hbGdvLnRzOjUxCiAgICAvLyBjb25zdCByZXN1bHRfazEgPSBvcC5lY2RzYVZlcmlmeShFY2RzYS5TZWNwMjU2azEsIGEsIGIsIGMsIGQsIGUpCiAgICBmcmFtZV9kaWcgLTUKICAgIGZyYW1lX2RpZyAtNAogICAgZnJhbWVfZGlnIC0zCiAgICBmcmFtZV9kaWcgLTIKICAgIGZyYW1lX2RpZyAtMQogICAgZWNkc2FfdmVyaWZ5IFNlY3AyNTZrMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2NyeXB0by1vcHMvY29udHJhY3QuYWxnby50czo1MgogICAgLy8gcmV0dXJuIHJlc3VsdF9rMQogICAgcmV0c3ViCgoKLy8gdGVzdHMvYXJ0aWZhY3RzL2NyeXB0by1vcHMvY29udHJhY3QuYWxnby50czo6Q3J5cHRvT3BzQ29udHJhY3QudmVyaWZ5X2VjZHNhX3ZlcmlmeV9yMShhOiBieXRlcywgYjogYnl0ZXMsIGM6IGJ5dGVzLCBkOiBieXRlcywgZTogYnl0ZXMpIC0+IHVpbnQ2NDoKdmVyaWZ5X2VjZHNhX3ZlcmlmeV9yMToKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9jcnlwdG8tb3BzL2NvbnRyYWN0LmFsZ28udHM6NTUtNTYKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBwdWJsaWMgdmVyaWZ5X2VjZHNhX3ZlcmlmeV9yMShhOiBieXRlcywgYjogYnl0ZXMsIGM6IGJ5dGVzLCBkOiBieXRlcywgZTogYnl0ZXMpOiBib29sZWFuIHsKICAgIHByb3RvIDUgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2NyeXB0by1vcHMvY29udHJhY3QuYWxnby50czo1NwogICAgLy8gZW5zdXJlQnVkZ2V0KDMwMDAsIE9wVXBGZWVTb3VyY2UuR3JvdXBDcmVkaXQpCiAgICBpbnRjXzMgLy8gMzAwMAogICAgaW50Y18wIC8vIDAKICAgIGNhbGxzdWIgZW5zdXJlX2J1ZGdldAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2NyeXB0by1vcHMvY29udHJhY3QuYWxnby50czo1OAogICAgLy8gY29uc3QgcmVzdWx0X3IxID0gb3AuZWNkc2FWZXJpZnkoRWNkc2EuU2VjcDI1NnIxLCBhLCBiLCBjLCBkLCBlKQogICAgZnJhbWVfZGlnIC01CiAgICBmcmFtZV9kaWcgLTQKICAgIGZyYW1lX2RpZyAtMwogICAgZnJhbWVfZGlnIC0yCiAgICBmcmFtZV9kaWcgLTEKICAgIGVjZHNhX3ZlcmlmeSBTZWNwMjU2cjEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9jcnlwdG8tb3BzL2NvbnRyYWN0LmFsZ28udHM6NTkKICAgIC8vIHJldHVybiByZXN1bHRfcjEKICAgIHJldHN1YgoKCi8vIHRlc3RzL2FydGlmYWN0cy9jcnlwdG8tb3BzL2NvbnRyYWN0LmFsZ28udHM6OkNyeXB0b09wc0NvbnRyYWN0LnZlcmlmeV9lY2RzYV9yZWNvdmVyX2sxKGE6IGJ5dGVzLCBiOiB1aW50NjQsIGM6IGJ5dGVzLCBkOiBieXRlcykgLT4gYnl0ZXMsIGJ5dGVzOgp2ZXJpZnlfZWNkc2FfcmVjb3Zlcl9rMToKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9jcnlwdG8tb3BzL2NvbnRyYWN0LmFsZ28udHM6NjItNjMKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBwdWJsaWMgdmVyaWZ5X2VjZHNhX3JlY292ZXJfazEoYTogYnl0ZXMsIGI6IHVpbnQ2NCwgYzogYnl0ZXMsIGQ6IGJ5dGVzKTogcmVhZG9ubHkgW2J5dGVzLCBieXRlc10gewogICAgcHJvdG8gNCAyCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvY3J5cHRvLW9wcy9jb250cmFjdC5hbGdvLnRzOjY0CiAgICAvLyBlbnN1cmVCdWRnZXQoMzAwMCwgT3BVcEZlZVNvdXJjZS5Hcm91cENyZWRpdCkKICAgIGludGNfMyAvLyAzMDAwCiAgICBpbnRjXzAgLy8gMAogICAgY2FsbHN1YiBlbnN1cmVfYnVkZ2V0CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvY3J5cHRvLW9wcy9jb250cmFjdC5hbGdvLnRzOjY1CiAgICAvLyByZXR1cm4gb3AuZWNkc2FQa1JlY292ZXIoRWNkc2EuU2VjcDI1NmsxLCBhLCBiLCBjLCBkKQogICAgZnJhbWVfZGlnIC00CiAgICBmcmFtZV9kaWcgLTMKICAgIGZyYW1lX2RpZyAtMgogICAgZnJhbWVfZGlnIC0xCiAgICBlY2RzYV9wa19yZWNvdmVyIFNlY3AyNTZrMQogICAgcmV0c3ViCgoKLy8gdGVzdHMvYXJ0aWZhY3RzL2NyeXB0by1vcHMvY29udHJhY3QuYWxnby50czo6Q3J5cHRvT3BzQ29udHJhY3QudmVyaWZ5X2VjZHNhX3JlY292ZXJfcjEoYTogYnl0ZXMsIGI6IHVpbnQ2NCwgYzogYnl0ZXMsIGQ6IGJ5dGVzKSAtPiBieXRlcywgYnl0ZXM6CnZlcmlmeV9lY2RzYV9yZWNvdmVyX3IxOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2NyeXB0by1vcHMvY29udHJhY3QuYWxnby50czo2OC02OQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIHB1YmxpYyB2ZXJpZnlfZWNkc2FfcmVjb3Zlcl9yMShhOiBieXRlcywgYjogdWludDY0LCBjOiBieXRlcywgZDogYnl0ZXMpOiByZWFkb25seSBbYnl0ZXMsIGJ5dGVzXSB7CiAgICBwcm90byA0IDIKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9jcnlwdG8tb3BzL2NvbnRyYWN0LmFsZ28udHM6NzMKICAgIC8vIGVuc3VyZUJ1ZGdldCgzMDAwLCBPcFVwRmVlU291cmNlLkdyb3VwQ3JlZGl0KQogICAgaW50Y18zIC8vIDMwMDAKICAgIGludGNfMCAvLyAwCiAgICBjYWxsc3ViIGVuc3VyZV9idWRnZXQKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9jcnlwdG8tb3BzL2NvbnRyYWN0LmFsZ28udHM6NzQKICAgIC8vIHJldHVybiBvcC5lY2RzYVBrUmVjb3ZlcihFY2RzYS5TZWNwMjU2cjEsIGEsIGIsIGMsIGQpCiAgICBmcmFtZV9kaWcgLTQKICAgIGZyYW1lX2RpZyAtMwogICAgZnJhbWVfZGlnIC0yCiAgICBmcmFtZV9kaWcgLTEKICAgIGVjZHNhX3BrX3JlY292ZXIgU2VjcDI1NnIxCiAgICByZXRzdWIKCgovLyB0ZXN0cy9hcnRpZmFjdHMvY3J5cHRvLW9wcy9jb250cmFjdC5hbGdvLnRzOjpDcnlwdG9PcHNDb250cmFjdC52ZXJpZnlfZWNkc2FfZGVjb21wcmVzc19rMShhOiBieXRlcykgLT4gYnl0ZXMsIGJ5dGVzOgp2ZXJpZnlfZWNkc2FfZGVjb21wcmVzc19rMToKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9jcnlwdG8tb3BzL2NvbnRyYWN0LmFsZ28udHM6NzctNzgKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBwdWJsaWMgdmVyaWZ5X2VjZHNhX2RlY29tcHJlc3NfazEoYTogYnl0ZXMpOiByZWFkb25seSBbYnl0ZXMsIGJ5dGVzXSB7CiAgICBwcm90byAxIDIKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9jcnlwdG8tb3BzL2NvbnRyYWN0LmFsZ28udHM6NzkKICAgIC8vIGVuc3VyZUJ1ZGdldCg3MDAsIE9wVXBGZWVTb3VyY2UuR3JvdXBDcmVkaXQpCiAgICBwdXNoaW50IDcwMCAvLyA3MDAKICAgIGludGNfMCAvLyAwCiAgICBjYWxsc3ViIGVuc3VyZV9idWRnZXQKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9jcnlwdG8tb3BzL2NvbnRyYWN0LmFsZ28udHM6ODAKICAgIC8vIHJldHVybiBvcC5lY2RzYVBrRGVjb21wcmVzcyhFY2RzYS5TZWNwMjU2azEsIGEpCiAgICBmcmFtZV9kaWcgLTEKICAgIGVjZHNhX3BrX2RlY29tcHJlc3MgU2VjcDI1NmsxCiAgICByZXRzdWIKCgovLyB0ZXN0cy9hcnRpZmFjdHMvY3J5cHRvLW9wcy9jb250cmFjdC5hbGdvLnRzOjpDcnlwdG9PcHNDb250cmFjdC52ZXJpZnlfZWNkc2FfZGVjb21wcmVzc19yMShhOiBieXRlcykgLT4gYnl0ZXMsIGJ5dGVzOgp2ZXJpZnlfZWNkc2FfZGVjb21wcmVzc19yMToKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9jcnlwdG8tb3BzL2NvbnRyYWN0LmFsZ28udHM6ODMtODQKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBwdWJsaWMgdmVyaWZ5X2VjZHNhX2RlY29tcHJlc3NfcjEoYTogYnl0ZXMpOiByZWFkb25seSBbYnl0ZXMsIGJ5dGVzXSB7CiAgICBwcm90byAxIDIKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9jcnlwdG8tb3BzL2NvbnRyYWN0LmFsZ28udHM6ODUKICAgIC8vIGVuc3VyZUJ1ZGdldCg3MDAsIE9wVXBGZWVTb3VyY2UuR3JvdXBDcmVkaXQpCiAgICBwdXNoaW50IDcwMCAvLyA3MDAKICAgIGludGNfMCAvLyAwCiAgICBjYWxsc3ViIGVuc3VyZV9idWRnZXQKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9jcnlwdG8tb3BzL2NvbnRyYWN0LmFsZ28udHM6ODYKICAgIC8vIHJldHVybiBvcC5lY2RzYVBrRGVjb21wcmVzcyhFY2RzYS5TZWNwMjU2cjEsIGEpCiAgICBmcmFtZV9kaWcgLTEKICAgIGVjZHNhX3BrX2RlY29tcHJlc3MgU2VjcDI1NnIxCiAgICByZXRzdWIKCgovLyB0ZXN0cy9hcnRpZmFjdHMvY3J5cHRvLW9wcy9jb250cmFjdC5hbGdvLnRzOjpDcnlwdG9PcHNDb250cmFjdC52ZXJpZnlfdnJmX3ZlcmlmeShhOiBieXRlcywgYjogYnl0ZXMsIGM6IGJ5dGVzKSAtPiBieXRlcywgdWludDY0Ogp2ZXJpZnlfdnJmX3ZlcmlmeToKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9jcnlwdG8tb3BzL2NvbnRyYWN0LmFsZ28udHM6ODktOTAKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBwdWJsaWMgdmVyaWZ5X3ZyZl92ZXJpZnkoYTogYnl0ZXMsIGI6IGJ5dGVzLCBjOiBieXRlcyk6IHJlYWRvbmx5IFtieXRlcywgYm9vbGVhbl0gewogICAgcHJvdG8gMyAyCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvY3J5cHRvLW9wcy9jb250cmFjdC5hbGdvLnRzOjkxCiAgICAvLyBlbnN1cmVCdWRnZXQoNTcwMCwgT3BVcEZlZVNvdXJjZS5Hcm91cENyZWRpdCkKICAgIHB1c2hpbnQgNTcwMCAvLyA1NzAwCiAgICBpbnRjXzAgLy8gMAogICAgY2FsbHN1YiBlbnN1cmVfYnVkZ2V0CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvY3J5cHRvLW9wcy9jb250cmFjdC5hbGdvLnRzOjkyCiAgICAvLyBjb25zdCByZXN1bHQgPSBvcC52cmZWZXJpZnkoVnJmVmVyaWZ5LlZyZkFsZ29yYW5kLCBhLCBiLCBjKQogICAgZnJhbWVfZGlnIC0zCiAgICBmcmFtZV9kaWcgLTIKICAgIGZyYW1lX2RpZyAtMQogICAgdnJmX3ZlcmlmeSBWcmZBbGdvcmFuZAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2NyeXB0by1vcHMvY29udHJhY3QuYWxnby50czo5MwogICAgLy8gcmV0dXJuIHJlc3VsdAogICAgcmV0c3ViCgoKLy8gX3B1eWFfbGliLnV0aWwuZW5zdXJlX2J1ZGdldChyZXF1aXJlZF9idWRnZXQ6IHVpbnQ2NCwgZmVlX3NvdXJjZTogdWludDY0KSAtPiB2b2lkOgplbnN1cmVfYnVkZ2V0OgogICAgcHJvdG8gMiAwCiAgICBmcmFtZV9kaWcgLTIKICAgIHB1c2hpbnQgMTAgLy8gMTAKICAgICsKCmVuc3VyZV9idWRnZXRfd2hpbGVfdG9wQDE6CiAgICBmcmFtZV9kaWcgMAogICAgZ2xvYmFsIE9wY29kZUJ1ZGdldAogICAgPgogICAgYnogZW5zdXJlX2J1ZGdldF9hZnRlcl93aGlsZUA3CiAgICBpdHhuX2JlZ2luCiAgICBwdXNoaW50IDYgLy8gYXBwbAogICAgaXR4bl9maWVsZCBUeXBlRW51bQogICAgcHVzaGludCA1IC8vIERlbGV0ZUFwcGxpY2F0aW9uCiAgICBpdHhuX2ZpZWxkIE9uQ29tcGxldGlvbgogICAgYnl0ZWNfMyAvLyAweDA2ODEwMQogICAgaXR4bl9maWVsZCBBcHByb3ZhbFByb2dyYW0KICAgIGJ5dGVjXzMgLy8gMHgwNjgxMDEKICAgIGl0eG5fZmllbGQgQ2xlYXJTdGF0ZVByb2dyYW0KICAgIGZyYW1lX2RpZyAtMQogICAgc3dpdGNoIGVuc3VyZV9idWRnZXRfc3dpdGNoX2Nhc2VfMEAzIGVuc3VyZV9idWRnZXRfc3dpdGNoX2Nhc2VfMUA0CiAgICBiIGVuc3VyZV9idWRnZXRfc3dpdGNoX2Nhc2VfbmV4dEA2CgplbnN1cmVfYnVkZ2V0X3N3aXRjaF9jYXNlXzBAMzoKICAgIGludGNfMCAvLyAwCiAgICBpdHhuX2ZpZWxkIEZlZQogICAgYiBlbnN1cmVfYnVkZ2V0X3N3aXRjaF9jYXNlX25leHRANgoKZW5zdXJlX2J1ZGdldF9zd2l0Y2hfY2FzZV8xQDQ6CiAgICBnbG9iYWwgTWluVHhuRmVlCiAgICBpdHhuX2ZpZWxkIEZlZQoKZW5zdXJlX2J1ZGdldF9zd2l0Y2hfY2FzZV9uZXh0QDY6CiAgICBpdHhuX3N1Ym1pdAogICAgYiBlbnN1cmVfYnVkZ2V0X3doaWxlX3RvcEAxCgplbnN1cmVfYnVkZ2V0X2FmdGVyX3doaWxlQDc6CiAgICByZXRzdWIK", - "clear": "I3ByYWdtYSB2ZXJzaW9uIDEwCgp0ZXN0cy9hcnRpZmFjdHMvY3J5cHRvLW9wcy9jb250cmFjdC5hbGdvLnRzOjpDcnlwdG9PcHNDb250cmFjdC5jbGVhclN0YXRlUHJvZ3JhbToKICAgIHB1c2hpbnQgMSAvLyAxCiAgICByZXR1cm4K" - }, - "state": { - "global": { - "num_byte_slices": 0, - "num_uints": 0 - }, - "local": { - "num_byte_slices": 0, - "num_uints": 0 - } - }, - "schema": { - "global": { - "declared": {}, - "reserved": {} - }, - "local": { - "declared": {}, - "reserved": {} - } - }, - "contract": { - "name": "CryptoOpsContract", - "methods": [ - { - "name": "verify_sha256", - "args": [ - { - "type": "byte[]", - "name": "a" - }, - { - "type": "uint64", - "name": "pad_size" - } - ], - "readonly": false, - "returns": { - "type": "byte[]" - } - }, - { - "name": "verify_sha3_256", - "args": [ - { - "type": "byte[]", - "name": "a" - }, - { - "type": "uint64", - "name": "pad_size" - } - ], - "readonly": false, - "returns": { - "type": "byte[]" - } - }, - { - "name": "verify_keccak_256", - "args": [ - { - "type": "byte[]", - "name": "a" - }, - { - "type": "uint64", - "name": "pad_size" - } - ], - "readonly": false, - "returns": { - "type": "byte[]" - } - }, - { - "name": "verify_sha512_256", - "args": [ - { - "type": "byte[]", - "name": "a" - }, - { - "type": "uint64", - "name": "pad_size" - } - ], - "readonly": false, - "returns": { - "type": "byte[]" - } - }, - { - "name": "verify_ed25519verify", - "args": [ - { - "type": "byte[]", - "name": "a" - }, - { - "type": "byte[]", - "name": "b" - }, - { - "type": "byte[]", - "name": "c" - } - ], - "readonly": false, - "returns": { - "type": "bool" - } - }, - { - "name": "verify_ed25519verify_bare", - "args": [ - { - "type": "byte[]", - "name": "a" - }, - { - "type": "byte[]", - "name": "b" - }, - { - "type": "byte[]", - "name": "c" - } - ], - "readonly": false, - "returns": { - "type": "bool" - } - }, - { - "name": "verify_ecdsa_verify_k1", - "args": [ - { - "type": "byte[]", - "name": "a" - }, - { - "type": "byte[]", - "name": "b" - }, - { - "type": "byte[]", - "name": "c" - }, - { - "type": "byte[]", - "name": "d" - }, - { - "type": "byte[]", - "name": "e" - } - ], - "readonly": false, - "returns": { - "type": "bool" - } - }, - { - "name": "verify_ecdsa_verify_r1", - "args": [ - { - "type": "byte[]", - "name": "a" - }, - { - "type": "byte[]", - "name": "b" - }, - { - "type": "byte[]", - "name": "c" - }, - { - "type": "byte[]", - "name": "d" - }, - { - "type": "byte[]", - "name": "e" - } - ], - "readonly": false, - "returns": { - "type": "bool" - } - }, - { - "name": "verify_ecdsa_recover_k1", - "args": [ - { - "type": "byte[]", - "name": "a" - }, - { - "type": "uint64", - "name": "b" - }, - { - "type": "byte[]", - "name": "c" - }, - { - "type": "byte[]", - "name": "d" - } - ], - "readonly": false, - "returns": { - "type": "(byte[],byte[])" - } - }, - { - "name": "verify_ecdsa_recover_r1", - "args": [ - { - "type": "byte[]", - "name": "a" - }, - { - "type": "uint64", - "name": "b" - }, - { - "type": "byte[]", - "name": "c" - }, - { - "type": "byte[]", - "name": "d" - } - ], - "readonly": false, - "returns": { - "type": "(byte[],byte[])" - } - }, - { - "name": "verify_ecdsa_decompress_k1", - "args": [ - { - "type": "byte[]", - "name": "a" - } - ], - "readonly": false, - "returns": { - "type": "(byte[],byte[])" - } - }, - { - "name": "verify_ecdsa_decompress_r1", - "args": [ - { - "type": "byte[]", - "name": "a" - } - ], - "readonly": false, - "returns": { - "type": "(byte[],byte[])" - } - }, - { - "name": "verify_vrf_verify", - "args": [ - { - "type": "byte[]", - "name": "a" - }, - { - "type": "byte[]", - "name": "b" - }, - { - "type": "byte[]", - "name": "c" - } - ], - "readonly": false, - "returns": { - "type": "(byte[],bool)" - } - } - ], - "networks": {} - }, - "bare_call_config": { - "no_op": "CREATE" - } -} \ No newline at end of file diff --git a/tests/artifacts/crypto-ops/data/CryptoOpsContract.arc56.json b/tests/artifacts/crypto-ops/data/CryptoOpsContract.arc56.json deleted file mode 100644 index 13d7f43..0000000 --- a/tests/artifacts/crypto-ops/data/CryptoOpsContract.arc56.json +++ /dev/null @@ -1,467 +0,0 @@ -{ - "name": "CryptoOpsContract", - "structs": {}, - "methods": [ - { - "name": "verify_sha256", - "args": [ - { - "type": "byte[]", - "name": "a" - }, - { - "type": "uint64", - "name": "pad_size" - } - ], - "returns": { - "type": "byte[]" - }, - "actions": { - "create": [], - "call": [ - "NoOp" - ] - }, - "readonly": false, - "events": [], - "recommendations": {} - }, - { - "name": "verify_sha3_256", - "args": [ - { - "type": "byte[]", - "name": "a" - }, - { - "type": "uint64", - "name": "pad_size" - } - ], - "returns": { - "type": "byte[]" - }, - "actions": { - "create": [], - "call": [ - "NoOp" - ] - }, - "readonly": false, - "events": [], - "recommendations": {} - }, - { - "name": "verify_keccak_256", - "args": [ - { - "type": "byte[]", - "name": "a" - }, - { - "type": "uint64", - "name": "pad_size" - } - ], - "returns": { - "type": "byte[]" - }, - "actions": { - "create": [], - "call": [ - "NoOp" - ] - }, - "readonly": false, - "events": [], - "recommendations": {} - }, - { - "name": "verify_sha512_256", - "args": [ - { - "type": "byte[]", - "name": "a" - }, - { - "type": "uint64", - "name": "pad_size" - } - ], - "returns": { - "type": "byte[]" - }, - "actions": { - "create": [], - "call": [ - "NoOp" - ] - }, - "readonly": false, - "events": [], - "recommendations": {} - }, - { - "name": "verify_ed25519verify", - "args": [ - { - "type": "byte[]", - "name": "a" - }, - { - "type": "byte[]", - "name": "b" - }, - { - "type": "byte[]", - "name": "c" - } - ], - "returns": { - "type": "bool" - }, - "actions": { - "create": [], - "call": [ - "NoOp" - ] - }, - "readonly": false, - "events": [], - "recommendations": {} - }, - { - "name": "verify_ed25519verify_bare", - "args": [ - { - "type": "byte[]", - "name": "a" - }, - { - "type": "byte[]", - "name": "b" - }, - { - "type": "byte[]", - "name": "c" - } - ], - "returns": { - "type": "bool" - }, - "actions": { - "create": [], - "call": [ - "NoOp" - ] - }, - "readonly": false, - "events": [], - "recommendations": {} - }, - { - "name": "verify_ecdsa_verify_k1", - "args": [ - { - "type": "byte[]", - "name": "a" - }, - { - "type": "byte[]", - "name": "b" - }, - { - "type": "byte[]", - "name": "c" - }, - { - "type": "byte[]", - "name": "d" - }, - { - "type": "byte[]", - "name": "e" - } - ], - "returns": { - "type": "bool" - }, - "actions": { - "create": [], - "call": [ - "NoOp" - ] - }, - "readonly": false, - "events": [], - "recommendations": {} - }, - { - "name": "verify_ecdsa_verify_r1", - "args": [ - { - "type": "byte[]", - "name": "a" - }, - { - "type": "byte[]", - "name": "b" - }, - { - "type": "byte[]", - "name": "c" - }, - { - "type": "byte[]", - "name": "d" - }, - { - "type": "byte[]", - "name": "e" - } - ], - "returns": { - "type": "bool" - }, - "actions": { - "create": [], - "call": [ - "NoOp" - ] - }, - "readonly": false, - "events": [], - "recommendations": {} - }, - { - "name": "verify_ecdsa_recover_k1", - "args": [ - { - "type": "byte[]", - "name": "a" - }, - { - "type": "uint64", - "name": "b" - }, - { - "type": "byte[]", - "name": "c" - }, - { - "type": "byte[]", - "name": "d" - } - ], - "returns": { - "type": "(byte[],byte[])" - }, - "actions": { - "create": [], - "call": [ - "NoOp" - ] - }, - "readonly": false, - "events": [], - "recommendations": {} - }, - { - "name": "verify_ecdsa_recover_r1", - "args": [ - { - "type": "byte[]", - "name": "a" - }, - { - "type": "uint64", - "name": "b" - }, - { - "type": "byte[]", - "name": "c" - }, - { - "type": "byte[]", - "name": "d" - } - ], - "returns": { - "type": "(byte[],byte[])" - }, - "actions": { - "create": [], - "call": [ - "NoOp" - ] - }, - "readonly": false, - "events": [], - "recommendations": {} - }, - { - "name": "verify_ecdsa_decompress_k1", - "args": [ - { - "type": "byte[]", - "name": "a" - } - ], - "returns": { - "type": "(byte[],byte[])" - }, - "actions": { - "create": [], - "call": [ - "NoOp" - ] - }, - "readonly": false, - "events": [], - "recommendations": {} - }, - { - "name": "verify_ecdsa_decompress_r1", - "args": [ - { - "type": "byte[]", - "name": "a" - } - ], - "returns": { - "type": "(byte[],byte[])" - }, - "actions": { - "create": [], - "call": [ - "NoOp" - ] - }, - "readonly": false, - "events": [], - "recommendations": {} - }, - { - "name": "verify_vrf_verify", - "args": [ - { - "type": "byte[]", - "name": "a" - }, - { - "type": "byte[]", - "name": "b" - }, - { - "type": "byte[]", - "name": "c" - } - ], - "returns": { - "type": "(byte[],bool)" - }, - "actions": { - "create": [], - "call": [ - "NoOp" - ] - }, - "readonly": false, - "events": [], - "recommendations": {} - } - ], - "arcs": [ - 22, - 28 - ], - "networks": {}, - "state": { - "schema": { - "global": { - "ints": 0, - "bytes": 0 - }, - "local": { - "ints": 0, - "bytes": 0 - } - }, - "keys": { - "global": {}, - "local": {}, - "box": {} - }, - "maps": { - "global": {}, - "local": {}, - "box": {} - } - }, - "bareActions": { - "create": [ - "NoOp" - ], - "call": [] - }, - "sourceInfo": { - "approval": { - "sourceInfo": [ - { - "pc": [ - 139, - 173, - 207, - 241, - 275, - 309, - 343, - 394, - 445, - 520, - 595, - 654, - 713 - ], - "errorMessage": "OnCompletion is not NoOp" - }, - { - "pc": [ - 775 - ], - "errorMessage": "can only call when creating" - }, - { - "pc": [ - 142, - 176, - 210, - 244, - 278, - 312, - 346, - 397, - 448, - 523, - 598, - 657, - 716 - ], - "errorMessage": "can only call when not creating" - } - ], - "pcOffsetMethod": "none" - }, - "clear": { - "sourceInfo": [], - "pcOffsetMethod": "none" - } - }, - "source": { - "approval": "I3ByYWdtYSB2ZXJzaW9uIDEwCgp0ZXN0cy9hcnRpZmFjdHMvY3J5cHRvLW9wcy9jb250cmFjdC5hbGdvLnRzOjpDcnlwdG9PcHNDb250cmFjdC5hcHByb3ZhbFByb2dyYW06CiAgICBpbnRjYmxvY2sgMCAxIDQgMzAwMAogICAgYnl0ZWNibG9jayAweDE1MWY3Yzc1IDB4MDAgMHgwMDA0IDB4MDY4MTAxCiAgICBjYWxsc3ViIF9fcHV5YV9hcmM0X3JvdXRlcl9fCiAgICByZXR1cm4KCgovLyB0ZXN0cy9hcnRpZmFjdHMvY3J5cHRvLW9wcy9jb250cmFjdC5hbGdvLnRzOjpDcnlwdG9PcHNDb250cmFjdC5fX3B1eWFfYXJjNF9yb3V0ZXJfXygpIC0+IHVpbnQ2NDoKX19wdXlhX2FyYzRfcm91dGVyX186CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvY3J5cHRvLW9wcy9jb250cmFjdC5hbGdvLnRzOjQKICAgIC8vIGV4cG9ydCBjbGFzcyBDcnlwdG9PcHNDb250cmFjdCBleHRlbmRzIGFyYzQuQ29udHJhY3QgewogICAgcHJvdG8gMCAxCiAgICB0eG4gTnVtQXBwQXJncwogICAgYnogX19wdXlhX2FyYzRfcm91dGVyX19fYmFyZV9yb3V0aW5nQDE3CiAgICBwdXNoYnl0ZXNzIDB4MzQ1NmM0YzMgMHhlODQ0MmI4NCAweDY1ZjU2N2FhIDB4MjU4NDU1YjEgMHgzNWFmMGYzOCAweDY1ODJjOTk3IDB4NjI5OGZmYmIgMHgzODg1YjU0ZiAweDIxNjRlMGJmIDB4NzU1Yjc5YTUgMHhmMDZiYjA3NyAweDEzM2Y4Y2NjIDB4MmY3YzY4YTkgLy8gbWV0aG9kICJ2ZXJpZnlfc2hhMjU2KGJ5dGVbXSx1aW50NjQpYnl0ZVtdIiwgbWV0aG9kICJ2ZXJpZnlfc2hhM18yNTYoYnl0ZVtdLHVpbnQ2NClieXRlW10iLCBtZXRob2QgInZlcmlmeV9rZWNjYWtfMjU2KGJ5dGVbXSx1aW50NjQpYnl0ZVtdIiwgbWV0aG9kICJ2ZXJpZnlfc2hhNTEyXzI1NihieXRlW10sdWludDY0KWJ5dGVbXSIsIG1ldGhvZCAidmVyaWZ5X2VkMjU1MTl2ZXJpZnkoYnl0ZVtdLGJ5dGVbXSxieXRlW10pYm9vbCIsIG1ldGhvZCAidmVyaWZ5X2VkMjU1MTl2ZXJpZnlfYmFyZShieXRlW10sYnl0ZVtdLGJ5dGVbXSlib29sIiwgbWV0aG9kICJ2ZXJpZnlfZWNkc2FfdmVyaWZ5X2sxKGJ5dGVbXSxieXRlW10sYnl0ZVtdLGJ5dGVbXSxieXRlW10pYm9vbCIsIG1ldGhvZCAidmVyaWZ5X2VjZHNhX3ZlcmlmeV9yMShieXRlW10sYnl0ZVtdLGJ5dGVbXSxieXRlW10sYnl0ZVtdKWJvb2wiLCBtZXRob2QgInZlcmlmeV9lY2RzYV9yZWNvdmVyX2sxKGJ5dGVbXSx1aW50NjQsYnl0ZVtdLGJ5dGVbXSkoYnl0ZVtdLGJ5dGVbXSkiLCBtZXRob2QgInZlcmlmeV9lY2RzYV9yZWNvdmVyX3IxKGJ5dGVbXSx1aW50NjQsYnl0ZVtdLGJ5dGVbXSkoYnl0ZVtdLGJ5dGVbXSkiLCBtZXRob2QgInZlcmlmeV9lY2RzYV9kZWNvbXByZXNzX2sxKGJ5dGVbXSkoYnl0ZVtdLGJ5dGVbXSkiLCBtZXRob2QgInZlcmlmeV9lY2RzYV9kZWNvbXByZXNzX3IxKGJ5dGVbXSkoYnl0ZVtdLGJ5dGVbXSkiLCBtZXRob2QgInZlcmlmeV92cmZfdmVyaWZ5KGJ5dGVbXSxieXRlW10sYnl0ZVtdKShieXRlW10sYm9vbCkiCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAwCiAgICBtYXRjaCBfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfc2hhMjU2X3JvdXRlQDIgX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X3NoYTNfMjU2X3JvdXRlQDMgX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2tlY2Nha18yNTZfcm91dGVANCBfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfc2hhNTEyXzI1Nl9yb3V0ZUA1IF9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9lZDI1NTE5dmVyaWZ5X3JvdXRlQDYgX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2VkMjU1MTl2ZXJpZnlfYmFyZV9yb3V0ZUA3IF9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9lY2RzYV92ZXJpZnlfazFfcm91dGVAOCBfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfZWNkc2FfdmVyaWZ5X3IxX3JvdXRlQDkgX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2VjZHNhX3JlY292ZXJfazFfcm91dGVAMTAgX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2VjZHNhX3JlY292ZXJfcjFfcm91dGVAMTEgX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2VjZHNhX2RlY29tcHJlc3NfazFfcm91dGVAMTIgX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2VjZHNhX2RlY29tcHJlc3NfcjFfcm91dGVAMTMgX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X3ZyZl92ZXJpZnlfcm91dGVAMTQKICAgIGludGNfMCAvLyAwCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9zaGEyNTZfcm91dGVAMjoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9jcnlwdG8tb3BzL2NvbnRyYWN0LmFsZ28udHM6NQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgbm90IE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gY2FuIG9ubHkgY2FsbCB3aGVuIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2NyeXB0by1vcHMvY29udHJhY3QuYWxnby50czo0CiAgICAvLyBleHBvcnQgY2xhc3MgQ3J5cHRvT3BzQ29udHJhY3QgZXh0ZW5kcyBhcmM0LkNvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGV4dHJhY3QgMiAwCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAyCiAgICBidG9pCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvY3J5cHRvLW9wcy9jb250cmFjdC5hbGdvLnRzOjUKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV9zaGEyNTYKICAgIGR1cAogICAgbGVuCiAgICBpdG9iCiAgICBleHRyYWN0IDYgMgogICAgc3dhcAogICAgY29uY2F0CiAgICBieXRlY18wIC8vIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnRjXzEgLy8gMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfc2hhM18yNTZfcm91dGVAMzoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9jcnlwdG8tb3BzL2NvbnRyYWN0LmFsZ28udHM6MTIKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIG5vdCBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGNhbiBvbmx5IGNhbGwgd2hlbiBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9jcnlwdG8tb3BzL2NvbnRyYWN0LmFsZ28udHM6NAogICAgLy8gZXhwb3J0IGNsYXNzIENyeXB0b09wc0NvbnRyYWN0IGV4dGVuZHMgYXJjNC5Db250cmFjdCB7CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBleHRyYWN0IDIgMAogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMgogICAgYnRvaQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2NyeXB0by1vcHMvY29udHJhY3QuYWxnby50czoxMgogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X3NoYTNfMjU2CiAgICBkdXAKICAgIGxlbgogICAgaXRvYgogICAgZXh0cmFjdCA2IDIKICAgIHN3YXAKICAgIGNvbmNhdAogICAgYnl0ZWNfMCAvLyAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50Y18xIC8vIDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2tlY2Nha18yNTZfcm91dGVANDoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9jcnlwdG8tb3BzL2NvbnRyYWN0LmFsZ28udHM6MTkKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIG5vdCBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGNhbiBvbmx5IGNhbGwgd2hlbiBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9jcnlwdG8tb3BzL2NvbnRyYWN0LmFsZ28udHM6NAogICAgLy8gZXhwb3J0IGNsYXNzIENyeXB0b09wc0NvbnRyYWN0IGV4dGVuZHMgYXJjNC5Db250cmFjdCB7CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBleHRyYWN0IDIgMAogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMgogICAgYnRvaQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2NyeXB0by1vcHMvY29udHJhY3QuYWxnby50czoxOQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X2tlY2Nha18yNTYKICAgIGR1cAogICAgbGVuCiAgICBpdG9iCiAgICBleHRyYWN0IDYgMgogICAgc3dhcAogICAgY29uY2F0CiAgICBieXRlY18wIC8vIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnRjXzEgLy8gMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfc2hhNTEyXzI1Nl9yb3V0ZUA1OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2NyeXB0by1vcHMvY29udHJhY3QuYWxnby50czoyNgogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgbm90IE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gY2FuIG9ubHkgY2FsbCB3aGVuIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2NyeXB0by1vcHMvY29udHJhY3QuYWxnby50czo0CiAgICAvLyBleHBvcnQgY2xhc3MgQ3J5cHRvT3BzQ29udHJhY3QgZXh0ZW5kcyBhcmM0LkNvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGV4dHJhY3QgMiAwCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAyCiAgICBidG9pCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvY3J5cHRvLW9wcy9jb250cmFjdC5hbGdvLnRzOjI2CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfc2hhNTEyXzI1NgogICAgZHVwCiAgICBsZW4KICAgIGl0b2IKICAgIGV4dHJhY3QgNiAyCiAgICBzd2FwCiAgICBjb25jYXQKICAgIGJ5dGVjXzAgLy8gMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludGNfMSAvLyAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9lZDI1NTE5dmVyaWZ5X3JvdXRlQDY6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvY3J5cHRvLW9wcy9jb250cmFjdC5hbGdvLnRzOjMzCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBub3QgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBjYW4gb25seSBjYWxsIHdoZW4gbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvY3J5cHRvLW9wcy9jb250cmFjdC5hbGdvLnRzOjQKICAgIC8vIGV4cG9ydCBjbGFzcyBDcnlwdG9PcHNDb250cmFjdCBleHRlbmRzIGFyYzQuQ29udHJhY3QgewogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgZXh0cmFjdCAyIDAKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDIKICAgIGV4dHJhY3QgMiAwCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAzCiAgICBleHRyYWN0IDIgMAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2NyeXB0by1vcHMvY29udHJhY3QuYWxnby50czozMwogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X2VkMjU1MTl2ZXJpZnkKICAgIGJ5dGVjXzAgLy8gMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludGNfMSAvLyAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9lZDI1NTE5dmVyaWZ5X2JhcmVfcm91dGVANzoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9jcnlwdG8tb3BzL2NvbnRyYWN0LmFsZ28udHM6NDAKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIG5vdCBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGNhbiBvbmx5IGNhbGwgd2hlbiBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9jcnlwdG8tb3BzL2NvbnRyYWN0LmFsZ28udHM6NAogICAgLy8gZXhwb3J0IGNsYXNzIENyeXB0b09wc0NvbnRyYWN0IGV4dGVuZHMgYXJjNC5Db250cmFjdCB7CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBleHRyYWN0IDIgMAogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMgogICAgZXh0cmFjdCAyIDAKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDMKICAgIGV4dHJhY3QgMiAwCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvY3J5cHRvLW9wcy9jb250cmFjdC5hbGdvLnRzOjQwCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfZWQyNTUxOXZlcmlmeV9iYXJlCiAgICBieXRlY18wIC8vIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnRjXzEgLy8gMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfZWNkc2FfdmVyaWZ5X2sxX3JvdXRlQDg6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvY3J5cHRvLW9wcy9jb250cmFjdC5hbGdvLnRzOjQ3CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBub3QgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBjYW4gb25seSBjYWxsIHdoZW4gbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvY3J5cHRvLW9wcy9jb250cmFjdC5hbGdvLnRzOjQKICAgIC8vIGV4cG9ydCBjbGFzcyBDcnlwdG9PcHNDb250cmFjdCBleHRlbmRzIGFyYzQuQ29udHJhY3QgewogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgZXh0cmFjdCAyIDAKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDIKICAgIGV4dHJhY3QgMiAwCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAzCiAgICBleHRyYWN0IDIgMAogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgNAogICAgZXh0cmFjdCAyIDAKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDUKICAgIGV4dHJhY3QgMiAwCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvY3J5cHRvLW9wcy9jb250cmFjdC5hbGdvLnRzOjQ3CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfZWNkc2FfdmVyaWZ5X2sxCiAgICBieXRlY18xIC8vIDB4MDAKICAgIGludGNfMCAvLyAwCiAgICB1bmNvdmVyIDIKICAgIHNldGJpdAogICAgYnl0ZWNfMCAvLyAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50Y18xIC8vIDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2VjZHNhX3ZlcmlmeV9yMV9yb3V0ZUA5OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2NyeXB0by1vcHMvY29udHJhY3QuYWxnby50czo1NAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgbm90IE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gY2FuIG9ubHkgY2FsbCB3aGVuIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2NyeXB0by1vcHMvY29udHJhY3QuYWxnby50czo0CiAgICAvLyBleHBvcnQgY2xhc3MgQ3J5cHRvT3BzQ29udHJhY3QgZXh0ZW5kcyBhcmM0LkNvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGV4dHJhY3QgMiAwCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAyCiAgICBleHRyYWN0IDIgMAogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMwogICAgZXh0cmFjdCAyIDAKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDQKICAgIGV4dHJhY3QgMiAwCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyA1CiAgICBleHRyYWN0IDIgMAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2NyeXB0by1vcHMvY29udHJhY3QuYWxnby50czo1NAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X2VjZHNhX3ZlcmlmeV9yMQogICAgYnl0ZWNfMSAvLyAweDAwCiAgICBpbnRjXzAgLy8gMAogICAgdW5jb3ZlciAyCiAgICBzZXRiaXQKICAgIGJ5dGVjXzAgLy8gMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludGNfMSAvLyAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9lY2RzYV9yZWNvdmVyX2sxX3JvdXRlQDEwOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2NyeXB0by1vcHMvY29udHJhY3QuYWxnby50czo2MQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgbm90IE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gY2FuIG9ubHkgY2FsbCB3aGVuIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2NyeXB0by1vcHMvY29udHJhY3QuYWxnby50czo0CiAgICAvLyBleHBvcnQgY2xhc3MgQ3J5cHRvT3BzQ29udHJhY3QgZXh0ZW5kcyBhcmM0LkNvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGV4dHJhY3QgMiAwCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAyCiAgICBidG9pCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAzCiAgICBleHRyYWN0IDIgMAogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgNAogICAgZXh0cmFjdCAyIDAKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9jcnlwdG8tb3BzL2NvbnRyYWN0LmFsZ28udHM6NjEKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV9lY2RzYV9yZWNvdmVyX2sxCiAgICBkaWcgMQogICAgbGVuCiAgICBpdG9iCiAgICBleHRyYWN0IDYgMgogICAgdW5jb3ZlciAyCiAgICBjb25jYXQKICAgIGRpZyAxCiAgICBsZW4KICAgIGl0b2IKICAgIGV4dHJhY3QgNiAyCiAgICB1bmNvdmVyIDIKICAgIGNvbmNhdAogICAgZGlnIDEKICAgIGxlbgogICAgaW50Y18yIC8vIDQKICAgICsKICAgIGl0b2IKICAgIGV4dHJhY3QgNiAyCiAgICBieXRlY18yIC8vIDB4MDAwNAogICAgc3dhcAogICAgY29uY2F0CiAgICB1bmNvdmVyIDIKICAgIGNvbmNhdAogICAgc3dhcAogICAgY29uY2F0CiAgICBieXRlY18wIC8vIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnRjXzEgLy8gMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfZWNkc2FfcmVjb3Zlcl9yMV9yb3V0ZUAxMToKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9jcnlwdG8tb3BzL2NvbnRyYWN0LmFsZ28udHM6NjcKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIG5vdCBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGNhbiBvbmx5IGNhbGwgd2hlbiBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9jcnlwdG8tb3BzL2NvbnRyYWN0LmFsZ28udHM6NAogICAgLy8gZXhwb3J0IGNsYXNzIENyeXB0b09wc0NvbnRyYWN0IGV4dGVuZHMgYXJjNC5Db250cmFjdCB7CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBleHRyYWN0IDIgMAogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMgogICAgYnRvaQogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMwogICAgZXh0cmFjdCAyIDAKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDQKICAgIGV4dHJhY3QgMiAwCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvY3J5cHRvLW9wcy9jb250cmFjdC5hbGdvLnRzOjY3CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfZWNkc2FfcmVjb3Zlcl9yMQogICAgZGlnIDEKICAgIGxlbgogICAgaXRvYgogICAgZXh0cmFjdCA2IDIKICAgIHVuY292ZXIgMgogICAgY29uY2F0CiAgICBkaWcgMQogICAgbGVuCiAgICBpdG9iCiAgICBleHRyYWN0IDYgMgogICAgdW5jb3ZlciAyCiAgICBjb25jYXQKICAgIGRpZyAxCiAgICBsZW4KICAgIGludGNfMiAvLyA0CiAgICArCiAgICBpdG9iCiAgICBleHRyYWN0IDYgMgogICAgYnl0ZWNfMiAvLyAweDAwMDQKICAgIHN3YXAKICAgIGNvbmNhdAogICAgdW5jb3ZlciAyCiAgICBjb25jYXQKICAgIHN3YXAKICAgIGNvbmNhdAogICAgYnl0ZWNfMCAvLyAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50Y18xIC8vIDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2VjZHNhX2RlY29tcHJlc3NfazFfcm91dGVAMTI6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvY3J5cHRvLW9wcy9jb250cmFjdC5hbGdvLnRzOjc2CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBub3QgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBjYW4gb25seSBjYWxsIHdoZW4gbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvY3J5cHRvLW9wcy9jb250cmFjdC5hbGdvLnRzOjQKICAgIC8vIGV4cG9ydCBjbGFzcyBDcnlwdG9PcHNDb250cmFjdCBleHRlbmRzIGFyYzQuQ29udHJhY3QgewogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgZXh0cmFjdCAyIDAKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9jcnlwdG8tb3BzL2NvbnRyYWN0LmFsZ28udHM6NzYKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV9lY2RzYV9kZWNvbXByZXNzX2sxCiAgICBkaWcgMQogICAgbGVuCiAgICBpdG9iCiAgICBleHRyYWN0IDYgMgogICAgdW5jb3ZlciAyCiAgICBjb25jYXQKICAgIGRpZyAxCiAgICBsZW4KICAgIGl0b2IKICAgIGV4dHJhY3QgNiAyCiAgICB1bmNvdmVyIDIKICAgIGNvbmNhdAogICAgZGlnIDEKICAgIGxlbgogICAgaW50Y18yIC8vIDQKICAgICsKICAgIGl0b2IKICAgIGV4dHJhY3QgNiAyCiAgICBieXRlY18yIC8vIDB4MDAwNAogICAgc3dhcAogICAgY29uY2F0CiAgICB1bmNvdmVyIDIKICAgIGNvbmNhdAogICAgc3dhcAogICAgY29uY2F0CiAgICBieXRlY18wIC8vIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnRjXzEgLy8gMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfZWNkc2FfZGVjb21wcmVzc19yMV9yb3V0ZUAxMzoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9jcnlwdG8tb3BzL2NvbnRyYWN0LmFsZ28udHM6ODIKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIG5vdCBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGNhbiBvbmx5IGNhbGwgd2hlbiBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9jcnlwdG8tb3BzL2NvbnRyYWN0LmFsZ28udHM6NAogICAgLy8gZXhwb3J0IGNsYXNzIENyeXB0b09wc0NvbnRyYWN0IGV4dGVuZHMgYXJjNC5Db250cmFjdCB7CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBleHRyYWN0IDIgMAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2NyeXB0by1vcHMvY29udHJhY3QuYWxnby50czo4MgogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X2VjZHNhX2RlY29tcHJlc3NfcjEKICAgIGRpZyAxCiAgICBsZW4KICAgIGl0b2IKICAgIGV4dHJhY3QgNiAyCiAgICB1bmNvdmVyIDIKICAgIGNvbmNhdAogICAgZGlnIDEKICAgIGxlbgogICAgaXRvYgogICAgZXh0cmFjdCA2IDIKICAgIHVuY292ZXIgMgogICAgY29uY2F0CiAgICBkaWcgMQogICAgbGVuCiAgICBpbnRjXzIgLy8gNAogICAgKwogICAgaXRvYgogICAgZXh0cmFjdCA2IDIKICAgIGJ5dGVjXzIgLy8gMHgwMDA0CiAgICBzd2FwCiAgICBjb25jYXQKICAgIHVuY292ZXIgMgogICAgY29uY2F0CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGJ5dGVjXzAgLy8gMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludGNfMSAvLyAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV92cmZfdmVyaWZ5X3JvdXRlQDE0OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2NyeXB0by1vcHMvY29udHJhY3QuYWxnby50czo4OAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgbm90IE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gY2FuIG9ubHkgY2FsbCB3aGVuIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2NyeXB0by1vcHMvY29udHJhY3QuYWxnby50czo0CiAgICAvLyBleHBvcnQgY2xhc3MgQ3J5cHRvT3BzQ29udHJhY3QgZXh0ZW5kcyBhcmM0LkNvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGV4dHJhY3QgMiAwCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAyCiAgICBleHRyYWN0IDIgMAogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMwogICAgZXh0cmFjdCAyIDAKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9jcnlwdG8tb3BzL2NvbnRyYWN0LmFsZ28udHM6ODgKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV92cmZfdmVyaWZ5CiAgICBkaWcgMQogICAgbGVuCiAgICBpdG9iCiAgICBleHRyYWN0IDYgMgogICAgdW5jb3ZlciAyCiAgICBjb25jYXQKICAgIGJ5dGVjXzEgLy8gMHgwMAogICAgaW50Y18wIC8vIDAKICAgIHVuY292ZXIgMwogICAgc2V0Yml0CiAgICBwdXNoYnl0ZXMgMHgwMDAzCiAgICBzd2FwCiAgICBjb25jYXQKICAgIHN3YXAKICAgIGNvbmNhdAogICAgYnl0ZWNfMCAvLyAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50Y18xIC8vIDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fYmFyZV9yb3V0aW5nQDE3OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2NyeXB0by1vcHMvY29udHJhY3QuYWxnby50czo0CiAgICAvLyBleHBvcnQgY2xhc3MgQ3J5cHRvT3BzQ29udHJhY3QgZXh0ZW5kcyBhcmM0LkNvbnRyYWN0IHsKICAgIHR4biBPbkNvbXBsZXRpb24KICAgIGJueiBfX3B1eWFfYXJjNF9yb3V0ZXJfX19hZnRlcl9pZl9lbHNlQDIxCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgIQogICAgYXNzZXJ0IC8vIGNhbiBvbmx5IGNhbGwgd2hlbiBjcmVhdGluZwogICAgaW50Y18xIC8vIDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fYWZ0ZXJfaWZfZWxzZUAyMToKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9jcnlwdG8tb3BzL2NvbnRyYWN0LmFsZ28udHM6NAogICAgLy8gZXhwb3J0IGNsYXNzIENyeXB0b09wc0NvbnRyYWN0IGV4dGVuZHMgYXJjNC5Db250cmFjdCB7CiAgICBpbnRjXzAgLy8gMAogICAgcmV0c3ViCgoKLy8gdGVzdHMvYXJ0aWZhY3RzL2NyeXB0by1vcHMvY29udHJhY3QuYWxnby50czo6Q3J5cHRvT3BzQ29udHJhY3QudmVyaWZ5X3NoYTI1NihhOiBieXRlcywgcGFkX3NpemU6IHVpbnQ2NCkgLT4gYnl0ZXM6CnZlcmlmeV9zaGEyNTY6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvY3J5cHRvLW9wcy9jb250cmFjdC5hbGdvLnRzOjUtNgogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIHB1YmxpYyB2ZXJpZnlfc2hhMjU2KGE6IGJ5dGVzLCBwYWRfc2l6ZTogdWludDY0KTogYnl0ZXMgewogICAgcHJvdG8gMiAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvY3J5cHRvLW9wcy9jb250cmFjdC5hbGdvLnRzOjcKICAgIC8vIGNvbnN0IHBhZGRlZEEgPSBvcC5iemVybyhwYWRfc2l6ZSkuY29uY2F0KGEpCiAgICBmcmFtZV9kaWcgLTEKICAgIGJ6ZXJvCiAgICBmcmFtZV9kaWcgLTIKICAgIGNvbmNhdAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2NyeXB0by1vcHMvY29udHJhY3QuYWxnby50czo4CiAgICAvLyBjb25zdCByZXN1bHQgPSBvcC5zaGEyNTYocGFkZGVkQSkKICAgIHNoYTI1NgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2NyeXB0by1vcHMvY29udHJhY3QuYWxnby50czo5CiAgICAvLyByZXR1cm4gcmVzdWx0CiAgICByZXRzdWIKCgovLyB0ZXN0cy9hcnRpZmFjdHMvY3J5cHRvLW9wcy9jb250cmFjdC5hbGdvLnRzOjpDcnlwdG9PcHNDb250cmFjdC52ZXJpZnlfc2hhM18yNTYoYTogYnl0ZXMsIHBhZF9zaXplOiB1aW50NjQpIC0+IGJ5dGVzOgp2ZXJpZnlfc2hhM18yNTY6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvY3J5cHRvLW9wcy9jb250cmFjdC5hbGdvLnRzOjEyLTEzCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gcHVibGljIHZlcmlmeV9zaGEzXzI1NihhOiBieXRlcywgcGFkX3NpemU6IHVpbnQ2NCk6IGJ5dGVzIHsKICAgIHByb3RvIDIgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2NyeXB0by1vcHMvY29udHJhY3QuYWxnby50czoxNAogICAgLy8gY29uc3QgcGFkZGVkQSA9IG9wLmJ6ZXJvKHBhZF9zaXplKS5jb25jYXQoYSkKICAgIGZyYW1lX2RpZyAtMQogICAgYnplcm8KICAgIGZyYW1lX2RpZyAtMgogICAgY29uY2F0CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvY3J5cHRvLW9wcy9jb250cmFjdC5hbGdvLnRzOjE1CiAgICAvLyBjb25zdCByZXN1bHQgPSBvcC5zaGEzXzI1NihwYWRkZWRBKQogICAgc2hhM18yNTYKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9jcnlwdG8tb3BzL2NvbnRyYWN0LmFsZ28udHM6MTYKICAgIC8vIHJldHVybiByZXN1bHQKICAgIHJldHN1YgoKCi8vIHRlc3RzL2FydGlmYWN0cy9jcnlwdG8tb3BzL2NvbnRyYWN0LmFsZ28udHM6OkNyeXB0b09wc0NvbnRyYWN0LnZlcmlmeV9rZWNjYWtfMjU2KGE6IGJ5dGVzLCBwYWRfc2l6ZTogdWludDY0KSAtPiBieXRlczoKdmVyaWZ5X2tlY2Nha18yNTY6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvY3J5cHRvLW9wcy9jb250cmFjdC5hbGdvLnRzOjE5LTIwCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gcHVibGljIHZlcmlmeV9rZWNjYWtfMjU2KGE6IGJ5dGVzLCBwYWRfc2l6ZTogdWludDY0KTogYnl0ZXMgewogICAgcHJvdG8gMiAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvY3J5cHRvLW9wcy9jb250cmFjdC5hbGdvLnRzOjIxCiAgICAvLyBjb25zdCBwYWRkZWRBID0gb3AuYnplcm8ocGFkX3NpemUpLmNvbmNhdChhKQogICAgZnJhbWVfZGlnIC0xCiAgICBiemVybwogICAgZnJhbWVfZGlnIC0yCiAgICBjb25jYXQKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9jcnlwdG8tb3BzL2NvbnRyYWN0LmFsZ28udHM6MjIKICAgIC8vIGNvbnN0IHJlc3VsdCA9IG9wLmtlY2NhazI1NihwYWRkZWRBKQogICAga2VjY2FrMjU2CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvY3J5cHRvLW9wcy9jb250cmFjdC5hbGdvLnRzOjIzCiAgICAvLyByZXR1cm4gcmVzdWx0CiAgICByZXRzdWIKCgovLyB0ZXN0cy9hcnRpZmFjdHMvY3J5cHRvLW9wcy9jb250cmFjdC5hbGdvLnRzOjpDcnlwdG9PcHNDb250cmFjdC52ZXJpZnlfc2hhNTEyXzI1NihhOiBieXRlcywgcGFkX3NpemU6IHVpbnQ2NCkgLT4gYnl0ZXM6CnZlcmlmeV9zaGE1MTJfMjU2OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2NyeXB0by1vcHMvY29udHJhY3QuYWxnby50czoyNi0yNwogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIHB1YmxpYyB2ZXJpZnlfc2hhNTEyXzI1NihhOiBieXRlcywgcGFkX3NpemU6IHVpbnQ2NCk6IGJ5dGVzIHsKICAgIHByb3RvIDIgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2NyeXB0by1vcHMvY29udHJhY3QuYWxnby50czoyOAogICAgLy8gY29uc3QgcGFkZGVkQSA9IG9wLmJ6ZXJvKHBhZF9zaXplKS5jb25jYXQoYSkKICAgIGZyYW1lX2RpZyAtMQogICAgYnplcm8KICAgIGZyYW1lX2RpZyAtMgogICAgY29uY2F0CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvY3J5cHRvLW9wcy9jb250cmFjdC5hbGdvLnRzOjI5CiAgICAvLyBjb25zdCByZXN1bHQgPSBvcC5zaGE1MTJfMjU2KHBhZGRlZEEpCiAgICBzaGE1MTJfMjU2CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvY3J5cHRvLW9wcy9jb250cmFjdC5hbGdvLnRzOjMwCiAgICAvLyByZXR1cm4gcmVzdWx0CiAgICByZXRzdWIKCgovLyB0ZXN0cy9hcnRpZmFjdHMvY3J5cHRvLW9wcy9jb250cmFjdC5hbGdvLnRzOjpDcnlwdG9PcHNDb250cmFjdC52ZXJpZnlfZWQyNTUxOXZlcmlmeShhOiBieXRlcywgYjogYnl0ZXMsIGM6IGJ5dGVzKSAtPiBieXRlczoKdmVyaWZ5X2VkMjU1MTl2ZXJpZnk6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvY3J5cHRvLW9wcy9jb250cmFjdC5hbGdvLnRzOjMzLTM0CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gcHVibGljIHZlcmlmeV9lZDI1NTE5dmVyaWZ5KGE6IGJ5dGVzLCBiOiBieXRlcywgYzogYnl0ZXMpOiBCb29sIHsKICAgIHByb3RvIDMgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2NyeXB0by1vcHMvY29udHJhY3QuYWxnby50czozNQogICAgLy8gZW5zdXJlQnVkZ2V0KDE5MDAsIE9wVXBGZWVTb3VyY2UuR3JvdXBDcmVkaXQpCiAgICBwdXNoaW50IDE5MDAgLy8gMTkwMAogICAgaW50Y18wIC8vIDAKICAgIGNhbGxzdWIgZW5zdXJlX2J1ZGdldAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2NyeXB0by1vcHMvY29udHJhY3QuYWxnby50czozNgogICAgLy8gY29uc3QgcmVzdWx0ID0gb3AuZWQyNTUxOXZlcmlmeShhLCBiLCBjKQogICAgZnJhbWVfZGlnIC0zCiAgICBmcmFtZV9kaWcgLTIKICAgIGZyYW1lX2RpZyAtMQogICAgZWQyNTUxOXZlcmlmeQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2NyeXB0by1vcHMvY29udHJhY3QuYWxnby50czozNwogICAgLy8gcmV0dXJuIG5ldyBCb29sKHJlc3VsdCkKICAgIGJ5dGVjXzEgLy8gMHgwMAogICAgaW50Y18wIC8vIDAKICAgIHVuY292ZXIgMgogICAgc2V0Yml0CiAgICByZXRzdWIKCgovLyB0ZXN0cy9hcnRpZmFjdHMvY3J5cHRvLW9wcy9jb250cmFjdC5hbGdvLnRzOjpDcnlwdG9PcHNDb250cmFjdC52ZXJpZnlfZWQyNTUxOXZlcmlmeV9iYXJlKGE6IGJ5dGVzLCBiOiBieXRlcywgYzogYnl0ZXMpIC0+IGJ5dGVzOgp2ZXJpZnlfZWQyNTUxOXZlcmlmeV9iYXJlOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2NyeXB0by1vcHMvY29udHJhY3QuYWxnby50czo0MC00MQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIHB1YmxpYyB2ZXJpZnlfZWQyNTUxOXZlcmlmeV9iYXJlKGE6IGJ5dGVzLCBiOiBieXRlcywgYzogYnl0ZXMpOiBCb29sIHsKICAgIHByb3RvIDMgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2NyeXB0by1vcHMvY29udHJhY3QuYWxnby50czo0MgogICAgLy8gZW5zdXJlQnVkZ2V0KDIwMDAwMDAwMCwgT3BVcEZlZVNvdXJjZS5Hcm91cENyZWRpdCkKICAgIHB1c2hpbnQgMjAwMDAwMDAwIC8vIDIwMDAwMDAwMAogICAgaW50Y18wIC8vIDAKICAgIGNhbGxzdWIgZW5zdXJlX2J1ZGdldAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2NyeXB0by1vcHMvY29udHJhY3QuYWxnby50czo0MwogICAgLy8gY29uc3QgcmVzdWx0ID0gb3AuZWQyNTUxOXZlcmlmeUJhcmUoYSwgYiwgYykKICAgIGZyYW1lX2RpZyAtMwogICAgZnJhbWVfZGlnIC0yCiAgICBmcmFtZV9kaWcgLTEKICAgIGVkMjU1MTl2ZXJpZnlfYmFyZQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2NyeXB0by1vcHMvY29udHJhY3QuYWxnby50czo0NAogICAgLy8gcmV0dXJuIG5ldyBCb29sKHJlc3VsdCkKICAgIGJ5dGVjXzEgLy8gMHgwMAogICAgaW50Y18wIC8vIDAKICAgIHVuY292ZXIgMgogICAgc2V0Yml0CiAgICByZXRzdWIKCgovLyB0ZXN0cy9hcnRpZmFjdHMvY3J5cHRvLW9wcy9jb250cmFjdC5hbGdvLnRzOjpDcnlwdG9PcHNDb250cmFjdC52ZXJpZnlfZWNkc2FfdmVyaWZ5X2sxKGE6IGJ5dGVzLCBiOiBieXRlcywgYzogYnl0ZXMsIGQ6IGJ5dGVzLCBlOiBieXRlcykgLT4gdWludDY0Ogp2ZXJpZnlfZWNkc2FfdmVyaWZ5X2sxOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2NyeXB0by1vcHMvY29udHJhY3QuYWxnby50czo0Ny00OAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIHB1YmxpYyB2ZXJpZnlfZWNkc2FfdmVyaWZ5X2sxKGE6IGJ5dGVzLCBiOiBieXRlcywgYzogYnl0ZXMsIGQ6IGJ5dGVzLCBlOiBieXRlcyk6IGJvb2xlYW4gewogICAgcHJvdG8gNSAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvY3J5cHRvLW9wcy9jb250cmFjdC5hbGdvLnRzOjQ5CiAgICAvLyBlbnN1cmVCdWRnZXQoMzAwMCwgT3BVcEZlZVNvdXJjZS5Hcm91cENyZWRpdCkKICAgIGludGNfMyAvLyAzMDAwCiAgICBpbnRjXzAgLy8gMAogICAgY2FsbHN1YiBlbnN1cmVfYnVkZ2V0CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvY3J5cHRvLW9wcy9jb250cmFjdC5hbGdvLnRzOjUwCiAgICAvLyBjb25zdCByZXN1bHRfazEgPSBvcC5lY2RzYVZlcmlmeShFY2RzYS5TZWNwMjU2azEsIGEsIGIsIGMsIGQsIGUpCiAgICBmcmFtZV9kaWcgLTUKICAgIGZyYW1lX2RpZyAtNAogICAgZnJhbWVfZGlnIC0zCiAgICBmcmFtZV9kaWcgLTIKICAgIGZyYW1lX2RpZyAtMQogICAgZWNkc2FfdmVyaWZ5IFNlY3AyNTZrMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2NyeXB0by1vcHMvY29udHJhY3QuYWxnby50czo1MQogICAgLy8gcmV0dXJuIHJlc3VsdF9rMQogICAgcmV0c3ViCgoKLy8gdGVzdHMvYXJ0aWZhY3RzL2NyeXB0by1vcHMvY29udHJhY3QuYWxnby50czo6Q3J5cHRvT3BzQ29udHJhY3QudmVyaWZ5X2VjZHNhX3ZlcmlmeV9yMShhOiBieXRlcywgYjogYnl0ZXMsIGM6IGJ5dGVzLCBkOiBieXRlcywgZTogYnl0ZXMpIC0+IHVpbnQ2NDoKdmVyaWZ5X2VjZHNhX3ZlcmlmeV9yMToKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9jcnlwdG8tb3BzL2NvbnRyYWN0LmFsZ28udHM6NTQtNTUKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBwdWJsaWMgdmVyaWZ5X2VjZHNhX3ZlcmlmeV9yMShhOiBieXRlcywgYjogYnl0ZXMsIGM6IGJ5dGVzLCBkOiBieXRlcywgZTogYnl0ZXMpOiBib29sZWFuIHsKICAgIHByb3RvIDUgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2NyeXB0by1vcHMvY29udHJhY3QuYWxnby50czo1NgogICAgLy8gZW5zdXJlQnVkZ2V0KDMwMDAsIE9wVXBGZWVTb3VyY2UuR3JvdXBDcmVkaXQpCiAgICBpbnRjXzMgLy8gMzAwMAogICAgaW50Y18wIC8vIDAKICAgIGNhbGxzdWIgZW5zdXJlX2J1ZGdldAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2NyeXB0by1vcHMvY29udHJhY3QuYWxnby50czo1NwogICAgLy8gY29uc3QgcmVzdWx0X3IxID0gb3AuZWNkc2FWZXJpZnkoRWNkc2EuU2VjcDI1NnIxLCBhLCBiLCBjLCBkLCBlKQogICAgZnJhbWVfZGlnIC01CiAgICBmcmFtZV9kaWcgLTQKICAgIGZyYW1lX2RpZyAtMwogICAgZnJhbWVfZGlnIC0yCiAgICBmcmFtZV9kaWcgLTEKICAgIGVjZHNhX3ZlcmlmeSBTZWNwMjU2cjEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9jcnlwdG8tb3BzL2NvbnRyYWN0LmFsZ28udHM6NTgKICAgIC8vIHJldHVybiByZXN1bHRfcjEKICAgIHJldHN1YgoKCi8vIHRlc3RzL2FydGlmYWN0cy9jcnlwdG8tb3BzL2NvbnRyYWN0LmFsZ28udHM6OkNyeXB0b09wc0NvbnRyYWN0LnZlcmlmeV9lY2RzYV9yZWNvdmVyX2sxKGE6IGJ5dGVzLCBiOiB1aW50NjQsIGM6IGJ5dGVzLCBkOiBieXRlcykgLT4gYnl0ZXMsIGJ5dGVzOgp2ZXJpZnlfZWNkc2FfcmVjb3Zlcl9rMToKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9jcnlwdG8tb3BzL2NvbnRyYWN0LmFsZ28udHM6NjEtNjIKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBwdWJsaWMgdmVyaWZ5X2VjZHNhX3JlY292ZXJfazEoYTogYnl0ZXMsIGI6IHVpbnQ2NCwgYzogYnl0ZXMsIGQ6IGJ5dGVzKTogcmVhZG9ubHkgW2J5dGVzLCBieXRlc10gewogICAgcHJvdG8gNCAyCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvY3J5cHRvLW9wcy9jb250cmFjdC5hbGdvLnRzOjYzCiAgICAvLyBlbnN1cmVCdWRnZXQoMzAwMCwgT3BVcEZlZVNvdXJjZS5Hcm91cENyZWRpdCkKICAgIGludGNfMyAvLyAzMDAwCiAgICBpbnRjXzAgLy8gMAogICAgY2FsbHN1YiBlbnN1cmVfYnVkZ2V0CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvY3J5cHRvLW9wcy9jb250cmFjdC5hbGdvLnRzOjY0CiAgICAvLyByZXR1cm4gb3AuZWNkc2FQa1JlY292ZXIoRWNkc2EuU2VjcDI1NmsxLCBhLCBiLCBjLCBkKQogICAgZnJhbWVfZGlnIC00CiAgICBmcmFtZV9kaWcgLTMKICAgIGZyYW1lX2RpZyAtMgogICAgZnJhbWVfZGlnIC0xCiAgICBlY2RzYV9wa19yZWNvdmVyIFNlY3AyNTZrMQogICAgcmV0c3ViCgoKLy8gdGVzdHMvYXJ0aWZhY3RzL2NyeXB0by1vcHMvY29udHJhY3QuYWxnby50czo6Q3J5cHRvT3BzQ29udHJhY3QudmVyaWZ5X2VjZHNhX3JlY292ZXJfcjEoYTogYnl0ZXMsIGI6IHVpbnQ2NCwgYzogYnl0ZXMsIGQ6IGJ5dGVzKSAtPiBieXRlcywgYnl0ZXM6CnZlcmlmeV9lY2RzYV9yZWNvdmVyX3IxOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2NyeXB0by1vcHMvY29udHJhY3QuYWxnby50czo2Ny02OAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIHB1YmxpYyB2ZXJpZnlfZWNkc2FfcmVjb3Zlcl9yMShhOiBieXRlcywgYjogdWludDY0LCBjOiBieXRlcywgZDogYnl0ZXMpOiByZWFkb25seSBbYnl0ZXMsIGJ5dGVzXSB7CiAgICBwcm90byA0IDIKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9jcnlwdG8tb3BzL2NvbnRyYWN0LmFsZ28udHM6NzIKICAgIC8vIGVuc3VyZUJ1ZGdldCgzMDAwLCBPcFVwRmVlU291cmNlLkdyb3VwQ3JlZGl0KQogICAgaW50Y18zIC8vIDMwMDAKICAgIGludGNfMCAvLyAwCiAgICBjYWxsc3ViIGVuc3VyZV9idWRnZXQKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9jcnlwdG8tb3BzL2NvbnRyYWN0LmFsZ28udHM6NzMKICAgIC8vIHJldHVybiBvcC5lY2RzYVBrUmVjb3ZlcihFY2RzYS5TZWNwMjU2cjEsIGEsIGIsIGMsIGQpCiAgICBmcmFtZV9kaWcgLTQKICAgIGZyYW1lX2RpZyAtMwogICAgZnJhbWVfZGlnIC0yCiAgICBmcmFtZV9kaWcgLTEKICAgIGVjZHNhX3BrX3JlY292ZXIgU2VjcDI1NnIxCiAgICByZXRzdWIKCgovLyB0ZXN0cy9hcnRpZmFjdHMvY3J5cHRvLW9wcy9jb250cmFjdC5hbGdvLnRzOjpDcnlwdG9PcHNDb250cmFjdC52ZXJpZnlfZWNkc2FfZGVjb21wcmVzc19rMShhOiBieXRlcykgLT4gYnl0ZXMsIGJ5dGVzOgp2ZXJpZnlfZWNkc2FfZGVjb21wcmVzc19rMToKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9jcnlwdG8tb3BzL2NvbnRyYWN0LmFsZ28udHM6NzYtNzcKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBwdWJsaWMgdmVyaWZ5X2VjZHNhX2RlY29tcHJlc3NfazEoYTogYnl0ZXMpOiByZWFkb25seSBbYnl0ZXMsIGJ5dGVzXSB7CiAgICBwcm90byAxIDIKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9jcnlwdG8tb3BzL2NvbnRyYWN0LmFsZ28udHM6NzgKICAgIC8vIGVuc3VyZUJ1ZGdldCg3MDAsIE9wVXBGZWVTb3VyY2UuR3JvdXBDcmVkaXQpCiAgICBwdXNoaW50IDcwMCAvLyA3MDAKICAgIGludGNfMCAvLyAwCiAgICBjYWxsc3ViIGVuc3VyZV9idWRnZXQKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9jcnlwdG8tb3BzL2NvbnRyYWN0LmFsZ28udHM6NzkKICAgIC8vIHJldHVybiBvcC5lY2RzYVBrRGVjb21wcmVzcyhFY2RzYS5TZWNwMjU2azEsIGEpCiAgICBmcmFtZV9kaWcgLTEKICAgIGVjZHNhX3BrX2RlY29tcHJlc3MgU2VjcDI1NmsxCiAgICByZXRzdWIKCgovLyB0ZXN0cy9hcnRpZmFjdHMvY3J5cHRvLW9wcy9jb250cmFjdC5hbGdvLnRzOjpDcnlwdG9PcHNDb250cmFjdC52ZXJpZnlfZWNkc2FfZGVjb21wcmVzc19yMShhOiBieXRlcykgLT4gYnl0ZXMsIGJ5dGVzOgp2ZXJpZnlfZWNkc2FfZGVjb21wcmVzc19yMToKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9jcnlwdG8tb3BzL2NvbnRyYWN0LmFsZ28udHM6ODItODMKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBwdWJsaWMgdmVyaWZ5X2VjZHNhX2RlY29tcHJlc3NfcjEoYTogYnl0ZXMpOiByZWFkb25seSBbYnl0ZXMsIGJ5dGVzXSB7CiAgICBwcm90byAxIDIKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9jcnlwdG8tb3BzL2NvbnRyYWN0LmFsZ28udHM6ODQKICAgIC8vIGVuc3VyZUJ1ZGdldCg3MDAsIE9wVXBGZWVTb3VyY2UuR3JvdXBDcmVkaXQpCiAgICBwdXNoaW50IDcwMCAvLyA3MDAKICAgIGludGNfMCAvLyAwCiAgICBjYWxsc3ViIGVuc3VyZV9idWRnZXQKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9jcnlwdG8tb3BzL2NvbnRyYWN0LmFsZ28udHM6ODUKICAgIC8vIHJldHVybiBvcC5lY2RzYVBrRGVjb21wcmVzcyhFY2RzYS5TZWNwMjU2cjEsIGEpCiAgICBmcmFtZV9kaWcgLTEKICAgIGVjZHNhX3BrX2RlY29tcHJlc3MgU2VjcDI1NnIxCiAgICByZXRzdWIKCgovLyB0ZXN0cy9hcnRpZmFjdHMvY3J5cHRvLW9wcy9jb250cmFjdC5hbGdvLnRzOjpDcnlwdG9PcHNDb250cmFjdC52ZXJpZnlfdnJmX3ZlcmlmeShhOiBieXRlcywgYjogYnl0ZXMsIGM6IGJ5dGVzKSAtPiBieXRlcywgdWludDY0Ogp2ZXJpZnlfdnJmX3ZlcmlmeToKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9jcnlwdG8tb3BzL2NvbnRyYWN0LmFsZ28udHM6ODgtODkKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBwdWJsaWMgdmVyaWZ5X3ZyZl92ZXJpZnkoYTogYnl0ZXMsIGI6IGJ5dGVzLCBjOiBieXRlcyk6IHJlYWRvbmx5IFtieXRlcywgYm9vbGVhbl0gewogICAgcHJvdG8gMyAyCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvY3J5cHRvLW9wcy9jb250cmFjdC5hbGdvLnRzOjkwCiAgICAvLyBlbnN1cmVCdWRnZXQoNTcwMCwgT3BVcEZlZVNvdXJjZS5Hcm91cENyZWRpdCkKICAgIHB1c2hpbnQgNTcwMCAvLyA1NzAwCiAgICBpbnRjXzAgLy8gMAogICAgY2FsbHN1YiBlbnN1cmVfYnVkZ2V0CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvY3J5cHRvLW9wcy9jb250cmFjdC5hbGdvLnRzOjkxCiAgICAvLyBjb25zdCByZXN1bHQgPSBvcC52cmZWZXJpZnkoVnJmVmVyaWZ5LlZyZkFsZ29yYW5kLCBhLCBiLCBjKQogICAgZnJhbWVfZGlnIC0zCiAgICBmcmFtZV9kaWcgLTIKICAgIGZyYW1lX2RpZyAtMQogICAgdnJmX3ZlcmlmeSBWcmZBbGdvcmFuZAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2NyeXB0by1vcHMvY29udHJhY3QuYWxnby50czo5MgogICAgLy8gcmV0dXJuIHJlc3VsdAogICAgcmV0c3ViCgoKLy8gX3B1eWFfbGliLnV0aWwuZW5zdXJlX2J1ZGdldChyZXF1aXJlZF9idWRnZXQ6IHVpbnQ2NCwgZmVlX3NvdXJjZTogdWludDY0KSAtPiB2b2lkOgplbnN1cmVfYnVkZ2V0OgogICAgcHJvdG8gMiAwCiAgICBmcmFtZV9kaWcgLTIKICAgIHB1c2hpbnQgMTAgLy8gMTAKICAgICsKCmVuc3VyZV9idWRnZXRfd2hpbGVfdG9wQDE6CiAgICBmcmFtZV9kaWcgMAogICAgZ2xvYmFsIE9wY29kZUJ1ZGdldAogICAgPgogICAgYnogZW5zdXJlX2J1ZGdldF9hZnRlcl93aGlsZUA3CiAgICBpdHhuX2JlZ2luCiAgICBwdXNoaW50IDYgLy8gYXBwbAogICAgaXR4bl9maWVsZCBUeXBlRW51bQogICAgcHVzaGludCA1IC8vIERlbGV0ZUFwcGxpY2F0aW9uCiAgICBpdHhuX2ZpZWxkIE9uQ29tcGxldGlvbgogICAgYnl0ZWNfMyAvLyAweDA2ODEwMQogICAgaXR4bl9maWVsZCBBcHByb3ZhbFByb2dyYW0KICAgIGJ5dGVjXzMgLy8gMHgwNjgxMDEKICAgIGl0eG5fZmllbGQgQ2xlYXJTdGF0ZVByb2dyYW0KICAgIGZyYW1lX2RpZyAtMQogICAgc3dpdGNoIGVuc3VyZV9idWRnZXRfc3dpdGNoX2Nhc2VfMEAzIGVuc3VyZV9idWRnZXRfc3dpdGNoX2Nhc2VfMUA0CiAgICBiIGVuc3VyZV9idWRnZXRfc3dpdGNoX2Nhc2VfbmV4dEA2CgplbnN1cmVfYnVkZ2V0X3N3aXRjaF9jYXNlXzBAMzoKICAgIGludGNfMCAvLyAwCiAgICBpdHhuX2ZpZWxkIEZlZQogICAgYiBlbnN1cmVfYnVkZ2V0X3N3aXRjaF9jYXNlX25leHRANgoKZW5zdXJlX2J1ZGdldF9zd2l0Y2hfY2FzZV8xQDQ6CiAgICBnbG9iYWwgTWluVHhuRmVlCiAgICBpdHhuX2ZpZWxkIEZlZQoKZW5zdXJlX2J1ZGdldF9zd2l0Y2hfY2FzZV9uZXh0QDY6CiAgICBpdHhuX3N1Ym1pdAogICAgYiBlbnN1cmVfYnVkZ2V0X3doaWxlX3RvcEAxCgplbnN1cmVfYnVkZ2V0X2FmdGVyX3doaWxlQDc6CiAgICByZXRzdWIK", - "clear": "I3ByYWdtYSB2ZXJzaW9uIDEwCgp0ZXN0cy9hcnRpZmFjdHMvY3J5cHRvLW9wcy9jb250cmFjdC5hbGdvLnRzOjpDcnlwdG9PcHNDb250cmFjdC5jbGVhclN0YXRlUHJvZ3JhbToKICAgIHB1c2hpbnQgMSAvLyAxCiAgICByZXR1cm4K" - }, - "events": [], - "templateVariables": {} -} \ No newline at end of file diff --git a/tests/artifacts/crypto-ops/data/CryptoOpsContract.clear.teal b/tests/artifacts/crypto-ops/data/CryptoOpsContract.clear.teal deleted file mode 100644 index 6ee7565..0000000 --- a/tests/artifacts/crypto-ops/data/CryptoOpsContract.clear.teal +++ /dev/null @@ -1,5 +0,0 @@ -#pragma version 10 - -tests/artifacts/crypto-ops/contract.algo.ts::CryptoOpsContract.clearStateProgram: - pushint 1 // 1 - return diff --git a/tests/artifacts/miscellaneous-ops/contract.algo.ts b/tests/artifacts/miscellaneous-ops/contract.algo.ts index 9876d85..75c992e 100644 --- a/tests/artifacts/miscellaneous-ops/contract.algo.ts +++ b/tests/artifacts/miscellaneous-ops/contract.algo.ts @@ -1,4 +1,5 @@ -import { arc4, Base64, BigUint, Bytes, bytes, err, op, uint64 } from '@algorandfoundation/algorand-typescript' +import type { bytes, uint64 } from '@algorandfoundation/algorand-typescript' +import { arc4, Base64, BigUint, Bytes, err, op } from '@algorandfoundation/algorand-typescript' export class MiscellaneousOpsContract extends arc4.Contract { @arc4.abimethod() @@ -95,10 +96,9 @@ export class MiscellaneousOpsContract extends arc4.Contract { return result } - // TODO: recompile to check if this results in correct TEAL code @arc4.abimethod() public verify_extract_from_2(a: bytes): bytes { - const result = op.extract(a, 2, 0) + const result = op.extract(a, 2) return result } diff --git a/tests/artifacts/miscellaneous-ops/data/MiscellaneousOpsContract.approval.teal b/tests/artifacts/miscellaneous-ops/data/MiscellaneousOpsContract.approval.teal deleted file mode 100644 index a53da57..0000000 --- a/tests/artifacts/miscellaneous-ops/data/MiscellaneousOpsContract.approval.teal +++ /dev/null @@ -1,1578 +0,0 @@ -#pragma version 10 - -tests/artifacts/miscellaneous-ops/contract.algo.ts::MiscellaneousOpsContract.approvalProgram: - intcblock 1 0 - bytecblock 0x151f7c75 - callsub __puya_arc4_router__ - return - - -// tests/artifacts/miscellaneous-ops/contract.algo.ts::MiscellaneousOpsContract.__puya_arc4_router__() -> uint64: -__puya_arc4_router__: - // tests/artifacts/miscellaneous-ops/contract.algo.ts:3 - // export class MiscellaneousOpsContract extends arc4.Contract { - proto 0 1 - txn NumAppArgs - bz __puya_arc4_router___bare_routing@39 - pushbytess 0x45847eea 0xf57aceb5 0x7d631730 0xa1b24441 0xcd7be1ac 0x7cfda64b 0x54a910d9 0xc46568de 0x7a46a6ae 0x04372209 0x7e5f6d72 0x24ebcf84 0x9c0b3397 0x0ad40da4 0x95178870 0xdeedc99b 0xab2150bb 0x02a54017 0x3db66b41 0xc7ea8c2a 0x1dcea50c 0x16166f9a 0x2f472065 0xc58d30e0 0xd5a739c3 0x61f3b3e1 0x56cf368b 0x919ffbd2 0x8e30f4e7 0x89f81d92 0xd5260327 0x114c8c6d 0x39e9e62a 0xd6a4c05e 0x1ef8151a // method "verify_addw(uint64,uint64)(uint64,uint64)", method "verify_base64_decode_standard(byte[])byte[]", method "verify_base64_decode_url(byte[])byte[]", method "verify_bytes_bitlen(byte[],uint64)uint64", method "verify_uint64_bitlen(uint64)uint64", method "verify_bsqrt(byte[])byte[]", method "verify_btoi(byte[])uint64", method "verify_bzero(uint64)byte[]", method "verify_concat(byte[],byte[],uint64,uint64)byte[]", method "verify_divmodw(uint64,uint64,uint64,uint64)(uint64,uint64,uint64,uint64)", method "verify_divw(uint64,uint64,uint64)uint64", method "verify_err()void", method "verify_exp(uint64,uint64)uint64", method "verify_expw(uint64,uint64)(uint64,uint64)", method "verify_extract(byte[],uint64,uint64)byte[]", method "verify_extract_from_2(byte[])byte[]", method "verify_extract_uint16(byte[],uint64)uint64", method "verify_extract_uint32(byte[],uint64)uint64", method "verify_extract_uint64(byte[],uint64)uint64", method "verify_getbit_bytes(byte[],uint64)uint64", method "verify_getbit_uint64(uint64,uint64)uint64", method "verify_getbyte(byte[],uint64)uint64", method "verify_itob(uint64)byte[]", method "verify_bytes_len(byte[],uint64)uint64", method "verify_mulw(uint64,uint64)(uint64,uint64)", method "verify_replace(byte[],uint64,byte[])byte[]", method "verify_select_bytes(byte[],byte[],uint64)byte[]", method "verify_select_uint64(uint64,uint64,uint64)uint64", method "verify_setbit_bytes(byte[],uint64,uint64)byte[]", method "verify_setbit_uint64(uint64,uint64,uint64)uint64", method "verify_setbyte(byte[],uint64,uint64)byte[]", method "verify_shl(uint64,uint64)uint64", method "verify_shr(uint64,uint64)uint64", method "verify_sqrt(uint64)uint64", method "verify_substring(byte[],uint64,uint64)byte[]" - txna ApplicationArgs 0 - match __puya_arc4_router___verify_addw_route@2 __puya_arc4_router___verify_base64_decode_standard_route@3 __puya_arc4_router___verify_base64_decode_url_route@4 __puya_arc4_router___verify_bytes_bitlen_route@5 __puya_arc4_router___verify_uint64_bitlen_route@6 __puya_arc4_router___verify_bsqrt_route@7 __puya_arc4_router___verify_btoi_route@8 __puya_arc4_router___verify_bzero_route@9 __puya_arc4_router___verify_concat_route@10 __puya_arc4_router___verify_divmodw_route@11 __puya_arc4_router___verify_divw_route@12 __puya_arc4_router___verify_err_route@13 __puya_arc4_router___verify_exp_route@14 __puya_arc4_router___verify_expw_route@15 __puya_arc4_router___verify_extract_route@16 __puya_arc4_router___verify_extract_from_2_route@17 __puya_arc4_router___verify_extract_uint16_route@18 __puya_arc4_router___verify_extract_uint32_route@19 __puya_arc4_router___verify_extract_uint64_route@20 __puya_arc4_router___verify_getbit_bytes_route@21 __puya_arc4_router___verify_getbit_uint64_route@22 __puya_arc4_router___verify_getbyte_route@23 __puya_arc4_router___verify_itob_route@24 __puya_arc4_router___verify_bytes_len_route@25 __puya_arc4_router___verify_mulw_route@26 __puya_arc4_router___verify_replace_route@27 __puya_arc4_router___verify_select_bytes_route@28 __puya_arc4_router___verify_select_uint64_route@29 __puya_arc4_router___verify_setbit_bytes_route@30 __puya_arc4_router___verify_setbit_uint64_route@31 __puya_arc4_router___verify_setbyte_route@32 __puya_arc4_router___verify_shl_route@33 __puya_arc4_router___verify_shr_route@34 __puya_arc4_router___verify_sqrt_route@35 __puya_arc4_router___verify_substring_route@36 - intc_1 // 0 - retsub - -__puya_arc4_router___verify_addw_route@2: - // tests/artifacts/miscellaneous-ops/contract.algo.ts:4 - // @arc4.abimethod() - txn OnCompletion - ! - assert // OnCompletion is not NoOp - txn ApplicationID - assert // can only call when not creating - // tests/artifacts/miscellaneous-ops/contract.algo.ts:3 - // export class MiscellaneousOpsContract extends arc4.Contract { - txna ApplicationArgs 1 - btoi - txna ApplicationArgs 2 - btoi - // tests/artifacts/miscellaneous-ops/contract.algo.ts:4 - // @arc4.abimethod() - callsub verify_addw - swap - itob - swap - itob - concat - bytec_0 // 0x151f7c75 - swap - concat - log - intc_0 // 1 - retsub - -__puya_arc4_router___verify_base64_decode_standard_route@3: - // tests/artifacts/miscellaneous-ops/contract.algo.ts:10 - // @arc4.abimethod() - txn OnCompletion - ! - assert // OnCompletion is not NoOp - txn ApplicationID - assert // can only call when not creating - // tests/artifacts/miscellaneous-ops/contract.algo.ts:3 - // export class MiscellaneousOpsContract extends arc4.Contract { - txna ApplicationArgs 1 - extract 2 0 - // tests/artifacts/miscellaneous-ops/contract.algo.ts:10 - // @arc4.abimethod() - callsub verify_base64_decode_standard - dup - len - itob - extract 6 2 - swap - concat - bytec_0 // 0x151f7c75 - swap - concat - log - intc_0 // 1 - retsub - -__puya_arc4_router___verify_base64_decode_url_route@4: - // tests/artifacts/miscellaneous-ops/contract.algo.ts:16 - // @arc4.abimethod() - txn OnCompletion - ! - assert // OnCompletion is not NoOp - txn ApplicationID - assert // can only call when not creating - // tests/artifacts/miscellaneous-ops/contract.algo.ts:3 - // export class MiscellaneousOpsContract extends arc4.Contract { - txna ApplicationArgs 1 - extract 2 0 - // tests/artifacts/miscellaneous-ops/contract.algo.ts:16 - // @arc4.abimethod() - callsub verify_base64_decode_url - dup - len - itob - extract 6 2 - swap - concat - bytec_0 // 0x151f7c75 - swap - concat - log - intc_0 // 1 - retsub - -__puya_arc4_router___verify_bytes_bitlen_route@5: - // tests/artifacts/miscellaneous-ops/contract.algo.ts:22 - // @arc4.abimethod() - txn OnCompletion - ! - assert // OnCompletion is not NoOp - txn ApplicationID - assert // can only call when not creating - // tests/artifacts/miscellaneous-ops/contract.algo.ts:3 - // export class MiscellaneousOpsContract extends arc4.Contract { - txna ApplicationArgs 1 - extract 2 0 - txna ApplicationArgs 2 - btoi - // tests/artifacts/miscellaneous-ops/contract.algo.ts:22 - // @arc4.abimethod() - callsub verify_bytes_bitlen - itob - bytec_0 // 0x151f7c75 - swap - concat - log - intc_0 // 1 - retsub - -__puya_arc4_router___verify_uint64_bitlen_route@6: - // tests/artifacts/miscellaneous-ops/contract.algo.ts:29 - // @arc4.abimethod() - txn OnCompletion - ! - assert // OnCompletion is not NoOp - txn ApplicationID - assert // can only call when not creating - // tests/artifacts/miscellaneous-ops/contract.algo.ts:3 - // export class MiscellaneousOpsContract extends arc4.Contract { - txna ApplicationArgs 1 - btoi - // tests/artifacts/miscellaneous-ops/contract.algo.ts:29 - // @arc4.abimethod() - callsub verify_uint64_bitlen - itob - bytec_0 // 0x151f7c75 - swap - concat - log - intc_0 // 1 - retsub - -__puya_arc4_router___verify_bsqrt_route@7: - // tests/artifacts/miscellaneous-ops/contract.algo.ts:35 - // @arc4.abimethod() - txn OnCompletion - ! - assert // OnCompletion is not NoOp - txn ApplicationID - assert // can only call when not creating - // tests/artifacts/miscellaneous-ops/contract.algo.ts:3 - // export class MiscellaneousOpsContract extends arc4.Contract { - txna ApplicationArgs 1 - extract 2 0 - // tests/artifacts/miscellaneous-ops/contract.algo.ts:35 - // @arc4.abimethod() - callsub verify_bsqrt - dup - len - itob - extract 6 2 - swap - concat - bytec_0 // 0x151f7c75 - swap - concat - log - intc_0 // 1 - retsub - -__puya_arc4_router___verify_btoi_route@8: - // tests/artifacts/miscellaneous-ops/contract.algo.ts:42 - // @arc4.abimethod() - txn OnCompletion - ! - assert // OnCompletion is not NoOp - txn ApplicationID - assert // can only call when not creating - // tests/artifacts/miscellaneous-ops/contract.algo.ts:3 - // export class MiscellaneousOpsContract extends arc4.Contract { - txna ApplicationArgs 1 - extract 2 0 - // tests/artifacts/miscellaneous-ops/contract.algo.ts:42 - // @arc4.abimethod() - callsub verify_btoi - itob - bytec_0 // 0x151f7c75 - swap - concat - log - intc_0 // 1 - retsub - -__puya_arc4_router___verify_bzero_route@9: - // tests/artifacts/miscellaneous-ops/contract.algo.ts:48 - // @arc4.abimethod() - txn OnCompletion - ! - assert // OnCompletion is not NoOp - txn ApplicationID - assert // can only call when not creating - // tests/artifacts/miscellaneous-ops/contract.algo.ts:3 - // export class MiscellaneousOpsContract extends arc4.Contract { - txna ApplicationArgs 1 - btoi - // tests/artifacts/miscellaneous-ops/contract.algo.ts:48 - // @arc4.abimethod() - callsub verify_bzero - dup - len - itob - extract 6 2 - swap - concat - bytec_0 // 0x151f7c75 - swap - concat - log - intc_0 // 1 - retsub - -__puya_arc4_router___verify_concat_route@10: - // tests/artifacts/miscellaneous-ops/contract.algo.ts:54 - // @arc4.abimethod() - txn OnCompletion - ! - assert // OnCompletion is not NoOp - txn ApplicationID - assert // can only call when not creating - // tests/artifacts/miscellaneous-ops/contract.algo.ts:3 - // export class MiscellaneousOpsContract extends arc4.Contract { - txna ApplicationArgs 1 - extract 2 0 - txna ApplicationArgs 2 - extract 2 0 - txna ApplicationArgs 3 - btoi - txna ApplicationArgs 4 - btoi - // tests/artifacts/miscellaneous-ops/contract.algo.ts:54 - // @arc4.abimethod() - callsub verify_concat - dup - len - itob - extract 6 2 - swap - concat - bytec_0 // 0x151f7c75 - swap - concat - log - intc_0 // 1 - retsub - -__puya_arc4_router___verify_divmodw_route@11: - // tests/artifacts/miscellaneous-ops/contract.algo.ts:63 - // @arc4.abimethod() - txn OnCompletion - ! - assert // OnCompletion is not NoOp - txn ApplicationID - assert // can only call when not creating - // tests/artifacts/miscellaneous-ops/contract.algo.ts:3 - // export class MiscellaneousOpsContract extends arc4.Contract { - txna ApplicationArgs 1 - btoi - txna ApplicationArgs 2 - btoi - txna ApplicationArgs 3 - btoi - txna ApplicationArgs 4 - btoi - // tests/artifacts/miscellaneous-ops/contract.algo.ts:63 - // @arc4.abimethod() - callsub verify_divmodw - uncover 3 - itob - uncover 3 - itob - uncover 3 - itob - uncover 3 - itob - uncover 3 - uncover 3 - concat - uncover 2 - concat - swap - concat - bytec_0 // 0x151f7c75 - swap - concat - log - intc_0 // 1 - retsub - -__puya_arc4_router___verify_divw_route@12: - // tests/artifacts/miscellaneous-ops/contract.algo.ts:69 - // @arc4.abimethod() - txn OnCompletion - ! - assert // OnCompletion is not NoOp - txn ApplicationID - assert // can only call when not creating - // tests/artifacts/miscellaneous-ops/contract.algo.ts:3 - // export class MiscellaneousOpsContract extends arc4.Contract { - txna ApplicationArgs 1 - btoi - txna ApplicationArgs 2 - btoi - txna ApplicationArgs 3 - btoi - // tests/artifacts/miscellaneous-ops/contract.algo.ts:69 - // @arc4.abimethod() - callsub verify_divw - itob - bytec_0 // 0x151f7c75 - swap - concat - log - intc_0 // 1 - retsub - -__puya_arc4_router___verify_err_route@13: - // tests/artifacts/miscellaneous-ops/contract.algo.ts:75 - // @arc4.abimethod() - txn OnCompletion - ! - assert // OnCompletion is not NoOp - txn ApplicationID - assert // can only call when not creating - callsub verify_err - intc_0 // 1 - retsub - -__puya_arc4_router___verify_exp_route@14: - // tests/artifacts/miscellaneous-ops/contract.algo.ts:80 - // @arc4.abimethod() - txn OnCompletion - ! - assert // OnCompletion is not NoOp - txn ApplicationID - assert // can only call when not creating - // tests/artifacts/miscellaneous-ops/contract.algo.ts:3 - // export class MiscellaneousOpsContract extends arc4.Contract { - txna ApplicationArgs 1 - btoi - txna ApplicationArgs 2 - btoi - // tests/artifacts/miscellaneous-ops/contract.algo.ts:80 - // @arc4.abimethod() - callsub verify_exp - itob - bytec_0 // 0x151f7c75 - swap - concat - log - intc_0 // 1 - retsub - -__puya_arc4_router___verify_expw_route@15: - // tests/artifacts/miscellaneous-ops/contract.algo.ts:86 - // @arc4.abimethod() - txn OnCompletion - ! - assert // OnCompletion is not NoOp - txn ApplicationID - assert // can only call when not creating - // tests/artifacts/miscellaneous-ops/contract.algo.ts:3 - // export class MiscellaneousOpsContract extends arc4.Contract { - txna ApplicationArgs 1 - btoi - txna ApplicationArgs 2 - btoi - // tests/artifacts/miscellaneous-ops/contract.algo.ts:86 - // @arc4.abimethod() - callsub verify_expw - swap - itob - swap - itob - concat - bytec_0 // 0x151f7c75 - swap - concat - log - intc_0 // 1 - retsub - -__puya_arc4_router___verify_extract_route@16: - // tests/artifacts/miscellaneous-ops/contract.algo.ts:92 - // @arc4.abimethod() - txn OnCompletion - ! - assert // OnCompletion is not NoOp - txn ApplicationID - assert // can only call when not creating - // tests/artifacts/miscellaneous-ops/contract.algo.ts:3 - // export class MiscellaneousOpsContract extends arc4.Contract { - txna ApplicationArgs 1 - extract 2 0 - txna ApplicationArgs 2 - btoi - txna ApplicationArgs 3 - btoi - // tests/artifacts/miscellaneous-ops/contract.algo.ts:92 - // @arc4.abimethod() - callsub verify_extract - dup - len - itob - extract 6 2 - swap - concat - bytec_0 // 0x151f7c75 - swap - concat - log - intc_0 // 1 - retsub - -__puya_arc4_router___verify_extract_from_2_route@17: - // tests/artifacts/miscellaneous-ops/contract.algo.ts:99 - // @arc4.abimethod() - txn OnCompletion - ! - assert // OnCompletion is not NoOp - txn ApplicationID - assert // can only call when not creating - // tests/artifacts/miscellaneous-ops/contract.algo.ts:3 - // export class MiscellaneousOpsContract extends arc4.Contract { - txna ApplicationArgs 1 - extract 2 0 - // tests/artifacts/miscellaneous-ops/contract.algo.ts:99 - // @arc4.abimethod() - callsub verify_extract_from_2 - dup - len - itob - extract 6 2 - swap - concat - bytec_0 // 0x151f7c75 - swap - concat - log - intc_0 // 1 - retsub - -__puya_arc4_router___verify_extract_uint16_route@18: - // tests/artifacts/miscellaneous-ops/contract.algo.ts:105 - // @arc4.abimethod() - txn OnCompletion - ! - assert // OnCompletion is not NoOp - txn ApplicationID - assert // can only call when not creating - // tests/artifacts/miscellaneous-ops/contract.algo.ts:3 - // export class MiscellaneousOpsContract extends arc4.Contract { - txna ApplicationArgs 1 - extract 2 0 - txna ApplicationArgs 2 - btoi - // tests/artifacts/miscellaneous-ops/contract.algo.ts:105 - // @arc4.abimethod() - callsub verify_extract_uint16 - itob - bytec_0 // 0x151f7c75 - swap - concat - log - intc_0 // 1 - retsub - -__puya_arc4_router___verify_extract_uint32_route@19: - // tests/artifacts/miscellaneous-ops/contract.algo.ts:111 - // @arc4.abimethod() - txn OnCompletion - ! - assert // OnCompletion is not NoOp - txn ApplicationID - assert // can only call when not creating - // tests/artifacts/miscellaneous-ops/contract.algo.ts:3 - // export class MiscellaneousOpsContract extends arc4.Contract { - txna ApplicationArgs 1 - extract 2 0 - txna ApplicationArgs 2 - btoi - // tests/artifacts/miscellaneous-ops/contract.algo.ts:111 - // @arc4.abimethod() - callsub verify_extract_uint32 - itob - bytec_0 // 0x151f7c75 - swap - concat - log - intc_0 // 1 - retsub - -__puya_arc4_router___verify_extract_uint64_route@20: - // tests/artifacts/miscellaneous-ops/contract.algo.ts:117 - // @arc4.abimethod() - txn OnCompletion - ! - assert // OnCompletion is not NoOp - txn ApplicationID - assert // can only call when not creating - // tests/artifacts/miscellaneous-ops/contract.algo.ts:3 - // export class MiscellaneousOpsContract extends arc4.Contract { - txna ApplicationArgs 1 - extract 2 0 - txna ApplicationArgs 2 - btoi - // tests/artifacts/miscellaneous-ops/contract.algo.ts:117 - // @arc4.abimethod() - callsub verify_extract_uint64 - itob - bytec_0 // 0x151f7c75 - swap - concat - log - intc_0 // 1 - retsub - -__puya_arc4_router___verify_getbit_bytes_route@21: - // tests/artifacts/miscellaneous-ops/contract.algo.ts:123 - // @arc4.abimethod() - txn OnCompletion - ! - assert // OnCompletion is not NoOp - txn ApplicationID - assert // can only call when not creating - // tests/artifacts/miscellaneous-ops/contract.algo.ts:3 - // export class MiscellaneousOpsContract extends arc4.Contract { - txna ApplicationArgs 1 - extract 2 0 - txna ApplicationArgs 2 - btoi - // tests/artifacts/miscellaneous-ops/contract.algo.ts:123 - // @arc4.abimethod() - callsub verify_getbit_bytes - itob - bytec_0 // 0x151f7c75 - swap - concat - log - intc_0 // 1 - retsub - -__puya_arc4_router___verify_getbit_uint64_route@22: - // tests/artifacts/miscellaneous-ops/contract.algo.ts:129 - // @arc4.abimethod() - txn OnCompletion - ! - assert // OnCompletion is not NoOp - txn ApplicationID - assert // can only call when not creating - // tests/artifacts/miscellaneous-ops/contract.algo.ts:3 - // export class MiscellaneousOpsContract extends arc4.Contract { - txna ApplicationArgs 1 - btoi - txna ApplicationArgs 2 - btoi - // tests/artifacts/miscellaneous-ops/contract.algo.ts:129 - // @arc4.abimethod() - callsub verify_getbit_uint64 - itob - bytec_0 // 0x151f7c75 - swap - concat - log - intc_0 // 1 - retsub - -__puya_arc4_router___verify_getbyte_route@23: - // tests/artifacts/miscellaneous-ops/contract.algo.ts:135 - // @arc4.abimethod() - txn OnCompletion - ! - assert // OnCompletion is not NoOp - txn ApplicationID - assert // can only call when not creating - // tests/artifacts/miscellaneous-ops/contract.algo.ts:3 - // export class MiscellaneousOpsContract extends arc4.Contract { - txna ApplicationArgs 1 - extract 2 0 - txna ApplicationArgs 2 - btoi - // tests/artifacts/miscellaneous-ops/contract.algo.ts:135 - // @arc4.abimethod() - callsub verify_getbyte - itob - bytec_0 // 0x151f7c75 - swap - concat - log - intc_0 // 1 - retsub - -__puya_arc4_router___verify_itob_route@24: - // tests/artifacts/miscellaneous-ops/contract.algo.ts:141 - // @arc4.abimethod() - txn OnCompletion - ! - assert // OnCompletion is not NoOp - txn ApplicationID - assert // can only call when not creating - // tests/artifacts/miscellaneous-ops/contract.algo.ts:3 - // export class MiscellaneousOpsContract extends arc4.Contract { - txna ApplicationArgs 1 - btoi - // tests/artifacts/miscellaneous-ops/contract.algo.ts:141 - // @arc4.abimethod() - callsub verify_itob - dup - len - itob - extract 6 2 - swap - concat - bytec_0 // 0x151f7c75 - swap - concat - log - intc_0 // 1 - retsub - -__puya_arc4_router___verify_bytes_len_route@25: - // tests/artifacts/miscellaneous-ops/contract.algo.ts:147 - // @arc4.abimethod() - txn OnCompletion - ! - assert // OnCompletion is not NoOp - txn ApplicationID - assert // can only call when not creating - // tests/artifacts/miscellaneous-ops/contract.algo.ts:3 - // export class MiscellaneousOpsContract extends arc4.Contract { - txna ApplicationArgs 1 - extract 2 0 - txna ApplicationArgs 2 - btoi - // tests/artifacts/miscellaneous-ops/contract.algo.ts:147 - // @arc4.abimethod() - callsub verify_bytes_len - itob - bytec_0 // 0x151f7c75 - swap - concat - log - intc_0 // 1 - retsub - -__puya_arc4_router___verify_mulw_route@26: - // tests/artifacts/miscellaneous-ops/contract.algo.ts:154 - // @arc4.abimethod() - txn OnCompletion - ! - assert // OnCompletion is not NoOp - txn ApplicationID - assert // can only call when not creating - // tests/artifacts/miscellaneous-ops/contract.algo.ts:3 - // export class MiscellaneousOpsContract extends arc4.Contract { - txna ApplicationArgs 1 - btoi - txna ApplicationArgs 2 - btoi - // tests/artifacts/miscellaneous-ops/contract.algo.ts:154 - // @arc4.abimethod() - callsub verify_mulw - swap - itob - swap - itob - concat - bytec_0 // 0x151f7c75 - swap - concat - log - intc_0 // 1 - retsub - -__puya_arc4_router___verify_replace_route@27: - // tests/artifacts/miscellaneous-ops/contract.algo.ts:160 - // @arc4.abimethod() - txn OnCompletion - ! - assert // OnCompletion is not NoOp - txn ApplicationID - assert // can only call when not creating - // tests/artifacts/miscellaneous-ops/contract.algo.ts:3 - // export class MiscellaneousOpsContract extends arc4.Contract { - txna ApplicationArgs 1 - extract 2 0 - txna ApplicationArgs 2 - btoi - txna ApplicationArgs 3 - extract 2 0 - // tests/artifacts/miscellaneous-ops/contract.algo.ts:160 - // @arc4.abimethod() - callsub verify_replace - dup - len - itob - extract 6 2 - swap - concat - bytec_0 // 0x151f7c75 - swap - concat - log - intc_0 // 1 - retsub - -__puya_arc4_router___verify_select_bytes_route@28: - // tests/artifacts/miscellaneous-ops/contract.algo.ts:166 - // @arc4.abimethod() - txn OnCompletion - ! - assert // OnCompletion is not NoOp - txn ApplicationID - assert // can only call when not creating - // tests/artifacts/miscellaneous-ops/contract.algo.ts:3 - // export class MiscellaneousOpsContract extends arc4.Contract { - txna ApplicationArgs 1 - extract 2 0 - txna ApplicationArgs 2 - extract 2 0 - txna ApplicationArgs 3 - btoi - // tests/artifacts/miscellaneous-ops/contract.algo.ts:166 - // @arc4.abimethod() - callsub verify_select_bytes - dup - len - itob - extract 6 2 - swap - concat - bytec_0 // 0x151f7c75 - swap - concat - log - intc_0 // 1 - retsub - -__puya_arc4_router___verify_select_uint64_route@29: - // tests/artifacts/miscellaneous-ops/contract.algo.ts:172 - // @arc4.abimethod() - txn OnCompletion - ! - assert // OnCompletion is not NoOp - txn ApplicationID - assert // can only call when not creating - // tests/artifacts/miscellaneous-ops/contract.algo.ts:3 - // export class MiscellaneousOpsContract extends arc4.Contract { - txna ApplicationArgs 1 - btoi - txna ApplicationArgs 2 - btoi - txna ApplicationArgs 3 - btoi - // tests/artifacts/miscellaneous-ops/contract.algo.ts:172 - // @arc4.abimethod() - callsub verify_select_uint64 - itob - bytec_0 // 0x151f7c75 - swap - concat - log - intc_0 // 1 - retsub - -__puya_arc4_router___verify_setbit_bytes_route@30: - // tests/artifacts/miscellaneous-ops/contract.algo.ts:178 - // @arc4.abimethod() - txn OnCompletion - ! - assert // OnCompletion is not NoOp - txn ApplicationID - assert // can only call when not creating - // tests/artifacts/miscellaneous-ops/contract.algo.ts:3 - // export class MiscellaneousOpsContract extends arc4.Contract { - txna ApplicationArgs 1 - extract 2 0 - txna ApplicationArgs 2 - btoi - txna ApplicationArgs 3 - btoi - // tests/artifacts/miscellaneous-ops/contract.algo.ts:178 - // @arc4.abimethod() - callsub verify_setbit_bytes - dup - len - itob - extract 6 2 - swap - concat - bytec_0 // 0x151f7c75 - swap - concat - log - intc_0 // 1 - retsub - -__puya_arc4_router___verify_setbit_uint64_route@31: - // tests/artifacts/miscellaneous-ops/contract.algo.ts:184 - // @arc4.abimethod() - txn OnCompletion - ! - assert // OnCompletion is not NoOp - txn ApplicationID - assert // can only call when not creating - // tests/artifacts/miscellaneous-ops/contract.algo.ts:3 - // export class MiscellaneousOpsContract extends arc4.Contract { - txna ApplicationArgs 1 - btoi - txna ApplicationArgs 2 - btoi - txna ApplicationArgs 3 - btoi - // tests/artifacts/miscellaneous-ops/contract.algo.ts:184 - // @arc4.abimethod() - callsub verify_setbit_uint64 - itob - bytec_0 // 0x151f7c75 - swap - concat - log - intc_0 // 1 - retsub - -__puya_arc4_router___verify_setbyte_route@32: - // tests/artifacts/miscellaneous-ops/contract.algo.ts:190 - // @arc4.abimethod() - txn OnCompletion - ! - assert // OnCompletion is not NoOp - txn ApplicationID - assert // can only call when not creating - // tests/artifacts/miscellaneous-ops/contract.algo.ts:3 - // export class MiscellaneousOpsContract extends arc4.Contract { - txna ApplicationArgs 1 - extract 2 0 - txna ApplicationArgs 2 - btoi - txna ApplicationArgs 3 - btoi - // tests/artifacts/miscellaneous-ops/contract.algo.ts:190 - // @arc4.abimethod() - callsub verify_setbyte - dup - len - itob - extract 6 2 - swap - concat - bytec_0 // 0x151f7c75 - swap - concat - log - intc_0 // 1 - retsub - -__puya_arc4_router___verify_shl_route@33: - // tests/artifacts/miscellaneous-ops/contract.algo.ts:196 - // @arc4.abimethod() - txn OnCompletion - ! - assert // OnCompletion is not NoOp - txn ApplicationID - assert // can only call when not creating - // tests/artifacts/miscellaneous-ops/contract.algo.ts:3 - // export class MiscellaneousOpsContract extends arc4.Contract { - txna ApplicationArgs 1 - btoi - txna ApplicationArgs 2 - btoi - // tests/artifacts/miscellaneous-ops/contract.algo.ts:196 - // @arc4.abimethod() - callsub verify_shl - itob - bytec_0 // 0x151f7c75 - swap - concat - log - intc_0 // 1 - retsub - -__puya_arc4_router___verify_shr_route@34: - // tests/artifacts/miscellaneous-ops/contract.algo.ts:202 - // @arc4.abimethod() - txn OnCompletion - ! - assert // OnCompletion is not NoOp - txn ApplicationID - assert // can only call when not creating - // tests/artifacts/miscellaneous-ops/contract.algo.ts:3 - // export class MiscellaneousOpsContract extends arc4.Contract { - txna ApplicationArgs 1 - btoi - txna ApplicationArgs 2 - btoi - // tests/artifacts/miscellaneous-ops/contract.algo.ts:202 - // @arc4.abimethod() - callsub verify_shr - itob - bytec_0 // 0x151f7c75 - swap - concat - log - intc_0 // 1 - retsub - -__puya_arc4_router___verify_sqrt_route@35: - // tests/artifacts/miscellaneous-ops/contract.algo.ts:208 - // @arc4.abimethod() - txn OnCompletion - ! - assert // OnCompletion is not NoOp - txn ApplicationID - assert // can only call when not creating - // tests/artifacts/miscellaneous-ops/contract.algo.ts:3 - // export class MiscellaneousOpsContract extends arc4.Contract { - txna ApplicationArgs 1 - btoi - // tests/artifacts/miscellaneous-ops/contract.algo.ts:208 - // @arc4.abimethod() - callsub verify_sqrt - itob - bytec_0 // 0x151f7c75 - swap - concat - log - intc_0 // 1 - retsub - -__puya_arc4_router___verify_substring_route@36: - // tests/artifacts/miscellaneous-ops/contract.algo.ts:214 - // @arc4.abimethod() - txn OnCompletion - ! - assert // OnCompletion is not NoOp - txn ApplicationID - assert // can only call when not creating - // tests/artifacts/miscellaneous-ops/contract.algo.ts:3 - // export class MiscellaneousOpsContract extends arc4.Contract { - txna ApplicationArgs 1 - extract 2 0 - txna ApplicationArgs 2 - btoi - txna ApplicationArgs 3 - btoi - // tests/artifacts/miscellaneous-ops/contract.algo.ts:214 - // @arc4.abimethod() - callsub verify_substring - dup - len - itob - extract 6 2 - swap - concat - bytec_0 // 0x151f7c75 - swap - concat - log - intc_0 // 1 - retsub - -__puya_arc4_router___bare_routing@39: - // tests/artifacts/miscellaneous-ops/contract.algo.ts:3 - // export class MiscellaneousOpsContract extends arc4.Contract { - txn OnCompletion - bnz __puya_arc4_router___after_if_else@43 - txn ApplicationID - ! - assert // can only call when creating - intc_0 // 1 - retsub - -__puya_arc4_router___after_if_else@43: - // tests/artifacts/miscellaneous-ops/contract.algo.ts:3 - // export class MiscellaneousOpsContract extends arc4.Contract { - intc_1 // 0 - retsub - - -// tests/artifacts/miscellaneous-ops/contract.algo.ts::MiscellaneousOpsContract.verify_addw(a: uint64, b: uint64) -> uint64, uint64: -verify_addw: - // tests/artifacts/miscellaneous-ops/contract.algo.ts:4-5 - // @arc4.abimethod() - // public verify_addw(a: uint64, b: uint64): readonly [uint64, uint64] { - proto 2 2 - // tests/artifacts/miscellaneous-ops/contract.algo.ts:6 - // const result = op.addw(a, b) - frame_dig -2 - frame_dig -1 - addw - // tests/artifacts/miscellaneous-ops/contract.algo.ts:7 - // return result - retsub - - -// tests/artifacts/miscellaneous-ops/contract.algo.ts::MiscellaneousOpsContract.verify_base64_decode_standard(a: bytes) -> bytes: -verify_base64_decode_standard: - // tests/artifacts/miscellaneous-ops/contract.algo.ts:10-11 - // @arc4.abimethod() - // public verify_base64_decode_standard(a: bytes): bytes { - proto 1 1 - // tests/artifacts/miscellaneous-ops/contract.algo.ts:12 - // const result = op.base64Decode(Base64.StdEncoding, a) - frame_dig -1 - base64_decode StdEncoding - // tests/artifacts/miscellaneous-ops/contract.algo.ts:13 - // return result - retsub - - -// tests/artifacts/miscellaneous-ops/contract.algo.ts::MiscellaneousOpsContract.verify_base64_decode_url(a: bytes) -> bytes: -verify_base64_decode_url: - // tests/artifacts/miscellaneous-ops/contract.algo.ts:16-17 - // @arc4.abimethod() - // public verify_base64_decode_url(a: bytes): bytes { - proto 1 1 - // tests/artifacts/miscellaneous-ops/contract.algo.ts:18 - // const result = op.base64Decode(Base64.URLEncoding, a) - frame_dig -1 - base64_decode URLEncoding - // tests/artifacts/miscellaneous-ops/contract.algo.ts:19 - // return result - retsub - - -// tests/artifacts/miscellaneous-ops/contract.algo.ts::MiscellaneousOpsContract.verify_bytes_bitlen(a: bytes, pad_a_size: uint64) -> uint64: -verify_bytes_bitlen: - // tests/artifacts/miscellaneous-ops/contract.algo.ts:22-23 - // @arc4.abimethod() - // public verify_bytes_bitlen(a: bytes, pad_a_size: uint64): uint64 { - proto 2 1 - // tests/artifacts/miscellaneous-ops/contract.algo.ts:24 - // const paddedA = op.bzero(pad_a_size).concat(a) - frame_dig -1 - bzero - frame_dig -2 - concat - // tests/artifacts/miscellaneous-ops/contract.algo.ts:25 - // const result = op.bitLength(paddedA) - bitlen - // tests/artifacts/miscellaneous-ops/contract.algo.ts:26 - // return result - retsub - - -// tests/artifacts/miscellaneous-ops/contract.algo.ts::MiscellaneousOpsContract.verify_uint64_bitlen(a: uint64) -> uint64: -verify_uint64_bitlen: - // tests/artifacts/miscellaneous-ops/contract.algo.ts:29-30 - // @arc4.abimethod() - // public verify_uint64_bitlen(a: uint64): uint64 { - proto 1 1 - // tests/artifacts/miscellaneous-ops/contract.algo.ts:31 - // const result = op.bitLength(a) - frame_dig -1 - bitlen - // tests/artifacts/miscellaneous-ops/contract.algo.ts:32 - // return result - retsub - - -// tests/artifacts/miscellaneous-ops/contract.algo.ts::MiscellaneousOpsContract.verify_bsqrt(a: bytes) -> bytes: -verify_bsqrt: - // tests/artifacts/miscellaneous-ops/contract.algo.ts:35-36 - // @arc4.abimethod() - // public verify_bsqrt(a: bytes): bytes { - proto 1 1 - // tests/artifacts/miscellaneous-ops/contract.algo.ts:38 - // const result = op.bsqrt(a_biguint) - frame_dig -1 - bsqrt - // tests/artifacts/miscellaneous-ops/contract.algo.ts:39 - // return Bytes(result) - retsub - - -// tests/artifacts/miscellaneous-ops/contract.algo.ts::MiscellaneousOpsContract.verify_btoi(a: bytes) -> uint64: -verify_btoi: - // tests/artifacts/miscellaneous-ops/contract.algo.ts:42-43 - // @arc4.abimethod() - // public verify_btoi(a: bytes): uint64 { - proto 1 1 - // tests/artifacts/miscellaneous-ops/contract.algo.ts:44 - // const result = op.btoi(a) - frame_dig -1 - btoi - // tests/artifacts/miscellaneous-ops/contract.algo.ts:45 - // return result - retsub - - -// tests/artifacts/miscellaneous-ops/contract.algo.ts::MiscellaneousOpsContract.verify_bzero(a: uint64) -> bytes: -verify_bzero: - // tests/artifacts/miscellaneous-ops/contract.algo.ts:48-49 - // @arc4.abimethod() - // public verify_bzero(a: uint64): bytes { - proto 1 1 - // tests/artifacts/miscellaneous-ops/contract.algo.ts:50 - // const result = op.bzero(a) - frame_dig -1 - bzero - // tests/artifacts/miscellaneous-ops/contract.algo.ts:51 - // return op.sha256(result) - sha256 - retsub - - -// tests/artifacts/miscellaneous-ops/contract.algo.ts::MiscellaneousOpsContract.verify_concat(a: bytes, b: bytes, pad_a_size: uint64, pad_b_size: uint64) -> bytes: -verify_concat: - // tests/artifacts/miscellaneous-ops/contract.algo.ts:54-55 - // @arc4.abimethod() - // public verify_concat(a: bytes, b: bytes, pad_a_size: uint64, pad_b_size: uint64): bytes { - proto 4 1 - // tests/artifacts/miscellaneous-ops/contract.algo.ts:56 - // const paddedA = op.bzero(pad_a_size).concat(a) - frame_dig -2 - bzero - frame_dig -4 - concat - // tests/artifacts/miscellaneous-ops/contract.algo.ts:57 - // const paddedB = op.bzero(pad_b_size).concat(b) - frame_dig -1 - bzero - frame_dig -3 - concat - // tests/artifacts/miscellaneous-ops/contract.algo.ts:58 - // const result = paddedA.concat(paddedB) - concat - // tests/artifacts/miscellaneous-ops/contract.algo.ts:59 - // const resultHash = op.sha256(result) - sha256 - // tests/artifacts/miscellaneous-ops/contract.algo.ts:60 - // return resultHash - retsub - - -// tests/artifacts/miscellaneous-ops/contract.algo.ts::MiscellaneousOpsContract.verify_divmodw(a: uint64, b: uint64, c: uint64, d: uint64) -> uint64, uint64, uint64, uint64: -verify_divmodw: - // tests/artifacts/miscellaneous-ops/contract.algo.ts:63-64 - // @arc4.abimethod() - // public verify_divmodw(a: uint64, b: uint64, c: uint64, d: uint64): readonly [uint64, uint64, uint64, uint64] { - proto 4 4 - // tests/artifacts/miscellaneous-ops/contract.algo.ts:65 - // const result = op.divmodw(a, b, c, d) - frame_dig -4 - frame_dig -3 - frame_dig -2 - frame_dig -1 - divmodw - // tests/artifacts/miscellaneous-ops/contract.algo.ts:66 - // return result - retsub - - -// tests/artifacts/miscellaneous-ops/contract.algo.ts::MiscellaneousOpsContract.verify_divw(a: uint64, b: uint64, c: uint64) -> uint64: -verify_divw: - // tests/artifacts/miscellaneous-ops/contract.algo.ts:69-70 - // @arc4.abimethod() - // public verify_divw(a: uint64, b: uint64, c: uint64): uint64 { - proto 3 1 - // tests/artifacts/miscellaneous-ops/contract.algo.ts:71 - // const result = op.divw(a, b, c) - frame_dig -3 - frame_dig -2 - frame_dig -1 - divw - // tests/artifacts/miscellaneous-ops/contract.algo.ts:72 - // return result - retsub - - -// tests/artifacts/miscellaneous-ops/contract.algo.ts::MiscellaneousOpsContract.verify_err() -> void: -verify_err: - // tests/artifacts/miscellaneous-ops/contract.algo.ts:75-76 - // @arc4.abimethod() - // public verify_err(): void { - proto 0 0 - // tests/artifacts/miscellaneous-ops/contract.algo.ts:77 - // err() - err - - -// tests/artifacts/miscellaneous-ops/contract.algo.ts::MiscellaneousOpsContract.verify_exp(a: uint64, b: uint64) -> uint64: -verify_exp: - // tests/artifacts/miscellaneous-ops/contract.algo.ts:80-81 - // @arc4.abimethod() - // public verify_exp(a: uint64, b: uint64): uint64 { - proto 2 1 - // tests/artifacts/miscellaneous-ops/contract.algo.ts:82 - // const result = op.exp(a, b) - frame_dig -2 - frame_dig -1 - exp - // tests/artifacts/miscellaneous-ops/contract.algo.ts:83 - // return result - retsub - - -// tests/artifacts/miscellaneous-ops/contract.algo.ts::MiscellaneousOpsContract.verify_expw(a: uint64, b: uint64) -> uint64, uint64: -verify_expw: - // tests/artifacts/miscellaneous-ops/contract.algo.ts:86-87 - // @arc4.abimethod() - // public verify_expw(a: uint64, b: uint64): readonly [uint64, uint64] { - proto 2 2 - // tests/artifacts/miscellaneous-ops/contract.algo.ts:88 - // const result = op.expw(a, b) - frame_dig -2 - frame_dig -1 - expw - // tests/artifacts/miscellaneous-ops/contract.algo.ts:89 - // return result - retsub - - -// tests/artifacts/miscellaneous-ops/contract.algo.ts::MiscellaneousOpsContract.verify_extract(a: bytes, b: uint64, c: uint64) -> bytes: -verify_extract: - // tests/artifacts/miscellaneous-ops/contract.algo.ts:92-93 - // @arc4.abimethod() - // public verify_extract(a: bytes, b: uint64, c: uint64): bytes { - proto 3 1 - // tests/artifacts/miscellaneous-ops/contract.algo.ts:94 - // const result = op.extract(a, b, c) - frame_dig -3 - frame_dig -2 - frame_dig -1 - extract3 - // tests/artifacts/miscellaneous-ops/contract.algo.ts:95 - // return result - retsub - - -// tests/artifacts/miscellaneous-ops/contract.algo.ts::MiscellaneousOpsContract.verify_extract_from_2(a: bytes) -> bytes: -verify_extract_from_2: - // tests/artifacts/miscellaneous-ops/contract.algo.ts:99-100 - // @arc4.abimethod() - // public verify_extract_from_2(a: bytes): bytes { - proto 1 1 - // tests/artifacts/miscellaneous-ops/contract.algo.ts:101 - // const result = op.extract(a, 2, 0) - frame_dig -1 - extract 2 0 - // tests/artifacts/miscellaneous-ops/contract.algo.ts:102 - // return result - retsub - - -// tests/artifacts/miscellaneous-ops/contract.algo.ts::MiscellaneousOpsContract.verify_extract_uint16(a: bytes, b: uint64) -> uint64: -verify_extract_uint16: - // tests/artifacts/miscellaneous-ops/contract.algo.ts:105-106 - // @arc4.abimethod() - // public verify_extract_uint16(a: bytes, b: uint64): uint64 { - proto 2 1 - // tests/artifacts/miscellaneous-ops/contract.algo.ts:107 - // const result = op.extractUint16(a, b) - frame_dig -2 - frame_dig -1 - extract_uint16 - // tests/artifacts/miscellaneous-ops/contract.algo.ts:108 - // return result - retsub - - -// tests/artifacts/miscellaneous-ops/contract.algo.ts::MiscellaneousOpsContract.verify_extract_uint32(a: bytes, b: uint64) -> uint64: -verify_extract_uint32: - // tests/artifacts/miscellaneous-ops/contract.algo.ts:111-112 - // @arc4.abimethod() - // public verify_extract_uint32(a: bytes, b: uint64): uint64 { - proto 2 1 - // tests/artifacts/miscellaneous-ops/contract.algo.ts:113 - // const result = op.extractUint32(a, b) - frame_dig -2 - frame_dig -1 - extract_uint32 - // tests/artifacts/miscellaneous-ops/contract.algo.ts:114 - // return result - retsub - - -// tests/artifacts/miscellaneous-ops/contract.algo.ts::MiscellaneousOpsContract.verify_extract_uint64(a: bytes, b: uint64) -> uint64: -verify_extract_uint64: - // tests/artifacts/miscellaneous-ops/contract.algo.ts:117-118 - // @arc4.abimethod() - // public verify_extract_uint64(a: bytes, b: uint64): uint64 { - proto 2 1 - // tests/artifacts/miscellaneous-ops/contract.algo.ts:119 - // const result = op.extractUint64(a, b) - frame_dig -2 - frame_dig -1 - extract_uint64 - // tests/artifacts/miscellaneous-ops/contract.algo.ts:120 - // return result - retsub - - -// tests/artifacts/miscellaneous-ops/contract.algo.ts::MiscellaneousOpsContract.verify_getbit_bytes(a: bytes, b: uint64) -> uint64: -verify_getbit_bytes: - // tests/artifacts/miscellaneous-ops/contract.algo.ts:123-124 - // @arc4.abimethod() - // public verify_getbit_bytes(a: bytes, b: uint64): uint64 { - proto 2 1 - // tests/artifacts/miscellaneous-ops/contract.algo.ts:125 - // const result = op.getBit(a, b) - frame_dig -2 - frame_dig -1 - getbit - // tests/artifacts/miscellaneous-ops/contract.algo.ts:126 - // return result - retsub - - -// tests/artifacts/miscellaneous-ops/contract.algo.ts::MiscellaneousOpsContract.verify_getbit_uint64(a: uint64, b: uint64) -> uint64: -verify_getbit_uint64: - // tests/artifacts/miscellaneous-ops/contract.algo.ts:129-130 - // @arc4.abimethod() - // public verify_getbit_uint64(a: uint64, b: uint64): uint64 { - proto 2 1 - // tests/artifacts/miscellaneous-ops/contract.algo.ts:131 - // const result = op.getBit(a, b) - frame_dig -2 - frame_dig -1 - getbit - // tests/artifacts/miscellaneous-ops/contract.algo.ts:132 - // return result - retsub - - -// tests/artifacts/miscellaneous-ops/contract.algo.ts::MiscellaneousOpsContract.verify_getbyte(a: bytes, b: uint64) -> uint64: -verify_getbyte: - // tests/artifacts/miscellaneous-ops/contract.algo.ts:135-136 - // @arc4.abimethod() - // public verify_getbyte(a: bytes, b: uint64): uint64 { - proto 2 1 - // tests/artifacts/miscellaneous-ops/contract.algo.ts:137 - // const result = op.getByte(a, b) - frame_dig -2 - frame_dig -1 - getbyte - // tests/artifacts/miscellaneous-ops/contract.algo.ts:138 - // return result - retsub - - -// tests/artifacts/miscellaneous-ops/contract.algo.ts::MiscellaneousOpsContract.verify_itob(a: uint64) -> bytes: -verify_itob: - // tests/artifacts/miscellaneous-ops/contract.algo.ts:141-142 - // @arc4.abimethod() - // public verify_itob(a: uint64): bytes { - proto 1 1 - // tests/artifacts/miscellaneous-ops/contract.algo.ts:143 - // const result = op.itob(a) - frame_dig -1 - itob - // tests/artifacts/miscellaneous-ops/contract.algo.ts:144 - // return result - retsub - - -// tests/artifacts/miscellaneous-ops/contract.algo.ts::MiscellaneousOpsContract.verify_bytes_len(a: bytes, pad_a_size: uint64) -> uint64: -verify_bytes_len: - // tests/artifacts/miscellaneous-ops/contract.algo.ts:147-148 - // @arc4.abimethod() - // public verify_bytes_len(a: bytes, pad_a_size: uint64): uint64 { - proto 2 1 - // tests/artifacts/miscellaneous-ops/contract.algo.ts:149 - // const paddedA = op.bzero(pad_a_size).concat(a) - frame_dig -1 - bzero - frame_dig -2 - concat - // tests/artifacts/miscellaneous-ops/contract.algo.ts:150 - // const result = op.len(paddedA) - len - // tests/artifacts/miscellaneous-ops/contract.algo.ts:151 - // return result - retsub - - -// tests/artifacts/miscellaneous-ops/contract.algo.ts::MiscellaneousOpsContract.verify_mulw(a: uint64, b: uint64) -> uint64, uint64: -verify_mulw: - // tests/artifacts/miscellaneous-ops/contract.algo.ts:154-155 - // @arc4.abimethod() - // public verify_mulw(a: uint64, b: uint64): readonly [uint64, uint64] { - proto 2 2 - // tests/artifacts/miscellaneous-ops/contract.algo.ts:156 - // const result = op.mulw(a, b) - frame_dig -2 - frame_dig -1 - mulw - // tests/artifacts/miscellaneous-ops/contract.algo.ts:157 - // return result - retsub - - -// tests/artifacts/miscellaneous-ops/contract.algo.ts::MiscellaneousOpsContract.verify_replace(a: bytes, b: uint64, c: bytes) -> bytes: -verify_replace: - // tests/artifacts/miscellaneous-ops/contract.algo.ts:160-161 - // @arc4.abimethod() - // public verify_replace(a: bytes, b: uint64, c: bytes): bytes { - proto 3 1 - // tests/artifacts/miscellaneous-ops/contract.algo.ts:162 - // const result = op.replace(a, b, c) - frame_dig -3 - frame_dig -2 - frame_dig -1 - replace3 - // tests/artifacts/miscellaneous-ops/contract.algo.ts:163 - // return result - retsub - - -// tests/artifacts/miscellaneous-ops/contract.algo.ts::MiscellaneousOpsContract.verify_select_bytes(a: bytes, b: bytes, c: uint64) -> bytes: -verify_select_bytes: - // tests/artifacts/miscellaneous-ops/contract.algo.ts:166-167 - // @arc4.abimethod() - // public verify_select_bytes(a: bytes, b: bytes, c: uint64): bytes { - proto 3 1 - // tests/artifacts/miscellaneous-ops/contract.algo.ts:168 - // const result = op.select(a, b, c) - frame_dig -3 - frame_dig -2 - frame_dig -1 - select - // tests/artifacts/miscellaneous-ops/contract.algo.ts:169 - // return result - retsub - - -// tests/artifacts/miscellaneous-ops/contract.algo.ts::MiscellaneousOpsContract.verify_select_uint64(a: uint64, b: uint64, c: uint64) -> uint64: -verify_select_uint64: - // tests/artifacts/miscellaneous-ops/contract.algo.ts:172-173 - // @arc4.abimethod() - // public verify_select_uint64(a: uint64, b: uint64, c: uint64): uint64 { - proto 3 1 - // tests/artifacts/miscellaneous-ops/contract.algo.ts:174 - // const result = op.select(a, b, c) - frame_dig -3 - frame_dig -2 - frame_dig -1 - select - // tests/artifacts/miscellaneous-ops/contract.algo.ts:175 - // return result - retsub - - -// tests/artifacts/miscellaneous-ops/contract.algo.ts::MiscellaneousOpsContract.verify_setbit_bytes(a: bytes, b: uint64, c: uint64) -> bytes: -verify_setbit_bytes: - // tests/artifacts/miscellaneous-ops/contract.algo.ts:178-179 - // @arc4.abimethod() - // public verify_setbit_bytes(a: bytes, b: uint64, c: uint64): bytes { - proto 3 1 - // tests/artifacts/miscellaneous-ops/contract.algo.ts:180 - // const result = op.setBit(a, b, c) - frame_dig -3 - frame_dig -2 - frame_dig -1 - setbit - // tests/artifacts/miscellaneous-ops/contract.algo.ts:181 - // return result - retsub - - -// tests/artifacts/miscellaneous-ops/contract.algo.ts::MiscellaneousOpsContract.verify_setbit_uint64(a: uint64, b: uint64, c: uint64) -> uint64: -verify_setbit_uint64: - // tests/artifacts/miscellaneous-ops/contract.algo.ts:184-185 - // @arc4.abimethod() - // public verify_setbit_uint64(a: uint64, b: uint64, c: uint64): uint64 { - proto 3 1 - // tests/artifacts/miscellaneous-ops/contract.algo.ts:186 - // const result = op.setBit(a, b, c) - frame_dig -3 - frame_dig -2 - frame_dig -1 - setbit - // tests/artifacts/miscellaneous-ops/contract.algo.ts:187 - // return result - retsub - - -// tests/artifacts/miscellaneous-ops/contract.algo.ts::MiscellaneousOpsContract.verify_setbyte(a: bytes, b: uint64, c: uint64) -> bytes: -verify_setbyte: - // tests/artifacts/miscellaneous-ops/contract.algo.ts:190-191 - // @arc4.abimethod() - // public verify_setbyte(a: bytes, b: uint64, c: uint64): bytes { - proto 3 1 - // tests/artifacts/miscellaneous-ops/contract.algo.ts:192 - // const result = op.setByte(a, b, c) - frame_dig -3 - frame_dig -2 - frame_dig -1 - setbyte - // tests/artifacts/miscellaneous-ops/contract.algo.ts:193 - // return result - retsub - - -// tests/artifacts/miscellaneous-ops/contract.algo.ts::MiscellaneousOpsContract.verify_shl(a: uint64, b: uint64) -> uint64: -verify_shl: - // tests/artifacts/miscellaneous-ops/contract.algo.ts:196-197 - // @arc4.abimethod() - // public verify_shl(a: uint64, b: uint64): uint64 { - proto 2 1 - // tests/artifacts/miscellaneous-ops/contract.algo.ts:198 - // const result = op.shl(a, b) - frame_dig -2 - frame_dig -1 - shl - // tests/artifacts/miscellaneous-ops/contract.algo.ts:199 - // return result - retsub - - -// tests/artifacts/miscellaneous-ops/contract.algo.ts::MiscellaneousOpsContract.verify_shr(a: uint64, b: uint64) -> uint64: -verify_shr: - // tests/artifacts/miscellaneous-ops/contract.algo.ts:202-203 - // @arc4.abimethod() - // public verify_shr(a: uint64, b: uint64): uint64 { - proto 2 1 - // tests/artifacts/miscellaneous-ops/contract.algo.ts:204 - // const result = op.shr(a, b) - frame_dig -2 - frame_dig -1 - shr - // tests/artifacts/miscellaneous-ops/contract.algo.ts:205 - // return result - retsub - - -// tests/artifacts/miscellaneous-ops/contract.algo.ts::MiscellaneousOpsContract.verify_sqrt(a: uint64) -> uint64: -verify_sqrt: - // tests/artifacts/miscellaneous-ops/contract.algo.ts:208-209 - // @arc4.abimethod() - // public verify_sqrt(a: uint64): uint64 { - proto 1 1 - // tests/artifacts/miscellaneous-ops/contract.algo.ts:210 - // const result = op.sqrt(a) - frame_dig -1 - sqrt - // tests/artifacts/miscellaneous-ops/contract.algo.ts:211 - // return result - retsub - - -// tests/artifacts/miscellaneous-ops/contract.algo.ts::MiscellaneousOpsContract.verify_substring(a: bytes, b: uint64, c: uint64) -> bytes: -verify_substring: - // tests/artifacts/miscellaneous-ops/contract.algo.ts:214-215 - // @arc4.abimethod() - // public verify_substring(a: bytes, b: uint64, c: uint64): bytes { - proto 3 1 - // tests/artifacts/miscellaneous-ops/contract.algo.ts:216 - // const result = op.substring(a, b, c) - frame_dig -3 - frame_dig -2 - frame_dig -1 - substring3 - // tests/artifacts/miscellaneous-ops/contract.algo.ts:217 - // return result - retsub diff --git a/tests/artifacts/miscellaneous-ops/data/MiscellaneousOpsContract.arc32.json b/tests/artifacts/miscellaneous-ops/data/MiscellaneousOpsContract.arc32.json deleted file mode 100644 index ad99366..0000000 --- a/tests/artifacts/miscellaneous-ops/data/MiscellaneousOpsContract.arc32.json +++ /dev/null @@ -1,814 +0,0 @@ -{ - "hints": { - "verify_addw(uint64,uint64)(uint64,uint64)": { - "call_config": { - "no_op": "CALL" - } - }, - "verify_base64_decode_standard(byte[])byte[]": { - "call_config": { - "no_op": "CALL" - } - }, - "verify_base64_decode_url(byte[])byte[]": { - "call_config": { - "no_op": "CALL" - } - }, - "verify_bytes_bitlen(byte[],uint64)uint64": { - "call_config": { - "no_op": "CALL" - } - }, - "verify_uint64_bitlen(uint64)uint64": { - "call_config": { - "no_op": "CALL" - } - }, - "verify_bsqrt(byte[])byte[]": { - "call_config": { - "no_op": "CALL" - } - }, - "verify_btoi(byte[])uint64": { - "call_config": { - "no_op": "CALL" - } - }, - "verify_bzero(uint64)byte[]": { - "call_config": { - "no_op": "CALL" - } - }, - "verify_concat(byte[],byte[],uint64,uint64)byte[]": { - "call_config": { - "no_op": "CALL" - } - }, - "verify_divmodw(uint64,uint64,uint64,uint64)(uint64,uint64,uint64,uint64)": { - "call_config": { - "no_op": "CALL" - } - }, - "verify_divw(uint64,uint64,uint64)uint64": { - "call_config": { - "no_op": "CALL" - } - }, - "verify_err()void": { - "call_config": { - "no_op": "CALL" - } - }, - "verify_exp(uint64,uint64)uint64": { - "call_config": { - "no_op": "CALL" - } - }, - "verify_expw(uint64,uint64)(uint64,uint64)": { - "call_config": { - "no_op": "CALL" - } - }, - "verify_extract(byte[],uint64,uint64)byte[]": { - "call_config": { - "no_op": "CALL" - } - }, - "verify_extract_from_2(byte[])byte[]": { - "call_config": { - "no_op": "CALL" - } - }, - "verify_extract_uint16(byte[],uint64)uint64": { - "call_config": { - "no_op": "CALL" - } - }, - "verify_extract_uint32(byte[],uint64)uint64": { - "call_config": { - "no_op": "CALL" - } - }, - "verify_extract_uint64(byte[],uint64)uint64": { - "call_config": { - "no_op": "CALL" - } - }, - "verify_getbit_bytes(byte[],uint64)uint64": { - "call_config": { - "no_op": "CALL" - } - }, - "verify_getbit_uint64(uint64,uint64)uint64": { - "call_config": { - "no_op": "CALL" - } - }, - "verify_getbyte(byte[],uint64)uint64": { - "call_config": { - "no_op": "CALL" - } - }, - "verify_itob(uint64)byte[]": { - "call_config": { - "no_op": "CALL" - } - }, - "verify_bytes_len(byte[],uint64)uint64": { - "call_config": { - "no_op": "CALL" - } - }, - "verify_mulw(uint64,uint64)(uint64,uint64)": { - "call_config": { - "no_op": "CALL" - } - }, - "verify_replace(byte[],uint64,byte[])byte[]": { - "call_config": { - "no_op": "CALL" - } - }, - "verify_select_bytes(byte[],byte[],uint64)byte[]": { - "call_config": { - "no_op": "CALL" - } - }, - "verify_select_uint64(uint64,uint64,uint64)uint64": { - "call_config": { - "no_op": "CALL" - } - }, - "verify_setbit_bytes(byte[],uint64,uint64)byte[]": { - "call_config": { - "no_op": "CALL" - } - }, - "verify_setbit_uint64(uint64,uint64,uint64)uint64": { - "call_config": { - "no_op": "CALL" - } - }, - "verify_setbyte(byte[],uint64,uint64)byte[]": { - "call_config": { - "no_op": "CALL" - } - }, - "verify_shl(uint64,uint64)uint64": { - "call_config": { - "no_op": "CALL" - } - }, - "verify_shr(uint64,uint64)uint64": { - "call_config": { - "no_op": "CALL" - } - }, - "verify_sqrt(uint64)uint64": { - "call_config": { - "no_op": "CALL" - } - }, - "verify_substring(byte[],uint64,uint64)byte[]": { - "call_config": { - "no_op": "CALL" - } - } - }, - "source": { - "approval": "I3ByYWdtYSB2ZXJzaW9uIDEwCgp0ZXN0cy9hcnRpZmFjdHMvbWlzY2VsbGFuZW91cy1vcHMvY29udHJhY3QuYWxnby50czo6TWlzY2VsbGFuZW91c09wc0NvbnRyYWN0LmFwcHJvdmFsUHJvZ3JhbToKICAgIGludGNibG9jayAxIDAKICAgIGJ5dGVjYmxvY2sgMHgxNTFmN2M3NQogICAgY2FsbHN1YiBfX3B1eWFfYXJjNF9yb3V0ZXJfXwogICAgcmV0dXJuCgoKLy8gdGVzdHMvYXJ0aWZhY3RzL21pc2NlbGxhbmVvdXMtb3BzL2NvbnRyYWN0LmFsZ28udHM6Ok1pc2NlbGxhbmVvdXNPcHNDb250cmFjdC5fX3B1eWFfYXJjNF9yb3V0ZXJfXygpIC0-IHVpbnQ2NDoKX19wdXlhX2FyYzRfcm91dGVyX186CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvbWlzY2VsbGFuZW91cy1vcHMvY29udHJhY3QuYWxnby50czozCiAgICAvLyBleHBvcnQgY2xhc3MgTWlzY2VsbGFuZW91c09wc0NvbnRyYWN0IGV4dGVuZHMgYXJjNC5Db250cmFjdCB7CiAgICBwcm90byAwIDEKICAgIHR4biBOdW1BcHBBcmdzCiAgICBieiBfX3B1eWFfYXJjNF9yb3V0ZXJfX19iYXJlX3JvdXRpbmdAMzkKICAgIHB1c2hieXRlc3MgMHg0NTg0N2VlYSAweGY1N2FjZWI1IDB4N2Q2MzE3MzAgMHhhMWIyNDQ0MSAweGNkN2JlMWFjIDB4N2NmZGE2NGIgMHg1NGE5MTBkOSAweGM0NjU2OGRlIDB4N2E0NmE2YWUgMHgwNDM3MjIwOSAweDdlNWY2ZDcyIDB4MjRlYmNmODQgMHg5YzBiMzM5NyAweDBhZDQwZGE0IDB4OTUxNzg4NzAgMHhkZWVkYzk5YiAweGFiMjE1MGJiIDB4MDJhNTQwMTcgMHgzZGI2NmI0MSAweGM3ZWE4YzJhIDB4MWRjZWE1MGMgMHgxNjE2NmY5YSAweDJmNDcyMDY1IDB4YzU4ZDMwZTAgMHhkNWE3MzljMyAweDYxZjNiM2UxIDB4NTZjZjM2OGIgMHg5MTlmZmJkMiAweDhlMzBmNGU3IDB4ODlmODFkOTIgMHhkNTI2MDMyNyAweDExNGM4YzZkIDB4MzllOWU2MmEgMHhkNmE0YzA1ZSAweDFlZjgxNTFhIC8vIG1ldGhvZCAidmVyaWZ5X2FkZHcodWludDY0LHVpbnQ2NCkodWludDY0LHVpbnQ2NCkiLCBtZXRob2QgInZlcmlmeV9iYXNlNjRfZGVjb2RlX3N0YW5kYXJkKGJ5dGVbXSlieXRlW10iLCBtZXRob2QgInZlcmlmeV9iYXNlNjRfZGVjb2RlX3VybChieXRlW10pYnl0ZVtdIiwgbWV0aG9kICJ2ZXJpZnlfYnl0ZXNfYml0bGVuKGJ5dGVbXSx1aW50NjQpdWludDY0IiwgbWV0aG9kICJ2ZXJpZnlfdWludDY0X2JpdGxlbih1aW50NjQpdWludDY0IiwgbWV0aG9kICJ2ZXJpZnlfYnNxcnQoYnl0ZVtdKWJ5dGVbXSIsIG1ldGhvZCAidmVyaWZ5X2J0b2koYnl0ZVtdKXVpbnQ2NCIsIG1ldGhvZCAidmVyaWZ5X2J6ZXJvKHVpbnQ2NClieXRlW10iLCBtZXRob2QgInZlcmlmeV9jb25jYXQoYnl0ZVtdLGJ5dGVbXSx1aW50NjQsdWludDY0KWJ5dGVbXSIsIG1ldGhvZCAidmVyaWZ5X2Rpdm1vZHcodWludDY0LHVpbnQ2NCx1aW50NjQsdWludDY0KSh1aW50NjQsdWludDY0LHVpbnQ2NCx1aW50NjQpIiwgbWV0aG9kICJ2ZXJpZnlfZGl2dyh1aW50NjQsdWludDY0LHVpbnQ2NCl1aW50NjQiLCBtZXRob2QgInZlcmlmeV9lcnIoKXZvaWQiLCBtZXRob2QgInZlcmlmeV9leHAodWludDY0LHVpbnQ2NCl1aW50NjQiLCBtZXRob2QgInZlcmlmeV9leHB3KHVpbnQ2NCx1aW50NjQpKHVpbnQ2NCx1aW50NjQpIiwgbWV0aG9kICJ2ZXJpZnlfZXh0cmFjdChieXRlW10sdWludDY0LHVpbnQ2NClieXRlW10iLCBtZXRob2QgInZlcmlmeV9leHRyYWN0X2Zyb21fMihieXRlW10pYnl0ZVtdIiwgbWV0aG9kICJ2ZXJpZnlfZXh0cmFjdF91aW50MTYoYnl0ZVtdLHVpbnQ2NCl1aW50NjQiLCBtZXRob2QgInZlcmlmeV9leHRyYWN0X3VpbnQzMihieXRlW10sdWludDY0KXVpbnQ2NCIsIG1ldGhvZCAidmVyaWZ5X2V4dHJhY3RfdWludDY0KGJ5dGVbXSx1aW50NjQpdWludDY0IiwgbWV0aG9kICJ2ZXJpZnlfZ2V0Yml0X2J5dGVzKGJ5dGVbXSx1aW50NjQpdWludDY0IiwgbWV0aG9kICJ2ZXJpZnlfZ2V0Yml0X3VpbnQ2NCh1aW50NjQsdWludDY0KXVpbnQ2NCIsIG1ldGhvZCAidmVyaWZ5X2dldGJ5dGUoYnl0ZVtdLHVpbnQ2NCl1aW50NjQiLCBtZXRob2QgInZlcmlmeV9pdG9iKHVpbnQ2NClieXRlW10iLCBtZXRob2QgInZlcmlmeV9ieXRlc19sZW4oYnl0ZVtdLHVpbnQ2NCl1aW50NjQiLCBtZXRob2QgInZlcmlmeV9tdWx3KHVpbnQ2NCx1aW50NjQpKHVpbnQ2NCx1aW50NjQpIiwgbWV0aG9kICJ2ZXJpZnlfcmVwbGFjZShieXRlW10sdWludDY0LGJ5dGVbXSlieXRlW10iLCBtZXRob2QgInZlcmlmeV9zZWxlY3RfYnl0ZXMoYnl0ZVtdLGJ5dGVbXSx1aW50NjQpYnl0ZVtdIiwgbWV0aG9kICJ2ZXJpZnlfc2VsZWN0X3VpbnQ2NCh1aW50NjQsdWludDY0LHVpbnQ2NCl1aW50NjQiLCBtZXRob2QgInZlcmlmeV9zZXRiaXRfYnl0ZXMoYnl0ZVtdLHVpbnQ2NCx1aW50NjQpYnl0ZVtdIiwgbWV0aG9kICJ2ZXJpZnlfc2V0Yml0X3VpbnQ2NCh1aW50NjQsdWludDY0LHVpbnQ2NCl1aW50NjQiLCBtZXRob2QgInZlcmlmeV9zZXRieXRlKGJ5dGVbXSx1aW50NjQsdWludDY0KWJ5dGVbXSIsIG1ldGhvZCAidmVyaWZ5X3NobCh1aW50NjQsdWludDY0KXVpbnQ2NCIsIG1ldGhvZCAidmVyaWZ5X3Nocih1aW50NjQsdWludDY0KXVpbnQ2NCIsIG1ldGhvZCAidmVyaWZ5X3NxcnQodWludDY0KXVpbnQ2NCIsIG1ldGhvZCAidmVyaWZ5X3N1YnN0cmluZyhieXRlW10sdWludDY0LHVpbnQ2NClieXRlW10iCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAwCiAgICBtYXRjaCBfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfYWRkd19yb3V0ZUAyIF9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9iYXNlNjRfZGVjb2RlX3N0YW5kYXJkX3JvdXRlQDMgX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2Jhc2U2NF9kZWNvZGVfdXJsX3JvdXRlQDQgX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2J5dGVzX2JpdGxlbl9yb3V0ZUA1IF9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV91aW50NjRfYml0bGVuX3JvdXRlQDYgX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2JzcXJ0X3JvdXRlQDcgX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2J0b2lfcm91dGVAOCBfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfYnplcm9fcm91dGVAOSBfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfY29uY2F0X3JvdXRlQDEwIF9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9kaXZtb2R3X3JvdXRlQDExIF9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9kaXZ3X3JvdXRlQDEyIF9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9lcnJfcm91dGVAMTMgX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2V4cF9yb3V0ZUAxNCBfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfZXhwd19yb3V0ZUAxNSBfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfZXh0cmFjdF9yb3V0ZUAxNiBfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfZXh0cmFjdF9mcm9tXzJfcm91dGVAMTcgX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2V4dHJhY3RfdWludDE2X3JvdXRlQDE4IF9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9leHRyYWN0X3VpbnQzMl9yb3V0ZUAxOSBfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfZXh0cmFjdF91aW50NjRfcm91dGVAMjAgX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2dldGJpdF9ieXRlc19yb3V0ZUAyMSBfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfZ2V0Yml0X3VpbnQ2NF9yb3V0ZUAyMiBfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfZ2V0Ynl0ZV9yb3V0ZUAyMyBfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfaXRvYl9yb3V0ZUAyNCBfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfYnl0ZXNfbGVuX3JvdXRlQDI1IF9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9tdWx3X3JvdXRlQDI2IF9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9yZXBsYWNlX3JvdXRlQDI3IF9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9zZWxlY3RfYnl0ZXNfcm91dGVAMjggX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X3NlbGVjdF91aW50NjRfcm91dGVAMjkgX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X3NldGJpdF9ieXRlc19yb3V0ZUAzMCBfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfc2V0Yml0X3VpbnQ2NF9yb3V0ZUAzMSBfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfc2V0Ynl0ZV9yb3V0ZUAzMiBfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfc2hsX3JvdXRlQDMzIF9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9zaHJfcm91dGVAMzQgX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X3NxcnRfcm91dGVAMzUgX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X3N1YnN0cmluZ19yb3V0ZUAzNgogICAgaW50Y18xIC8vIDAKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2FkZHdfcm91dGVAMjoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9taXNjZWxsYW5lb3VzLW9wcy9jb250cmFjdC5hbGdvLnRzOjQKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIG5vdCBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGNhbiBvbmx5IGNhbGwgd2hlbiBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9taXNjZWxsYW5lb3VzLW9wcy9jb250cmFjdC5hbGdvLnRzOjMKICAgIC8vIGV4cG9ydCBjbGFzcyBNaXNjZWxsYW5lb3VzT3BzQ29udHJhY3QgZXh0ZW5kcyBhcmM0LkNvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGJ0b2kKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDIKICAgIGJ0b2kKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9taXNjZWxsYW5lb3VzLW9wcy9jb250cmFjdC5hbGdvLnRzOjQKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV9hZGR3CiAgICBzd2FwCiAgICBpdG9iCiAgICBzd2FwCiAgICBpdG9iCiAgICBjb25jYXQKICAgIGJ5dGVjXzAgLy8gMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludGNfMCAvLyAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9iYXNlNjRfZGVjb2RlX3N0YW5kYXJkX3JvdXRlQDM6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvbWlzY2VsbGFuZW91cy1vcHMvY29udHJhY3QuYWxnby50czoxMAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgbm90IE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gY2FuIG9ubHkgY2FsbCB3aGVuIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL21pc2NlbGxhbmVvdXMtb3BzL2NvbnRyYWN0LmFsZ28udHM6MwogICAgLy8gZXhwb3J0IGNsYXNzIE1pc2NlbGxhbmVvdXNPcHNDb250cmFjdCBleHRlbmRzIGFyYzQuQ29udHJhY3QgewogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgZXh0cmFjdCAyIDAKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9taXNjZWxsYW5lb3VzLW9wcy9jb250cmFjdC5hbGdvLnRzOjEwCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfYmFzZTY0X2RlY29kZV9zdGFuZGFyZAogICAgZHVwCiAgICBsZW4KICAgIGl0b2IKICAgIGV4dHJhY3QgNiAyCiAgICBzd2FwCiAgICBjb25jYXQKICAgIGJ5dGVjXzAgLy8gMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludGNfMCAvLyAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9iYXNlNjRfZGVjb2RlX3VybF9yb3V0ZUA0OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL21pc2NlbGxhbmVvdXMtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTYKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIG5vdCBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGNhbiBvbmx5IGNhbGwgd2hlbiBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9taXNjZWxsYW5lb3VzLW9wcy9jb250cmFjdC5hbGdvLnRzOjMKICAgIC8vIGV4cG9ydCBjbGFzcyBNaXNjZWxsYW5lb3VzT3BzQ29udHJhY3QgZXh0ZW5kcyBhcmM0LkNvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGV4dHJhY3QgMiAwCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvbWlzY2VsbGFuZW91cy1vcHMvY29udHJhY3QuYWxnby50czoxNgogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X2Jhc2U2NF9kZWNvZGVfdXJsCiAgICBkdXAKICAgIGxlbgogICAgaXRvYgogICAgZXh0cmFjdCA2IDIKICAgIHN3YXAKICAgIGNvbmNhdAogICAgYnl0ZWNfMCAvLyAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50Y18wIC8vIDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2J5dGVzX2JpdGxlbl9yb3V0ZUA1OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL21pc2NlbGxhbmVvdXMtb3BzL2NvbnRyYWN0LmFsZ28udHM6MjIKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIG5vdCBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGNhbiBvbmx5IGNhbGwgd2hlbiBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9taXNjZWxsYW5lb3VzLW9wcy9jb250cmFjdC5hbGdvLnRzOjMKICAgIC8vIGV4cG9ydCBjbGFzcyBNaXNjZWxsYW5lb3VzT3BzQ29udHJhY3QgZXh0ZW5kcyBhcmM0LkNvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGV4dHJhY3QgMiAwCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAyCiAgICBidG9pCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvbWlzY2VsbGFuZW91cy1vcHMvY29udHJhY3QuYWxnby50czoyMgogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X2J5dGVzX2JpdGxlbgogICAgaXRvYgogICAgYnl0ZWNfMCAvLyAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50Y18wIC8vIDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X3VpbnQ2NF9iaXRsZW5fcm91dGVANjoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9taXNjZWxsYW5lb3VzLW9wcy9jb250cmFjdC5hbGdvLnRzOjI5CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBub3QgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBjYW4gb25seSBjYWxsIHdoZW4gbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvbWlzY2VsbGFuZW91cy1vcHMvY29udHJhY3QuYWxnby50czozCiAgICAvLyBleHBvcnQgY2xhc3MgTWlzY2VsbGFuZW91c09wc0NvbnRyYWN0IGV4dGVuZHMgYXJjNC5Db250cmFjdCB7CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBidG9pCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvbWlzY2VsbGFuZW91cy1vcHMvY29udHJhY3QuYWxnby50czoyOQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X3VpbnQ2NF9iaXRsZW4KICAgIGl0b2IKICAgIGJ5dGVjXzAgLy8gMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludGNfMCAvLyAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9ic3FydF9yb3V0ZUA3OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL21pc2NlbGxhbmVvdXMtb3BzL2NvbnRyYWN0LmFsZ28udHM6MzUKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIG5vdCBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGNhbiBvbmx5IGNhbGwgd2hlbiBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9taXNjZWxsYW5lb3VzLW9wcy9jb250cmFjdC5hbGdvLnRzOjMKICAgIC8vIGV4cG9ydCBjbGFzcyBNaXNjZWxsYW5lb3VzT3BzQ29udHJhY3QgZXh0ZW5kcyBhcmM0LkNvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGV4dHJhY3QgMiAwCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvbWlzY2VsbGFuZW91cy1vcHMvY29udHJhY3QuYWxnby50czozNQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X2JzcXJ0CiAgICBkdXAKICAgIGxlbgogICAgaXRvYgogICAgZXh0cmFjdCA2IDIKICAgIHN3YXAKICAgIGNvbmNhdAogICAgYnl0ZWNfMCAvLyAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50Y18wIC8vIDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2J0b2lfcm91dGVAODoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9taXNjZWxsYW5lb3VzLW9wcy9jb250cmFjdC5hbGdvLnRzOjQyCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBub3QgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBjYW4gb25seSBjYWxsIHdoZW4gbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvbWlzY2VsbGFuZW91cy1vcHMvY29udHJhY3QuYWxnby50czozCiAgICAvLyBleHBvcnQgY2xhc3MgTWlzY2VsbGFuZW91c09wc0NvbnRyYWN0IGV4dGVuZHMgYXJjNC5Db250cmFjdCB7CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBleHRyYWN0IDIgMAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL21pc2NlbGxhbmVvdXMtb3BzL2NvbnRyYWN0LmFsZ28udHM6NDIKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV9idG9pCiAgICBpdG9iCiAgICBieXRlY18wIC8vIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnRjXzAgLy8gMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfYnplcm9fcm91dGVAOToKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9taXNjZWxsYW5lb3VzLW9wcy9jb250cmFjdC5hbGdvLnRzOjQ4CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBub3QgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBjYW4gb25seSBjYWxsIHdoZW4gbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvbWlzY2VsbGFuZW91cy1vcHMvY29udHJhY3QuYWxnby50czozCiAgICAvLyBleHBvcnQgY2xhc3MgTWlzY2VsbGFuZW91c09wc0NvbnRyYWN0IGV4dGVuZHMgYXJjNC5Db250cmFjdCB7CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBidG9pCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvbWlzY2VsbGFuZW91cy1vcHMvY29udHJhY3QuYWxnby50czo0OAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X2J6ZXJvCiAgICBkdXAKICAgIGxlbgogICAgaXRvYgogICAgZXh0cmFjdCA2IDIKICAgIHN3YXAKICAgIGNvbmNhdAogICAgYnl0ZWNfMCAvLyAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50Y18wIC8vIDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2NvbmNhdF9yb3V0ZUAxMDoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9taXNjZWxsYW5lb3VzLW9wcy9jb250cmFjdC5hbGdvLnRzOjU0CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBub3QgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBjYW4gb25seSBjYWxsIHdoZW4gbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvbWlzY2VsbGFuZW91cy1vcHMvY29udHJhY3QuYWxnby50czozCiAgICAvLyBleHBvcnQgY2xhc3MgTWlzY2VsbGFuZW91c09wc0NvbnRyYWN0IGV4dGVuZHMgYXJjNC5Db250cmFjdCB7CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBleHRyYWN0IDIgMAogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMgogICAgZXh0cmFjdCAyIDAKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDMKICAgIGJ0b2kKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDQKICAgIGJ0b2kKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9taXNjZWxsYW5lb3VzLW9wcy9jb250cmFjdC5hbGdvLnRzOjU0CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfY29uY2F0CiAgICBkdXAKICAgIGxlbgogICAgaXRvYgogICAgZXh0cmFjdCA2IDIKICAgIHN3YXAKICAgIGNvbmNhdAogICAgYnl0ZWNfMCAvLyAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50Y18wIC8vIDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2Rpdm1vZHdfcm91dGVAMTE6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvbWlzY2VsbGFuZW91cy1vcHMvY29udHJhY3QuYWxnby50czo2MwogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgbm90IE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gY2FuIG9ubHkgY2FsbCB3aGVuIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL21pc2NlbGxhbmVvdXMtb3BzL2NvbnRyYWN0LmFsZ28udHM6MwogICAgLy8gZXhwb3J0IGNsYXNzIE1pc2NlbGxhbmVvdXNPcHNDb250cmFjdCBleHRlbmRzIGFyYzQuQ29udHJhY3QgewogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgYnRvaQogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMgogICAgYnRvaQogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMwogICAgYnRvaQogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgNAogICAgYnRvaQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL21pc2NlbGxhbmVvdXMtb3BzL2NvbnRyYWN0LmFsZ28udHM6NjMKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV9kaXZtb2R3CiAgICB1bmNvdmVyIDMKICAgIGl0b2IKICAgIHVuY292ZXIgMwogICAgaXRvYgogICAgdW5jb3ZlciAzCiAgICBpdG9iCiAgICB1bmNvdmVyIDMKICAgIGl0b2IKICAgIHVuY292ZXIgMwogICAgdW5jb3ZlciAzCiAgICBjb25jYXQKICAgIHVuY292ZXIgMgogICAgY29uY2F0CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGJ5dGVjXzAgLy8gMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludGNfMCAvLyAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9kaXZ3X3JvdXRlQDEyOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL21pc2NlbGxhbmVvdXMtb3BzL2NvbnRyYWN0LmFsZ28udHM6NjkKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIG5vdCBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGNhbiBvbmx5IGNhbGwgd2hlbiBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9taXNjZWxsYW5lb3VzLW9wcy9jb250cmFjdC5hbGdvLnRzOjMKICAgIC8vIGV4cG9ydCBjbGFzcyBNaXNjZWxsYW5lb3VzT3BzQ29udHJhY3QgZXh0ZW5kcyBhcmM0LkNvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGJ0b2kKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDIKICAgIGJ0b2kKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDMKICAgIGJ0b2kKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9taXNjZWxsYW5lb3VzLW9wcy9jb250cmFjdC5hbGdvLnRzOjY5CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfZGl2dwogICAgaXRvYgogICAgYnl0ZWNfMCAvLyAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50Y18wIC8vIDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2Vycl9yb3V0ZUAxMzoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9taXNjZWxsYW5lb3VzLW9wcy9jb250cmFjdC5hbGdvLnRzOjc1CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBub3QgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBjYW4gb25seSBjYWxsIHdoZW4gbm90IGNyZWF0aW5nCiAgICBjYWxsc3ViIHZlcmlmeV9lcnIKICAgIGludGNfMCAvLyAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9leHBfcm91dGVAMTQ6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvbWlzY2VsbGFuZW91cy1vcHMvY29udHJhY3QuYWxnby50czo4MAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgbm90IE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gY2FuIG9ubHkgY2FsbCB3aGVuIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL21pc2NlbGxhbmVvdXMtb3BzL2NvbnRyYWN0LmFsZ28udHM6MwogICAgLy8gZXhwb3J0IGNsYXNzIE1pc2NlbGxhbmVvdXNPcHNDb250cmFjdCBleHRlbmRzIGFyYzQuQ29udHJhY3QgewogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgYnRvaQogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMgogICAgYnRvaQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL21pc2NlbGxhbmVvdXMtb3BzL2NvbnRyYWN0LmFsZ28udHM6ODAKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV9leHAKICAgIGl0b2IKICAgIGJ5dGVjXzAgLy8gMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludGNfMCAvLyAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9leHB3X3JvdXRlQDE1OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL21pc2NlbGxhbmVvdXMtb3BzL2NvbnRyYWN0LmFsZ28udHM6ODYKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIG5vdCBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGNhbiBvbmx5IGNhbGwgd2hlbiBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9taXNjZWxsYW5lb3VzLW9wcy9jb250cmFjdC5hbGdvLnRzOjMKICAgIC8vIGV4cG9ydCBjbGFzcyBNaXNjZWxsYW5lb3VzT3BzQ29udHJhY3QgZXh0ZW5kcyBhcmM0LkNvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGJ0b2kKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDIKICAgIGJ0b2kKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9taXNjZWxsYW5lb3VzLW9wcy9jb250cmFjdC5hbGdvLnRzOjg2CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfZXhwdwogICAgc3dhcAogICAgaXRvYgogICAgc3dhcAogICAgaXRvYgogICAgY29uY2F0CiAgICBieXRlY18wIC8vIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnRjXzAgLy8gMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfZXh0cmFjdF9yb3V0ZUAxNjoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9taXNjZWxsYW5lb3VzLW9wcy9jb250cmFjdC5hbGdvLnRzOjkyCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBub3QgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBjYW4gb25seSBjYWxsIHdoZW4gbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvbWlzY2VsbGFuZW91cy1vcHMvY29udHJhY3QuYWxnby50czozCiAgICAvLyBleHBvcnQgY2xhc3MgTWlzY2VsbGFuZW91c09wc0NvbnRyYWN0IGV4dGVuZHMgYXJjNC5Db250cmFjdCB7CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBleHRyYWN0IDIgMAogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMgogICAgYnRvaQogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMwogICAgYnRvaQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL21pc2NlbGxhbmVvdXMtb3BzL2NvbnRyYWN0LmFsZ28udHM6OTIKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV9leHRyYWN0CiAgICBkdXAKICAgIGxlbgogICAgaXRvYgogICAgZXh0cmFjdCA2IDIKICAgIHN3YXAKICAgIGNvbmNhdAogICAgYnl0ZWNfMCAvLyAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50Y18wIC8vIDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2V4dHJhY3RfZnJvbV8yX3JvdXRlQDE3OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL21pc2NlbGxhbmVvdXMtb3BzL2NvbnRyYWN0LmFsZ28udHM6OTkKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIG5vdCBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGNhbiBvbmx5IGNhbGwgd2hlbiBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9taXNjZWxsYW5lb3VzLW9wcy9jb250cmFjdC5hbGdvLnRzOjMKICAgIC8vIGV4cG9ydCBjbGFzcyBNaXNjZWxsYW5lb3VzT3BzQ29udHJhY3QgZXh0ZW5kcyBhcmM0LkNvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGV4dHJhY3QgMiAwCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvbWlzY2VsbGFuZW91cy1vcHMvY29udHJhY3QuYWxnby50czo5OQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X2V4dHJhY3RfZnJvbV8yCiAgICBkdXAKICAgIGxlbgogICAgaXRvYgogICAgZXh0cmFjdCA2IDIKICAgIHN3YXAKICAgIGNvbmNhdAogICAgYnl0ZWNfMCAvLyAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50Y18wIC8vIDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2V4dHJhY3RfdWludDE2X3JvdXRlQDE4OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL21pc2NlbGxhbmVvdXMtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTA1CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBub3QgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBjYW4gb25seSBjYWxsIHdoZW4gbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvbWlzY2VsbGFuZW91cy1vcHMvY29udHJhY3QuYWxnby50czozCiAgICAvLyBleHBvcnQgY2xhc3MgTWlzY2VsbGFuZW91c09wc0NvbnRyYWN0IGV4dGVuZHMgYXJjNC5Db250cmFjdCB7CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBleHRyYWN0IDIgMAogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMgogICAgYnRvaQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL21pc2NlbGxhbmVvdXMtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTA1CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfZXh0cmFjdF91aW50MTYKICAgIGl0b2IKICAgIGJ5dGVjXzAgLy8gMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludGNfMCAvLyAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9leHRyYWN0X3VpbnQzMl9yb3V0ZUAxOToKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9taXNjZWxsYW5lb3VzLW9wcy9jb250cmFjdC5hbGdvLnRzOjExMQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgbm90IE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gY2FuIG9ubHkgY2FsbCB3aGVuIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL21pc2NlbGxhbmVvdXMtb3BzL2NvbnRyYWN0LmFsZ28udHM6MwogICAgLy8gZXhwb3J0IGNsYXNzIE1pc2NlbGxhbmVvdXNPcHNDb250cmFjdCBleHRlbmRzIGFyYzQuQ29udHJhY3QgewogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgZXh0cmFjdCAyIDAKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDIKICAgIGJ0b2kKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9taXNjZWxsYW5lb3VzLW9wcy9jb250cmFjdC5hbGdvLnRzOjExMQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X2V4dHJhY3RfdWludDMyCiAgICBpdG9iCiAgICBieXRlY18wIC8vIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnRjXzAgLy8gMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfZXh0cmFjdF91aW50NjRfcm91dGVAMjA6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvbWlzY2VsbGFuZW91cy1vcHMvY29udHJhY3QuYWxnby50czoxMTcKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIG5vdCBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGNhbiBvbmx5IGNhbGwgd2hlbiBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9taXNjZWxsYW5lb3VzLW9wcy9jb250cmFjdC5hbGdvLnRzOjMKICAgIC8vIGV4cG9ydCBjbGFzcyBNaXNjZWxsYW5lb3VzT3BzQ29udHJhY3QgZXh0ZW5kcyBhcmM0LkNvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGV4dHJhY3QgMiAwCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAyCiAgICBidG9pCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvbWlzY2VsbGFuZW91cy1vcHMvY29udHJhY3QuYWxnby50czoxMTcKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV9leHRyYWN0X3VpbnQ2NAogICAgaXRvYgogICAgYnl0ZWNfMCAvLyAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50Y18wIC8vIDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2dldGJpdF9ieXRlc19yb3V0ZUAyMToKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9taXNjZWxsYW5lb3VzLW9wcy9jb250cmFjdC5hbGdvLnRzOjEyMwogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgbm90IE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gY2FuIG9ubHkgY2FsbCB3aGVuIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL21pc2NlbGxhbmVvdXMtb3BzL2NvbnRyYWN0LmFsZ28udHM6MwogICAgLy8gZXhwb3J0IGNsYXNzIE1pc2NlbGxhbmVvdXNPcHNDb250cmFjdCBleHRlbmRzIGFyYzQuQ29udHJhY3QgewogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgZXh0cmFjdCAyIDAKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDIKICAgIGJ0b2kKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9taXNjZWxsYW5lb3VzLW9wcy9jb250cmFjdC5hbGdvLnRzOjEyMwogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X2dldGJpdF9ieXRlcwogICAgaXRvYgogICAgYnl0ZWNfMCAvLyAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50Y18wIC8vIDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2dldGJpdF91aW50NjRfcm91dGVAMjI6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvbWlzY2VsbGFuZW91cy1vcHMvY29udHJhY3QuYWxnby50czoxMjkKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIG5vdCBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGNhbiBvbmx5IGNhbGwgd2hlbiBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9taXNjZWxsYW5lb3VzLW9wcy9jb250cmFjdC5hbGdvLnRzOjMKICAgIC8vIGV4cG9ydCBjbGFzcyBNaXNjZWxsYW5lb3VzT3BzQ29udHJhY3QgZXh0ZW5kcyBhcmM0LkNvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGJ0b2kKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDIKICAgIGJ0b2kKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9taXNjZWxsYW5lb3VzLW9wcy9jb250cmFjdC5hbGdvLnRzOjEyOQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X2dldGJpdF91aW50NjQKICAgIGl0b2IKICAgIGJ5dGVjXzAgLy8gMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludGNfMCAvLyAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9nZXRieXRlX3JvdXRlQDIzOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL21pc2NlbGxhbmVvdXMtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTM1CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBub3QgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBjYW4gb25seSBjYWxsIHdoZW4gbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvbWlzY2VsbGFuZW91cy1vcHMvY29udHJhY3QuYWxnby50czozCiAgICAvLyBleHBvcnQgY2xhc3MgTWlzY2VsbGFuZW91c09wc0NvbnRyYWN0IGV4dGVuZHMgYXJjNC5Db250cmFjdCB7CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBleHRyYWN0IDIgMAogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMgogICAgYnRvaQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL21pc2NlbGxhbmVvdXMtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTM1CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfZ2V0Ynl0ZQogICAgaXRvYgogICAgYnl0ZWNfMCAvLyAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50Y18wIC8vIDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2l0b2Jfcm91dGVAMjQ6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvbWlzY2VsbGFuZW91cy1vcHMvY29udHJhY3QuYWxnby50czoxNDEKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIG5vdCBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGNhbiBvbmx5IGNhbGwgd2hlbiBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9taXNjZWxsYW5lb3VzLW9wcy9jb250cmFjdC5hbGdvLnRzOjMKICAgIC8vIGV4cG9ydCBjbGFzcyBNaXNjZWxsYW5lb3VzT3BzQ29udHJhY3QgZXh0ZW5kcyBhcmM0LkNvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGJ0b2kKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9taXNjZWxsYW5lb3VzLW9wcy9jb250cmFjdC5hbGdvLnRzOjE0MQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X2l0b2IKICAgIGR1cAogICAgbGVuCiAgICBpdG9iCiAgICBleHRyYWN0IDYgMgogICAgc3dhcAogICAgY29uY2F0CiAgICBieXRlY18wIC8vIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnRjXzAgLy8gMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfYnl0ZXNfbGVuX3JvdXRlQDI1OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL21pc2NlbGxhbmVvdXMtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTQ3CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBub3QgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBjYW4gb25seSBjYWxsIHdoZW4gbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvbWlzY2VsbGFuZW91cy1vcHMvY29udHJhY3QuYWxnby50czozCiAgICAvLyBleHBvcnQgY2xhc3MgTWlzY2VsbGFuZW91c09wc0NvbnRyYWN0IGV4dGVuZHMgYXJjNC5Db250cmFjdCB7CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBleHRyYWN0IDIgMAogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMgogICAgYnRvaQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL21pc2NlbGxhbmVvdXMtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTQ3CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfYnl0ZXNfbGVuCiAgICBpdG9iCiAgICBieXRlY18wIC8vIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnRjXzAgLy8gMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfbXVsd19yb3V0ZUAyNjoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9taXNjZWxsYW5lb3VzLW9wcy9jb250cmFjdC5hbGdvLnRzOjE1NAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgbm90IE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gY2FuIG9ubHkgY2FsbCB3aGVuIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL21pc2NlbGxhbmVvdXMtb3BzL2NvbnRyYWN0LmFsZ28udHM6MwogICAgLy8gZXhwb3J0IGNsYXNzIE1pc2NlbGxhbmVvdXNPcHNDb250cmFjdCBleHRlbmRzIGFyYzQuQ29udHJhY3QgewogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgYnRvaQogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMgogICAgYnRvaQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL21pc2NlbGxhbmVvdXMtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTU0CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfbXVsdwogICAgc3dhcAogICAgaXRvYgogICAgc3dhcAogICAgaXRvYgogICAgY29uY2F0CiAgICBieXRlY18wIC8vIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnRjXzAgLy8gMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfcmVwbGFjZV9yb3V0ZUAyNzoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9taXNjZWxsYW5lb3VzLW9wcy9jb250cmFjdC5hbGdvLnRzOjE2MAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgbm90IE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gY2FuIG9ubHkgY2FsbCB3aGVuIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL21pc2NlbGxhbmVvdXMtb3BzL2NvbnRyYWN0LmFsZ28udHM6MwogICAgLy8gZXhwb3J0IGNsYXNzIE1pc2NlbGxhbmVvdXNPcHNDb250cmFjdCBleHRlbmRzIGFyYzQuQ29udHJhY3QgewogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgZXh0cmFjdCAyIDAKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDIKICAgIGJ0b2kKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDMKICAgIGV4dHJhY3QgMiAwCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvbWlzY2VsbGFuZW91cy1vcHMvY29udHJhY3QuYWxnby50czoxNjAKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV9yZXBsYWNlCiAgICBkdXAKICAgIGxlbgogICAgaXRvYgogICAgZXh0cmFjdCA2IDIKICAgIHN3YXAKICAgIGNvbmNhdAogICAgYnl0ZWNfMCAvLyAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50Y18wIC8vIDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X3NlbGVjdF9ieXRlc19yb3V0ZUAyODoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9taXNjZWxsYW5lb3VzLW9wcy9jb250cmFjdC5hbGdvLnRzOjE2NgogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgbm90IE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gY2FuIG9ubHkgY2FsbCB3aGVuIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL21pc2NlbGxhbmVvdXMtb3BzL2NvbnRyYWN0LmFsZ28udHM6MwogICAgLy8gZXhwb3J0IGNsYXNzIE1pc2NlbGxhbmVvdXNPcHNDb250cmFjdCBleHRlbmRzIGFyYzQuQ29udHJhY3QgewogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgZXh0cmFjdCAyIDAKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDIKICAgIGV4dHJhY3QgMiAwCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAzCiAgICBidG9pCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvbWlzY2VsbGFuZW91cy1vcHMvY29udHJhY3QuYWxnby50czoxNjYKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV9zZWxlY3RfYnl0ZXMKICAgIGR1cAogICAgbGVuCiAgICBpdG9iCiAgICBleHRyYWN0IDYgMgogICAgc3dhcAogICAgY29uY2F0CiAgICBieXRlY18wIC8vIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnRjXzAgLy8gMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfc2VsZWN0X3VpbnQ2NF9yb3V0ZUAyOToKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9taXNjZWxsYW5lb3VzLW9wcy9jb250cmFjdC5hbGdvLnRzOjE3MgogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgbm90IE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gY2FuIG9ubHkgY2FsbCB3aGVuIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL21pc2NlbGxhbmVvdXMtb3BzL2NvbnRyYWN0LmFsZ28udHM6MwogICAgLy8gZXhwb3J0IGNsYXNzIE1pc2NlbGxhbmVvdXNPcHNDb250cmFjdCBleHRlbmRzIGFyYzQuQ29udHJhY3QgewogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgYnRvaQogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMgogICAgYnRvaQogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMwogICAgYnRvaQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL21pc2NlbGxhbmVvdXMtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTcyCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfc2VsZWN0X3VpbnQ2NAogICAgaXRvYgogICAgYnl0ZWNfMCAvLyAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50Y18wIC8vIDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X3NldGJpdF9ieXRlc19yb3V0ZUAzMDoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9taXNjZWxsYW5lb3VzLW9wcy9jb250cmFjdC5hbGdvLnRzOjE3OAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgbm90IE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gY2FuIG9ubHkgY2FsbCB3aGVuIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL21pc2NlbGxhbmVvdXMtb3BzL2NvbnRyYWN0LmFsZ28udHM6MwogICAgLy8gZXhwb3J0IGNsYXNzIE1pc2NlbGxhbmVvdXNPcHNDb250cmFjdCBleHRlbmRzIGFyYzQuQ29udHJhY3QgewogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgZXh0cmFjdCAyIDAKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDIKICAgIGJ0b2kKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDMKICAgIGJ0b2kKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9taXNjZWxsYW5lb3VzLW9wcy9jb250cmFjdC5hbGdvLnRzOjE3OAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X3NldGJpdF9ieXRlcwogICAgZHVwCiAgICBsZW4KICAgIGl0b2IKICAgIGV4dHJhY3QgNiAyCiAgICBzd2FwCiAgICBjb25jYXQKICAgIGJ5dGVjXzAgLy8gMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludGNfMCAvLyAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9zZXRiaXRfdWludDY0X3JvdXRlQDMxOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL21pc2NlbGxhbmVvdXMtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTg0CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBub3QgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBjYW4gb25seSBjYWxsIHdoZW4gbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvbWlzY2VsbGFuZW91cy1vcHMvY29udHJhY3QuYWxnby50czozCiAgICAvLyBleHBvcnQgY2xhc3MgTWlzY2VsbGFuZW91c09wc0NvbnRyYWN0IGV4dGVuZHMgYXJjNC5Db250cmFjdCB7CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBidG9pCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAyCiAgICBidG9pCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAzCiAgICBidG9pCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvbWlzY2VsbGFuZW91cy1vcHMvY29udHJhY3QuYWxnby50czoxODQKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV9zZXRiaXRfdWludDY0CiAgICBpdG9iCiAgICBieXRlY18wIC8vIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnRjXzAgLy8gMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfc2V0Ynl0ZV9yb3V0ZUAzMjoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9taXNjZWxsYW5lb3VzLW9wcy9jb250cmFjdC5hbGdvLnRzOjE5MAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgbm90IE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gY2FuIG9ubHkgY2FsbCB3aGVuIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL21pc2NlbGxhbmVvdXMtb3BzL2NvbnRyYWN0LmFsZ28udHM6MwogICAgLy8gZXhwb3J0IGNsYXNzIE1pc2NlbGxhbmVvdXNPcHNDb250cmFjdCBleHRlbmRzIGFyYzQuQ29udHJhY3QgewogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgZXh0cmFjdCAyIDAKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDIKICAgIGJ0b2kKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDMKICAgIGJ0b2kKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9taXNjZWxsYW5lb3VzLW9wcy9jb250cmFjdC5hbGdvLnRzOjE5MAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X3NldGJ5dGUKICAgIGR1cAogICAgbGVuCiAgICBpdG9iCiAgICBleHRyYWN0IDYgMgogICAgc3dhcAogICAgY29uY2F0CiAgICBieXRlY18wIC8vIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnRjXzAgLy8gMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfc2hsX3JvdXRlQDMzOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL21pc2NlbGxhbmVvdXMtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTk2CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBub3QgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBjYW4gb25seSBjYWxsIHdoZW4gbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvbWlzY2VsbGFuZW91cy1vcHMvY29udHJhY3QuYWxnby50czozCiAgICAvLyBleHBvcnQgY2xhc3MgTWlzY2VsbGFuZW91c09wc0NvbnRyYWN0IGV4dGVuZHMgYXJjNC5Db250cmFjdCB7CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBidG9pCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAyCiAgICBidG9pCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvbWlzY2VsbGFuZW91cy1vcHMvY29udHJhY3QuYWxnby50czoxOTYKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV9zaGwKICAgIGl0b2IKICAgIGJ5dGVjXzAgLy8gMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludGNfMCAvLyAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9zaHJfcm91dGVAMzQ6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvbWlzY2VsbGFuZW91cy1vcHMvY29udHJhY3QuYWxnby50czoyMDIKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIG5vdCBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGNhbiBvbmx5IGNhbGwgd2hlbiBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9taXNjZWxsYW5lb3VzLW9wcy9jb250cmFjdC5hbGdvLnRzOjMKICAgIC8vIGV4cG9ydCBjbGFzcyBNaXNjZWxsYW5lb3VzT3BzQ29udHJhY3QgZXh0ZW5kcyBhcmM0LkNvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGJ0b2kKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDIKICAgIGJ0b2kKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9taXNjZWxsYW5lb3VzLW9wcy9jb250cmFjdC5hbGdvLnRzOjIwMgogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X3NocgogICAgaXRvYgogICAgYnl0ZWNfMCAvLyAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50Y18wIC8vIDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X3NxcnRfcm91dGVAMzU6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvbWlzY2VsbGFuZW91cy1vcHMvY29udHJhY3QuYWxnby50czoyMDgKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIG5vdCBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGNhbiBvbmx5IGNhbGwgd2hlbiBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9taXNjZWxsYW5lb3VzLW9wcy9jb250cmFjdC5hbGdvLnRzOjMKICAgIC8vIGV4cG9ydCBjbGFzcyBNaXNjZWxsYW5lb3VzT3BzQ29udHJhY3QgZXh0ZW5kcyBhcmM0LkNvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGJ0b2kKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9taXNjZWxsYW5lb3VzLW9wcy9jb250cmFjdC5hbGdvLnRzOjIwOAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X3NxcnQKICAgIGl0b2IKICAgIGJ5dGVjXzAgLy8gMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludGNfMCAvLyAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9zdWJzdHJpbmdfcm91dGVAMzY6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvbWlzY2VsbGFuZW91cy1vcHMvY29udHJhY3QuYWxnby50czoyMTQKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIG5vdCBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGNhbiBvbmx5IGNhbGwgd2hlbiBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9taXNjZWxsYW5lb3VzLW9wcy9jb250cmFjdC5hbGdvLnRzOjMKICAgIC8vIGV4cG9ydCBjbGFzcyBNaXNjZWxsYW5lb3VzT3BzQ29udHJhY3QgZXh0ZW5kcyBhcmM0LkNvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGV4dHJhY3QgMiAwCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAyCiAgICBidG9pCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAzCiAgICBidG9pCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvbWlzY2VsbGFuZW91cy1vcHMvY29udHJhY3QuYWxnby50czoyMTQKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV9zdWJzdHJpbmcKICAgIGR1cAogICAgbGVuCiAgICBpdG9iCiAgICBleHRyYWN0IDYgMgogICAgc3dhcAogICAgY29uY2F0CiAgICBieXRlY18wIC8vIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnRjXzAgLy8gMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX19iYXJlX3JvdXRpbmdAMzk6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvbWlzY2VsbGFuZW91cy1vcHMvY29udHJhY3QuYWxnby50czozCiAgICAvLyBleHBvcnQgY2xhc3MgTWlzY2VsbGFuZW91c09wc0NvbnRyYWN0IGV4dGVuZHMgYXJjNC5Db250cmFjdCB7CiAgICB0eG4gT25Db21wbGV0aW9uCiAgICBibnogX19wdXlhX2FyYzRfcm91dGVyX19fYWZ0ZXJfaWZfZWxzZUA0MwogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgICEKICAgIGFzc2VydCAvLyBjYW4gb25seSBjYWxsIHdoZW4gY3JlYXRpbmcKICAgIGludGNfMCAvLyAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX2FmdGVyX2lmX2Vsc2VANDM6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvbWlzY2VsbGFuZW91cy1vcHMvY29udHJhY3QuYWxnby50czozCiAgICAvLyBleHBvcnQgY2xhc3MgTWlzY2VsbGFuZW91c09wc0NvbnRyYWN0IGV4dGVuZHMgYXJjNC5Db250cmFjdCB7CiAgICBpbnRjXzEgLy8gMAogICAgcmV0c3ViCgoKLy8gdGVzdHMvYXJ0aWZhY3RzL21pc2NlbGxhbmVvdXMtb3BzL2NvbnRyYWN0LmFsZ28udHM6Ok1pc2NlbGxhbmVvdXNPcHNDb250cmFjdC52ZXJpZnlfYWRkdyhhOiB1aW50NjQsIGI6IHVpbnQ2NCkgLT4gdWludDY0LCB1aW50NjQ6CnZlcmlmeV9hZGR3OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL21pc2NlbGxhbmVvdXMtb3BzL2NvbnRyYWN0LmFsZ28udHM6NC01CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gcHVibGljIHZlcmlmeV9hZGR3KGE6IHVpbnQ2NCwgYjogdWludDY0KTogcmVhZG9ubHkgW3VpbnQ2NCwgdWludDY0XSB7CiAgICBwcm90byAyIDIKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9taXNjZWxsYW5lb3VzLW9wcy9jb250cmFjdC5hbGdvLnRzOjYKICAgIC8vIGNvbnN0IHJlc3VsdCA9IG9wLmFkZHcoYSwgYikKICAgIGZyYW1lX2RpZyAtMgogICAgZnJhbWVfZGlnIC0xCiAgICBhZGR3CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvbWlzY2VsbGFuZW91cy1vcHMvY29udHJhY3QuYWxnby50czo3CiAgICAvLyByZXR1cm4gcmVzdWx0CiAgICByZXRzdWIKCgovLyB0ZXN0cy9hcnRpZmFjdHMvbWlzY2VsbGFuZW91cy1vcHMvY29udHJhY3QuYWxnby50czo6TWlzY2VsbGFuZW91c09wc0NvbnRyYWN0LnZlcmlmeV9iYXNlNjRfZGVjb2RlX3N0YW5kYXJkKGE6IGJ5dGVzKSAtPiBieXRlczoKdmVyaWZ5X2Jhc2U2NF9kZWNvZGVfc3RhbmRhcmQ6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvbWlzY2VsbGFuZW91cy1vcHMvY29udHJhY3QuYWxnby50czoxMC0xMQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIHB1YmxpYyB2ZXJpZnlfYmFzZTY0X2RlY29kZV9zdGFuZGFyZChhOiBieXRlcyk6IGJ5dGVzIHsKICAgIHByb3RvIDEgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL21pc2NlbGxhbmVvdXMtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTIKICAgIC8vIGNvbnN0IHJlc3VsdCA9IG9wLmJhc2U2NERlY29kZShCYXNlNjQuU3RkRW5jb2RpbmcsIGEpCiAgICBmcmFtZV9kaWcgLTEKICAgIGJhc2U2NF9kZWNvZGUgU3RkRW5jb2RpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9taXNjZWxsYW5lb3VzLW9wcy9jb250cmFjdC5hbGdvLnRzOjEzCiAgICAvLyByZXR1cm4gcmVzdWx0CiAgICByZXRzdWIKCgovLyB0ZXN0cy9hcnRpZmFjdHMvbWlzY2VsbGFuZW91cy1vcHMvY29udHJhY3QuYWxnby50czo6TWlzY2VsbGFuZW91c09wc0NvbnRyYWN0LnZlcmlmeV9iYXNlNjRfZGVjb2RlX3VybChhOiBieXRlcykgLT4gYnl0ZXM6CnZlcmlmeV9iYXNlNjRfZGVjb2RlX3VybDoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9taXNjZWxsYW5lb3VzLW9wcy9jb250cmFjdC5hbGdvLnRzOjE2LTE3CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gcHVibGljIHZlcmlmeV9iYXNlNjRfZGVjb2RlX3VybChhOiBieXRlcyk6IGJ5dGVzIHsKICAgIHByb3RvIDEgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL21pc2NlbGxhbmVvdXMtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTgKICAgIC8vIGNvbnN0IHJlc3VsdCA9IG9wLmJhc2U2NERlY29kZShCYXNlNjQuVVJMRW5jb2RpbmcsIGEpCiAgICBmcmFtZV9kaWcgLTEKICAgIGJhc2U2NF9kZWNvZGUgVVJMRW5jb2RpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9taXNjZWxsYW5lb3VzLW9wcy9jb250cmFjdC5hbGdvLnRzOjE5CiAgICAvLyByZXR1cm4gcmVzdWx0CiAgICByZXRzdWIKCgovLyB0ZXN0cy9hcnRpZmFjdHMvbWlzY2VsbGFuZW91cy1vcHMvY29udHJhY3QuYWxnby50czo6TWlzY2VsbGFuZW91c09wc0NvbnRyYWN0LnZlcmlmeV9ieXRlc19iaXRsZW4oYTogYnl0ZXMsIHBhZF9hX3NpemU6IHVpbnQ2NCkgLT4gdWludDY0Ogp2ZXJpZnlfYnl0ZXNfYml0bGVuOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL21pc2NlbGxhbmVvdXMtb3BzL2NvbnRyYWN0LmFsZ28udHM6MjItMjMKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBwdWJsaWMgdmVyaWZ5X2J5dGVzX2JpdGxlbihhOiBieXRlcywgcGFkX2Ffc2l6ZTogdWludDY0KTogdWludDY0IHsKICAgIHByb3RvIDIgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL21pc2NlbGxhbmVvdXMtb3BzL2NvbnRyYWN0LmFsZ28udHM6MjQKICAgIC8vIGNvbnN0IHBhZGRlZEEgPSBvcC5iemVybyhwYWRfYV9zaXplKS5jb25jYXQoYSkKICAgIGZyYW1lX2RpZyAtMQogICAgYnplcm8KICAgIGZyYW1lX2RpZyAtMgogICAgY29uY2F0CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvbWlzY2VsbGFuZW91cy1vcHMvY29udHJhY3QuYWxnby50czoyNQogICAgLy8gY29uc3QgcmVzdWx0ID0gb3AuYml0TGVuZ3RoKHBhZGRlZEEpCiAgICBiaXRsZW4KICAgIC8vIHRlc3RzL2FydGlmYWN0cy9taXNjZWxsYW5lb3VzLW9wcy9jb250cmFjdC5hbGdvLnRzOjI2CiAgICAvLyByZXR1cm4gcmVzdWx0CiAgICByZXRzdWIKCgovLyB0ZXN0cy9hcnRpZmFjdHMvbWlzY2VsbGFuZW91cy1vcHMvY29udHJhY3QuYWxnby50czo6TWlzY2VsbGFuZW91c09wc0NvbnRyYWN0LnZlcmlmeV91aW50NjRfYml0bGVuKGE6IHVpbnQ2NCkgLT4gdWludDY0Ogp2ZXJpZnlfdWludDY0X2JpdGxlbjoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9taXNjZWxsYW5lb3VzLW9wcy9jb250cmFjdC5hbGdvLnRzOjI5LTMwCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gcHVibGljIHZlcmlmeV91aW50NjRfYml0bGVuKGE6IHVpbnQ2NCk6IHVpbnQ2NCB7CiAgICBwcm90byAxIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9taXNjZWxsYW5lb3VzLW9wcy9jb250cmFjdC5hbGdvLnRzOjMxCiAgICAvLyBjb25zdCByZXN1bHQgPSBvcC5iaXRMZW5ndGgoYSkKICAgIGZyYW1lX2RpZyAtMQogICAgYml0bGVuCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvbWlzY2VsbGFuZW91cy1vcHMvY29udHJhY3QuYWxnby50czozMgogICAgLy8gcmV0dXJuIHJlc3VsdAogICAgcmV0c3ViCgoKLy8gdGVzdHMvYXJ0aWZhY3RzL21pc2NlbGxhbmVvdXMtb3BzL2NvbnRyYWN0LmFsZ28udHM6Ok1pc2NlbGxhbmVvdXNPcHNDb250cmFjdC52ZXJpZnlfYnNxcnQoYTogYnl0ZXMpIC0-IGJ5dGVzOgp2ZXJpZnlfYnNxcnQ6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvbWlzY2VsbGFuZW91cy1vcHMvY29udHJhY3QuYWxnby50czozNS0zNgogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIHB1YmxpYyB2ZXJpZnlfYnNxcnQoYTogYnl0ZXMpOiBieXRlcyB7CiAgICBwcm90byAxIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9taXNjZWxsYW5lb3VzLW9wcy9jb250cmFjdC5hbGdvLnRzOjM4CiAgICAvLyBjb25zdCByZXN1bHQgPSBvcC5ic3FydChhX2JpZ3VpbnQpCiAgICBmcmFtZV9kaWcgLTEKICAgIGJzcXJ0CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvbWlzY2VsbGFuZW91cy1vcHMvY29udHJhY3QuYWxnby50czozOQogICAgLy8gcmV0dXJuIEJ5dGVzKHJlc3VsdCkKICAgIHJldHN1YgoKCi8vIHRlc3RzL2FydGlmYWN0cy9taXNjZWxsYW5lb3VzLW9wcy9jb250cmFjdC5hbGdvLnRzOjpNaXNjZWxsYW5lb3VzT3BzQ29udHJhY3QudmVyaWZ5X2J0b2koYTogYnl0ZXMpIC0-IHVpbnQ2NDoKdmVyaWZ5X2J0b2k6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvbWlzY2VsbGFuZW91cy1vcHMvY29udHJhY3QuYWxnby50czo0Mi00MwogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIHB1YmxpYyB2ZXJpZnlfYnRvaShhOiBieXRlcyk6IHVpbnQ2NCB7CiAgICBwcm90byAxIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9taXNjZWxsYW5lb3VzLW9wcy9jb250cmFjdC5hbGdvLnRzOjQ0CiAgICAvLyBjb25zdCByZXN1bHQgPSBvcC5idG9pKGEpCiAgICBmcmFtZV9kaWcgLTEKICAgIGJ0b2kKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9taXNjZWxsYW5lb3VzLW9wcy9jb250cmFjdC5hbGdvLnRzOjQ1CiAgICAvLyByZXR1cm4gcmVzdWx0CiAgICByZXRzdWIKCgovLyB0ZXN0cy9hcnRpZmFjdHMvbWlzY2VsbGFuZW91cy1vcHMvY29udHJhY3QuYWxnby50czo6TWlzY2VsbGFuZW91c09wc0NvbnRyYWN0LnZlcmlmeV9iemVybyhhOiB1aW50NjQpIC0-IGJ5dGVzOgp2ZXJpZnlfYnplcm86CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvbWlzY2VsbGFuZW91cy1vcHMvY29udHJhY3QuYWxnby50czo0OC00OQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIHB1YmxpYyB2ZXJpZnlfYnplcm8oYTogdWludDY0KTogYnl0ZXMgewogICAgcHJvdG8gMSAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvbWlzY2VsbGFuZW91cy1vcHMvY29udHJhY3QuYWxnby50czo1MAogICAgLy8gY29uc3QgcmVzdWx0ID0gb3AuYnplcm8oYSkKICAgIGZyYW1lX2RpZyAtMQogICAgYnplcm8KICAgIC8vIHRlc3RzL2FydGlmYWN0cy9taXNjZWxsYW5lb3VzLW9wcy9jb250cmFjdC5hbGdvLnRzOjUxCiAgICAvLyByZXR1cm4gb3Auc2hhMjU2KHJlc3VsdCkKICAgIHNoYTI1NgogICAgcmV0c3ViCgoKLy8gdGVzdHMvYXJ0aWZhY3RzL21pc2NlbGxhbmVvdXMtb3BzL2NvbnRyYWN0LmFsZ28udHM6Ok1pc2NlbGxhbmVvdXNPcHNDb250cmFjdC52ZXJpZnlfY29uY2F0KGE6IGJ5dGVzLCBiOiBieXRlcywgcGFkX2Ffc2l6ZTogdWludDY0LCBwYWRfYl9zaXplOiB1aW50NjQpIC0-IGJ5dGVzOgp2ZXJpZnlfY29uY2F0OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL21pc2NlbGxhbmVvdXMtb3BzL2NvbnRyYWN0LmFsZ28udHM6NTQtNTUKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBwdWJsaWMgdmVyaWZ5X2NvbmNhdChhOiBieXRlcywgYjogYnl0ZXMsIHBhZF9hX3NpemU6IHVpbnQ2NCwgcGFkX2Jfc2l6ZTogdWludDY0KTogYnl0ZXMgewogICAgcHJvdG8gNCAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvbWlzY2VsbGFuZW91cy1vcHMvY29udHJhY3QuYWxnby50czo1NgogICAgLy8gY29uc3QgcGFkZGVkQSA9IG9wLmJ6ZXJvKHBhZF9hX3NpemUpLmNvbmNhdChhKQogICAgZnJhbWVfZGlnIC0yCiAgICBiemVybwogICAgZnJhbWVfZGlnIC00CiAgICBjb25jYXQKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9taXNjZWxsYW5lb3VzLW9wcy9jb250cmFjdC5hbGdvLnRzOjU3CiAgICAvLyBjb25zdCBwYWRkZWRCID0gb3AuYnplcm8ocGFkX2Jfc2l6ZSkuY29uY2F0KGIpCiAgICBmcmFtZV9kaWcgLTEKICAgIGJ6ZXJvCiAgICBmcmFtZV9kaWcgLTMKICAgIGNvbmNhdAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL21pc2NlbGxhbmVvdXMtb3BzL2NvbnRyYWN0LmFsZ28udHM6NTgKICAgIC8vIGNvbnN0IHJlc3VsdCA9IHBhZGRlZEEuY29uY2F0KHBhZGRlZEIpCiAgICBjb25jYXQKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9taXNjZWxsYW5lb3VzLW9wcy9jb250cmFjdC5hbGdvLnRzOjU5CiAgICAvLyBjb25zdCByZXN1bHRIYXNoID0gb3Auc2hhMjU2KHJlc3VsdCkKICAgIHNoYTI1NgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL21pc2NlbGxhbmVvdXMtb3BzL2NvbnRyYWN0LmFsZ28udHM6NjAKICAgIC8vIHJldHVybiByZXN1bHRIYXNoCiAgICByZXRzdWIKCgovLyB0ZXN0cy9hcnRpZmFjdHMvbWlzY2VsbGFuZW91cy1vcHMvY29udHJhY3QuYWxnby50czo6TWlzY2VsbGFuZW91c09wc0NvbnRyYWN0LnZlcmlmeV9kaXZtb2R3KGE6IHVpbnQ2NCwgYjogdWludDY0LCBjOiB1aW50NjQsIGQ6IHVpbnQ2NCkgLT4gdWludDY0LCB1aW50NjQsIHVpbnQ2NCwgdWludDY0Ogp2ZXJpZnlfZGl2bW9kdzoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9taXNjZWxsYW5lb3VzLW9wcy9jb250cmFjdC5hbGdvLnRzOjYzLTY0CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gcHVibGljIHZlcmlmeV9kaXZtb2R3KGE6IHVpbnQ2NCwgYjogdWludDY0LCBjOiB1aW50NjQsIGQ6IHVpbnQ2NCk6IHJlYWRvbmx5IFt1aW50NjQsIHVpbnQ2NCwgdWludDY0LCB1aW50NjRdIHsKICAgIHByb3RvIDQgNAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL21pc2NlbGxhbmVvdXMtb3BzL2NvbnRyYWN0LmFsZ28udHM6NjUKICAgIC8vIGNvbnN0IHJlc3VsdCA9IG9wLmRpdm1vZHcoYSwgYiwgYywgZCkKICAgIGZyYW1lX2RpZyAtNAogICAgZnJhbWVfZGlnIC0zCiAgICBmcmFtZV9kaWcgLTIKICAgIGZyYW1lX2RpZyAtMQogICAgZGl2bW9kdwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL21pc2NlbGxhbmVvdXMtb3BzL2NvbnRyYWN0LmFsZ28udHM6NjYKICAgIC8vIHJldHVybiByZXN1bHQKICAgIHJldHN1YgoKCi8vIHRlc3RzL2FydGlmYWN0cy9taXNjZWxsYW5lb3VzLW9wcy9jb250cmFjdC5hbGdvLnRzOjpNaXNjZWxsYW5lb3VzT3BzQ29udHJhY3QudmVyaWZ5X2RpdncoYTogdWludDY0LCBiOiB1aW50NjQsIGM6IHVpbnQ2NCkgLT4gdWludDY0Ogp2ZXJpZnlfZGl2dzoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9taXNjZWxsYW5lb3VzLW9wcy9jb250cmFjdC5hbGdvLnRzOjY5LTcwCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gcHVibGljIHZlcmlmeV9kaXZ3KGE6IHVpbnQ2NCwgYjogdWludDY0LCBjOiB1aW50NjQpOiB1aW50NjQgewogICAgcHJvdG8gMyAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvbWlzY2VsbGFuZW91cy1vcHMvY29udHJhY3QuYWxnby50czo3MQogICAgLy8gY29uc3QgcmVzdWx0ID0gb3AuZGl2dyhhLCBiLCBjKQogICAgZnJhbWVfZGlnIC0zCiAgICBmcmFtZV9kaWcgLTIKICAgIGZyYW1lX2RpZyAtMQogICAgZGl2dwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL21pc2NlbGxhbmVvdXMtb3BzL2NvbnRyYWN0LmFsZ28udHM6NzIKICAgIC8vIHJldHVybiByZXN1bHQKICAgIHJldHN1YgoKCi8vIHRlc3RzL2FydGlmYWN0cy9taXNjZWxsYW5lb3VzLW9wcy9jb250cmFjdC5hbGdvLnRzOjpNaXNjZWxsYW5lb3VzT3BzQ29udHJhY3QudmVyaWZ5X2VycigpIC0-IHZvaWQ6CnZlcmlmeV9lcnI6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvbWlzY2VsbGFuZW91cy1vcHMvY29udHJhY3QuYWxnby50czo3NS03NgogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIHB1YmxpYyB2ZXJpZnlfZXJyKCk6IHZvaWQgewogICAgcHJvdG8gMCAwCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvbWlzY2VsbGFuZW91cy1vcHMvY29udHJhY3QuYWxnby50czo3NwogICAgLy8gZXJyKCkKICAgIGVycgoKCi8vIHRlc3RzL2FydGlmYWN0cy9taXNjZWxsYW5lb3VzLW9wcy9jb250cmFjdC5hbGdvLnRzOjpNaXNjZWxsYW5lb3VzT3BzQ29udHJhY3QudmVyaWZ5X2V4cChhOiB1aW50NjQsIGI6IHVpbnQ2NCkgLT4gdWludDY0Ogp2ZXJpZnlfZXhwOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL21pc2NlbGxhbmVvdXMtb3BzL2NvbnRyYWN0LmFsZ28udHM6ODAtODEKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBwdWJsaWMgdmVyaWZ5X2V4cChhOiB1aW50NjQsIGI6IHVpbnQ2NCk6IHVpbnQ2NCB7CiAgICBwcm90byAyIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9taXNjZWxsYW5lb3VzLW9wcy9jb250cmFjdC5hbGdvLnRzOjgyCiAgICAvLyBjb25zdCByZXN1bHQgPSBvcC5leHAoYSwgYikKICAgIGZyYW1lX2RpZyAtMgogICAgZnJhbWVfZGlnIC0xCiAgICBleHAKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9taXNjZWxsYW5lb3VzLW9wcy9jb250cmFjdC5hbGdvLnRzOjgzCiAgICAvLyByZXR1cm4gcmVzdWx0CiAgICByZXRzdWIKCgovLyB0ZXN0cy9hcnRpZmFjdHMvbWlzY2VsbGFuZW91cy1vcHMvY29udHJhY3QuYWxnby50czo6TWlzY2VsbGFuZW91c09wc0NvbnRyYWN0LnZlcmlmeV9leHB3KGE6IHVpbnQ2NCwgYjogdWludDY0KSAtPiB1aW50NjQsIHVpbnQ2NDoKdmVyaWZ5X2V4cHc6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvbWlzY2VsbGFuZW91cy1vcHMvY29udHJhY3QuYWxnby50czo4Ni04NwogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIHB1YmxpYyB2ZXJpZnlfZXhwdyhhOiB1aW50NjQsIGI6IHVpbnQ2NCk6IHJlYWRvbmx5IFt1aW50NjQsIHVpbnQ2NF0gewogICAgcHJvdG8gMiAyCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvbWlzY2VsbGFuZW91cy1vcHMvY29udHJhY3QuYWxnby50czo4OAogICAgLy8gY29uc3QgcmVzdWx0ID0gb3AuZXhwdyhhLCBiKQogICAgZnJhbWVfZGlnIC0yCiAgICBmcmFtZV9kaWcgLTEKICAgIGV4cHcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9taXNjZWxsYW5lb3VzLW9wcy9jb250cmFjdC5hbGdvLnRzOjg5CiAgICAvLyByZXR1cm4gcmVzdWx0CiAgICByZXRzdWIKCgovLyB0ZXN0cy9hcnRpZmFjdHMvbWlzY2VsbGFuZW91cy1vcHMvY29udHJhY3QuYWxnby50czo6TWlzY2VsbGFuZW91c09wc0NvbnRyYWN0LnZlcmlmeV9leHRyYWN0KGE6IGJ5dGVzLCBiOiB1aW50NjQsIGM6IHVpbnQ2NCkgLT4gYnl0ZXM6CnZlcmlmeV9leHRyYWN0OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL21pc2NlbGxhbmVvdXMtb3BzL2NvbnRyYWN0LmFsZ28udHM6OTItOTMKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBwdWJsaWMgdmVyaWZ5X2V4dHJhY3QoYTogYnl0ZXMsIGI6IHVpbnQ2NCwgYzogdWludDY0KTogYnl0ZXMgewogICAgcHJvdG8gMyAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvbWlzY2VsbGFuZW91cy1vcHMvY29udHJhY3QuYWxnby50czo5NAogICAgLy8gY29uc3QgcmVzdWx0ID0gb3AuZXh0cmFjdChhLCBiLCBjKQogICAgZnJhbWVfZGlnIC0zCiAgICBmcmFtZV9kaWcgLTIKICAgIGZyYW1lX2RpZyAtMQogICAgZXh0cmFjdDMKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9taXNjZWxsYW5lb3VzLW9wcy9jb250cmFjdC5hbGdvLnRzOjk1CiAgICAvLyByZXR1cm4gcmVzdWx0CiAgICByZXRzdWIKCgovLyB0ZXN0cy9hcnRpZmFjdHMvbWlzY2VsbGFuZW91cy1vcHMvY29udHJhY3QuYWxnby50czo6TWlzY2VsbGFuZW91c09wc0NvbnRyYWN0LnZlcmlmeV9leHRyYWN0X2Zyb21fMihhOiBieXRlcykgLT4gYnl0ZXM6CnZlcmlmeV9leHRyYWN0X2Zyb21fMjoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9taXNjZWxsYW5lb3VzLW9wcy9jb250cmFjdC5hbGdvLnRzOjk5LTEwMAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIHB1YmxpYyB2ZXJpZnlfZXh0cmFjdF9mcm9tXzIoYTogYnl0ZXMpOiBieXRlcyB7CiAgICBwcm90byAxIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9taXNjZWxsYW5lb3VzLW9wcy9jb250cmFjdC5hbGdvLnRzOjEwMQogICAgLy8gY29uc3QgcmVzdWx0ID0gb3AuZXh0cmFjdChhLCAyLCAwKQogICAgZnJhbWVfZGlnIC0xCiAgICBleHRyYWN0IDIgMAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL21pc2NlbGxhbmVvdXMtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTAyCiAgICAvLyByZXR1cm4gcmVzdWx0CiAgICByZXRzdWIKCgovLyB0ZXN0cy9hcnRpZmFjdHMvbWlzY2VsbGFuZW91cy1vcHMvY29udHJhY3QuYWxnby50czo6TWlzY2VsbGFuZW91c09wc0NvbnRyYWN0LnZlcmlmeV9leHRyYWN0X3VpbnQxNihhOiBieXRlcywgYjogdWludDY0KSAtPiB1aW50NjQ6CnZlcmlmeV9leHRyYWN0X3VpbnQxNjoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9taXNjZWxsYW5lb3VzLW9wcy9jb250cmFjdC5hbGdvLnRzOjEwNS0xMDYKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBwdWJsaWMgdmVyaWZ5X2V4dHJhY3RfdWludDE2KGE6IGJ5dGVzLCBiOiB1aW50NjQpOiB1aW50NjQgewogICAgcHJvdG8gMiAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvbWlzY2VsbGFuZW91cy1vcHMvY29udHJhY3QuYWxnby50czoxMDcKICAgIC8vIGNvbnN0IHJlc3VsdCA9IG9wLmV4dHJhY3RVaW50MTYoYSwgYikKICAgIGZyYW1lX2RpZyAtMgogICAgZnJhbWVfZGlnIC0xCiAgICBleHRyYWN0X3VpbnQxNgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL21pc2NlbGxhbmVvdXMtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTA4CiAgICAvLyByZXR1cm4gcmVzdWx0CiAgICByZXRzdWIKCgovLyB0ZXN0cy9hcnRpZmFjdHMvbWlzY2VsbGFuZW91cy1vcHMvY29udHJhY3QuYWxnby50czo6TWlzY2VsbGFuZW91c09wc0NvbnRyYWN0LnZlcmlmeV9leHRyYWN0X3VpbnQzMihhOiBieXRlcywgYjogdWludDY0KSAtPiB1aW50NjQ6CnZlcmlmeV9leHRyYWN0X3VpbnQzMjoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9taXNjZWxsYW5lb3VzLW9wcy9jb250cmFjdC5hbGdvLnRzOjExMS0xMTIKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBwdWJsaWMgdmVyaWZ5X2V4dHJhY3RfdWludDMyKGE6IGJ5dGVzLCBiOiB1aW50NjQpOiB1aW50NjQgewogICAgcHJvdG8gMiAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvbWlzY2VsbGFuZW91cy1vcHMvY29udHJhY3QuYWxnby50czoxMTMKICAgIC8vIGNvbnN0IHJlc3VsdCA9IG9wLmV4dHJhY3RVaW50MzIoYSwgYikKICAgIGZyYW1lX2RpZyAtMgogICAgZnJhbWVfZGlnIC0xCiAgICBleHRyYWN0X3VpbnQzMgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL21pc2NlbGxhbmVvdXMtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTE0CiAgICAvLyByZXR1cm4gcmVzdWx0CiAgICByZXRzdWIKCgovLyB0ZXN0cy9hcnRpZmFjdHMvbWlzY2VsbGFuZW91cy1vcHMvY29udHJhY3QuYWxnby50czo6TWlzY2VsbGFuZW91c09wc0NvbnRyYWN0LnZlcmlmeV9leHRyYWN0X3VpbnQ2NChhOiBieXRlcywgYjogdWludDY0KSAtPiB1aW50NjQ6CnZlcmlmeV9leHRyYWN0X3VpbnQ2NDoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9taXNjZWxsYW5lb3VzLW9wcy9jb250cmFjdC5hbGdvLnRzOjExNy0xMTgKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBwdWJsaWMgdmVyaWZ5X2V4dHJhY3RfdWludDY0KGE6IGJ5dGVzLCBiOiB1aW50NjQpOiB1aW50NjQgewogICAgcHJvdG8gMiAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvbWlzY2VsbGFuZW91cy1vcHMvY29udHJhY3QuYWxnby50czoxMTkKICAgIC8vIGNvbnN0IHJlc3VsdCA9IG9wLmV4dHJhY3RVaW50NjQoYSwgYikKICAgIGZyYW1lX2RpZyAtMgogICAgZnJhbWVfZGlnIC0xCiAgICBleHRyYWN0X3VpbnQ2NAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL21pc2NlbGxhbmVvdXMtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTIwCiAgICAvLyByZXR1cm4gcmVzdWx0CiAgICByZXRzdWIKCgovLyB0ZXN0cy9hcnRpZmFjdHMvbWlzY2VsbGFuZW91cy1vcHMvY29udHJhY3QuYWxnby50czo6TWlzY2VsbGFuZW91c09wc0NvbnRyYWN0LnZlcmlmeV9nZXRiaXRfYnl0ZXMoYTogYnl0ZXMsIGI6IHVpbnQ2NCkgLT4gdWludDY0Ogp2ZXJpZnlfZ2V0Yml0X2J5dGVzOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL21pc2NlbGxhbmVvdXMtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTIzLTEyNAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIHB1YmxpYyB2ZXJpZnlfZ2V0Yml0X2J5dGVzKGE6IGJ5dGVzLCBiOiB1aW50NjQpOiB1aW50NjQgewogICAgcHJvdG8gMiAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvbWlzY2VsbGFuZW91cy1vcHMvY29udHJhY3QuYWxnby50czoxMjUKICAgIC8vIGNvbnN0IHJlc3VsdCA9IG9wLmdldEJpdChhLCBiKQogICAgZnJhbWVfZGlnIC0yCiAgICBmcmFtZV9kaWcgLTEKICAgIGdldGJpdAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL21pc2NlbGxhbmVvdXMtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTI2CiAgICAvLyByZXR1cm4gcmVzdWx0CiAgICByZXRzdWIKCgovLyB0ZXN0cy9hcnRpZmFjdHMvbWlzY2VsbGFuZW91cy1vcHMvY29udHJhY3QuYWxnby50czo6TWlzY2VsbGFuZW91c09wc0NvbnRyYWN0LnZlcmlmeV9nZXRiaXRfdWludDY0KGE6IHVpbnQ2NCwgYjogdWludDY0KSAtPiB1aW50NjQ6CnZlcmlmeV9nZXRiaXRfdWludDY0OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL21pc2NlbGxhbmVvdXMtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTI5LTEzMAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIHB1YmxpYyB2ZXJpZnlfZ2V0Yml0X3VpbnQ2NChhOiB1aW50NjQsIGI6IHVpbnQ2NCk6IHVpbnQ2NCB7CiAgICBwcm90byAyIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9taXNjZWxsYW5lb3VzLW9wcy9jb250cmFjdC5hbGdvLnRzOjEzMQogICAgLy8gY29uc3QgcmVzdWx0ID0gb3AuZ2V0Qml0KGEsIGIpCiAgICBmcmFtZV9kaWcgLTIKICAgIGZyYW1lX2RpZyAtMQogICAgZ2V0Yml0CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvbWlzY2VsbGFuZW91cy1vcHMvY29udHJhY3QuYWxnby50czoxMzIKICAgIC8vIHJldHVybiByZXN1bHQKICAgIHJldHN1YgoKCi8vIHRlc3RzL2FydGlmYWN0cy9taXNjZWxsYW5lb3VzLW9wcy9jb250cmFjdC5hbGdvLnRzOjpNaXNjZWxsYW5lb3VzT3BzQ29udHJhY3QudmVyaWZ5X2dldGJ5dGUoYTogYnl0ZXMsIGI6IHVpbnQ2NCkgLT4gdWludDY0Ogp2ZXJpZnlfZ2V0Ynl0ZToKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9taXNjZWxsYW5lb3VzLW9wcy9jb250cmFjdC5hbGdvLnRzOjEzNS0xMzYKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBwdWJsaWMgdmVyaWZ5X2dldGJ5dGUoYTogYnl0ZXMsIGI6IHVpbnQ2NCk6IHVpbnQ2NCB7CiAgICBwcm90byAyIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9taXNjZWxsYW5lb3VzLW9wcy9jb250cmFjdC5hbGdvLnRzOjEzNwogICAgLy8gY29uc3QgcmVzdWx0ID0gb3AuZ2V0Qnl0ZShhLCBiKQogICAgZnJhbWVfZGlnIC0yCiAgICBmcmFtZV9kaWcgLTEKICAgIGdldGJ5dGUKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9taXNjZWxsYW5lb3VzLW9wcy9jb250cmFjdC5hbGdvLnRzOjEzOAogICAgLy8gcmV0dXJuIHJlc3VsdAogICAgcmV0c3ViCgoKLy8gdGVzdHMvYXJ0aWZhY3RzL21pc2NlbGxhbmVvdXMtb3BzL2NvbnRyYWN0LmFsZ28udHM6Ok1pc2NlbGxhbmVvdXNPcHNDb250cmFjdC52ZXJpZnlfaXRvYihhOiB1aW50NjQpIC0-IGJ5dGVzOgp2ZXJpZnlfaXRvYjoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9taXNjZWxsYW5lb3VzLW9wcy9jb250cmFjdC5hbGdvLnRzOjE0MS0xNDIKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBwdWJsaWMgdmVyaWZ5X2l0b2IoYTogdWludDY0KTogYnl0ZXMgewogICAgcHJvdG8gMSAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvbWlzY2VsbGFuZW91cy1vcHMvY29udHJhY3QuYWxnby50czoxNDMKICAgIC8vIGNvbnN0IHJlc3VsdCA9IG9wLml0b2IoYSkKICAgIGZyYW1lX2RpZyAtMQogICAgaXRvYgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL21pc2NlbGxhbmVvdXMtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTQ0CiAgICAvLyByZXR1cm4gcmVzdWx0CiAgICByZXRzdWIKCgovLyB0ZXN0cy9hcnRpZmFjdHMvbWlzY2VsbGFuZW91cy1vcHMvY29udHJhY3QuYWxnby50czo6TWlzY2VsbGFuZW91c09wc0NvbnRyYWN0LnZlcmlmeV9ieXRlc19sZW4oYTogYnl0ZXMsIHBhZF9hX3NpemU6IHVpbnQ2NCkgLT4gdWludDY0Ogp2ZXJpZnlfYnl0ZXNfbGVuOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL21pc2NlbGxhbmVvdXMtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTQ3LTE0OAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIHB1YmxpYyB2ZXJpZnlfYnl0ZXNfbGVuKGE6IGJ5dGVzLCBwYWRfYV9zaXplOiB1aW50NjQpOiB1aW50NjQgewogICAgcHJvdG8gMiAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvbWlzY2VsbGFuZW91cy1vcHMvY29udHJhY3QuYWxnby50czoxNDkKICAgIC8vIGNvbnN0IHBhZGRlZEEgPSBvcC5iemVybyhwYWRfYV9zaXplKS5jb25jYXQoYSkKICAgIGZyYW1lX2RpZyAtMQogICAgYnplcm8KICAgIGZyYW1lX2RpZyAtMgogICAgY29uY2F0CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvbWlzY2VsbGFuZW91cy1vcHMvY29udHJhY3QuYWxnby50czoxNTAKICAgIC8vIGNvbnN0IHJlc3VsdCA9IG9wLmxlbihwYWRkZWRBKQogICAgbGVuCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvbWlzY2VsbGFuZW91cy1vcHMvY29udHJhY3QuYWxnby50czoxNTEKICAgIC8vIHJldHVybiByZXN1bHQKICAgIHJldHN1YgoKCi8vIHRlc3RzL2FydGlmYWN0cy9taXNjZWxsYW5lb3VzLW9wcy9jb250cmFjdC5hbGdvLnRzOjpNaXNjZWxsYW5lb3VzT3BzQ29udHJhY3QudmVyaWZ5X211bHcoYTogdWludDY0LCBiOiB1aW50NjQpIC0-IHVpbnQ2NCwgdWludDY0Ogp2ZXJpZnlfbXVsdzoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9taXNjZWxsYW5lb3VzLW9wcy9jb250cmFjdC5hbGdvLnRzOjE1NC0xNTUKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBwdWJsaWMgdmVyaWZ5X211bHcoYTogdWludDY0LCBiOiB1aW50NjQpOiByZWFkb25seSBbdWludDY0LCB1aW50NjRdIHsKICAgIHByb3RvIDIgMgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL21pc2NlbGxhbmVvdXMtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTU2CiAgICAvLyBjb25zdCByZXN1bHQgPSBvcC5tdWx3KGEsIGIpCiAgICBmcmFtZV9kaWcgLTIKICAgIGZyYW1lX2RpZyAtMQogICAgbXVsdwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL21pc2NlbGxhbmVvdXMtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTU3CiAgICAvLyByZXR1cm4gcmVzdWx0CiAgICByZXRzdWIKCgovLyB0ZXN0cy9hcnRpZmFjdHMvbWlzY2VsbGFuZW91cy1vcHMvY29udHJhY3QuYWxnby50czo6TWlzY2VsbGFuZW91c09wc0NvbnRyYWN0LnZlcmlmeV9yZXBsYWNlKGE6IGJ5dGVzLCBiOiB1aW50NjQsIGM6IGJ5dGVzKSAtPiBieXRlczoKdmVyaWZ5X3JlcGxhY2U6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvbWlzY2VsbGFuZW91cy1vcHMvY29udHJhY3QuYWxnby50czoxNjAtMTYxCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gcHVibGljIHZlcmlmeV9yZXBsYWNlKGE6IGJ5dGVzLCBiOiB1aW50NjQsIGM6IGJ5dGVzKTogYnl0ZXMgewogICAgcHJvdG8gMyAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvbWlzY2VsbGFuZW91cy1vcHMvY29udHJhY3QuYWxnby50czoxNjIKICAgIC8vIGNvbnN0IHJlc3VsdCA9IG9wLnJlcGxhY2UoYSwgYiwgYykKICAgIGZyYW1lX2RpZyAtMwogICAgZnJhbWVfZGlnIC0yCiAgICBmcmFtZV9kaWcgLTEKICAgIHJlcGxhY2UzCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvbWlzY2VsbGFuZW91cy1vcHMvY29udHJhY3QuYWxnby50czoxNjMKICAgIC8vIHJldHVybiByZXN1bHQKICAgIHJldHN1YgoKCi8vIHRlc3RzL2FydGlmYWN0cy9taXNjZWxsYW5lb3VzLW9wcy9jb250cmFjdC5hbGdvLnRzOjpNaXNjZWxsYW5lb3VzT3BzQ29udHJhY3QudmVyaWZ5X3NlbGVjdF9ieXRlcyhhOiBieXRlcywgYjogYnl0ZXMsIGM6IHVpbnQ2NCkgLT4gYnl0ZXM6CnZlcmlmeV9zZWxlY3RfYnl0ZXM6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvbWlzY2VsbGFuZW91cy1vcHMvY29udHJhY3QuYWxnby50czoxNjYtMTY3CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gcHVibGljIHZlcmlmeV9zZWxlY3RfYnl0ZXMoYTogYnl0ZXMsIGI6IGJ5dGVzLCBjOiB1aW50NjQpOiBieXRlcyB7CiAgICBwcm90byAzIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9taXNjZWxsYW5lb3VzLW9wcy9jb250cmFjdC5hbGdvLnRzOjE2OAogICAgLy8gY29uc3QgcmVzdWx0ID0gb3Auc2VsZWN0KGEsIGIsIGMpCiAgICBmcmFtZV9kaWcgLTMKICAgIGZyYW1lX2RpZyAtMgogICAgZnJhbWVfZGlnIC0xCiAgICBzZWxlY3QKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9taXNjZWxsYW5lb3VzLW9wcy9jb250cmFjdC5hbGdvLnRzOjE2OQogICAgLy8gcmV0dXJuIHJlc3VsdAogICAgcmV0c3ViCgoKLy8gdGVzdHMvYXJ0aWZhY3RzL21pc2NlbGxhbmVvdXMtb3BzL2NvbnRyYWN0LmFsZ28udHM6Ok1pc2NlbGxhbmVvdXNPcHNDb250cmFjdC52ZXJpZnlfc2VsZWN0X3VpbnQ2NChhOiB1aW50NjQsIGI6IHVpbnQ2NCwgYzogdWludDY0KSAtPiB1aW50NjQ6CnZlcmlmeV9zZWxlY3RfdWludDY0OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL21pc2NlbGxhbmVvdXMtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTcyLTE3MwogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIHB1YmxpYyB2ZXJpZnlfc2VsZWN0X3VpbnQ2NChhOiB1aW50NjQsIGI6IHVpbnQ2NCwgYzogdWludDY0KTogdWludDY0IHsKICAgIHByb3RvIDMgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL21pc2NlbGxhbmVvdXMtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTc0CiAgICAvLyBjb25zdCByZXN1bHQgPSBvcC5zZWxlY3QoYSwgYiwgYykKICAgIGZyYW1lX2RpZyAtMwogICAgZnJhbWVfZGlnIC0yCiAgICBmcmFtZV9kaWcgLTEKICAgIHNlbGVjdAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL21pc2NlbGxhbmVvdXMtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTc1CiAgICAvLyByZXR1cm4gcmVzdWx0CiAgICByZXRzdWIKCgovLyB0ZXN0cy9hcnRpZmFjdHMvbWlzY2VsbGFuZW91cy1vcHMvY29udHJhY3QuYWxnby50czo6TWlzY2VsbGFuZW91c09wc0NvbnRyYWN0LnZlcmlmeV9zZXRiaXRfYnl0ZXMoYTogYnl0ZXMsIGI6IHVpbnQ2NCwgYzogdWludDY0KSAtPiBieXRlczoKdmVyaWZ5X3NldGJpdF9ieXRlczoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9taXNjZWxsYW5lb3VzLW9wcy9jb250cmFjdC5hbGdvLnRzOjE3OC0xNzkKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBwdWJsaWMgdmVyaWZ5X3NldGJpdF9ieXRlcyhhOiBieXRlcywgYjogdWludDY0LCBjOiB1aW50NjQpOiBieXRlcyB7CiAgICBwcm90byAzIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9taXNjZWxsYW5lb3VzLW9wcy9jb250cmFjdC5hbGdvLnRzOjE4MAogICAgLy8gY29uc3QgcmVzdWx0ID0gb3Auc2V0Qml0KGEsIGIsIGMpCiAgICBmcmFtZV9kaWcgLTMKICAgIGZyYW1lX2RpZyAtMgogICAgZnJhbWVfZGlnIC0xCiAgICBzZXRiaXQKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9taXNjZWxsYW5lb3VzLW9wcy9jb250cmFjdC5hbGdvLnRzOjE4MQogICAgLy8gcmV0dXJuIHJlc3VsdAogICAgcmV0c3ViCgoKLy8gdGVzdHMvYXJ0aWZhY3RzL21pc2NlbGxhbmVvdXMtb3BzL2NvbnRyYWN0LmFsZ28udHM6Ok1pc2NlbGxhbmVvdXNPcHNDb250cmFjdC52ZXJpZnlfc2V0Yml0X3VpbnQ2NChhOiB1aW50NjQsIGI6IHVpbnQ2NCwgYzogdWludDY0KSAtPiB1aW50NjQ6CnZlcmlmeV9zZXRiaXRfdWludDY0OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL21pc2NlbGxhbmVvdXMtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTg0LTE4NQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIHB1YmxpYyB2ZXJpZnlfc2V0Yml0X3VpbnQ2NChhOiB1aW50NjQsIGI6IHVpbnQ2NCwgYzogdWludDY0KTogdWludDY0IHsKICAgIHByb3RvIDMgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL21pc2NlbGxhbmVvdXMtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTg2CiAgICAvLyBjb25zdCByZXN1bHQgPSBvcC5zZXRCaXQoYSwgYiwgYykKICAgIGZyYW1lX2RpZyAtMwogICAgZnJhbWVfZGlnIC0yCiAgICBmcmFtZV9kaWcgLTEKICAgIHNldGJpdAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL21pc2NlbGxhbmVvdXMtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTg3CiAgICAvLyByZXR1cm4gcmVzdWx0CiAgICByZXRzdWIKCgovLyB0ZXN0cy9hcnRpZmFjdHMvbWlzY2VsbGFuZW91cy1vcHMvY29udHJhY3QuYWxnby50czo6TWlzY2VsbGFuZW91c09wc0NvbnRyYWN0LnZlcmlmeV9zZXRieXRlKGE6IGJ5dGVzLCBiOiB1aW50NjQsIGM6IHVpbnQ2NCkgLT4gYnl0ZXM6CnZlcmlmeV9zZXRieXRlOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL21pc2NlbGxhbmVvdXMtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTkwLTE5MQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIHB1YmxpYyB2ZXJpZnlfc2V0Ynl0ZShhOiBieXRlcywgYjogdWludDY0LCBjOiB1aW50NjQpOiBieXRlcyB7CiAgICBwcm90byAzIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9taXNjZWxsYW5lb3VzLW9wcy9jb250cmFjdC5hbGdvLnRzOjE5MgogICAgLy8gY29uc3QgcmVzdWx0ID0gb3Auc2V0Qnl0ZShhLCBiLCBjKQogICAgZnJhbWVfZGlnIC0zCiAgICBmcmFtZV9kaWcgLTIKICAgIGZyYW1lX2RpZyAtMQogICAgc2V0Ynl0ZQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL21pc2NlbGxhbmVvdXMtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTkzCiAgICAvLyByZXR1cm4gcmVzdWx0CiAgICByZXRzdWIKCgovLyB0ZXN0cy9hcnRpZmFjdHMvbWlzY2VsbGFuZW91cy1vcHMvY29udHJhY3QuYWxnby50czo6TWlzY2VsbGFuZW91c09wc0NvbnRyYWN0LnZlcmlmeV9zaGwoYTogdWludDY0LCBiOiB1aW50NjQpIC0-IHVpbnQ2NDoKdmVyaWZ5X3NobDoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9taXNjZWxsYW5lb3VzLW9wcy9jb250cmFjdC5hbGdvLnRzOjE5Ni0xOTcKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBwdWJsaWMgdmVyaWZ5X3NobChhOiB1aW50NjQsIGI6IHVpbnQ2NCk6IHVpbnQ2NCB7CiAgICBwcm90byAyIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9taXNjZWxsYW5lb3VzLW9wcy9jb250cmFjdC5hbGdvLnRzOjE5OAogICAgLy8gY29uc3QgcmVzdWx0ID0gb3Auc2hsKGEsIGIpCiAgICBmcmFtZV9kaWcgLTIKICAgIGZyYW1lX2RpZyAtMQogICAgc2hsCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvbWlzY2VsbGFuZW91cy1vcHMvY29udHJhY3QuYWxnby50czoxOTkKICAgIC8vIHJldHVybiByZXN1bHQKICAgIHJldHN1YgoKCi8vIHRlc3RzL2FydGlmYWN0cy9taXNjZWxsYW5lb3VzLW9wcy9jb250cmFjdC5hbGdvLnRzOjpNaXNjZWxsYW5lb3VzT3BzQ29udHJhY3QudmVyaWZ5X3NocihhOiB1aW50NjQsIGI6IHVpbnQ2NCkgLT4gdWludDY0Ogp2ZXJpZnlfc2hyOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL21pc2NlbGxhbmVvdXMtb3BzL2NvbnRyYWN0LmFsZ28udHM6MjAyLTIwMwogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIHB1YmxpYyB2ZXJpZnlfc2hyKGE6IHVpbnQ2NCwgYjogdWludDY0KTogdWludDY0IHsKICAgIHByb3RvIDIgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL21pc2NlbGxhbmVvdXMtb3BzL2NvbnRyYWN0LmFsZ28udHM6MjA0CiAgICAvLyBjb25zdCByZXN1bHQgPSBvcC5zaHIoYSwgYikKICAgIGZyYW1lX2RpZyAtMgogICAgZnJhbWVfZGlnIC0xCiAgICBzaHIKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9taXNjZWxsYW5lb3VzLW9wcy9jb250cmFjdC5hbGdvLnRzOjIwNQogICAgLy8gcmV0dXJuIHJlc3VsdAogICAgcmV0c3ViCgoKLy8gdGVzdHMvYXJ0aWZhY3RzL21pc2NlbGxhbmVvdXMtb3BzL2NvbnRyYWN0LmFsZ28udHM6Ok1pc2NlbGxhbmVvdXNPcHNDb250cmFjdC52ZXJpZnlfc3FydChhOiB1aW50NjQpIC0-IHVpbnQ2NDoKdmVyaWZ5X3NxcnQ6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvbWlzY2VsbGFuZW91cy1vcHMvY29udHJhY3QuYWxnby50czoyMDgtMjA5CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gcHVibGljIHZlcmlmeV9zcXJ0KGE6IHVpbnQ2NCk6IHVpbnQ2NCB7CiAgICBwcm90byAxIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9taXNjZWxsYW5lb3VzLW9wcy9jb250cmFjdC5hbGdvLnRzOjIxMAogICAgLy8gY29uc3QgcmVzdWx0ID0gb3Auc3FydChhKQogICAgZnJhbWVfZGlnIC0xCiAgICBzcXJ0CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvbWlzY2VsbGFuZW91cy1vcHMvY29udHJhY3QuYWxnby50czoyMTEKICAgIC8vIHJldHVybiByZXN1bHQKICAgIHJldHN1YgoKCi8vIHRlc3RzL2FydGlmYWN0cy9taXNjZWxsYW5lb3VzLW9wcy9jb250cmFjdC5hbGdvLnRzOjpNaXNjZWxsYW5lb3VzT3BzQ29udHJhY3QudmVyaWZ5X3N1YnN0cmluZyhhOiBieXRlcywgYjogdWludDY0LCBjOiB1aW50NjQpIC0-IGJ5dGVzOgp2ZXJpZnlfc3Vic3RyaW5nOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL21pc2NlbGxhbmVvdXMtb3BzL2NvbnRyYWN0LmFsZ28udHM6MjE0LTIxNQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIHB1YmxpYyB2ZXJpZnlfc3Vic3RyaW5nKGE6IGJ5dGVzLCBiOiB1aW50NjQsIGM6IHVpbnQ2NCk6IGJ5dGVzIHsKICAgIHByb3RvIDMgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL21pc2NlbGxhbmVvdXMtb3BzL2NvbnRyYWN0LmFsZ28udHM6MjE2CiAgICAvLyBjb25zdCByZXN1bHQgPSBvcC5zdWJzdHJpbmcoYSwgYiwgYykKICAgIGZyYW1lX2RpZyAtMwogICAgZnJhbWVfZGlnIC0yCiAgICBmcmFtZV9kaWcgLTEKICAgIHN1YnN0cmluZzMKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9taXNjZWxsYW5lb3VzLW9wcy9jb250cmFjdC5hbGdvLnRzOjIxNwogICAgLy8gcmV0dXJuIHJlc3VsdAogICAgcmV0c3ViCg==", - "clear": "I3ByYWdtYSB2ZXJzaW9uIDEwCgp0ZXN0cy9hcnRpZmFjdHMvbWlzY2VsbGFuZW91cy1vcHMvY29udHJhY3QuYWxnby50czo6TWlzY2VsbGFuZW91c09wc0NvbnRyYWN0LmNsZWFyU3RhdGVQcm9ncmFtOgogICAgcHVzaGludCAxIC8vIDEKICAgIHJldHVybgo=" - }, - "state": { - "global": { - "num_byte_slices": 0, - "num_uints": 0 - }, - "local": { - "num_byte_slices": 0, - "num_uints": 0 - } - }, - "schema": { - "global": { - "declared": {}, - "reserved": {} - }, - "local": { - "declared": {}, - "reserved": {} - } - }, - "contract": { - "name": "MiscellaneousOpsContract", - "methods": [ - { - "name": "verify_addw", - "args": [ - { - "type": "uint64", - "name": "a" - }, - { - "type": "uint64", - "name": "b" - } - ], - "readonly": false, - "returns": { - "type": "(uint64,uint64)" - } - }, - { - "name": "verify_base64_decode_standard", - "args": [ - { - "type": "byte[]", - "name": "a" - } - ], - "readonly": false, - "returns": { - "type": "byte[]" - } - }, - { - "name": "verify_base64_decode_url", - "args": [ - { - "type": "byte[]", - "name": "a" - } - ], - "readonly": false, - "returns": { - "type": "byte[]" - } - }, - { - "name": "verify_bytes_bitlen", - "args": [ - { - "type": "byte[]", - "name": "a" - }, - { - "type": "uint64", - "name": "pad_a_size" - } - ], - "readonly": false, - "returns": { - "type": "uint64" - } - }, - { - "name": "verify_uint64_bitlen", - "args": [ - { - "type": "uint64", - "name": "a" - } - ], - "readonly": false, - "returns": { - "type": "uint64" - } - }, - { - "name": "verify_bsqrt", - "args": [ - { - "type": "byte[]", - "name": "a" - } - ], - "readonly": false, - "returns": { - "type": "byte[]" - } - }, - { - "name": "verify_btoi", - "args": [ - { - "type": "byte[]", - "name": "a" - } - ], - "readonly": false, - "returns": { - "type": "uint64" - } - }, - { - "name": "verify_bzero", - "args": [ - { - "type": "uint64", - "name": "a" - } - ], - "readonly": false, - "returns": { - "type": "byte[]" - } - }, - { - "name": "verify_concat", - "args": [ - { - "type": "byte[]", - "name": "a" - }, - { - "type": "byte[]", - "name": "b" - }, - { - "type": "uint64", - "name": "pad_a_size" - }, - { - "type": "uint64", - "name": "pad_b_size" - } - ], - "readonly": false, - "returns": { - "type": "byte[]" - } - }, - { - "name": "verify_divmodw", - "args": [ - { - "type": "uint64", - "name": "a" - }, - { - "type": "uint64", - "name": "b" - }, - { - "type": "uint64", - "name": "c" - }, - { - "type": "uint64", - "name": "d" - } - ], - "readonly": false, - "returns": { - "type": "(uint64,uint64,uint64,uint64)" - } - }, - { - "name": "verify_divw", - "args": [ - { - "type": "uint64", - "name": "a" - }, - { - "type": "uint64", - "name": "b" - }, - { - "type": "uint64", - "name": "c" - } - ], - "readonly": false, - "returns": { - "type": "uint64" - } - }, - { - "name": "verify_err", - "args": [], - "readonly": false, - "returns": { - "type": "void" - } - }, - { - "name": "verify_exp", - "args": [ - { - "type": "uint64", - "name": "a" - }, - { - "type": "uint64", - "name": "b" - } - ], - "readonly": false, - "returns": { - "type": "uint64" - } - }, - { - "name": "verify_expw", - "args": [ - { - "type": "uint64", - "name": "a" - }, - { - "type": "uint64", - "name": "b" - } - ], - "readonly": false, - "returns": { - "type": "(uint64,uint64)" - } - }, - { - "name": "verify_extract", - "args": [ - { - "type": "byte[]", - "name": "a" - }, - { - "type": "uint64", - "name": "b" - }, - { - "type": "uint64", - "name": "c" - } - ], - "readonly": false, - "returns": { - "type": "byte[]" - } - }, - { - "name": "verify_extract_from_2", - "args": [ - { - "type": "byte[]", - "name": "a" - } - ], - "readonly": false, - "returns": { - "type": "byte[]" - } - }, - { - "name": "verify_extract_uint16", - "args": [ - { - "type": "byte[]", - "name": "a" - }, - { - "type": "uint64", - "name": "b" - } - ], - "readonly": false, - "returns": { - "type": "uint64" - } - }, - { - "name": "verify_extract_uint32", - "args": [ - { - "type": "byte[]", - "name": "a" - }, - { - "type": "uint64", - "name": "b" - } - ], - "readonly": false, - "returns": { - "type": "uint64" - } - }, - { - "name": "verify_extract_uint64", - "args": [ - { - "type": "byte[]", - "name": "a" - }, - { - "type": "uint64", - "name": "b" - } - ], - "readonly": false, - "returns": { - "type": "uint64" - } - }, - { - "name": "verify_getbit_bytes", - "args": [ - { - "type": "byte[]", - "name": "a" - }, - { - "type": "uint64", - "name": "b" - } - ], - "readonly": false, - "returns": { - "type": "uint64" - } - }, - { - "name": "verify_getbit_uint64", - "args": [ - { - "type": "uint64", - "name": "a" - }, - { - "type": "uint64", - "name": "b" - } - ], - "readonly": false, - "returns": { - "type": "uint64" - } - }, - { - "name": "verify_getbyte", - "args": [ - { - "type": "byte[]", - "name": "a" - }, - { - "type": "uint64", - "name": "b" - } - ], - "readonly": false, - "returns": { - "type": "uint64" - } - }, - { - "name": "verify_itob", - "args": [ - { - "type": "uint64", - "name": "a" - } - ], - "readonly": false, - "returns": { - "type": "byte[]" - } - }, - { - "name": "verify_bytes_len", - "args": [ - { - "type": "byte[]", - "name": "a" - }, - { - "type": "uint64", - "name": "pad_a_size" - } - ], - "readonly": false, - "returns": { - "type": "uint64" - } - }, - { - "name": "verify_mulw", - "args": [ - { - "type": "uint64", - "name": "a" - }, - { - "type": "uint64", - "name": "b" - } - ], - "readonly": false, - "returns": { - "type": "(uint64,uint64)" - } - }, - { - "name": "verify_replace", - "args": [ - { - "type": "byte[]", - "name": "a" - }, - { - "type": "uint64", - "name": "b" - }, - { - "type": "byte[]", - "name": "c" - } - ], - "readonly": false, - "returns": { - "type": "byte[]" - } - }, - { - "name": "verify_select_bytes", - "args": [ - { - "type": "byte[]", - "name": "a" - }, - { - "type": "byte[]", - "name": "b" - }, - { - "type": "uint64", - "name": "c" - } - ], - "readonly": false, - "returns": { - "type": "byte[]" - } - }, - { - "name": "verify_select_uint64", - "args": [ - { - "type": "uint64", - "name": "a" - }, - { - "type": "uint64", - "name": "b" - }, - { - "type": "uint64", - "name": "c" - } - ], - "readonly": false, - "returns": { - "type": "uint64" - } - }, - { - "name": "verify_setbit_bytes", - "args": [ - { - "type": "byte[]", - "name": "a" - }, - { - "type": "uint64", - "name": "b" - }, - { - "type": "uint64", - "name": "c" - } - ], - "readonly": false, - "returns": { - "type": "byte[]" - } - }, - { - "name": "verify_setbit_uint64", - "args": [ - { - "type": "uint64", - "name": "a" - }, - { - "type": "uint64", - "name": "b" - }, - { - "type": "uint64", - "name": "c" - } - ], - "readonly": false, - "returns": { - "type": "uint64" - } - }, - { - "name": "verify_setbyte", - "args": [ - { - "type": "byte[]", - "name": "a" - }, - { - "type": "uint64", - "name": "b" - }, - { - "type": "uint64", - "name": "c" - } - ], - "readonly": false, - "returns": { - "type": "byte[]" - } - }, - { - "name": "verify_shl", - "args": [ - { - "type": "uint64", - "name": "a" - }, - { - "type": "uint64", - "name": "b" - } - ], - "readonly": false, - "returns": { - "type": "uint64" - } - }, - { - "name": "verify_shr", - "args": [ - { - "type": "uint64", - "name": "a" - }, - { - "type": "uint64", - "name": "b" - } - ], - "readonly": false, - "returns": { - "type": "uint64" - } - }, - { - "name": "verify_sqrt", - "args": [ - { - "type": "uint64", - "name": "a" - } - ], - "readonly": false, - "returns": { - "type": "uint64" - } - }, - { - "name": "verify_substring", - "args": [ - { - "type": "byte[]", - "name": "a" - }, - { - "type": "uint64", - "name": "b" - }, - { - "type": "uint64", - "name": "c" - } - ], - "readonly": false, - "returns": { - "type": "byte[]" - } - } - ], - "networks": {} - }, - "bare_call_config": { - "no_op": "CREATE" - } -} diff --git a/tests/artifacts/miscellaneous-ops/data/MiscellaneousOpsContract.arc56.json b/tests/artifacts/miscellaneous-ops/data/MiscellaneousOpsContract.arc56.json deleted file mode 100644 index 2c01953..0000000 --- a/tests/artifacts/miscellaneous-ops/data/MiscellaneousOpsContract.arc56.json +++ /dev/null @@ -1,1024 +0,0 @@ -{ - "name": "MiscellaneousOpsContract", - "structs": {}, - "methods": [ - { - "name": "verify_addw", - "args": [ - { - "type": "uint64", - "name": "a" - }, - { - "type": "uint64", - "name": "b" - } - ], - "returns": { - "type": "(uint64,uint64)" - }, - "actions": { - "create": [], - "call": [ - "NoOp" - ] - }, - "readonly": false, - "events": [], - "recommendations": {} - }, - { - "name": "verify_base64_decode_standard", - "args": [ - { - "type": "byte[]", - "name": "a" - } - ], - "returns": { - "type": "byte[]" - }, - "actions": { - "create": [], - "call": [ - "NoOp" - ] - }, - "readonly": false, - "events": [], - "recommendations": {} - }, - { - "name": "verify_base64_decode_url", - "args": [ - { - "type": "byte[]", - "name": "a" - } - ], - "returns": { - "type": "byte[]" - }, - "actions": { - "create": [], - "call": [ - "NoOp" - ] - }, - "readonly": false, - "events": [], - "recommendations": {} - }, - { - "name": "verify_bytes_bitlen", - "args": [ - { - "type": "byte[]", - "name": "a" - }, - { - "type": "uint64", - "name": "pad_a_size" - } - ], - "returns": { - "type": "uint64" - }, - "actions": { - "create": [], - "call": [ - "NoOp" - ] - }, - "readonly": false, - "events": [], - "recommendations": {} - }, - { - "name": "verify_uint64_bitlen", - "args": [ - { - "type": "uint64", - "name": "a" - } - ], - "returns": { - "type": "uint64" - }, - "actions": { - "create": [], - "call": [ - "NoOp" - ] - }, - "readonly": false, - "events": [], - "recommendations": {} - }, - { - "name": "verify_bsqrt", - "args": [ - { - "type": "byte[]", - "name": "a" - } - ], - "returns": { - "type": "byte[]" - }, - "actions": { - "create": [], - "call": [ - "NoOp" - ] - }, - "readonly": false, - "events": [], - "recommendations": {} - }, - { - "name": "verify_btoi", - "args": [ - { - "type": "byte[]", - "name": "a" - } - ], - "returns": { - "type": "uint64" - }, - "actions": { - "create": [], - "call": [ - "NoOp" - ] - }, - "readonly": false, - "events": [], - "recommendations": {} - }, - { - "name": "verify_bzero", - "args": [ - { - "type": "uint64", - "name": "a" - } - ], - "returns": { - "type": "byte[]" - }, - "actions": { - "create": [], - "call": [ - "NoOp" - ] - }, - "readonly": false, - "events": [], - "recommendations": {} - }, - { - "name": "verify_concat", - "args": [ - { - "type": "byte[]", - "name": "a" - }, - { - "type": "byte[]", - "name": "b" - }, - { - "type": "uint64", - "name": "pad_a_size" - }, - { - "type": "uint64", - "name": "pad_b_size" - } - ], - "returns": { - "type": "byte[]" - }, - "actions": { - "create": [], - "call": [ - "NoOp" - ] - }, - "readonly": false, - "events": [], - "recommendations": {} - }, - { - "name": "verify_divmodw", - "args": [ - { - "type": "uint64", - "name": "a" - }, - { - "type": "uint64", - "name": "b" - }, - { - "type": "uint64", - "name": "c" - }, - { - "type": "uint64", - "name": "d" - } - ], - "returns": { - "type": "(uint64,uint64,uint64,uint64)" - }, - "actions": { - "create": [], - "call": [ - "NoOp" - ] - }, - "readonly": false, - "events": [], - "recommendations": {} - }, - { - "name": "verify_divw", - "args": [ - { - "type": "uint64", - "name": "a" - }, - { - "type": "uint64", - "name": "b" - }, - { - "type": "uint64", - "name": "c" - } - ], - "returns": { - "type": "uint64" - }, - "actions": { - "create": [], - "call": [ - "NoOp" - ] - }, - "readonly": false, - "events": [], - "recommendations": {} - }, - { - "name": "verify_err", - "args": [], - "returns": { - "type": "void" - }, - "actions": { - "create": [], - "call": [ - "NoOp" - ] - }, - "readonly": false, - "events": [], - "recommendations": {} - }, - { - "name": "verify_exp", - "args": [ - { - "type": "uint64", - "name": "a" - }, - { - "type": "uint64", - "name": "b" - } - ], - "returns": { - "type": "uint64" - }, - "actions": { - "create": [], - "call": [ - "NoOp" - ] - }, - "readonly": false, - "events": [], - "recommendations": {} - }, - { - "name": "verify_expw", - "args": [ - { - "type": "uint64", - "name": "a" - }, - { - "type": "uint64", - "name": "b" - } - ], - "returns": { - "type": "(uint64,uint64)" - }, - "actions": { - "create": [], - "call": [ - "NoOp" - ] - }, - "readonly": false, - "events": [], - "recommendations": {} - }, - { - "name": "verify_extract", - "args": [ - { - "type": "byte[]", - "name": "a" - }, - { - "type": "uint64", - "name": "b" - }, - { - "type": "uint64", - "name": "c" - } - ], - "returns": { - "type": "byte[]" - }, - "actions": { - "create": [], - "call": [ - "NoOp" - ] - }, - "readonly": false, - "events": [], - "recommendations": {} - }, - { - "name": "verify_extract_from_2", - "args": [ - { - "type": "byte[]", - "name": "a" - } - ], - "returns": { - "type": "byte[]" - }, - "actions": { - "create": [], - "call": [ - "NoOp" - ] - }, - "readonly": false, - "events": [], - "recommendations": {} - }, - { - "name": "verify_extract_uint16", - "args": [ - { - "type": "byte[]", - "name": "a" - }, - { - "type": "uint64", - "name": "b" - } - ], - "returns": { - "type": "uint64" - }, - "actions": { - "create": [], - "call": [ - "NoOp" - ] - }, - "readonly": false, - "events": [], - "recommendations": {} - }, - { - "name": "verify_extract_uint32", - "args": [ - { - "type": "byte[]", - "name": "a" - }, - { - "type": "uint64", - "name": "b" - } - ], - "returns": { - "type": "uint64" - }, - "actions": { - "create": [], - "call": [ - "NoOp" - ] - }, - "readonly": false, - "events": [], - "recommendations": {} - }, - { - "name": "verify_extract_uint64", - "args": [ - { - "type": "byte[]", - "name": "a" - }, - { - "type": "uint64", - "name": "b" - } - ], - "returns": { - "type": "uint64" - }, - "actions": { - "create": [], - "call": [ - "NoOp" - ] - }, - "readonly": false, - "events": [], - "recommendations": {} - }, - { - "name": "verify_getbit_bytes", - "args": [ - { - "type": "byte[]", - "name": "a" - }, - { - "type": "uint64", - "name": "b" - } - ], - "returns": { - "type": "uint64" - }, - "actions": { - "create": [], - "call": [ - "NoOp" - ] - }, - "readonly": false, - "events": [], - "recommendations": {} - }, - { - "name": "verify_getbit_uint64", - "args": [ - { - "type": "uint64", - "name": "a" - }, - { - "type": "uint64", - "name": "b" - } - ], - "returns": { - "type": "uint64" - }, - "actions": { - "create": [], - "call": [ - "NoOp" - ] - }, - "readonly": false, - "events": [], - "recommendations": {} - }, - { - "name": "verify_getbyte", - "args": [ - { - "type": "byte[]", - "name": "a" - }, - { - "type": "uint64", - "name": "b" - } - ], - "returns": { - "type": "uint64" - }, - "actions": { - "create": [], - "call": [ - "NoOp" - ] - }, - "readonly": false, - "events": [], - "recommendations": {} - }, - { - "name": "verify_itob", - "args": [ - { - "type": "uint64", - "name": "a" - } - ], - "returns": { - "type": "byte[]" - }, - "actions": { - "create": [], - "call": [ - "NoOp" - ] - }, - "readonly": false, - "events": [], - "recommendations": {} - }, - { - "name": "verify_bytes_len", - "args": [ - { - "type": "byte[]", - "name": "a" - }, - { - "type": "uint64", - "name": "pad_a_size" - } - ], - "returns": { - "type": "uint64" - }, - "actions": { - "create": [], - "call": [ - "NoOp" - ] - }, - "readonly": false, - "events": [], - "recommendations": {} - }, - { - "name": "verify_mulw", - "args": [ - { - "type": "uint64", - "name": "a" - }, - { - "type": "uint64", - "name": "b" - } - ], - "returns": { - "type": "(uint64,uint64)" - }, - "actions": { - "create": [], - "call": [ - "NoOp" - ] - }, - "readonly": false, - "events": [], - "recommendations": {} - }, - { - "name": "verify_replace", - "args": [ - { - "type": "byte[]", - "name": "a" - }, - { - "type": "uint64", - "name": "b" - }, - { - "type": "byte[]", - "name": "c" - } - ], - "returns": { - "type": "byte[]" - }, - "actions": { - "create": [], - "call": [ - "NoOp" - ] - }, - "readonly": false, - "events": [], - "recommendations": {} - }, - { - "name": "verify_select_bytes", - "args": [ - { - "type": "byte[]", - "name": "a" - }, - { - "type": "byte[]", - "name": "b" - }, - { - "type": "uint64", - "name": "c" - } - ], - "returns": { - "type": "byte[]" - }, - "actions": { - "create": [], - "call": [ - "NoOp" - ] - }, - "readonly": false, - "events": [], - "recommendations": {} - }, - { - "name": "verify_select_uint64", - "args": [ - { - "type": "uint64", - "name": "a" - }, - { - "type": "uint64", - "name": "b" - }, - { - "type": "uint64", - "name": "c" - } - ], - "returns": { - "type": "uint64" - }, - "actions": { - "create": [], - "call": [ - "NoOp" - ] - }, - "readonly": false, - "events": [], - "recommendations": {} - }, - { - "name": "verify_setbit_bytes", - "args": [ - { - "type": "byte[]", - "name": "a" - }, - { - "type": "uint64", - "name": "b" - }, - { - "type": "uint64", - "name": "c" - } - ], - "returns": { - "type": "byte[]" - }, - "actions": { - "create": [], - "call": [ - "NoOp" - ] - }, - "readonly": false, - "events": [], - "recommendations": {} - }, - { - "name": "verify_setbit_uint64", - "args": [ - { - "type": "uint64", - "name": "a" - }, - { - "type": "uint64", - "name": "b" - }, - { - "type": "uint64", - "name": "c" - } - ], - "returns": { - "type": "uint64" - }, - "actions": { - "create": [], - "call": [ - "NoOp" - ] - }, - "readonly": false, - "events": [], - "recommendations": {} - }, - { - "name": "verify_setbyte", - "args": [ - { - "type": "byte[]", - "name": "a" - }, - { - "type": "uint64", - "name": "b" - }, - { - "type": "uint64", - "name": "c" - } - ], - "returns": { - "type": "byte[]" - }, - "actions": { - "create": [], - "call": [ - "NoOp" - ] - }, - "readonly": false, - "events": [], - "recommendations": {} - }, - { - "name": "verify_shl", - "args": [ - { - "type": "uint64", - "name": "a" - }, - { - "type": "uint64", - "name": "b" - } - ], - "returns": { - "type": "uint64" - }, - "actions": { - "create": [], - "call": [ - "NoOp" - ] - }, - "readonly": false, - "events": [], - "recommendations": {} - }, - { - "name": "verify_shr", - "args": [ - { - "type": "uint64", - "name": "a" - }, - { - "type": "uint64", - "name": "b" - } - ], - "returns": { - "type": "uint64" - }, - "actions": { - "create": [], - "call": [ - "NoOp" - ] - }, - "readonly": false, - "events": [], - "recommendations": {} - }, - { - "name": "verify_sqrt", - "args": [ - { - "type": "uint64", - "name": "a" - } - ], - "returns": { - "type": "uint64" - }, - "actions": { - "create": [], - "call": [ - "NoOp" - ] - }, - "readonly": false, - "events": [], - "recommendations": {} - }, - { - "name": "verify_substring", - "args": [ - { - "type": "byte[]", - "name": "a" - }, - { - "type": "uint64", - "name": "b" - }, - { - "type": "uint64", - "name": "c" - } - ], - "returns": { - "type": "byte[]" - }, - "actions": { - "create": [], - "call": [ - "NoOp" - ] - }, - "readonly": false, - "events": [], - "recommendations": {} - } - ], - "arcs": [ - 22, - 28 - ], - "networks": {}, - "state": { - "schema": { - "global": { - "ints": 0, - "bytes": 0 - }, - "local": { - "ints": 0, - "bytes": 0 - } - }, - "keys": { - "global": {}, - "local": {}, - "box": {} - }, - "maps": { - "global": {}, - "local": {}, - "box": {} - } - }, - "bareActions": { - "create": [ - "NoOp" - ], - "call": [] - }, - "sourceInfo": { - "approval": { - "sourceInfo": [ - { - "pc": [ - 281, - 310, - 340, - 370, - 397, - 418, - 448, - 471, - 499, - 543, - 597, - 626, - 638, - 663, - 692, - 730, - 760, - 787, - 814, - 841, - 868, - 893, - 920, - 948, - 975, - 1004, - 1044, - 1084, - 1113, - 1151, - 1180, - 1218, - 1243, - 1268, - 1289 - ], - "errorMessage": "OnCompletion is not NoOp" - }, - { - "pc": [ - 1332 - ], - "errorMessage": "can only call when creating" - }, - { - "pc": [ - 284, - 313, - 343, - 373, - 400, - 421, - 451, - 474, - 502, - 546, - 600, - 629, - 641, - 666, - 695, - 733, - 763, - 790, - 817, - 844, - 871, - 896, - 923, - 951, - 978, - 1007, - 1047, - 1087, - 1116, - 1154, - 1183, - 1221, - 1246, - 1271, - 1292 - ], - "errorMessage": "can only call when not creating" - } - ], - "pcOffsetMethod": "none" - }, - "clear": { - "sourceInfo": [], - "pcOffsetMethod": "none" - } - }, - "source": { - "approval": "I3ByYWdtYSB2ZXJzaW9uIDEwCgp0ZXN0cy9hcnRpZmFjdHMvbWlzY2VsbGFuZW91cy1vcHMvY29udHJhY3QuYWxnby50czo6TWlzY2VsbGFuZW91c09wc0NvbnRyYWN0LmFwcHJvdmFsUHJvZ3JhbToKICAgIGludGNibG9jayAxIDAKICAgIGJ5dGVjYmxvY2sgMHgxNTFmN2M3NQogICAgY2FsbHN1YiBfX3B1eWFfYXJjNF9yb3V0ZXJfXwogICAgcmV0dXJuCgoKLy8gdGVzdHMvYXJ0aWZhY3RzL21pc2NlbGxhbmVvdXMtb3BzL2NvbnRyYWN0LmFsZ28udHM6Ok1pc2NlbGxhbmVvdXNPcHNDb250cmFjdC5fX3B1eWFfYXJjNF9yb3V0ZXJfXygpIC0+IHVpbnQ2NDoKX19wdXlhX2FyYzRfcm91dGVyX186CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvbWlzY2VsbGFuZW91cy1vcHMvY29udHJhY3QuYWxnby50czozCiAgICAvLyBleHBvcnQgY2xhc3MgTWlzY2VsbGFuZW91c09wc0NvbnRyYWN0IGV4dGVuZHMgYXJjNC5Db250cmFjdCB7CiAgICBwcm90byAwIDEKICAgIHR4biBOdW1BcHBBcmdzCiAgICBieiBfX3B1eWFfYXJjNF9yb3V0ZXJfX19iYXJlX3JvdXRpbmdAMzkKICAgIHB1c2hieXRlc3MgMHg0NTg0N2VlYSAweGY1N2FjZWI1IDB4N2Q2MzE3MzAgMHhhMWIyNDQ0MSAweGNkN2JlMWFjIDB4N2NmZGE2NGIgMHg1NGE5MTBkOSAweGM0NjU2OGRlIDB4N2E0NmE2YWUgMHgwNDM3MjIwOSAweDdlNWY2ZDcyIDB4MjRlYmNmODQgMHg5YzBiMzM5NyAweDBhZDQwZGE0IDB4OTUxNzg4NzAgMHhkZWVkYzk5YiAweGFiMjE1MGJiIDB4MDJhNTQwMTcgMHgzZGI2NmI0MSAweGM3ZWE4YzJhIDB4MWRjZWE1MGMgMHgxNjE2NmY5YSAweDJmNDcyMDY1IDB4YzU4ZDMwZTAgMHhkNWE3MzljMyAweDYxZjNiM2UxIDB4NTZjZjM2OGIgMHg5MTlmZmJkMiAweDhlMzBmNGU3IDB4ODlmODFkOTIgMHhkNTI2MDMyNyAweDExNGM4YzZkIDB4MzllOWU2MmEgMHhkNmE0YzA1ZSAweDFlZjgxNTFhIC8vIG1ldGhvZCAidmVyaWZ5X2FkZHcodWludDY0LHVpbnQ2NCkodWludDY0LHVpbnQ2NCkiLCBtZXRob2QgInZlcmlmeV9iYXNlNjRfZGVjb2RlX3N0YW5kYXJkKGJ5dGVbXSlieXRlW10iLCBtZXRob2QgInZlcmlmeV9iYXNlNjRfZGVjb2RlX3VybChieXRlW10pYnl0ZVtdIiwgbWV0aG9kICJ2ZXJpZnlfYnl0ZXNfYml0bGVuKGJ5dGVbXSx1aW50NjQpdWludDY0IiwgbWV0aG9kICJ2ZXJpZnlfdWludDY0X2JpdGxlbih1aW50NjQpdWludDY0IiwgbWV0aG9kICJ2ZXJpZnlfYnNxcnQoYnl0ZVtdKWJ5dGVbXSIsIG1ldGhvZCAidmVyaWZ5X2J0b2koYnl0ZVtdKXVpbnQ2NCIsIG1ldGhvZCAidmVyaWZ5X2J6ZXJvKHVpbnQ2NClieXRlW10iLCBtZXRob2QgInZlcmlmeV9jb25jYXQoYnl0ZVtdLGJ5dGVbXSx1aW50NjQsdWludDY0KWJ5dGVbXSIsIG1ldGhvZCAidmVyaWZ5X2Rpdm1vZHcodWludDY0LHVpbnQ2NCx1aW50NjQsdWludDY0KSh1aW50NjQsdWludDY0LHVpbnQ2NCx1aW50NjQpIiwgbWV0aG9kICJ2ZXJpZnlfZGl2dyh1aW50NjQsdWludDY0LHVpbnQ2NCl1aW50NjQiLCBtZXRob2QgInZlcmlmeV9lcnIoKXZvaWQiLCBtZXRob2QgInZlcmlmeV9leHAodWludDY0LHVpbnQ2NCl1aW50NjQiLCBtZXRob2QgInZlcmlmeV9leHB3KHVpbnQ2NCx1aW50NjQpKHVpbnQ2NCx1aW50NjQpIiwgbWV0aG9kICJ2ZXJpZnlfZXh0cmFjdChieXRlW10sdWludDY0LHVpbnQ2NClieXRlW10iLCBtZXRob2QgInZlcmlmeV9leHRyYWN0X2Zyb21fMihieXRlW10pYnl0ZVtdIiwgbWV0aG9kICJ2ZXJpZnlfZXh0cmFjdF91aW50MTYoYnl0ZVtdLHVpbnQ2NCl1aW50NjQiLCBtZXRob2QgInZlcmlmeV9leHRyYWN0X3VpbnQzMihieXRlW10sdWludDY0KXVpbnQ2NCIsIG1ldGhvZCAidmVyaWZ5X2V4dHJhY3RfdWludDY0KGJ5dGVbXSx1aW50NjQpdWludDY0IiwgbWV0aG9kICJ2ZXJpZnlfZ2V0Yml0X2J5dGVzKGJ5dGVbXSx1aW50NjQpdWludDY0IiwgbWV0aG9kICJ2ZXJpZnlfZ2V0Yml0X3VpbnQ2NCh1aW50NjQsdWludDY0KXVpbnQ2NCIsIG1ldGhvZCAidmVyaWZ5X2dldGJ5dGUoYnl0ZVtdLHVpbnQ2NCl1aW50NjQiLCBtZXRob2QgInZlcmlmeV9pdG9iKHVpbnQ2NClieXRlW10iLCBtZXRob2QgInZlcmlmeV9ieXRlc19sZW4oYnl0ZVtdLHVpbnQ2NCl1aW50NjQiLCBtZXRob2QgInZlcmlmeV9tdWx3KHVpbnQ2NCx1aW50NjQpKHVpbnQ2NCx1aW50NjQpIiwgbWV0aG9kICJ2ZXJpZnlfcmVwbGFjZShieXRlW10sdWludDY0LGJ5dGVbXSlieXRlW10iLCBtZXRob2QgInZlcmlmeV9zZWxlY3RfYnl0ZXMoYnl0ZVtdLGJ5dGVbXSx1aW50NjQpYnl0ZVtdIiwgbWV0aG9kICJ2ZXJpZnlfc2VsZWN0X3VpbnQ2NCh1aW50NjQsdWludDY0LHVpbnQ2NCl1aW50NjQiLCBtZXRob2QgInZlcmlmeV9zZXRiaXRfYnl0ZXMoYnl0ZVtdLHVpbnQ2NCx1aW50NjQpYnl0ZVtdIiwgbWV0aG9kICJ2ZXJpZnlfc2V0Yml0X3VpbnQ2NCh1aW50NjQsdWludDY0LHVpbnQ2NCl1aW50NjQiLCBtZXRob2QgInZlcmlmeV9zZXRieXRlKGJ5dGVbXSx1aW50NjQsdWludDY0KWJ5dGVbXSIsIG1ldGhvZCAidmVyaWZ5X3NobCh1aW50NjQsdWludDY0KXVpbnQ2NCIsIG1ldGhvZCAidmVyaWZ5X3Nocih1aW50NjQsdWludDY0KXVpbnQ2NCIsIG1ldGhvZCAidmVyaWZ5X3NxcnQodWludDY0KXVpbnQ2NCIsIG1ldGhvZCAidmVyaWZ5X3N1YnN0cmluZyhieXRlW10sdWludDY0LHVpbnQ2NClieXRlW10iCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAwCiAgICBtYXRjaCBfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfYWRkd19yb3V0ZUAyIF9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9iYXNlNjRfZGVjb2RlX3N0YW5kYXJkX3JvdXRlQDMgX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2Jhc2U2NF9kZWNvZGVfdXJsX3JvdXRlQDQgX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2J5dGVzX2JpdGxlbl9yb3V0ZUA1IF9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV91aW50NjRfYml0bGVuX3JvdXRlQDYgX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2JzcXJ0X3JvdXRlQDcgX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2J0b2lfcm91dGVAOCBfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfYnplcm9fcm91dGVAOSBfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfY29uY2F0X3JvdXRlQDEwIF9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9kaXZtb2R3X3JvdXRlQDExIF9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9kaXZ3X3JvdXRlQDEyIF9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9lcnJfcm91dGVAMTMgX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2V4cF9yb3V0ZUAxNCBfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfZXhwd19yb3V0ZUAxNSBfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfZXh0cmFjdF9yb3V0ZUAxNiBfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfZXh0cmFjdF9mcm9tXzJfcm91dGVAMTcgX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2V4dHJhY3RfdWludDE2X3JvdXRlQDE4IF9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9leHRyYWN0X3VpbnQzMl9yb3V0ZUAxOSBfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfZXh0cmFjdF91aW50NjRfcm91dGVAMjAgX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2dldGJpdF9ieXRlc19yb3V0ZUAyMSBfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfZ2V0Yml0X3VpbnQ2NF9yb3V0ZUAyMiBfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfZ2V0Ynl0ZV9yb3V0ZUAyMyBfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfaXRvYl9yb3V0ZUAyNCBfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfYnl0ZXNfbGVuX3JvdXRlQDI1IF9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9tdWx3X3JvdXRlQDI2IF9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9yZXBsYWNlX3JvdXRlQDI3IF9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9zZWxlY3RfYnl0ZXNfcm91dGVAMjggX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X3NlbGVjdF91aW50NjRfcm91dGVAMjkgX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X3NldGJpdF9ieXRlc19yb3V0ZUAzMCBfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfc2V0Yml0X3VpbnQ2NF9yb3V0ZUAzMSBfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfc2V0Ynl0ZV9yb3V0ZUAzMiBfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfc2hsX3JvdXRlQDMzIF9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9zaHJfcm91dGVAMzQgX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X3NxcnRfcm91dGVAMzUgX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X3N1YnN0cmluZ19yb3V0ZUAzNgogICAgaW50Y18xIC8vIDAKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2FkZHdfcm91dGVAMjoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9taXNjZWxsYW5lb3VzLW9wcy9jb250cmFjdC5hbGdvLnRzOjQKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIG5vdCBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGNhbiBvbmx5IGNhbGwgd2hlbiBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9taXNjZWxsYW5lb3VzLW9wcy9jb250cmFjdC5hbGdvLnRzOjMKICAgIC8vIGV4cG9ydCBjbGFzcyBNaXNjZWxsYW5lb3VzT3BzQ29udHJhY3QgZXh0ZW5kcyBhcmM0LkNvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGJ0b2kKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDIKICAgIGJ0b2kKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9taXNjZWxsYW5lb3VzLW9wcy9jb250cmFjdC5hbGdvLnRzOjQKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV9hZGR3CiAgICBzd2FwCiAgICBpdG9iCiAgICBzd2FwCiAgICBpdG9iCiAgICBjb25jYXQKICAgIGJ5dGVjXzAgLy8gMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludGNfMCAvLyAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9iYXNlNjRfZGVjb2RlX3N0YW5kYXJkX3JvdXRlQDM6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvbWlzY2VsbGFuZW91cy1vcHMvY29udHJhY3QuYWxnby50czoxMAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgbm90IE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gY2FuIG9ubHkgY2FsbCB3aGVuIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL21pc2NlbGxhbmVvdXMtb3BzL2NvbnRyYWN0LmFsZ28udHM6MwogICAgLy8gZXhwb3J0IGNsYXNzIE1pc2NlbGxhbmVvdXNPcHNDb250cmFjdCBleHRlbmRzIGFyYzQuQ29udHJhY3QgewogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgZXh0cmFjdCAyIDAKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9taXNjZWxsYW5lb3VzLW9wcy9jb250cmFjdC5hbGdvLnRzOjEwCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfYmFzZTY0X2RlY29kZV9zdGFuZGFyZAogICAgZHVwCiAgICBsZW4KICAgIGl0b2IKICAgIGV4dHJhY3QgNiAyCiAgICBzd2FwCiAgICBjb25jYXQKICAgIGJ5dGVjXzAgLy8gMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludGNfMCAvLyAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9iYXNlNjRfZGVjb2RlX3VybF9yb3V0ZUA0OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL21pc2NlbGxhbmVvdXMtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTYKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIG5vdCBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGNhbiBvbmx5IGNhbGwgd2hlbiBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9taXNjZWxsYW5lb3VzLW9wcy9jb250cmFjdC5hbGdvLnRzOjMKICAgIC8vIGV4cG9ydCBjbGFzcyBNaXNjZWxsYW5lb3VzT3BzQ29udHJhY3QgZXh0ZW5kcyBhcmM0LkNvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGV4dHJhY3QgMiAwCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvbWlzY2VsbGFuZW91cy1vcHMvY29udHJhY3QuYWxnby50czoxNgogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X2Jhc2U2NF9kZWNvZGVfdXJsCiAgICBkdXAKICAgIGxlbgogICAgaXRvYgogICAgZXh0cmFjdCA2IDIKICAgIHN3YXAKICAgIGNvbmNhdAogICAgYnl0ZWNfMCAvLyAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50Y18wIC8vIDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2J5dGVzX2JpdGxlbl9yb3V0ZUA1OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL21pc2NlbGxhbmVvdXMtb3BzL2NvbnRyYWN0LmFsZ28udHM6MjIKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIG5vdCBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGNhbiBvbmx5IGNhbGwgd2hlbiBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9taXNjZWxsYW5lb3VzLW9wcy9jb250cmFjdC5hbGdvLnRzOjMKICAgIC8vIGV4cG9ydCBjbGFzcyBNaXNjZWxsYW5lb3VzT3BzQ29udHJhY3QgZXh0ZW5kcyBhcmM0LkNvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGV4dHJhY3QgMiAwCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAyCiAgICBidG9pCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvbWlzY2VsbGFuZW91cy1vcHMvY29udHJhY3QuYWxnby50czoyMgogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X2J5dGVzX2JpdGxlbgogICAgaXRvYgogICAgYnl0ZWNfMCAvLyAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50Y18wIC8vIDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X3VpbnQ2NF9iaXRsZW5fcm91dGVANjoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9taXNjZWxsYW5lb3VzLW9wcy9jb250cmFjdC5hbGdvLnRzOjI5CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBub3QgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBjYW4gb25seSBjYWxsIHdoZW4gbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvbWlzY2VsbGFuZW91cy1vcHMvY29udHJhY3QuYWxnby50czozCiAgICAvLyBleHBvcnQgY2xhc3MgTWlzY2VsbGFuZW91c09wc0NvbnRyYWN0IGV4dGVuZHMgYXJjNC5Db250cmFjdCB7CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBidG9pCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvbWlzY2VsbGFuZW91cy1vcHMvY29udHJhY3QuYWxnby50czoyOQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X3VpbnQ2NF9iaXRsZW4KICAgIGl0b2IKICAgIGJ5dGVjXzAgLy8gMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludGNfMCAvLyAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9ic3FydF9yb3V0ZUA3OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL21pc2NlbGxhbmVvdXMtb3BzL2NvbnRyYWN0LmFsZ28udHM6MzUKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIG5vdCBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGNhbiBvbmx5IGNhbGwgd2hlbiBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9taXNjZWxsYW5lb3VzLW9wcy9jb250cmFjdC5hbGdvLnRzOjMKICAgIC8vIGV4cG9ydCBjbGFzcyBNaXNjZWxsYW5lb3VzT3BzQ29udHJhY3QgZXh0ZW5kcyBhcmM0LkNvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGV4dHJhY3QgMiAwCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvbWlzY2VsbGFuZW91cy1vcHMvY29udHJhY3QuYWxnby50czozNQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X2JzcXJ0CiAgICBkdXAKICAgIGxlbgogICAgaXRvYgogICAgZXh0cmFjdCA2IDIKICAgIHN3YXAKICAgIGNvbmNhdAogICAgYnl0ZWNfMCAvLyAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50Y18wIC8vIDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2J0b2lfcm91dGVAODoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9taXNjZWxsYW5lb3VzLW9wcy9jb250cmFjdC5hbGdvLnRzOjQyCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBub3QgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBjYW4gb25seSBjYWxsIHdoZW4gbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvbWlzY2VsbGFuZW91cy1vcHMvY29udHJhY3QuYWxnby50czozCiAgICAvLyBleHBvcnQgY2xhc3MgTWlzY2VsbGFuZW91c09wc0NvbnRyYWN0IGV4dGVuZHMgYXJjNC5Db250cmFjdCB7CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBleHRyYWN0IDIgMAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL21pc2NlbGxhbmVvdXMtb3BzL2NvbnRyYWN0LmFsZ28udHM6NDIKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV9idG9pCiAgICBpdG9iCiAgICBieXRlY18wIC8vIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnRjXzAgLy8gMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfYnplcm9fcm91dGVAOToKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9taXNjZWxsYW5lb3VzLW9wcy9jb250cmFjdC5hbGdvLnRzOjQ4CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBub3QgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBjYW4gb25seSBjYWxsIHdoZW4gbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvbWlzY2VsbGFuZW91cy1vcHMvY29udHJhY3QuYWxnby50czozCiAgICAvLyBleHBvcnQgY2xhc3MgTWlzY2VsbGFuZW91c09wc0NvbnRyYWN0IGV4dGVuZHMgYXJjNC5Db250cmFjdCB7CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBidG9pCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvbWlzY2VsbGFuZW91cy1vcHMvY29udHJhY3QuYWxnby50czo0OAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X2J6ZXJvCiAgICBkdXAKICAgIGxlbgogICAgaXRvYgogICAgZXh0cmFjdCA2IDIKICAgIHN3YXAKICAgIGNvbmNhdAogICAgYnl0ZWNfMCAvLyAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50Y18wIC8vIDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2NvbmNhdF9yb3V0ZUAxMDoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9taXNjZWxsYW5lb3VzLW9wcy9jb250cmFjdC5hbGdvLnRzOjU0CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBub3QgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBjYW4gb25seSBjYWxsIHdoZW4gbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvbWlzY2VsbGFuZW91cy1vcHMvY29udHJhY3QuYWxnby50czozCiAgICAvLyBleHBvcnQgY2xhc3MgTWlzY2VsbGFuZW91c09wc0NvbnRyYWN0IGV4dGVuZHMgYXJjNC5Db250cmFjdCB7CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBleHRyYWN0IDIgMAogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMgogICAgZXh0cmFjdCAyIDAKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDMKICAgIGJ0b2kKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDQKICAgIGJ0b2kKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9taXNjZWxsYW5lb3VzLW9wcy9jb250cmFjdC5hbGdvLnRzOjU0CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfY29uY2F0CiAgICBkdXAKICAgIGxlbgogICAgaXRvYgogICAgZXh0cmFjdCA2IDIKICAgIHN3YXAKICAgIGNvbmNhdAogICAgYnl0ZWNfMCAvLyAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50Y18wIC8vIDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2Rpdm1vZHdfcm91dGVAMTE6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvbWlzY2VsbGFuZW91cy1vcHMvY29udHJhY3QuYWxnby50czo2MwogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgbm90IE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gY2FuIG9ubHkgY2FsbCB3aGVuIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL21pc2NlbGxhbmVvdXMtb3BzL2NvbnRyYWN0LmFsZ28udHM6MwogICAgLy8gZXhwb3J0IGNsYXNzIE1pc2NlbGxhbmVvdXNPcHNDb250cmFjdCBleHRlbmRzIGFyYzQuQ29udHJhY3QgewogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgYnRvaQogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMgogICAgYnRvaQogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMwogICAgYnRvaQogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgNAogICAgYnRvaQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL21pc2NlbGxhbmVvdXMtb3BzL2NvbnRyYWN0LmFsZ28udHM6NjMKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV9kaXZtb2R3CiAgICB1bmNvdmVyIDMKICAgIGl0b2IKICAgIHVuY292ZXIgMwogICAgaXRvYgogICAgdW5jb3ZlciAzCiAgICBpdG9iCiAgICB1bmNvdmVyIDMKICAgIGl0b2IKICAgIHVuY292ZXIgMwogICAgdW5jb3ZlciAzCiAgICBjb25jYXQKICAgIHVuY292ZXIgMgogICAgY29uY2F0CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGJ5dGVjXzAgLy8gMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludGNfMCAvLyAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9kaXZ3X3JvdXRlQDEyOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL21pc2NlbGxhbmVvdXMtb3BzL2NvbnRyYWN0LmFsZ28udHM6NjkKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIG5vdCBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGNhbiBvbmx5IGNhbGwgd2hlbiBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9taXNjZWxsYW5lb3VzLW9wcy9jb250cmFjdC5hbGdvLnRzOjMKICAgIC8vIGV4cG9ydCBjbGFzcyBNaXNjZWxsYW5lb3VzT3BzQ29udHJhY3QgZXh0ZW5kcyBhcmM0LkNvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGJ0b2kKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDIKICAgIGJ0b2kKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDMKICAgIGJ0b2kKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9taXNjZWxsYW5lb3VzLW9wcy9jb250cmFjdC5hbGdvLnRzOjY5CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfZGl2dwogICAgaXRvYgogICAgYnl0ZWNfMCAvLyAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50Y18wIC8vIDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2Vycl9yb3V0ZUAxMzoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9taXNjZWxsYW5lb3VzLW9wcy9jb250cmFjdC5hbGdvLnRzOjc1CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBub3QgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBjYW4gb25seSBjYWxsIHdoZW4gbm90IGNyZWF0aW5nCiAgICBjYWxsc3ViIHZlcmlmeV9lcnIKICAgIGludGNfMCAvLyAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9leHBfcm91dGVAMTQ6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvbWlzY2VsbGFuZW91cy1vcHMvY29udHJhY3QuYWxnby50czo4MAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgbm90IE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gY2FuIG9ubHkgY2FsbCB3aGVuIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL21pc2NlbGxhbmVvdXMtb3BzL2NvbnRyYWN0LmFsZ28udHM6MwogICAgLy8gZXhwb3J0IGNsYXNzIE1pc2NlbGxhbmVvdXNPcHNDb250cmFjdCBleHRlbmRzIGFyYzQuQ29udHJhY3QgewogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgYnRvaQogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMgogICAgYnRvaQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL21pc2NlbGxhbmVvdXMtb3BzL2NvbnRyYWN0LmFsZ28udHM6ODAKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV9leHAKICAgIGl0b2IKICAgIGJ5dGVjXzAgLy8gMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludGNfMCAvLyAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9leHB3X3JvdXRlQDE1OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL21pc2NlbGxhbmVvdXMtb3BzL2NvbnRyYWN0LmFsZ28udHM6ODYKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIG5vdCBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGNhbiBvbmx5IGNhbGwgd2hlbiBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9taXNjZWxsYW5lb3VzLW9wcy9jb250cmFjdC5hbGdvLnRzOjMKICAgIC8vIGV4cG9ydCBjbGFzcyBNaXNjZWxsYW5lb3VzT3BzQ29udHJhY3QgZXh0ZW5kcyBhcmM0LkNvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGJ0b2kKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDIKICAgIGJ0b2kKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9taXNjZWxsYW5lb3VzLW9wcy9jb250cmFjdC5hbGdvLnRzOjg2CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfZXhwdwogICAgc3dhcAogICAgaXRvYgogICAgc3dhcAogICAgaXRvYgogICAgY29uY2F0CiAgICBieXRlY18wIC8vIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnRjXzAgLy8gMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfZXh0cmFjdF9yb3V0ZUAxNjoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9taXNjZWxsYW5lb3VzLW9wcy9jb250cmFjdC5hbGdvLnRzOjkyCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBub3QgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBjYW4gb25seSBjYWxsIHdoZW4gbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvbWlzY2VsbGFuZW91cy1vcHMvY29udHJhY3QuYWxnby50czozCiAgICAvLyBleHBvcnQgY2xhc3MgTWlzY2VsbGFuZW91c09wc0NvbnRyYWN0IGV4dGVuZHMgYXJjNC5Db250cmFjdCB7CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBleHRyYWN0IDIgMAogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMgogICAgYnRvaQogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMwogICAgYnRvaQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL21pc2NlbGxhbmVvdXMtb3BzL2NvbnRyYWN0LmFsZ28udHM6OTIKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV9leHRyYWN0CiAgICBkdXAKICAgIGxlbgogICAgaXRvYgogICAgZXh0cmFjdCA2IDIKICAgIHN3YXAKICAgIGNvbmNhdAogICAgYnl0ZWNfMCAvLyAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50Y18wIC8vIDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2V4dHJhY3RfZnJvbV8yX3JvdXRlQDE3OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL21pc2NlbGxhbmVvdXMtb3BzL2NvbnRyYWN0LmFsZ28udHM6OTkKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIG5vdCBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGNhbiBvbmx5IGNhbGwgd2hlbiBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9taXNjZWxsYW5lb3VzLW9wcy9jb250cmFjdC5hbGdvLnRzOjMKICAgIC8vIGV4cG9ydCBjbGFzcyBNaXNjZWxsYW5lb3VzT3BzQ29udHJhY3QgZXh0ZW5kcyBhcmM0LkNvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGV4dHJhY3QgMiAwCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvbWlzY2VsbGFuZW91cy1vcHMvY29udHJhY3QuYWxnby50czo5OQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X2V4dHJhY3RfZnJvbV8yCiAgICBkdXAKICAgIGxlbgogICAgaXRvYgogICAgZXh0cmFjdCA2IDIKICAgIHN3YXAKICAgIGNvbmNhdAogICAgYnl0ZWNfMCAvLyAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50Y18wIC8vIDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2V4dHJhY3RfdWludDE2X3JvdXRlQDE4OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL21pc2NlbGxhbmVvdXMtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTA1CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBub3QgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBjYW4gb25seSBjYWxsIHdoZW4gbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvbWlzY2VsbGFuZW91cy1vcHMvY29udHJhY3QuYWxnby50czozCiAgICAvLyBleHBvcnQgY2xhc3MgTWlzY2VsbGFuZW91c09wc0NvbnRyYWN0IGV4dGVuZHMgYXJjNC5Db250cmFjdCB7CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBleHRyYWN0IDIgMAogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMgogICAgYnRvaQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL21pc2NlbGxhbmVvdXMtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTA1CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfZXh0cmFjdF91aW50MTYKICAgIGl0b2IKICAgIGJ5dGVjXzAgLy8gMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludGNfMCAvLyAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9leHRyYWN0X3VpbnQzMl9yb3V0ZUAxOToKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9taXNjZWxsYW5lb3VzLW9wcy9jb250cmFjdC5hbGdvLnRzOjExMQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgbm90IE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gY2FuIG9ubHkgY2FsbCB3aGVuIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL21pc2NlbGxhbmVvdXMtb3BzL2NvbnRyYWN0LmFsZ28udHM6MwogICAgLy8gZXhwb3J0IGNsYXNzIE1pc2NlbGxhbmVvdXNPcHNDb250cmFjdCBleHRlbmRzIGFyYzQuQ29udHJhY3QgewogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgZXh0cmFjdCAyIDAKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDIKICAgIGJ0b2kKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9taXNjZWxsYW5lb3VzLW9wcy9jb250cmFjdC5hbGdvLnRzOjExMQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X2V4dHJhY3RfdWludDMyCiAgICBpdG9iCiAgICBieXRlY18wIC8vIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnRjXzAgLy8gMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfZXh0cmFjdF91aW50NjRfcm91dGVAMjA6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvbWlzY2VsbGFuZW91cy1vcHMvY29udHJhY3QuYWxnby50czoxMTcKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIG5vdCBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGNhbiBvbmx5IGNhbGwgd2hlbiBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9taXNjZWxsYW5lb3VzLW9wcy9jb250cmFjdC5hbGdvLnRzOjMKICAgIC8vIGV4cG9ydCBjbGFzcyBNaXNjZWxsYW5lb3VzT3BzQ29udHJhY3QgZXh0ZW5kcyBhcmM0LkNvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGV4dHJhY3QgMiAwCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAyCiAgICBidG9pCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvbWlzY2VsbGFuZW91cy1vcHMvY29udHJhY3QuYWxnby50czoxMTcKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV9leHRyYWN0X3VpbnQ2NAogICAgaXRvYgogICAgYnl0ZWNfMCAvLyAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50Y18wIC8vIDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2dldGJpdF9ieXRlc19yb3V0ZUAyMToKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9taXNjZWxsYW5lb3VzLW9wcy9jb250cmFjdC5hbGdvLnRzOjEyMwogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgbm90IE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gY2FuIG9ubHkgY2FsbCB3aGVuIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL21pc2NlbGxhbmVvdXMtb3BzL2NvbnRyYWN0LmFsZ28udHM6MwogICAgLy8gZXhwb3J0IGNsYXNzIE1pc2NlbGxhbmVvdXNPcHNDb250cmFjdCBleHRlbmRzIGFyYzQuQ29udHJhY3QgewogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgZXh0cmFjdCAyIDAKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDIKICAgIGJ0b2kKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9taXNjZWxsYW5lb3VzLW9wcy9jb250cmFjdC5hbGdvLnRzOjEyMwogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X2dldGJpdF9ieXRlcwogICAgaXRvYgogICAgYnl0ZWNfMCAvLyAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50Y18wIC8vIDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2dldGJpdF91aW50NjRfcm91dGVAMjI6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvbWlzY2VsbGFuZW91cy1vcHMvY29udHJhY3QuYWxnby50czoxMjkKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIG5vdCBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGNhbiBvbmx5IGNhbGwgd2hlbiBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9taXNjZWxsYW5lb3VzLW9wcy9jb250cmFjdC5hbGdvLnRzOjMKICAgIC8vIGV4cG9ydCBjbGFzcyBNaXNjZWxsYW5lb3VzT3BzQ29udHJhY3QgZXh0ZW5kcyBhcmM0LkNvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGJ0b2kKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDIKICAgIGJ0b2kKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9taXNjZWxsYW5lb3VzLW9wcy9jb250cmFjdC5hbGdvLnRzOjEyOQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X2dldGJpdF91aW50NjQKICAgIGl0b2IKICAgIGJ5dGVjXzAgLy8gMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludGNfMCAvLyAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9nZXRieXRlX3JvdXRlQDIzOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL21pc2NlbGxhbmVvdXMtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTM1CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBub3QgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBjYW4gb25seSBjYWxsIHdoZW4gbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvbWlzY2VsbGFuZW91cy1vcHMvY29udHJhY3QuYWxnby50czozCiAgICAvLyBleHBvcnQgY2xhc3MgTWlzY2VsbGFuZW91c09wc0NvbnRyYWN0IGV4dGVuZHMgYXJjNC5Db250cmFjdCB7CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBleHRyYWN0IDIgMAogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMgogICAgYnRvaQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL21pc2NlbGxhbmVvdXMtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTM1CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfZ2V0Ynl0ZQogICAgaXRvYgogICAgYnl0ZWNfMCAvLyAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50Y18wIC8vIDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2l0b2Jfcm91dGVAMjQ6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvbWlzY2VsbGFuZW91cy1vcHMvY29udHJhY3QuYWxnby50czoxNDEKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIG5vdCBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGNhbiBvbmx5IGNhbGwgd2hlbiBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9taXNjZWxsYW5lb3VzLW9wcy9jb250cmFjdC5hbGdvLnRzOjMKICAgIC8vIGV4cG9ydCBjbGFzcyBNaXNjZWxsYW5lb3VzT3BzQ29udHJhY3QgZXh0ZW5kcyBhcmM0LkNvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGJ0b2kKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9taXNjZWxsYW5lb3VzLW9wcy9jb250cmFjdC5hbGdvLnRzOjE0MQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X2l0b2IKICAgIGR1cAogICAgbGVuCiAgICBpdG9iCiAgICBleHRyYWN0IDYgMgogICAgc3dhcAogICAgY29uY2F0CiAgICBieXRlY18wIC8vIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnRjXzAgLy8gMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfYnl0ZXNfbGVuX3JvdXRlQDI1OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL21pc2NlbGxhbmVvdXMtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTQ3CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBub3QgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBjYW4gb25seSBjYWxsIHdoZW4gbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvbWlzY2VsbGFuZW91cy1vcHMvY29udHJhY3QuYWxnby50czozCiAgICAvLyBleHBvcnQgY2xhc3MgTWlzY2VsbGFuZW91c09wc0NvbnRyYWN0IGV4dGVuZHMgYXJjNC5Db250cmFjdCB7CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBleHRyYWN0IDIgMAogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMgogICAgYnRvaQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL21pc2NlbGxhbmVvdXMtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTQ3CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfYnl0ZXNfbGVuCiAgICBpdG9iCiAgICBieXRlY18wIC8vIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnRjXzAgLy8gMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfbXVsd19yb3V0ZUAyNjoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9taXNjZWxsYW5lb3VzLW9wcy9jb250cmFjdC5hbGdvLnRzOjE1NAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgbm90IE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gY2FuIG9ubHkgY2FsbCB3aGVuIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL21pc2NlbGxhbmVvdXMtb3BzL2NvbnRyYWN0LmFsZ28udHM6MwogICAgLy8gZXhwb3J0IGNsYXNzIE1pc2NlbGxhbmVvdXNPcHNDb250cmFjdCBleHRlbmRzIGFyYzQuQ29udHJhY3QgewogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgYnRvaQogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMgogICAgYnRvaQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL21pc2NlbGxhbmVvdXMtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTU0CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfbXVsdwogICAgc3dhcAogICAgaXRvYgogICAgc3dhcAogICAgaXRvYgogICAgY29uY2F0CiAgICBieXRlY18wIC8vIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnRjXzAgLy8gMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfcmVwbGFjZV9yb3V0ZUAyNzoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9taXNjZWxsYW5lb3VzLW9wcy9jb250cmFjdC5hbGdvLnRzOjE2MAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgbm90IE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gY2FuIG9ubHkgY2FsbCB3aGVuIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL21pc2NlbGxhbmVvdXMtb3BzL2NvbnRyYWN0LmFsZ28udHM6MwogICAgLy8gZXhwb3J0IGNsYXNzIE1pc2NlbGxhbmVvdXNPcHNDb250cmFjdCBleHRlbmRzIGFyYzQuQ29udHJhY3QgewogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgZXh0cmFjdCAyIDAKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDIKICAgIGJ0b2kKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDMKICAgIGV4dHJhY3QgMiAwCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvbWlzY2VsbGFuZW91cy1vcHMvY29udHJhY3QuYWxnby50czoxNjAKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV9yZXBsYWNlCiAgICBkdXAKICAgIGxlbgogICAgaXRvYgogICAgZXh0cmFjdCA2IDIKICAgIHN3YXAKICAgIGNvbmNhdAogICAgYnl0ZWNfMCAvLyAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50Y18wIC8vIDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X3NlbGVjdF9ieXRlc19yb3V0ZUAyODoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9taXNjZWxsYW5lb3VzLW9wcy9jb250cmFjdC5hbGdvLnRzOjE2NgogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgbm90IE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gY2FuIG9ubHkgY2FsbCB3aGVuIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL21pc2NlbGxhbmVvdXMtb3BzL2NvbnRyYWN0LmFsZ28udHM6MwogICAgLy8gZXhwb3J0IGNsYXNzIE1pc2NlbGxhbmVvdXNPcHNDb250cmFjdCBleHRlbmRzIGFyYzQuQ29udHJhY3QgewogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgZXh0cmFjdCAyIDAKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDIKICAgIGV4dHJhY3QgMiAwCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAzCiAgICBidG9pCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvbWlzY2VsbGFuZW91cy1vcHMvY29udHJhY3QuYWxnby50czoxNjYKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV9zZWxlY3RfYnl0ZXMKICAgIGR1cAogICAgbGVuCiAgICBpdG9iCiAgICBleHRyYWN0IDYgMgogICAgc3dhcAogICAgY29uY2F0CiAgICBieXRlY18wIC8vIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnRjXzAgLy8gMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfc2VsZWN0X3VpbnQ2NF9yb3V0ZUAyOToKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9taXNjZWxsYW5lb3VzLW9wcy9jb250cmFjdC5hbGdvLnRzOjE3MgogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgbm90IE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gY2FuIG9ubHkgY2FsbCB3aGVuIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL21pc2NlbGxhbmVvdXMtb3BzL2NvbnRyYWN0LmFsZ28udHM6MwogICAgLy8gZXhwb3J0IGNsYXNzIE1pc2NlbGxhbmVvdXNPcHNDb250cmFjdCBleHRlbmRzIGFyYzQuQ29udHJhY3QgewogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgYnRvaQogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMgogICAgYnRvaQogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMwogICAgYnRvaQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL21pc2NlbGxhbmVvdXMtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTcyCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfc2VsZWN0X3VpbnQ2NAogICAgaXRvYgogICAgYnl0ZWNfMCAvLyAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50Y18wIC8vIDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X3NldGJpdF9ieXRlc19yb3V0ZUAzMDoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9taXNjZWxsYW5lb3VzLW9wcy9jb250cmFjdC5hbGdvLnRzOjE3OAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgbm90IE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gY2FuIG9ubHkgY2FsbCB3aGVuIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL21pc2NlbGxhbmVvdXMtb3BzL2NvbnRyYWN0LmFsZ28udHM6MwogICAgLy8gZXhwb3J0IGNsYXNzIE1pc2NlbGxhbmVvdXNPcHNDb250cmFjdCBleHRlbmRzIGFyYzQuQ29udHJhY3QgewogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgZXh0cmFjdCAyIDAKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDIKICAgIGJ0b2kKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDMKICAgIGJ0b2kKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9taXNjZWxsYW5lb3VzLW9wcy9jb250cmFjdC5hbGdvLnRzOjE3OAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X3NldGJpdF9ieXRlcwogICAgZHVwCiAgICBsZW4KICAgIGl0b2IKICAgIGV4dHJhY3QgNiAyCiAgICBzd2FwCiAgICBjb25jYXQKICAgIGJ5dGVjXzAgLy8gMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludGNfMCAvLyAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9zZXRiaXRfdWludDY0X3JvdXRlQDMxOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL21pc2NlbGxhbmVvdXMtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTg0CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBub3QgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBjYW4gb25seSBjYWxsIHdoZW4gbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvbWlzY2VsbGFuZW91cy1vcHMvY29udHJhY3QuYWxnby50czozCiAgICAvLyBleHBvcnQgY2xhc3MgTWlzY2VsbGFuZW91c09wc0NvbnRyYWN0IGV4dGVuZHMgYXJjNC5Db250cmFjdCB7CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBidG9pCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAyCiAgICBidG9pCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAzCiAgICBidG9pCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvbWlzY2VsbGFuZW91cy1vcHMvY29udHJhY3QuYWxnby50czoxODQKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV9zZXRiaXRfdWludDY0CiAgICBpdG9iCiAgICBieXRlY18wIC8vIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnRjXzAgLy8gMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfc2V0Ynl0ZV9yb3V0ZUAzMjoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9taXNjZWxsYW5lb3VzLW9wcy9jb250cmFjdC5hbGdvLnRzOjE5MAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgbm90IE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gY2FuIG9ubHkgY2FsbCB3aGVuIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL21pc2NlbGxhbmVvdXMtb3BzL2NvbnRyYWN0LmFsZ28udHM6MwogICAgLy8gZXhwb3J0IGNsYXNzIE1pc2NlbGxhbmVvdXNPcHNDb250cmFjdCBleHRlbmRzIGFyYzQuQ29udHJhY3QgewogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgZXh0cmFjdCAyIDAKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDIKICAgIGJ0b2kKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDMKICAgIGJ0b2kKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9taXNjZWxsYW5lb3VzLW9wcy9jb250cmFjdC5hbGdvLnRzOjE5MAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X3NldGJ5dGUKICAgIGR1cAogICAgbGVuCiAgICBpdG9iCiAgICBleHRyYWN0IDYgMgogICAgc3dhcAogICAgY29uY2F0CiAgICBieXRlY18wIC8vIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnRjXzAgLy8gMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfc2hsX3JvdXRlQDMzOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL21pc2NlbGxhbmVvdXMtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTk2CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBub3QgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBjYW4gb25seSBjYWxsIHdoZW4gbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvbWlzY2VsbGFuZW91cy1vcHMvY29udHJhY3QuYWxnby50czozCiAgICAvLyBleHBvcnQgY2xhc3MgTWlzY2VsbGFuZW91c09wc0NvbnRyYWN0IGV4dGVuZHMgYXJjNC5Db250cmFjdCB7CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBidG9pCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAyCiAgICBidG9pCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvbWlzY2VsbGFuZW91cy1vcHMvY29udHJhY3QuYWxnby50czoxOTYKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV9zaGwKICAgIGl0b2IKICAgIGJ5dGVjXzAgLy8gMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludGNfMCAvLyAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9zaHJfcm91dGVAMzQ6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvbWlzY2VsbGFuZW91cy1vcHMvY29udHJhY3QuYWxnby50czoyMDIKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIG5vdCBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGNhbiBvbmx5IGNhbGwgd2hlbiBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9taXNjZWxsYW5lb3VzLW9wcy9jb250cmFjdC5hbGdvLnRzOjMKICAgIC8vIGV4cG9ydCBjbGFzcyBNaXNjZWxsYW5lb3VzT3BzQ29udHJhY3QgZXh0ZW5kcyBhcmM0LkNvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGJ0b2kKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDIKICAgIGJ0b2kKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9taXNjZWxsYW5lb3VzLW9wcy9jb250cmFjdC5hbGdvLnRzOjIwMgogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X3NocgogICAgaXRvYgogICAgYnl0ZWNfMCAvLyAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50Y18wIC8vIDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X3NxcnRfcm91dGVAMzU6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvbWlzY2VsbGFuZW91cy1vcHMvY29udHJhY3QuYWxnby50czoyMDgKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIG5vdCBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGNhbiBvbmx5IGNhbGwgd2hlbiBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9taXNjZWxsYW5lb3VzLW9wcy9jb250cmFjdC5hbGdvLnRzOjMKICAgIC8vIGV4cG9ydCBjbGFzcyBNaXNjZWxsYW5lb3VzT3BzQ29udHJhY3QgZXh0ZW5kcyBhcmM0LkNvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGJ0b2kKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9taXNjZWxsYW5lb3VzLW9wcy9jb250cmFjdC5hbGdvLnRzOjIwOAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X3NxcnQKICAgIGl0b2IKICAgIGJ5dGVjXzAgLy8gMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludGNfMCAvLyAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9zdWJzdHJpbmdfcm91dGVAMzY6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvbWlzY2VsbGFuZW91cy1vcHMvY29udHJhY3QuYWxnby50czoyMTQKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIG5vdCBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGNhbiBvbmx5IGNhbGwgd2hlbiBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9taXNjZWxsYW5lb3VzLW9wcy9jb250cmFjdC5hbGdvLnRzOjMKICAgIC8vIGV4cG9ydCBjbGFzcyBNaXNjZWxsYW5lb3VzT3BzQ29udHJhY3QgZXh0ZW5kcyBhcmM0LkNvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGV4dHJhY3QgMiAwCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAyCiAgICBidG9pCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAzCiAgICBidG9pCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvbWlzY2VsbGFuZW91cy1vcHMvY29udHJhY3QuYWxnby50czoyMTQKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV9zdWJzdHJpbmcKICAgIGR1cAogICAgbGVuCiAgICBpdG9iCiAgICBleHRyYWN0IDYgMgogICAgc3dhcAogICAgY29uY2F0CiAgICBieXRlY18wIC8vIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnRjXzAgLy8gMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX19iYXJlX3JvdXRpbmdAMzk6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvbWlzY2VsbGFuZW91cy1vcHMvY29udHJhY3QuYWxnby50czozCiAgICAvLyBleHBvcnQgY2xhc3MgTWlzY2VsbGFuZW91c09wc0NvbnRyYWN0IGV4dGVuZHMgYXJjNC5Db250cmFjdCB7CiAgICB0eG4gT25Db21wbGV0aW9uCiAgICBibnogX19wdXlhX2FyYzRfcm91dGVyX19fYWZ0ZXJfaWZfZWxzZUA0MwogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgICEKICAgIGFzc2VydCAvLyBjYW4gb25seSBjYWxsIHdoZW4gY3JlYXRpbmcKICAgIGludGNfMCAvLyAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX2FmdGVyX2lmX2Vsc2VANDM6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvbWlzY2VsbGFuZW91cy1vcHMvY29udHJhY3QuYWxnby50czozCiAgICAvLyBleHBvcnQgY2xhc3MgTWlzY2VsbGFuZW91c09wc0NvbnRyYWN0IGV4dGVuZHMgYXJjNC5Db250cmFjdCB7CiAgICBpbnRjXzEgLy8gMAogICAgcmV0c3ViCgoKLy8gdGVzdHMvYXJ0aWZhY3RzL21pc2NlbGxhbmVvdXMtb3BzL2NvbnRyYWN0LmFsZ28udHM6Ok1pc2NlbGxhbmVvdXNPcHNDb250cmFjdC52ZXJpZnlfYWRkdyhhOiB1aW50NjQsIGI6IHVpbnQ2NCkgLT4gdWludDY0LCB1aW50NjQ6CnZlcmlmeV9hZGR3OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL21pc2NlbGxhbmVvdXMtb3BzL2NvbnRyYWN0LmFsZ28udHM6NC01CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gcHVibGljIHZlcmlmeV9hZGR3KGE6IHVpbnQ2NCwgYjogdWludDY0KTogcmVhZG9ubHkgW3VpbnQ2NCwgdWludDY0XSB7CiAgICBwcm90byAyIDIKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9taXNjZWxsYW5lb3VzLW9wcy9jb250cmFjdC5hbGdvLnRzOjYKICAgIC8vIGNvbnN0IHJlc3VsdCA9IG9wLmFkZHcoYSwgYikKICAgIGZyYW1lX2RpZyAtMgogICAgZnJhbWVfZGlnIC0xCiAgICBhZGR3CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvbWlzY2VsbGFuZW91cy1vcHMvY29udHJhY3QuYWxnby50czo3CiAgICAvLyByZXR1cm4gcmVzdWx0CiAgICByZXRzdWIKCgovLyB0ZXN0cy9hcnRpZmFjdHMvbWlzY2VsbGFuZW91cy1vcHMvY29udHJhY3QuYWxnby50czo6TWlzY2VsbGFuZW91c09wc0NvbnRyYWN0LnZlcmlmeV9iYXNlNjRfZGVjb2RlX3N0YW5kYXJkKGE6IGJ5dGVzKSAtPiBieXRlczoKdmVyaWZ5X2Jhc2U2NF9kZWNvZGVfc3RhbmRhcmQ6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvbWlzY2VsbGFuZW91cy1vcHMvY29udHJhY3QuYWxnby50czoxMC0xMQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIHB1YmxpYyB2ZXJpZnlfYmFzZTY0X2RlY29kZV9zdGFuZGFyZChhOiBieXRlcyk6IGJ5dGVzIHsKICAgIHByb3RvIDEgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL21pc2NlbGxhbmVvdXMtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTIKICAgIC8vIGNvbnN0IHJlc3VsdCA9IG9wLmJhc2U2NERlY29kZShCYXNlNjQuU3RkRW5jb2RpbmcsIGEpCiAgICBmcmFtZV9kaWcgLTEKICAgIGJhc2U2NF9kZWNvZGUgU3RkRW5jb2RpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9taXNjZWxsYW5lb3VzLW9wcy9jb250cmFjdC5hbGdvLnRzOjEzCiAgICAvLyByZXR1cm4gcmVzdWx0CiAgICByZXRzdWIKCgovLyB0ZXN0cy9hcnRpZmFjdHMvbWlzY2VsbGFuZW91cy1vcHMvY29udHJhY3QuYWxnby50czo6TWlzY2VsbGFuZW91c09wc0NvbnRyYWN0LnZlcmlmeV9iYXNlNjRfZGVjb2RlX3VybChhOiBieXRlcykgLT4gYnl0ZXM6CnZlcmlmeV9iYXNlNjRfZGVjb2RlX3VybDoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9taXNjZWxsYW5lb3VzLW9wcy9jb250cmFjdC5hbGdvLnRzOjE2LTE3CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gcHVibGljIHZlcmlmeV9iYXNlNjRfZGVjb2RlX3VybChhOiBieXRlcyk6IGJ5dGVzIHsKICAgIHByb3RvIDEgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL21pc2NlbGxhbmVvdXMtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTgKICAgIC8vIGNvbnN0IHJlc3VsdCA9IG9wLmJhc2U2NERlY29kZShCYXNlNjQuVVJMRW5jb2RpbmcsIGEpCiAgICBmcmFtZV9kaWcgLTEKICAgIGJhc2U2NF9kZWNvZGUgVVJMRW5jb2RpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9taXNjZWxsYW5lb3VzLW9wcy9jb250cmFjdC5hbGdvLnRzOjE5CiAgICAvLyByZXR1cm4gcmVzdWx0CiAgICByZXRzdWIKCgovLyB0ZXN0cy9hcnRpZmFjdHMvbWlzY2VsbGFuZW91cy1vcHMvY29udHJhY3QuYWxnby50czo6TWlzY2VsbGFuZW91c09wc0NvbnRyYWN0LnZlcmlmeV9ieXRlc19iaXRsZW4oYTogYnl0ZXMsIHBhZF9hX3NpemU6IHVpbnQ2NCkgLT4gdWludDY0Ogp2ZXJpZnlfYnl0ZXNfYml0bGVuOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL21pc2NlbGxhbmVvdXMtb3BzL2NvbnRyYWN0LmFsZ28udHM6MjItMjMKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBwdWJsaWMgdmVyaWZ5X2J5dGVzX2JpdGxlbihhOiBieXRlcywgcGFkX2Ffc2l6ZTogdWludDY0KTogdWludDY0IHsKICAgIHByb3RvIDIgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL21pc2NlbGxhbmVvdXMtb3BzL2NvbnRyYWN0LmFsZ28udHM6MjQKICAgIC8vIGNvbnN0IHBhZGRlZEEgPSBvcC5iemVybyhwYWRfYV9zaXplKS5jb25jYXQoYSkKICAgIGZyYW1lX2RpZyAtMQogICAgYnplcm8KICAgIGZyYW1lX2RpZyAtMgogICAgY29uY2F0CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvbWlzY2VsbGFuZW91cy1vcHMvY29udHJhY3QuYWxnby50czoyNQogICAgLy8gY29uc3QgcmVzdWx0ID0gb3AuYml0TGVuZ3RoKHBhZGRlZEEpCiAgICBiaXRsZW4KICAgIC8vIHRlc3RzL2FydGlmYWN0cy9taXNjZWxsYW5lb3VzLW9wcy9jb250cmFjdC5hbGdvLnRzOjI2CiAgICAvLyByZXR1cm4gcmVzdWx0CiAgICByZXRzdWIKCgovLyB0ZXN0cy9hcnRpZmFjdHMvbWlzY2VsbGFuZW91cy1vcHMvY29udHJhY3QuYWxnby50czo6TWlzY2VsbGFuZW91c09wc0NvbnRyYWN0LnZlcmlmeV91aW50NjRfYml0bGVuKGE6IHVpbnQ2NCkgLT4gdWludDY0Ogp2ZXJpZnlfdWludDY0X2JpdGxlbjoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9taXNjZWxsYW5lb3VzLW9wcy9jb250cmFjdC5hbGdvLnRzOjI5LTMwCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gcHVibGljIHZlcmlmeV91aW50NjRfYml0bGVuKGE6IHVpbnQ2NCk6IHVpbnQ2NCB7CiAgICBwcm90byAxIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9taXNjZWxsYW5lb3VzLW9wcy9jb250cmFjdC5hbGdvLnRzOjMxCiAgICAvLyBjb25zdCByZXN1bHQgPSBvcC5iaXRMZW5ndGgoYSkKICAgIGZyYW1lX2RpZyAtMQogICAgYml0bGVuCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvbWlzY2VsbGFuZW91cy1vcHMvY29udHJhY3QuYWxnby50czozMgogICAgLy8gcmV0dXJuIHJlc3VsdAogICAgcmV0c3ViCgoKLy8gdGVzdHMvYXJ0aWZhY3RzL21pc2NlbGxhbmVvdXMtb3BzL2NvbnRyYWN0LmFsZ28udHM6Ok1pc2NlbGxhbmVvdXNPcHNDb250cmFjdC52ZXJpZnlfYnNxcnQoYTogYnl0ZXMpIC0+IGJ5dGVzOgp2ZXJpZnlfYnNxcnQ6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvbWlzY2VsbGFuZW91cy1vcHMvY29udHJhY3QuYWxnby50czozNS0zNgogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIHB1YmxpYyB2ZXJpZnlfYnNxcnQoYTogYnl0ZXMpOiBieXRlcyB7CiAgICBwcm90byAxIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9taXNjZWxsYW5lb3VzLW9wcy9jb250cmFjdC5hbGdvLnRzOjM4CiAgICAvLyBjb25zdCByZXN1bHQgPSBvcC5ic3FydChhX2JpZ3VpbnQpCiAgICBmcmFtZV9kaWcgLTEKICAgIGJzcXJ0CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvbWlzY2VsbGFuZW91cy1vcHMvY29udHJhY3QuYWxnby50czozOQogICAgLy8gcmV0dXJuIEJ5dGVzKHJlc3VsdCkKICAgIHJldHN1YgoKCi8vIHRlc3RzL2FydGlmYWN0cy9taXNjZWxsYW5lb3VzLW9wcy9jb250cmFjdC5hbGdvLnRzOjpNaXNjZWxsYW5lb3VzT3BzQ29udHJhY3QudmVyaWZ5X2J0b2koYTogYnl0ZXMpIC0+IHVpbnQ2NDoKdmVyaWZ5X2J0b2k6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvbWlzY2VsbGFuZW91cy1vcHMvY29udHJhY3QuYWxnby50czo0Mi00MwogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIHB1YmxpYyB2ZXJpZnlfYnRvaShhOiBieXRlcyk6IHVpbnQ2NCB7CiAgICBwcm90byAxIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9taXNjZWxsYW5lb3VzLW9wcy9jb250cmFjdC5hbGdvLnRzOjQ0CiAgICAvLyBjb25zdCByZXN1bHQgPSBvcC5idG9pKGEpCiAgICBmcmFtZV9kaWcgLTEKICAgIGJ0b2kKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9taXNjZWxsYW5lb3VzLW9wcy9jb250cmFjdC5hbGdvLnRzOjQ1CiAgICAvLyByZXR1cm4gcmVzdWx0CiAgICByZXRzdWIKCgovLyB0ZXN0cy9hcnRpZmFjdHMvbWlzY2VsbGFuZW91cy1vcHMvY29udHJhY3QuYWxnby50czo6TWlzY2VsbGFuZW91c09wc0NvbnRyYWN0LnZlcmlmeV9iemVybyhhOiB1aW50NjQpIC0+IGJ5dGVzOgp2ZXJpZnlfYnplcm86CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvbWlzY2VsbGFuZW91cy1vcHMvY29udHJhY3QuYWxnby50czo0OC00OQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIHB1YmxpYyB2ZXJpZnlfYnplcm8oYTogdWludDY0KTogYnl0ZXMgewogICAgcHJvdG8gMSAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvbWlzY2VsbGFuZW91cy1vcHMvY29udHJhY3QuYWxnby50czo1MAogICAgLy8gY29uc3QgcmVzdWx0ID0gb3AuYnplcm8oYSkKICAgIGZyYW1lX2RpZyAtMQogICAgYnplcm8KICAgIC8vIHRlc3RzL2FydGlmYWN0cy9taXNjZWxsYW5lb3VzLW9wcy9jb250cmFjdC5hbGdvLnRzOjUxCiAgICAvLyByZXR1cm4gb3Auc2hhMjU2KHJlc3VsdCkKICAgIHNoYTI1NgogICAgcmV0c3ViCgoKLy8gdGVzdHMvYXJ0aWZhY3RzL21pc2NlbGxhbmVvdXMtb3BzL2NvbnRyYWN0LmFsZ28udHM6Ok1pc2NlbGxhbmVvdXNPcHNDb250cmFjdC52ZXJpZnlfY29uY2F0KGE6IGJ5dGVzLCBiOiBieXRlcywgcGFkX2Ffc2l6ZTogdWludDY0LCBwYWRfYl9zaXplOiB1aW50NjQpIC0+IGJ5dGVzOgp2ZXJpZnlfY29uY2F0OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL21pc2NlbGxhbmVvdXMtb3BzL2NvbnRyYWN0LmFsZ28udHM6NTQtNTUKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBwdWJsaWMgdmVyaWZ5X2NvbmNhdChhOiBieXRlcywgYjogYnl0ZXMsIHBhZF9hX3NpemU6IHVpbnQ2NCwgcGFkX2Jfc2l6ZTogdWludDY0KTogYnl0ZXMgewogICAgcHJvdG8gNCAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvbWlzY2VsbGFuZW91cy1vcHMvY29udHJhY3QuYWxnby50czo1NgogICAgLy8gY29uc3QgcGFkZGVkQSA9IG9wLmJ6ZXJvKHBhZF9hX3NpemUpLmNvbmNhdChhKQogICAgZnJhbWVfZGlnIC0yCiAgICBiemVybwogICAgZnJhbWVfZGlnIC00CiAgICBjb25jYXQKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9taXNjZWxsYW5lb3VzLW9wcy9jb250cmFjdC5hbGdvLnRzOjU3CiAgICAvLyBjb25zdCBwYWRkZWRCID0gb3AuYnplcm8ocGFkX2Jfc2l6ZSkuY29uY2F0KGIpCiAgICBmcmFtZV9kaWcgLTEKICAgIGJ6ZXJvCiAgICBmcmFtZV9kaWcgLTMKICAgIGNvbmNhdAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL21pc2NlbGxhbmVvdXMtb3BzL2NvbnRyYWN0LmFsZ28udHM6NTgKICAgIC8vIGNvbnN0IHJlc3VsdCA9IHBhZGRlZEEuY29uY2F0KHBhZGRlZEIpCiAgICBjb25jYXQKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9taXNjZWxsYW5lb3VzLW9wcy9jb250cmFjdC5hbGdvLnRzOjU5CiAgICAvLyBjb25zdCByZXN1bHRIYXNoID0gb3Auc2hhMjU2KHJlc3VsdCkKICAgIHNoYTI1NgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL21pc2NlbGxhbmVvdXMtb3BzL2NvbnRyYWN0LmFsZ28udHM6NjAKICAgIC8vIHJldHVybiByZXN1bHRIYXNoCiAgICByZXRzdWIKCgovLyB0ZXN0cy9hcnRpZmFjdHMvbWlzY2VsbGFuZW91cy1vcHMvY29udHJhY3QuYWxnby50czo6TWlzY2VsbGFuZW91c09wc0NvbnRyYWN0LnZlcmlmeV9kaXZtb2R3KGE6IHVpbnQ2NCwgYjogdWludDY0LCBjOiB1aW50NjQsIGQ6IHVpbnQ2NCkgLT4gdWludDY0LCB1aW50NjQsIHVpbnQ2NCwgdWludDY0Ogp2ZXJpZnlfZGl2bW9kdzoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9taXNjZWxsYW5lb3VzLW9wcy9jb250cmFjdC5hbGdvLnRzOjYzLTY0CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gcHVibGljIHZlcmlmeV9kaXZtb2R3KGE6IHVpbnQ2NCwgYjogdWludDY0LCBjOiB1aW50NjQsIGQ6IHVpbnQ2NCk6IHJlYWRvbmx5IFt1aW50NjQsIHVpbnQ2NCwgdWludDY0LCB1aW50NjRdIHsKICAgIHByb3RvIDQgNAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL21pc2NlbGxhbmVvdXMtb3BzL2NvbnRyYWN0LmFsZ28udHM6NjUKICAgIC8vIGNvbnN0IHJlc3VsdCA9IG9wLmRpdm1vZHcoYSwgYiwgYywgZCkKICAgIGZyYW1lX2RpZyAtNAogICAgZnJhbWVfZGlnIC0zCiAgICBmcmFtZV9kaWcgLTIKICAgIGZyYW1lX2RpZyAtMQogICAgZGl2bW9kdwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL21pc2NlbGxhbmVvdXMtb3BzL2NvbnRyYWN0LmFsZ28udHM6NjYKICAgIC8vIHJldHVybiByZXN1bHQKICAgIHJldHN1YgoKCi8vIHRlc3RzL2FydGlmYWN0cy9taXNjZWxsYW5lb3VzLW9wcy9jb250cmFjdC5hbGdvLnRzOjpNaXNjZWxsYW5lb3VzT3BzQ29udHJhY3QudmVyaWZ5X2RpdncoYTogdWludDY0LCBiOiB1aW50NjQsIGM6IHVpbnQ2NCkgLT4gdWludDY0Ogp2ZXJpZnlfZGl2dzoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9taXNjZWxsYW5lb3VzLW9wcy9jb250cmFjdC5hbGdvLnRzOjY5LTcwCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gcHVibGljIHZlcmlmeV9kaXZ3KGE6IHVpbnQ2NCwgYjogdWludDY0LCBjOiB1aW50NjQpOiB1aW50NjQgewogICAgcHJvdG8gMyAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvbWlzY2VsbGFuZW91cy1vcHMvY29udHJhY3QuYWxnby50czo3MQogICAgLy8gY29uc3QgcmVzdWx0ID0gb3AuZGl2dyhhLCBiLCBjKQogICAgZnJhbWVfZGlnIC0zCiAgICBmcmFtZV9kaWcgLTIKICAgIGZyYW1lX2RpZyAtMQogICAgZGl2dwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL21pc2NlbGxhbmVvdXMtb3BzL2NvbnRyYWN0LmFsZ28udHM6NzIKICAgIC8vIHJldHVybiByZXN1bHQKICAgIHJldHN1YgoKCi8vIHRlc3RzL2FydGlmYWN0cy9taXNjZWxsYW5lb3VzLW9wcy9jb250cmFjdC5hbGdvLnRzOjpNaXNjZWxsYW5lb3VzT3BzQ29udHJhY3QudmVyaWZ5X2VycigpIC0+IHZvaWQ6CnZlcmlmeV9lcnI6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvbWlzY2VsbGFuZW91cy1vcHMvY29udHJhY3QuYWxnby50czo3NS03NgogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIHB1YmxpYyB2ZXJpZnlfZXJyKCk6IHZvaWQgewogICAgcHJvdG8gMCAwCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvbWlzY2VsbGFuZW91cy1vcHMvY29udHJhY3QuYWxnby50czo3NwogICAgLy8gZXJyKCkKICAgIGVycgoKCi8vIHRlc3RzL2FydGlmYWN0cy9taXNjZWxsYW5lb3VzLW9wcy9jb250cmFjdC5hbGdvLnRzOjpNaXNjZWxsYW5lb3VzT3BzQ29udHJhY3QudmVyaWZ5X2V4cChhOiB1aW50NjQsIGI6IHVpbnQ2NCkgLT4gdWludDY0Ogp2ZXJpZnlfZXhwOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL21pc2NlbGxhbmVvdXMtb3BzL2NvbnRyYWN0LmFsZ28udHM6ODAtODEKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBwdWJsaWMgdmVyaWZ5X2V4cChhOiB1aW50NjQsIGI6IHVpbnQ2NCk6IHVpbnQ2NCB7CiAgICBwcm90byAyIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9taXNjZWxsYW5lb3VzLW9wcy9jb250cmFjdC5hbGdvLnRzOjgyCiAgICAvLyBjb25zdCByZXN1bHQgPSBvcC5leHAoYSwgYikKICAgIGZyYW1lX2RpZyAtMgogICAgZnJhbWVfZGlnIC0xCiAgICBleHAKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9taXNjZWxsYW5lb3VzLW9wcy9jb250cmFjdC5hbGdvLnRzOjgzCiAgICAvLyByZXR1cm4gcmVzdWx0CiAgICByZXRzdWIKCgovLyB0ZXN0cy9hcnRpZmFjdHMvbWlzY2VsbGFuZW91cy1vcHMvY29udHJhY3QuYWxnby50czo6TWlzY2VsbGFuZW91c09wc0NvbnRyYWN0LnZlcmlmeV9leHB3KGE6IHVpbnQ2NCwgYjogdWludDY0KSAtPiB1aW50NjQsIHVpbnQ2NDoKdmVyaWZ5X2V4cHc6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvbWlzY2VsbGFuZW91cy1vcHMvY29udHJhY3QuYWxnby50czo4Ni04NwogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIHB1YmxpYyB2ZXJpZnlfZXhwdyhhOiB1aW50NjQsIGI6IHVpbnQ2NCk6IHJlYWRvbmx5IFt1aW50NjQsIHVpbnQ2NF0gewogICAgcHJvdG8gMiAyCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvbWlzY2VsbGFuZW91cy1vcHMvY29udHJhY3QuYWxnby50czo4OAogICAgLy8gY29uc3QgcmVzdWx0ID0gb3AuZXhwdyhhLCBiKQogICAgZnJhbWVfZGlnIC0yCiAgICBmcmFtZV9kaWcgLTEKICAgIGV4cHcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9taXNjZWxsYW5lb3VzLW9wcy9jb250cmFjdC5hbGdvLnRzOjg5CiAgICAvLyByZXR1cm4gcmVzdWx0CiAgICByZXRzdWIKCgovLyB0ZXN0cy9hcnRpZmFjdHMvbWlzY2VsbGFuZW91cy1vcHMvY29udHJhY3QuYWxnby50czo6TWlzY2VsbGFuZW91c09wc0NvbnRyYWN0LnZlcmlmeV9leHRyYWN0KGE6IGJ5dGVzLCBiOiB1aW50NjQsIGM6IHVpbnQ2NCkgLT4gYnl0ZXM6CnZlcmlmeV9leHRyYWN0OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL21pc2NlbGxhbmVvdXMtb3BzL2NvbnRyYWN0LmFsZ28udHM6OTItOTMKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBwdWJsaWMgdmVyaWZ5X2V4dHJhY3QoYTogYnl0ZXMsIGI6IHVpbnQ2NCwgYzogdWludDY0KTogYnl0ZXMgewogICAgcHJvdG8gMyAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvbWlzY2VsbGFuZW91cy1vcHMvY29udHJhY3QuYWxnby50czo5NAogICAgLy8gY29uc3QgcmVzdWx0ID0gb3AuZXh0cmFjdChhLCBiLCBjKQogICAgZnJhbWVfZGlnIC0zCiAgICBmcmFtZV9kaWcgLTIKICAgIGZyYW1lX2RpZyAtMQogICAgZXh0cmFjdDMKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9taXNjZWxsYW5lb3VzLW9wcy9jb250cmFjdC5hbGdvLnRzOjk1CiAgICAvLyByZXR1cm4gcmVzdWx0CiAgICByZXRzdWIKCgovLyB0ZXN0cy9hcnRpZmFjdHMvbWlzY2VsbGFuZW91cy1vcHMvY29udHJhY3QuYWxnby50czo6TWlzY2VsbGFuZW91c09wc0NvbnRyYWN0LnZlcmlmeV9leHRyYWN0X2Zyb21fMihhOiBieXRlcykgLT4gYnl0ZXM6CnZlcmlmeV9leHRyYWN0X2Zyb21fMjoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9taXNjZWxsYW5lb3VzLW9wcy9jb250cmFjdC5hbGdvLnRzOjk5LTEwMAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIHB1YmxpYyB2ZXJpZnlfZXh0cmFjdF9mcm9tXzIoYTogYnl0ZXMpOiBieXRlcyB7CiAgICBwcm90byAxIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9taXNjZWxsYW5lb3VzLW9wcy9jb250cmFjdC5hbGdvLnRzOjEwMQogICAgLy8gY29uc3QgcmVzdWx0ID0gb3AuZXh0cmFjdChhLCAyLCAwKQogICAgZnJhbWVfZGlnIC0xCiAgICBwdXNoaW50IDIgLy8gMgogICAgaW50Y18xIC8vIDAKICAgIGV4dHJhY3QzCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvbWlzY2VsbGFuZW91cy1vcHMvY29udHJhY3QuYWxnby50czoxMDIKICAgIC8vIHJldHVybiByZXN1bHQKICAgIHJldHN1YgoKCi8vIHRlc3RzL2FydGlmYWN0cy9taXNjZWxsYW5lb3VzLW9wcy9jb250cmFjdC5hbGdvLnRzOjpNaXNjZWxsYW5lb3VzT3BzQ29udHJhY3QudmVyaWZ5X2V4dHJhY3RfdWludDE2KGE6IGJ5dGVzLCBiOiB1aW50NjQpIC0+IHVpbnQ2NDoKdmVyaWZ5X2V4dHJhY3RfdWludDE2OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL21pc2NlbGxhbmVvdXMtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTA1LTEwNgogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIHB1YmxpYyB2ZXJpZnlfZXh0cmFjdF91aW50MTYoYTogYnl0ZXMsIGI6IHVpbnQ2NCk6IHVpbnQ2NCB7CiAgICBwcm90byAyIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9taXNjZWxsYW5lb3VzLW9wcy9jb250cmFjdC5hbGdvLnRzOjEwNwogICAgLy8gY29uc3QgcmVzdWx0ID0gb3AuZXh0cmFjdFVpbnQxNihhLCBiKQogICAgZnJhbWVfZGlnIC0yCiAgICBmcmFtZV9kaWcgLTEKICAgIGV4dHJhY3RfdWludDE2CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvbWlzY2VsbGFuZW91cy1vcHMvY29udHJhY3QuYWxnby50czoxMDgKICAgIC8vIHJldHVybiByZXN1bHQKICAgIHJldHN1YgoKCi8vIHRlc3RzL2FydGlmYWN0cy9taXNjZWxsYW5lb3VzLW9wcy9jb250cmFjdC5hbGdvLnRzOjpNaXNjZWxsYW5lb3VzT3BzQ29udHJhY3QudmVyaWZ5X2V4dHJhY3RfdWludDMyKGE6IGJ5dGVzLCBiOiB1aW50NjQpIC0+IHVpbnQ2NDoKdmVyaWZ5X2V4dHJhY3RfdWludDMyOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL21pc2NlbGxhbmVvdXMtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTExLTExMgogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIHB1YmxpYyB2ZXJpZnlfZXh0cmFjdF91aW50MzIoYTogYnl0ZXMsIGI6IHVpbnQ2NCk6IHVpbnQ2NCB7CiAgICBwcm90byAyIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9taXNjZWxsYW5lb3VzLW9wcy9jb250cmFjdC5hbGdvLnRzOjExMwogICAgLy8gY29uc3QgcmVzdWx0ID0gb3AuZXh0cmFjdFVpbnQzMihhLCBiKQogICAgZnJhbWVfZGlnIC0yCiAgICBmcmFtZV9kaWcgLTEKICAgIGV4dHJhY3RfdWludDMyCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvbWlzY2VsbGFuZW91cy1vcHMvY29udHJhY3QuYWxnby50czoxMTQKICAgIC8vIHJldHVybiByZXN1bHQKICAgIHJldHN1YgoKCi8vIHRlc3RzL2FydGlmYWN0cy9taXNjZWxsYW5lb3VzLW9wcy9jb250cmFjdC5hbGdvLnRzOjpNaXNjZWxsYW5lb3VzT3BzQ29udHJhY3QudmVyaWZ5X2V4dHJhY3RfdWludDY0KGE6IGJ5dGVzLCBiOiB1aW50NjQpIC0+IHVpbnQ2NDoKdmVyaWZ5X2V4dHJhY3RfdWludDY0OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL21pc2NlbGxhbmVvdXMtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTE3LTExOAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIHB1YmxpYyB2ZXJpZnlfZXh0cmFjdF91aW50NjQoYTogYnl0ZXMsIGI6IHVpbnQ2NCk6IHVpbnQ2NCB7CiAgICBwcm90byAyIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9taXNjZWxsYW5lb3VzLW9wcy9jb250cmFjdC5hbGdvLnRzOjExOQogICAgLy8gY29uc3QgcmVzdWx0ID0gb3AuZXh0cmFjdFVpbnQ2NChhLCBiKQogICAgZnJhbWVfZGlnIC0yCiAgICBmcmFtZV9kaWcgLTEKICAgIGV4dHJhY3RfdWludDY0CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvbWlzY2VsbGFuZW91cy1vcHMvY29udHJhY3QuYWxnby50czoxMjAKICAgIC8vIHJldHVybiByZXN1bHQKICAgIHJldHN1YgoKCi8vIHRlc3RzL2FydGlmYWN0cy9taXNjZWxsYW5lb3VzLW9wcy9jb250cmFjdC5hbGdvLnRzOjpNaXNjZWxsYW5lb3VzT3BzQ29udHJhY3QudmVyaWZ5X2dldGJpdF9ieXRlcyhhOiBieXRlcywgYjogdWludDY0KSAtPiB1aW50NjQ6CnZlcmlmeV9nZXRiaXRfYnl0ZXM6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvbWlzY2VsbGFuZW91cy1vcHMvY29udHJhY3QuYWxnby50czoxMjMtMTI0CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gcHVibGljIHZlcmlmeV9nZXRiaXRfYnl0ZXMoYTogYnl0ZXMsIGI6IHVpbnQ2NCk6IHVpbnQ2NCB7CiAgICBwcm90byAyIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9taXNjZWxsYW5lb3VzLW9wcy9jb250cmFjdC5hbGdvLnRzOjEyNQogICAgLy8gY29uc3QgcmVzdWx0ID0gb3AuZ2V0Qml0KGEsIGIpCiAgICBmcmFtZV9kaWcgLTIKICAgIGZyYW1lX2RpZyAtMQogICAgZ2V0Yml0CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvbWlzY2VsbGFuZW91cy1vcHMvY29udHJhY3QuYWxnby50czoxMjYKICAgIC8vIHJldHVybiByZXN1bHQKICAgIHJldHN1YgoKCi8vIHRlc3RzL2FydGlmYWN0cy9taXNjZWxsYW5lb3VzLW9wcy9jb250cmFjdC5hbGdvLnRzOjpNaXNjZWxsYW5lb3VzT3BzQ29udHJhY3QudmVyaWZ5X2dldGJpdF91aW50NjQoYTogdWludDY0LCBiOiB1aW50NjQpIC0+IHVpbnQ2NDoKdmVyaWZ5X2dldGJpdF91aW50NjQ6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvbWlzY2VsbGFuZW91cy1vcHMvY29udHJhY3QuYWxnby50czoxMjktMTMwCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gcHVibGljIHZlcmlmeV9nZXRiaXRfdWludDY0KGE6IHVpbnQ2NCwgYjogdWludDY0KTogdWludDY0IHsKICAgIHByb3RvIDIgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL21pc2NlbGxhbmVvdXMtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTMxCiAgICAvLyBjb25zdCByZXN1bHQgPSBvcC5nZXRCaXQoYSwgYikKICAgIGZyYW1lX2RpZyAtMgogICAgZnJhbWVfZGlnIC0xCiAgICBnZXRiaXQKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9taXNjZWxsYW5lb3VzLW9wcy9jb250cmFjdC5hbGdvLnRzOjEzMgogICAgLy8gcmV0dXJuIHJlc3VsdAogICAgcmV0c3ViCgoKLy8gdGVzdHMvYXJ0aWZhY3RzL21pc2NlbGxhbmVvdXMtb3BzL2NvbnRyYWN0LmFsZ28udHM6Ok1pc2NlbGxhbmVvdXNPcHNDb250cmFjdC52ZXJpZnlfZ2V0Ynl0ZShhOiBieXRlcywgYjogdWludDY0KSAtPiB1aW50NjQ6CnZlcmlmeV9nZXRieXRlOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL21pc2NlbGxhbmVvdXMtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTM1LTEzNgogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIHB1YmxpYyB2ZXJpZnlfZ2V0Ynl0ZShhOiBieXRlcywgYjogdWludDY0KTogdWludDY0IHsKICAgIHByb3RvIDIgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL21pc2NlbGxhbmVvdXMtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTM3CiAgICAvLyBjb25zdCByZXN1bHQgPSBvcC5nZXRCeXRlKGEsIGIpCiAgICBmcmFtZV9kaWcgLTIKICAgIGZyYW1lX2RpZyAtMQogICAgZ2V0Ynl0ZQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL21pc2NlbGxhbmVvdXMtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTM4CiAgICAvLyByZXR1cm4gcmVzdWx0CiAgICByZXRzdWIKCgovLyB0ZXN0cy9hcnRpZmFjdHMvbWlzY2VsbGFuZW91cy1vcHMvY29udHJhY3QuYWxnby50czo6TWlzY2VsbGFuZW91c09wc0NvbnRyYWN0LnZlcmlmeV9pdG9iKGE6IHVpbnQ2NCkgLT4gYnl0ZXM6CnZlcmlmeV9pdG9iOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL21pc2NlbGxhbmVvdXMtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTQxLTE0MgogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIHB1YmxpYyB2ZXJpZnlfaXRvYihhOiB1aW50NjQpOiBieXRlcyB7CiAgICBwcm90byAxIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9taXNjZWxsYW5lb3VzLW9wcy9jb250cmFjdC5hbGdvLnRzOjE0MwogICAgLy8gY29uc3QgcmVzdWx0ID0gb3AuaXRvYihhKQogICAgZnJhbWVfZGlnIC0xCiAgICBpdG9iCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvbWlzY2VsbGFuZW91cy1vcHMvY29udHJhY3QuYWxnby50czoxNDQKICAgIC8vIHJldHVybiByZXN1bHQKICAgIHJldHN1YgoKCi8vIHRlc3RzL2FydGlmYWN0cy9taXNjZWxsYW5lb3VzLW9wcy9jb250cmFjdC5hbGdvLnRzOjpNaXNjZWxsYW5lb3VzT3BzQ29udHJhY3QudmVyaWZ5X2J5dGVzX2xlbihhOiBieXRlcywgcGFkX2Ffc2l6ZTogdWludDY0KSAtPiB1aW50NjQ6CnZlcmlmeV9ieXRlc19sZW46CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvbWlzY2VsbGFuZW91cy1vcHMvY29udHJhY3QuYWxnby50czoxNDctMTQ4CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gcHVibGljIHZlcmlmeV9ieXRlc19sZW4oYTogYnl0ZXMsIHBhZF9hX3NpemU6IHVpbnQ2NCk6IHVpbnQ2NCB7CiAgICBwcm90byAyIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9taXNjZWxsYW5lb3VzLW9wcy9jb250cmFjdC5hbGdvLnRzOjE0OQogICAgLy8gY29uc3QgcGFkZGVkQSA9IG9wLmJ6ZXJvKHBhZF9hX3NpemUpLmNvbmNhdChhKQogICAgZnJhbWVfZGlnIC0xCiAgICBiemVybwogICAgZnJhbWVfZGlnIC0yCiAgICBjb25jYXQKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9taXNjZWxsYW5lb3VzLW9wcy9jb250cmFjdC5hbGdvLnRzOjE1MAogICAgLy8gY29uc3QgcmVzdWx0ID0gb3AubGVuKHBhZGRlZEEpCiAgICBsZW4KICAgIC8vIHRlc3RzL2FydGlmYWN0cy9taXNjZWxsYW5lb3VzLW9wcy9jb250cmFjdC5hbGdvLnRzOjE1MQogICAgLy8gcmV0dXJuIHJlc3VsdAogICAgcmV0c3ViCgoKLy8gdGVzdHMvYXJ0aWZhY3RzL21pc2NlbGxhbmVvdXMtb3BzL2NvbnRyYWN0LmFsZ28udHM6Ok1pc2NlbGxhbmVvdXNPcHNDb250cmFjdC52ZXJpZnlfbXVsdyhhOiB1aW50NjQsIGI6IHVpbnQ2NCkgLT4gdWludDY0LCB1aW50NjQ6CnZlcmlmeV9tdWx3OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL21pc2NlbGxhbmVvdXMtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTU0LTE1NQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIHB1YmxpYyB2ZXJpZnlfbXVsdyhhOiB1aW50NjQsIGI6IHVpbnQ2NCk6IHJlYWRvbmx5IFt1aW50NjQsIHVpbnQ2NF0gewogICAgcHJvdG8gMiAyCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvbWlzY2VsbGFuZW91cy1vcHMvY29udHJhY3QuYWxnby50czoxNTYKICAgIC8vIGNvbnN0IHJlc3VsdCA9IG9wLm11bHcoYSwgYikKICAgIGZyYW1lX2RpZyAtMgogICAgZnJhbWVfZGlnIC0xCiAgICBtdWx3CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvbWlzY2VsbGFuZW91cy1vcHMvY29udHJhY3QuYWxnby50czoxNTcKICAgIC8vIHJldHVybiByZXN1bHQKICAgIHJldHN1YgoKCi8vIHRlc3RzL2FydGlmYWN0cy9taXNjZWxsYW5lb3VzLW9wcy9jb250cmFjdC5hbGdvLnRzOjpNaXNjZWxsYW5lb3VzT3BzQ29udHJhY3QudmVyaWZ5X3JlcGxhY2UoYTogYnl0ZXMsIGI6IHVpbnQ2NCwgYzogYnl0ZXMpIC0+IGJ5dGVzOgp2ZXJpZnlfcmVwbGFjZToKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9taXNjZWxsYW5lb3VzLW9wcy9jb250cmFjdC5hbGdvLnRzOjE2MC0xNjEKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBwdWJsaWMgdmVyaWZ5X3JlcGxhY2UoYTogYnl0ZXMsIGI6IHVpbnQ2NCwgYzogYnl0ZXMpOiBieXRlcyB7CiAgICBwcm90byAzIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9taXNjZWxsYW5lb3VzLW9wcy9jb250cmFjdC5hbGdvLnRzOjE2MgogICAgLy8gY29uc3QgcmVzdWx0ID0gb3AucmVwbGFjZShhLCBiLCBjKQogICAgZnJhbWVfZGlnIC0zCiAgICBmcmFtZV9kaWcgLTIKICAgIGZyYW1lX2RpZyAtMQogICAgcmVwbGFjZTMKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9taXNjZWxsYW5lb3VzLW9wcy9jb250cmFjdC5hbGdvLnRzOjE2MwogICAgLy8gcmV0dXJuIHJlc3VsdAogICAgcmV0c3ViCgoKLy8gdGVzdHMvYXJ0aWZhY3RzL21pc2NlbGxhbmVvdXMtb3BzL2NvbnRyYWN0LmFsZ28udHM6Ok1pc2NlbGxhbmVvdXNPcHNDb250cmFjdC52ZXJpZnlfc2VsZWN0X2J5dGVzKGE6IGJ5dGVzLCBiOiBieXRlcywgYzogdWludDY0KSAtPiBieXRlczoKdmVyaWZ5X3NlbGVjdF9ieXRlczoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9taXNjZWxsYW5lb3VzLW9wcy9jb250cmFjdC5hbGdvLnRzOjE2Ni0xNjcKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBwdWJsaWMgdmVyaWZ5X3NlbGVjdF9ieXRlcyhhOiBieXRlcywgYjogYnl0ZXMsIGM6IHVpbnQ2NCk6IGJ5dGVzIHsKICAgIHByb3RvIDMgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL21pc2NlbGxhbmVvdXMtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTY4CiAgICAvLyBjb25zdCByZXN1bHQgPSBvcC5zZWxlY3QoYSwgYiwgYykKICAgIGZyYW1lX2RpZyAtMwogICAgZnJhbWVfZGlnIC0yCiAgICBmcmFtZV9kaWcgLTEKICAgIHNlbGVjdAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL21pc2NlbGxhbmVvdXMtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTY5CiAgICAvLyByZXR1cm4gcmVzdWx0CiAgICByZXRzdWIKCgovLyB0ZXN0cy9hcnRpZmFjdHMvbWlzY2VsbGFuZW91cy1vcHMvY29udHJhY3QuYWxnby50czo6TWlzY2VsbGFuZW91c09wc0NvbnRyYWN0LnZlcmlmeV9zZWxlY3RfdWludDY0KGE6IHVpbnQ2NCwgYjogdWludDY0LCBjOiB1aW50NjQpIC0+IHVpbnQ2NDoKdmVyaWZ5X3NlbGVjdF91aW50NjQ6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvbWlzY2VsbGFuZW91cy1vcHMvY29udHJhY3QuYWxnby50czoxNzItMTczCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gcHVibGljIHZlcmlmeV9zZWxlY3RfdWludDY0KGE6IHVpbnQ2NCwgYjogdWludDY0LCBjOiB1aW50NjQpOiB1aW50NjQgewogICAgcHJvdG8gMyAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvbWlzY2VsbGFuZW91cy1vcHMvY29udHJhY3QuYWxnby50czoxNzQKICAgIC8vIGNvbnN0IHJlc3VsdCA9IG9wLnNlbGVjdChhLCBiLCBjKQogICAgZnJhbWVfZGlnIC0zCiAgICBmcmFtZV9kaWcgLTIKICAgIGZyYW1lX2RpZyAtMQogICAgc2VsZWN0CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvbWlzY2VsbGFuZW91cy1vcHMvY29udHJhY3QuYWxnby50czoxNzUKICAgIC8vIHJldHVybiByZXN1bHQKICAgIHJldHN1YgoKCi8vIHRlc3RzL2FydGlmYWN0cy9taXNjZWxsYW5lb3VzLW9wcy9jb250cmFjdC5hbGdvLnRzOjpNaXNjZWxsYW5lb3VzT3BzQ29udHJhY3QudmVyaWZ5X3NldGJpdF9ieXRlcyhhOiBieXRlcywgYjogdWludDY0LCBjOiB1aW50NjQpIC0+IGJ5dGVzOgp2ZXJpZnlfc2V0Yml0X2J5dGVzOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL21pc2NlbGxhbmVvdXMtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTc4LTE3OQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIHB1YmxpYyB2ZXJpZnlfc2V0Yml0X2J5dGVzKGE6IGJ5dGVzLCBiOiB1aW50NjQsIGM6IHVpbnQ2NCk6IGJ5dGVzIHsKICAgIHByb3RvIDMgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL21pc2NlbGxhbmVvdXMtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTgwCiAgICAvLyBjb25zdCByZXN1bHQgPSBvcC5zZXRCaXQoYSwgYiwgYykKICAgIGZyYW1lX2RpZyAtMwogICAgZnJhbWVfZGlnIC0yCiAgICBmcmFtZV9kaWcgLTEKICAgIHNldGJpdAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL21pc2NlbGxhbmVvdXMtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTgxCiAgICAvLyByZXR1cm4gcmVzdWx0CiAgICByZXRzdWIKCgovLyB0ZXN0cy9hcnRpZmFjdHMvbWlzY2VsbGFuZW91cy1vcHMvY29udHJhY3QuYWxnby50czo6TWlzY2VsbGFuZW91c09wc0NvbnRyYWN0LnZlcmlmeV9zZXRiaXRfdWludDY0KGE6IHVpbnQ2NCwgYjogdWludDY0LCBjOiB1aW50NjQpIC0+IHVpbnQ2NDoKdmVyaWZ5X3NldGJpdF91aW50NjQ6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvbWlzY2VsbGFuZW91cy1vcHMvY29udHJhY3QuYWxnby50czoxODQtMTg1CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gcHVibGljIHZlcmlmeV9zZXRiaXRfdWludDY0KGE6IHVpbnQ2NCwgYjogdWludDY0LCBjOiB1aW50NjQpOiB1aW50NjQgewogICAgcHJvdG8gMyAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvbWlzY2VsbGFuZW91cy1vcHMvY29udHJhY3QuYWxnby50czoxODYKICAgIC8vIGNvbnN0IHJlc3VsdCA9IG9wLnNldEJpdChhLCBiLCBjKQogICAgZnJhbWVfZGlnIC0zCiAgICBmcmFtZV9kaWcgLTIKICAgIGZyYW1lX2RpZyAtMQogICAgc2V0Yml0CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvbWlzY2VsbGFuZW91cy1vcHMvY29udHJhY3QuYWxnby50czoxODcKICAgIC8vIHJldHVybiByZXN1bHQKICAgIHJldHN1YgoKCi8vIHRlc3RzL2FydGlmYWN0cy9taXNjZWxsYW5lb3VzLW9wcy9jb250cmFjdC5hbGdvLnRzOjpNaXNjZWxsYW5lb3VzT3BzQ29udHJhY3QudmVyaWZ5X3NldGJ5dGUoYTogYnl0ZXMsIGI6IHVpbnQ2NCwgYzogdWludDY0KSAtPiBieXRlczoKdmVyaWZ5X3NldGJ5dGU6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvbWlzY2VsbGFuZW91cy1vcHMvY29udHJhY3QuYWxnby50czoxOTAtMTkxCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gcHVibGljIHZlcmlmeV9zZXRieXRlKGE6IGJ5dGVzLCBiOiB1aW50NjQsIGM6IHVpbnQ2NCk6IGJ5dGVzIHsKICAgIHByb3RvIDMgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL21pc2NlbGxhbmVvdXMtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTkyCiAgICAvLyBjb25zdCByZXN1bHQgPSBvcC5zZXRCeXRlKGEsIGIsIGMpCiAgICBmcmFtZV9kaWcgLTMKICAgIGZyYW1lX2RpZyAtMgogICAgZnJhbWVfZGlnIC0xCiAgICBzZXRieXRlCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvbWlzY2VsbGFuZW91cy1vcHMvY29udHJhY3QuYWxnby50czoxOTMKICAgIC8vIHJldHVybiByZXN1bHQKICAgIHJldHN1YgoKCi8vIHRlc3RzL2FydGlmYWN0cy9taXNjZWxsYW5lb3VzLW9wcy9jb250cmFjdC5hbGdvLnRzOjpNaXNjZWxsYW5lb3VzT3BzQ29udHJhY3QudmVyaWZ5X3NobChhOiB1aW50NjQsIGI6IHVpbnQ2NCkgLT4gdWludDY0Ogp2ZXJpZnlfc2hsOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL21pc2NlbGxhbmVvdXMtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTk2LTE5NwogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIHB1YmxpYyB2ZXJpZnlfc2hsKGE6IHVpbnQ2NCwgYjogdWludDY0KTogdWludDY0IHsKICAgIHByb3RvIDIgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL21pc2NlbGxhbmVvdXMtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTk4CiAgICAvLyBjb25zdCByZXN1bHQgPSBvcC5zaGwoYSwgYikKICAgIGZyYW1lX2RpZyAtMgogICAgZnJhbWVfZGlnIC0xCiAgICBzaGwKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9taXNjZWxsYW5lb3VzLW9wcy9jb250cmFjdC5hbGdvLnRzOjE5OQogICAgLy8gcmV0dXJuIHJlc3VsdAogICAgcmV0c3ViCgoKLy8gdGVzdHMvYXJ0aWZhY3RzL21pc2NlbGxhbmVvdXMtb3BzL2NvbnRyYWN0LmFsZ28udHM6Ok1pc2NlbGxhbmVvdXNPcHNDb250cmFjdC52ZXJpZnlfc2hyKGE6IHVpbnQ2NCwgYjogdWludDY0KSAtPiB1aW50NjQ6CnZlcmlmeV9zaHI6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvbWlzY2VsbGFuZW91cy1vcHMvY29udHJhY3QuYWxnby50czoyMDItMjAzCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gcHVibGljIHZlcmlmeV9zaHIoYTogdWludDY0LCBiOiB1aW50NjQpOiB1aW50NjQgewogICAgcHJvdG8gMiAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvbWlzY2VsbGFuZW91cy1vcHMvY29udHJhY3QuYWxnby50czoyMDQKICAgIC8vIGNvbnN0IHJlc3VsdCA9IG9wLnNocihhLCBiKQogICAgZnJhbWVfZGlnIC0yCiAgICBmcmFtZV9kaWcgLTEKICAgIHNocgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL21pc2NlbGxhbmVvdXMtb3BzL2NvbnRyYWN0LmFsZ28udHM6MjA1CiAgICAvLyByZXR1cm4gcmVzdWx0CiAgICByZXRzdWIKCgovLyB0ZXN0cy9hcnRpZmFjdHMvbWlzY2VsbGFuZW91cy1vcHMvY29udHJhY3QuYWxnby50czo6TWlzY2VsbGFuZW91c09wc0NvbnRyYWN0LnZlcmlmeV9zcXJ0KGE6IHVpbnQ2NCkgLT4gdWludDY0Ogp2ZXJpZnlfc3FydDoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9taXNjZWxsYW5lb3VzLW9wcy9jb250cmFjdC5hbGdvLnRzOjIwOC0yMDkKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBwdWJsaWMgdmVyaWZ5X3NxcnQoYTogdWludDY0KTogdWludDY0IHsKICAgIHByb3RvIDEgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL21pc2NlbGxhbmVvdXMtb3BzL2NvbnRyYWN0LmFsZ28udHM6MjEwCiAgICAvLyBjb25zdCByZXN1bHQgPSBvcC5zcXJ0KGEpCiAgICBmcmFtZV9kaWcgLTEKICAgIHNxcnQKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9taXNjZWxsYW5lb3VzLW9wcy9jb250cmFjdC5hbGdvLnRzOjIxMQogICAgLy8gcmV0dXJuIHJlc3VsdAogICAgcmV0c3ViCgoKLy8gdGVzdHMvYXJ0aWZhY3RzL21pc2NlbGxhbmVvdXMtb3BzL2NvbnRyYWN0LmFsZ28udHM6Ok1pc2NlbGxhbmVvdXNPcHNDb250cmFjdC52ZXJpZnlfc3Vic3RyaW5nKGE6IGJ5dGVzLCBiOiB1aW50NjQsIGM6IHVpbnQ2NCkgLT4gYnl0ZXM6CnZlcmlmeV9zdWJzdHJpbmc6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvbWlzY2VsbGFuZW91cy1vcHMvY29udHJhY3QuYWxnby50czoyMTQtMjE1CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gcHVibGljIHZlcmlmeV9zdWJzdHJpbmcoYTogYnl0ZXMsIGI6IHVpbnQ2NCwgYzogdWludDY0KTogYnl0ZXMgewogICAgcHJvdG8gMyAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvbWlzY2VsbGFuZW91cy1vcHMvY29udHJhY3QuYWxnby50czoyMTYKICAgIC8vIGNvbnN0IHJlc3VsdCA9IG9wLnN1YnN0cmluZyhhLCBiLCBjKQogICAgZnJhbWVfZGlnIC0zCiAgICBmcmFtZV9kaWcgLTIKICAgIGZyYW1lX2RpZyAtMQogICAgc3Vic3RyaW5nMwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL21pc2NlbGxhbmVvdXMtb3BzL2NvbnRyYWN0LmFsZ28udHM6MjE3CiAgICAvLyByZXR1cm4gcmVzdWx0CiAgICByZXRzdWIK", - "clear": "I3ByYWdtYSB2ZXJzaW9uIDEwCgp0ZXN0cy9hcnRpZmFjdHMvbWlzY2VsbGFuZW91cy1vcHMvY29udHJhY3QuYWxnby50czo6TWlzY2VsbGFuZW91c09wc0NvbnRyYWN0LmNsZWFyU3RhdGVQcm9ncmFtOgogICAgcHVzaGludCAxIC8vIDEKICAgIHJldHVybgo=" - }, - "events": [], - "templateVariables": {} -} \ No newline at end of file diff --git a/tests/artifacts/miscellaneous-ops/data/MiscellaneousOpsContract.clear.teal b/tests/artifacts/miscellaneous-ops/data/MiscellaneousOpsContract.clear.teal deleted file mode 100644 index ccc2a5e..0000000 --- a/tests/artifacts/miscellaneous-ops/data/MiscellaneousOpsContract.clear.teal +++ /dev/null @@ -1,5 +0,0 @@ -#pragma version 10 - -tests/artifacts/miscellaneous-ops/contract.algo.ts::MiscellaneousOpsContract.clearStateProgram: - pushint 1 // 1 - return diff --git a/tests/artifacts/multi-inheritance/contract.algo.ts b/tests/artifacts/multi-inheritance/contract.algo.ts new file mode 100644 index 0000000..b6d53cb --- /dev/null +++ b/tests/artifacts/multi-inheritance/contract.algo.ts @@ -0,0 +1,58 @@ +import type { uint64 } from '@algorandfoundation/algorand-typescript' +import { Contract, GlobalState, Uint64 } from '@algorandfoundation/algorand-typescript' +import { classes } from 'polytype' + +export class CommonBase extends Contract { + stateCommon = GlobalState({ initialValue: 123 }) + + methodCommon() { + return 'common' + } + + b2CantOverride(): string { + return 'common' + } +} + +export class BaseOne extends CommonBase { + stateOne = GlobalState({ initialValue: Uint64(45) }) + methodOne() { + return 'base-one' + } +} + +export class BaseTwo extends CommonBase { + stateTwo = GlobalState({ initialValue: 'Hello' }) + methodTwo() { + return 'base-two' + } + + /** + * Because CommonBase implements this method, and MRO for polytype is depth first; this method + * should not be accessible from MultiBases as the MRO should be `BaseOne => CommonBase => BaseTwo => CommonBase` + * and since CommonBase provides an implementation, this one should not be used + */ + b2CantOverride(): string { + return 'base-two' + } +} + +export class MultiBases extends classes(BaseOne, BaseTwo) { + stateMulti = GlobalState({ initialValue: 'Hmmm' }) + + methodMulti() { + return 'multi-bases' + } + + methodCallsSuper() { + return super.methodTwo() + } + + callB2CantOverride() { + return super.class(BaseTwo).b2CantOverride() + } + + callB2Common() { + return super.class(BaseTwo).methodCommon() + } +} diff --git a/tests/artifacts/primitive-ops/contract.algo.ts b/tests/artifacts/primitive-ops/contract.algo.ts index 9dfee26..2759f38 100644 --- a/tests/artifacts/primitive-ops/contract.algo.ts +++ b/tests/artifacts/primitive-ops/contract.algo.ts @@ -1,8 +1,8 @@ -import { arc4, biguint, BigUint, Bytes, bytes, log, op, uint64 } from '@algorandfoundation/algorand-typescript' -import { +import type { biguint, bytes, uint64 } from '@algorandfoundation/algorand-typescript' +import { arc4, BigUint, Bytes, log, op } from '@algorandfoundation/algorand-typescript' +import type { Bool, DynamicArray, - interpretAsArc4, StaticArray, Str, Tuple, @@ -13,6 +13,7 @@ import { UintN64, UintN8, } from '@algorandfoundation/algorand-typescript/arc4' +import { interpretAsArc4 } from '@algorandfoundation/algorand-typescript/arc4' export class PrimitiveOpsContract extends arc4.Contract { @arc4.abimethod() diff --git a/tests/artifacts/primitive-ops/data/PrimitiveOpsContract.approval.teal b/tests/artifacts/primitive-ops/data/PrimitiveOpsContract.approval.teal deleted file mode 100644 index 873741f..0000000 --- a/tests/artifacts/primitive-ops/data/PrimitiveOpsContract.approval.teal +++ /dev/null @@ -1,2608 +0,0 @@ -#pragma version 10 - -tests/artifacts/primitive-ops/contract.algo.ts::PrimitiveOpsContract.approvalProgram: - intcblock 1 0 - bytecblock 0x151f7c75 0x00 - callsub __puya_arc4_router__ - return - - -// tests/artifacts/primitive-ops/contract.algo.ts::PrimitiveOpsContract.__puya_arc4_router__() -> uint64: -__puya_arc4_router__: - // tests/artifacts/primitive-ops/contract.algo.ts:4 - // export class PrimitiveOpsContract extends arc4.Contract { - proto 0 1 - txn NumAppArgs - bz __puya_arc4_router___bare_routing@60 - pushbytess 0x725c692b 0x17314559 0x53f34893 0x88c8b269 0xa464b7ab 0x9c8b11b8 0x6f40654e 0xec9a2974 0xc793708f 0x7ddb7499 0xa21c443d 0x6e7fb212 0xb007fcb0 0x2ebc20d4 0xb0954b66 0xdd140aef 0xace474da 0xba694990 0x6db581c0 0x91c8db89 0xdbe77158 0x9a0f22e1 0x64033d37 0x2a7237c5 0xe3a94458 0x42f87f7d 0x2b5542a4 0x9be2fbe9 0x1cd92515 0x64e1705c 0xf1271c50 0x2ab63b70 0x834bb7d2 0x531620d7 0x3fb9e769 0xfa8db0bc 0xa72ea485 0xb7b0ba19 0x74460c42 0xab320738 0x52ad4654 0x10156399 0x0f075957 0xbd843dff 0xb377d381 0x89767265 0x456b4b23 0x33d1b88c 0x6bf973ea 0x67cd6bb2 0x3f58805a 0x1e130039 0x509dc91d 0xa564a202 0x23650763 0xe007c10b // method "verify_uint64_init(byte[])uint64", method "verify_uint64_add(uint64,uint64)uint64", method "verify_uint64_sub(uint64,uint64)uint64", method "verify_uint64_mul(uint64,uint64)uint64", method "verify_uint64_div(uint64,uint64)uint64", method "verify_uint64_mod(uint64,uint64)uint64", method "verify_uint64_and(uint64,uint64)uint64", method "verify_uint64_or(uint64,uint64)uint64", method "verify_uint64_xor(uint64,uint64)uint64", method "verify_uint64_not(uint64)uint64", method "verify_uint64_lshift(uint64,uint64)uint64", method "verify_uint64_rshift(uint64,uint64)uint64", method "verify_uint64_pow(uint64,uint64)uint64", method "verify_uint64_eq(uint64,uint64)bool", method "verify_uint64_ne(uint64,uint64)bool", method "verify_uint64_lt(uint64,uint64)bool", method "verify_uint64_le(uint64,uint64)bool", method "verify_uint64_gt(uint64,uint64)bool", method "verify_uint64_ge(uint64,uint64)bool", method "verify_bytes_init(uint64)byte[]", method "verify_bytes_add(byte[],byte[],uint64,uint64)byte[]", method "verify_bytes_eq(byte[],byte[])bool", method "verify_bytes_ne(byte[],byte[])bool", method "verify_bytes_and(byte[],byte[])byte[]", method "verify_bytes_or(byte[],byte[])byte[]", method "verify_bytes_xor(byte[],byte[])byte[]", method "verify_bytes_not(byte[],uint64)byte[]", method "verify_biguint_add(byte[],byte[])byte[]", method "verify_biguint_add_uint64(byte[],uint64)byte[]", method "verify_biguint_sub(byte[],byte[])byte[]", method "verify_biguint_sub_uint64(byte[],uint64)byte[]", method "verify_biguint_mul(byte[],byte[])byte[]", method "verify_biguint_mul_uint64(byte[],uint64)byte[]", method "verify_biguint_div(byte[],byte[])byte[]", method "verify_biguint_div_uint64(byte[],uint64)byte[]", method "verify_biguint_mod(byte[],byte[])byte[]", method "verify_biguint_mod_uint64(byte[],uint64)byte[]", method "verify_biguint_and(byte[],byte[])byte[]", method "verify_biguint_and_uint64(byte[],uint64)byte[]", method "verify_biguint_or(byte[],byte[])byte[]", method "verify_biguint_or_uint64(byte[],uint64)byte[]", method "verify_biguint_xor(byte[],byte[])byte[]", method "verify_biguint_xor_uint64(byte[],uint64)byte[]", method "verify_biguint_eq(byte[],byte[])bool", method "verify_biguint_eq_uint64(byte[],uint64)bool", method "verify_biguint_ne(byte[],byte[])bool", method "verify_biguint_ne_uint64(byte[],uint64)bool", method "verify_biguint_lt(byte[],byte[])bool", method "verify_biguint_lt_uint64(byte[],uint64)bool", method "verify_biguint_le(byte[],byte[])bool", method "verify_biguint_le_uint64(byte[],uint64)bool", method "verify_biguint_gt(byte[],byte[])bool", method "verify_biguint_gt_uint64(byte[],uint64)bool", method "verify_biguint_ge(byte[],byte[])bool", method "verify_biguint_ge_uint64(byte[],uint64)bool", method "verify_log(string,uint64,byte[],byte[],bool,string,uint64,uint256,ufixed32x8,ufixed256x16,byte[],byte[],byte[])void" - txna ApplicationArgs 0 - match __puya_arc4_router___verify_uint64_init_route@2 __puya_arc4_router___verify_uint64_add_route@3 __puya_arc4_router___verify_uint64_sub_route@4 __puya_arc4_router___verify_uint64_mul_route@5 __puya_arc4_router___verify_uint64_div_route@6 __puya_arc4_router___verify_uint64_mod_route@7 __puya_arc4_router___verify_uint64_and_route@8 __puya_arc4_router___verify_uint64_or_route@9 __puya_arc4_router___verify_uint64_xor_route@10 __puya_arc4_router___verify_uint64_not_route@11 __puya_arc4_router___verify_uint64_lshift_route@12 __puya_arc4_router___verify_uint64_rshift_route@13 __puya_arc4_router___verify_uint64_pow_route@14 __puya_arc4_router___verify_uint64_eq_route@15 __puya_arc4_router___verify_uint64_ne_route@16 __puya_arc4_router___verify_uint64_lt_route@17 __puya_arc4_router___verify_uint64_le_route@18 __puya_arc4_router___verify_uint64_gt_route@19 __puya_arc4_router___verify_uint64_ge_route@20 __puya_arc4_router___verify_bytes_init_route@21 __puya_arc4_router___verify_bytes_add_route@22 __puya_arc4_router___verify_bytes_eq_route@23 __puya_arc4_router___verify_bytes_ne_route@24 __puya_arc4_router___verify_bytes_and_route@25 __puya_arc4_router___verify_bytes_or_route@26 __puya_arc4_router___verify_bytes_xor_route@27 __puya_arc4_router___verify_bytes_not_route@28 __puya_arc4_router___verify_biguint_add_route@29 __puya_arc4_router___verify_biguint_add_uint64_route@30 __puya_arc4_router___verify_biguint_sub_route@31 __puya_arc4_router___verify_biguint_sub_uint64_route@32 __puya_arc4_router___verify_biguint_mul_route@33 __puya_arc4_router___verify_biguint_mul_uint64_route@34 __puya_arc4_router___verify_biguint_div_route@35 __puya_arc4_router___verify_biguint_div_uint64_route@36 __puya_arc4_router___verify_biguint_mod_route@37 __puya_arc4_router___verify_biguint_mod_uint64_route@38 __puya_arc4_router___verify_biguint_and_route@39 __puya_arc4_router___verify_biguint_and_uint64_route@40 __puya_arc4_router___verify_biguint_or_route@41 __puya_arc4_router___verify_biguint_or_uint64_route@42 __puya_arc4_router___verify_biguint_xor_route@43 __puya_arc4_router___verify_biguint_xor_uint64_route@44 __puya_arc4_router___verify_biguint_eq_route@45 __puya_arc4_router___verify_biguint_eq_uint64_route@46 __puya_arc4_router___verify_biguint_ne_route@47 __puya_arc4_router___verify_biguint_ne_uint64_route@48 __puya_arc4_router___verify_biguint_lt_route@49 __puya_arc4_router___verify_biguint_lt_uint64_route@50 __puya_arc4_router___verify_biguint_le_route@51 __puya_arc4_router___verify_biguint_le_uint64_route@52 __puya_arc4_router___verify_biguint_gt_route@53 __puya_arc4_router___verify_biguint_gt_uint64_route@54 __puya_arc4_router___verify_biguint_ge_route@55 __puya_arc4_router___verify_biguint_ge_uint64_route@56 __puya_arc4_router___verify_log_route@57 - intc_1 // 0 - retsub - -__puya_arc4_router___verify_uint64_init_route@2: - // tests/artifacts/primitive-ops/contract.algo.ts:5 - // @arc4.abimethod() - txn OnCompletion - ! - assert // OnCompletion is not NoOp - txn ApplicationID - assert // can only call when not creating - // tests/artifacts/primitive-ops/contract.algo.ts:4 - // export class PrimitiveOpsContract extends arc4.Contract { - txna ApplicationArgs 1 - extract 2 0 - // tests/artifacts/primitive-ops/contract.algo.ts:5 - // @arc4.abimethod() - callsub verify_uint64_init - itob - bytec_0 // 0x151f7c75 - swap - concat - log - intc_0 // 1 - retsub - -__puya_arc4_router___verify_uint64_add_route@3: - // tests/artifacts/primitive-ops/contract.algo.ts:11 - // @arc4.abimethod() - txn OnCompletion - ! - assert // OnCompletion is not NoOp - txn ApplicationID - assert // can only call when not creating - // tests/artifacts/primitive-ops/contract.algo.ts:4 - // export class PrimitiveOpsContract extends arc4.Contract { - txna ApplicationArgs 1 - btoi - txna ApplicationArgs 2 - btoi - // tests/artifacts/primitive-ops/contract.algo.ts:11 - // @arc4.abimethod() - callsub verify_uint64_add - itob - bytec_0 // 0x151f7c75 - swap - concat - log - intc_0 // 1 - retsub - -__puya_arc4_router___verify_uint64_sub_route@4: - // tests/artifacts/primitive-ops/contract.algo.ts:17 - // @arc4.abimethod() - txn OnCompletion - ! - assert // OnCompletion is not NoOp - txn ApplicationID - assert // can only call when not creating - // tests/artifacts/primitive-ops/contract.algo.ts:4 - // export class PrimitiveOpsContract extends arc4.Contract { - txna ApplicationArgs 1 - btoi - txna ApplicationArgs 2 - btoi - // tests/artifacts/primitive-ops/contract.algo.ts:17 - // @arc4.abimethod() - callsub verify_uint64_sub - itob - bytec_0 // 0x151f7c75 - swap - concat - log - intc_0 // 1 - retsub - -__puya_arc4_router___verify_uint64_mul_route@5: - // tests/artifacts/primitive-ops/contract.algo.ts:23 - // @arc4.abimethod() - txn OnCompletion - ! - assert // OnCompletion is not NoOp - txn ApplicationID - assert // can only call when not creating - // tests/artifacts/primitive-ops/contract.algo.ts:4 - // export class PrimitiveOpsContract extends arc4.Contract { - txna ApplicationArgs 1 - btoi - txna ApplicationArgs 2 - btoi - // tests/artifacts/primitive-ops/contract.algo.ts:23 - // @arc4.abimethod() - callsub verify_uint64_mul - itob - bytec_0 // 0x151f7c75 - swap - concat - log - intc_0 // 1 - retsub - -__puya_arc4_router___verify_uint64_div_route@6: - // tests/artifacts/primitive-ops/contract.algo.ts:29 - // @arc4.abimethod() - txn OnCompletion - ! - assert // OnCompletion is not NoOp - txn ApplicationID - assert // can only call when not creating - // tests/artifacts/primitive-ops/contract.algo.ts:4 - // export class PrimitiveOpsContract extends arc4.Contract { - txna ApplicationArgs 1 - btoi - txna ApplicationArgs 2 - btoi - // tests/artifacts/primitive-ops/contract.algo.ts:29 - // @arc4.abimethod() - callsub verify_uint64_div - itob - bytec_0 // 0x151f7c75 - swap - concat - log - intc_0 // 1 - retsub - -__puya_arc4_router___verify_uint64_mod_route@7: - // tests/artifacts/primitive-ops/contract.algo.ts:35 - // @arc4.abimethod() - txn OnCompletion - ! - assert // OnCompletion is not NoOp - txn ApplicationID - assert // can only call when not creating - // tests/artifacts/primitive-ops/contract.algo.ts:4 - // export class PrimitiveOpsContract extends arc4.Contract { - txna ApplicationArgs 1 - btoi - txna ApplicationArgs 2 - btoi - // tests/artifacts/primitive-ops/contract.algo.ts:35 - // @arc4.abimethod() - callsub verify_uint64_mod - itob - bytec_0 // 0x151f7c75 - swap - concat - log - intc_0 // 1 - retsub - -__puya_arc4_router___verify_uint64_and_route@8: - // tests/artifacts/primitive-ops/contract.algo.ts:41 - // @arc4.abimethod() - txn OnCompletion - ! - assert // OnCompletion is not NoOp - txn ApplicationID - assert // can only call when not creating - // tests/artifacts/primitive-ops/contract.algo.ts:4 - // export class PrimitiveOpsContract extends arc4.Contract { - txna ApplicationArgs 1 - btoi - txna ApplicationArgs 2 - btoi - // tests/artifacts/primitive-ops/contract.algo.ts:41 - // @arc4.abimethod() - callsub verify_uint64_and - itob - bytec_0 // 0x151f7c75 - swap - concat - log - intc_0 // 1 - retsub - -__puya_arc4_router___verify_uint64_or_route@9: - // tests/artifacts/primitive-ops/contract.algo.ts:47 - // @arc4.abimethod() - txn OnCompletion - ! - assert // OnCompletion is not NoOp - txn ApplicationID - assert // can only call when not creating - // tests/artifacts/primitive-ops/contract.algo.ts:4 - // export class PrimitiveOpsContract extends arc4.Contract { - txna ApplicationArgs 1 - btoi - txna ApplicationArgs 2 - btoi - // tests/artifacts/primitive-ops/contract.algo.ts:47 - // @arc4.abimethod() - callsub verify_uint64_or - itob - bytec_0 // 0x151f7c75 - swap - concat - log - intc_0 // 1 - retsub - -__puya_arc4_router___verify_uint64_xor_route@10: - // tests/artifacts/primitive-ops/contract.algo.ts:53 - // @arc4.abimethod() - txn OnCompletion - ! - assert // OnCompletion is not NoOp - txn ApplicationID - assert // can only call when not creating - // tests/artifacts/primitive-ops/contract.algo.ts:4 - // export class PrimitiveOpsContract extends arc4.Contract { - txna ApplicationArgs 1 - btoi - txna ApplicationArgs 2 - btoi - // tests/artifacts/primitive-ops/contract.algo.ts:53 - // @arc4.abimethod() - callsub verify_uint64_xor - itob - bytec_0 // 0x151f7c75 - swap - concat - log - intc_0 // 1 - retsub - -__puya_arc4_router___verify_uint64_not_route@11: - // tests/artifacts/primitive-ops/contract.algo.ts:59 - // @arc4.abimethod() - txn OnCompletion - ! - assert // OnCompletion is not NoOp - txn ApplicationID - assert // can only call when not creating - // tests/artifacts/primitive-ops/contract.algo.ts:4 - // export class PrimitiveOpsContract extends arc4.Contract { - txna ApplicationArgs 1 - btoi - // tests/artifacts/primitive-ops/contract.algo.ts:59 - // @arc4.abimethod() - callsub verify_uint64_not - itob - bytec_0 // 0x151f7c75 - swap - concat - log - intc_0 // 1 - retsub - -__puya_arc4_router___verify_uint64_lshift_route@12: - // tests/artifacts/primitive-ops/contract.algo.ts:65 - // @arc4.abimethod() - txn OnCompletion - ! - assert // OnCompletion is not NoOp - txn ApplicationID - assert // can only call when not creating - // tests/artifacts/primitive-ops/contract.algo.ts:4 - // export class PrimitiveOpsContract extends arc4.Contract { - txna ApplicationArgs 1 - btoi - txna ApplicationArgs 2 - btoi - // tests/artifacts/primitive-ops/contract.algo.ts:65 - // @arc4.abimethod() - callsub verify_uint64_lshift - itob - bytec_0 // 0x151f7c75 - swap - concat - log - intc_0 // 1 - retsub - -__puya_arc4_router___verify_uint64_rshift_route@13: - // tests/artifacts/primitive-ops/contract.algo.ts:71 - // @arc4.abimethod() - txn OnCompletion - ! - assert // OnCompletion is not NoOp - txn ApplicationID - assert // can only call when not creating - // tests/artifacts/primitive-ops/contract.algo.ts:4 - // export class PrimitiveOpsContract extends arc4.Contract { - txna ApplicationArgs 1 - btoi - txna ApplicationArgs 2 - btoi - // tests/artifacts/primitive-ops/contract.algo.ts:71 - // @arc4.abimethod() - callsub verify_uint64_rshift - itob - bytec_0 // 0x151f7c75 - swap - concat - log - intc_0 // 1 - retsub - -__puya_arc4_router___verify_uint64_pow_route@14: - // tests/artifacts/primitive-ops/contract.algo.ts:77 - // @arc4.abimethod() - txn OnCompletion - ! - assert // OnCompletion is not NoOp - txn ApplicationID - assert // can only call when not creating - // tests/artifacts/primitive-ops/contract.algo.ts:4 - // export class PrimitiveOpsContract extends arc4.Contract { - txna ApplicationArgs 1 - btoi - txna ApplicationArgs 2 - btoi - // tests/artifacts/primitive-ops/contract.algo.ts:77 - // @arc4.abimethod() - callsub verify_uint64_pow - itob - bytec_0 // 0x151f7c75 - swap - concat - log - intc_0 // 1 - retsub - -__puya_arc4_router___verify_uint64_eq_route@15: - // tests/artifacts/primitive-ops/contract.algo.ts:83 - // @arc4.abimethod() - txn OnCompletion - ! - assert // OnCompletion is not NoOp - txn ApplicationID - assert // can only call when not creating - // tests/artifacts/primitive-ops/contract.algo.ts:4 - // export class PrimitiveOpsContract extends arc4.Contract { - txna ApplicationArgs 1 - btoi - txna ApplicationArgs 2 - btoi - // tests/artifacts/primitive-ops/contract.algo.ts:83 - // @arc4.abimethod() - callsub verify_uint64_eq - bytec_1 // 0x00 - intc_1 // 0 - uncover 2 - setbit - bytec_0 // 0x151f7c75 - swap - concat - log - intc_0 // 1 - retsub - -__puya_arc4_router___verify_uint64_ne_route@16: - // tests/artifacts/primitive-ops/contract.algo.ts:89 - // @arc4.abimethod() - txn OnCompletion - ! - assert // OnCompletion is not NoOp - txn ApplicationID - assert // can only call when not creating - // tests/artifacts/primitive-ops/contract.algo.ts:4 - // export class PrimitiveOpsContract extends arc4.Contract { - txna ApplicationArgs 1 - btoi - txna ApplicationArgs 2 - btoi - // tests/artifacts/primitive-ops/contract.algo.ts:89 - // @arc4.abimethod() - callsub verify_uint64_ne - bytec_1 // 0x00 - intc_1 // 0 - uncover 2 - setbit - bytec_0 // 0x151f7c75 - swap - concat - log - intc_0 // 1 - retsub - -__puya_arc4_router___verify_uint64_lt_route@17: - // tests/artifacts/primitive-ops/contract.algo.ts:95 - // @arc4.abimethod() - txn OnCompletion - ! - assert // OnCompletion is not NoOp - txn ApplicationID - assert // can only call when not creating - // tests/artifacts/primitive-ops/contract.algo.ts:4 - // export class PrimitiveOpsContract extends arc4.Contract { - txna ApplicationArgs 1 - btoi - txna ApplicationArgs 2 - btoi - // tests/artifacts/primitive-ops/contract.algo.ts:95 - // @arc4.abimethod() - callsub verify_uint64_lt - bytec_1 // 0x00 - intc_1 // 0 - uncover 2 - setbit - bytec_0 // 0x151f7c75 - swap - concat - log - intc_0 // 1 - retsub - -__puya_arc4_router___verify_uint64_le_route@18: - // tests/artifacts/primitive-ops/contract.algo.ts:101 - // @arc4.abimethod() - txn OnCompletion - ! - assert // OnCompletion is not NoOp - txn ApplicationID - assert // can only call when not creating - // tests/artifacts/primitive-ops/contract.algo.ts:4 - // export class PrimitiveOpsContract extends arc4.Contract { - txna ApplicationArgs 1 - btoi - txna ApplicationArgs 2 - btoi - // tests/artifacts/primitive-ops/contract.algo.ts:101 - // @arc4.abimethod() - callsub verify_uint64_le - bytec_1 // 0x00 - intc_1 // 0 - uncover 2 - setbit - bytec_0 // 0x151f7c75 - swap - concat - log - intc_0 // 1 - retsub - -__puya_arc4_router___verify_uint64_gt_route@19: - // tests/artifacts/primitive-ops/contract.algo.ts:107 - // @arc4.abimethod() - txn OnCompletion - ! - assert // OnCompletion is not NoOp - txn ApplicationID - assert // can only call when not creating - // tests/artifacts/primitive-ops/contract.algo.ts:4 - // export class PrimitiveOpsContract extends arc4.Contract { - txna ApplicationArgs 1 - btoi - txna ApplicationArgs 2 - btoi - // tests/artifacts/primitive-ops/contract.algo.ts:107 - // @arc4.abimethod() - callsub verify_uint64_gt - bytec_1 // 0x00 - intc_1 // 0 - uncover 2 - setbit - bytec_0 // 0x151f7c75 - swap - concat - log - intc_0 // 1 - retsub - -__puya_arc4_router___verify_uint64_ge_route@20: - // tests/artifacts/primitive-ops/contract.algo.ts:113 - // @arc4.abimethod() - txn OnCompletion - ! - assert // OnCompletion is not NoOp - txn ApplicationID - assert // can only call when not creating - // tests/artifacts/primitive-ops/contract.algo.ts:4 - // export class PrimitiveOpsContract extends arc4.Contract { - txna ApplicationArgs 1 - btoi - txna ApplicationArgs 2 - btoi - // tests/artifacts/primitive-ops/contract.algo.ts:113 - // @arc4.abimethod() - callsub verify_uint64_ge - bytec_1 // 0x00 - intc_1 // 0 - uncover 2 - setbit - bytec_0 // 0x151f7c75 - swap - concat - log - intc_0 // 1 - retsub - -__puya_arc4_router___verify_bytes_init_route@21: - // tests/artifacts/primitive-ops/contract.algo.ts:119 - // @arc4.abimethod() - txn OnCompletion - ! - assert // OnCompletion is not NoOp - txn ApplicationID - assert // can only call when not creating - // tests/artifacts/primitive-ops/contract.algo.ts:4 - // export class PrimitiveOpsContract extends arc4.Contract { - txna ApplicationArgs 1 - btoi - // tests/artifacts/primitive-ops/contract.algo.ts:119 - // @arc4.abimethod() - callsub verify_bytes_init - dup - len - itob - extract 6 2 - swap - concat - bytec_0 // 0x151f7c75 - swap - concat - log - intc_0 // 1 - retsub - -__puya_arc4_router___verify_bytes_add_route@22: - // tests/artifacts/primitive-ops/contract.algo.ts:125 - // @arc4.abimethod() - txn OnCompletion - ! - assert // OnCompletion is not NoOp - txn ApplicationID - assert // can only call when not creating - // tests/artifacts/primitive-ops/contract.algo.ts:4 - // export class PrimitiveOpsContract extends arc4.Contract { - txna ApplicationArgs 1 - extract 2 0 - txna ApplicationArgs 2 - extract 2 0 - txna ApplicationArgs 3 - btoi - txna ApplicationArgs 4 - btoi - // tests/artifacts/primitive-ops/contract.algo.ts:125 - // @arc4.abimethod() - callsub verify_bytes_add - dup - len - itob - extract 6 2 - swap - concat - bytec_0 // 0x151f7c75 - swap - concat - log - intc_0 // 1 - retsub - -__puya_arc4_router___verify_bytes_eq_route@23: - // tests/artifacts/primitive-ops/contract.algo.ts:134 - // @arc4.abimethod() - txn OnCompletion - ! - assert // OnCompletion is not NoOp - txn ApplicationID - assert // can only call when not creating - // tests/artifacts/primitive-ops/contract.algo.ts:4 - // export class PrimitiveOpsContract extends arc4.Contract { - txna ApplicationArgs 1 - extract 2 0 - txna ApplicationArgs 2 - extract 2 0 - // tests/artifacts/primitive-ops/contract.algo.ts:134 - // @arc4.abimethod() - callsub verify_bytes_eq - bytec_1 // 0x00 - intc_1 // 0 - uncover 2 - setbit - bytec_0 // 0x151f7c75 - swap - concat - log - intc_0 // 1 - retsub - -__puya_arc4_router___verify_bytes_ne_route@24: - // tests/artifacts/primitive-ops/contract.algo.ts:140 - // @arc4.abimethod() - txn OnCompletion - ! - assert // OnCompletion is not NoOp - txn ApplicationID - assert // can only call when not creating - // tests/artifacts/primitive-ops/contract.algo.ts:4 - // export class PrimitiveOpsContract extends arc4.Contract { - txna ApplicationArgs 1 - extract 2 0 - txna ApplicationArgs 2 - extract 2 0 - // tests/artifacts/primitive-ops/contract.algo.ts:140 - // @arc4.abimethod() - callsub verify_bytes_ne - bytec_1 // 0x00 - intc_1 // 0 - uncover 2 - setbit - bytec_0 // 0x151f7c75 - swap - concat - log - intc_0 // 1 - retsub - -__puya_arc4_router___verify_bytes_and_route@25: - // tests/artifacts/primitive-ops/contract.algo.ts:146 - // @arc4.abimethod() - txn OnCompletion - ! - assert // OnCompletion is not NoOp - txn ApplicationID - assert // can only call when not creating - // tests/artifacts/primitive-ops/contract.algo.ts:4 - // export class PrimitiveOpsContract extends arc4.Contract { - txna ApplicationArgs 1 - extract 2 0 - txna ApplicationArgs 2 - extract 2 0 - // tests/artifacts/primitive-ops/contract.algo.ts:146 - // @arc4.abimethod() - callsub verify_bytes_and - dup - len - itob - extract 6 2 - swap - concat - bytec_0 // 0x151f7c75 - swap - concat - log - intc_0 // 1 - retsub - -__puya_arc4_router___verify_bytes_or_route@26: - // tests/artifacts/primitive-ops/contract.algo.ts:152 - // @arc4.abimethod() - txn OnCompletion - ! - assert // OnCompletion is not NoOp - txn ApplicationID - assert // can only call when not creating - // tests/artifacts/primitive-ops/contract.algo.ts:4 - // export class PrimitiveOpsContract extends arc4.Contract { - txna ApplicationArgs 1 - extract 2 0 - txna ApplicationArgs 2 - extract 2 0 - // tests/artifacts/primitive-ops/contract.algo.ts:152 - // @arc4.abimethod() - callsub verify_bytes_or - dup - len - itob - extract 6 2 - swap - concat - bytec_0 // 0x151f7c75 - swap - concat - log - intc_0 // 1 - retsub - -__puya_arc4_router___verify_bytes_xor_route@27: - // tests/artifacts/primitive-ops/contract.algo.ts:158 - // @arc4.abimethod() - txn OnCompletion - ! - assert // OnCompletion is not NoOp - txn ApplicationID - assert // can only call when not creating - // tests/artifacts/primitive-ops/contract.algo.ts:4 - // export class PrimitiveOpsContract extends arc4.Contract { - txna ApplicationArgs 1 - extract 2 0 - txna ApplicationArgs 2 - extract 2 0 - // tests/artifacts/primitive-ops/contract.algo.ts:158 - // @arc4.abimethod() - callsub verify_bytes_xor - dup - len - itob - extract 6 2 - swap - concat - bytec_0 // 0x151f7c75 - swap - concat - log - intc_0 // 1 - retsub - -__puya_arc4_router___verify_bytes_not_route@28: - // tests/artifacts/primitive-ops/contract.algo.ts:164 - // @arc4.abimethod() - txn OnCompletion - ! - assert // OnCompletion is not NoOp - txn ApplicationID - assert // can only call when not creating - // tests/artifacts/primitive-ops/contract.algo.ts:4 - // export class PrimitiveOpsContract extends arc4.Contract { - txna ApplicationArgs 1 - extract 2 0 - txna ApplicationArgs 2 - btoi - // tests/artifacts/primitive-ops/contract.algo.ts:164 - // @arc4.abimethod() - callsub verify_bytes_not - dup - len - itob - extract 6 2 - swap - concat - bytec_0 // 0x151f7c75 - swap - concat - log - intc_0 // 1 - retsub - -__puya_arc4_router___verify_biguint_add_route@29: - // tests/artifacts/primitive-ops/contract.algo.ts:172 - // @arc4.abimethod() - txn OnCompletion - ! - assert // OnCompletion is not NoOp - txn ApplicationID - assert // can only call when not creating - // tests/artifacts/primitive-ops/contract.algo.ts:4 - // export class PrimitiveOpsContract extends arc4.Contract { - txna ApplicationArgs 1 - extract 2 0 - txna ApplicationArgs 2 - extract 2 0 - // tests/artifacts/primitive-ops/contract.algo.ts:172 - // @arc4.abimethod() - callsub verify_biguint_add - dup - len - itob - extract 6 2 - swap - concat - bytec_0 // 0x151f7c75 - swap - concat - log - intc_0 // 1 - retsub - -__puya_arc4_router___verify_biguint_add_uint64_route@30: - // tests/artifacts/primitive-ops/contract.algo.ts:180 - // @arc4.abimethod() - txn OnCompletion - ! - assert // OnCompletion is not NoOp - txn ApplicationID - assert // can only call when not creating - // tests/artifacts/primitive-ops/contract.algo.ts:4 - // export class PrimitiveOpsContract extends arc4.Contract { - txna ApplicationArgs 1 - extract 2 0 - txna ApplicationArgs 2 - btoi - // tests/artifacts/primitive-ops/contract.algo.ts:180 - // @arc4.abimethod() - callsub verify_biguint_add_uint64 - dup - len - itob - extract 6 2 - swap - concat - bytec_0 // 0x151f7c75 - swap - concat - log - intc_0 // 1 - retsub - -__puya_arc4_router___verify_biguint_sub_route@31: - // tests/artifacts/primitive-ops/contract.algo.ts:188 - // @arc4.abimethod() - txn OnCompletion - ! - assert // OnCompletion is not NoOp - txn ApplicationID - assert // can only call when not creating - // tests/artifacts/primitive-ops/contract.algo.ts:4 - // export class PrimitiveOpsContract extends arc4.Contract { - txna ApplicationArgs 1 - extract 2 0 - txna ApplicationArgs 2 - extract 2 0 - // tests/artifacts/primitive-ops/contract.algo.ts:188 - // @arc4.abimethod() - callsub verify_biguint_sub - dup - len - itob - extract 6 2 - swap - concat - bytec_0 // 0x151f7c75 - swap - concat - log - intc_0 // 1 - retsub - -__puya_arc4_router___verify_biguint_sub_uint64_route@32: - // tests/artifacts/primitive-ops/contract.algo.ts:196 - // @arc4.abimethod() - txn OnCompletion - ! - assert // OnCompletion is not NoOp - txn ApplicationID - assert // can only call when not creating - // tests/artifacts/primitive-ops/contract.algo.ts:4 - // export class PrimitiveOpsContract extends arc4.Contract { - txna ApplicationArgs 1 - extract 2 0 - txna ApplicationArgs 2 - btoi - // tests/artifacts/primitive-ops/contract.algo.ts:196 - // @arc4.abimethod() - callsub verify_biguint_sub_uint64 - dup - len - itob - extract 6 2 - swap - concat - bytec_0 // 0x151f7c75 - swap - concat - log - intc_0 // 1 - retsub - -__puya_arc4_router___verify_biguint_mul_route@33: - // tests/artifacts/primitive-ops/contract.algo.ts:204 - // @arc4.abimethod() - txn OnCompletion - ! - assert // OnCompletion is not NoOp - txn ApplicationID - assert // can only call when not creating - // tests/artifacts/primitive-ops/contract.algo.ts:4 - // export class PrimitiveOpsContract extends arc4.Contract { - txna ApplicationArgs 1 - extract 2 0 - txna ApplicationArgs 2 - extract 2 0 - // tests/artifacts/primitive-ops/contract.algo.ts:204 - // @arc4.abimethod() - callsub verify_biguint_mul - dup - len - itob - extract 6 2 - swap - concat - bytec_0 // 0x151f7c75 - swap - concat - log - intc_0 // 1 - retsub - -__puya_arc4_router___verify_biguint_mul_uint64_route@34: - // tests/artifacts/primitive-ops/contract.algo.ts:212 - // @arc4.abimethod() - txn OnCompletion - ! - assert // OnCompletion is not NoOp - txn ApplicationID - assert // can only call when not creating - // tests/artifacts/primitive-ops/contract.algo.ts:4 - // export class PrimitiveOpsContract extends arc4.Contract { - txna ApplicationArgs 1 - extract 2 0 - txna ApplicationArgs 2 - btoi - // tests/artifacts/primitive-ops/contract.algo.ts:212 - // @arc4.abimethod() - callsub verify_biguint_mul_uint64 - dup - len - itob - extract 6 2 - swap - concat - bytec_0 // 0x151f7c75 - swap - concat - log - intc_0 // 1 - retsub - -__puya_arc4_router___verify_biguint_div_route@35: - // tests/artifacts/primitive-ops/contract.algo.ts:220 - // @arc4.abimethod() - txn OnCompletion - ! - assert // OnCompletion is not NoOp - txn ApplicationID - assert // can only call when not creating - // tests/artifacts/primitive-ops/contract.algo.ts:4 - // export class PrimitiveOpsContract extends arc4.Contract { - txna ApplicationArgs 1 - extract 2 0 - txna ApplicationArgs 2 - extract 2 0 - // tests/artifacts/primitive-ops/contract.algo.ts:220 - // @arc4.abimethod() - callsub verify_biguint_div - dup - len - itob - extract 6 2 - swap - concat - bytec_0 // 0x151f7c75 - swap - concat - log - intc_0 // 1 - retsub - -__puya_arc4_router___verify_biguint_div_uint64_route@36: - // tests/artifacts/primitive-ops/contract.algo.ts:228 - // @arc4.abimethod() - txn OnCompletion - ! - assert // OnCompletion is not NoOp - txn ApplicationID - assert // can only call when not creating - // tests/artifacts/primitive-ops/contract.algo.ts:4 - // export class PrimitiveOpsContract extends arc4.Contract { - txna ApplicationArgs 1 - extract 2 0 - txna ApplicationArgs 2 - btoi - // tests/artifacts/primitive-ops/contract.algo.ts:228 - // @arc4.abimethod() - callsub verify_biguint_div_uint64 - dup - len - itob - extract 6 2 - swap - concat - bytec_0 // 0x151f7c75 - swap - concat - log - intc_0 // 1 - retsub - -__puya_arc4_router___verify_biguint_mod_route@37: - // tests/artifacts/primitive-ops/contract.algo.ts:236 - // @arc4.abimethod() - txn OnCompletion - ! - assert // OnCompletion is not NoOp - txn ApplicationID - assert // can only call when not creating - // tests/artifacts/primitive-ops/contract.algo.ts:4 - // export class PrimitiveOpsContract extends arc4.Contract { - txna ApplicationArgs 1 - extract 2 0 - txna ApplicationArgs 2 - extract 2 0 - // tests/artifacts/primitive-ops/contract.algo.ts:236 - // @arc4.abimethod() - callsub verify_biguint_mod - dup - len - itob - extract 6 2 - swap - concat - bytec_0 // 0x151f7c75 - swap - concat - log - intc_0 // 1 - retsub - -__puya_arc4_router___verify_biguint_mod_uint64_route@38: - // tests/artifacts/primitive-ops/contract.algo.ts:244 - // @arc4.abimethod() - txn OnCompletion - ! - assert // OnCompletion is not NoOp - txn ApplicationID - assert // can only call when not creating - // tests/artifacts/primitive-ops/contract.algo.ts:4 - // export class PrimitiveOpsContract extends arc4.Contract { - txna ApplicationArgs 1 - extract 2 0 - txna ApplicationArgs 2 - btoi - // tests/artifacts/primitive-ops/contract.algo.ts:244 - // @arc4.abimethod() - callsub verify_biguint_mod_uint64 - dup - len - itob - extract 6 2 - swap - concat - bytec_0 // 0x151f7c75 - swap - concat - log - intc_0 // 1 - retsub - -__puya_arc4_router___verify_biguint_and_route@39: - // tests/artifacts/primitive-ops/contract.algo.ts:252 - // @arc4.abimethod() - txn OnCompletion - ! - assert // OnCompletion is not NoOp - txn ApplicationID - assert // can only call when not creating - // tests/artifacts/primitive-ops/contract.algo.ts:4 - // export class PrimitiveOpsContract extends arc4.Contract { - txna ApplicationArgs 1 - extract 2 0 - txna ApplicationArgs 2 - extract 2 0 - // tests/artifacts/primitive-ops/contract.algo.ts:252 - // @arc4.abimethod() - callsub verify_biguint_and - dup - len - itob - extract 6 2 - swap - concat - bytec_0 // 0x151f7c75 - swap - concat - log - intc_0 // 1 - retsub - -__puya_arc4_router___verify_biguint_and_uint64_route@40: - // tests/artifacts/primitive-ops/contract.algo.ts:260 - // @arc4.abimethod() - txn OnCompletion - ! - assert // OnCompletion is not NoOp - txn ApplicationID - assert // can only call when not creating - // tests/artifacts/primitive-ops/contract.algo.ts:4 - // export class PrimitiveOpsContract extends arc4.Contract { - txna ApplicationArgs 1 - extract 2 0 - txna ApplicationArgs 2 - btoi - // tests/artifacts/primitive-ops/contract.algo.ts:260 - // @arc4.abimethod() - callsub verify_biguint_and_uint64 - dup - len - itob - extract 6 2 - swap - concat - bytec_0 // 0x151f7c75 - swap - concat - log - intc_0 // 1 - retsub - -__puya_arc4_router___verify_biguint_or_route@41: - // tests/artifacts/primitive-ops/contract.algo.ts:268 - // @arc4.abimethod() - txn OnCompletion - ! - assert // OnCompletion is not NoOp - txn ApplicationID - assert // can only call when not creating - // tests/artifacts/primitive-ops/contract.algo.ts:4 - // export class PrimitiveOpsContract extends arc4.Contract { - txna ApplicationArgs 1 - extract 2 0 - txna ApplicationArgs 2 - extract 2 0 - // tests/artifacts/primitive-ops/contract.algo.ts:268 - // @arc4.abimethod() - callsub verify_biguint_or - dup - len - itob - extract 6 2 - swap - concat - bytec_0 // 0x151f7c75 - swap - concat - log - intc_0 // 1 - retsub - -__puya_arc4_router___verify_biguint_or_uint64_route@42: - // tests/artifacts/primitive-ops/contract.algo.ts:276 - // @arc4.abimethod() - txn OnCompletion - ! - assert // OnCompletion is not NoOp - txn ApplicationID - assert // can only call when not creating - // tests/artifacts/primitive-ops/contract.algo.ts:4 - // export class PrimitiveOpsContract extends arc4.Contract { - txna ApplicationArgs 1 - extract 2 0 - txna ApplicationArgs 2 - btoi - // tests/artifacts/primitive-ops/contract.algo.ts:276 - // @arc4.abimethod() - callsub verify_biguint_or_uint64 - dup - len - itob - extract 6 2 - swap - concat - bytec_0 // 0x151f7c75 - swap - concat - log - intc_0 // 1 - retsub - -__puya_arc4_router___verify_biguint_xor_route@43: - // tests/artifacts/primitive-ops/contract.algo.ts:284 - // @arc4.abimethod() - txn OnCompletion - ! - assert // OnCompletion is not NoOp - txn ApplicationID - assert // can only call when not creating - // tests/artifacts/primitive-ops/contract.algo.ts:4 - // export class PrimitiveOpsContract extends arc4.Contract { - txna ApplicationArgs 1 - extract 2 0 - txna ApplicationArgs 2 - extract 2 0 - // tests/artifacts/primitive-ops/contract.algo.ts:284 - // @arc4.abimethod() - callsub verify_biguint_xor - dup - len - itob - extract 6 2 - swap - concat - bytec_0 // 0x151f7c75 - swap - concat - log - intc_0 // 1 - retsub - -__puya_arc4_router___verify_biguint_xor_uint64_route@44: - // tests/artifacts/primitive-ops/contract.algo.ts:292 - // @arc4.abimethod() - txn OnCompletion - ! - assert // OnCompletion is not NoOp - txn ApplicationID - assert // can only call when not creating - // tests/artifacts/primitive-ops/contract.algo.ts:4 - // export class PrimitiveOpsContract extends arc4.Contract { - txna ApplicationArgs 1 - extract 2 0 - txna ApplicationArgs 2 - btoi - // tests/artifacts/primitive-ops/contract.algo.ts:292 - // @arc4.abimethod() - callsub verify_biguint_xor_uint64 - dup - len - itob - extract 6 2 - swap - concat - bytec_0 // 0x151f7c75 - swap - concat - log - intc_0 // 1 - retsub - -__puya_arc4_router___verify_biguint_eq_route@45: - // tests/artifacts/primitive-ops/contract.algo.ts:300 - // @arc4.abimethod() - txn OnCompletion - ! - assert // OnCompletion is not NoOp - txn ApplicationID - assert // can only call when not creating - // tests/artifacts/primitive-ops/contract.algo.ts:4 - // export class PrimitiveOpsContract extends arc4.Contract { - txna ApplicationArgs 1 - extract 2 0 - txna ApplicationArgs 2 - extract 2 0 - // tests/artifacts/primitive-ops/contract.algo.ts:300 - // @arc4.abimethod() - callsub verify_biguint_eq - bytec_1 // 0x00 - intc_1 // 0 - uncover 2 - setbit - bytec_0 // 0x151f7c75 - swap - concat - log - intc_0 // 1 - retsub - -__puya_arc4_router___verify_biguint_eq_uint64_route@46: - // tests/artifacts/primitive-ops/contract.algo.ts:308 - // @arc4.abimethod() - txn OnCompletion - ! - assert // OnCompletion is not NoOp - txn ApplicationID - assert // can only call when not creating - // tests/artifacts/primitive-ops/contract.algo.ts:4 - // export class PrimitiveOpsContract extends arc4.Contract { - txna ApplicationArgs 1 - extract 2 0 - txna ApplicationArgs 2 - btoi - // tests/artifacts/primitive-ops/contract.algo.ts:308 - // @arc4.abimethod() - callsub verify_biguint_eq_uint64 - bytec_1 // 0x00 - intc_1 // 0 - uncover 2 - setbit - bytec_0 // 0x151f7c75 - swap - concat - log - intc_0 // 1 - retsub - -__puya_arc4_router___verify_biguint_ne_route@47: - // tests/artifacts/primitive-ops/contract.algo.ts:315 - // @arc4.abimethod() - txn OnCompletion - ! - assert // OnCompletion is not NoOp - txn ApplicationID - assert // can only call when not creating - // tests/artifacts/primitive-ops/contract.algo.ts:4 - // export class PrimitiveOpsContract extends arc4.Contract { - txna ApplicationArgs 1 - extract 2 0 - txna ApplicationArgs 2 - extract 2 0 - // tests/artifacts/primitive-ops/contract.algo.ts:315 - // @arc4.abimethod() - callsub verify_biguint_ne - bytec_1 // 0x00 - intc_1 // 0 - uncover 2 - setbit - bytec_0 // 0x151f7c75 - swap - concat - log - intc_0 // 1 - retsub - -__puya_arc4_router___verify_biguint_ne_uint64_route@48: - // tests/artifacts/primitive-ops/contract.algo.ts:323 - // @arc4.abimethod() - txn OnCompletion - ! - assert // OnCompletion is not NoOp - txn ApplicationID - assert // can only call when not creating - // tests/artifacts/primitive-ops/contract.algo.ts:4 - // export class PrimitiveOpsContract extends arc4.Contract { - txna ApplicationArgs 1 - extract 2 0 - txna ApplicationArgs 2 - btoi - // tests/artifacts/primitive-ops/contract.algo.ts:323 - // @arc4.abimethod() - callsub verify_biguint_ne_uint64 - bytec_1 // 0x00 - intc_1 // 0 - uncover 2 - setbit - bytec_0 // 0x151f7c75 - swap - concat - log - intc_0 // 1 - retsub - -__puya_arc4_router___verify_biguint_lt_route@49: - // tests/artifacts/primitive-ops/contract.algo.ts:330 - // @arc4.abimethod() - txn OnCompletion - ! - assert // OnCompletion is not NoOp - txn ApplicationID - assert // can only call when not creating - // tests/artifacts/primitive-ops/contract.algo.ts:4 - // export class PrimitiveOpsContract extends arc4.Contract { - txna ApplicationArgs 1 - extract 2 0 - txna ApplicationArgs 2 - extract 2 0 - // tests/artifacts/primitive-ops/contract.algo.ts:330 - // @arc4.abimethod() - callsub verify_biguint_lt - bytec_1 // 0x00 - intc_1 // 0 - uncover 2 - setbit - bytec_0 // 0x151f7c75 - swap - concat - log - intc_0 // 1 - retsub - -__puya_arc4_router___verify_biguint_lt_uint64_route@50: - // tests/artifacts/primitive-ops/contract.algo.ts:338 - // @arc4.abimethod() - txn OnCompletion - ! - assert // OnCompletion is not NoOp - txn ApplicationID - assert // can only call when not creating - // tests/artifacts/primitive-ops/contract.algo.ts:4 - // export class PrimitiveOpsContract extends arc4.Contract { - txna ApplicationArgs 1 - extract 2 0 - txna ApplicationArgs 2 - btoi - // tests/artifacts/primitive-ops/contract.algo.ts:338 - // @arc4.abimethod() - callsub verify_biguint_lt_uint64 - bytec_1 // 0x00 - intc_1 // 0 - uncover 2 - setbit - bytec_0 // 0x151f7c75 - swap - concat - log - intc_0 // 1 - retsub - -__puya_arc4_router___verify_biguint_le_route@51: - // tests/artifacts/primitive-ops/contract.algo.ts:346 - // @arc4.abimethod() - txn OnCompletion - ! - assert // OnCompletion is not NoOp - txn ApplicationID - assert // can only call when not creating - // tests/artifacts/primitive-ops/contract.algo.ts:4 - // export class PrimitiveOpsContract extends arc4.Contract { - txna ApplicationArgs 1 - extract 2 0 - txna ApplicationArgs 2 - extract 2 0 - // tests/artifacts/primitive-ops/contract.algo.ts:346 - // @arc4.abimethod() - callsub verify_biguint_le - bytec_1 // 0x00 - intc_1 // 0 - uncover 2 - setbit - bytec_0 // 0x151f7c75 - swap - concat - log - intc_0 // 1 - retsub - -__puya_arc4_router___verify_biguint_le_uint64_route@52: - // tests/artifacts/primitive-ops/contract.algo.ts:354 - // @arc4.abimethod() - txn OnCompletion - ! - assert // OnCompletion is not NoOp - txn ApplicationID - assert // can only call when not creating - // tests/artifacts/primitive-ops/contract.algo.ts:4 - // export class PrimitiveOpsContract extends arc4.Contract { - txna ApplicationArgs 1 - extract 2 0 - txna ApplicationArgs 2 - btoi - // tests/artifacts/primitive-ops/contract.algo.ts:354 - // @arc4.abimethod() - callsub verify_biguint_le_uint64 - bytec_1 // 0x00 - intc_1 // 0 - uncover 2 - setbit - bytec_0 // 0x151f7c75 - swap - concat - log - intc_0 // 1 - retsub - -__puya_arc4_router___verify_biguint_gt_route@53: - // tests/artifacts/primitive-ops/contract.algo.ts:362 - // @arc4.abimethod() - txn OnCompletion - ! - assert // OnCompletion is not NoOp - txn ApplicationID - assert // can only call when not creating - // tests/artifacts/primitive-ops/contract.algo.ts:4 - // export class PrimitiveOpsContract extends arc4.Contract { - txna ApplicationArgs 1 - extract 2 0 - txna ApplicationArgs 2 - extract 2 0 - // tests/artifacts/primitive-ops/contract.algo.ts:362 - // @arc4.abimethod() - callsub verify_biguint_gt - bytec_1 // 0x00 - intc_1 // 0 - uncover 2 - setbit - bytec_0 // 0x151f7c75 - swap - concat - log - intc_0 // 1 - retsub - -__puya_arc4_router___verify_biguint_gt_uint64_route@54: - // tests/artifacts/primitive-ops/contract.algo.ts:370 - // @arc4.abimethod() - txn OnCompletion - ! - assert // OnCompletion is not NoOp - txn ApplicationID - assert // can only call when not creating - // tests/artifacts/primitive-ops/contract.algo.ts:4 - // export class PrimitiveOpsContract extends arc4.Contract { - txna ApplicationArgs 1 - extract 2 0 - txna ApplicationArgs 2 - btoi - // tests/artifacts/primitive-ops/contract.algo.ts:370 - // @arc4.abimethod() - callsub verify_biguint_gt_uint64 - bytec_1 // 0x00 - intc_1 // 0 - uncover 2 - setbit - bytec_0 // 0x151f7c75 - swap - concat - log - intc_0 // 1 - retsub - -__puya_arc4_router___verify_biguint_ge_route@55: - // tests/artifacts/primitive-ops/contract.algo.ts:378 - // @arc4.abimethod() - txn OnCompletion - ! - assert // OnCompletion is not NoOp - txn ApplicationID - assert // can only call when not creating - // tests/artifacts/primitive-ops/contract.algo.ts:4 - // export class PrimitiveOpsContract extends arc4.Contract { - txna ApplicationArgs 1 - extract 2 0 - txna ApplicationArgs 2 - extract 2 0 - // tests/artifacts/primitive-ops/contract.algo.ts:378 - // @arc4.abimethod() - callsub verify_biguint_ge - bytec_1 // 0x00 - intc_1 // 0 - uncover 2 - setbit - bytec_0 // 0x151f7c75 - swap - concat - log - intc_0 // 1 - retsub - -__puya_arc4_router___verify_biguint_ge_uint64_route@56: - // tests/artifacts/primitive-ops/contract.algo.ts:386 - // @arc4.abimethod() - txn OnCompletion - ! - assert // OnCompletion is not NoOp - txn ApplicationID - assert // can only call when not creating - // tests/artifacts/primitive-ops/contract.algo.ts:4 - // export class PrimitiveOpsContract extends arc4.Contract { - txna ApplicationArgs 1 - extract 2 0 - txna ApplicationArgs 2 - btoi - // tests/artifacts/primitive-ops/contract.algo.ts:386 - // @arc4.abimethod() - callsub verify_biguint_ge_uint64 - bytec_1 // 0x00 - intc_1 // 0 - uncover 2 - setbit - bytec_0 // 0x151f7c75 - swap - concat - log - intc_0 // 1 - retsub - -__puya_arc4_router___verify_log_route@57: - // tests/artifacts/primitive-ops/contract.algo.ts:395 - // @arc4.abimethod() - txn OnCompletion - ! - assert // OnCompletion is not NoOp - txn ApplicationID - assert // can only call when not creating - // tests/artifacts/primitive-ops/contract.algo.ts:4 - // export class PrimitiveOpsContract extends arc4.Contract { - txna ApplicationArgs 1 - extract 2 0 - txna ApplicationArgs 2 - btoi - txna ApplicationArgs 3 - extract 2 0 - txna ApplicationArgs 4 - extract 2 0 - txna ApplicationArgs 5 - txna ApplicationArgs 6 - txna ApplicationArgs 7 - txna ApplicationArgs 8 - txna ApplicationArgs 9 - txna ApplicationArgs 10 - txna ApplicationArgs 11 - extract 2 0 - txna ApplicationArgs 12 - extract 2 0 - txna ApplicationArgs 13 - extract 2 0 - // tests/artifacts/primitive-ops/contract.algo.ts:395 - // @arc4.abimethod() - callsub verify_log - intc_0 // 1 - retsub - -__puya_arc4_router___bare_routing@60: - // tests/artifacts/primitive-ops/contract.algo.ts:4 - // export class PrimitiveOpsContract extends arc4.Contract { - txn OnCompletion - bnz __puya_arc4_router___after_if_else@64 - txn ApplicationID - ! - assert // can only call when creating - intc_0 // 1 - retsub - -__puya_arc4_router___after_if_else@64: - // tests/artifacts/primitive-ops/contract.algo.ts:4 - // export class PrimitiveOpsContract extends arc4.Contract { - intc_1 // 0 - retsub - - -// tests/artifacts/primitive-ops/contract.algo.ts::PrimitiveOpsContract.verify_uint64_init(raw_value: bytes) -> uint64: -verify_uint64_init: - // tests/artifacts/primitive-ops/contract.algo.ts:5-6 - // @arc4.abimethod() - // public verify_uint64_init(raw_value: bytes): uint64 { - proto 1 1 - // tests/artifacts/primitive-ops/contract.algo.ts:7 - // const result = op.btoi(raw_value) - frame_dig -1 - btoi - // tests/artifacts/primitive-ops/contract.algo.ts:8 - // return result - retsub - - -// tests/artifacts/primitive-ops/contract.algo.ts::PrimitiveOpsContract.verify_uint64_add(a: uint64, b: uint64) -> uint64: -verify_uint64_add: - // tests/artifacts/primitive-ops/contract.algo.ts:11-12 - // @arc4.abimethod() - // public verify_uint64_add(a: uint64, b: uint64): uint64 { - proto 2 1 - // tests/artifacts/primitive-ops/contract.algo.ts:13 - // const result: uint64 = a + b - frame_dig -2 - frame_dig -1 - + - // tests/artifacts/primitive-ops/contract.algo.ts:14 - // return result - retsub - - -// tests/artifacts/primitive-ops/contract.algo.ts::PrimitiveOpsContract.verify_uint64_sub(a: uint64, b: uint64) -> uint64: -verify_uint64_sub: - // tests/artifacts/primitive-ops/contract.algo.ts:17-18 - // @arc4.abimethod() - // public verify_uint64_sub(a: uint64, b: uint64): uint64 { - proto 2 1 - // tests/artifacts/primitive-ops/contract.algo.ts:19 - // const result: uint64 = a - b - frame_dig -2 - frame_dig -1 - - - // tests/artifacts/primitive-ops/contract.algo.ts:20 - // return result - retsub - - -// tests/artifacts/primitive-ops/contract.algo.ts::PrimitiveOpsContract.verify_uint64_mul(a: uint64, b: uint64) -> uint64: -verify_uint64_mul: - // tests/artifacts/primitive-ops/contract.algo.ts:23-24 - // @arc4.abimethod() - // public verify_uint64_mul(a: uint64, b: uint64): uint64 { - proto 2 1 - // tests/artifacts/primitive-ops/contract.algo.ts:25 - // const result: uint64 = a * b - frame_dig -2 - frame_dig -1 - * - // tests/artifacts/primitive-ops/contract.algo.ts:26 - // return result - retsub - - -// tests/artifacts/primitive-ops/contract.algo.ts::PrimitiveOpsContract.verify_uint64_div(a: uint64, b: uint64) -> uint64: -verify_uint64_div: - // tests/artifacts/primitive-ops/contract.algo.ts:29-30 - // @arc4.abimethod() - // public verify_uint64_div(a: uint64, b: uint64): uint64 { - proto 2 1 - // tests/artifacts/primitive-ops/contract.algo.ts:31 - // const result: uint64 = a / b - frame_dig -2 - frame_dig -1 - / - // tests/artifacts/primitive-ops/contract.algo.ts:32 - // return result - retsub - - -// tests/artifacts/primitive-ops/contract.algo.ts::PrimitiveOpsContract.verify_uint64_mod(a: uint64, b: uint64) -> uint64: -verify_uint64_mod: - // tests/artifacts/primitive-ops/contract.algo.ts:35-36 - // @arc4.abimethod() - // public verify_uint64_mod(a: uint64, b: uint64): uint64 { - proto 2 1 - // tests/artifacts/primitive-ops/contract.algo.ts:37 - // const result: uint64 = a % b - frame_dig -2 - frame_dig -1 - % - // tests/artifacts/primitive-ops/contract.algo.ts:38 - // return result - retsub - - -// tests/artifacts/primitive-ops/contract.algo.ts::PrimitiveOpsContract.verify_uint64_and(a: uint64, b: uint64) -> uint64: -verify_uint64_and: - // tests/artifacts/primitive-ops/contract.algo.ts:41-42 - // @arc4.abimethod() - // public verify_uint64_and(a: uint64, b: uint64): uint64 { - proto 2 1 - // tests/artifacts/primitive-ops/contract.algo.ts:43 - // const result: uint64 = a & b - frame_dig -2 - frame_dig -1 - & - // tests/artifacts/primitive-ops/contract.algo.ts:44 - // return result - retsub - - -// tests/artifacts/primitive-ops/contract.algo.ts::PrimitiveOpsContract.verify_uint64_or(a: uint64, b: uint64) -> uint64: -verify_uint64_or: - // tests/artifacts/primitive-ops/contract.algo.ts:47-48 - // @arc4.abimethod() - // public verify_uint64_or(a: uint64, b: uint64): uint64 { - proto 2 1 - // tests/artifacts/primitive-ops/contract.algo.ts:49 - // const result: uint64 = a | b - frame_dig -2 - frame_dig -1 - | - // tests/artifacts/primitive-ops/contract.algo.ts:50 - // return result - retsub - - -// tests/artifacts/primitive-ops/contract.algo.ts::PrimitiveOpsContract.verify_uint64_xor(a: uint64, b: uint64) -> uint64: -verify_uint64_xor: - // tests/artifacts/primitive-ops/contract.algo.ts:53-54 - // @arc4.abimethod() - // public verify_uint64_xor(a: uint64, b: uint64): uint64 { - proto 2 1 - // tests/artifacts/primitive-ops/contract.algo.ts:55 - // const result: uint64 = a ^ b - frame_dig -2 - frame_dig -1 - ^ - // tests/artifacts/primitive-ops/contract.algo.ts:56 - // return result - retsub - - -// tests/artifacts/primitive-ops/contract.algo.ts::PrimitiveOpsContract.verify_uint64_not(a: uint64) -> uint64: -verify_uint64_not: - // tests/artifacts/primitive-ops/contract.algo.ts:59-60 - // @arc4.abimethod() - // public verify_uint64_not(a: uint64): uint64 { - proto 1 1 - // tests/artifacts/primitive-ops/contract.algo.ts:61 - // const result: uint64 = ~a - frame_dig -1 - ~ - // tests/artifacts/primitive-ops/contract.algo.ts:62 - // return result - retsub - - -// tests/artifacts/primitive-ops/contract.algo.ts::PrimitiveOpsContract.verify_uint64_lshift(a: uint64, b: uint64) -> uint64: -verify_uint64_lshift: - // tests/artifacts/primitive-ops/contract.algo.ts:65-66 - // @arc4.abimethod() - // public verify_uint64_lshift(a: uint64, b: uint64): uint64 { - proto 2 1 - // tests/artifacts/primitive-ops/contract.algo.ts:67 - // const result: uint64 = a << b - frame_dig -2 - frame_dig -1 - shl - // tests/artifacts/primitive-ops/contract.algo.ts:68 - // return result - retsub - - -// tests/artifacts/primitive-ops/contract.algo.ts::PrimitiveOpsContract.verify_uint64_rshift(a: uint64, b: uint64) -> uint64: -verify_uint64_rshift: - // tests/artifacts/primitive-ops/contract.algo.ts:71-72 - // @arc4.abimethod() - // public verify_uint64_rshift(a: uint64, b: uint64): uint64 { - proto 2 1 - // tests/artifacts/primitive-ops/contract.algo.ts:73 - // const result: uint64 = a >> b - frame_dig -2 - frame_dig -1 - shr - // tests/artifacts/primitive-ops/contract.algo.ts:74 - // return result - retsub - - -// tests/artifacts/primitive-ops/contract.algo.ts::PrimitiveOpsContract.verify_uint64_pow(a: uint64, b: uint64) -> uint64: -verify_uint64_pow: - // tests/artifacts/primitive-ops/contract.algo.ts:77-78 - // @arc4.abimethod() - // public verify_uint64_pow(a: uint64, b: uint64): uint64 { - proto 2 1 - // tests/artifacts/primitive-ops/contract.algo.ts:79 - // const result: uint64 = a ** b - frame_dig -2 - frame_dig -1 - exp - // tests/artifacts/primitive-ops/contract.algo.ts:80 - // return result - retsub - - -// tests/artifacts/primitive-ops/contract.algo.ts::PrimitiveOpsContract.verify_uint64_eq(a: uint64, b: uint64) -> uint64: -verify_uint64_eq: - // tests/artifacts/primitive-ops/contract.algo.ts:83-84 - // @arc4.abimethod() - // public verify_uint64_eq(a: uint64, b: uint64): boolean { - proto 2 1 - // tests/artifacts/primitive-ops/contract.algo.ts:85 - // const result = a === b - frame_dig -2 - frame_dig -1 - == - // tests/artifacts/primitive-ops/contract.algo.ts:86 - // return result - retsub - - -// tests/artifacts/primitive-ops/contract.algo.ts::PrimitiveOpsContract.verify_uint64_ne(a: uint64, b: uint64) -> uint64: -verify_uint64_ne: - // tests/artifacts/primitive-ops/contract.algo.ts:89-90 - // @arc4.abimethod() - // public verify_uint64_ne(a: uint64, b: uint64): boolean { - proto 2 1 - // tests/artifacts/primitive-ops/contract.algo.ts:91 - // const result = a !== b - frame_dig -2 - frame_dig -1 - != - // tests/artifacts/primitive-ops/contract.algo.ts:92 - // return result - retsub - - -// tests/artifacts/primitive-ops/contract.algo.ts::PrimitiveOpsContract.verify_uint64_lt(a: uint64, b: uint64) -> uint64: -verify_uint64_lt: - // tests/artifacts/primitive-ops/contract.algo.ts:95-96 - // @arc4.abimethod() - // public verify_uint64_lt(a: uint64, b: uint64): boolean { - proto 2 1 - // tests/artifacts/primitive-ops/contract.algo.ts:97 - // const result = a < b - frame_dig -2 - frame_dig -1 - < - // tests/artifacts/primitive-ops/contract.algo.ts:98 - // return result - retsub - - -// tests/artifacts/primitive-ops/contract.algo.ts::PrimitiveOpsContract.verify_uint64_le(a: uint64, b: uint64) -> uint64: -verify_uint64_le: - // tests/artifacts/primitive-ops/contract.algo.ts:101-102 - // @arc4.abimethod() - // public verify_uint64_le(a: uint64, b: uint64): boolean { - proto 2 1 - // tests/artifacts/primitive-ops/contract.algo.ts:103 - // const result = a <= b - frame_dig -2 - frame_dig -1 - <= - // tests/artifacts/primitive-ops/contract.algo.ts:104 - // return result - retsub - - -// tests/artifacts/primitive-ops/contract.algo.ts::PrimitiveOpsContract.verify_uint64_gt(a: uint64, b: uint64) -> uint64: -verify_uint64_gt: - // tests/artifacts/primitive-ops/contract.algo.ts:107-108 - // @arc4.abimethod() - // public verify_uint64_gt(a: uint64, b: uint64): boolean { - proto 2 1 - // tests/artifacts/primitive-ops/contract.algo.ts:109 - // const result = a > b - frame_dig -2 - frame_dig -1 - > - // tests/artifacts/primitive-ops/contract.algo.ts:110 - // return result - retsub - - -// tests/artifacts/primitive-ops/contract.algo.ts::PrimitiveOpsContract.verify_uint64_ge(a: uint64, b: uint64) -> uint64: -verify_uint64_ge: - // tests/artifacts/primitive-ops/contract.algo.ts:113-114 - // @arc4.abimethod() - // public verify_uint64_ge(a: uint64, b: uint64): boolean { - proto 2 1 - // tests/artifacts/primitive-ops/contract.algo.ts:115 - // const result = a >= b - frame_dig -2 - frame_dig -1 - >= - // tests/artifacts/primitive-ops/contract.algo.ts:116 - // return result - retsub - - -// tests/artifacts/primitive-ops/contract.algo.ts::PrimitiveOpsContract.verify_bytes_init(raw_value: uint64) -> bytes: -verify_bytes_init: - // tests/artifacts/primitive-ops/contract.algo.ts:119-120 - // @arc4.abimethod() - // public verify_bytes_init(raw_value: uint64): bytes { - proto 1 1 - // tests/artifacts/primitive-ops/contract.algo.ts:121 - // const result = op.itob(raw_value) - frame_dig -1 - itob - // tests/artifacts/primitive-ops/contract.algo.ts:122 - // return result - retsub - - -// tests/artifacts/primitive-ops/contract.algo.ts::PrimitiveOpsContract.verify_bytes_add(a: bytes, b: bytes, pad_a_size: uint64, pad_b_size: uint64) -> bytes: -verify_bytes_add: - // tests/artifacts/primitive-ops/contract.algo.ts:125-126 - // @arc4.abimethod() - // public verify_bytes_add(a: bytes, b: bytes, pad_a_size: uint64, pad_b_size: uint64): bytes { - proto 4 1 - // tests/artifacts/primitive-ops/contract.algo.ts:127 - // const paddedA = op.bzero(pad_a_size).concat(a) - frame_dig -2 - bzero - frame_dig -4 - concat - // tests/artifacts/primitive-ops/contract.algo.ts:128 - // const paddedB = op.bzero(pad_b_size).concat(b) - frame_dig -1 - bzero - frame_dig -3 - concat - // tests/artifacts/primitive-ops/contract.algo.ts:129 - // const result = paddedA.concat(paddedB) - concat - // tests/artifacts/primitive-ops/contract.algo.ts:130 - // const resultHash = op.sha256(result) - sha256 - // tests/artifacts/primitive-ops/contract.algo.ts:131 - // return resultHash - retsub - - -// tests/artifacts/primitive-ops/contract.algo.ts::PrimitiveOpsContract.verify_bytes_eq(a: bytes, b: bytes) -> uint64: -verify_bytes_eq: - // tests/artifacts/primitive-ops/contract.algo.ts:134-135 - // @arc4.abimethod() - // public verify_bytes_eq(a: bytes, b: bytes): boolean { - proto 2 1 - // tests/artifacts/primitive-ops/contract.algo.ts:136 - // const result = a === b - frame_dig -2 - frame_dig -1 - == - // tests/artifacts/primitive-ops/contract.algo.ts:137 - // return result - retsub - - -// tests/artifacts/primitive-ops/contract.algo.ts::PrimitiveOpsContract.verify_bytes_ne(a: bytes, b: bytes) -> uint64: -verify_bytes_ne: - // tests/artifacts/primitive-ops/contract.algo.ts:140-141 - // @arc4.abimethod() - // public verify_bytes_ne(a: bytes, b: bytes): boolean { - proto 2 1 - // tests/artifacts/primitive-ops/contract.algo.ts:142 - // const result = a !== b - frame_dig -2 - frame_dig -1 - != - // tests/artifacts/primitive-ops/contract.algo.ts:143 - // return result - retsub - - -// tests/artifacts/primitive-ops/contract.algo.ts::PrimitiveOpsContract.verify_bytes_and(a: bytes, b: bytes) -> bytes: -verify_bytes_and: - // tests/artifacts/primitive-ops/contract.algo.ts:146-147 - // @arc4.abimethod() - // public verify_bytes_and(a: bytes, b: bytes): bytes { - proto 2 1 - // tests/artifacts/primitive-ops/contract.algo.ts:148 - // const result = a.bitwiseAnd(b) - frame_dig -2 - frame_dig -1 - b& - // tests/artifacts/primitive-ops/contract.algo.ts:149 - // return result - retsub - - -// tests/artifacts/primitive-ops/contract.algo.ts::PrimitiveOpsContract.verify_bytes_or(a: bytes, b: bytes) -> bytes: -verify_bytes_or: - // tests/artifacts/primitive-ops/contract.algo.ts:152-153 - // @arc4.abimethod() - // public verify_bytes_or(a: bytes, b: bytes): bytes { - proto 2 1 - // tests/artifacts/primitive-ops/contract.algo.ts:154 - // const result = a.bitwiseOr(b) - frame_dig -2 - frame_dig -1 - b| - // tests/artifacts/primitive-ops/contract.algo.ts:155 - // return result - retsub - - -// tests/artifacts/primitive-ops/contract.algo.ts::PrimitiveOpsContract.verify_bytes_xor(a: bytes, b: bytes) -> bytes: -verify_bytes_xor: - // tests/artifacts/primitive-ops/contract.algo.ts:158-159 - // @arc4.abimethod() - // public verify_bytes_xor(a: bytes, b: bytes): bytes { - proto 2 1 - // tests/artifacts/primitive-ops/contract.algo.ts:160 - // const result = a.bitwiseXor(b) - frame_dig -2 - frame_dig -1 - b^ - // tests/artifacts/primitive-ops/contract.algo.ts:161 - // return result - retsub - - -// tests/artifacts/primitive-ops/contract.algo.ts::PrimitiveOpsContract.verify_bytes_not(a: bytes, pad_size: uint64) -> bytes: -verify_bytes_not: - // tests/artifacts/primitive-ops/contract.algo.ts:164-165 - // @arc4.abimethod() - // public verify_bytes_not(a: bytes, pad_size: uint64): bytes { - proto 2 1 - // tests/artifacts/primitive-ops/contract.algo.ts:166 - // const paddedA = op.bzero(pad_size).concat(a) - frame_dig -1 - bzero - frame_dig -2 - concat - // tests/artifacts/primitive-ops/contract.algo.ts:167 - // const result = paddedA.bitwiseInvert() - b~ - // tests/artifacts/primitive-ops/contract.algo.ts:168 - // const resultHash = op.sha256(result) - sha256 - // tests/artifacts/primitive-ops/contract.algo.ts:169 - // return resultHash - retsub - - -// tests/artifacts/primitive-ops/contract.algo.ts::PrimitiveOpsContract.verify_biguint_add(a: bytes, b: bytes) -> bytes: -verify_biguint_add: - // tests/artifacts/primitive-ops/contract.algo.ts:172-173 - // @arc4.abimethod() - // public verify_biguint_add(a: bytes, b: bytes): bytes { - proto 2 1 - // tests/artifacts/primitive-ops/contract.algo.ts:176 - // const result: biguint = a_biguint + b_biguint - frame_dig -2 - frame_dig -1 - b+ - // tests/artifacts/primitive-ops/contract.algo.ts:177 - // return Bytes(result) - retsub - - -// tests/artifacts/primitive-ops/contract.algo.ts::PrimitiveOpsContract.verify_biguint_add_uint64(a: bytes, b: uint64) -> bytes: -verify_biguint_add_uint64: - // tests/artifacts/primitive-ops/contract.algo.ts:180-181 - // @arc4.abimethod() - // public verify_biguint_add_uint64(a: bytes, b: uint64): bytes { - proto 2 1 - // tests/artifacts/primitive-ops/contract.algo.ts:183 - // const b_biguint = BigUint(b) - frame_dig -1 - itob - // tests/artifacts/primitive-ops/contract.algo.ts:184 - // const result: biguint = a_biguint + b_biguint - frame_dig -2 - b+ - // tests/artifacts/primitive-ops/contract.algo.ts:185 - // return Bytes(result) - retsub - - -// tests/artifacts/primitive-ops/contract.algo.ts::PrimitiveOpsContract.verify_biguint_sub(a: bytes, b: bytes) -> bytes: -verify_biguint_sub: - // tests/artifacts/primitive-ops/contract.algo.ts:188-189 - // @arc4.abimethod() - // public verify_biguint_sub(a: bytes, b: bytes): bytes { - proto 2 1 - // tests/artifacts/primitive-ops/contract.algo.ts:192 - // const result: biguint = a_biguint - b_biguint - frame_dig -2 - frame_dig -1 - b- - // tests/artifacts/primitive-ops/contract.algo.ts:193 - // return Bytes(result) - retsub - - -// tests/artifacts/primitive-ops/contract.algo.ts::PrimitiveOpsContract.verify_biguint_sub_uint64(a: bytes, b: uint64) -> bytes: -verify_biguint_sub_uint64: - // tests/artifacts/primitive-ops/contract.algo.ts:196-197 - // @arc4.abimethod() - // public verify_biguint_sub_uint64(a: bytes, b: uint64): bytes { - proto 2 1 - // tests/artifacts/primitive-ops/contract.algo.ts:199 - // const b_biguint = BigUint(b) - frame_dig -1 - itob - // tests/artifacts/primitive-ops/contract.algo.ts:200 - // const result: biguint = a_biguint - b_biguint - frame_dig -2 - swap - b- - // tests/artifacts/primitive-ops/contract.algo.ts:201 - // return Bytes(result) - retsub - - -// tests/artifacts/primitive-ops/contract.algo.ts::PrimitiveOpsContract.verify_biguint_mul(a: bytes, b: bytes) -> bytes: -verify_biguint_mul: - // tests/artifacts/primitive-ops/contract.algo.ts:204-205 - // @arc4.abimethod() - // public verify_biguint_mul(a: bytes, b: bytes): bytes { - proto 2 1 - // tests/artifacts/primitive-ops/contract.algo.ts:208 - // const result: biguint = a_biguint * b_biguint - frame_dig -2 - frame_dig -1 - b* - // tests/artifacts/primitive-ops/contract.algo.ts:209 - // return Bytes(result) - retsub - - -// tests/artifacts/primitive-ops/contract.algo.ts::PrimitiveOpsContract.verify_biguint_mul_uint64(a: bytes, b: uint64) -> bytes: -verify_biguint_mul_uint64: - // tests/artifacts/primitive-ops/contract.algo.ts:212-213 - // @arc4.abimethod() - // public verify_biguint_mul_uint64(a: bytes, b: uint64): bytes { - proto 2 1 - // tests/artifacts/primitive-ops/contract.algo.ts:215 - // const b_biguint = BigUint(b) - frame_dig -1 - itob - // tests/artifacts/primitive-ops/contract.algo.ts:216 - // const result: biguint = a_biguint * b_biguint - frame_dig -2 - b* - // tests/artifacts/primitive-ops/contract.algo.ts:217 - // return Bytes(result) - retsub - - -// tests/artifacts/primitive-ops/contract.algo.ts::PrimitiveOpsContract.verify_biguint_div(a: bytes, b: bytes) -> bytes: -verify_biguint_div: - // tests/artifacts/primitive-ops/contract.algo.ts:220-221 - // @arc4.abimethod() - // public verify_biguint_div(a: bytes, b: bytes): bytes { - proto 2 1 - // tests/artifacts/primitive-ops/contract.algo.ts:224 - // const result: biguint = a_biguint / b_biguint - frame_dig -2 - frame_dig -1 - b/ - // tests/artifacts/primitive-ops/contract.algo.ts:225 - // return Bytes(result) - retsub - - -// tests/artifacts/primitive-ops/contract.algo.ts::PrimitiveOpsContract.verify_biguint_div_uint64(a: bytes, b: uint64) -> bytes: -verify_biguint_div_uint64: - // tests/artifacts/primitive-ops/contract.algo.ts:228-229 - // @arc4.abimethod() - // public verify_biguint_div_uint64(a: bytes, b: uint64): bytes { - proto 2 1 - // tests/artifacts/primitive-ops/contract.algo.ts:231 - // const b_biguint = BigUint(b) - frame_dig -1 - itob - // tests/artifacts/primitive-ops/contract.algo.ts:232 - // const result: biguint = a_biguint / b_biguint - frame_dig -2 - swap - b/ - // tests/artifacts/primitive-ops/contract.algo.ts:233 - // return Bytes(result) - retsub - - -// tests/artifacts/primitive-ops/contract.algo.ts::PrimitiveOpsContract.verify_biguint_mod(a: bytes, b: bytes) -> bytes: -verify_biguint_mod: - // tests/artifacts/primitive-ops/contract.algo.ts:236-237 - // @arc4.abimethod() - // public verify_biguint_mod(a: bytes, b: bytes): bytes { - proto 2 1 - // tests/artifacts/primitive-ops/contract.algo.ts:240 - // const result: biguint = a_biguint % b_biguint - frame_dig -2 - frame_dig -1 - b% - // tests/artifacts/primitive-ops/contract.algo.ts:241 - // return Bytes(result) - retsub - - -// tests/artifacts/primitive-ops/contract.algo.ts::PrimitiveOpsContract.verify_biguint_mod_uint64(a: bytes, b: uint64) -> bytes: -verify_biguint_mod_uint64: - // tests/artifacts/primitive-ops/contract.algo.ts:244-245 - // @arc4.abimethod() - // public verify_biguint_mod_uint64(a: bytes, b: uint64): bytes { - proto 2 1 - // tests/artifacts/primitive-ops/contract.algo.ts:247 - // const b_biguint = BigUint(b) - frame_dig -1 - itob - // tests/artifacts/primitive-ops/contract.algo.ts:248 - // const result: biguint = a_biguint % b_biguint - frame_dig -2 - swap - b% - // tests/artifacts/primitive-ops/contract.algo.ts:249 - // return Bytes(result) - retsub - - -// tests/artifacts/primitive-ops/contract.algo.ts::PrimitiveOpsContract.verify_biguint_and(a: bytes, b: bytes) -> bytes: -verify_biguint_and: - // tests/artifacts/primitive-ops/contract.algo.ts:252-253 - // @arc4.abimethod() - // public verify_biguint_and(a: bytes, b: bytes): bytes { - proto 2 1 - // tests/artifacts/primitive-ops/contract.algo.ts:256 - // const result: biguint = a_biguint & b_biguint - frame_dig -2 - frame_dig -1 - b& - // tests/artifacts/primitive-ops/contract.algo.ts:257 - // return Bytes(result) - retsub - - -// tests/artifacts/primitive-ops/contract.algo.ts::PrimitiveOpsContract.verify_biguint_and_uint64(a: bytes, b: uint64) -> bytes: -verify_biguint_and_uint64: - // tests/artifacts/primitive-ops/contract.algo.ts:260-261 - // @arc4.abimethod() - // public verify_biguint_and_uint64(a: bytes, b: uint64): bytes { - proto 2 1 - // tests/artifacts/primitive-ops/contract.algo.ts:263 - // const b_biguint = BigUint(b) - frame_dig -1 - itob - // tests/artifacts/primitive-ops/contract.algo.ts:264 - // const result: biguint = a_biguint & b_biguint - frame_dig -2 - b& - // tests/artifacts/primitive-ops/contract.algo.ts:265 - // return Bytes(result) - retsub - - -// tests/artifacts/primitive-ops/contract.algo.ts::PrimitiveOpsContract.verify_biguint_or(a: bytes, b: bytes) -> bytes: -verify_biguint_or: - // tests/artifacts/primitive-ops/contract.algo.ts:268-269 - // @arc4.abimethod() - // public verify_biguint_or(a: bytes, b: bytes): bytes { - proto 2 1 - // tests/artifacts/primitive-ops/contract.algo.ts:272 - // const result: biguint = a_biguint | b_biguint - frame_dig -2 - frame_dig -1 - b| - // tests/artifacts/primitive-ops/contract.algo.ts:273 - // return Bytes(result) - retsub - - -// tests/artifacts/primitive-ops/contract.algo.ts::PrimitiveOpsContract.verify_biguint_or_uint64(a: bytes, b: uint64) -> bytes: -verify_biguint_or_uint64: - // tests/artifacts/primitive-ops/contract.algo.ts:276-277 - // @arc4.abimethod() - // public verify_biguint_or_uint64(a: bytes, b: uint64): bytes { - proto 2 1 - // tests/artifacts/primitive-ops/contract.algo.ts:279 - // const b_biguint = BigUint(b) - frame_dig -1 - itob - // tests/artifacts/primitive-ops/contract.algo.ts:280 - // const result: biguint = a_biguint | b_biguint - frame_dig -2 - b| - // tests/artifacts/primitive-ops/contract.algo.ts:281 - // return Bytes(result) - retsub - - -// tests/artifacts/primitive-ops/contract.algo.ts::PrimitiveOpsContract.verify_biguint_xor(a: bytes, b: bytes) -> bytes: -verify_biguint_xor: - // tests/artifacts/primitive-ops/contract.algo.ts:284-285 - // @arc4.abimethod() - // public verify_biguint_xor(a: bytes, b: bytes): bytes { - proto 2 1 - // tests/artifacts/primitive-ops/contract.algo.ts:288 - // const result: biguint = a_biguint ^ b_biguint - frame_dig -2 - frame_dig -1 - b^ - // tests/artifacts/primitive-ops/contract.algo.ts:289 - // return Bytes(result) - retsub - - -// tests/artifacts/primitive-ops/contract.algo.ts::PrimitiveOpsContract.verify_biguint_xor_uint64(a: bytes, b: uint64) -> bytes: -verify_biguint_xor_uint64: - // tests/artifacts/primitive-ops/contract.algo.ts:292-293 - // @arc4.abimethod() - // public verify_biguint_xor_uint64(a: bytes, b: uint64): bytes { - proto 2 1 - // tests/artifacts/primitive-ops/contract.algo.ts:295 - // const b_biguint = BigUint(b) - frame_dig -1 - itob - // tests/artifacts/primitive-ops/contract.algo.ts:296 - // const result: biguint = a_biguint ^ b_biguint - frame_dig -2 - b^ - // tests/artifacts/primitive-ops/contract.algo.ts:297 - // return Bytes(result) - retsub - - -// tests/artifacts/primitive-ops/contract.algo.ts::PrimitiveOpsContract.verify_biguint_eq(a: bytes, b: bytes) -> uint64: -verify_biguint_eq: - // tests/artifacts/primitive-ops/contract.algo.ts:300-301 - // @arc4.abimethod() - // public verify_biguint_eq(a: bytes, b: bytes): boolean { - proto 2 1 - // tests/artifacts/primitive-ops/contract.algo.ts:304 - // const result = a_biguint === b_biguint - frame_dig -2 - frame_dig -1 - b== - // tests/artifacts/primitive-ops/contract.algo.ts:305 - // return result - retsub - - -// tests/artifacts/primitive-ops/contract.algo.ts::PrimitiveOpsContract.verify_biguint_eq_uint64(a: bytes, b: uint64) -> uint64: -verify_biguint_eq_uint64: - // tests/artifacts/primitive-ops/contract.algo.ts:308-309 - // @arc4.abimethod() - // public verify_biguint_eq_uint64(a: bytes, b: uint64): boolean { - proto 2 1 - // tests/artifacts/primitive-ops/contract.algo.ts:311 - // const result = a_biguint === BigUint(b) - frame_dig -1 - itob - frame_dig -2 - b== - // tests/artifacts/primitive-ops/contract.algo.ts:312 - // return result - retsub - - -// tests/artifacts/primitive-ops/contract.algo.ts::PrimitiveOpsContract.verify_biguint_ne(a: bytes, b: bytes) -> uint64: -verify_biguint_ne: - // tests/artifacts/primitive-ops/contract.algo.ts:315-316 - // @arc4.abimethod() - // public verify_biguint_ne(a: bytes, b: bytes): boolean { - proto 2 1 - // tests/artifacts/primitive-ops/contract.algo.ts:319 - // const result = a_biguint !== b_biguint - frame_dig -2 - frame_dig -1 - b!= - // tests/artifacts/primitive-ops/contract.algo.ts:320 - // return result - retsub - - -// tests/artifacts/primitive-ops/contract.algo.ts::PrimitiveOpsContract.verify_biguint_ne_uint64(a: bytes, b: uint64) -> uint64: -verify_biguint_ne_uint64: - // tests/artifacts/primitive-ops/contract.algo.ts:323-324 - // @arc4.abimethod() - // public verify_biguint_ne_uint64(a: bytes, b: uint64): boolean { - proto 2 1 - // tests/artifacts/primitive-ops/contract.algo.ts:326 - // const result = a_biguint !== BigUint(b) - frame_dig -1 - itob - frame_dig -2 - b!= - // tests/artifacts/primitive-ops/contract.algo.ts:327 - // return result - retsub - - -// tests/artifacts/primitive-ops/contract.algo.ts::PrimitiveOpsContract.verify_biguint_lt(a: bytes, b: bytes) -> uint64: -verify_biguint_lt: - // tests/artifacts/primitive-ops/contract.algo.ts:330-331 - // @arc4.abimethod() - // public verify_biguint_lt(a: bytes, b: bytes): boolean { - proto 2 1 - // tests/artifacts/primitive-ops/contract.algo.ts:334 - // const result = a_biguint < b_biguint - frame_dig -2 - frame_dig -1 - b< - // tests/artifacts/primitive-ops/contract.algo.ts:335 - // return result - retsub - - -// tests/artifacts/primitive-ops/contract.algo.ts::PrimitiveOpsContract.verify_biguint_lt_uint64(a: bytes, b: uint64) -> uint64: -verify_biguint_lt_uint64: - // tests/artifacts/primitive-ops/contract.algo.ts:338-339 - // @arc4.abimethod() - // public verify_biguint_lt_uint64(a: bytes, b: uint64): boolean { - proto 2 1 - // tests/artifacts/primitive-ops/contract.algo.ts:341 - // const b_biguint = BigUint(b) - frame_dig -1 - itob - // tests/artifacts/primitive-ops/contract.algo.ts:342 - // const result = a_biguint < b_biguint - frame_dig -2 - b> - // tests/artifacts/primitive-ops/contract.algo.ts:343 - // return result - retsub - - -// tests/artifacts/primitive-ops/contract.algo.ts::PrimitiveOpsContract.verify_biguint_le(a: bytes, b: bytes) -> uint64: -verify_biguint_le: - // tests/artifacts/primitive-ops/contract.algo.ts:346-347 - // @arc4.abimethod() - // public verify_biguint_le(a: bytes, b: bytes): boolean { - proto 2 1 - // tests/artifacts/primitive-ops/contract.algo.ts:350 - // const result = a_biguint <= b_biguint - frame_dig -2 - frame_dig -1 - b<= - // tests/artifacts/primitive-ops/contract.algo.ts:351 - // return result - retsub - - -// tests/artifacts/primitive-ops/contract.algo.ts::PrimitiveOpsContract.verify_biguint_le_uint64(a: bytes, b: uint64) -> uint64: -verify_biguint_le_uint64: - // tests/artifacts/primitive-ops/contract.algo.ts:354-355 - // @arc4.abimethod() - // public verify_biguint_le_uint64(a: bytes, b: uint64): boolean { - proto 2 1 - // tests/artifacts/primitive-ops/contract.algo.ts:357 - // const b_biguint = BigUint(b) - frame_dig -1 - itob - // tests/artifacts/primitive-ops/contract.algo.ts:358 - // const result = a_biguint <= b_biguint - frame_dig -2 - b>= - // tests/artifacts/primitive-ops/contract.algo.ts:359 - // return result - retsub - - -// tests/artifacts/primitive-ops/contract.algo.ts::PrimitiveOpsContract.verify_biguint_gt(a: bytes, b: bytes) -> uint64: -verify_biguint_gt: - // tests/artifacts/primitive-ops/contract.algo.ts:362-363 - // @arc4.abimethod() - // public verify_biguint_gt(a: bytes, b: bytes): boolean { - proto 2 1 - // tests/artifacts/primitive-ops/contract.algo.ts:366 - // const result = a_biguint > b_biguint - frame_dig -2 - frame_dig -1 - b> - // tests/artifacts/primitive-ops/contract.algo.ts:367 - // return result - retsub - - -// tests/artifacts/primitive-ops/contract.algo.ts::PrimitiveOpsContract.verify_biguint_gt_uint64(a: bytes, b: uint64) -> uint64: -verify_biguint_gt_uint64: - // tests/artifacts/primitive-ops/contract.algo.ts:370-371 - // @arc4.abimethod() - // public verify_biguint_gt_uint64(a: bytes, b: uint64): boolean { - proto 2 1 - // tests/artifacts/primitive-ops/contract.algo.ts:373 - // const b_biguint = BigUint(b) - frame_dig -1 - itob - // tests/artifacts/primitive-ops/contract.algo.ts:374 - // const result = a_biguint > b_biguint - frame_dig -2 - b< - // tests/artifacts/primitive-ops/contract.algo.ts:375 - // return result - retsub - - -// tests/artifacts/primitive-ops/contract.algo.ts::PrimitiveOpsContract.verify_biguint_ge(a: bytes, b: bytes) -> uint64: -verify_biguint_ge: - // tests/artifacts/primitive-ops/contract.algo.ts:378-379 - // @arc4.abimethod() - // public verify_biguint_ge(a: bytes, b: bytes): boolean { - proto 2 1 - // tests/artifacts/primitive-ops/contract.algo.ts:382 - // const result = a_biguint >= b_biguint - frame_dig -2 - frame_dig -1 - b>= - // tests/artifacts/primitive-ops/contract.algo.ts:383 - // return result - retsub - - -// tests/artifacts/primitive-ops/contract.algo.ts::PrimitiveOpsContract.verify_biguint_ge_uint64(a: bytes, b: uint64) -> uint64: -verify_biguint_ge_uint64: - // tests/artifacts/primitive-ops/contract.algo.ts:386-387 - // @arc4.abimethod() - // public verify_biguint_ge_uint64(a: bytes, b: uint64): boolean { - proto 2 1 - // tests/artifacts/primitive-ops/contract.algo.ts:389 - // const b_biguint = BigUint(b) - frame_dig -1 - itob - // tests/artifacts/primitive-ops/contract.algo.ts:390 - // const result = a_biguint >= b_biguint - frame_dig -2 - b<= - // tests/artifacts/primitive-ops/contract.algo.ts:391 - // return result - retsub - - -// tests/artifacts/primitive-ops/contract.algo.ts::PrimitiveOpsContract.verify_log(a: bytes, b: uint64, c: bytes, d: bytes, e: bytes, f: bytes, g: bytes, h: bytes, i: bytes, j: bytes, k: bytes, m: bytes, n: bytes) -> void: -verify_log: - // tests/artifacts/primitive-ops/contract.algo.ts:395-410 - // @arc4.abimethod() - // public verify_log( - // a: string, - // b: uint64, - // c: bytes, - // d: bytes, - // e: Bool, - // f: Str, - // g: UintN<64>, - // h: UintN<256>, - // i: UFixedNxM<32, 8>, - // j: UFixedNxM<256, 16>, - // k: bytes, - // m: bytes, - // n: bytes, - // ) { - proto 13 0 - // tests/artifacts/primitive-ops/contract.algo.ts:415 - // log(a, b, c, d_biguint, e, f, g, h, i, j, arc4_k, arc4_m, arc4_n) - frame_dig -12 - itob - frame_dig -13 - swap - concat - frame_dig -11 - concat - frame_dig -10 - concat - frame_dig -9 - concat - frame_dig -8 - concat - frame_dig -7 - concat - frame_dig -6 - concat - frame_dig -5 - concat - frame_dig -4 - concat - frame_dig -3 - concat - frame_dig -2 - concat - frame_dig -1 - concat - log - retsub diff --git a/tests/artifacts/primitive-ops/data/PrimitiveOpsContract.arc32.json b/tests/artifacts/primitive-ops/data/PrimitiveOpsContract.arc32.json deleted file mode 100644 index 8649c5e..0000000 --- a/tests/artifacts/primitive-ops/data/PrimitiveOpsContract.arc32.json +++ /dev/null @@ -1,1309 +0,0 @@ -{ - "hints": { - "verify_uint64_init(byte[])uint64": { - "call_config": { - "no_op": "CALL" - } - }, - "verify_uint64_add(uint64,uint64)uint64": { - "call_config": { - "no_op": "CALL" - } - }, - "verify_uint64_sub(uint64,uint64)uint64": { - "call_config": { - "no_op": "CALL" - } - }, - "verify_uint64_mul(uint64,uint64)uint64": { - "call_config": { - "no_op": "CALL" - } - }, - "verify_uint64_div(uint64,uint64)uint64": { - "call_config": { - "no_op": "CALL" - } - }, - "verify_uint64_mod(uint64,uint64)uint64": { - "call_config": { - "no_op": "CALL" - } - }, - "verify_uint64_and(uint64,uint64)uint64": { - "call_config": { - "no_op": "CALL" - } - }, - "verify_uint64_or(uint64,uint64)uint64": { - "call_config": { - "no_op": "CALL" - } - }, - "verify_uint64_xor(uint64,uint64)uint64": { - "call_config": { - "no_op": "CALL" - } - }, - "verify_uint64_not(uint64)uint64": { - "call_config": { - "no_op": "CALL" - } - }, - "verify_uint64_lshift(uint64,uint64)uint64": { - "call_config": { - "no_op": "CALL" - } - }, - "verify_uint64_rshift(uint64,uint64)uint64": { - "call_config": { - "no_op": "CALL" - } - }, - "verify_uint64_pow(uint64,uint64)uint64": { - "call_config": { - "no_op": "CALL" - } - }, - "verify_uint64_eq(uint64,uint64)bool": { - "call_config": { - "no_op": "CALL" - } - }, - "verify_uint64_ne(uint64,uint64)bool": { - "call_config": { - "no_op": "CALL" - } - }, - "verify_uint64_lt(uint64,uint64)bool": { - "call_config": { - "no_op": "CALL" - } - }, - "verify_uint64_le(uint64,uint64)bool": { - "call_config": { - "no_op": "CALL" - } - }, - "verify_uint64_gt(uint64,uint64)bool": { - "call_config": { - "no_op": "CALL" - } - }, - "verify_uint64_ge(uint64,uint64)bool": { - "call_config": { - "no_op": "CALL" - } - }, - "verify_bytes_init(uint64)byte[]": { - "call_config": { - "no_op": "CALL" - } - }, - "verify_bytes_add(byte[],byte[],uint64,uint64)byte[]": { - "call_config": { - "no_op": "CALL" - } - }, - "verify_bytes_eq(byte[],byte[])bool": { - "call_config": { - "no_op": "CALL" - } - }, - "verify_bytes_ne(byte[],byte[])bool": { - "call_config": { - "no_op": "CALL" - } - }, - "verify_bytes_and(byte[],byte[])byte[]": { - "call_config": { - "no_op": "CALL" - } - }, - "verify_bytes_or(byte[],byte[])byte[]": { - "call_config": { - "no_op": "CALL" - } - }, - "verify_bytes_xor(byte[],byte[])byte[]": { - "call_config": { - "no_op": "CALL" - } - }, - "verify_bytes_not(byte[],uint64)byte[]": { - "call_config": { - "no_op": "CALL" - } - }, - "verify_biguint_add(byte[],byte[])byte[]": { - "call_config": { - "no_op": "CALL" - } - }, - "verify_biguint_add_uint64(byte[],uint64)byte[]": { - "call_config": { - "no_op": "CALL" - } - }, - "verify_biguint_sub(byte[],byte[])byte[]": { - "call_config": { - "no_op": "CALL" - } - }, - "verify_biguint_sub_uint64(byte[],uint64)byte[]": { - "call_config": { - "no_op": "CALL" - } - }, - "verify_biguint_mul(byte[],byte[])byte[]": { - "call_config": { - "no_op": "CALL" - } - }, - "verify_biguint_mul_uint64(byte[],uint64)byte[]": { - "call_config": { - "no_op": "CALL" - } - }, - "verify_biguint_div(byte[],byte[])byte[]": { - "call_config": { - "no_op": "CALL" - } - }, - "verify_biguint_div_uint64(byte[],uint64)byte[]": { - "call_config": { - "no_op": "CALL" - } - }, - "verify_biguint_mod(byte[],byte[])byte[]": { - "call_config": { - "no_op": "CALL" - } - }, - "verify_biguint_mod_uint64(byte[],uint64)byte[]": { - "call_config": { - "no_op": "CALL" - } - }, - "verify_biguint_and(byte[],byte[])byte[]": { - "call_config": { - "no_op": "CALL" - } - }, - "verify_biguint_and_uint64(byte[],uint64)byte[]": { - "call_config": { - "no_op": "CALL" - } - }, - "verify_biguint_or(byte[],byte[])byte[]": { - "call_config": { - "no_op": "CALL" - } - }, - "verify_biguint_or_uint64(byte[],uint64)byte[]": { - "call_config": { - "no_op": "CALL" - } - }, - "verify_biguint_xor(byte[],byte[])byte[]": { - "call_config": { - "no_op": "CALL" - } - }, - "verify_biguint_xor_uint64(byte[],uint64)byte[]": { - "call_config": { - "no_op": "CALL" - } - }, - "verify_biguint_eq(byte[],byte[])bool": { - "call_config": { - "no_op": "CALL" - } - }, - "verify_biguint_eq_uint64(byte[],uint64)bool": { - "call_config": { - "no_op": "CALL" - } - }, - "verify_biguint_ne(byte[],byte[])bool": { - "call_config": { - "no_op": "CALL" - } - }, - "verify_biguint_ne_uint64(byte[],uint64)bool": { - "call_config": { - "no_op": "CALL" - } - }, - "verify_biguint_lt(byte[],byte[])bool": { - "call_config": { - "no_op": "CALL" - } - }, - "verify_biguint_lt_uint64(byte[],uint64)bool": { - "call_config": { - "no_op": "CALL" - } - }, - "verify_biguint_le(byte[],byte[])bool": { - "call_config": { - "no_op": "CALL" - } - }, - "verify_biguint_le_uint64(byte[],uint64)bool": { - "call_config": { - "no_op": "CALL" - } - }, - "verify_biguint_gt(byte[],byte[])bool": { - "call_config": { - "no_op": "CALL" - } - }, - "verify_biguint_gt_uint64(byte[],uint64)bool": { - "call_config": { - "no_op": "CALL" - } - }, - "verify_biguint_ge(byte[],byte[])bool": { - "call_config": { - "no_op": "CALL" - } - }, - "verify_biguint_ge_uint64(byte[],uint64)bool": { - "call_config": { - "no_op": "CALL" - } - }, - "verify_log(string,uint64,byte[],byte[],bool,string,uint64,uint256,ufixed32x8,ufixed256x16,byte[],byte[],byte[])void": { - "call_config": { - "no_op": "CALL" - } - } - }, - "source": { - "approval": "I3ByYWdtYSB2ZXJzaW9uIDEwCgp0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjpQcmltaXRpdmVPcHNDb250cmFjdC5hcHByb3ZhbFByb2dyYW06CiAgICBpbnRjYmxvY2sgMSAwCiAgICBieXRlY2Jsb2NrIDB4MTUxZjdjNzUgMHgwMAogICAgY2FsbHN1YiBfX3B1eWFfYXJjNF9yb3V0ZXJfXwogICAgcmV0dXJuCgoKLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo6UHJpbWl0aXZlT3BzQ29udHJhY3QuX19wdXlhX2FyYzRfcm91dGVyX18oKSAtPiB1aW50NjQ6Cl9fcHV5YV9hcmM0X3JvdXRlcl9fOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo0CiAgICAvLyBleHBvcnQgY2xhc3MgUHJpbWl0aXZlT3BzQ29udHJhY3QgZXh0ZW5kcyBhcmM0LkNvbnRyYWN0IHsKICAgIHByb3RvIDAgMQogICAgdHhuIE51bUFwcEFyZ3MKICAgIGJ6IF9fcHV5YV9hcmM0X3JvdXRlcl9fX2JhcmVfcm91dGluZ0A2MAogICAgcHVzaGJ5dGVzcyAweDcyNWM2OTJiIDB4MTczMTQ1NTkgMHg1M2YzNDg5MyAweDg4YzhiMjY5IDB4YTQ2NGI3YWIgMHg5YzhiMTFiOCAweDZmNDA2NTRlIDB4ZWM5YTI5NzQgMHhjNzkzNzA4ZiAweDdkZGI3NDk5IDB4YTIxYzQ0M2QgMHg2ZTdmYjIxMiAweGIwMDdmY2IwIDB4MmViYzIwZDQgMHhiMDk1NGI2NiAweGRkMTQwYWVmIDB4YWNlNDc0ZGEgMHhiYTY5NDk5MCAweDZkYjU4MWMwIDB4OTFjOGRiODkgMHhkYmU3NzE1OCAweDlhMGYyMmUxIDB4NjQwMzNkMzcgMHgyYTcyMzdjNSAweGUzYTk0NDU4IDB4NDJmODdmN2QgMHgyYjU1NDJhNCAweDliZTJmYmU5IDB4MWNkOTI1MTUgMHg2NGUxNzA1YyAweGYxMjcxYzUwIDB4MmFiNjNiNzAgMHg4MzRiYjdkMiAweDUzMTYyMGQ3IDB4M2ZiOWU3NjkgMHhmYThkYjBiYyAweGE3MmVhNDg1IDB4YjdiMGJhMTkgMHg3NDQ2MGM0MiAweGFiMzIwNzM4IDB4NTJhZDQ2NTQgMHgxMDE1NjM5OSAweDBmMDc1OTU3IDB4YmQ4NDNkZmYgMHhiMzc3ZDM4MSAweDg5NzY3MjY1IDB4NDU2YjRiMjMgMHgzM2QxYjg4YyAweDZiZjk3M2VhIDB4NjdjZDZiYjIgMHgzZjU4ODA1YSAweDFlMTMwMDM5IDB4NTA5ZGM5MWQgMHhhNTY0YTIwMiAweDIzNjUwNzYzIDB4ZTAwN2MxMGIgLy8gbWV0aG9kICJ2ZXJpZnlfdWludDY0X2luaXQoYnl0ZVtdKXVpbnQ2NCIsIG1ldGhvZCAidmVyaWZ5X3VpbnQ2NF9hZGQodWludDY0LHVpbnQ2NCl1aW50NjQiLCBtZXRob2QgInZlcmlmeV91aW50NjRfc3ViKHVpbnQ2NCx1aW50NjQpdWludDY0IiwgbWV0aG9kICJ2ZXJpZnlfdWludDY0X211bCh1aW50NjQsdWludDY0KXVpbnQ2NCIsIG1ldGhvZCAidmVyaWZ5X3VpbnQ2NF9kaXYodWludDY0LHVpbnQ2NCl1aW50NjQiLCBtZXRob2QgInZlcmlmeV91aW50NjRfbW9kKHVpbnQ2NCx1aW50NjQpdWludDY0IiwgbWV0aG9kICJ2ZXJpZnlfdWludDY0X2FuZCh1aW50NjQsdWludDY0KXVpbnQ2NCIsIG1ldGhvZCAidmVyaWZ5X3VpbnQ2NF9vcih1aW50NjQsdWludDY0KXVpbnQ2NCIsIG1ldGhvZCAidmVyaWZ5X3VpbnQ2NF94b3IodWludDY0LHVpbnQ2NCl1aW50NjQiLCBtZXRob2QgInZlcmlmeV91aW50NjRfbm90KHVpbnQ2NCl1aW50NjQiLCBtZXRob2QgInZlcmlmeV91aW50NjRfbHNoaWZ0KHVpbnQ2NCx1aW50NjQpdWludDY0IiwgbWV0aG9kICJ2ZXJpZnlfdWludDY0X3JzaGlmdCh1aW50NjQsdWludDY0KXVpbnQ2NCIsIG1ldGhvZCAidmVyaWZ5X3VpbnQ2NF9wb3codWludDY0LHVpbnQ2NCl1aW50NjQiLCBtZXRob2QgInZlcmlmeV91aW50NjRfZXEodWludDY0LHVpbnQ2NClib29sIiwgbWV0aG9kICJ2ZXJpZnlfdWludDY0X25lKHVpbnQ2NCx1aW50NjQpYm9vbCIsIG1ldGhvZCAidmVyaWZ5X3VpbnQ2NF9sdCh1aW50NjQsdWludDY0KWJvb2wiLCBtZXRob2QgInZlcmlmeV91aW50NjRfbGUodWludDY0LHVpbnQ2NClib29sIiwgbWV0aG9kICJ2ZXJpZnlfdWludDY0X2d0KHVpbnQ2NCx1aW50NjQpYm9vbCIsIG1ldGhvZCAidmVyaWZ5X3VpbnQ2NF9nZSh1aW50NjQsdWludDY0KWJvb2wiLCBtZXRob2QgInZlcmlmeV9ieXRlc19pbml0KHVpbnQ2NClieXRlW10iLCBtZXRob2QgInZlcmlmeV9ieXRlc19hZGQoYnl0ZVtdLGJ5dGVbXSx1aW50NjQsdWludDY0KWJ5dGVbXSIsIG1ldGhvZCAidmVyaWZ5X2J5dGVzX2VxKGJ5dGVbXSxieXRlW10pYm9vbCIsIG1ldGhvZCAidmVyaWZ5X2J5dGVzX25lKGJ5dGVbXSxieXRlW10pYm9vbCIsIG1ldGhvZCAidmVyaWZ5X2J5dGVzX2FuZChieXRlW10sYnl0ZVtdKWJ5dGVbXSIsIG1ldGhvZCAidmVyaWZ5X2J5dGVzX29yKGJ5dGVbXSxieXRlW10pYnl0ZVtdIiwgbWV0aG9kICJ2ZXJpZnlfYnl0ZXNfeG9yKGJ5dGVbXSxieXRlW10pYnl0ZVtdIiwgbWV0aG9kICJ2ZXJpZnlfYnl0ZXNfbm90KGJ5dGVbXSx1aW50NjQpYnl0ZVtdIiwgbWV0aG9kICJ2ZXJpZnlfYmlndWludF9hZGQoYnl0ZVtdLGJ5dGVbXSlieXRlW10iLCBtZXRob2QgInZlcmlmeV9iaWd1aW50X2FkZF91aW50NjQoYnl0ZVtdLHVpbnQ2NClieXRlW10iLCBtZXRob2QgInZlcmlmeV9iaWd1aW50X3N1YihieXRlW10sYnl0ZVtdKWJ5dGVbXSIsIG1ldGhvZCAidmVyaWZ5X2JpZ3VpbnRfc3ViX3VpbnQ2NChieXRlW10sdWludDY0KWJ5dGVbXSIsIG1ldGhvZCAidmVyaWZ5X2JpZ3VpbnRfbXVsKGJ5dGVbXSxieXRlW10pYnl0ZVtdIiwgbWV0aG9kICJ2ZXJpZnlfYmlndWludF9tdWxfdWludDY0KGJ5dGVbXSx1aW50NjQpYnl0ZVtdIiwgbWV0aG9kICJ2ZXJpZnlfYmlndWludF9kaXYoYnl0ZVtdLGJ5dGVbXSlieXRlW10iLCBtZXRob2QgInZlcmlmeV9iaWd1aW50X2Rpdl91aW50NjQoYnl0ZVtdLHVpbnQ2NClieXRlW10iLCBtZXRob2QgInZlcmlmeV9iaWd1aW50X21vZChieXRlW10sYnl0ZVtdKWJ5dGVbXSIsIG1ldGhvZCAidmVyaWZ5X2JpZ3VpbnRfbW9kX3VpbnQ2NChieXRlW10sdWludDY0KWJ5dGVbXSIsIG1ldGhvZCAidmVyaWZ5X2JpZ3VpbnRfYW5kKGJ5dGVbXSxieXRlW10pYnl0ZVtdIiwgbWV0aG9kICJ2ZXJpZnlfYmlndWludF9hbmRfdWludDY0KGJ5dGVbXSx1aW50NjQpYnl0ZVtdIiwgbWV0aG9kICJ2ZXJpZnlfYmlndWludF9vcihieXRlW10sYnl0ZVtdKWJ5dGVbXSIsIG1ldGhvZCAidmVyaWZ5X2JpZ3VpbnRfb3JfdWludDY0KGJ5dGVbXSx1aW50NjQpYnl0ZVtdIiwgbWV0aG9kICJ2ZXJpZnlfYmlndWludF94b3IoYnl0ZVtdLGJ5dGVbXSlieXRlW10iLCBtZXRob2QgInZlcmlmeV9iaWd1aW50X3hvcl91aW50NjQoYnl0ZVtdLHVpbnQ2NClieXRlW10iLCBtZXRob2QgInZlcmlmeV9iaWd1aW50X2VxKGJ5dGVbXSxieXRlW10pYm9vbCIsIG1ldGhvZCAidmVyaWZ5X2JpZ3VpbnRfZXFfdWludDY0KGJ5dGVbXSx1aW50NjQpYm9vbCIsIG1ldGhvZCAidmVyaWZ5X2JpZ3VpbnRfbmUoYnl0ZVtdLGJ5dGVbXSlib29sIiwgbWV0aG9kICJ2ZXJpZnlfYmlndWludF9uZV91aW50NjQoYnl0ZVtdLHVpbnQ2NClib29sIiwgbWV0aG9kICJ2ZXJpZnlfYmlndWludF9sdChieXRlW10sYnl0ZVtdKWJvb2wiLCBtZXRob2QgInZlcmlmeV9iaWd1aW50X2x0X3VpbnQ2NChieXRlW10sdWludDY0KWJvb2wiLCBtZXRob2QgInZlcmlmeV9iaWd1aW50X2xlKGJ5dGVbXSxieXRlW10pYm9vbCIsIG1ldGhvZCAidmVyaWZ5X2JpZ3VpbnRfbGVfdWludDY0KGJ5dGVbXSx1aW50NjQpYm9vbCIsIG1ldGhvZCAidmVyaWZ5X2JpZ3VpbnRfZ3QoYnl0ZVtdLGJ5dGVbXSlib29sIiwgbWV0aG9kICJ2ZXJpZnlfYmlndWludF9ndF91aW50NjQoYnl0ZVtdLHVpbnQ2NClib29sIiwgbWV0aG9kICJ2ZXJpZnlfYmlndWludF9nZShieXRlW10sYnl0ZVtdKWJvb2wiLCBtZXRob2QgInZlcmlmeV9iaWd1aW50X2dlX3VpbnQ2NChieXRlW10sdWludDY0KWJvb2wiLCBtZXRob2QgInZlcmlmeV9sb2coc3RyaW5nLHVpbnQ2NCxieXRlW10sYnl0ZVtdLGJvb2wsc3RyaW5nLHVpbnQ2NCx1aW50MjU2LHVmaXhlZDMyeDgsdWZpeGVkMjU2eDE2LGJ5dGVbXSxieXRlW10sYnl0ZVtdKXZvaWQiCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAwCiAgICBtYXRjaCBfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfdWludDY0X2luaXRfcm91dGVAMiBfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfdWludDY0X2FkZF9yb3V0ZUAzIF9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV91aW50NjRfc3ViX3JvdXRlQDQgX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X3VpbnQ2NF9tdWxfcm91dGVANSBfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfdWludDY0X2Rpdl9yb3V0ZUA2IF9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV91aW50NjRfbW9kX3JvdXRlQDcgX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X3VpbnQ2NF9hbmRfcm91dGVAOCBfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfdWludDY0X29yX3JvdXRlQDkgX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X3VpbnQ2NF94b3Jfcm91dGVAMTAgX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X3VpbnQ2NF9ub3Rfcm91dGVAMTEgX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X3VpbnQ2NF9sc2hpZnRfcm91dGVAMTIgX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X3VpbnQ2NF9yc2hpZnRfcm91dGVAMTMgX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X3VpbnQ2NF9wb3dfcm91dGVAMTQgX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X3VpbnQ2NF9lcV9yb3V0ZUAxNSBfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfdWludDY0X25lX3JvdXRlQDE2IF9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV91aW50NjRfbHRfcm91dGVAMTcgX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X3VpbnQ2NF9sZV9yb3V0ZUAxOCBfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfdWludDY0X2d0X3JvdXRlQDE5IF9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV91aW50NjRfZ2Vfcm91dGVAMjAgX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2J5dGVzX2luaXRfcm91dGVAMjEgX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2J5dGVzX2FkZF9yb3V0ZUAyMiBfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfYnl0ZXNfZXFfcm91dGVAMjMgX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2J5dGVzX25lX3JvdXRlQDI0IF9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9ieXRlc19hbmRfcm91dGVAMjUgX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2J5dGVzX29yX3JvdXRlQDI2IF9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9ieXRlc194b3Jfcm91dGVAMjcgX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2J5dGVzX25vdF9yb3V0ZUAyOCBfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfYmlndWludF9hZGRfcm91dGVAMjkgX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2JpZ3VpbnRfYWRkX3VpbnQ2NF9yb3V0ZUAzMCBfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfYmlndWludF9zdWJfcm91dGVAMzEgX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2JpZ3VpbnRfc3ViX3VpbnQ2NF9yb3V0ZUAzMiBfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfYmlndWludF9tdWxfcm91dGVAMzMgX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2JpZ3VpbnRfbXVsX3VpbnQ2NF9yb3V0ZUAzNCBfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfYmlndWludF9kaXZfcm91dGVAMzUgX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2JpZ3VpbnRfZGl2X3VpbnQ2NF9yb3V0ZUAzNiBfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfYmlndWludF9tb2Rfcm91dGVAMzcgX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2JpZ3VpbnRfbW9kX3VpbnQ2NF9yb3V0ZUAzOCBfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfYmlndWludF9hbmRfcm91dGVAMzkgX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2JpZ3VpbnRfYW5kX3VpbnQ2NF9yb3V0ZUA0MCBfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfYmlndWludF9vcl9yb3V0ZUA0MSBfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfYmlndWludF9vcl91aW50NjRfcm91dGVANDIgX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2JpZ3VpbnRfeG9yX3JvdXRlQDQzIF9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9iaWd1aW50X3hvcl91aW50NjRfcm91dGVANDQgX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2JpZ3VpbnRfZXFfcm91dGVANDUgX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2JpZ3VpbnRfZXFfdWludDY0X3JvdXRlQDQ2IF9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9iaWd1aW50X25lX3JvdXRlQDQ3IF9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9iaWd1aW50X25lX3VpbnQ2NF9yb3V0ZUA0OCBfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfYmlndWludF9sdF9yb3V0ZUA0OSBfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfYmlndWludF9sdF91aW50NjRfcm91dGVANTAgX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2JpZ3VpbnRfbGVfcm91dGVANTEgX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2JpZ3VpbnRfbGVfdWludDY0X3JvdXRlQDUyIF9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9iaWd1aW50X2d0X3JvdXRlQDUzIF9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9iaWd1aW50X2d0X3VpbnQ2NF9yb3V0ZUA1NCBfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfYmlndWludF9nZV9yb3V0ZUA1NSBfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfYmlndWludF9nZV91aW50NjRfcm91dGVANTYgX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2xvZ19yb3V0ZUA1NwogICAgaW50Y18xIC8vIDAKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X3VpbnQ2NF9pbml0X3JvdXRlQDI6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjUKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIG5vdCBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGNhbiBvbmx5IGNhbGwgd2hlbiBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NAogICAgLy8gZXhwb3J0IGNsYXNzIFByaW1pdGl2ZU9wc0NvbnRyYWN0IGV4dGVuZHMgYXJjNC5Db250cmFjdCB7CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBleHRyYWN0IDIgMAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo1CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfdWludDY0X2luaXQKICAgIGl0b2IKICAgIGJ5dGVjXzAgLy8gMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludGNfMCAvLyAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV91aW50NjRfYWRkX3JvdXRlQDM6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjExCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBub3QgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBjYW4gb25seSBjYWxsIHdoZW4gbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjQKICAgIC8vIGV4cG9ydCBjbGFzcyBQcmltaXRpdmVPcHNDb250cmFjdCBleHRlbmRzIGFyYzQuQ29udHJhY3QgewogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgYnRvaQogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMgogICAgYnRvaQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoxMQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X3VpbnQ2NF9hZGQKICAgIGl0b2IKICAgIGJ5dGVjXzAgLy8gMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludGNfMCAvLyAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV91aW50NjRfc3ViX3JvdXRlQDQ6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjE3CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBub3QgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBjYW4gb25seSBjYWxsIHdoZW4gbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjQKICAgIC8vIGV4cG9ydCBjbGFzcyBQcmltaXRpdmVPcHNDb250cmFjdCBleHRlbmRzIGFyYzQuQ29udHJhY3QgewogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgYnRvaQogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMgogICAgYnRvaQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoxNwogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X3VpbnQ2NF9zdWIKICAgIGl0b2IKICAgIGJ5dGVjXzAgLy8gMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludGNfMCAvLyAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV91aW50NjRfbXVsX3JvdXRlQDU6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjIzCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBub3QgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBjYW4gb25seSBjYWxsIHdoZW4gbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjQKICAgIC8vIGV4cG9ydCBjbGFzcyBQcmltaXRpdmVPcHNDb250cmFjdCBleHRlbmRzIGFyYzQuQ29udHJhY3QgewogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgYnRvaQogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMgogICAgYnRvaQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoyMwogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X3VpbnQ2NF9tdWwKICAgIGl0b2IKICAgIGJ5dGVjXzAgLy8gMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludGNfMCAvLyAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV91aW50NjRfZGl2X3JvdXRlQDY6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjI5CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBub3QgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBjYW4gb25seSBjYWxsIHdoZW4gbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjQKICAgIC8vIGV4cG9ydCBjbGFzcyBQcmltaXRpdmVPcHNDb250cmFjdCBleHRlbmRzIGFyYzQuQ29udHJhY3QgewogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgYnRvaQogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMgogICAgYnRvaQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoyOQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X3VpbnQ2NF9kaXYKICAgIGl0b2IKICAgIGJ5dGVjXzAgLy8gMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludGNfMCAvLyAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV91aW50NjRfbW9kX3JvdXRlQDc6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjM1CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBub3QgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBjYW4gb25seSBjYWxsIHdoZW4gbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjQKICAgIC8vIGV4cG9ydCBjbGFzcyBQcmltaXRpdmVPcHNDb250cmFjdCBleHRlbmRzIGFyYzQuQ29udHJhY3QgewogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgYnRvaQogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMgogICAgYnRvaQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czozNQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X3VpbnQ2NF9tb2QKICAgIGl0b2IKICAgIGJ5dGVjXzAgLy8gMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludGNfMCAvLyAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV91aW50NjRfYW5kX3JvdXRlQDg6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjQxCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBub3QgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBjYW4gb25seSBjYWxsIHdoZW4gbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjQKICAgIC8vIGV4cG9ydCBjbGFzcyBQcmltaXRpdmVPcHNDb250cmFjdCBleHRlbmRzIGFyYzQuQ29udHJhY3QgewogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgYnRvaQogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMgogICAgYnRvaQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo0MQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X3VpbnQ2NF9hbmQKICAgIGl0b2IKICAgIGJ5dGVjXzAgLy8gMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludGNfMCAvLyAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV91aW50NjRfb3Jfcm91dGVAOToKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NDcKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIG5vdCBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGNhbiBvbmx5IGNhbGwgd2hlbiBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NAogICAgLy8gZXhwb3J0IGNsYXNzIFByaW1pdGl2ZU9wc0NvbnRyYWN0IGV4dGVuZHMgYXJjNC5Db250cmFjdCB7CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBidG9pCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAyCiAgICBidG9pCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjQ3CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfdWludDY0X29yCiAgICBpdG9iCiAgICBieXRlY18wIC8vIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnRjXzAgLy8gMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfdWludDY0X3hvcl9yb3V0ZUAxMDoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NTMKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIG5vdCBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGNhbiBvbmx5IGNhbGwgd2hlbiBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NAogICAgLy8gZXhwb3J0IGNsYXNzIFByaW1pdGl2ZU9wc0NvbnRyYWN0IGV4dGVuZHMgYXJjNC5Db250cmFjdCB7CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBidG9pCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAyCiAgICBidG9pCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjUzCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfdWludDY0X3hvcgogICAgaXRvYgogICAgYnl0ZWNfMCAvLyAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50Y18wIC8vIDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X3VpbnQ2NF9ub3Rfcm91dGVAMTE6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjU5CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBub3QgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBjYW4gb25seSBjYWxsIHdoZW4gbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjQKICAgIC8vIGV4cG9ydCBjbGFzcyBQcmltaXRpdmVPcHNDb250cmFjdCBleHRlbmRzIGFyYzQuQ29udHJhY3QgewogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgYnRvaQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo1OQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X3VpbnQ2NF9ub3QKICAgIGl0b2IKICAgIGJ5dGVjXzAgLy8gMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludGNfMCAvLyAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV91aW50NjRfbHNoaWZ0X3JvdXRlQDEyOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo2NQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgbm90IE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gY2FuIG9ubHkgY2FsbCB3aGVuIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo0CiAgICAvLyBleHBvcnQgY2xhc3MgUHJpbWl0aXZlT3BzQ29udHJhY3QgZXh0ZW5kcyBhcmM0LkNvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGJ0b2kKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDIKICAgIGJ0b2kKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NjUKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV91aW50NjRfbHNoaWZ0CiAgICBpdG9iCiAgICBieXRlY18wIC8vIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnRjXzAgLy8gMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfdWludDY0X3JzaGlmdF9yb3V0ZUAxMzoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NzEKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIG5vdCBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGNhbiBvbmx5IGNhbGwgd2hlbiBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NAogICAgLy8gZXhwb3J0IGNsYXNzIFByaW1pdGl2ZU9wc0NvbnRyYWN0IGV4dGVuZHMgYXJjNC5Db250cmFjdCB7CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBidG9pCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAyCiAgICBidG9pCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjcxCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfdWludDY0X3JzaGlmdAogICAgaXRvYgogICAgYnl0ZWNfMCAvLyAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50Y18wIC8vIDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X3VpbnQ2NF9wb3dfcm91dGVAMTQ6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjc3CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBub3QgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBjYW4gb25seSBjYWxsIHdoZW4gbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjQKICAgIC8vIGV4cG9ydCBjbGFzcyBQcmltaXRpdmVPcHNDb250cmFjdCBleHRlbmRzIGFyYzQuQ29udHJhY3QgewogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgYnRvaQogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMgogICAgYnRvaQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo3NwogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X3VpbnQ2NF9wb3cKICAgIGl0b2IKICAgIGJ5dGVjXzAgLy8gMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludGNfMCAvLyAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV91aW50NjRfZXFfcm91dGVAMTU6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjgzCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBub3QgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBjYW4gb25seSBjYWxsIHdoZW4gbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjQKICAgIC8vIGV4cG9ydCBjbGFzcyBQcmltaXRpdmVPcHNDb250cmFjdCBleHRlbmRzIGFyYzQuQ29udHJhY3QgewogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgYnRvaQogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMgogICAgYnRvaQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo4MwogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X3VpbnQ2NF9lcQogICAgYnl0ZWNfMSAvLyAweDAwCiAgICBpbnRjXzEgLy8gMAogICAgdW5jb3ZlciAyCiAgICBzZXRiaXQKICAgIGJ5dGVjXzAgLy8gMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludGNfMCAvLyAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV91aW50NjRfbmVfcm91dGVAMTY6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjg5CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBub3QgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBjYW4gb25seSBjYWxsIHdoZW4gbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjQKICAgIC8vIGV4cG9ydCBjbGFzcyBQcmltaXRpdmVPcHNDb250cmFjdCBleHRlbmRzIGFyYzQuQ29udHJhY3QgewogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgYnRvaQogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMgogICAgYnRvaQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo4OQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X3VpbnQ2NF9uZQogICAgYnl0ZWNfMSAvLyAweDAwCiAgICBpbnRjXzEgLy8gMAogICAgdW5jb3ZlciAyCiAgICBzZXRiaXQKICAgIGJ5dGVjXzAgLy8gMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludGNfMCAvLyAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV91aW50NjRfbHRfcm91dGVAMTc6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjk1CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBub3QgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBjYW4gb25seSBjYWxsIHdoZW4gbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjQKICAgIC8vIGV4cG9ydCBjbGFzcyBQcmltaXRpdmVPcHNDb250cmFjdCBleHRlbmRzIGFyYzQuQ29udHJhY3QgewogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgYnRvaQogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMgogICAgYnRvaQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo5NQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X3VpbnQ2NF9sdAogICAgYnl0ZWNfMSAvLyAweDAwCiAgICBpbnRjXzEgLy8gMAogICAgdW5jb3ZlciAyCiAgICBzZXRiaXQKICAgIGJ5dGVjXzAgLy8gMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludGNfMCAvLyAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV91aW50NjRfbGVfcm91dGVAMTg6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjEwMQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgbm90IE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gY2FuIG9ubHkgY2FsbCB3aGVuIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo0CiAgICAvLyBleHBvcnQgY2xhc3MgUHJpbWl0aXZlT3BzQ29udHJhY3QgZXh0ZW5kcyBhcmM0LkNvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGJ0b2kKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDIKICAgIGJ0b2kKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTAxCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfdWludDY0X2xlCiAgICBieXRlY18xIC8vIDB4MDAKICAgIGludGNfMSAvLyAwCiAgICB1bmNvdmVyIDIKICAgIHNldGJpdAogICAgYnl0ZWNfMCAvLyAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50Y18wIC8vIDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X3VpbnQ2NF9ndF9yb3V0ZUAxOToKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTA3CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBub3QgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBjYW4gb25seSBjYWxsIHdoZW4gbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjQKICAgIC8vIGV4cG9ydCBjbGFzcyBQcmltaXRpdmVPcHNDb250cmFjdCBleHRlbmRzIGFyYzQuQ29udHJhY3QgewogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgYnRvaQogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMgogICAgYnRvaQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoxMDcKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV91aW50NjRfZ3QKICAgIGJ5dGVjXzEgLy8gMHgwMAogICAgaW50Y18xIC8vIDAKICAgIHVuY292ZXIgMgogICAgc2V0Yml0CiAgICBieXRlY18wIC8vIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnRjXzAgLy8gMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfdWludDY0X2dlX3JvdXRlQDIwOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoxMTMKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIG5vdCBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGNhbiBvbmx5IGNhbGwgd2hlbiBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NAogICAgLy8gZXhwb3J0IGNsYXNzIFByaW1pdGl2ZU9wc0NvbnRyYWN0IGV4dGVuZHMgYXJjNC5Db250cmFjdCB7CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBidG9pCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAyCiAgICBidG9pCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjExMwogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X3VpbnQ2NF9nZQogICAgYnl0ZWNfMSAvLyAweDAwCiAgICBpbnRjXzEgLy8gMAogICAgdW5jb3ZlciAyCiAgICBzZXRiaXQKICAgIGJ5dGVjXzAgLy8gMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludGNfMCAvLyAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9ieXRlc19pbml0X3JvdXRlQDIxOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoxMTkKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIG5vdCBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGNhbiBvbmx5IGNhbGwgd2hlbiBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NAogICAgLy8gZXhwb3J0IGNsYXNzIFByaW1pdGl2ZU9wc0NvbnRyYWN0IGV4dGVuZHMgYXJjNC5Db250cmFjdCB7CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBidG9pCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjExOQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X2J5dGVzX2luaXQKICAgIGR1cAogICAgbGVuCiAgICBpdG9iCiAgICBleHRyYWN0IDYgMgogICAgc3dhcAogICAgY29uY2F0CiAgICBieXRlY18wIC8vIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnRjXzAgLy8gMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfYnl0ZXNfYWRkX3JvdXRlQDIyOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoxMjUKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIG5vdCBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGNhbiBvbmx5IGNhbGwgd2hlbiBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NAogICAgLy8gZXhwb3J0IGNsYXNzIFByaW1pdGl2ZU9wc0NvbnRyYWN0IGV4dGVuZHMgYXJjNC5Db250cmFjdCB7CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBleHRyYWN0IDIgMAogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMgogICAgZXh0cmFjdCAyIDAKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDMKICAgIGJ0b2kKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDQKICAgIGJ0b2kKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTI1CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfYnl0ZXNfYWRkCiAgICBkdXAKICAgIGxlbgogICAgaXRvYgogICAgZXh0cmFjdCA2IDIKICAgIHN3YXAKICAgIGNvbmNhdAogICAgYnl0ZWNfMCAvLyAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50Y18wIC8vIDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2J5dGVzX2VxX3JvdXRlQDIzOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoxMzQKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIG5vdCBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGNhbiBvbmx5IGNhbGwgd2hlbiBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NAogICAgLy8gZXhwb3J0IGNsYXNzIFByaW1pdGl2ZU9wc0NvbnRyYWN0IGV4dGVuZHMgYXJjNC5Db250cmFjdCB7CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBleHRyYWN0IDIgMAogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMgogICAgZXh0cmFjdCAyIDAKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTM0CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfYnl0ZXNfZXEKICAgIGJ5dGVjXzEgLy8gMHgwMAogICAgaW50Y18xIC8vIDAKICAgIHVuY292ZXIgMgogICAgc2V0Yml0CiAgICBieXRlY18wIC8vIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnRjXzAgLy8gMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfYnl0ZXNfbmVfcm91dGVAMjQ6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjE0MAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgbm90IE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gY2FuIG9ubHkgY2FsbCB3aGVuIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo0CiAgICAvLyBleHBvcnQgY2xhc3MgUHJpbWl0aXZlT3BzQ29udHJhY3QgZXh0ZW5kcyBhcmM0LkNvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGV4dHJhY3QgMiAwCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAyCiAgICBleHRyYWN0IDIgMAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoxNDAKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV9ieXRlc19uZQogICAgYnl0ZWNfMSAvLyAweDAwCiAgICBpbnRjXzEgLy8gMAogICAgdW5jb3ZlciAyCiAgICBzZXRiaXQKICAgIGJ5dGVjXzAgLy8gMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludGNfMCAvLyAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9ieXRlc19hbmRfcm91dGVAMjU6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjE0NgogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgbm90IE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gY2FuIG9ubHkgY2FsbCB3aGVuIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo0CiAgICAvLyBleHBvcnQgY2xhc3MgUHJpbWl0aXZlT3BzQ29udHJhY3QgZXh0ZW5kcyBhcmM0LkNvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGV4dHJhY3QgMiAwCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAyCiAgICBleHRyYWN0IDIgMAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoxNDYKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV9ieXRlc19hbmQKICAgIGR1cAogICAgbGVuCiAgICBpdG9iCiAgICBleHRyYWN0IDYgMgogICAgc3dhcAogICAgY29uY2F0CiAgICBieXRlY18wIC8vIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnRjXzAgLy8gMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfYnl0ZXNfb3Jfcm91dGVAMjY6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjE1MgogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgbm90IE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gY2FuIG9ubHkgY2FsbCB3aGVuIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo0CiAgICAvLyBleHBvcnQgY2xhc3MgUHJpbWl0aXZlT3BzQ29udHJhY3QgZXh0ZW5kcyBhcmM0LkNvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGV4dHJhY3QgMiAwCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAyCiAgICBleHRyYWN0IDIgMAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoxNTIKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV9ieXRlc19vcgogICAgZHVwCiAgICBsZW4KICAgIGl0b2IKICAgIGV4dHJhY3QgNiAyCiAgICBzd2FwCiAgICBjb25jYXQKICAgIGJ5dGVjXzAgLy8gMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludGNfMCAvLyAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9ieXRlc194b3Jfcm91dGVAMjc6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjE1OAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgbm90IE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gY2FuIG9ubHkgY2FsbCB3aGVuIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo0CiAgICAvLyBleHBvcnQgY2xhc3MgUHJpbWl0aXZlT3BzQ29udHJhY3QgZXh0ZW5kcyBhcmM0LkNvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGV4dHJhY3QgMiAwCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAyCiAgICBleHRyYWN0IDIgMAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoxNTgKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV9ieXRlc194b3IKICAgIGR1cAogICAgbGVuCiAgICBpdG9iCiAgICBleHRyYWN0IDYgMgogICAgc3dhcAogICAgY29uY2F0CiAgICBieXRlY18wIC8vIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnRjXzAgLy8gMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfYnl0ZXNfbm90X3JvdXRlQDI4OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoxNjQKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIG5vdCBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGNhbiBvbmx5IGNhbGwgd2hlbiBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NAogICAgLy8gZXhwb3J0IGNsYXNzIFByaW1pdGl2ZU9wc0NvbnRyYWN0IGV4dGVuZHMgYXJjNC5Db250cmFjdCB7CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBleHRyYWN0IDIgMAogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMgogICAgYnRvaQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoxNjQKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV9ieXRlc19ub3QKICAgIGR1cAogICAgbGVuCiAgICBpdG9iCiAgICBleHRyYWN0IDYgMgogICAgc3dhcAogICAgY29uY2F0CiAgICBieXRlY18wIC8vIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnRjXzAgLy8gMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfYmlndWludF9hZGRfcm91dGVAMjk6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjE3MgogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgbm90IE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gY2FuIG9ubHkgY2FsbCB3aGVuIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo0CiAgICAvLyBleHBvcnQgY2xhc3MgUHJpbWl0aXZlT3BzQ29udHJhY3QgZXh0ZW5kcyBhcmM0LkNvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGV4dHJhY3QgMiAwCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAyCiAgICBleHRyYWN0IDIgMAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoxNzIKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV9iaWd1aW50X2FkZAogICAgZHVwCiAgICBsZW4KICAgIGl0b2IKICAgIGV4dHJhY3QgNiAyCiAgICBzd2FwCiAgICBjb25jYXQKICAgIGJ5dGVjXzAgLy8gMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludGNfMCAvLyAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9iaWd1aW50X2FkZF91aW50NjRfcm91dGVAMzA6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjE4MAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgbm90IE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gY2FuIG9ubHkgY2FsbCB3aGVuIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo0CiAgICAvLyBleHBvcnQgY2xhc3MgUHJpbWl0aXZlT3BzQ29udHJhY3QgZXh0ZW5kcyBhcmM0LkNvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGV4dHJhY3QgMiAwCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAyCiAgICBidG9pCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjE4MAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X2JpZ3VpbnRfYWRkX3VpbnQ2NAogICAgZHVwCiAgICBsZW4KICAgIGl0b2IKICAgIGV4dHJhY3QgNiAyCiAgICBzd2FwCiAgICBjb25jYXQKICAgIGJ5dGVjXzAgLy8gMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludGNfMCAvLyAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9iaWd1aW50X3N1Yl9yb3V0ZUAzMToKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTg4CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBub3QgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBjYW4gb25seSBjYWxsIHdoZW4gbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjQKICAgIC8vIGV4cG9ydCBjbGFzcyBQcmltaXRpdmVPcHNDb250cmFjdCBleHRlbmRzIGFyYzQuQ29udHJhY3QgewogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgZXh0cmFjdCAyIDAKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDIKICAgIGV4dHJhY3QgMiAwCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjE4OAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X2JpZ3VpbnRfc3ViCiAgICBkdXAKICAgIGxlbgogICAgaXRvYgogICAgZXh0cmFjdCA2IDIKICAgIHN3YXAKICAgIGNvbmNhdAogICAgYnl0ZWNfMCAvLyAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50Y18wIC8vIDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2JpZ3VpbnRfc3ViX3VpbnQ2NF9yb3V0ZUAzMjoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTk2CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBub3QgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBjYW4gb25seSBjYWxsIHdoZW4gbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjQKICAgIC8vIGV4cG9ydCBjbGFzcyBQcmltaXRpdmVPcHNDb250cmFjdCBleHRlbmRzIGFyYzQuQ29udHJhY3QgewogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgZXh0cmFjdCAyIDAKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDIKICAgIGJ0b2kKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTk2CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfYmlndWludF9zdWJfdWludDY0CiAgICBkdXAKICAgIGxlbgogICAgaXRvYgogICAgZXh0cmFjdCA2IDIKICAgIHN3YXAKICAgIGNvbmNhdAogICAgYnl0ZWNfMCAvLyAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50Y18wIC8vIDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2JpZ3VpbnRfbXVsX3JvdXRlQDMzOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoyMDQKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIG5vdCBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGNhbiBvbmx5IGNhbGwgd2hlbiBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NAogICAgLy8gZXhwb3J0IGNsYXNzIFByaW1pdGl2ZU9wc0NvbnRyYWN0IGV4dGVuZHMgYXJjNC5Db250cmFjdCB7CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBleHRyYWN0IDIgMAogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMgogICAgZXh0cmFjdCAyIDAKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MjA0CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfYmlndWludF9tdWwKICAgIGR1cAogICAgbGVuCiAgICBpdG9iCiAgICBleHRyYWN0IDYgMgogICAgc3dhcAogICAgY29uY2F0CiAgICBieXRlY18wIC8vIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnRjXzAgLy8gMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfYmlndWludF9tdWxfdWludDY0X3JvdXRlQDM0OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoyMTIKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIG5vdCBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGNhbiBvbmx5IGNhbGwgd2hlbiBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NAogICAgLy8gZXhwb3J0IGNsYXNzIFByaW1pdGl2ZU9wc0NvbnRyYWN0IGV4dGVuZHMgYXJjNC5Db250cmFjdCB7CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBleHRyYWN0IDIgMAogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMgogICAgYnRvaQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoyMTIKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV9iaWd1aW50X211bF91aW50NjQKICAgIGR1cAogICAgbGVuCiAgICBpdG9iCiAgICBleHRyYWN0IDYgMgogICAgc3dhcAogICAgY29uY2F0CiAgICBieXRlY18wIC8vIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnRjXzAgLy8gMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfYmlndWludF9kaXZfcm91dGVAMzU6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjIyMAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgbm90IE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gY2FuIG9ubHkgY2FsbCB3aGVuIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo0CiAgICAvLyBleHBvcnQgY2xhc3MgUHJpbWl0aXZlT3BzQ29udHJhY3QgZXh0ZW5kcyBhcmM0LkNvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGV4dHJhY3QgMiAwCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAyCiAgICBleHRyYWN0IDIgMAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoyMjAKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV9iaWd1aW50X2RpdgogICAgZHVwCiAgICBsZW4KICAgIGl0b2IKICAgIGV4dHJhY3QgNiAyCiAgICBzd2FwCiAgICBjb25jYXQKICAgIGJ5dGVjXzAgLy8gMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludGNfMCAvLyAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9iaWd1aW50X2Rpdl91aW50NjRfcm91dGVAMzY6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjIyOAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgbm90IE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gY2FuIG9ubHkgY2FsbCB3aGVuIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo0CiAgICAvLyBleHBvcnQgY2xhc3MgUHJpbWl0aXZlT3BzQ29udHJhY3QgZXh0ZW5kcyBhcmM0LkNvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGV4dHJhY3QgMiAwCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAyCiAgICBidG9pCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjIyOAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X2JpZ3VpbnRfZGl2X3VpbnQ2NAogICAgZHVwCiAgICBsZW4KICAgIGl0b2IKICAgIGV4dHJhY3QgNiAyCiAgICBzd2FwCiAgICBjb25jYXQKICAgIGJ5dGVjXzAgLy8gMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludGNfMCAvLyAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9iaWd1aW50X21vZF9yb3V0ZUAzNzoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MjM2CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBub3QgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBjYW4gb25seSBjYWxsIHdoZW4gbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjQKICAgIC8vIGV4cG9ydCBjbGFzcyBQcmltaXRpdmVPcHNDb250cmFjdCBleHRlbmRzIGFyYzQuQ29udHJhY3QgewogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgZXh0cmFjdCAyIDAKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDIKICAgIGV4dHJhY3QgMiAwCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjIzNgogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X2JpZ3VpbnRfbW9kCiAgICBkdXAKICAgIGxlbgogICAgaXRvYgogICAgZXh0cmFjdCA2IDIKICAgIHN3YXAKICAgIGNvbmNhdAogICAgYnl0ZWNfMCAvLyAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50Y18wIC8vIDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2JpZ3VpbnRfbW9kX3VpbnQ2NF9yb3V0ZUAzODoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MjQ0CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBub3QgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBjYW4gb25seSBjYWxsIHdoZW4gbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjQKICAgIC8vIGV4cG9ydCBjbGFzcyBQcmltaXRpdmVPcHNDb250cmFjdCBleHRlbmRzIGFyYzQuQ29udHJhY3QgewogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgZXh0cmFjdCAyIDAKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDIKICAgIGJ0b2kKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MjQ0CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfYmlndWludF9tb2RfdWludDY0CiAgICBkdXAKICAgIGxlbgogICAgaXRvYgogICAgZXh0cmFjdCA2IDIKICAgIHN3YXAKICAgIGNvbmNhdAogICAgYnl0ZWNfMCAvLyAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50Y18wIC8vIDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2JpZ3VpbnRfYW5kX3JvdXRlQDM5OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoyNTIKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIG5vdCBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGNhbiBvbmx5IGNhbGwgd2hlbiBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NAogICAgLy8gZXhwb3J0IGNsYXNzIFByaW1pdGl2ZU9wc0NvbnRyYWN0IGV4dGVuZHMgYXJjNC5Db250cmFjdCB7CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBleHRyYWN0IDIgMAogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMgogICAgZXh0cmFjdCAyIDAKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MjUyCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfYmlndWludF9hbmQKICAgIGR1cAogICAgbGVuCiAgICBpdG9iCiAgICBleHRyYWN0IDYgMgogICAgc3dhcAogICAgY29uY2F0CiAgICBieXRlY18wIC8vIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnRjXzAgLy8gMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfYmlndWludF9hbmRfdWludDY0X3JvdXRlQDQwOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoyNjAKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIG5vdCBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGNhbiBvbmx5IGNhbGwgd2hlbiBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NAogICAgLy8gZXhwb3J0IGNsYXNzIFByaW1pdGl2ZU9wc0NvbnRyYWN0IGV4dGVuZHMgYXJjNC5Db250cmFjdCB7CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBleHRyYWN0IDIgMAogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMgogICAgYnRvaQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoyNjAKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV9iaWd1aW50X2FuZF91aW50NjQKICAgIGR1cAogICAgbGVuCiAgICBpdG9iCiAgICBleHRyYWN0IDYgMgogICAgc3dhcAogICAgY29uY2F0CiAgICBieXRlY18wIC8vIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnRjXzAgLy8gMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfYmlndWludF9vcl9yb3V0ZUA0MToKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MjY4CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBub3QgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBjYW4gb25seSBjYWxsIHdoZW4gbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjQKICAgIC8vIGV4cG9ydCBjbGFzcyBQcmltaXRpdmVPcHNDb250cmFjdCBleHRlbmRzIGFyYzQuQ29udHJhY3QgewogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgZXh0cmFjdCAyIDAKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDIKICAgIGV4dHJhY3QgMiAwCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjI2OAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X2JpZ3VpbnRfb3IKICAgIGR1cAogICAgbGVuCiAgICBpdG9iCiAgICBleHRyYWN0IDYgMgogICAgc3dhcAogICAgY29uY2F0CiAgICBieXRlY18wIC8vIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnRjXzAgLy8gMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfYmlndWludF9vcl91aW50NjRfcm91dGVANDI6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjI3NgogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgbm90IE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gY2FuIG9ubHkgY2FsbCB3aGVuIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo0CiAgICAvLyBleHBvcnQgY2xhc3MgUHJpbWl0aXZlT3BzQ29udHJhY3QgZXh0ZW5kcyBhcmM0LkNvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGV4dHJhY3QgMiAwCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAyCiAgICBidG9pCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjI3NgogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X2JpZ3VpbnRfb3JfdWludDY0CiAgICBkdXAKICAgIGxlbgogICAgaXRvYgogICAgZXh0cmFjdCA2IDIKICAgIHN3YXAKICAgIGNvbmNhdAogICAgYnl0ZWNfMCAvLyAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50Y18wIC8vIDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2JpZ3VpbnRfeG9yX3JvdXRlQDQzOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoyODQKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIG5vdCBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGNhbiBvbmx5IGNhbGwgd2hlbiBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NAogICAgLy8gZXhwb3J0IGNsYXNzIFByaW1pdGl2ZU9wc0NvbnRyYWN0IGV4dGVuZHMgYXJjNC5Db250cmFjdCB7CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBleHRyYWN0IDIgMAogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMgogICAgZXh0cmFjdCAyIDAKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6Mjg0CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfYmlndWludF94b3IKICAgIGR1cAogICAgbGVuCiAgICBpdG9iCiAgICBleHRyYWN0IDYgMgogICAgc3dhcAogICAgY29uY2F0CiAgICBieXRlY18wIC8vIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnRjXzAgLy8gMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfYmlndWludF94b3JfdWludDY0X3JvdXRlQDQ0OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoyOTIKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIG5vdCBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGNhbiBvbmx5IGNhbGwgd2hlbiBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NAogICAgLy8gZXhwb3J0IGNsYXNzIFByaW1pdGl2ZU9wc0NvbnRyYWN0IGV4dGVuZHMgYXJjNC5Db250cmFjdCB7CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBleHRyYWN0IDIgMAogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMgogICAgYnRvaQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoyOTIKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV9iaWd1aW50X3hvcl91aW50NjQKICAgIGR1cAogICAgbGVuCiAgICBpdG9iCiAgICBleHRyYWN0IDYgMgogICAgc3dhcAogICAgY29uY2F0CiAgICBieXRlY18wIC8vIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnRjXzAgLy8gMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfYmlndWludF9lcV9yb3V0ZUA0NToKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MzAwCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBub3QgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBjYW4gb25seSBjYWxsIHdoZW4gbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjQKICAgIC8vIGV4cG9ydCBjbGFzcyBQcmltaXRpdmVPcHNDb250cmFjdCBleHRlbmRzIGFyYzQuQ29udHJhY3QgewogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgZXh0cmFjdCAyIDAKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDIKICAgIGV4dHJhY3QgMiAwCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjMwMAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X2JpZ3VpbnRfZXEKICAgIGJ5dGVjXzEgLy8gMHgwMAogICAgaW50Y18xIC8vIDAKICAgIHVuY292ZXIgMgogICAgc2V0Yml0CiAgICBieXRlY18wIC8vIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnRjXzAgLy8gMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfYmlndWludF9lcV91aW50NjRfcm91dGVANDY6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjMwOAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgbm90IE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gY2FuIG9ubHkgY2FsbCB3aGVuIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo0CiAgICAvLyBleHBvcnQgY2xhc3MgUHJpbWl0aXZlT3BzQ29udHJhY3QgZXh0ZW5kcyBhcmM0LkNvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGV4dHJhY3QgMiAwCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAyCiAgICBidG9pCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjMwOAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X2JpZ3VpbnRfZXFfdWludDY0CiAgICBieXRlY18xIC8vIDB4MDAKICAgIGludGNfMSAvLyAwCiAgICB1bmNvdmVyIDIKICAgIHNldGJpdAogICAgYnl0ZWNfMCAvLyAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50Y18wIC8vIDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2JpZ3VpbnRfbmVfcm91dGVANDc6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjMxNQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgbm90IE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gY2FuIG9ubHkgY2FsbCB3aGVuIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo0CiAgICAvLyBleHBvcnQgY2xhc3MgUHJpbWl0aXZlT3BzQ29udHJhY3QgZXh0ZW5kcyBhcmM0LkNvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGV4dHJhY3QgMiAwCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAyCiAgICBleHRyYWN0IDIgMAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czozMTUKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV9iaWd1aW50X25lCiAgICBieXRlY18xIC8vIDB4MDAKICAgIGludGNfMSAvLyAwCiAgICB1bmNvdmVyIDIKICAgIHNldGJpdAogICAgYnl0ZWNfMCAvLyAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50Y18wIC8vIDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2JpZ3VpbnRfbmVfdWludDY0X3JvdXRlQDQ4OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czozMjMKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIG5vdCBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGNhbiBvbmx5IGNhbGwgd2hlbiBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NAogICAgLy8gZXhwb3J0IGNsYXNzIFByaW1pdGl2ZU9wc0NvbnRyYWN0IGV4dGVuZHMgYXJjNC5Db250cmFjdCB7CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBleHRyYWN0IDIgMAogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMgogICAgYnRvaQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czozMjMKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV9iaWd1aW50X25lX3VpbnQ2NAogICAgYnl0ZWNfMSAvLyAweDAwCiAgICBpbnRjXzEgLy8gMAogICAgdW5jb3ZlciAyCiAgICBzZXRiaXQKICAgIGJ5dGVjXzAgLy8gMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludGNfMCAvLyAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9iaWd1aW50X2x0X3JvdXRlQDQ5OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czozMzAKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIG5vdCBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGNhbiBvbmx5IGNhbGwgd2hlbiBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NAogICAgLy8gZXhwb3J0IGNsYXNzIFByaW1pdGl2ZU9wc0NvbnRyYWN0IGV4dGVuZHMgYXJjNC5Db250cmFjdCB7CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBleHRyYWN0IDIgMAogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMgogICAgZXh0cmFjdCAyIDAKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MzMwCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfYmlndWludF9sdAogICAgYnl0ZWNfMSAvLyAweDAwCiAgICBpbnRjXzEgLy8gMAogICAgdW5jb3ZlciAyCiAgICBzZXRiaXQKICAgIGJ5dGVjXzAgLy8gMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludGNfMCAvLyAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9iaWd1aW50X2x0X3VpbnQ2NF9yb3V0ZUA1MDoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MzM4CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBub3QgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBjYW4gb25seSBjYWxsIHdoZW4gbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjQKICAgIC8vIGV4cG9ydCBjbGFzcyBQcmltaXRpdmVPcHNDb250cmFjdCBleHRlbmRzIGFyYzQuQ29udHJhY3QgewogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgZXh0cmFjdCAyIDAKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDIKICAgIGJ0b2kKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MzM4CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfYmlndWludF9sdF91aW50NjQKICAgIGJ5dGVjXzEgLy8gMHgwMAogICAgaW50Y18xIC8vIDAKICAgIHVuY292ZXIgMgogICAgc2V0Yml0CiAgICBieXRlY18wIC8vIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnRjXzAgLy8gMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfYmlndWludF9sZV9yb3V0ZUA1MToKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MzQ2CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBub3QgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBjYW4gb25seSBjYWxsIHdoZW4gbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjQKICAgIC8vIGV4cG9ydCBjbGFzcyBQcmltaXRpdmVPcHNDb250cmFjdCBleHRlbmRzIGFyYzQuQ29udHJhY3QgewogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgZXh0cmFjdCAyIDAKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDIKICAgIGV4dHJhY3QgMiAwCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjM0NgogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X2JpZ3VpbnRfbGUKICAgIGJ5dGVjXzEgLy8gMHgwMAogICAgaW50Y18xIC8vIDAKICAgIHVuY292ZXIgMgogICAgc2V0Yml0CiAgICBieXRlY18wIC8vIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnRjXzAgLy8gMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfYmlndWludF9sZV91aW50NjRfcm91dGVANTI6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjM1NAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgbm90IE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gY2FuIG9ubHkgY2FsbCB3aGVuIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo0CiAgICAvLyBleHBvcnQgY2xhc3MgUHJpbWl0aXZlT3BzQ29udHJhY3QgZXh0ZW5kcyBhcmM0LkNvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGV4dHJhY3QgMiAwCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAyCiAgICBidG9pCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjM1NAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X2JpZ3VpbnRfbGVfdWludDY0CiAgICBieXRlY18xIC8vIDB4MDAKICAgIGludGNfMSAvLyAwCiAgICB1bmNvdmVyIDIKICAgIHNldGJpdAogICAgYnl0ZWNfMCAvLyAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50Y18wIC8vIDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2JpZ3VpbnRfZ3Rfcm91dGVANTM6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjM2MgogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgbm90IE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gY2FuIG9ubHkgY2FsbCB3aGVuIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo0CiAgICAvLyBleHBvcnQgY2xhc3MgUHJpbWl0aXZlT3BzQ29udHJhY3QgZXh0ZW5kcyBhcmM0LkNvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGV4dHJhY3QgMiAwCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAyCiAgICBleHRyYWN0IDIgMAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czozNjIKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV9iaWd1aW50X2d0CiAgICBieXRlY18xIC8vIDB4MDAKICAgIGludGNfMSAvLyAwCiAgICB1bmNvdmVyIDIKICAgIHNldGJpdAogICAgYnl0ZWNfMCAvLyAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50Y18wIC8vIDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2JpZ3VpbnRfZ3RfdWludDY0X3JvdXRlQDU0OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czozNzAKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIG5vdCBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGNhbiBvbmx5IGNhbGwgd2hlbiBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NAogICAgLy8gZXhwb3J0IGNsYXNzIFByaW1pdGl2ZU9wc0NvbnRyYWN0IGV4dGVuZHMgYXJjNC5Db250cmFjdCB7CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBleHRyYWN0IDIgMAogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMgogICAgYnRvaQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czozNzAKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV9iaWd1aW50X2d0X3VpbnQ2NAogICAgYnl0ZWNfMSAvLyAweDAwCiAgICBpbnRjXzEgLy8gMAogICAgdW5jb3ZlciAyCiAgICBzZXRiaXQKICAgIGJ5dGVjXzAgLy8gMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludGNfMCAvLyAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9iaWd1aW50X2dlX3JvdXRlQDU1OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czozNzgKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIG5vdCBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGNhbiBvbmx5IGNhbGwgd2hlbiBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NAogICAgLy8gZXhwb3J0IGNsYXNzIFByaW1pdGl2ZU9wc0NvbnRyYWN0IGV4dGVuZHMgYXJjNC5Db250cmFjdCB7CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBleHRyYWN0IDIgMAogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMgogICAgZXh0cmFjdCAyIDAKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6Mzc4CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfYmlndWludF9nZQogICAgYnl0ZWNfMSAvLyAweDAwCiAgICBpbnRjXzEgLy8gMAogICAgdW5jb3ZlciAyCiAgICBzZXRiaXQKICAgIGJ5dGVjXzAgLy8gMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludGNfMCAvLyAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9iaWd1aW50X2dlX3VpbnQ2NF9yb3V0ZUA1NjoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6Mzg2CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBub3QgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBjYW4gb25seSBjYWxsIHdoZW4gbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjQKICAgIC8vIGV4cG9ydCBjbGFzcyBQcmltaXRpdmVPcHNDb250cmFjdCBleHRlbmRzIGFyYzQuQ29udHJhY3QgewogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgZXh0cmFjdCAyIDAKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDIKICAgIGJ0b2kKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6Mzg2CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfYmlndWludF9nZV91aW50NjQKICAgIGJ5dGVjXzEgLy8gMHgwMAogICAgaW50Y18xIC8vIDAKICAgIHVuY292ZXIgMgogICAgc2V0Yml0CiAgICBieXRlY18wIC8vIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnRjXzAgLy8gMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfbG9nX3JvdXRlQDU3OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czozOTUKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIG5vdCBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGNhbiBvbmx5IGNhbGwgd2hlbiBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NAogICAgLy8gZXhwb3J0IGNsYXNzIFByaW1pdGl2ZU9wc0NvbnRyYWN0IGV4dGVuZHMgYXJjNC5Db250cmFjdCB7CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBleHRyYWN0IDIgMAogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMgogICAgYnRvaQogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMwogICAgZXh0cmFjdCAyIDAKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDQKICAgIGV4dHJhY3QgMiAwCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyA1CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyA2CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyA3CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyA4CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyA5CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxMAogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMTEKICAgIGV4dHJhY3QgMiAwCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxMgogICAgZXh0cmFjdCAyIDAKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEzCiAgICBleHRyYWN0IDIgMAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czozOTUKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV9sb2cKICAgIGludGNfMCAvLyAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX2JhcmVfcm91dGluZ0A2MDoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NAogICAgLy8gZXhwb3J0IGNsYXNzIFByaW1pdGl2ZU9wc0NvbnRyYWN0IGV4dGVuZHMgYXJjNC5Db250cmFjdCB7CiAgICB0eG4gT25Db21wbGV0aW9uCiAgICBibnogX19wdXlhX2FyYzRfcm91dGVyX19fYWZ0ZXJfaWZfZWxzZUA2NAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgICEKICAgIGFzc2VydCAvLyBjYW4gb25seSBjYWxsIHdoZW4gY3JlYXRpbmcKICAgIGludGNfMCAvLyAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX2FmdGVyX2lmX2Vsc2VANjQ6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjQKICAgIC8vIGV4cG9ydCBjbGFzcyBQcmltaXRpdmVPcHNDb250cmFjdCBleHRlbmRzIGFyYzQuQ29udHJhY3QgewogICAgaW50Y18xIC8vIDAKICAgIHJldHN1YgoKCi8vIHRlc3RzL2FydGlmYWN0cy9wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OlByaW1pdGl2ZU9wc0NvbnRyYWN0LnZlcmlmeV91aW50NjRfaW5pdChyYXdfdmFsdWU6IGJ5dGVzKSAtPiB1aW50NjQ6CnZlcmlmeV91aW50NjRfaW5pdDoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NS02CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gcHVibGljIHZlcmlmeV91aW50NjRfaW5pdChyYXdfdmFsdWU6IGJ5dGVzKTogdWludDY0IHsKICAgIHByb3RvIDEgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo3CiAgICAvLyBjb25zdCByZXN1bHQgPSBvcC5idG9pKHJhd192YWx1ZSkKICAgIGZyYW1lX2RpZyAtMQogICAgYnRvaQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo4CiAgICAvLyByZXR1cm4gcmVzdWx0CiAgICByZXRzdWIKCgovLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjpQcmltaXRpdmVPcHNDb250cmFjdC52ZXJpZnlfdWludDY0X2FkZChhOiB1aW50NjQsIGI6IHVpbnQ2NCkgLT4gdWludDY0Ogp2ZXJpZnlfdWludDY0X2FkZDoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTEtMTIKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBwdWJsaWMgdmVyaWZ5X3VpbnQ2NF9hZGQoYTogdWludDY0LCBiOiB1aW50NjQpOiB1aW50NjQgewogICAgcHJvdG8gMiAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjEzCiAgICAvLyBjb25zdCByZXN1bHQ6IHVpbnQ2NCA9IGEgKyBiCiAgICBmcmFtZV9kaWcgLTIKICAgIGZyYW1lX2RpZyAtMQogICAgKwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoxNAogICAgLy8gcmV0dXJuIHJlc3VsdAogICAgcmV0c3ViCgoKLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo6UHJpbWl0aXZlT3BzQ29udHJhY3QudmVyaWZ5X3VpbnQ2NF9zdWIoYTogdWludDY0LCBiOiB1aW50NjQpIC0+IHVpbnQ2NDoKdmVyaWZ5X3VpbnQ2NF9zdWI6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjE3LTE4CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gcHVibGljIHZlcmlmeV91aW50NjRfc3ViKGE6IHVpbnQ2NCwgYjogdWludDY0KTogdWludDY0IHsKICAgIHByb3RvIDIgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoxOQogICAgLy8gY29uc3QgcmVzdWx0OiB1aW50NjQgPSBhIC0gYgogICAgZnJhbWVfZGlnIC0yCiAgICBmcmFtZV9kaWcgLTEKICAgIC0KICAgIC8vIHRlc3RzL2FydGlmYWN0cy9wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MjAKICAgIC8vIHJldHVybiByZXN1bHQKICAgIHJldHN1YgoKCi8vIHRlc3RzL2FydGlmYWN0cy9wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OlByaW1pdGl2ZU9wc0NvbnRyYWN0LnZlcmlmeV91aW50NjRfbXVsKGE6IHVpbnQ2NCwgYjogdWludDY0KSAtPiB1aW50NjQ6CnZlcmlmeV91aW50NjRfbXVsOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoyMy0yNAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIHB1YmxpYyB2ZXJpZnlfdWludDY0X211bChhOiB1aW50NjQsIGI6IHVpbnQ2NCk6IHVpbnQ2NCB7CiAgICBwcm90byAyIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MjUKICAgIC8vIGNvbnN0IHJlc3VsdDogdWludDY0ID0gYSAqIGIKICAgIGZyYW1lX2RpZyAtMgogICAgZnJhbWVfZGlnIC0xCiAgICAqCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjI2CiAgICAvLyByZXR1cm4gcmVzdWx0CiAgICByZXRzdWIKCgovLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjpQcmltaXRpdmVPcHNDb250cmFjdC52ZXJpZnlfdWludDY0X2RpdihhOiB1aW50NjQsIGI6IHVpbnQ2NCkgLT4gdWludDY0Ogp2ZXJpZnlfdWludDY0X2RpdjoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MjktMzAKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBwdWJsaWMgdmVyaWZ5X3VpbnQ2NF9kaXYoYTogdWludDY0LCBiOiB1aW50NjQpOiB1aW50NjQgewogICAgcHJvdG8gMiAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjMxCiAgICAvLyBjb25zdCByZXN1bHQ6IHVpbnQ2NCA9IGEgLyBiCiAgICBmcmFtZV9kaWcgLTIKICAgIGZyYW1lX2RpZyAtMQogICAgLwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czozMgogICAgLy8gcmV0dXJuIHJlc3VsdAogICAgcmV0c3ViCgoKLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo6UHJpbWl0aXZlT3BzQ29udHJhY3QudmVyaWZ5X3VpbnQ2NF9tb2QoYTogdWludDY0LCBiOiB1aW50NjQpIC0+IHVpbnQ2NDoKdmVyaWZ5X3VpbnQ2NF9tb2Q6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjM1LTM2CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gcHVibGljIHZlcmlmeV91aW50NjRfbW9kKGE6IHVpbnQ2NCwgYjogdWludDY0KTogdWludDY0IHsKICAgIHByb3RvIDIgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czozNwogICAgLy8gY29uc3QgcmVzdWx0OiB1aW50NjQgPSBhICUgYgogICAgZnJhbWVfZGlnIC0yCiAgICBmcmFtZV9kaWcgLTEKICAgICUKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MzgKICAgIC8vIHJldHVybiByZXN1bHQKICAgIHJldHN1YgoKCi8vIHRlc3RzL2FydGlmYWN0cy9wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OlByaW1pdGl2ZU9wc0NvbnRyYWN0LnZlcmlmeV91aW50NjRfYW5kKGE6IHVpbnQ2NCwgYjogdWludDY0KSAtPiB1aW50NjQ6CnZlcmlmeV91aW50NjRfYW5kOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo0MS00MgogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIHB1YmxpYyB2ZXJpZnlfdWludDY0X2FuZChhOiB1aW50NjQsIGI6IHVpbnQ2NCk6IHVpbnQ2NCB7CiAgICBwcm90byAyIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NDMKICAgIC8vIGNvbnN0IHJlc3VsdDogdWludDY0ID0gYSAmIGIKICAgIGZyYW1lX2RpZyAtMgogICAgZnJhbWVfZGlnIC0xCiAgICAmCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjQ0CiAgICAvLyByZXR1cm4gcmVzdWx0CiAgICByZXRzdWIKCgovLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjpQcmltaXRpdmVPcHNDb250cmFjdC52ZXJpZnlfdWludDY0X29yKGE6IHVpbnQ2NCwgYjogdWludDY0KSAtPiB1aW50NjQ6CnZlcmlmeV91aW50NjRfb3I6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjQ3LTQ4CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gcHVibGljIHZlcmlmeV91aW50NjRfb3IoYTogdWludDY0LCBiOiB1aW50NjQpOiB1aW50NjQgewogICAgcHJvdG8gMiAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjQ5CiAgICAvLyBjb25zdCByZXN1bHQ6IHVpbnQ2NCA9IGEgfCBiCiAgICBmcmFtZV9kaWcgLTIKICAgIGZyYW1lX2RpZyAtMQogICAgfAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo1MAogICAgLy8gcmV0dXJuIHJlc3VsdAogICAgcmV0c3ViCgoKLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo6UHJpbWl0aXZlT3BzQ29udHJhY3QudmVyaWZ5X3VpbnQ2NF94b3IoYTogdWludDY0LCBiOiB1aW50NjQpIC0+IHVpbnQ2NDoKdmVyaWZ5X3VpbnQ2NF94b3I6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjUzLTU0CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gcHVibGljIHZlcmlmeV91aW50NjRfeG9yKGE6IHVpbnQ2NCwgYjogdWludDY0KTogdWludDY0IHsKICAgIHByb3RvIDIgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo1NQogICAgLy8gY29uc3QgcmVzdWx0OiB1aW50NjQgPSBhIF4gYgogICAgZnJhbWVfZGlnIC0yCiAgICBmcmFtZV9kaWcgLTEKICAgIF4KICAgIC8vIHRlc3RzL2FydGlmYWN0cy9wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NTYKICAgIC8vIHJldHVybiByZXN1bHQKICAgIHJldHN1YgoKCi8vIHRlc3RzL2FydGlmYWN0cy9wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OlByaW1pdGl2ZU9wc0NvbnRyYWN0LnZlcmlmeV91aW50NjRfbm90KGE6IHVpbnQ2NCkgLT4gdWludDY0Ogp2ZXJpZnlfdWludDY0X25vdDoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NTktNjAKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBwdWJsaWMgdmVyaWZ5X3VpbnQ2NF9ub3QoYTogdWludDY0KTogdWludDY0IHsKICAgIHByb3RvIDEgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo2MQogICAgLy8gY29uc3QgcmVzdWx0OiB1aW50NjQgPSB+YQogICAgZnJhbWVfZGlnIC0xCiAgICB+CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjYyCiAgICAvLyByZXR1cm4gcmVzdWx0CiAgICByZXRzdWIKCgovLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjpQcmltaXRpdmVPcHNDb250cmFjdC52ZXJpZnlfdWludDY0X2xzaGlmdChhOiB1aW50NjQsIGI6IHVpbnQ2NCkgLT4gdWludDY0Ogp2ZXJpZnlfdWludDY0X2xzaGlmdDoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NjUtNjYKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBwdWJsaWMgdmVyaWZ5X3VpbnQ2NF9sc2hpZnQoYTogdWludDY0LCBiOiB1aW50NjQpOiB1aW50NjQgewogICAgcHJvdG8gMiAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjY3CiAgICAvLyBjb25zdCByZXN1bHQ6IHVpbnQ2NCA9IGEgPDwgYgogICAgZnJhbWVfZGlnIC0yCiAgICBmcmFtZV9kaWcgLTEKICAgIHNobAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo2OAogICAgLy8gcmV0dXJuIHJlc3VsdAogICAgcmV0c3ViCgoKLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo6UHJpbWl0aXZlT3BzQ29udHJhY3QudmVyaWZ5X3VpbnQ2NF9yc2hpZnQoYTogdWludDY0LCBiOiB1aW50NjQpIC0+IHVpbnQ2NDoKdmVyaWZ5X3VpbnQ2NF9yc2hpZnQ6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjcxLTcyCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gcHVibGljIHZlcmlmeV91aW50NjRfcnNoaWZ0KGE6IHVpbnQ2NCwgYjogdWludDY0KTogdWludDY0IHsKICAgIHByb3RvIDIgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo3MwogICAgLy8gY29uc3QgcmVzdWx0OiB1aW50NjQgPSBhID4+IGIKICAgIGZyYW1lX2RpZyAtMgogICAgZnJhbWVfZGlnIC0xCiAgICBzaHIKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NzQKICAgIC8vIHJldHVybiByZXN1bHQKICAgIHJldHN1YgoKCi8vIHRlc3RzL2FydGlmYWN0cy9wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OlByaW1pdGl2ZU9wc0NvbnRyYWN0LnZlcmlmeV91aW50NjRfcG93KGE6IHVpbnQ2NCwgYjogdWludDY0KSAtPiB1aW50NjQ6CnZlcmlmeV91aW50NjRfcG93OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo3Ny03OAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIHB1YmxpYyB2ZXJpZnlfdWludDY0X3BvdyhhOiB1aW50NjQsIGI6IHVpbnQ2NCk6IHVpbnQ2NCB7CiAgICBwcm90byAyIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NzkKICAgIC8vIGNvbnN0IHJlc3VsdDogdWludDY0ID0gYSAqKiBiCiAgICBmcmFtZV9kaWcgLTIKICAgIGZyYW1lX2RpZyAtMQogICAgZXhwCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjgwCiAgICAvLyByZXR1cm4gcmVzdWx0CiAgICByZXRzdWIKCgovLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjpQcmltaXRpdmVPcHNDb250cmFjdC52ZXJpZnlfdWludDY0X2VxKGE6IHVpbnQ2NCwgYjogdWludDY0KSAtPiB1aW50NjQ6CnZlcmlmeV91aW50NjRfZXE6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjgzLTg0CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gcHVibGljIHZlcmlmeV91aW50NjRfZXEoYTogdWludDY0LCBiOiB1aW50NjQpOiBib29sZWFuIHsKICAgIHByb3RvIDIgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo4NQogICAgLy8gY29uc3QgcmVzdWx0ID0gYSA9PT0gYgogICAgZnJhbWVfZGlnIC0yCiAgICBmcmFtZV9kaWcgLTEKICAgID09CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjg2CiAgICAvLyByZXR1cm4gcmVzdWx0CiAgICByZXRzdWIKCgovLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjpQcmltaXRpdmVPcHNDb250cmFjdC52ZXJpZnlfdWludDY0X25lKGE6IHVpbnQ2NCwgYjogdWludDY0KSAtPiB1aW50NjQ6CnZlcmlmeV91aW50NjRfbmU6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjg5LTkwCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gcHVibGljIHZlcmlmeV91aW50NjRfbmUoYTogdWludDY0LCBiOiB1aW50NjQpOiBib29sZWFuIHsKICAgIHByb3RvIDIgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo5MQogICAgLy8gY29uc3QgcmVzdWx0ID0gYSAhPT0gYgogICAgZnJhbWVfZGlnIC0yCiAgICBmcmFtZV9kaWcgLTEKICAgICE9CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjkyCiAgICAvLyByZXR1cm4gcmVzdWx0CiAgICByZXRzdWIKCgovLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjpQcmltaXRpdmVPcHNDb250cmFjdC52ZXJpZnlfdWludDY0X2x0KGE6IHVpbnQ2NCwgYjogdWludDY0KSAtPiB1aW50NjQ6CnZlcmlmeV91aW50NjRfbHQ6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjk1LTk2CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gcHVibGljIHZlcmlmeV91aW50NjRfbHQoYTogdWludDY0LCBiOiB1aW50NjQpOiBib29sZWFuIHsKICAgIHByb3RvIDIgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo5NwogICAgLy8gY29uc3QgcmVzdWx0ID0gYSA8IGIKICAgIGZyYW1lX2RpZyAtMgogICAgZnJhbWVfZGlnIC0xCiAgICA8CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjk4CiAgICAvLyByZXR1cm4gcmVzdWx0CiAgICByZXRzdWIKCgovLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjpQcmltaXRpdmVPcHNDb250cmFjdC52ZXJpZnlfdWludDY0X2xlKGE6IHVpbnQ2NCwgYjogdWludDY0KSAtPiB1aW50NjQ6CnZlcmlmeV91aW50NjRfbGU6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjEwMS0xMDIKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBwdWJsaWMgdmVyaWZ5X3VpbnQ2NF9sZShhOiB1aW50NjQsIGI6IHVpbnQ2NCk6IGJvb2xlYW4gewogICAgcHJvdG8gMiAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjEwMwogICAgLy8gY29uc3QgcmVzdWx0ID0gYSA8PSBiCiAgICBmcmFtZV9kaWcgLTIKICAgIGZyYW1lX2RpZyAtMQogICAgPD0KICAgIC8vIHRlc3RzL2FydGlmYWN0cy9wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTA0CiAgICAvLyByZXR1cm4gcmVzdWx0CiAgICByZXRzdWIKCgovLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjpQcmltaXRpdmVPcHNDb250cmFjdC52ZXJpZnlfdWludDY0X2d0KGE6IHVpbnQ2NCwgYjogdWludDY0KSAtPiB1aW50NjQ6CnZlcmlmeV91aW50NjRfZ3Q6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjEwNy0xMDgKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBwdWJsaWMgdmVyaWZ5X3VpbnQ2NF9ndChhOiB1aW50NjQsIGI6IHVpbnQ2NCk6IGJvb2xlYW4gewogICAgcHJvdG8gMiAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjEwOQogICAgLy8gY29uc3QgcmVzdWx0ID0gYSA+IGIKICAgIGZyYW1lX2RpZyAtMgogICAgZnJhbWVfZGlnIC0xCiAgICA+CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjExMAogICAgLy8gcmV0dXJuIHJlc3VsdAogICAgcmV0c3ViCgoKLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo6UHJpbWl0aXZlT3BzQ29udHJhY3QudmVyaWZ5X3VpbnQ2NF9nZShhOiB1aW50NjQsIGI6IHVpbnQ2NCkgLT4gdWludDY0Ogp2ZXJpZnlfdWludDY0X2dlOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoxMTMtMTE0CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gcHVibGljIHZlcmlmeV91aW50NjRfZ2UoYTogdWludDY0LCBiOiB1aW50NjQpOiBib29sZWFuIHsKICAgIHByb3RvIDIgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoxMTUKICAgIC8vIGNvbnN0IHJlc3VsdCA9IGEgPj0gYgogICAgZnJhbWVfZGlnIC0yCiAgICBmcmFtZV9kaWcgLTEKICAgID49CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjExNgogICAgLy8gcmV0dXJuIHJlc3VsdAogICAgcmV0c3ViCgoKLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo6UHJpbWl0aXZlT3BzQ29udHJhY3QudmVyaWZ5X2J5dGVzX2luaXQocmF3X3ZhbHVlOiB1aW50NjQpIC0+IGJ5dGVzOgp2ZXJpZnlfYnl0ZXNfaW5pdDoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTE5LTEyMAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIHB1YmxpYyB2ZXJpZnlfYnl0ZXNfaW5pdChyYXdfdmFsdWU6IHVpbnQ2NCk6IGJ5dGVzIHsKICAgIHByb3RvIDEgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoxMjEKICAgIC8vIGNvbnN0IHJlc3VsdCA9IG9wLml0b2IocmF3X3ZhbHVlKQogICAgZnJhbWVfZGlnIC0xCiAgICBpdG9iCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjEyMgogICAgLy8gcmV0dXJuIHJlc3VsdAogICAgcmV0c3ViCgoKLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo6UHJpbWl0aXZlT3BzQ29udHJhY3QudmVyaWZ5X2J5dGVzX2FkZChhOiBieXRlcywgYjogYnl0ZXMsIHBhZF9hX3NpemU6IHVpbnQ2NCwgcGFkX2Jfc2l6ZTogdWludDY0KSAtPiBieXRlczoKdmVyaWZ5X2J5dGVzX2FkZDoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTI1LTEyNgogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIHB1YmxpYyB2ZXJpZnlfYnl0ZXNfYWRkKGE6IGJ5dGVzLCBiOiBieXRlcywgcGFkX2Ffc2l6ZTogdWludDY0LCBwYWRfYl9zaXplOiB1aW50NjQpOiBieXRlcyB7CiAgICBwcm90byA0IDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTI3CiAgICAvLyBjb25zdCBwYWRkZWRBID0gb3AuYnplcm8ocGFkX2Ffc2l6ZSkuY29uY2F0KGEpCiAgICBmcmFtZV9kaWcgLTIKICAgIGJ6ZXJvCiAgICBmcmFtZV9kaWcgLTQKICAgIGNvbmNhdAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoxMjgKICAgIC8vIGNvbnN0IHBhZGRlZEIgPSBvcC5iemVybyhwYWRfYl9zaXplKS5jb25jYXQoYikKICAgIGZyYW1lX2RpZyAtMQogICAgYnplcm8KICAgIGZyYW1lX2RpZyAtMwogICAgY29uY2F0CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjEyOQogICAgLy8gY29uc3QgcmVzdWx0ID0gcGFkZGVkQS5jb25jYXQocGFkZGVkQikKICAgIGNvbmNhdAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoxMzAKICAgIC8vIGNvbnN0IHJlc3VsdEhhc2ggPSBvcC5zaGEyNTYocmVzdWx0KQogICAgc2hhMjU2CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjEzMQogICAgLy8gcmV0dXJuIHJlc3VsdEhhc2gKICAgIHJldHN1YgoKCi8vIHRlc3RzL2FydGlmYWN0cy9wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OlByaW1pdGl2ZU9wc0NvbnRyYWN0LnZlcmlmeV9ieXRlc19lcShhOiBieXRlcywgYjogYnl0ZXMpIC0+IHVpbnQ2NDoKdmVyaWZ5X2J5dGVzX2VxOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoxMzQtMTM1CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gcHVibGljIHZlcmlmeV9ieXRlc19lcShhOiBieXRlcywgYjogYnl0ZXMpOiBib29sZWFuIHsKICAgIHByb3RvIDIgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoxMzYKICAgIC8vIGNvbnN0IHJlc3VsdCA9IGEgPT09IGIKICAgIGZyYW1lX2RpZyAtMgogICAgZnJhbWVfZGlnIC0xCiAgICA9PQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoxMzcKICAgIC8vIHJldHVybiByZXN1bHQKICAgIHJldHN1YgoKCi8vIHRlc3RzL2FydGlmYWN0cy9wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OlByaW1pdGl2ZU9wc0NvbnRyYWN0LnZlcmlmeV9ieXRlc19uZShhOiBieXRlcywgYjogYnl0ZXMpIC0+IHVpbnQ2NDoKdmVyaWZ5X2J5dGVzX25lOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoxNDAtMTQxCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gcHVibGljIHZlcmlmeV9ieXRlc19uZShhOiBieXRlcywgYjogYnl0ZXMpOiBib29sZWFuIHsKICAgIHByb3RvIDIgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoxNDIKICAgIC8vIGNvbnN0IHJlc3VsdCA9IGEgIT09IGIKICAgIGZyYW1lX2RpZyAtMgogICAgZnJhbWVfZGlnIC0xCiAgICAhPQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoxNDMKICAgIC8vIHJldHVybiByZXN1bHQKICAgIHJldHN1YgoKCi8vIHRlc3RzL2FydGlmYWN0cy9wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OlByaW1pdGl2ZU9wc0NvbnRyYWN0LnZlcmlmeV9ieXRlc19hbmQoYTogYnl0ZXMsIGI6IGJ5dGVzKSAtPiBieXRlczoKdmVyaWZ5X2J5dGVzX2FuZDoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTQ2LTE0NwogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIHB1YmxpYyB2ZXJpZnlfYnl0ZXNfYW5kKGE6IGJ5dGVzLCBiOiBieXRlcyk6IGJ5dGVzIHsKICAgIHByb3RvIDIgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoxNDgKICAgIC8vIGNvbnN0IHJlc3VsdCA9IGEuYml0d2lzZUFuZChiKQogICAgZnJhbWVfZGlnIC0yCiAgICBmcmFtZV9kaWcgLTEKICAgIGImCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjE0OQogICAgLy8gcmV0dXJuIHJlc3VsdAogICAgcmV0c3ViCgoKLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo6UHJpbWl0aXZlT3BzQ29udHJhY3QudmVyaWZ5X2J5dGVzX29yKGE6IGJ5dGVzLCBiOiBieXRlcykgLT4gYnl0ZXM6CnZlcmlmeV9ieXRlc19vcjoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTUyLTE1MwogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIHB1YmxpYyB2ZXJpZnlfYnl0ZXNfb3IoYTogYnl0ZXMsIGI6IGJ5dGVzKTogYnl0ZXMgewogICAgcHJvdG8gMiAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjE1NAogICAgLy8gY29uc3QgcmVzdWx0ID0gYS5iaXR3aXNlT3IoYikKICAgIGZyYW1lX2RpZyAtMgogICAgZnJhbWVfZGlnIC0xCiAgICBifAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoxNTUKICAgIC8vIHJldHVybiByZXN1bHQKICAgIHJldHN1YgoKCi8vIHRlc3RzL2FydGlmYWN0cy9wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OlByaW1pdGl2ZU9wc0NvbnRyYWN0LnZlcmlmeV9ieXRlc194b3IoYTogYnl0ZXMsIGI6IGJ5dGVzKSAtPiBieXRlczoKdmVyaWZ5X2J5dGVzX3hvcjoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTU4LTE1OQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIHB1YmxpYyB2ZXJpZnlfYnl0ZXNfeG9yKGE6IGJ5dGVzLCBiOiBieXRlcyk6IGJ5dGVzIHsKICAgIHByb3RvIDIgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoxNjAKICAgIC8vIGNvbnN0IHJlc3VsdCA9IGEuYml0d2lzZVhvcihiKQogICAgZnJhbWVfZGlnIC0yCiAgICBmcmFtZV9kaWcgLTEKICAgIGJeCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjE2MQogICAgLy8gcmV0dXJuIHJlc3VsdAogICAgcmV0c3ViCgoKLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo6UHJpbWl0aXZlT3BzQ29udHJhY3QudmVyaWZ5X2J5dGVzX25vdChhOiBieXRlcywgcGFkX3NpemU6IHVpbnQ2NCkgLT4gYnl0ZXM6CnZlcmlmeV9ieXRlc19ub3Q6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjE2NC0xNjUKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBwdWJsaWMgdmVyaWZ5X2J5dGVzX25vdChhOiBieXRlcywgcGFkX3NpemU6IHVpbnQ2NCk6IGJ5dGVzIHsKICAgIHByb3RvIDIgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoxNjYKICAgIC8vIGNvbnN0IHBhZGRlZEEgPSBvcC5iemVybyhwYWRfc2l6ZSkuY29uY2F0KGEpCiAgICBmcmFtZV9kaWcgLTEKICAgIGJ6ZXJvCiAgICBmcmFtZV9kaWcgLTIKICAgIGNvbmNhdAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoxNjcKICAgIC8vIGNvbnN0IHJlc3VsdCA9IHBhZGRlZEEuYml0d2lzZUludmVydCgpCiAgICBifgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoxNjgKICAgIC8vIGNvbnN0IHJlc3VsdEhhc2ggPSBvcC5zaGEyNTYocmVzdWx0KQogICAgc2hhMjU2CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjE2OQogICAgLy8gcmV0dXJuIHJlc3VsdEhhc2gKICAgIHJldHN1YgoKCi8vIHRlc3RzL2FydGlmYWN0cy9wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OlByaW1pdGl2ZU9wc0NvbnRyYWN0LnZlcmlmeV9iaWd1aW50X2FkZChhOiBieXRlcywgYjogYnl0ZXMpIC0+IGJ5dGVzOgp2ZXJpZnlfYmlndWludF9hZGQ6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjE3Mi0xNzMKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBwdWJsaWMgdmVyaWZ5X2JpZ3VpbnRfYWRkKGE6IGJ5dGVzLCBiOiBieXRlcyk6IGJ5dGVzIHsKICAgIHByb3RvIDIgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoxNzYKICAgIC8vIGNvbnN0IHJlc3VsdDogYmlndWludCA9IGFfYmlndWludCArIGJfYmlndWludAogICAgZnJhbWVfZGlnIC0yCiAgICBmcmFtZV9kaWcgLTEKICAgIGIrCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjE3NwogICAgLy8gcmV0dXJuIEJ5dGVzKHJlc3VsdCkKICAgIHJldHN1YgoKCi8vIHRlc3RzL2FydGlmYWN0cy9wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OlByaW1pdGl2ZU9wc0NvbnRyYWN0LnZlcmlmeV9iaWd1aW50X2FkZF91aW50NjQoYTogYnl0ZXMsIGI6IHVpbnQ2NCkgLT4gYnl0ZXM6CnZlcmlmeV9iaWd1aW50X2FkZF91aW50NjQ6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjE4MC0xODEKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBwdWJsaWMgdmVyaWZ5X2JpZ3VpbnRfYWRkX3VpbnQ2NChhOiBieXRlcywgYjogdWludDY0KTogYnl0ZXMgewogICAgcHJvdG8gMiAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjE4MwogICAgLy8gY29uc3QgYl9iaWd1aW50ID0gQmlnVWludChiKQogICAgZnJhbWVfZGlnIC0xCiAgICBpdG9iCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjE4NAogICAgLy8gY29uc3QgcmVzdWx0OiBiaWd1aW50ID0gYV9iaWd1aW50ICsgYl9iaWd1aW50CiAgICBmcmFtZV9kaWcgLTIKICAgIGIrCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjE4NQogICAgLy8gcmV0dXJuIEJ5dGVzKHJlc3VsdCkKICAgIHJldHN1YgoKCi8vIHRlc3RzL2FydGlmYWN0cy9wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OlByaW1pdGl2ZU9wc0NvbnRyYWN0LnZlcmlmeV9iaWd1aW50X3N1YihhOiBieXRlcywgYjogYnl0ZXMpIC0+IGJ5dGVzOgp2ZXJpZnlfYmlndWludF9zdWI6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjE4OC0xODkKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBwdWJsaWMgdmVyaWZ5X2JpZ3VpbnRfc3ViKGE6IGJ5dGVzLCBiOiBieXRlcyk6IGJ5dGVzIHsKICAgIHByb3RvIDIgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoxOTIKICAgIC8vIGNvbnN0IHJlc3VsdDogYmlndWludCA9IGFfYmlndWludCAtIGJfYmlndWludAogICAgZnJhbWVfZGlnIC0yCiAgICBmcmFtZV9kaWcgLTEKICAgIGItCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjE5MwogICAgLy8gcmV0dXJuIEJ5dGVzKHJlc3VsdCkKICAgIHJldHN1YgoKCi8vIHRlc3RzL2FydGlmYWN0cy9wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OlByaW1pdGl2ZU9wc0NvbnRyYWN0LnZlcmlmeV9iaWd1aW50X3N1Yl91aW50NjQoYTogYnl0ZXMsIGI6IHVpbnQ2NCkgLT4gYnl0ZXM6CnZlcmlmeV9iaWd1aW50X3N1Yl91aW50NjQ6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjE5Ni0xOTcKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBwdWJsaWMgdmVyaWZ5X2JpZ3VpbnRfc3ViX3VpbnQ2NChhOiBieXRlcywgYjogdWludDY0KTogYnl0ZXMgewogICAgcHJvdG8gMiAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjE5OQogICAgLy8gY29uc3QgYl9iaWd1aW50ID0gQmlnVWludChiKQogICAgZnJhbWVfZGlnIC0xCiAgICBpdG9iCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjIwMAogICAgLy8gY29uc3QgcmVzdWx0OiBiaWd1aW50ID0gYV9iaWd1aW50IC0gYl9iaWd1aW50CiAgICBmcmFtZV9kaWcgLTIKICAgIHN3YXAKICAgIGItCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjIwMQogICAgLy8gcmV0dXJuIEJ5dGVzKHJlc3VsdCkKICAgIHJldHN1YgoKCi8vIHRlc3RzL2FydGlmYWN0cy9wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OlByaW1pdGl2ZU9wc0NvbnRyYWN0LnZlcmlmeV9iaWd1aW50X211bChhOiBieXRlcywgYjogYnl0ZXMpIC0+IGJ5dGVzOgp2ZXJpZnlfYmlndWludF9tdWw6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjIwNC0yMDUKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBwdWJsaWMgdmVyaWZ5X2JpZ3VpbnRfbXVsKGE6IGJ5dGVzLCBiOiBieXRlcyk6IGJ5dGVzIHsKICAgIHByb3RvIDIgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoyMDgKICAgIC8vIGNvbnN0IHJlc3VsdDogYmlndWludCA9IGFfYmlndWludCAqIGJfYmlndWludAogICAgZnJhbWVfZGlnIC0yCiAgICBmcmFtZV9kaWcgLTEKICAgIGIqCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjIwOQogICAgLy8gcmV0dXJuIEJ5dGVzKHJlc3VsdCkKICAgIHJldHN1YgoKCi8vIHRlc3RzL2FydGlmYWN0cy9wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OlByaW1pdGl2ZU9wc0NvbnRyYWN0LnZlcmlmeV9iaWd1aW50X211bF91aW50NjQoYTogYnl0ZXMsIGI6IHVpbnQ2NCkgLT4gYnl0ZXM6CnZlcmlmeV9iaWd1aW50X211bF91aW50NjQ6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjIxMi0yMTMKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBwdWJsaWMgdmVyaWZ5X2JpZ3VpbnRfbXVsX3VpbnQ2NChhOiBieXRlcywgYjogdWludDY0KTogYnl0ZXMgewogICAgcHJvdG8gMiAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjIxNQogICAgLy8gY29uc3QgYl9iaWd1aW50ID0gQmlnVWludChiKQogICAgZnJhbWVfZGlnIC0xCiAgICBpdG9iCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjIxNgogICAgLy8gY29uc3QgcmVzdWx0OiBiaWd1aW50ID0gYV9iaWd1aW50ICogYl9iaWd1aW50CiAgICBmcmFtZV9kaWcgLTIKICAgIGIqCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjIxNwogICAgLy8gcmV0dXJuIEJ5dGVzKHJlc3VsdCkKICAgIHJldHN1YgoKCi8vIHRlc3RzL2FydGlmYWN0cy9wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OlByaW1pdGl2ZU9wc0NvbnRyYWN0LnZlcmlmeV9iaWd1aW50X2RpdihhOiBieXRlcywgYjogYnl0ZXMpIC0+IGJ5dGVzOgp2ZXJpZnlfYmlndWludF9kaXY6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjIyMC0yMjEKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBwdWJsaWMgdmVyaWZ5X2JpZ3VpbnRfZGl2KGE6IGJ5dGVzLCBiOiBieXRlcyk6IGJ5dGVzIHsKICAgIHByb3RvIDIgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoyMjQKICAgIC8vIGNvbnN0IHJlc3VsdDogYmlndWludCA9IGFfYmlndWludCAvIGJfYmlndWludAogICAgZnJhbWVfZGlnIC0yCiAgICBmcmFtZV9kaWcgLTEKICAgIGIvCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjIyNQogICAgLy8gcmV0dXJuIEJ5dGVzKHJlc3VsdCkKICAgIHJldHN1YgoKCi8vIHRlc3RzL2FydGlmYWN0cy9wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OlByaW1pdGl2ZU9wc0NvbnRyYWN0LnZlcmlmeV9iaWd1aW50X2Rpdl91aW50NjQoYTogYnl0ZXMsIGI6IHVpbnQ2NCkgLT4gYnl0ZXM6CnZlcmlmeV9iaWd1aW50X2Rpdl91aW50NjQ6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjIyOC0yMjkKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBwdWJsaWMgdmVyaWZ5X2JpZ3VpbnRfZGl2X3VpbnQ2NChhOiBieXRlcywgYjogdWludDY0KTogYnl0ZXMgewogICAgcHJvdG8gMiAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjIzMQogICAgLy8gY29uc3QgYl9iaWd1aW50ID0gQmlnVWludChiKQogICAgZnJhbWVfZGlnIC0xCiAgICBpdG9iCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjIzMgogICAgLy8gY29uc3QgcmVzdWx0OiBiaWd1aW50ID0gYV9iaWd1aW50IC8gYl9iaWd1aW50CiAgICBmcmFtZV9kaWcgLTIKICAgIHN3YXAKICAgIGIvCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjIzMwogICAgLy8gcmV0dXJuIEJ5dGVzKHJlc3VsdCkKICAgIHJldHN1YgoKCi8vIHRlc3RzL2FydGlmYWN0cy9wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OlByaW1pdGl2ZU9wc0NvbnRyYWN0LnZlcmlmeV9iaWd1aW50X21vZChhOiBieXRlcywgYjogYnl0ZXMpIC0+IGJ5dGVzOgp2ZXJpZnlfYmlndWludF9tb2Q6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjIzNi0yMzcKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBwdWJsaWMgdmVyaWZ5X2JpZ3VpbnRfbW9kKGE6IGJ5dGVzLCBiOiBieXRlcyk6IGJ5dGVzIHsKICAgIHByb3RvIDIgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoyNDAKICAgIC8vIGNvbnN0IHJlc3VsdDogYmlndWludCA9IGFfYmlndWludCAlIGJfYmlndWludAogICAgZnJhbWVfZGlnIC0yCiAgICBmcmFtZV9kaWcgLTEKICAgIGIlCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjI0MQogICAgLy8gcmV0dXJuIEJ5dGVzKHJlc3VsdCkKICAgIHJldHN1YgoKCi8vIHRlc3RzL2FydGlmYWN0cy9wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OlByaW1pdGl2ZU9wc0NvbnRyYWN0LnZlcmlmeV9iaWd1aW50X21vZF91aW50NjQoYTogYnl0ZXMsIGI6IHVpbnQ2NCkgLT4gYnl0ZXM6CnZlcmlmeV9iaWd1aW50X21vZF91aW50NjQ6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjI0NC0yNDUKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBwdWJsaWMgdmVyaWZ5X2JpZ3VpbnRfbW9kX3VpbnQ2NChhOiBieXRlcywgYjogdWludDY0KTogYnl0ZXMgewogICAgcHJvdG8gMiAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjI0NwogICAgLy8gY29uc3QgYl9iaWd1aW50ID0gQmlnVWludChiKQogICAgZnJhbWVfZGlnIC0xCiAgICBpdG9iCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjI0OAogICAgLy8gY29uc3QgcmVzdWx0OiBiaWd1aW50ID0gYV9iaWd1aW50ICUgYl9iaWd1aW50CiAgICBmcmFtZV9kaWcgLTIKICAgIHN3YXAKICAgIGIlCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjI0OQogICAgLy8gcmV0dXJuIEJ5dGVzKHJlc3VsdCkKICAgIHJldHN1YgoKCi8vIHRlc3RzL2FydGlmYWN0cy9wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OlByaW1pdGl2ZU9wc0NvbnRyYWN0LnZlcmlmeV9iaWd1aW50X2FuZChhOiBieXRlcywgYjogYnl0ZXMpIC0+IGJ5dGVzOgp2ZXJpZnlfYmlndWludF9hbmQ6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjI1Mi0yNTMKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBwdWJsaWMgdmVyaWZ5X2JpZ3VpbnRfYW5kKGE6IGJ5dGVzLCBiOiBieXRlcyk6IGJ5dGVzIHsKICAgIHByb3RvIDIgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoyNTYKICAgIC8vIGNvbnN0IHJlc3VsdDogYmlndWludCA9IGFfYmlndWludCAmIGJfYmlndWludAogICAgZnJhbWVfZGlnIC0yCiAgICBmcmFtZV9kaWcgLTEKICAgIGImCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjI1NwogICAgLy8gcmV0dXJuIEJ5dGVzKHJlc3VsdCkKICAgIHJldHN1YgoKCi8vIHRlc3RzL2FydGlmYWN0cy9wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OlByaW1pdGl2ZU9wc0NvbnRyYWN0LnZlcmlmeV9iaWd1aW50X2FuZF91aW50NjQoYTogYnl0ZXMsIGI6IHVpbnQ2NCkgLT4gYnl0ZXM6CnZlcmlmeV9iaWd1aW50X2FuZF91aW50NjQ6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjI2MC0yNjEKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBwdWJsaWMgdmVyaWZ5X2JpZ3VpbnRfYW5kX3VpbnQ2NChhOiBieXRlcywgYjogdWludDY0KTogYnl0ZXMgewogICAgcHJvdG8gMiAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjI2MwogICAgLy8gY29uc3QgYl9iaWd1aW50ID0gQmlnVWludChiKQogICAgZnJhbWVfZGlnIC0xCiAgICBpdG9iCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjI2NAogICAgLy8gY29uc3QgcmVzdWx0OiBiaWd1aW50ID0gYV9iaWd1aW50ICYgYl9iaWd1aW50CiAgICBmcmFtZV9kaWcgLTIKICAgIGImCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjI2NQogICAgLy8gcmV0dXJuIEJ5dGVzKHJlc3VsdCkKICAgIHJldHN1YgoKCi8vIHRlc3RzL2FydGlmYWN0cy9wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OlByaW1pdGl2ZU9wc0NvbnRyYWN0LnZlcmlmeV9iaWd1aW50X29yKGE6IGJ5dGVzLCBiOiBieXRlcykgLT4gYnl0ZXM6CnZlcmlmeV9iaWd1aW50X29yOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoyNjgtMjY5CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gcHVibGljIHZlcmlmeV9iaWd1aW50X29yKGE6IGJ5dGVzLCBiOiBieXRlcyk6IGJ5dGVzIHsKICAgIHByb3RvIDIgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoyNzIKICAgIC8vIGNvbnN0IHJlc3VsdDogYmlndWludCA9IGFfYmlndWludCB8IGJfYmlndWludAogICAgZnJhbWVfZGlnIC0yCiAgICBmcmFtZV9kaWcgLTEKICAgIGJ8CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjI3MwogICAgLy8gcmV0dXJuIEJ5dGVzKHJlc3VsdCkKICAgIHJldHN1YgoKCi8vIHRlc3RzL2FydGlmYWN0cy9wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OlByaW1pdGl2ZU9wc0NvbnRyYWN0LnZlcmlmeV9iaWd1aW50X29yX3VpbnQ2NChhOiBieXRlcywgYjogdWludDY0KSAtPiBieXRlczoKdmVyaWZ5X2JpZ3VpbnRfb3JfdWludDY0OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoyNzYtMjc3CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gcHVibGljIHZlcmlmeV9iaWd1aW50X29yX3VpbnQ2NChhOiBieXRlcywgYjogdWludDY0KTogYnl0ZXMgewogICAgcHJvdG8gMiAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjI3OQogICAgLy8gY29uc3QgYl9iaWd1aW50ID0gQmlnVWludChiKQogICAgZnJhbWVfZGlnIC0xCiAgICBpdG9iCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjI4MAogICAgLy8gY29uc3QgcmVzdWx0OiBiaWd1aW50ID0gYV9iaWd1aW50IHwgYl9iaWd1aW50CiAgICBmcmFtZV9kaWcgLTIKICAgIGJ8CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjI4MQogICAgLy8gcmV0dXJuIEJ5dGVzKHJlc3VsdCkKICAgIHJldHN1YgoKCi8vIHRlc3RzL2FydGlmYWN0cy9wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OlByaW1pdGl2ZU9wc0NvbnRyYWN0LnZlcmlmeV9iaWd1aW50X3hvcihhOiBieXRlcywgYjogYnl0ZXMpIC0+IGJ5dGVzOgp2ZXJpZnlfYmlndWludF94b3I6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjI4NC0yODUKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBwdWJsaWMgdmVyaWZ5X2JpZ3VpbnRfeG9yKGE6IGJ5dGVzLCBiOiBieXRlcyk6IGJ5dGVzIHsKICAgIHByb3RvIDIgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoyODgKICAgIC8vIGNvbnN0IHJlc3VsdDogYmlndWludCA9IGFfYmlndWludCBeIGJfYmlndWludAogICAgZnJhbWVfZGlnIC0yCiAgICBmcmFtZV9kaWcgLTEKICAgIGJeCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjI4OQogICAgLy8gcmV0dXJuIEJ5dGVzKHJlc3VsdCkKICAgIHJldHN1YgoKCi8vIHRlc3RzL2FydGlmYWN0cy9wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OlByaW1pdGl2ZU9wc0NvbnRyYWN0LnZlcmlmeV9iaWd1aW50X3hvcl91aW50NjQoYTogYnl0ZXMsIGI6IHVpbnQ2NCkgLT4gYnl0ZXM6CnZlcmlmeV9iaWd1aW50X3hvcl91aW50NjQ6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjI5Mi0yOTMKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBwdWJsaWMgdmVyaWZ5X2JpZ3VpbnRfeG9yX3VpbnQ2NChhOiBieXRlcywgYjogdWludDY0KTogYnl0ZXMgewogICAgcHJvdG8gMiAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjI5NQogICAgLy8gY29uc3QgYl9iaWd1aW50ID0gQmlnVWludChiKQogICAgZnJhbWVfZGlnIC0xCiAgICBpdG9iCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjI5NgogICAgLy8gY29uc3QgcmVzdWx0OiBiaWd1aW50ID0gYV9iaWd1aW50IF4gYl9iaWd1aW50CiAgICBmcmFtZV9kaWcgLTIKICAgIGJeCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjI5NwogICAgLy8gcmV0dXJuIEJ5dGVzKHJlc3VsdCkKICAgIHJldHN1YgoKCi8vIHRlc3RzL2FydGlmYWN0cy9wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OlByaW1pdGl2ZU9wc0NvbnRyYWN0LnZlcmlmeV9iaWd1aW50X2VxKGE6IGJ5dGVzLCBiOiBieXRlcykgLT4gdWludDY0Ogp2ZXJpZnlfYmlndWludF9lcToKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MzAwLTMwMQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIHB1YmxpYyB2ZXJpZnlfYmlndWludF9lcShhOiBieXRlcywgYjogYnl0ZXMpOiBib29sZWFuIHsKICAgIHByb3RvIDIgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czozMDQKICAgIC8vIGNvbnN0IHJlc3VsdCA9IGFfYmlndWludCA9PT0gYl9iaWd1aW50CiAgICBmcmFtZV9kaWcgLTIKICAgIGZyYW1lX2RpZyAtMQogICAgYj09CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjMwNQogICAgLy8gcmV0dXJuIHJlc3VsdAogICAgcmV0c3ViCgoKLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo6UHJpbWl0aXZlT3BzQ29udHJhY3QudmVyaWZ5X2JpZ3VpbnRfZXFfdWludDY0KGE6IGJ5dGVzLCBiOiB1aW50NjQpIC0+IHVpbnQ2NDoKdmVyaWZ5X2JpZ3VpbnRfZXFfdWludDY0OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czozMDgtMzA5CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gcHVibGljIHZlcmlmeV9iaWd1aW50X2VxX3VpbnQ2NChhOiBieXRlcywgYjogdWludDY0KTogYm9vbGVhbiB7CiAgICBwcm90byAyIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MzExCiAgICAvLyBjb25zdCByZXN1bHQgPSBhX2JpZ3VpbnQgPT09IEJpZ1VpbnQoYikKICAgIGZyYW1lX2RpZyAtMQogICAgaXRvYgogICAgZnJhbWVfZGlnIC0yCiAgICBiPT0KICAgIC8vIHRlc3RzL2FydGlmYWN0cy9wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MzEyCiAgICAvLyByZXR1cm4gcmVzdWx0CiAgICByZXRzdWIKCgovLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjpQcmltaXRpdmVPcHNDb250cmFjdC52ZXJpZnlfYmlndWludF9uZShhOiBieXRlcywgYjogYnl0ZXMpIC0+IHVpbnQ2NDoKdmVyaWZ5X2JpZ3VpbnRfbmU6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjMxNS0zMTYKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBwdWJsaWMgdmVyaWZ5X2JpZ3VpbnRfbmUoYTogYnl0ZXMsIGI6IGJ5dGVzKTogYm9vbGVhbiB7CiAgICBwcm90byAyIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MzE5CiAgICAvLyBjb25zdCByZXN1bHQgPSBhX2JpZ3VpbnQgIT09IGJfYmlndWludAogICAgZnJhbWVfZGlnIC0yCiAgICBmcmFtZV9kaWcgLTEKICAgIGIhPQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czozMjAKICAgIC8vIHJldHVybiByZXN1bHQKICAgIHJldHN1YgoKCi8vIHRlc3RzL2FydGlmYWN0cy9wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OlByaW1pdGl2ZU9wc0NvbnRyYWN0LnZlcmlmeV9iaWd1aW50X25lX3VpbnQ2NChhOiBieXRlcywgYjogdWludDY0KSAtPiB1aW50NjQ6CnZlcmlmeV9iaWd1aW50X25lX3VpbnQ2NDoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MzIzLTMyNAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIHB1YmxpYyB2ZXJpZnlfYmlndWludF9uZV91aW50NjQoYTogYnl0ZXMsIGI6IHVpbnQ2NCk6IGJvb2xlYW4gewogICAgcHJvdG8gMiAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjMyNgogICAgLy8gY29uc3QgcmVzdWx0ID0gYV9iaWd1aW50ICE9PSBCaWdVaW50KGIpCiAgICBmcmFtZV9kaWcgLTEKICAgIGl0b2IKICAgIGZyYW1lX2RpZyAtMgogICAgYiE9CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjMyNwogICAgLy8gcmV0dXJuIHJlc3VsdAogICAgcmV0c3ViCgoKLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo6UHJpbWl0aXZlT3BzQ29udHJhY3QudmVyaWZ5X2JpZ3VpbnRfbHQoYTogYnl0ZXMsIGI6IGJ5dGVzKSAtPiB1aW50NjQ6CnZlcmlmeV9iaWd1aW50X2x0OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czozMzAtMzMxCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gcHVibGljIHZlcmlmeV9iaWd1aW50X2x0KGE6IGJ5dGVzLCBiOiBieXRlcyk6IGJvb2xlYW4gewogICAgcHJvdG8gMiAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjMzNAogICAgLy8gY29uc3QgcmVzdWx0ID0gYV9iaWd1aW50IDwgYl9iaWd1aW50CiAgICBmcmFtZV9kaWcgLTIKICAgIGZyYW1lX2RpZyAtMQogICAgYjwKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MzM1CiAgICAvLyByZXR1cm4gcmVzdWx0CiAgICByZXRzdWIKCgovLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjpQcmltaXRpdmVPcHNDb250cmFjdC52ZXJpZnlfYmlndWludF9sdF91aW50NjQoYTogYnl0ZXMsIGI6IHVpbnQ2NCkgLT4gdWludDY0Ogp2ZXJpZnlfYmlndWludF9sdF91aW50NjQ6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjMzOC0zMzkKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBwdWJsaWMgdmVyaWZ5X2JpZ3VpbnRfbHRfdWludDY0KGE6IGJ5dGVzLCBiOiB1aW50NjQpOiBib29sZWFuIHsKICAgIHByb3RvIDIgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czozNDEKICAgIC8vIGNvbnN0IGJfYmlndWludCA9IEJpZ1VpbnQoYikKICAgIGZyYW1lX2RpZyAtMQogICAgaXRvYgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czozNDIKICAgIC8vIGNvbnN0IHJlc3VsdCA9IGFfYmlndWludCA8IGJfYmlndWludAogICAgZnJhbWVfZGlnIC0yCiAgICBiPgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czozNDMKICAgIC8vIHJldHVybiByZXN1bHQKICAgIHJldHN1YgoKCi8vIHRlc3RzL2FydGlmYWN0cy9wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OlByaW1pdGl2ZU9wc0NvbnRyYWN0LnZlcmlmeV9iaWd1aW50X2xlKGE6IGJ5dGVzLCBiOiBieXRlcykgLT4gdWludDY0Ogp2ZXJpZnlfYmlndWludF9sZToKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MzQ2LTM0NwogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIHB1YmxpYyB2ZXJpZnlfYmlndWludF9sZShhOiBieXRlcywgYjogYnl0ZXMpOiBib29sZWFuIHsKICAgIHByb3RvIDIgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czozNTAKICAgIC8vIGNvbnN0IHJlc3VsdCA9IGFfYmlndWludCA8PSBiX2JpZ3VpbnQKICAgIGZyYW1lX2RpZyAtMgogICAgZnJhbWVfZGlnIC0xCiAgICBiPD0KICAgIC8vIHRlc3RzL2FydGlmYWN0cy9wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MzUxCiAgICAvLyByZXR1cm4gcmVzdWx0CiAgICByZXRzdWIKCgovLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjpQcmltaXRpdmVPcHNDb250cmFjdC52ZXJpZnlfYmlndWludF9sZV91aW50NjQoYTogYnl0ZXMsIGI6IHVpbnQ2NCkgLT4gdWludDY0Ogp2ZXJpZnlfYmlndWludF9sZV91aW50NjQ6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjM1NC0zNTUKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBwdWJsaWMgdmVyaWZ5X2JpZ3VpbnRfbGVfdWludDY0KGE6IGJ5dGVzLCBiOiB1aW50NjQpOiBib29sZWFuIHsKICAgIHByb3RvIDIgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czozNTcKICAgIC8vIGNvbnN0IGJfYmlndWludCA9IEJpZ1VpbnQoYikKICAgIGZyYW1lX2RpZyAtMQogICAgaXRvYgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czozNTgKICAgIC8vIGNvbnN0IHJlc3VsdCA9IGFfYmlndWludCA8PSBiX2JpZ3VpbnQKICAgIGZyYW1lX2RpZyAtMgogICAgYj49CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjM1OQogICAgLy8gcmV0dXJuIHJlc3VsdAogICAgcmV0c3ViCgoKLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo6UHJpbWl0aXZlT3BzQ29udHJhY3QudmVyaWZ5X2JpZ3VpbnRfZ3QoYTogYnl0ZXMsIGI6IGJ5dGVzKSAtPiB1aW50NjQ6CnZlcmlmeV9iaWd1aW50X2d0OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czozNjItMzYzCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gcHVibGljIHZlcmlmeV9iaWd1aW50X2d0KGE6IGJ5dGVzLCBiOiBieXRlcyk6IGJvb2xlYW4gewogICAgcHJvdG8gMiAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjM2NgogICAgLy8gY29uc3QgcmVzdWx0ID0gYV9iaWd1aW50ID4gYl9iaWd1aW50CiAgICBmcmFtZV9kaWcgLTIKICAgIGZyYW1lX2RpZyAtMQogICAgYj4KICAgIC8vIHRlc3RzL2FydGlmYWN0cy9wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MzY3CiAgICAvLyByZXR1cm4gcmVzdWx0CiAgICByZXRzdWIKCgovLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjpQcmltaXRpdmVPcHNDb250cmFjdC52ZXJpZnlfYmlndWludF9ndF91aW50NjQoYTogYnl0ZXMsIGI6IHVpbnQ2NCkgLT4gdWludDY0Ogp2ZXJpZnlfYmlndWludF9ndF91aW50NjQ6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjM3MC0zNzEKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBwdWJsaWMgdmVyaWZ5X2JpZ3VpbnRfZ3RfdWludDY0KGE6IGJ5dGVzLCBiOiB1aW50NjQpOiBib29sZWFuIHsKICAgIHByb3RvIDIgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czozNzMKICAgIC8vIGNvbnN0IGJfYmlndWludCA9IEJpZ1VpbnQoYikKICAgIGZyYW1lX2RpZyAtMQogICAgaXRvYgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czozNzQKICAgIC8vIGNvbnN0IHJlc3VsdCA9IGFfYmlndWludCA+IGJfYmlndWludAogICAgZnJhbWVfZGlnIC0yCiAgICBiPAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czozNzUKICAgIC8vIHJldHVybiByZXN1bHQKICAgIHJldHN1YgoKCi8vIHRlc3RzL2FydGlmYWN0cy9wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OlByaW1pdGl2ZU9wc0NvbnRyYWN0LnZlcmlmeV9iaWd1aW50X2dlKGE6IGJ5dGVzLCBiOiBieXRlcykgLT4gdWludDY0Ogp2ZXJpZnlfYmlndWludF9nZToKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6Mzc4LTM3OQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIHB1YmxpYyB2ZXJpZnlfYmlndWludF9nZShhOiBieXRlcywgYjogYnl0ZXMpOiBib29sZWFuIHsKICAgIHByb3RvIDIgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czozODIKICAgIC8vIGNvbnN0IHJlc3VsdCA9IGFfYmlndWludCA+PSBiX2JpZ3VpbnQKICAgIGZyYW1lX2RpZyAtMgogICAgZnJhbWVfZGlnIC0xCiAgICBiPj0KICAgIC8vIHRlc3RzL2FydGlmYWN0cy9wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MzgzCiAgICAvLyByZXR1cm4gcmVzdWx0CiAgICByZXRzdWIKCgovLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjpQcmltaXRpdmVPcHNDb250cmFjdC52ZXJpZnlfYmlndWludF9nZV91aW50NjQoYTogYnl0ZXMsIGI6IHVpbnQ2NCkgLT4gdWludDY0Ogp2ZXJpZnlfYmlndWludF9nZV91aW50NjQ6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjM4Ni0zODcKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBwdWJsaWMgdmVyaWZ5X2JpZ3VpbnRfZ2VfdWludDY0KGE6IGJ5dGVzLCBiOiB1aW50NjQpOiBib29sZWFuIHsKICAgIHByb3RvIDIgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czozODkKICAgIC8vIGNvbnN0IGJfYmlndWludCA9IEJpZ1VpbnQoYikKICAgIGZyYW1lX2RpZyAtMQogICAgaXRvYgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czozOTAKICAgIC8vIGNvbnN0IHJlc3VsdCA9IGFfYmlndWludCA+PSBiX2JpZ3VpbnQKICAgIGZyYW1lX2RpZyAtMgogICAgYjw9CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjM5MQogICAgLy8gcmV0dXJuIHJlc3VsdAogICAgcmV0c3ViCgoKLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo6UHJpbWl0aXZlT3BzQ29udHJhY3QudmVyaWZ5X2xvZyhhOiBieXRlcywgYjogdWludDY0LCBjOiBieXRlcywgZDogYnl0ZXMsIGU6IGJ5dGVzLCBmOiBieXRlcywgZzogYnl0ZXMsIGg6IGJ5dGVzLCBpOiBieXRlcywgajogYnl0ZXMsIGs6IGJ5dGVzLCBtOiBieXRlcywgbjogYnl0ZXMpIC0+IHZvaWQ6CnZlcmlmeV9sb2c6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjM5NS00MTAKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBwdWJsaWMgdmVyaWZ5X2xvZygKICAgIC8vICAgYTogc3RyaW5nLAogICAgLy8gICBiOiB1aW50NjQsCiAgICAvLyAgIGM6IGJ5dGVzLAogICAgLy8gICBkOiBieXRlcywKICAgIC8vICAgZTogQm9vbCwKICAgIC8vICAgZjogU3RyLAogICAgLy8gICBnOiBVaW50Tjw2ND4sCiAgICAvLyAgIGg6IFVpbnROPDI1Nj4sCiAgICAvLyAgIGk6IFVGaXhlZE54TTwzMiwgOD4sCiAgICAvLyAgIGo6IFVGaXhlZE54TTwyNTYsIDE2PiwKICAgIC8vICAgazogYnl0ZXMsCiAgICAvLyAgIG06IGJ5dGVzLAogICAgLy8gICBuOiBieXRlcywKICAgIC8vICkgewogICAgcHJvdG8gMTMgMAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo0MTUKICAgIC8vIGxvZyhhLCBiLCBjLCBkX2JpZ3VpbnQsIGUsIGYsIGcsIGgsIGksIGosIGFyYzRfaywgYXJjNF9tLCBhcmM0X24pCiAgICBmcmFtZV9kaWcgLTEyCiAgICBpdG9iCiAgICBmcmFtZV9kaWcgLTEzCiAgICBzd2FwCiAgICBjb25jYXQKICAgIGZyYW1lX2RpZyAtMTEKICAgIGNvbmNhdAogICAgZnJhbWVfZGlnIC0xMAogICAgY29uY2F0CiAgICBmcmFtZV9kaWcgLTkKICAgIGNvbmNhdAogICAgZnJhbWVfZGlnIC04CiAgICBjb25jYXQKICAgIGZyYW1lX2RpZyAtNwogICAgY29uY2F0CiAgICBmcmFtZV9kaWcgLTYKICAgIGNvbmNhdAogICAgZnJhbWVfZGlnIC01CiAgICBjb25jYXQKICAgIGZyYW1lX2RpZyAtNAogICAgY29uY2F0CiAgICBmcmFtZV9kaWcgLTMKICAgIGNvbmNhdAogICAgZnJhbWVfZGlnIC0yCiAgICBjb25jYXQKICAgIGZyYW1lX2RpZyAtMQogICAgY29uY2F0CiAgICBsb2cKICAgIHJldHN1Ygo=", - "clear": "I3ByYWdtYSB2ZXJzaW9uIDEwCgp0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjpQcmltaXRpdmVPcHNDb250cmFjdC5jbGVhclN0YXRlUHJvZ3JhbToKICAgIHB1c2hpbnQgMSAvLyAxCiAgICByZXR1cm4K" - }, - "state": { - "global": { - "num_byte_slices": 0, - "num_uints": 0 - }, - "local": { - "num_byte_slices": 0, - "num_uints": 0 - } - }, - "schema": { - "global": { - "declared": {}, - "reserved": {} - }, - "local": { - "declared": {}, - "reserved": {} - } - }, - "contract": { - "name": "PrimitiveOpsContract", - "methods": [ - { - "name": "verify_uint64_init", - "args": [ - { - "type": "byte[]", - "name": "raw_value" - } - ], - "readonly": false, - "returns": { - "type": "uint64" - } - }, - { - "name": "verify_uint64_add", - "args": [ - { - "type": "uint64", - "name": "a" - }, - { - "type": "uint64", - "name": "b" - } - ], - "readonly": false, - "returns": { - "type": "uint64" - } - }, - { - "name": "verify_uint64_sub", - "args": [ - { - "type": "uint64", - "name": "a" - }, - { - "type": "uint64", - "name": "b" - } - ], - "readonly": false, - "returns": { - "type": "uint64" - } - }, - { - "name": "verify_uint64_mul", - "args": [ - { - "type": "uint64", - "name": "a" - }, - { - "type": "uint64", - "name": "b" - } - ], - "readonly": false, - "returns": { - "type": "uint64" - } - }, - { - "name": "verify_uint64_div", - "args": [ - { - "type": "uint64", - "name": "a" - }, - { - "type": "uint64", - "name": "b" - } - ], - "readonly": false, - "returns": { - "type": "uint64" - } - }, - { - "name": "verify_uint64_mod", - "args": [ - { - "type": "uint64", - "name": "a" - }, - { - "type": "uint64", - "name": "b" - } - ], - "readonly": false, - "returns": { - "type": "uint64" - } - }, - { - "name": "verify_uint64_and", - "args": [ - { - "type": "uint64", - "name": "a" - }, - { - "type": "uint64", - "name": "b" - } - ], - "readonly": false, - "returns": { - "type": "uint64" - } - }, - { - "name": "verify_uint64_or", - "args": [ - { - "type": "uint64", - "name": "a" - }, - { - "type": "uint64", - "name": "b" - } - ], - "readonly": false, - "returns": { - "type": "uint64" - } - }, - { - "name": "verify_uint64_xor", - "args": [ - { - "type": "uint64", - "name": "a" - }, - { - "type": "uint64", - "name": "b" - } - ], - "readonly": false, - "returns": { - "type": "uint64" - } - }, - { - "name": "verify_uint64_not", - "args": [ - { - "type": "uint64", - "name": "a" - } - ], - "readonly": false, - "returns": { - "type": "uint64" - } - }, - { - "name": "verify_uint64_lshift", - "args": [ - { - "type": "uint64", - "name": "a" - }, - { - "type": "uint64", - "name": "b" - } - ], - "readonly": false, - "returns": { - "type": "uint64" - } - }, - { - "name": "verify_uint64_rshift", - "args": [ - { - "type": "uint64", - "name": "a" - }, - { - "type": "uint64", - "name": "b" - } - ], - "readonly": false, - "returns": { - "type": "uint64" - } - }, - { - "name": "verify_uint64_pow", - "args": [ - { - "type": "uint64", - "name": "a" - }, - { - "type": "uint64", - "name": "b" - } - ], - "readonly": false, - "returns": { - "type": "uint64" - } - }, - { - "name": "verify_uint64_eq", - "args": [ - { - "type": "uint64", - "name": "a" - }, - { - "type": "uint64", - "name": "b" - } - ], - "readonly": false, - "returns": { - "type": "bool" - } - }, - { - "name": "verify_uint64_ne", - "args": [ - { - "type": "uint64", - "name": "a" - }, - { - "type": "uint64", - "name": "b" - } - ], - "readonly": false, - "returns": { - "type": "bool" - } - }, - { - "name": "verify_uint64_lt", - "args": [ - { - "type": "uint64", - "name": "a" - }, - { - "type": "uint64", - "name": "b" - } - ], - "readonly": false, - "returns": { - "type": "bool" - } - }, - { - "name": "verify_uint64_le", - "args": [ - { - "type": "uint64", - "name": "a" - }, - { - "type": "uint64", - "name": "b" - } - ], - "readonly": false, - "returns": { - "type": "bool" - } - }, - { - "name": "verify_uint64_gt", - "args": [ - { - "type": "uint64", - "name": "a" - }, - { - "type": "uint64", - "name": "b" - } - ], - "readonly": false, - "returns": { - "type": "bool" - } - }, - { - "name": "verify_uint64_ge", - "args": [ - { - "type": "uint64", - "name": "a" - }, - { - "type": "uint64", - "name": "b" - } - ], - "readonly": false, - "returns": { - "type": "bool" - } - }, - { - "name": "verify_bytes_init", - "args": [ - { - "type": "uint64", - "name": "raw_value" - } - ], - "readonly": false, - "returns": { - "type": "byte[]" - } - }, - { - "name": "verify_bytes_add", - "args": [ - { - "type": "byte[]", - "name": "a" - }, - { - "type": "byte[]", - "name": "b" - }, - { - "type": "uint64", - "name": "pad_a_size" - }, - { - "type": "uint64", - "name": "pad_b_size" - } - ], - "readonly": false, - "returns": { - "type": "byte[]" - } - }, - { - "name": "verify_bytes_eq", - "args": [ - { - "type": "byte[]", - "name": "a" - }, - { - "type": "byte[]", - "name": "b" - } - ], - "readonly": false, - "returns": { - "type": "bool" - } - }, - { - "name": "verify_bytes_ne", - "args": [ - { - "type": "byte[]", - "name": "a" - }, - { - "type": "byte[]", - "name": "b" - } - ], - "readonly": false, - "returns": { - "type": "bool" - } - }, - { - "name": "verify_bytes_and", - "args": [ - { - "type": "byte[]", - "name": "a" - }, - { - "type": "byte[]", - "name": "b" - } - ], - "readonly": false, - "returns": { - "type": "byte[]" - } - }, - { - "name": "verify_bytes_or", - "args": [ - { - "type": "byte[]", - "name": "a" - }, - { - "type": "byte[]", - "name": "b" - } - ], - "readonly": false, - "returns": { - "type": "byte[]" - } - }, - { - "name": "verify_bytes_xor", - "args": [ - { - "type": "byte[]", - "name": "a" - }, - { - "type": "byte[]", - "name": "b" - } - ], - "readonly": false, - "returns": { - "type": "byte[]" - } - }, - { - "name": "verify_bytes_not", - "args": [ - { - "type": "byte[]", - "name": "a" - }, - { - "type": "uint64", - "name": "pad_size" - } - ], - "readonly": false, - "returns": { - "type": "byte[]" - } - }, - { - "name": "verify_biguint_add", - "args": [ - { - "type": "byte[]", - "name": "a" - }, - { - "type": "byte[]", - "name": "b" - } - ], - "readonly": false, - "returns": { - "type": "byte[]" - } - }, - { - "name": "verify_biguint_add_uint64", - "args": [ - { - "type": "byte[]", - "name": "a" - }, - { - "type": "uint64", - "name": "b" - } - ], - "readonly": false, - "returns": { - "type": "byte[]" - } - }, - { - "name": "verify_biguint_sub", - "args": [ - { - "type": "byte[]", - "name": "a" - }, - { - "type": "byte[]", - "name": "b" - } - ], - "readonly": false, - "returns": { - "type": "byte[]" - } - }, - { - "name": "verify_biguint_sub_uint64", - "args": [ - { - "type": "byte[]", - "name": "a" - }, - { - "type": "uint64", - "name": "b" - } - ], - "readonly": false, - "returns": { - "type": "byte[]" - } - }, - { - "name": "verify_biguint_mul", - "args": [ - { - "type": "byte[]", - "name": "a" - }, - { - "type": "byte[]", - "name": "b" - } - ], - "readonly": false, - "returns": { - "type": "byte[]" - } - }, - { - "name": "verify_biguint_mul_uint64", - "args": [ - { - "type": "byte[]", - "name": "a" - }, - { - "type": "uint64", - "name": "b" - } - ], - "readonly": false, - "returns": { - "type": "byte[]" - } - }, - { - "name": "verify_biguint_div", - "args": [ - { - "type": "byte[]", - "name": "a" - }, - { - "type": "byte[]", - "name": "b" - } - ], - "readonly": false, - "returns": { - "type": "byte[]" - } - }, - { - "name": "verify_biguint_div_uint64", - "args": [ - { - "type": "byte[]", - "name": "a" - }, - { - "type": "uint64", - "name": "b" - } - ], - "readonly": false, - "returns": { - "type": "byte[]" - } - }, - { - "name": "verify_biguint_mod", - "args": [ - { - "type": "byte[]", - "name": "a" - }, - { - "type": "byte[]", - "name": "b" - } - ], - "readonly": false, - "returns": { - "type": "byte[]" - } - }, - { - "name": "verify_biguint_mod_uint64", - "args": [ - { - "type": "byte[]", - "name": "a" - }, - { - "type": "uint64", - "name": "b" - } - ], - "readonly": false, - "returns": { - "type": "byte[]" - } - }, - { - "name": "verify_biguint_and", - "args": [ - { - "type": "byte[]", - "name": "a" - }, - { - "type": "byte[]", - "name": "b" - } - ], - "readonly": false, - "returns": { - "type": "byte[]" - } - }, - { - "name": "verify_biguint_and_uint64", - "args": [ - { - "type": "byte[]", - "name": "a" - }, - { - "type": "uint64", - "name": "b" - } - ], - "readonly": false, - "returns": { - "type": "byte[]" - } - }, - { - "name": "verify_biguint_or", - "args": [ - { - "type": "byte[]", - "name": "a" - }, - { - "type": "byte[]", - "name": "b" - } - ], - "readonly": false, - "returns": { - "type": "byte[]" - } - }, - { - "name": "verify_biguint_or_uint64", - "args": [ - { - "type": "byte[]", - "name": "a" - }, - { - "type": "uint64", - "name": "b" - } - ], - "readonly": false, - "returns": { - "type": "byte[]" - } - }, - { - "name": "verify_biguint_xor", - "args": [ - { - "type": "byte[]", - "name": "a" - }, - { - "type": "byte[]", - "name": "b" - } - ], - "readonly": false, - "returns": { - "type": "byte[]" - } - }, - { - "name": "verify_biguint_xor_uint64", - "args": [ - { - "type": "byte[]", - "name": "a" - }, - { - "type": "uint64", - "name": "b" - } - ], - "readonly": false, - "returns": { - "type": "byte[]" - } - }, - { - "name": "verify_biguint_eq", - "args": [ - { - "type": "byte[]", - "name": "a" - }, - { - "type": "byte[]", - "name": "b" - } - ], - "readonly": false, - "returns": { - "type": "bool" - } - }, - { - "name": "verify_biguint_eq_uint64", - "args": [ - { - "type": "byte[]", - "name": "a" - }, - { - "type": "uint64", - "name": "b" - } - ], - "readonly": false, - "returns": { - "type": "bool" - } - }, - { - "name": "verify_biguint_ne", - "args": [ - { - "type": "byte[]", - "name": "a" - }, - { - "type": "byte[]", - "name": "b" - } - ], - "readonly": false, - "returns": { - "type": "bool" - } - }, - { - "name": "verify_biguint_ne_uint64", - "args": [ - { - "type": "byte[]", - "name": "a" - }, - { - "type": "uint64", - "name": "b" - } - ], - "readonly": false, - "returns": { - "type": "bool" - } - }, - { - "name": "verify_biguint_lt", - "args": [ - { - "type": "byte[]", - "name": "a" - }, - { - "type": "byte[]", - "name": "b" - } - ], - "readonly": false, - "returns": { - "type": "bool" - } - }, - { - "name": "verify_biguint_lt_uint64", - "args": [ - { - "type": "byte[]", - "name": "a" - }, - { - "type": "uint64", - "name": "b" - } - ], - "readonly": false, - "returns": { - "type": "bool" - } - }, - { - "name": "verify_biguint_le", - "args": [ - { - "type": "byte[]", - "name": "a" - }, - { - "type": "byte[]", - "name": "b" - } - ], - "readonly": false, - "returns": { - "type": "bool" - } - }, - { - "name": "verify_biguint_le_uint64", - "args": [ - { - "type": "byte[]", - "name": "a" - }, - { - "type": "uint64", - "name": "b" - } - ], - "readonly": false, - "returns": { - "type": "bool" - } - }, - { - "name": "verify_biguint_gt", - "args": [ - { - "type": "byte[]", - "name": "a" - }, - { - "type": "byte[]", - "name": "b" - } - ], - "readonly": false, - "returns": { - "type": "bool" - } - }, - { - "name": "verify_biguint_gt_uint64", - "args": [ - { - "type": "byte[]", - "name": "a" - }, - { - "type": "uint64", - "name": "b" - } - ], - "readonly": false, - "returns": { - "type": "bool" - } - }, - { - "name": "verify_biguint_ge", - "args": [ - { - "type": "byte[]", - "name": "a" - }, - { - "type": "byte[]", - "name": "b" - } - ], - "readonly": false, - "returns": { - "type": "bool" - } - }, - { - "name": "verify_biguint_ge_uint64", - "args": [ - { - "type": "byte[]", - "name": "a" - }, - { - "type": "uint64", - "name": "b" - } - ], - "readonly": false, - "returns": { - "type": "bool" - } - }, - { - "name": "verify_log", - "args": [ - { - "type": "string", - "name": "a" - }, - { - "type": "uint64", - "name": "b" - }, - { - "type": "byte[]", - "name": "c" - }, - { - "type": "byte[]", - "name": "d" - }, - { - "type": "bool", - "name": "e" - }, - { - "type": "string", - "name": "f" - }, - { - "type": "uint64", - "name": "g" - }, - { - "type": "uint256", - "name": "h" - }, - { - "type": "ufixed32x8", - "name": "i" - }, - { - "type": "ufixed256x16", - "name": "j" - }, - { - "type": "byte[]", - "name": "k" - }, - { - "type": "byte[]", - "name": "m" - }, - { - "type": "byte[]", - "name": "n" - } - ], - "readonly": false, - "returns": { - "type": "void" - } - } - ], - "networks": {} - }, - "bare_call_config": { - "no_op": "CREATE" - } -} \ No newline at end of file diff --git a/tests/artifacts/primitive-ops/data/PrimitiveOpsContract.arc56.json b/tests/artifacts/primitive-ops/data/PrimitiveOpsContract.arc56.json deleted file mode 100644 index e03b9b5..0000000 --- a/tests/artifacts/primitive-ops/data/PrimitiveOpsContract.arc56.json +++ /dev/null @@ -1,1624 +0,0 @@ -{ - "name": "PrimitiveOpsContract", - "structs": {}, - "methods": [ - { - "name": "verify_uint64_init", - "args": [ - { - "type": "byte[]", - "name": "raw_value" - } - ], - "returns": { - "type": "uint64" - }, - "actions": { - "create": [], - "call": [ - "NoOp" - ] - }, - "readonly": false, - "events": [], - "recommendations": {} - }, - { - "name": "verify_uint64_add", - "args": [ - { - "type": "uint64", - "name": "a" - }, - { - "type": "uint64", - "name": "b" - } - ], - "returns": { - "type": "uint64" - }, - "actions": { - "create": [], - "call": [ - "NoOp" - ] - }, - "readonly": false, - "events": [], - "recommendations": {} - }, - { - "name": "verify_uint64_sub", - "args": [ - { - "type": "uint64", - "name": "a" - }, - { - "type": "uint64", - "name": "b" - } - ], - "returns": { - "type": "uint64" - }, - "actions": { - "create": [], - "call": [ - "NoOp" - ] - }, - "readonly": false, - "events": [], - "recommendations": {} - }, - { - "name": "verify_uint64_mul", - "args": [ - { - "type": "uint64", - "name": "a" - }, - { - "type": "uint64", - "name": "b" - } - ], - "returns": { - "type": "uint64" - }, - "actions": { - "create": [], - "call": [ - "NoOp" - ] - }, - "readonly": false, - "events": [], - "recommendations": {} - }, - { - "name": "verify_uint64_div", - "args": [ - { - "type": "uint64", - "name": "a" - }, - { - "type": "uint64", - "name": "b" - } - ], - "returns": { - "type": "uint64" - }, - "actions": { - "create": [], - "call": [ - "NoOp" - ] - }, - "readonly": false, - "events": [], - "recommendations": {} - }, - { - "name": "verify_uint64_mod", - "args": [ - { - "type": "uint64", - "name": "a" - }, - { - "type": "uint64", - "name": "b" - } - ], - "returns": { - "type": "uint64" - }, - "actions": { - "create": [], - "call": [ - "NoOp" - ] - }, - "readonly": false, - "events": [], - "recommendations": {} - }, - { - "name": "verify_uint64_and", - "args": [ - { - "type": "uint64", - "name": "a" - }, - { - "type": "uint64", - "name": "b" - } - ], - "returns": { - "type": "uint64" - }, - "actions": { - "create": [], - "call": [ - "NoOp" - ] - }, - "readonly": false, - "events": [], - "recommendations": {} - }, - { - "name": "verify_uint64_or", - "args": [ - { - "type": "uint64", - "name": "a" - }, - { - "type": "uint64", - "name": "b" - } - ], - "returns": { - "type": "uint64" - }, - "actions": { - "create": [], - "call": [ - "NoOp" - ] - }, - "readonly": false, - "events": [], - "recommendations": {} - }, - { - "name": "verify_uint64_xor", - "args": [ - { - "type": "uint64", - "name": "a" - }, - { - "type": "uint64", - "name": "b" - } - ], - "returns": { - "type": "uint64" - }, - "actions": { - "create": [], - "call": [ - "NoOp" - ] - }, - "readonly": false, - "events": [], - "recommendations": {} - }, - { - "name": "verify_uint64_not", - "args": [ - { - "type": "uint64", - "name": "a" - } - ], - "returns": { - "type": "uint64" - }, - "actions": { - "create": [], - "call": [ - "NoOp" - ] - }, - "readonly": false, - "events": [], - "recommendations": {} - }, - { - "name": "verify_uint64_lshift", - "args": [ - { - "type": "uint64", - "name": "a" - }, - { - "type": "uint64", - "name": "b" - } - ], - "returns": { - "type": "uint64" - }, - "actions": { - "create": [], - "call": [ - "NoOp" - ] - }, - "readonly": false, - "events": [], - "recommendations": {} - }, - { - "name": "verify_uint64_rshift", - "args": [ - { - "type": "uint64", - "name": "a" - }, - { - "type": "uint64", - "name": "b" - } - ], - "returns": { - "type": "uint64" - }, - "actions": { - "create": [], - "call": [ - "NoOp" - ] - }, - "readonly": false, - "events": [], - "recommendations": {} - }, - { - "name": "verify_uint64_pow", - "args": [ - { - "type": "uint64", - "name": "a" - }, - { - "type": "uint64", - "name": "b" - } - ], - "returns": { - "type": "uint64" - }, - "actions": { - "create": [], - "call": [ - "NoOp" - ] - }, - "readonly": false, - "events": [], - "recommendations": {} - }, - { - "name": "verify_uint64_eq", - "args": [ - { - "type": "uint64", - "name": "a" - }, - { - "type": "uint64", - "name": "b" - } - ], - "returns": { - "type": "bool" - }, - "actions": { - "create": [], - "call": [ - "NoOp" - ] - }, - "readonly": false, - "events": [], - "recommendations": {} - }, - { - "name": "verify_uint64_ne", - "args": [ - { - "type": "uint64", - "name": "a" - }, - { - "type": "uint64", - "name": "b" - } - ], - "returns": { - "type": "bool" - }, - "actions": { - "create": [], - "call": [ - "NoOp" - ] - }, - "readonly": false, - "events": [], - "recommendations": {} - }, - { - "name": "verify_uint64_lt", - "args": [ - { - "type": "uint64", - "name": "a" - }, - { - "type": "uint64", - "name": "b" - } - ], - "returns": { - "type": "bool" - }, - "actions": { - "create": [], - "call": [ - "NoOp" - ] - }, - "readonly": false, - "events": [], - "recommendations": {} - }, - { - "name": "verify_uint64_le", - "args": [ - { - "type": "uint64", - "name": "a" - }, - { - "type": "uint64", - "name": "b" - } - ], - "returns": { - "type": "bool" - }, - "actions": { - "create": [], - "call": [ - "NoOp" - ] - }, - "readonly": false, - "events": [], - "recommendations": {} - }, - { - "name": "verify_uint64_gt", - "args": [ - { - "type": "uint64", - "name": "a" - }, - { - "type": "uint64", - "name": "b" - } - ], - "returns": { - "type": "bool" - }, - "actions": { - "create": [], - "call": [ - "NoOp" - ] - }, - "readonly": false, - "events": [], - "recommendations": {} - }, - { - "name": "verify_uint64_ge", - "args": [ - { - "type": "uint64", - "name": "a" - }, - { - "type": "uint64", - "name": "b" - } - ], - "returns": { - "type": "bool" - }, - "actions": { - "create": [], - "call": [ - "NoOp" - ] - }, - "readonly": false, - "events": [], - "recommendations": {} - }, - { - "name": "verify_bytes_init", - "args": [ - { - "type": "uint64", - "name": "raw_value" - } - ], - "returns": { - "type": "byte[]" - }, - "actions": { - "create": [], - "call": [ - "NoOp" - ] - }, - "readonly": false, - "events": [], - "recommendations": {} - }, - { - "name": "verify_bytes_add", - "args": [ - { - "type": "byte[]", - "name": "a" - }, - { - "type": "byte[]", - "name": "b" - }, - { - "type": "uint64", - "name": "pad_a_size" - }, - { - "type": "uint64", - "name": "pad_b_size" - } - ], - "returns": { - "type": "byte[]" - }, - "actions": { - "create": [], - "call": [ - "NoOp" - ] - }, - "readonly": false, - "events": [], - "recommendations": {} - }, - { - "name": "verify_bytes_eq", - "args": [ - { - "type": "byte[]", - "name": "a" - }, - { - "type": "byte[]", - "name": "b" - } - ], - "returns": { - "type": "bool" - }, - "actions": { - "create": [], - "call": [ - "NoOp" - ] - }, - "readonly": false, - "events": [], - "recommendations": {} - }, - { - "name": "verify_bytes_ne", - "args": [ - { - "type": "byte[]", - "name": "a" - }, - { - "type": "byte[]", - "name": "b" - } - ], - "returns": { - "type": "bool" - }, - "actions": { - "create": [], - "call": [ - "NoOp" - ] - }, - "readonly": false, - "events": [], - "recommendations": {} - }, - { - "name": "verify_bytes_and", - "args": [ - { - "type": "byte[]", - "name": "a" - }, - { - "type": "byte[]", - "name": "b" - } - ], - "returns": { - "type": "byte[]" - }, - "actions": { - "create": [], - "call": [ - "NoOp" - ] - }, - "readonly": false, - "events": [], - "recommendations": {} - }, - { - "name": "verify_bytes_or", - "args": [ - { - "type": "byte[]", - "name": "a" - }, - { - "type": "byte[]", - "name": "b" - } - ], - "returns": { - "type": "byte[]" - }, - "actions": { - "create": [], - "call": [ - "NoOp" - ] - }, - "readonly": false, - "events": [], - "recommendations": {} - }, - { - "name": "verify_bytes_xor", - "args": [ - { - "type": "byte[]", - "name": "a" - }, - { - "type": "byte[]", - "name": "b" - } - ], - "returns": { - "type": "byte[]" - }, - "actions": { - "create": [], - "call": [ - "NoOp" - ] - }, - "readonly": false, - "events": [], - "recommendations": {} - }, - { - "name": "verify_bytes_not", - "args": [ - { - "type": "byte[]", - "name": "a" - }, - { - "type": "uint64", - "name": "pad_size" - } - ], - "returns": { - "type": "byte[]" - }, - "actions": { - "create": [], - "call": [ - "NoOp" - ] - }, - "readonly": false, - "events": [], - "recommendations": {} - }, - { - "name": "verify_biguint_add", - "args": [ - { - "type": "byte[]", - "name": "a" - }, - { - "type": "byte[]", - "name": "b" - } - ], - "returns": { - "type": "byte[]" - }, - "actions": { - "create": [], - "call": [ - "NoOp" - ] - }, - "readonly": false, - "events": [], - "recommendations": {} - }, - { - "name": "verify_biguint_add_uint64", - "args": [ - { - "type": "byte[]", - "name": "a" - }, - { - "type": "uint64", - "name": "b" - } - ], - "returns": { - "type": "byte[]" - }, - "actions": { - "create": [], - "call": [ - "NoOp" - ] - }, - "readonly": false, - "events": [], - "recommendations": {} - }, - { - "name": "verify_biguint_sub", - "args": [ - { - "type": "byte[]", - "name": "a" - }, - { - "type": "byte[]", - "name": "b" - } - ], - "returns": { - "type": "byte[]" - }, - "actions": { - "create": [], - "call": [ - "NoOp" - ] - }, - "readonly": false, - "events": [], - "recommendations": {} - }, - { - "name": "verify_biguint_sub_uint64", - "args": [ - { - "type": "byte[]", - "name": "a" - }, - { - "type": "uint64", - "name": "b" - } - ], - "returns": { - "type": "byte[]" - }, - "actions": { - "create": [], - "call": [ - "NoOp" - ] - }, - "readonly": false, - "events": [], - "recommendations": {} - }, - { - "name": "verify_biguint_mul", - "args": [ - { - "type": "byte[]", - "name": "a" - }, - { - "type": "byte[]", - "name": "b" - } - ], - "returns": { - "type": "byte[]" - }, - "actions": { - "create": [], - "call": [ - "NoOp" - ] - }, - "readonly": false, - "events": [], - "recommendations": {} - }, - { - "name": "verify_biguint_mul_uint64", - "args": [ - { - "type": "byte[]", - "name": "a" - }, - { - "type": "uint64", - "name": "b" - } - ], - "returns": { - "type": "byte[]" - }, - "actions": { - "create": [], - "call": [ - "NoOp" - ] - }, - "readonly": false, - "events": [], - "recommendations": {} - }, - { - "name": "verify_biguint_div", - "args": [ - { - "type": "byte[]", - "name": "a" - }, - { - "type": "byte[]", - "name": "b" - } - ], - "returns": { - "type": "byte[]" - }, - "actions": { - "create": [], - "call": [ - "NoOp" - ] - }, - "readonly": false, - "events": [], - "recommendations": {} - }, - { - "name": "verify_biguint_div_uint64", - "args": [ - { - "type": "byte[]", - "name": "a" - }, - { - "type": "uint64", - "name": "b" - } - ], - "returns": { - "type": "byte[]" - }, - "actions": { - "create": [], - "call": [ - "NoOp" - ] - }, - "readonly": false, - "events": [], - "recommendations": {} - }, - { - "name": "verify_biguint_mod", - "args": [ - { - "type": "byte[]", - "name": "a" - }, - { - "type": "byte[]", - "name": "b" - } - ], - "returns": { - "type": "byte[]" - }, - "actions": { - "create": [], - "call": [ - "NoOp" - ] - }, - "readonly": false, - "events": [], - "recommendations": {} - }, - { - "name": "verify_biguint_mod_uint64", - "args": [ - { - "type": "byte[]", - "name": "a" - }, - { - "type": "uint64", - "name": "b" - } - ], - "returns": { - "type": "byte[]" - }, - "actions": { - "create": [], - "call": [ - "NoOp" - ] - }, - "readonly": false, - "events": [], - "recommendations": {} - }, - { - "name": "verify_biguint_and", - "args": [ - { - "type": "byte[]", - "name": "a" - }, - { - "type": "byte[]", - "name": "b" - } - ], - "returns": { - "type": "byte[]" - }, - "actions": { - "create": [], - "call": [ - "NoOp" - ] - }, - "readonly": false, - "events": [], - "recommendations": {} - }, - { - "name": "verify_biguint_and_uint64", - "args": [ - { - "type": "byte[]", - "name": "a" - }, - { - "type": "uint64", - "name": "b" - } - ], - "returns": { - "type": "byte[]" - }, - "actions": { - "create": [], - "call": [ - "NoOp" - ] - }, - "readonly": false, - "events": [], - "recommendations": {} - }, - { - "name": "verify_biguint_or", - "args": [ - { - "type": "byte[]", - "name": "a" - }, - { - "type": "byte[]", - "name": "b" - } - ], - "returns": { - "type": "byte[]" - }, - "actions": { - "create": [], - "call": [ - "NoOp" - ] - }, - "readonly": false, - "events": [], - "recommendations": {} - }, - { - "name": "verify_biguint_or_uint64", - "args": [ - { - "type": "byte[]", - "name": "a" - }, - { - "type": "uint64", - "name": "b" - } - ], - "returns": { - "type": "byte[]" - }, - "actions": { - "create": [], - "call": [ - "NoOp" - ] - }, - "readonly": false, - "events": [], - "recommendations": {} - }, - { - "name": "verify_biguint_xor", - "args": [ - { - "type": "byte[]", - "name": "a" - }, - { - "type": "byte[]", - "name": "b" - } - ], - "returns": { - "type": "byte[]" - }, - "actions": { - "create": [], - "call": [ - "NoOp" - ] - }, - "readonly": false, - "events": [], - "recommendations": {} - }, - { - "name": "verify_biguint_xor_uint64", - "args": [ - { - "type": "byte[]", - "name": "a" - }, - { - "type": "uint64", - "name": "b" - } - ], - "returns": { - "type": "byte[]" - }, - "actions": { - "create": [], - "call": [ - "NoOp" - ] - }, - "readonly": false, - "events": [], - "recommendations": {} - }, - { - "name": "verify_biguint_eq", - "args": [ - { - "type": "byte[]", - "name": "a" - }, - { - "type": "byte[]", - "name": "b" - } - ], - "returns": { - "type": "bool" - }, - "actions": { - "create": [], - "call": [ - "NoOp" - ] - }, - "readonly": false, - "events": [], - "recommendations": {} - }, - { - "name": "verify_biguint_eq_uint64", - "args": [ - { - "type": "byte[]", - "name": "a" - }, - { - "type": "uint64", - "name": "b" - } - ], - "returns": { - "type": "bool" - }, - "actions": { - "create": [], - "call": [ - "NoOp" - ] - }, - "readonly": false, - "events": [], - "recommendations": {} - }, - { - "name": "verify_biguint_ne", - "args": [ - { - "type": "byte[]", - "name": "a" - }, - { - "type": "byte[]", - "name": "b" - } - ], - "returns": { - "type": "bool" - }, - "actions": { - "create": [], - "call": [ - "NoOp" - ] - }, - "readonly": false, - "events": [], - "recommendations": {} - }, - { - "name": "verify_biguint_ne_uint64", - "args": [ - { - "type": "byte[]", - "name": "a" - }, - { - "type": "uint64", - "name": "b" - } - ], - "returns": { - "type": "bool" - }, - "actions": { - "create": [], - "call": [ - "NoOp" - ] - }, - "readonly": false, - "events": [], - "recommendations": {} - }, - { - "name": "verify_biguint_lt", - "args": [ - { - "type": "byte[]", - "name": "a" - }, - { - "type": "byte[]", - "name": "b" - } - ], - "returns": { - "type": "bool" - }, - "actions": { - "create": [], - "call": [ - "NoOp" - ] - }, - "readonly": false, - "events": [], - "recommendations": {} - }, - { - "name": "verify_biguint_lt_uint64", - "args": [ - { - "type": "byte[]", - "name": "a" - }, - { - "type": "uint64", - "name": "b" - } - ], - "returns": { - "type": "bool" - }, - "actions": { - "create": [], - "call": [ - "NoOp" - ] - }, - "readonly": false, - "events": [], - "recommendations": {} - }, - { - "name": "verify_biguint_le", - "args": [ - { - "type": "byte[]", - "name": "a" - }, - { - "type": "byte[]", - "name": "b" - } - ], - "returns": { - "type": "bool" - }, - "actions": { - "create": [], - "call": [ - "NoOp" - ] - }, - "readonly": false, - "events": [], - "recommendations": {} - }, - { - "name": "verify_biguint_le_uint64", - "args": [ - { - "type": "byte[]", - "name": "a" - }, - { - "type": "uint64", - "name": "b" - } - ], - "returns": { - "type": "bool" - }, - "actions": { - "create": [], - "call": [ - "NoOp" - ] - }, - "readonly": false, - "events": [], - "recommendations": {} - }, - { - "name": "verify_biguint_gt", - "args": [ - { - "type": "byte[]", - "name": "a" - }, - { - "type": "byte[]", - "name": "b" - } - ], - "returns": { - "type": "bool" - }, - "actions": { - "create": [], - "call": [ - "NoOp" - ] - }, - "readonly": false, - "events": [], - "recommendations": {} - }, - { - "name": "verify_biguint_gt_uint64", - "args": [ - { - "type": "byte[]", - "name": "a" - }, - { - "type": "uint64", - "name": "b" - } - ], - "returns": { - "type": "bool" - }, - "actions": { - "create": [], - "call": [ - "NoOp" - ] - }, - "readonly": false, - "events": [], - "recommendations": {} - }, - { - "name": "verify_biguint_ge", - "args": [ - { - "type": "byte[]", - "name": "a" - }, - { - "type": "byte[]", - "name": "b" - } - ], - "returns": { - "type": "bool" - }, - "actions": { - "create": [], - "call": [ - "NoOp" - ] - }, - "readonly": false, - "events": [], - "recommendations": {} - }, - { - "name": "verify_biguint_ge_uint64", - "args": [ - { - "type": "byte[]", - "name": "a" - }, - { - "type": "uint64", - "name": "b" - } - ], - "returns": { - "type": "bool" - }, - "actions": { - "create": [], - "call": [ - "NoOp" - ] - }, - "readonly": false, - "events": [], - "recommendations": {} - }, - { - "name": "verify_log", - "args": [ - { - "type": "string", - "name": "a" - }, - { - "type": "uint64", - "name": "b" - }, - { - "type": "byte[]", - "name": "c" - }, - { - "type": "byte[]", - "name": "d" - }, - { - "type": "bool", - "name": "e" - }, - { - "type": "string", - "name": "f" - }, - { - "type": "uint64", - "name": "g" - }, - { - "type": "uint256", - "name": "h" - }, - { - "type": "ufixed32x8", - "name": "i" - }, - { - "type": "ufixed256x16", - "name": "j" - }, - { - "type": "byte[]", - "name": "k" - }, - { - "type": "byte[]", - "name": "m" - }, - { - "type": "byte[]", - "name": "n" - } - ], - "returns": { - "type": "void" - }, - "actions": { - "create": [], - "call": [ - "NoOp" - ] - }, - "readonly": false, - "events": [], - "recommendations": {} - } - ], - "arcs": [ - 22, - 28 - ], - "networks": {}, - "state": { - "schema": { - "global": { - "ints": 0, - "bytes": 0 - }, - "local": { - "ints": 0, - "bytes": 0 - } - }, - "keys": { - "global": {}, - "local": {}, - "box": {} - }, - "maps": { - "global": {}, - "local": {}, - "box": {} - } - }, - "bareActions": { - "create": [ - "NoOp" - ], - "call": [] - }, - "sourceInfo": { - "approval": { - "sourceInfo": [ - { - "pc": [ - 430, - 453, - 478, - 503, - 528, - 553, - 578, - 603, - 628, - 653, - 674, - 699, - 724, - 749, - 778, - 807, - 836, - 865, - 894, - 923, - 951, - 995, - 1028, - 1061, - 1097, - 1133, - 1169, - 1203, - 1239, - 1273, - 1309, - 1343, - 1379, - 1413, - 1449, - 1483, - 1519, - 1553, - 1589, - 1623, - 1659, - 1693, - 1729, - 1763, - 1796, - 1827, - 1860, - 1891, - 1924, - 1955, - 1988, - 2019, - 2052, - 2083, - 2116, - 2147 - ], - "errorMessage": "OnCompletion is not NoOp" - }, - { - "pc": [ - 2222 - ], - "errorMessage": "can only call when creating" - }, - { - "pc": [ - 433, - 456, - 481, - 506, - 531, - 556, - 581, - 606, - 631, - 656, - 677, - 702, - 727, - 752, - 781, - 810, - 839, - 868, - 897, - 926, - 954, - 998, - 1031, - 1064, - 1100, - 1136, - 1172, - 1206, - 1242, - 1276, - 1312, - 1346, - 1382, - 1416, - 1452, - 1486, - 1522, - 1556, - 1592, - 1626, - 1662, - 1696, - 1732, - 1766, - 1799, - 1830, - 1863, - 1894, - 1927, - 1958, - 1991, - 2022, - 2055, - 2086, - 2119, - 2150 - ], - "errorMessage": "can only call when not creating" - } - ], - "pcOffsetMethod": "none" - }, - "clear": { - "sourceInfo": [], - "pcOffsetMethod": "none" - } - }, - "source": { - "approval": "I3ByYWdtYSB2ZXJzaW9uIDEwCgp0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjpQcmltaXRpdmVPcHNDb250cmFjdC5hcHByb3ZhbFByb2dyYW06CiAgICBpbnRjYmxvY2sgMSAwCiAgICBieXRlY2Jsb2NrIDB4MTUxZjdjNzUgMHgwMAogICAgY2FsbHN1YiBfX3B1eWFfYXJjNF9yb3V0ZXJfXwogICAgcmV0dXJuCgoKLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo6UHJpbWl0aXZlT3BzQ29udHJhY3QuX19wdXlhX2FyYzRfcm91dGVyX18oKSAtPiB1aW50NjQ6Cl9fcHV5YV9hcmM0X3JvdXRlcl9fOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo0CiAgICAvLyBleHBvcnQgY2xhc3MgUHJpbWl0aXZlT3BzQ29udHJhY3QgZXh0ZW5kcyBhcmM0LkNvbnRyYWN0IHsKICAgIHByb3RvIDAgMQogICAgdHhuIE51bUFwcEFyZ3MKICAgIGJ6IF9fcHV5YV9hcmM0X3JvdXRlcl9fX2JhcmVfcm91dGluZ0A2MAogICAgcHVzaGJ5dGVzcyAweDcyNWM2OTJiIDB4MTczMTQ1NTkgMHg1M2YzNDg5MyAweDg4YzhiMjY5IDB4YTQ2NGI3YWIgMHg5YzhiMTFiOCAweDZmNDA2NTRlIDB4ZWM5YTI5NzQgMHhjNzkzNzA4ZiAweDdkZGI3NDk5IDB4YTIxYzQ0M2QgMHg2ZTdmYjIxMiAweGIwMDdmY2IwIDB4MmViYzIwZDQgMHhiMDk1NGI2NiAweGRkMTQwYWVmIDB4YWNlNDc0ZGEgMHhiYTY5NDk5MCAweDZkYjU4MWMwIDB4OTFjOGRiODkgMHhkYmU3NzE1OCAweDlhMGYyMmUxIDB4NjQwMzNkMzcgMHgyYTcyMzdjNSAweGUzYTk0NDU4IDB4NDJmODdmN2QgMHgyYjU1NDJhNCAweDliZTJmYmU5IDB4MWNkOTI1MTUgMHg2NGUxNzA1YyAweGYxMjcxYzUwIDB4MmFiNjNiNzAgMHg4MzRiYjdkMiAweDUzMTYyMGQ3IDB4M2ZiOWU3NjkgMHhmYThkYjBiYyAweGE3MmVhNDg1IDB4YjdiMGJhMTkgMHg3NDQ2MGM0MiAweGFiMzIwNzM4IDB4NTJhZDQ2NTQgMHgxMDE1NjM5OSAweDBmMDc1OTU3IDB4YmQ4NDNkZmYgMHhiMzc3ZDM4MSAweDg5NzY3MjY1IDB4NDU2YjRiMjMgMHgzM2QxYjg4YyAweDZiZjk3M2VhIDB4NjdjZDZiYjIgMHgzZjU4ODA1YSAweDFlMTMwMDM5IDB4NTA5ZGM5MWQgMHhhNTY0YTIwMiAweDIzNjUwNzYzIDB4ZTAwN2MxMGIgLy8gbWV0aG9kICJ2ZXJpZnlfdWludDY0X2luaXQoYnl0ZVtdKXVpbnQ2NCIsIG1ldGhvZCAidmVyaWZ5X3VpbnQ2NF9hZGQodWludDY0LHVpbnQ2NCl1aW50NjQiLCBtZXRob2QgInZlcmlmeV91aW50NjRfc3ViKHVpbnQ2NCx1aW50NjQpdWludDY0IiwgbWV0aG9kICJ2ZXJpZnlfdWludDY0X211bCh1aW50NjQsdWludDY0KXVpbnQ2NCIsIG1ldGhvZCAidmVyaWZ5X3VpbnQ2NF9kaXYodWludDY0LHVpbnQ2NCl1aW50NjQiLCBtZXRob2QgInZlcmlmeV91aW50NjRfbW9kKHVpbnQ2NCx1aW50NjQpdWludDY0IiwgbWV0aG9kICJ2ZXJpZnlfdWludDY0X2FuZCh1aW50NjQsdWludDY0KXVpbnQ2NCIsIG1ldGhvZCAidmVyaWZ5X3VpbnQ2NF9vcih1aW50NjQsdWludDY0KXVpbnQ2NCIsIG1ldGhvZCAidmVyaWZ5X3VpbnQ2NF94b3IodWludDY0LHVpbnQ2NCl1aW50NjQiLCBtZXRob2QgInZlcmlmeV91aW50NjRfbm90KHVpbnQ2NCl1aW50NjQiLCBtZXRob2QgInZlcmlmeV91aW50NjRfbHNoaWZ0KHVpbnQ2NCx1aW50NjQpdWludDY0IiwgbWV0aG9kICJ2ZXJpZnlfdWludDY0X3JzaGlmdCh1aW50NjQsdWludDY0KXVpbnQ2NCIsIG1ldGhvZCAidmVyaWZ5X3VpbnQ2NF9wb3codWludDY0LHVpbnQ2NCl1aW50NjQiLCBtZXRob2QgInZlcmlmeV91aW50NjRfZXEodWludDY0LHVpbnQ2NClib29sIiwgbWV0aG9kICJ2ZXJpZnlfdWludDY0X25lKHVpbnQ2NCx1aW50NjQpYm9vbCIsIG1ldGhvZCAidmVyaWZ5X3VpbnQ2NF9sdCh1aW50NjQsdWludDY0KWJvb2wiLCBtZXRob2QgInZlcmlmeV91aW50NjRfbGUodWludDY0LHVpbnQ2NClib29sIiwgbWV0aG9kICJ2ZXJpZnlfdWludDY0X2d0KHVpbnQ2NCx1aW50NjQpYm9vbCIsIG1ldGhvZCAidmVyaWZ5X3VpbnQ2NF9nZSh1aW50NjQsdWludDY0KWJvb2wiLCBtZXRob2QgInZlcmlmeV9ieXRlc19pbml0KHVpbnQ2NClieXRlW10iLCBtZXRob2QgInZlcmlmeV9ieXRlc19hZGQoYnl0ZVtdLGJ5dGVbXSx1aW50NjQsdWludDY0KWJ5dGVbXSIsIG1ldGhvZCAidmVyaWZ5X2J5dGVzX2VxKGJ5dGVbXSxieXRlW10pYm9vbCIsIG1ldGhvZCAidmVyaWZ5X2J5dGVzX25lKGJ5dGVbXSxieXRlW10pYm9vbCIsIG1ldGhvZCAidmVyaWZ5X2J5dGVzX2FuZChieXRlW10sYnl0ZVtdKWJ5dGVbXSIsIG1ldGhvZCAidmVyaWZ5X2J5dGVzX29yKGJ5dGVbXSxieXRlW10pYnl0ZVtdIiwgbWV0aG9kICJ2ZXJpZnlfYnl0ZXNfeG9yKGJ5dGVbXSxieXRlW10pYnl0ZVtdIiwgbWV0aG9kICJ2ZXJpZnlfYnl0ZXNfbm90KGJ5dGVbXSx1aW50NjQpYnl0ZVtdIiwgbWV0aG9kICJ2ZXJpZnlfYmlndWludF9hZGQoYnl0ZVtdLGJ5dGVbXSlieXRlW10iLCBtZXRob2QgInZlcmlmeV9iaWd1aW50X2FkZF91aW50NjQoYnl0ZVtdLHVpbnQ2NClieXRlW10iLCBtZXRob2QgInZlcmlmeV9iaWd1aW50X3N1YihieXRlW10sYnl0ZVtdKWJ5dGVbXSIsIG1ldGhvZCAidmVyaWZ5X2JpZ3VpbnRfc3ViX3VpbnQ2NChieXRlW10sdWludDY0KWJ5dGVbXSIsIG1ldGhvZCAidmVyaWZ5X2JpZ3VpbnRfbXVsKGJ5dGVbXSxieXRlW10pYnl0ZVtdIiwgbWV0aG9kICJ2ZXJpZnlfYmlndWludF9tdWxfdWludDY0KGJ5dGVbXSx1aW50NjQpYnl0ZVtdIiwgbWV0aG9kICJ2ZXJpZnlfYmlndWludF9kaXYoYnl0ZVtdLGJ5dGVbXSlieXRlW10iLCBtZXRob2QgInZlcmlmeV9iaWd1aW50X2Rpdl91aW50NjQoYnl0ZVtdLHVpbnQ2NClieXRlW10iLCBtZXRob2QgInZlcmlmeV9iaWd1aW50X21vZChieXRlW10sYnl0ZVtdKWJ5dGVbXSIsIG1ldGhvZCAidmVyaWZ5X2JpZ3VpbnRfbW9kX3VpbnQ2NChieXRlW10sdWludDY0KWJ5dGVbXSIsIG1ldGhvZCAidmVyaWZ5X2JpZ3VpbnRfYW5kKGJ5dGVbXSxieXRlW10pYnl0ZVtdIiwgbWV0aG9kICJ2ZXJpZnlfYmlndWludF9hbmRfdWludDY0KGJ5dGVbXSx1aW50NjQpYnl0ZVtdIiwgbWV0aG9kICJ2ZXJpZnlfYmlndWludF9vcihieXRlW10sYnl0ZVtdKWJ5dGVbXSIsIG1ldGhvZCAidmVyaWZ5X2JpZ3VpbnRfb3JfdWludDY0KGJ5dGVbXSx1aW50NjQpYnl0ZVtdIiwgbWV0aG9kICJ2ZXJpZnlfYmlndWludF94b3IoYnl0ZVtdLGJ5dGVbXSlieXRlW10iLCBtZXRob2QgInZlcmlmeV9iaWd1aW50X3hvcl91aW50NjQoYnl0ZVtdLHVpbnQ2NClieXRlW10iLCBtZXRob2QgInZlcmlmeV9iaWd1aW50X2VxKGJ5dGVbXSxieXRlW10pYm9vbCIsIG1ldGhvZCAidmVyaWZ5X2JpZ3VpbnRfZXFfdWludDY0KGJ5dGVbXSx1aW50NjQpYm9vbCIsIG1ldGhvZCAidmVyaWZ5X2JpZ3VpbnRfbmUoYnl0ZVtdLGJ5dGVbXSlib29sIiwgbWV0aG9kICJ2ZXJpZnlfYmlndWludF9uZV91aW50NjQoYnl0ZVtdLHVpbnQ2NClib29sIiwgbWV0aG9kICJ2ZXJpZnlfYmlndWludF9sdChieXRlW10sYnl0ZVtdKWJvb2wiLCBtZXRob2QgInZlcmlmeV9iaWd1aW50X2x0X3VpbnQ2NChieXRlW10sdWludDY0KWJvb2wiLCBtZXRob2QgInZlcmlmeV9iaWd1aW50X2xlKGJ5dGVbXSxieXRlW10pYm9vbCIsIG1ldGhvZCAidmVyaWZ5X2JpZ3VpbnRfbGVfdWludDY0KGJ5dGVbXSx1aW50NjQpYm9vbCIsIG1ldGhvZCAidmVyaWZ5X2JpZ3VpbnRfZ3QoYnl0ZVtdLGJ5dGVbXSlib29sIiwgbWV0aG9kICJ2ZXJpZnlfYmlndWludF9ndF91aW50NjQoYnl0ZVtdLHVpbnQ2NClib29sIiwgbWV0aG9kICJ2ZXJpZnlfYmlndWludF9nZShieXRlW10sYnl0ZVtdKWJvb2wiLCBtZXRob2QgInZlcmlmeV9iaWd1aW50X2dlX3VpbnQ2NChieXRlW10sdWludDY0KWJvb2wiLCBtZXRob2QgInZlcmlmeV9sb2coc3RyaW5nLHVpbnQ2NCxieXRlW10sYnl0ZVtdLGJvb2wsc3RyaW5nLHVpbnQ2NCx1aW50MjU2LHVmaXhlZDMyeDgsdWZpeGVkMjU2eDE2LGJ5dGVbXSxieXRlW10sYnl0ZVtdKXZvaWQiCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAwCiAgICBtYXRjaCBfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfdWludDY0X2luaXRfcm91dGVAMiBfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfdWludDY0X2FkZF9yb3V0ZUAzIF9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV91aW50NjRfc3ViX3JvdXRlQDQgX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X3VpbnQ2NF9tdWxfcm91dGVANSBfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfdWludDY0X2Rpdl9yb3V0ZUA2IF9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV91aW50NjRfbW9kX3JvdXRlQDcgX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X3VpbnQ2NF9hbmRfcm91dGVAOCBfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfdWludDY0X29yX3JvdXRlQDkgX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X3VpbnQ2NF94b3Jfcm91dGVAMTAgX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X3VpbnQ2NF9ub3Rfcm91dGVAMTEgX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X3VpbnQ2NF9sc2hpZnRfcm91dGVAMTIgX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X3VpbnQ2NF9yc2hpZnRfcm91dGVAMTMgX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X3VpbnQ2NF9wb3dfcm91dGVAMTQgX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X3VpbnQ2NF9lcV9yb3V0ZUAxNSBfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfdWludDY0X25lX3JvdXRlQDE2IF9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV91aW50NjRfbHRfcm91dGVAMTcgX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X3VpbnQ2NF9sZV9yb3V0ZUAxOCBfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfdWludDY0X2d0X3JvdXRlQDE5IF9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV91aW50NjRfZ2Vfcm91dGVAMjAgX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2J5dGVzX2luaXRfcm91dGVAMjEgX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2J5dGVzX2FkZF9yb3V0ZUAyMiBfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfYnl0ZXNfZXFfcm91dGVAMjMgX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2J5dGVzX25lX3JvdXRlQDI0IF9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9ieXRlc19hbmRfcm91dGVAMjUgX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2J5dGVzX29yX3JvdXRlQDI2IF9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9ieXRlc194b3Jfcm91dGVAMjcgX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2J5dGVzX25vdF9yb3V0ZUAyOCBfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfYmlndWludF9hZGRfcm91dGVAMjkgX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2JpZ3VpbnRfYWRkX3VpbnQ2NF9yb3V0ZUAzMCBfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfYmlndWludF9zdWJfcm91dGVAMzEgX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2JpZ3VpbnRfc3ViX3VpbnQ2NF9yb3V0ZUAzMiBfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfYmlndWludF9tdWxfcm91dGVAMzMgX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2JpZ3VpbnRfbXVsX3VpbnQ2NF9yb3V0ZUAzNCBfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfYmlndWludF9kaXZfcm91dGVAMzUgX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2JpZ3VpbnRfZGl2X3VpbnQ2NF9yb3V0ZUAzNiBfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfYmlndWludF9tb2Rfcm91dGVAMzcgX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2JpZ3VpbnRfbW9kX3VpbnQ2NF9yb3V0ZUAzOCBfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfYmlndWludF9hbmRfcm91dGVAMzkgX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2JpZ3VpbnRfYW5kX3VpbnQ2NF9yb3V0ZUA0MCBfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfYmlndWludF9vcl9yb3V0ZUA0MSBfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfYmlndWludF9vcl91aW50NjRfcm91dGVANDIgX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2JpZ3VpbnRfeG9yX3JvdXRlQDQzIF9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9iaWd1aW50X3hvcl91aW50NjRfcm91dGVANDQgX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2JpZ3VpbnRfZXFfcm91dGVANDUgX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2JpZ3VpbnRfZXFfdWludDY0X3JvdXRlQDQ2IF9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9iaWd1aW50X25lX3JvdXRlQDQ3IF9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9iaWd1aW50X25lX3VpbnQ2NF9yb3V0ZUA0OCBfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfYmlndWludF9sdF9yb3V0ZUA0OSBfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfYmlndWludF9sdF91aW50NjRfcm91dGVANTAgX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2JpZ3VpbnRfbGVfcm91dGVANTEgX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2JpZ3VpbnRfbGVfdWludDY0X3JvdXRlQDUyIF9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9iaWd1aW50X2d0X3JvdXRlQDUzIF9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9iaWd1aW50X2d0X3VpbnQ2NF9yb3V0ZUA1NCBfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfYmlndWludF9nZV9yb3V0ZUA1NSBfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfYmlndWludF9nZV91aW50NjRfcm91dGVANTYgX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2xvZ19yb3V0ZUA1NwogICAgaW50Y18xIC8vIDAKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X3VpbnQ2NF9pbml0X3JvdXRlQDI6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjUKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIG5vdCBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGNhbiBvbmx5IGNhbGwgd2hlbiBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NAogICAgLy8gZXhwb3J0IGNsYXNzIFByaW1pdGl2ZU9wc0NvbnRyYWN0IGV4dGVuZHMgYXJjNC5Db250cmFjdCB7CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBleHRyYWN0IDIgMAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo1CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfdWludDY0X2luaXQKICAgIGl0b2IKICAgIGJ5dGVjXzAgLy8gMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludGNfMCAvLyAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV91aW50NjRfYWRkX3JvdXRlQDM6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjExCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBub3QgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBjYW4gb25seSBjYWxsIHdoZW4gbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjQKICAgIC8vIGV4cG9ydCBjbGFzcyBQcmltaXRpdmVPcHNDb250cmFjdCBleHRlbmRzIGFyYzQuQ29udHJhY3QgewogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgYnRvaQogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMgogICAgYnRvaQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoxMQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X3VpbnQ2NF9hZGQKICAgIGl0b2IKICAgIGJ5dGVjXzAgLy8gMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludGNfMCAvLyAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV91aW50NjRfc3ViX3JvdXRlQDQ6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjE3CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBub3QgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBjYW4gb25seSBjYWxsIHdoZW4gbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjQKICAgIC8vIGV4cG9ydCBjbGFzcyBQcmltaXRpdmVPcHNDb250cmFjdCBleHRlbmRzIGFyYzQuQ29udHJhY3QgewogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgYnRvaQogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMgogICAgYnRvaQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoxNwogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X3VpbnQ2NF9zdWIKICAgIGl0b2IKICAgIGJ5dGVjXzAgLy8gMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludGNfMCAvLyAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV91aW50NjRfbXVsX3JvdXRlQDU6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjIzCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBub3QgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBjYW4gb25seSBjYWxsIHdoZW4gbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjQKICAgIC8vIGV4cG9ydCBjbGFzcyBQcmltaXRpdmVPcHNDb250cmFjdCBleHRlbmRzIGFyYzQuQ29udHJhY3QgewogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgYnRvaQogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMgogICAgYnRvaQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoyMwogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X3VpbnQ2NF9tdWwKICAgIGl0b2IKICAgIGJ5dGVjXzAgLy8gMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludGNfMCAvLyAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV91aW50NjRfZGl2X3JvdXRlQDY6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjI5CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBub3QgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBjYW4gb25seSBjYWxsIHdoZW4gbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjQKICAgIC8vIGV4cG9ydCBjbGFzcyBQcmltaXRpdmVPcHNDb250cmFjdCBleHRlbmRzIGFyYzQuQ29udHJhY3QgewogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgYnRvaQogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMgogICAgYnRvaQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoyOQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X3VpbnQ2NF9kaXYKICAgIGl0b2IKICAgIGJ5dGVjXzAgLy8gMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludGNfMCAvLyAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV91aW50NjRfbW9kX3JvdXRlQDc6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjM1CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBub3QgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBjYW4gb25seSBjYWxsIHdoZW4gbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjQKICAgIC8vIGV4cG9ydCBjbGFzcyBQcmltaXRpdmVPcHNDb250cmFjdCBleHRlbmRzIGFyYzQuQ29udHJhY3QgewogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgYnRvaQogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMgogICAgYnRvaQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czozNQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X3VpbnQ2NF9tb2QKICAgIGl0b2IKICAgIGJ5dGVjXzAgLy8gMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludGNfMCAvLyAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV91aW50NjRfYW5kX3JvdXRlQDg6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjQxCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBub3QgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBjYW4gb25seSBjYWxsIHdoZW4gbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjQKICAgIC8vIGV4cG9ydCBjbGFzcyBQcmltaXRpdmVPcHNDb250cmFjdCBleHRlbmRzIGFyYzQuQ29udHJhY3QgewogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgYnRvaQogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMgogICAgYnRvaQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo0MQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X3VpbnQ2NF9hbmQKICAgIGl0b2IKICAgIGJ5dGVjXzAgLy8gMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludGNfMCAvLyAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV91aW50NjRfb3Jfcm91dGVAOToKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NDcKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIG5vdCBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGNhbiBvbmx5IGNhbGwgd2hlbiBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NAogICAgLy8gZXhwb3J0IGNsYXNzIFByaW1pdGl2ZU9wc0NvbnRyYWN0IGV4dGVuZHMgYXJjNC5Db250cmFjdCB7CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBidG9pCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAyCiAgICBidG9pCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjQ3CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfdWludDY0X29yCiAgICBpdG9iCiAgICBieXRlY18wIC8vIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnRjXzAgLy8gMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfdWludDY0X3hvcl9yb3V0ZUAxMDoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NTMKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIG5vdCBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGNhbiBvbmx5IGNhbGwgd2hlbiBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NAogICAgLy8gZXhwb3J0IGNsYXNzIFByaW1pdGl2ZU9wc0NvbnRyYWN0IGV4dGVuZHMgYXJjNC5Db250cmFjdCB7CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBidG9pCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAyCiAgICBidG9pCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjUzCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfdWludDY0X3hvcgogICAgaXRvYgogICAgYnl0ZWNfMCAvLyAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50Y18wIC8vIDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X3VpbnQ2NF9ub3Rfcm91dGVAMTE6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjU5CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBub3QgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBjYW4gb25seSBjYWxsIHdoZW4gbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjQKICAgIC8vIGV4cG9ydCBjbGFzcyBQcmltaXRpdmVPcHNDb250cmFjdCBleHRlbmRzIGFyYzQuQ29udHJhY3QgewogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgYnRvaQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo1OQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X3VpbnQ2NF9ub3QKICAgIGl0b2IKICAgIGJ5dGVjXzAgLy8gMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludGNfMCAvLyAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV91aW50NjRfbHNoaWZ0X3JvdXRlQDEyOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo2NQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgbm90IE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gY2FuIG9ubHkgY2FsbCB3aGVuIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo0CiAgICAvLyBleHBvcnQgY2xhc3MgUHJpbWl0aXZlT3BzQ29udHJhY3QgZXh0ZW5kcyBhcmM0LkNvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGJ0b2kKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDIKICAgIGJ0b2kKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NjUKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV91aW50NjRfbHNoaWZ0CiAgICBpdG9iCiAgICBieXRlY18wIC8vIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnRjXzAgLy8gMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfdWludDY0X3JzaGlmdF9yb3V0ZUAxMzoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NzEKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIG5vdCBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGNhbiBvbmx5IGNhbGwgd2hlbiBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NAogICAgLy8gZXhwb3J0IGNsYXNzIFByaW1pdGl2ZU9wc0NvbnRyYWN0IGV4dGVuZHMgYXJjNC5Db250cmFjdCB7CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBidG9pCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAyCiAgICBidG9pCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjcxCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfdWludDY0X3JzaGlmdAogICAgaXRvYgogICAgYnl0ZWNfMCAvLyAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50Y18wIC8vIDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X3VpbnQ2NF9wb3dfcm91dGVAMTQ6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjc3CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBub3QgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBjYW4gb25seSBjYWxsIHdoZW4gbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjQKICAgIC8vIGV4cG9ydCBjbGFzcyBQcmltaXRpdmVPcHNDb250cmFjdCBleHRlbmRzIGFyYzQuQ29udHJhY3QgewogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgYnRvaQogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMgogICAgYnRvaQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo3NwogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X3VpbnQ2NF9wb3cKICAgIGl0b2IKICAgIGJ5dGVjXzAgLy8gMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludGNfMCAvLyAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV91aW50NjRfZXFfcm91dGVAMTU6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjgzCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBub3QgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBjYW4gb25seSBjYWxsIHdoZW4gbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjQKICAgIC8vIGV4cG9ydCBjbGFzcyBQcmltaXRpdmVPcHNDb250cmFjdCBleHRlbmRzIGFyYzQuQ29udHJhY3QgewogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgYnRvaQogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMgogICAgYnRvaQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo4MwogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X3VpbnQ2NF9lcQogICAgYnl0ZWNfMSAvLyAweDAwCiAgICBpbnRjXzEgLy8gMAogICAgdW5jb3ZlciAyCiAgICBzZXRiaXQKICAgIGJ5dGVjXzAgLy8gMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludGNfMCAvLyAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV91aW50NjRfbmVfcm91dGVAMTY6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjg5CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBub3QgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBjYW4gb25seSBjYWxsIHdoZW4gbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjQKICAgIC8vIGV4cG9ydCBjbGFzcyBQcmltaXRpdmVPcHNDb250cmFjdCBleHRlbmRzIGFyYzQuQ29udHJhY3QgewogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgYnRvaQogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMgogICAgYnRvaQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo4OQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X3VpbnQ2NF9uZQogICAgYnl0ZWNfMSAvLyAweDAwCiAgICBpbnRjXzEgLy8gMAogICAgdW5jb3ZlciAyCiAgICBzZXRiaXQKICAgIGJ5dGVjXzAgLy8gMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludGNfMCAvLyAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV91aW50NjRfbHRfcm91dGVAMTc6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjk1CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBub3QgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBjYW4gb25seSBjYWxsIHdoZW4gbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjQKICAgIC8vIGV4cG9ydCBjbGFzcyBQcmltaXRpdmVPcHNDb250cmFjdCBleHRlbmRzIGFyYzQuQ29udHJhY3QgewogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgYnRvaQogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMgogICAgYnRvaQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo5NQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X3VpbnQ2NF9sdAogICAgYnl0ZWNfMSAvLyAweDAwCiAgICBpbnRjXzEgLy8gMAogICAgdW5jb3ZlciAyCiAgICBzZXRiaXQKICAgIGJ5dGVjXzAgLy8gMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludGNfMCAvLyAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV91aW50NjRfbGVfcm91dGVAMTg6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjEwMQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgbm90IE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gY2FuIG9ubHkgY2FsbCB3aGVuIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo0CiAgICAvLyBleHBvcnQgY2xhc3MgUHJpbWl0aXZlT3BzQ29udHJhY3QgZXh0ZW5kcyBhcmM0LkNvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGJ0b2kKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDIKICAgIGJ0b2kKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTAxCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfdWludDY0X2xlCiAgICBieXRlY18xIC8vIDB4MDAKICAgIGludGNfMSAvLyAwCiAgICB1bmNvdmVyIDIKICAgIHNldGJpdAogICAgYnl0ZWNfMCAvLyAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50Y18wIC8vIDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X3VpbnQ2NF9ndF9yb3V0ZUAxOToKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTA3CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBub3QgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBjYW4gb25seSBjYWxsIHdoZW4gbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjQKICAgIC8vIGV4cG9ydCBjbGFzcyBQcmltaXRpdmVPcHNDb250cmFjdCBleHRlbmRzIGFyYzQuQ29udHJhY3QgewogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgYnRvaQogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMgogICAgYnRvaQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoxMDcKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV91aW50NjRfZ3QKICAgIGJ5dGVjXzEgLy8gMHgwMAogICAgaW50Y18xIC8vIDAKICAgIHVuY292ZXIgMgogICAgc2V0Yml0CiAgICBieXRlY18wIC8vIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnRjXzAgLy8gMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfdWludDY0X2dlX3JvdXRlQDIwOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoxMTMKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIG5vdCBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGNhbiBvbmx5IGNhbGwgd2hlbiBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NAogICAgLy8gZXhwb3J0IGNsYXNzIFByaW1pdGl2ZU9wc0NvbnRyYWN0IGV4dGVuZHMgYXJjNC5Db250cmFjdCB7CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBidG9pCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAyCiAgICBidG9pCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjExMwogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X3VpbnQ2NF9nZQogICAgYnl0ZWNfMSAvLyAweDAwCiAgICBpbnRjXzEgLy8gMAogICAgdW5jb3ZlciAyCiAgICBzZXRiaXQKICAgIGJ5dGVjXzAgLy8gMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludGNfMCAvLyAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9ieXRlc19pbml0X3JvdXRlQDIxOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoxMTkKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIG5vdCBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGNhbiBvbmx5IGNhbGwgd2hlbiBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NAogICAgLy8gZXhwb3J0IGNsYXNzIFByaW1pdGl2ZU9wc0NvbnRyYWN0IGV4dGVuZHMgYXJjNC5Db250cmFjdCB7CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBidG9pCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjExOQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X2J5dGVzX2luaXQKICAgIGR1cAogICAgbGVuCiAgICBpdG9iCiAgICBleHRyYWN0IDYgMgogICAgc3dhcAogICAgY29uY2F0CiAgICBieXRlY18wIC8vIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnRjXzAgLy8gMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfYnl0ZXNfYWRkX3JvdXRlQDIyOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoxMjUKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIG5vdCBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGNhbiBvbmx5IGNhbGwgd2hlbiBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NAogICAgLy8gZXhwb3J0IGNsYXNzIFByaW1pdGl2ZU9wc0NvbnRyYWN0IGV4dGVuZHMgYXJjNC5Db250cmFjdCB7CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBleHRyYWN0IDIgMAogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMgogICAgZXh0cmFjdCAyIDAKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDMKICAgIGJ0b2kKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDQKICAgIGJ0b2kKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTI1CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfYnl0ZXNfYWRkCiAgICBkdXAKICAgIGxlbgogICAgaXRvYgogICAgZXh0cmFjdCA2IDIKICAgIHN3YXAKICAgIGNvbmNhdAogICAgYnl0ZWNfMCAvLyAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50Y18wIC8vIDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2J5dGVzX2VxX3JvdXRlQDIzOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoxMzQKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIG5vdCBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGNhbiBvbmx5IGNhbGwgd2hlbiBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NAogICAgLy8gZXhwb3J0IGNsYXNzIFByaW1pdGl2ZU9wc0NvbnRyYWN0IGV4dGVuZHMgYXJjNC5Db250cmFjdCB7CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBleHRyYWN0IDIgMAogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMgogICAgZXh0cmFjdCAyIDAKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTM0CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfYnl0ZXNfZXEKICAgIGJ5dGVjXzEgLy8gMHgwMAogICAgaW50Y18xIC8vIDAKICAgIHVuY292ZXIgMgogICAgc2V0Yml0CiAgICBieXRlY18wIC8vIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnRjXzAgLy8gMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfYnl0ZXNfbmVfcm91dGVAMjQ6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjE0MAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgbm90IE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gY2FuIG9ubHkgY2FsbCB3aGVuIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo0CiAgICAvLyBleHBvcnQgY2xhc3MgUHJpbWl0aXZlT3BzQ29udHJhY3QgZXh0ZW5kcyBhcmM0LkNvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGV4dHJhY3QgMiAwCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAyCiAgICBleHRyYWN0IDIgMAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoxNDAKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV9ieXRlc19uZQogICAgYnl0ZWNfMSAvLyAweDAwCiAgICBpbnRjXzEgLy8gMAogICAgdW5jb3ZlciAyCiAgICBzZXRiaXQKICAgIGJ5dGVjXzAgLy8gMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludGNfMCAvLyAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9ieXRlc19hbmRfcm91dGVAMjU6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjE0NgogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgbm90IE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gY2FuIG9ubHkgY2FsbCB3aGVuIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo0CiAgICAvLyBleHBvcnQgY2xhc3MgUHJpbWl0aXZlT3BzQ29udHJhY3QgZXh0ZW5kcyBhcmM0LkNvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGV4dHJhY3QgMiAwCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAyCiAgICBleHRyYWN0IDIgMAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoxNDYKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV9ieXRlc19hbmQKICAgIGR1cAogICAgbGVuCiAgICBpdG9iCiAgICBleHRyYWN0IDYgMgogICAgc3dhcAogICAgY29uY2F0CiAgICBieXRlY18wIC8vIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnRjXzAgLy8gMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfYnl0ZXNfb3Jfcm91dGVAMjY6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjE1MgogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgbm90IE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gY2FuIG9ubHkgY2FsbCB3aGVuIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo0CiAgICAvLyBleHBvcnQgY2xhc3MgUHJpbWl0aXZlT3BzQ29udHJhY3QgZXh0ZW5kcyBhcmM0LkNvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGV4dHJhY3QgMiAwCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAyCiAgICBleHRyYWN0IDIgMAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoxNTIKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV9ieXRlc19vcgogICAgZHVwCiAgICBsZW4KICAgIGl0b2IKICAgIGV4dHJhY3QgNiAyCiAgICBzd2FwCiAgICBjb25jYXQKICAgIGJ5dGVjXzAgLy8gMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludGNfMCAvLyAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9ieXRlc194b3Jfcm91dGVAMjc6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjE1OAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgbm90IE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gY2FuIG9ubHkgY2FsbCB3aGVuIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo0CiAgICAvLyBleHBvcnQgY2xhc3MgUHJpbWl0aXZlT3BzQ29udHJhY3QgZXh0ZW5kcyBhcmM0LkNvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGV4dHJhY3QgMiAwCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAyCiAgICBleHRyYWN0IDIgMAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoxNTgKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV9ieXRlc194b3IKICAgIGR1cAogICAgbGVuCiAgICBpdG9iCiAgICBleHRyYWN0IDYgMgogICAgc3dhcAogICAgY29uY2F0CiAgICBieXRlY18wIC8vIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnRjXzAgLy8gMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfYnl0ZXNfbm90X3JvdXRlQDI4OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoxNjQKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIG5vdCBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGNhbiBvbmx5IGNhbGwgd2hlbiBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NAogICAgLy8gZXhwb3J0IGNsYXNzIFByaW1pdGl2ZU9wc0NvbnRyYWN0IGV4dGVuZHMgYXJjNC5Db250cmFjdCB7CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBleHRyYWN0IDIgMAogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMgogICAgYnRvaQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoxNjQKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV9ieXRlc19ub3QKICAgIGR1cAogICAgbGVuCiAgICBpdG9iCiAgICBleHRyYWN0IDYgMgogICAgc3dhcAogICAgY29uY2F0CiAgICBieXRlY18wIC8vIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnRjXzAgLy8gMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfYmlndWludF9hZGRfcm91dGVAMjk6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjE3MgogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgbm90IE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gY2FuIG9ubHkgY2FsbCB3aGVuIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo0CiAgICAvLyBleHBvcnQgY2xhc3MgUHJpbWl0aXZlT3BzQ29udHJhY3QgZXh0ZW5kcyBhcmM0LkNvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGV4dHJhY3QgMiAwCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAyCiAgICBleHRyYWN0IDIgMAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoxNzIKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV9iaWd1aW50X2FkZAogICAgZHVwCiAgICBsZW4KICAgIGl0b2IKICAgIGV4dHJhY3QgNiAyCiAgICBzd2FwCiAgICBjb25jYXQKICAgIGJ5dGVjXzAgLy8gMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludGNfMCAvLyAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9iaWd1aW50X2FkZF91aW50NjRfcm91dGVAMzA6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjE4MAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgbm90IE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gY2FuIG9ubHkgY2FsbCB3aGVuIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo0CiAgICAvLyBleHBvcnQgY2xhc3MgUHJpbWl0aXZlT3BzQ29udHJhY3QgZXh0ZW5kcyBhcmM0LkNvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGV4dHJhY3QgMiAwCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAyCiAgICBidG9pCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjE4MAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X2JpZ3VpbnRfYWRkX3VpbnQ2NAogICAgZHVwCiAgICBsZW4KICAgIGl0b2IKICAgIGV4dHJhY3QgNiAyCiAgICBzd2FwCiAgICBjb25jYXQKICAgIGJ5dGVjXzAgLy8gMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludGNfMCAvLyAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9iaWd1aW50X3N1Yl9yb3V0ZUAzMToKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTg4CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBub3QgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBjYW4gb25seSBjYWxsIHdoZW4gbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjQKICAgIC8vIGV4cG9ydCBjbGFzcyBQcmltaXRpdmVPcHNDb250cmFjdCBleHRlbmRzIGFyYzQuQ29udHJhY3QgewogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgZXh0cmFjdCAyIDAKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDIKICAgIGV4dHJhY3QgMiAwCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjE4OAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X2JpZ3VpbnRfc3ViCiAgICBkdXAKICAgIGxlbgogICAgaXRvYgogICAgZXh0cmFjdCA2IDIKICAgIHN3YXAKICAgIGNvbmNhdAogICAgYnl0ZWNfMCAvLyAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50Y18wIC8vIDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2JpZ3VpbnRfc3ViX3VpbnQ2NF9yb3V0ZUAzMjoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTk2CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBub3QgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBjYW4gb25seSBjYWxsIHdoZW4gbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjQKICAgIC8vIGV4cG9ydCBjbGFzcyBQcmltaXRpdmVPcHNDb250cmFjdCBleHRlbmRzIGFyYzQuQ29udHJhY3QgewogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgZXh0cmFjdCAyIDAKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDIKICAgIGJ0b2kKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTk2CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfYmlndWludF9zdWJfdWludDY0CiAgICBkdXAKICAgIGxlbgogICAgaXRvYgogICAgZXh0cmFjdCA2IDIKICAgIHN3YXAKICAgIGNvbmNhdAogICAgYnl0ZWNfMCAvLyAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50Y18wIC8vIDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2JpZ3VpbnRfbXVsX3JvdXRlQDMzOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoyMDQKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIG5vdCBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGNhbiBvbmx5IGNhbGwgd2hlbiBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NAogICAgLy8gZXhwb3J0IGNsYXNzIFByaW1pdGl2ZU9wc0NvbnRyYWN0IGV4dGVuZHMgYXJjNC5Db250cmFjdCB7CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBleHRyYWN0IDIgMAogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMgogICAgZXh0cmFjdCAyIDAKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MjA0CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfYmlndWludF9tdWwKICAgIGR1cAogICAgbGVuCiAgICBpdG9iCiAgICBleHRyYWN0IDYgMgogICAgc3dhcAogICAgY29uY2F0CiAgICBieXRlY18wIC8vIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnRjXzAgLy8gMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfYmlndWludF9tdWxfdWludDY0X3JvdXRlQDM0OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoyMTIKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIG5vdCBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGNhbiBvbmx5IGNhbGwgd2hlbiBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NAogICAgLy8gZXhwb3J0IGNsYXNzIFByaW1pdGl2ZU9wc0NvbnRyYWN0IGV4dGVuZHMgYXJjNC5Db250cmFjdCB7CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBleHRyYWN0IDIgMAogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMgogICAgYnRvaQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoyMTIKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV9iaWd1aW50X211bF91aW50NjQKICAgIGR1cAogICAgbGVuCiAgICBpdG9iCiAgICBleHRyYWN0IDYgMgogICAgc3dhcAogICAgY29uY2F0CiAgICBieXRlY18wIC8vIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnRjXzAgLy8gMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfYmlndWludF9kaXZfcm91dGVAMzU6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjIyMAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgbm90IE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gY2FuIG9ubHkgY2FsbCB3aGVuIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo0CiAgICAvLyBleHBvcnQgY2xhc3MgUHJpbWl0aXZlT3BzQ29udHJhY3QgZXh0ZW5kcyBhcmM0LkNvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGV4dHJhY3QgMiAwCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAyCiAgICBleHRyYWN0IDIgMAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoyMjAKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV9iaWd1aW50X2RpdgogICAgZHVwCiAgICBsZW4KICAgIGl0b2IKICAgIGV4dHJhY3QgNiAyCiAgICBzd2FwCiAgICBjb25jYXQKICAgIGJ5dGVjXzAgLy8gMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludGNfMCAvLyAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9iaWd1aW50X2Rpdl91aW50NjRfcm91dGVAMzY6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjIyOAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgbm90IE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gY2FuIG9ubHkgY2FsbCB3aGVuIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo0CiAgICAvLyBleHBvcnQgY2xhc3MgUHJpbWl0aXZlT3BzQ29udHJhY3QgZXh0ZW5kcyBhcmM0LkNvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGV4dHJhY3QgMiAwCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAyCiAgICBidG9pCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjIyOAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X2JpZ3VpbnRfZGl2X3VpbnQ2NAogICAgZHVwCiAgICBsZW4KICAgIGl0b2IKICAgIGV4dHJhY3QgNiAyCiAgICBzd2FwCiAgICBjb25jYXQKICAgIGJ5dGVjXzAgLy8gMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludGNfMCAvLyAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9iaWd1aW50X21vZF9yb3V0ZUAzNzoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MjM2CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBub3QgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBjYW4gb25seSBjYWxsIHdoZW4gbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjQKICAgIC8vIGV4cG9ydCBjbGFzcyBQcmltaXRpdmVPcHNDb250cmFjdCBleHRlbmRzIGFyYzQuQ29udHJhY3QgewogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgZXh0cmFjdCAyIDAKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDIKICAgIGV4dHJhY3QgMiAwCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjIzNgogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X2JpZ3VpbnRfbW9kCiAgICBkdXAKICAgIGxlbgogICAgaXRvYgogICAgZXh0cmFjdCA2IDIKICAgIHN3YXAKICAgIGNvbmNhdAogICAgYnl0ZWNfMCAvLyAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50Y18wIC8vIDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2JpZ3VpbnRfbW9kX3VpbnQ2NF9yb3V0ZUAzODoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MjQ0CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBub3QgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBjYW4gb25seSBjYWxsIHdoZW4gbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjQKICAgIC8vIGV4cG9ydCBjbGFzcyBQcmltaXRpdmVPcHNDb250cmFjdCBleHRlbmRzIGFyYzQuQ29udHJhY3QgewogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgZXh0cmFjdCAyIDAKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDIKICAgIGJ0b2kKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MjQ0CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfYmlndWludF9tb2RfdWludDY0CiAgICBkdXAKICAgIGxlbgogICAgaXRvYgogICAgZXh0cmFjdCA2IDIKICAgIHN3YXAKICAgIGNvbmNhdAogICAgYnl0ZWNfMCAvLyAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50Y18wIC8vIDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2JpZ3VpbnRfYW5kX3JvdXRlQDM5OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoyNTIKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIG5vdCBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGNhbiBvbmx5IGNhbGwgd2hlbiBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NAogICAgLy8gZXhwb3J0IGNsYXNzIFByaW1pdGl2ZU9wc0NvbnRyYWN0IGV4dGVuZHMgYXJjNC5Db250cmFjdCB7CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBleHRyYWN0IDIgMAogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMgogICAgZXh0cmFjdCAyIDAKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MjUyCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfYmlndWludF9hbmQKICAgIGR1cAogICAgbGVuCiAgICBpdG9iCiAgICBleHRyYWN0IDYgMgogICAgc3dhcAogICAgY29uY2F0CiAgICBieXRlY18wIC8vIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnRjXzAgLy8gMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfYmlndWludF9hbmRfdWludDY0X3JvdXRlQDQwOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoyNjAKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIG5vdCBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGNhbiBvbmx5IGNhbGwgd2hlbiBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NAogICAgLy8gZXhwb3J0IGNsYXNzIFByaW1pdGl2ZU9wc0NvbnRyYWN0IGV4dGVuZHMgYXJjNC5Db250cmFjdCB7CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBleHRyYWN0IDIgMAogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMgogICAgYnRvaQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoyNjAKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV9iaWd1aW50X2FuZF91aW50NjQKICAgIGR1cAogICAgbGVuCiAgICBpdG9iCiAgICBleHRyYWN0IDYgMgogICAgc3dhcAogICAgY29uY2F0CiAgICBieXRlY18wIC8vIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnRjXzAgLy8gMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfYmlndWludF9vcl9yb3V0ZUA0MToKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MjY4CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBub3QgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBjYW4gb25seSBjYWxsIHdoZW4gbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjQKICAgIC8vIGV4cG9ydCBjbGFzcyBQcmltaXRpdmVPcHNDb250cmFjdCBleHRlbmRzIGFyYzQuQ29udHJhY3QgewogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgZXh0cmFjdCAyIDAKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDIKICAgIGV4dHJhY3QgMiAwCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjI2OAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X2JpZ3VpbnRfb3IKICAgIGR1cAogICAgbGVuCiAgICBpdG9iCiAgICBleHRyYWN0IDYgMgogICAgc3dhcAogICAgY29uY2F0CiAgICBieXRlY18wIC8vIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnRjXzAgLy8gMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfYmlndWludF9vcl91aW50NjRfcm91dGVANDI6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjI3NgogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgbm90IE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gY2FuIG9ubHkgY2FsbCB3aGVuIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo0CiAgICAvLyBleHBvcnQgY2xhc3MgUHJpbWl0aXZlT3BzQ29udHJhY3QgZXh0ZW5kcyBhcmM0LkNvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGV4dHJhY3QgMiAwCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAyCiAgICBidG9pCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjI3NgogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X2JpZ3VpbnRfb3JfdWludDY0CiAgICBkdXAKICAgIGxlbgogICAgaXRvYgogICAgZXh0cmFjdCA2IDIKICAgIHN3YXAKICAgIGNvbmNhdAogICAgYnl0ZWNfMCAvLyAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50Y18wIC8vIDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2JpZ3VpbnRfeG9yX3JvdXRlQDQzOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoyODQKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIG5vdCBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGNhbiBvbmx5IGNhbGwgd2hlbiBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NAogICAgLy8gZXhwb3J0IGNsYXNzIFByaW1pdGl2ZU9wc0NvbnRyYWN0IGV4dGVuZHMgYXJjNC5Db250cmFjdCB7CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBleHRyYWN0IDIgMAogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMgogICAgZXh0cmFjdCAyIDAKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6Mjg0CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfYmlndWludF94b3IKICAgIGR1cAogICAgbGVuCiAgICBpdG9iCiAgICBleHRyYWN0IDYgMgogICAgc3dhcAogICAgY29uY2F0CiAgICBieXRlY18wIC8vIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnRjXzAgLy8gMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfYmlndWludF94b3JfdWludDY0X3JvdXRlQDQ0OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoyOTIKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIG5vdCBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGNhbiBvbmx5IGNhbGwgd2hlbiBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NAogICAgLy8gZXhwb3J0IGNsYXNzIFByaW1pdGl2ZU9wc0NvbnRyYWN0IGV4dGVuZHMgYXJjNC5Db250cmFjdCB7CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBleHRyYWN0IDIgMAogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMgogICAgYnRvaQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoyOTIKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV9iaWd1aW50X3hvcl91aW50NjQKICAgIGR1cAogICAgbGVuCiAgICBpdG9iCiAgICBleHRyYWN0IDYgMgogICAgc3dhcAogICAgY29uY2F0CiAgICBieXRlY18wIC8vIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnRjXzAgLy8gMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfYmlndWludF9lcV9yb3V0ZUA0NToKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MzAwCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBub3QgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBjYW4gb25seSBjYWxsIHdoZW4gbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjQKICAgIC8vIGV4cG9ydCBjbGFzcyBQcmltaXRpdmVPcHNDb250cmFjdCBleHRlbmRzIGFyYzQuQ29udHJhY3QgewogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgZXh0cmFjdCAyIDAKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDIKICAgIGV4dHJhY3QgMiAwCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjMwMAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X2JpZ3VpbnRfZXEKICAgIGJ5dGVjXzEgLy8gMHgwMAogICAgaW50Y18xIC8vIDAKICAgIHVuY292ZXIgMgogICAgc2V0Yml0CiAgICBieXRlY18wIC8vIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnRjXzAgLy8gMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfYmlndWludF9lcV91aW50NjRfcm91dGVANDY6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjMwOAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgbm90IE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gY2FuIG9ubHkgY2FsbCB3aGVuIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo0CiAgICAvLyBleHBvcnQgY2xhc3MgUHJpbWl0aXZlT3BzQ29udHJhY3QgZXh0ZW5kcyBhcmM0LkNvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGV4dHJhY3QgMiAwCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAyCiAgICBidG9pCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjMwOAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X2JpZ3VpbnRfZXFfdWludDY0CiAgICBieXRlY18xIC8vIDB4MDAKICAgIGludGNfMSAvLyAwCiAgICB1bmNvdmVyIDIKICAgIHNldGJpdAogICAgYnl0ZWNfMCAvLyAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50Y18wIC8vIDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2JpZ3VpbnRfbmVfcm91dGVANDc6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjMxNQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgbm90IE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gY2FuIG9ubHkgY2FsbCB3aGVuIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo0CiAgICAvLyBleHBvcnQgY2xhc3MgUHJpbWl0aXZlT3BzQ29udHJhY3QgZXh0ZW5kcyBhcmM0LkNvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGV4dHJhY3QgMiAwCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAyCiAgICBleHRyYWN0IDIgMAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czozMTUKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV9iaWd1aW50X25lCiAgICBieXRlY18xIC8vIDB4MDAKICAgIGludGNfMSAvLyAwCiAgICB1bmNvdmVyIDIKICAgIHNldGJpdAogICAgYnl0ZWNfMCAvLyAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50Y18wIC8vIDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2JpZ3VpbnRfbmVfdWludDY0X3JvdXRlQDQ4OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czozMjMKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIG5vdCBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGNhbiBvbmx5IGNhbGwgd2hlbiBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NAogICAgLy8gZXhwb3J0IGNsYXNzIFByaW1pdGl2ZU9wc0NvbnRyYWN0IGV4dGVuZHMgYXJjNC5Db250cmFjdCB7CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBleHRyYWN0IDIgMAogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMgogICAgYnRvaQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czozMjMKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV9iaWd1aW50X25lX3VpbnQ2NAogICAgYnl0ZWNfMSAvLyAweDAwCiAgICBpbnRjXzEgLy8gMAogICAgdW5jb3ZlciAyCiAgICBzZXRiaXQKICAgIGJ5dGVjXzAgLy8gMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludGNfMCAvLyAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9iaWd1aW50X2x0X3JvdXRlQDQ5OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czozMzAKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIG5vdCBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGNhbiBvbmx5IGNhbGwgd2hlbiBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NAogICAgLy8gZXhwb3J0IGNsYXNzIFByaW1pdGl2ZU9wc0NvbnRyYWN0IGV4dGVuZHMgYXJjNC5Db250cmFjdCB7CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBleHRyYWN0IDIgMAogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMgogICAgZXh0cmFjdCAyIDAKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MzMwCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfYmlndWludF9sdAogICAgYnl0ZWNfMSAvLyAweDAwCiAgICBpbnRjXzEgLy8gMAogICAgdW5jb3ZlciAyCiAgICBzZXRiaXQKICAgIGJ5dGVjXzAgLy8gMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludGNfMCAvLyAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9iaWd1aW50X2x0X3VpbnQ2NF9yb3V0ZUA1MDoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MzM4CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBub3QgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBjYW4gb25seSBjYWxsIHdoZW4gbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjQKICAgIC8vIGV4cG9ydCBjbGFzcyBQcmltaXRpdmVPcHNDb250cmFjdCBleHRlbmRzIGFyYzQuQ29udHJhY3QgewogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgZXh0cmFjdCAyIDAKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDIKICAgIGJ0b2kKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MzM4CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfYmlndWludF9sdF91aW50NjQKICAgIGJ5dGVjXzEgLy8gMHgwMAogICAgaW50Y18xIC8vIDAKICAgIHVuY292ZXIgMgogICAgc2V0Yml0CiAgICBieXRlY18wIC8vIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnRjXzAgLy8gMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfYmlndWludF9sZV9yb3V0ZUA1MToKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MzQ2CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBub3QgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBjYW4gb25seSBjYWxsIHdoZW4gbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjQKICAgIC8vIGV4cG9ydCBjbGFzcyBQcmltaXRpdmVPcHNDb250cmFjdCBleHRlbmRzIGFyYzQuQ29udHJhY3QgewogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgZXh0cmFjdCAyIDAKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDIKICAgIGV4dHJhY3QgMiAwCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjM0NgogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X2JpZ3VpbnRfbGUKICAgIGJ5dGVjXzEgLy8gMHgwMAogICAgaW50Y18xIC8vIDAKICAgIHVuY292ZXIgMgogICAgc2V0Yml0CiAgICBieXRlY18wIC8vIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnRjXzAgLy8gMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfYmlndWludF9sZV91aW50NjRfcm91dGVANTI6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjM1NAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgbm90IE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gY2FuIG9ubHkgY2FsbCB3aGVuIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo0CiAgICAvLyBleHBvcnQgY2xhc3MgUHJpbWl0aXZlT3BzQ29udHJhY3QgZXh0ZW5kcyBhcmM0LkNvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGV4dHJhY3QgMiAwCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAyCiAgICBidG9pCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjM1NAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X2JpZ3VpbnRfbGVfdWludDY0CiAgICBieXRlY18xIC8vIDB4MDAKICAgIGludGNfMSAvLyAwCiAgICB1bmNvdmVyIDIKICAgIHNldGJpdAogICAgYnl0ZWNfMCAvLyAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50Y18wIC8vIDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2JpZ3VpbnRfZ3Rfcm91dGVANTM6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjM2MgogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgbm90IE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gY2FuIG9ubHkgY2FsbCB3aGVuIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo0CiAgICAvLyBleHBvcnQgY2xhc3MgUHJpbWl0aXZlT3BzQ29udHJhY3QgZXh0ZW5kcyBhcmM0LkNvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGV4dHJhY3QgMiAwCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAyCiAgICBleHRyYWN0IDIgMAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czozNjIKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV9iaWd1aW50X2d0CiAgICBieXRlY18xIC8vIDB4MDAKICAgIGludGNfMSAvLyAwCiAgICB1bmNvdmVyIDIKICAgIHNldGJpdAogICAgYnl0ZWNfMCAvLyAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50Y18wIC8vIDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2JpZ3VpbnRfZ3RfdWludDY0X3JvdXRlQDU0OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czozNzAKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIG5vdCBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGNhbiBvbmx5IGNhbGwgd2hlbiBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NAogICAgLy8gZXhwb3J0IGNsYXNzIFByaW1pdGl2ZU9wc0NvbnRyYWN0IGV4dGVuZHMgYXJjNC5Db250cmFjdCB7CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBleHRyYWN0IDIgMAogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMgogICAgYnRvaQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czozNzAKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV9iaWd1aW50X2d0X3VpbnQ2NAogICAgYnl0ZWNfMSAvLyAweDAwCiAgICBpbnRjXzEgLy8gMAogICAgdW5jb3ZlciAyCiAgICBzZXRiaXQKICAgIGJ5dGVjXzAgLy8gMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludGNfMCAvLyAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9iaWd1aW50X2dlX3JvdXRlQDU1OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czozNzgKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIG5vdCBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGNhbiBvbmx5IGNhbGwgd2hlbiBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NAogICAgLy8gZXhwb3J0IGNsYXNzIFByaW1pdGl2ZU9wc0NvbnRyYWN0IGV4dGVuZHMgYXJjNC5Db250cmFjdCB7CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBleHRyYWN0IDIgMAogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMgogICAgZXh0cmFjdCAyIDAKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6Mzc4CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfYmlndWludF9nZQogICAgYnl0ZWNfMSAvLyAweDAwCiAgICBpbnRjXzEgLy8gMAogICAgdW5jb3ZlciAyCiAgICBzZXRiaXQKICAgIGJ5dGVjXzAgLy8gMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludGNfMCAvLyAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9iaWd1aW50X2dlX3VpbnQ2NF9yb3V0ZUA1NjoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6Mzg2CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBub3QgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBjYW4gb25seSBjYWxsIHdoZW4gbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjQKICAgIC8vIGV4cG9ydCBjbGFzcyBQcmltaXRpdmVPcHNDb250cmFjdCBleHRlbmRzIGFyYzQuQ29udHJhY3QgewogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgZXh0cmFjdCAyIDAKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDIKICAgIGJ0b2kKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6Mzg2CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfYmlndWludF9nZV91aW50NjQKICAgIGJ5dGVjXzEgLy8gMHgwMAogICAgaW50Y18xIC8vIDAKICAgIHVuY292ZXIgMgogICAgc2V0Yml0CiAgICBieXRlY18wIC8vIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnRjXzAgLy8gMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfbG9nX3JvdXRlQDU3OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czozOTUKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIG5vdCBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGNhbiBvbmx5IGNhbGwgd2hlbiBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NAogICAgLy8gZXhwb3J0IGNsYXNzIFByaW1pdGl2ZU9wc0NvbnRyYWN0IGV4dGVuZHMgYXJjNC5Db250cmFjdCB7CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBleHRyYWN0IDIgMAogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMgogICAgYnRvaQogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMwogICAgZXh0cmFjdCAyIDAKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDQKICAgIGV4dHJhY3QgMiAwCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyA1CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyA2CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyA3CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyA4CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyA5CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxMAogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMTEKICAgIGV4dHJhY3QgMiAwCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxMgogICAgZXh0cmFjdCAyIDAKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEzCiAgICBleHRyYWN0IDIgMAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czozOTUKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV9sb2cKICAgIGludGNfMCAvLyAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX2JhcmVfcm91dGluZ0A2MDoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NAogICAgLy8gZXhwb3J0IGNsYXNzIFByaW1pdGl2ZU9wc0NvbnRyYWN0IGV4dGVuZHMgYXJjNC5Db250cmFjdCB7CiAgICB0eG4gT25Db21wbGV0aW9uCiAgICBibnogX19wdXlhX2FyYzRfcm91dGVyX19fYWZ0ZXJfaWZfZWxzZUA2NAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgICEKICAgIGFzc2VydCAvLyBjYW4gb25seSBjYWxsIHdoZW4gY3JlYXRpbmcKICAgIGludGNfMCAvLyAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX2FmdGVyX2lmX2Vsc2VANjQ6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjQKICAgIC8vIGV4cG9ydCBjbGFzcyBQcmltaXRpdmVPcHNDb250cmFjdCBleHRlbmRzIGFyYzQuQ29udHJhY3QgewogICAgaW50Y18xIC8vIDAKICAgIHJldHN1YgoKCi8vIHRlc3RzL2FydGlmYWN0cy9wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OlByaW1pdGl2ZU9wc0NvbnRyYWN0LnZlcmlmeV91aW50NjRfaW5pdChyYXdfdmFsdWU6IGJ5dGVzKSAtPiB1aW50NjQ6CnZlcmlmeV91aW50NjRfaW5pdDoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NS02CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gcHVibGljIHZlcmlmeV91aW50NjRfaW5pdChyYXdfdmFsdWU6IGJ5dGVzKTogdWludDY0IHsKICAgIHByb3RvIDEgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo3CiAgICAvLyBjb25zdCByZXN1bHQgPSBvcC5idG9pKHJhd192YWx1ZSkKICAgIGZyYW1lX2RpZyAtMQogICAgYnRvaQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo4CiAgICAvLyByZXR1cm4gcmVzdWx0CiAgICByZXRzdWIKCgovLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjpQcmltaXRpdmVPcHNDb250cmFjdC52ZXJpZnlfdWludDY0X2FkZChhOiB1aW50NjQsIGI6IHVpbnQ2NCkgLT4gdWludDY0Ogp2ZXJpZnlfdWludDY0X2FkZDoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTEtMTIKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBwdWJsaWMgdmVyaWZ5X3VpbnQ2NF9hZGQoYTogdWludDY0LCBiOiB1aW50NjQpOiB1aW50NjQgewogICAgcHJvdG8gMiAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjEzCiAgICAvLyBjb25zdCByZXN1bHQ6IHVpbnQ2NCA9IGEgKyBiCiAgICBmcmFtZV9kaWcgLTIKICAgIGZyYW1lX2RpZyAtMQogICAgKwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoxNAogICAgLy8gcmV0dXJuIHJlc3VsdAogICAgcmV0c3ViCgoKLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo6UHJpbWl0aXZlT3BzQ29udHJhY3QudmVyaWZ5X3VpbnQ2NF9zdWIoYTogdWludDY0LCBiOiB1aW50NjQpIC0+IHVpbnQ2NDoKdmVyaWZ5X3VpbnQ2NF9zdWI6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjE3LTE4CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gcHVibGljIHZlcmlmeV91aW50NjRfc3ViKGE6IHVpbnQ2NCwgYjogdWludDY0KTogdWludDY0IHsKICAgIHByb3RvIDIgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoxOQogICAgLy8gY29uc3QgcmVzdWx0OiB1aW50NjQgPSBhIC0gYgogICAgZnJhbWVfZGlnIC0yCiAgICBmcmFtZV9kaWcgLTEKICAgIC0KICAgIC8vIHRlc3RzL2FydGlmYWN0cy9wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MjAKICAgIC8vIHJldHVybiByZXN1bHQKICAgIHJldHN1YgoKCi8vIHRlc3RzL2FydGlmYWN0cy9wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OlByaW1pdGl2ZU9wc0NvbnRyYWN0LnZlcmlmeV91aW50NjRfbXVsKGE6IHVpbnQ2NCwgYjogdWludDY0KSAtPiB1aW50NjQ6CnZlcmlmeV91aW50NjRfbXVsOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoyMy0yNAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIHB1YmxpYyB2ZXJpZnlfdWludDY0X211bChhOiB1aW50NjQsIGI6IHVpbnQ2NCk6IHVpbnQ2NCB7CiAgICBwcm90byAyIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MjUKICAgIC8vIGNvbnN0IHJlc3VsdDogdWludDY0ID0gYSAqIGIKICAgIGZyYW1lX2RpZyAtMgogICAgZnJhbWVfZGlnIC0xCiAgICAqCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjI2CiAgICAvLyByZXR1cm4gcmVzdWx0CiAgICByZXRzdWIKCgovLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjpQcmltaXRpdmVPcHNDb250cmFjdC52ZXJpZnlfdWludDY0X2RpdihhOiB1aW50NjQsIGI6IHVpbnQ2NCkgLT4gdWludDY0Ogp2ZXJpZnlfdWludDY0X2RpdjoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MjktMzAKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBwdWJsaWMgdmVyaWZ5X3VpbnQ2NF9kaXYoYTogdWludDY0LCBiOiB1aW50NjQpOiB1aW50NjQgewogICAgcHJvdG8gMiAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjMxCiAgICAvLyBjb25zdCByZXN1bHQ6IHVpbnQ2NCA9IGEgLyBiCiAgICBmcmFtZV9kaWcgLTIKICAgIGZyYW1lX2RpZyAtMQogICAgLwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czozMgogICAgLy8gcmV0dXJuIHJlc3VsdAogICAgcmV0c3ViCgoKLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo6UHJpbWl0aXZlT3BzQ29udHJhY3QudmVyaWZ5X3VpbnQ2NF9tb2QoYTogdWludDY0LCBiOiB1aW50NjQpIC0+IHVpbnQ2NDoKdmVyaWZ5X3VpbnQ2NF9tb2Q6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjM1LTM2CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gcHVibGljIHZlcmlmeV91aW50NjRfbW9kKGE6IHVpbnQ2NCwgYjogdWludDY0KTogdWludDY0IHsKICAgIHByb3RvIDIgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czozNwogICAgLy8gY29uc3QgcmVzdWx0OiB1aW50NjQgPSBhICUgYgogICAgZnJhbWVfZGlnIC0yCiAgICBmcmFtZV9kaWcgLTEKICAgICUKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MzgKICAgIC8vIHJldHVybiByZXN1bHQKICAgIHJldHN1YgoKCi8vIHRlc3RzL2FydGlmYWN0cy9wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OlByaW1pdGl2ZU9wc0NvbnRyYWN0LnZlcmlmeV91aW50NjRfYW5kKGE6IHVpbnQ2NCwgYjogdWludDY0KSAtPiB1aW50NjQ6CnZlcmlmeV91aW50NjRfYW5kOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo0MS00MgogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIHB1YmxpYyB2ZXJpZnlfdWludDY0X2FuZChhOiB1aW50NjQsIGI6IHVpbnQ2NCk6IHVpbnQ2NCB7CiAgICBwcm90byAyIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NDMKICAgIC8vIGNvbnN0IHJlc3VsdDogdWludDY0ID0gYSAmIGIKICAgIGZyYW1lX2RpZyAtMgogICAgZnJhbWVfZGlnIC0xCiAgICAmCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjQ0CiAgICAvLyByZXR1cm4gcmVzdWx0CiAgICByZXRzdWIKCgovLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjpQcmltaXRpdmVPcHNDb250cmFjdC52ZXJpZnlfdWludDY0X29yKGE6IHVpbnQ2NCwgYjogdWludDY0KSAtPiB1aW50NjQ6CnZlcmlmeV91aW50NjRfb3I6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjQ3LTQ4CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gcHVibGljIHZlcmlmeV91aW50NjRfb3IoYTogdWludDY0LCBiOiB1aW50NjQpOiB1aW50NjQgewogICAgcHJvdG8gMiAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjQ5CiAgICAvLyBjb25zdCByZXN1bHQ6IHVpbnQ2NCA9IGEgfCBiCiAgICBmcmFtZV9kaWcgLTIKICAgIGZyYW1lX2RpZyAtMQogICAgfAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo1MAogICAgLy8gcmV0dXJuIHJlc3VsdAogICAgcmV0c3ViCgoKLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo6UHJpbWl0aXZlT3BzQ29udHJhY3QudmVyaWZ5X3VpbnQ2NF94b3IoYTogdWludDY0LCBiOiB1aW50NjQpIC0+IHVpbnQ2NDoKdmVyaWZ5X3VpbnQ2NF94b3I6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjUzLTU0CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gcHVibGljIHZlcmlmeV91aW50NjRfeG9yKGE6IHVpbnQ2NCwgYjogdWludDY0KTogdWludDY0IHsKICAgIHByb3RvIDIgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo1NQogICAgLy8gY29uc3QgcmVzdWx0OiB1aW50NjQgPSBhIF4gYgogICAgZnJhbWVfZGlnIC0yCiAgICBmcmFtZV9kaWcgLTEKICAgIF4KICAgIC8vIHRlc3RzL2FydGlmYWN0cy9wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NTYKICAgIC8vIHJldHVybiByZXN1bHQKICAgIHJldHN1YgoKCi8vIHRlc3RzL2FydGlmYWN0cy9wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OlByaW1pdGl2ZU9wc0NvbnRyYWN0LnZlcmlmeV91aW50NjRfbm90KGE6IHVpbnQ2NCkgLT4gdWludDY0Ogp2ZXJpZnlfdWludDY0X25vdDoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NTktNjAKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBwdWJsaWMgdmVyaWZ5X3VpbnQ2NF9ub3QoYTogdWludDY0KTogdWludDY0IHsKICAgIHByb3RvIDEgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo2MQogICAgLy8gY29uc3QgcmVzdWx0OiB1aW50NjQgPSB+YQogICAgZnJhbWVfZGlnIC0xCiAgICB+CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjYyCiAgICAvLyByZXR1cm4gcmVzdWx0CiAgICByZXRzdWIKCgovLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjpQcmltaXRpdmVPcHNDb250cmFjdC52ZXJpZnlfdWludDY0X2xzaGlmdChhOiB1aW50NjQsIGI6IHVpbnQ2NCkgLT4gdWludDY0Ogp2ZXJpZnlfdWludDY0X2xzaGlmdDoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NjUtNjYKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBwdWJsaWMgdmVyaWZ5X3VpbnQ2NF9sc2hpZnQoYTogdWludDY0LCBiOiB1aW50NjQpOiB1aW50NjQgewogICAgcHJvdG8gMiAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjY3CiAgICAvLyBjb25zdCByZXN1bHQ6IHVpbnQ2NCA9IGEgPDwgYgogICAgZnJhbWVfZGlnIC0yCiAgICBmcmFtZV9kaWcgLTEKICAgIHNobAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo2OAogICAgLy8gcmV0dXJuIHJlc3VsdAogICAgcmV0c3ViCgoKLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo6UHJpbWl0aXZlT3BzQ29udHJhY3QudmVyaWZ5X3VpbnQ2NF9yc2hpZnQoYTogdWludDY0LCBiOiB1aW50NjQpIC0+IHVpbnQ2NDoKdmVyaWZ5X3VpbnQ2NF9yc2hpZnQ6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjcxLTcyCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gcHVibGljIHZlcmlmeV91aW50NjRfcnNoaWZ0KGE6IHVpbnQ2NCwgYjogdWludDY0KTogdWludDY0IHsKICAgIHByb3RvIDIgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo3MwogICAgLy8gY29uc3QgcmVzdWx0OiB1aW50NjQgPSBhID4+IGIKICAgIGZyYW1lX2RpZyAtMgogICAgZnJhbWVfZGlnIC0xCiAgICBzaHIKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NzQKICAgIC8vIHJldHVybiByZXN1bHQKICAgIHJldHN1YgoKCi8vIHRlc3RzL2FydGlmYWN0cy9wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OlByaW1pdGl2ZU9wc0NvbnRyYWN0LnZlcmlmeV91aW50NjRfcG93KGE6IHVpbnQ2NCwgYjogdWludDY0KSAtPiB1aW50NjQ6CnZlcmlmeV91aW50NjRfcG93OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo3Ny03OAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIHB1YmxpYyB2ZXJpZnlfdWludDY0X3BvdyhhOiB1aW50NjQsIGI6IHVpbnQ2NCk6IHVpbnQ2NCB7CiAgICBwcm90byAyIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NzkKICAgIC8vIGNvbnN0IHJlc3VsdDogdWludDY0ID0gYSAqKiBiCiAgICBmcmFtZV9kaWcgLTIKICAgIGZyYW1lX2RpZyAtMQogICAgZXhwCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjgwCiAgICAvLyByZXR1cm4gcmVzdWx0CiAgICByZXRzdWIKCgovLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjpQcmltaXRpdmVPcHNDb250cmFjdC52ZXJpZnlfdWludDY0X2VxKGE6IHVpbnQ2NCwgYjogdWludDY0KSAtPiB1aW50NjQ6CnZlcmlmeV91aW50NjRfZXE6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjgzLTg0CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gcHVibGljIHZlcmlmeV91aW50NjRfZXEoYTogdWludDY0LCBiOiB1aW50NjQpOiBib29sZWFuIHsKICAgIHByb3RvIDIgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo4NQogICAgLy8gY29uc3QgcmVzdWx0ID0gYSA9PT0gYgogICAgZnJhbWVfZGlnIC0yCiAgICBmcmFtZV9kaWcgLTEKICAgID09CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjg2CiAgICAvLyByZXR1cm4gcmVzdWx0CiAgICByZXRzdWIKCgovLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjpQcmltaXRpdmVPcHNDb250cmFjdC52ZXJpZnlfdWludDY0X25lKGE6IHVpbnQ2NCwgYjogdWludDY0KSAtPiB1aW50NjQ6CnZlcmlmeV91aW50NjRfbmU6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjg5LTkwCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gcHVibGljIHZlcmlmeV91aW50NjRfbmUoYTogdWludDY0LCBiOiB1aW50NjQpOiBib29sZWFuIHsKICAgIHByb3RvIDIgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo5MQogICAgLy8gY29uc3QgcmVzdWx0ID0gYSAhPT0gYgogICAgZnJhbWVfZGlnIC0yCiAgICBmcmFtZV9kaWcgLTEKICAgICE9CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjkyCiAgICAvLyByZXR1cm4gcmVzdWx0CiAgICByZXRzdWIKCgovLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjpQcmltaXRpdmVPcHNDb250cmFjdC52ZXJpZnlfdWludDY0X2x0KGE6IHVpbnQ2NCwgYjogdWludDY0KSAtPiB1aW50NjQ6CnZlcmlmeV91aW50NjRfbHQ6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjk1LTk2CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gcHVibGljIHZlcmlmeV91aW50NjRfbHQoYTogdWludDY0LCBiOiB1aW50NjQpOiBib29sZWFuIHsKICAgIHByb3RvIDIgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo5NwogICAgLy8gY29uc3QgcmVzdWx0ID0gYSA8IGIKICAgIGZyYW1lX2RpZyAtMgogICAgZnJhbWVfZGlnIC0xCiAgICA8CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjk4CiAgICAvLyByZXR1cm4gcmVzdWx0CiAgICByZXRzdWIKCgovLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjpQcmltaXRpdmVPcHNDb250cmFjdC52ZXJpZnlfdWludDY0X2xlKGE6IHVpbnQ2NCwgYjogdWludDY0KSAtPiB1aW50NjQ6CnZlcmlmeV91aW50NjRfbGU6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjEwMS0xMDIKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBwdWJsaWMgdmVyaWZ5X3VpbnQ2NF9sZShhOiB1aW50NjQsIGI6IHVpbnQ2NCk6IGJvb2xlYW4gewogICAgcHJvdG8gMiAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjEwMwogICAgLy8gY29uc3QgcmVzdWx0ID0gYSA8PSBiCiAgICBmcmFtZV9kaWcgLTIKICAgIGZyYW1lX2RpZyAtMQogICAgPD0KICAgIC8vIHRlc3RzL2FydGlmYWN0cy9wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTA0CiAgICAvLyByZXR1cm4gcmVzdWx0CiAgICByZXRzdWIKCgovLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjpQcmltaXRpdmVPcHNDb250cmFjdC52ZXJpZnlfdWludDY0X2d0KGE6IHVpbnQ2NCwgYjogdWludDY0KSAtPiB1aW50NjQ6CnZlcmlmeV91aW50NjRfZ3Q6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjEwNy0xMDgKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBwdWJsaWMgdmVyaWZ5X3VpbnQ2NF9ndChhOiB1aW50NjQsIGI6IHVpbnQ2NCk6IGJvb2xlYW4gewogICAgcHJvdG8gMiAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjEwOQogICAgLy8gY29uc3QgcmVzdWx0ID0gYSA+IGIKICAgIGZyYW1lX2RpZyAtMgogICAgZnJhbWVfZGlnIC0xCiAgICA+CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjExMAogICAgLy8gcmV0dXJuIHJlc3VsdAogICAgcmV0c3ViCgoKLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo6UHJpbWl0aXZlT3BzQ29udHJhY3QudmVyaWZ5X3VpbnQ2NF9nZShhOiB1aW50NjQsIGI6IHVpbnQ2NCkgLT4gdWludDY0Ogp2ZXJpZnlfdWludDY0X2dlOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoxMTMtMTE0CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gcHVibGljIHZlcmlmeV91aW50NjRfZ2UoYTogdWludDY0LCBiOiB1aW50NjQpOiBib29sZWFuIHsKICAgIHByb3RvIDIgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoxMTUKICAgIC8vIGNvbnN0IHJlc3VsdCA9IGEgPj0gYgogICAgZnJhbWVfZGlnIC0yCiAgICBmcmFtZV9kaWcgLTEKICAgID49CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjExNgogICAgLy8gcmV0dXJuIHJlc3VsdAogICAgcmV0c3ViCgoKLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo6UHJpbWl0aXZlT3BzQ29udHJhY3QudmVyaWZ5X2J5dGVzX2luaXQocmF3X3ZhbHVlOiB1aW50NjQpIC0+IGJ5dGVzOgp2ZXJpZnlfYnl0ZXNfaW5pdDoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTE5LTEyMAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIHB1YmxpYyB2ZXJpZnlfYnl0ZXNfaW5pdChyYXdfdmFsdWU6IHVpbnQ2NCk6IGJ5dGVzIHsKICAgIHByb3RvIDEgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoxMjEKICAgIC8vIGNvbnN0IHJlc3VsdCA9IG9wLml0b2IocmF3X3ZhbHVlKQogICAgZnJhbWVfZGlnIC0xCiAgICBpdG9iCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjEyMgogICAgLy8gcmV0dXJuIHJlc3VsdAogICAgcmV0c3ViCgoKLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo6UHJpbWl0aXZlT3BzQ29udHJhY3QudmVyaWZ5X2J5dGVzX2FkZChhOiBieXRlcywgYjogYnl0ZXMsIHBhZF9hX3NpemU6IHVpbnQ2NCwgcGFkX2Jfc2l6ZTogdWludDY0KSAtPiBieXRlczoKdmVyaWZ5X2J5dGVzX2FkZDoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTI1LTEyNgogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIHB1YmxpYyB2ZXJpZnlfYnl0ZXNfYWRkKGE6IGJ5dGVzLCBiOiBieXRlcywgcGFkX2Ffc2l6ZTogdWludDY0LCBwYWRfYl9zaXplOiB1aW50NjQpOiBieXRlcyB7CiAgICBwcm90byA0IDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTI3CiAgICAvLyBjb25zdCBwYWRkZWRBID0gb3AuYnplcm8ocGFkX2Ffc2l6ZSkuY29uY2F0KGEpCiAgICBmcmFtZV9kaWcgLTIKICAgIGJ6ZXJvCiAgICBmcmFtZV9kaWcgLTQKICAgIGNvbmNhdAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoxMjgKICAgIC8vIGNvbnN0IHBhZGRlZEIgPSBvcC5iemVybyhwYWRfYl9zaXplKS5jb25jYXQoYikKICAgIGZyYW1lX2RpZyAtMQogICAgYnplcm8KICAgIGZyYW1lX2RpZyAtMwogICAgY29uY2F0CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjEyOQogICAgLy8gY29uc3QgcmVzdWx0ID0gcGFkZGVkQS5jb25jYXQocGFkZGVkQikKICAgIGNvbmNhdAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoxMzAKICAgIC8vIGNvbnN0IHJlc3VsdEhhc2ggPSBvcC5zaGEyNTYocmVzdWx0KQogICAgc2hhMjU2CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjEzMQogICAgLy8gcmV0dXJuIHJlc3VsdEhhc2gKICAgIHJldHN1YgoKCi8vIHRlc3RzL2FydGlmYWN0cy9wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OlByaW1pdGl2ZU9wc0NvbnRyYWN0LnZlcmlmeV9ieXRlc19lcShhOiBieXRlcywgYjogYnl0ZXMpIC0+IHVpbnQ2NDoKdmVyaWZ5X2J5dGVzX2VxOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoxMzQtMTM1CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gcHVibGljIHZlcmlmeV9ieXRlc19lcShhOiBieXRlcywgYjogYnl0ZXMpOiBib29sZWFuIHsKICAgIHByb3RvIDIgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoxMzYKICAgIC8vIGNvbnN0IHJlc3VsdCA9IGEgPT09IGIKICAgIGZyYW1lX2RpZyAtMgogICAgZnJhbWVfZGlnIC0xCiAgICA9PQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoxMzcKICAgIC8vIHJldHVybiByZXN1bHQKICAgIHJldHN1YgoKCi8vIHRlc3RzL2FydGlmYWN0cy9wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OlByaW1pdGl2ZU9wc0NvbnRyYWN0LnZlcmlmeV9ieXRlc19uZShhOiBieXRlcywgYjogYnl0ZXMpIC0+IHVpbnQ2NDoKdmVyaWZ5X2J5dGVzX25lOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoxNDAtMTQxCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gcHVibGljIHZlcmlmeV9ieXRlc19uZShhOiBieXRlcywgYjogYnl0ZXMpOiBib29sZWFuIHsKICAgIHByb3RvIDIgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoxNDIKICAgIC8vIGNvbnN0IHJlc3VsdCA9IGEgIT09IGIKICAgIGZyYW1lX2RpZyAtMgogICAgZnJhbWVfZGlnIC0xCiAgICAhPQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoxNDMKICAgIC8vIHJldHVybiByZXN1bHQKICAgIHJldHN1YgoKCi8vIHRlc3RzL2FydGlmYWN0cy9wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OlByaW1pdGl2ZU9wc0NvbnRyYWN0LnZlcmlmeV9ieXRlc19hbmQoYTogYnl0ZXMsIGI6IGJ5dGVzKSAtPiBieXRlczoKdmVyaWZ5X2J5dGVzX2FuZDoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTQ2LTE0NwogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIHB1YmxpYyB2ZXJpZnlfYnl0ZXNfYW5kKGE6IGJ5dGVzLCBiOiBieXRlcyk6IGJ5dGVzIHsKICAgIHByb3RvIDIgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoxNDgKICAgIC8vIGNvbnN0IHJlc3VsdCA9IGEuYml0d2lzZUFuZChiKQogICAgZnJhbWVfZGlnIC0yCiAgICBmcmFtZV9kaWcgLTEKICAgIGImCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjE0OQogICAgLy8gcmV0dXJuIHJlc3VsdAogICAgcmV0c3ViCgoKLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo6UHJpbWl0aXZlT3BzQ29udHJhY3QudmVyaWZ5X2J5dGVzX29yKGE6IGJ5dGVzLCBiOiBieXRlcykgLT4gYnl0ZXM6CnZlcmlmeV9ieXRlc19vcjoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTUyLTE1MwogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIHB1YmxpYyB2ZXJpZnlfYnl0ZXNfb3IoYTogYnl0ZXMsIGI6IGJ5dGVzKTogYnl0ZXMgewogICAgcHJvdG8gMiAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjE1NAogICAgLy8gY29uc3QgcmVzdWx0ID0gYS5iaXR3aXNlT3IoYikKICAgIGZyYW1lX2RpZyAtMgogICAgZnJhbWVfZGlnIC0xCiAgICBifAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoxNTUKICAgIC8vIHJldHVybiByZXN1bHQKICAgIHJldHN1YgoKCi8vIHRlc3RzL2FydGlmYWN0cy9wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OlByaW1pdGl2ZU9wc0NvbnRyYWN0LnZlcmlmeV9ieXRlc194b3IoYTogYnl0ZXMsIGI6IGJ5dGVzKSAtPiBieXRlczoKdmVyaWZ5X2J5dGVzX3hvcjoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTU4LTE1OQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIHB1YmxpYyB2ZXJpZnlfYnl0ZXNfeG9yKGE6IGJ5dGVzLCBiOiBieXRlcyk6IGJ5dGVzIHsKICAgIHByb3RvIDIgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoxNjAKICAgIC8vIGNvbnN0IHJlc3VsdCA9IGEuYml0d2lzZVhvcihiKQogICAgZnJhbWVfZGlnIC0yCiAgICBmcmFtZV9kaWcgLTEKICAgIGJeCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjE2MQogICAgLy8gcmV0dXJuIHJlc3VsdAogICAgcmV0c3ViCgoKLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo6UHJpbWl0aXZlT3BzQ29udHJhY3QudmVyaWZ5X2J5dGVzX25vdChhOiBieXRlcywgcGFkX3NpemU6IHVpbnQ2NCkgLT4gYnl0ZXM6CnZlcmlmeV9ieXRlc19ub3Q6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjE2NC0xNjUKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBwdWJsaWMgdmVyaWZ5X2J5dGVzX25vdChhOiBieXRlcywgcGFkX3NpemU6IHVpbnQ2NCk6IGJ5dGVzIHsKICAgIHByb3RvIDIgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoxNjYKICAgIC8vIGNvbnN0IHBhZGRlZEEgPSBvcC5iemVybyhwYWRfc2l6ZSkuY29uY2F0KGEpCiAgICBmcmFtZV9kaWcgLTEKICAgIGJ6ZXJvCiAgICBmcmFtZV9kaWcgLTIKICAgIGNvbmNhdAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoxNjcKICAgIC8vIGNvbnN0IHJlc3VsdCA9IHBhZGRlZEEuYml0d2lzZUludmVydCgpCiAgICBifgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoxNjgKICAgIC8vIGNvbnN0IHJlc3VsdEhhc2ggPSBvcC5zaGEyNTYocmVzdWx0KQogICAgc2hhMjU2CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjE2OQogICAgLy8gcmV0dXJuIHJlc3VsdEhhc2gKICAgIHJldHN1YgoKCi8vIHRlc3RzL2FydGlmYWN0cy9wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OlByaW1pdGl2ZU9wc0NvbnRyYWN0LnZlcmlmeV9iaWd1aW50X2FkZChhOiBieXRlcywgYjogYnl0ZXMpIC0+IGJ5dGVzOgp2ZXJpZnlfYmlndWludF9hZGQ6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjE3Mi0xNzMKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBwdWJsaWMgdmVyaWZ5X2JpZ3VpbnRfYWRkKGE6IGJ5dGVzLCBiOiBieXRlcyk6IGJ5dGVzIHsKICAgIHByb3RvIDIgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoxNzYKICAgIC8vIGNvbnN0IHJlc3VsdDogYmlndWludCA9IGFfYmlndWludCArIGJfYmlndWludAogICAgZnJhbWVfZGlnIC0yCiAgICBmcmFtZV9kaWcgLTEKICAgIGIrCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjE3NwogICAgLy8gcmV0dXJuIEJ5dGVzKHJlc3VsdCkKICAgIHJldHN1YgoKCi8vIHRlc3RzL2FydGlmYWN0cy9wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OlByaW1pdGl2ZU9wc0NvbnRyYWN0LnZlcmlmeV9iaWd1aW50X2FkZF91aW50NjQoYTogYnl0ZXMsIGI6IHVpbnQ2NCkgLT4gYnl0ZXM6CnZlcmlmeV9iaWd1aW50X2FkZF91aW50NjQ6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjE4MC0xODEKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBwdWJsaWMgdmVyaWZ5X2JpZ3VpbnRfYWRkX3VpbnQ2NChhOiBieXRlcywgYjogdWludDY0KTogYnl0ZXMgewogICAgcHJvdG8gMiAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjE4MwogICAgLy8gY29uc3QgYl9iaWd1aW50ID0gQmlnVWludChiKQogICAgZnJhbWVfZGlnIC0xCiAgICBpdG9iCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjE4NAogICAgLy8gY29uc3QgcmVzdWx0OiBiaWd1aW50ID0gYV9iaWd1aW50ICsgYl9iaWd1aW50CiAgICBmcmFtZV9kaWcgLTIKICAgIGIrCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjE4NQogICAgLy8gcmV0dXJuIEJ5dGVzKHJlc3VsdCkKICAgIHJldHN1YgoKCi8vIHRlc3RzL2FydGlmYWN0cy9wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OlByaW1pdGl2ZU9wc0NvbnRyYWN0LnZlcmlmeV9iaWd1aW50X3N1YihhOiBieXRlcywgYjogYnl0ZXMpIC0+IGJ5dGVzOgp2ZXJpZnlfYmlndWludF9zdWI6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjE4OC0xODkKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBwdWJsaWMgdmVyaWZ5X2JpZ3VpbnRfc3ViKGE6IGJ5dGVzLCBiOiBieXRlcyk6IGJ5dGVzIHsKICAgIHByb3RvIDIgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoxOTIKICAgIC8vIGNvbnN0IHJlc3VsdDogYmlndWludCA9IGFfYmlndWludCAtIGJfYmlndWludAogICAgZnJhbWVfZGlnIC0yCiAgICBmcmFtZV9kaWcgLTEKICAgIGItCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjE5MwogICAgLy8gcmV0dXJuIEJ5dGVzKHJlc3VsdCkKICAgIHJldHN1YgoKCi8vIHRlc3RzL2FydGlmYWN0cy9wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OlByaW1pdGl2ZU9wc0NvbnRyYWN0LnZlcmlmeV9iaWd1aW50X3N1Yl91aW50NjQoYTogYnl0ZXMsIGI6IHVpbnQ2NCkgLT4gYnl0ZXM6CnZlcmlmeV9iaWd1aW50X3N1Yl91aW50NjQ6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjE5Ni0xOTcKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBwdWJsaWMgdmVyaWZ5X2JpZ3VpbnRfc3ViX3VpbnQ2NChhOiBieXRlcywgYjogdWludDY0KTogYnl0ZXMgewogICAgcHJvdG8gMiAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjE5OQogICAgLy8gY29uc3QgYl9iaWd1aW50ID0gQmlnVWludChiKQogICAgZnJhbWVfZGlnIC0xCiAgICBpdG9iCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjIwMAogICAgLy8gY29uc3QgcmVzdWx0OiBiaWd1aW50ID0gYV9iaWd1aW50IC0gYl9iaWd1aW50CiAgICBmcmFtZV9kaWcgLTIKICAgIHN3YXAKICAgIGItCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjIwMQogICAgLy8gcmV0dXJuIEJ5dGVzKHJlc3VsdCkKICAgIHJldHN1YgoKCi8vIHRlc3RzL2FydGlmYWN0cy9wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OlByaW1pdGl2ZU9wc0NvbnRyYWN0LnZlcmlmeV9iaWd1aW50X211bChhOiBieXRlcywgYjogYnl0ZXMpIC0+IGJ5dGVzOgp2ZXJpZnlfYmlndWludF9tdWw6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjIwNC0yMDUKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBwdWJsaWMgdmVyaWZ5X2JpZ3VpbnRfbXVsKGE6IGJ5dGVzLCBiOiBieXRlcyk6IGJ5dGVzIHsKICAgIHByb3RvIDIgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoyMDgKICAgIC8vIGNvbnN0IHJlc3VsdDogYmlndWludCA9IGFfYmlndWludCAqIGJfYmlndWludAogICAgZnJhbWVfZGlnIC0yCiAgICBmcmFtZV9kaWcgLTEKICAgIGIqCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjIwOQogICAgLy8gcmV0dXJuIEJ5dGVzKHJlc3VsdCkKICAgIHJldHN1YgoKCi8vIHRlc3RzL2FydGlmYWN0cy9wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OlByaW1pdGl2ZU9wc0NvbnRyYWN0LnZlcmlmeV9iaWd1aW50X211bF91aW50NjQoYTogYnl0ZXMsIGI6IHVpbnQ2NCkgLT4gYnl0ZXM6CnZlcmlmeV9iaWd1aW50X211bF91aW50NjQ6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjIxMi0yMTMKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBwdWJsaWMgdmVyaWZ5X2JpZ3VpbnRfbXVsX3VpbnQ2NChhOiBieXRlcywgYjogdWludDY0KTogYnl0ZXMgewogICAgcHJvdG8gMiAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjIxNQogICAgLy8gY29uc3QgYl9iaWd1aW50ID0gQmlnVWludChiKQogICAgZnJhbWVfZGlnIC0xCiAgICBpdG9iCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjIxNgogICAgLy8gY29uc3QgcmVzdWx0OiBiaWd1aW50ID0gYV9iaWd1aW50ICogYl9iaWd1aW50CiAgICBmcmFtZV9kaWcgLTIKICAgIGIqCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjIxNwogICAgLy8gcmV0dXJuIEJ5dGVzKHJlc3VsdCkKICAgIHJldHN1YgoKCi8vIHRlc3RzL2FydGlmYWN0cy9wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OlByaW1pdGl2ZU9wc0NvbnRyYWN0LnZlcmlmeV9iaWd1aW50X2RpdihhOiBieXRlcywgYjogYnl0ZXMpIC0+IGJ5dGVzOgp2ZXJpZnlfYmlndWludF9kaXY6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjIyMC0yMjEKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBwdWJsaWMgdmVyaWZ5X2JpZ3VpbnRfZGl2KGE6IGJ5dGVzLCBiOiBieXRlcyk6IGJ5dGVzIHsKICAgIHByb3RvIDIgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoyMjQKICAgIC8vIGNvbnN0IHJlc3VsdDogYmlndWludCA9IGFfYmlndWludCAvIGJfYmlndWludAogICAgZnJhbWVfZGlnIC0yCiAgICBmcmFtZV9kaWcgLTEKICAgIGIvCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjIyNQogICAgLy8gcmV0dXJuIEJ5dGVzKHJlc3VsdCkKICAgIHJldHN1YgoKCi8vIHRlc3RzL2FydGlmYWN0cy9wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OlByaW1pdGl2ZU9wc0NvbnRyYWN0LnZlcmlmeV9iaWd1aW50X2Rpdl91aW50NjQoYTogYnl0ZXMsIGI6IHVpbnQ2NCkgLT4gYnl0ZXM6CnZlcmlmeV9iaWd1aW50X2Rpdl91aW50NjQ6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjIyOC0yMjkKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBwdWJsaWMgdmVyaWZ5X2JpZ3VpbnRfZGl2X3VpbnQ2NChhOiBieXRlcywgYjogdWludDY0KTogYnl0ZXMgewogICAgcHJvdG8gMiAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjIzMQogICAgLy8gY29uc3QgYl9iaWd1aW50ID0gQmlnVWludChiKQogICAgZnJhbWVfZGlnIC0xCiAgICBpdG9iCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjIzMgogICAgLy8gY29uc3QgcmVzdWx0OiBiaWd1aW50ID0gYV9iaWd1aW50IC8gYl9iaWd1aW50CiAgICBmcmFtZV9kaWcgLTIKICAgIHN3YXAKICAgIGIvCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjIzMwogICAgLy8gcmV0dXJuIEJ5dGVzKHJlc3VsdCkKICAgIHJldHN1YgoKCi8vIHRlc3RzL2FydGlmYWN0cy9wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OlByaW1pdGl2ZU9wc0NvbnRyYWN0LnZlcmlmeV9iaWd1aW50X21vZChhOiBieXRlcywgYjogYnl0ZXMpIC0+IGJ5dGVzOgp2ZXJpZnlfYmlndWludF9tb2Q6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjIzNi0yMzcKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBwdWJsaWMgdmVyaWZ5X2JpZ3VpbnRfbW9kKGE6IGJ5dGVzLCBiOiBieXRlcyk6IGJ5dGVzIHsKICAgIHByb3RvIDIgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoyNDAKICAgIC8vIGNvbnN0IHJlc3VsdDogYmlndWludCA9IGFfYmlndWludCAlIGJfYmlndWludAogICAgZnJhbWVfZGlnIC0yCiAgICBmcmFtZV9kaWcgLTEKICAgIGIlCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjI0MQogICAgLy8gcmV0dXJuIEJ5dGVzKHJlc3VsdCkKICAgIHJldHN1YgoKCi8vIHRlc3RzL2FydGlmYWN0cy9wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OlByaW1pdGl2ZU9wc0NvbnRyYWN0LnZlcmlmeV9iaWd1aW50X21vZF91aW50NjQoYTogYnl0ZXMsIGI6IHVpbnQ2NCkgLT4gYnl0ZXM6CnZlcmlmeV9iaWd1aW50X21vZF91aW50NjQ6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjI0NC0yNDUKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBwdWJsaWMgdmVyaWZ5X2JpZ3VpbnRfbW9kX3VpbnQ2NChhOiBieXRlcywgYjogdWludDY0KTogYnl0ZXMgewogICAgcHJvdG8gMiAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjI0NwogICAgLy8gY29uc3QgYl9iaWd1aW50ID0gQmlnVWludChiKQogICAgZnJhbWVfZGlnIC0xCiAgICBpdG9iCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjI0OAogICAgLy8gY29uc3QgcmVzdWx0OiBiaWd1aW50ID0gYV9iaWd1aW50ICUgYl9iaWd1aW50CiAgICBmcmFtZV9kaWcgLTIKICAgIHN3YXAKICAgIGIlCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjI0OQogICAgLy8gcmV0dXJuIEJ5dGVzKHJlc3VsdCkKICAgIHJldHN1YgoKCi8vIHRlc3RzL2FydGlmYWN0cy9wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OlByaW1pdGl2ZU9wc0NvbnRyYWN0LnZlcmlmeV9iaWd1aW50X2FuZChhOiBieXRlcywgYjogYnl0ZXMpIC0+IGJ5dGVzOgp2ZXJpZnlfYmlndWludF9hbmQ6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjI1Mi0yNTMKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBwdWJsaWMgdmVyaWZ5X2JpZ3VpbnRfYW5kKGE6IGJ5dGVzLCBiOiBieXRlcyk6IGJ5dGVzIHsKICAgIHByb3RvIDIgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoyNTYKICAgIC8vIGNvbnN0IHJlc3VsdDogYmlndWludCA9IGFfYmlndWludCAmIGJfYmlndWludAogICAgZnJhbWVfZGlnIC0yCiAgICBmcmFtZV9kaWcgLTEKICAgIGImCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjI1NwogICAgLy8gcmV0dXJuIEJ5dGVzKHJlc3VsdCkKICAgIHJldHN1YgoKCi8vIHRlc3RzL2FydGlmYWN0cy9wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OlByaW1pdGl2ZU9wc0NvbnRyYWN0LnZlcmlmeV9iaWd1aW50X2FuZF91aW50NjQoYTogYnl0ZXMsIGI6IHVpbnQ2NCkgLT4gYnl0ZXM6CnZlcmlmeV9iaWd1aW50X2FuZF91aW50NjQ6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjI2MC0yNjEKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBwdWJsaWMgdmVyaWZ5X2JpZ3VpbnRfYW5kX3VpbnQ2NChhOiBieXRlcywgYjogdWludDY0KTogYnl0ZXMgewogICAgcHJvdG8gMiAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjI2MwogICAgLy8gY29uc3QgYl9iaWd1aW50ID0gQmlnVWludChiKQogICAgZnJhbWVfZGlnIC0xCiAgICBpdG9iCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjI2NAogICAgLy8gY29uc3QgcmVzdWx0OiBiaWd1aW50ID0gYV9iaWd1aW50ICYgYl9iaWd1aW50CiAgICBmcmFtZV9kaWcgLTIKICAgIGImCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjI2NQogICAgLy8gcmV0dXJuIEJ5dGVzKHJlc3VsdCkKICAgIHJldHN1YgoKCi8vIHRlc3RzL2FydGlmYWN0cy9wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OlByaW1pdGl2ZU9wc0NvbnRyYWN0LnZlcmlmeV9iaWd1aW50X29yKGE6IGJ5dGVzLCBiOiBieXRlcykgLT4gYnl0ZXM6CnZlcmlmeV9iaWd1aW50X29yOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoyNjgtMjY5CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gcHVibGljIHZlcmlmeV9iaWd1aW50X29yKGE6IGJ5dGVzLCBiOiBieXRlcyk6IGJ5dGVzIHsKICAgIHByb3RvIDIgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoyNzIKICAgIC8vIGNvbnN0IHJlc3VsdDogYmlndWludCA9IGFfYmlndWludCB8IGJfYmlndWludAogICAgZnJhbWVfZGlnIC0yCiAgICBmcmFtZV9kaWcgLTEKICAgIGJ8CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjI3MwogICAgLy8gcmV0dXJuIEJ5dGVzKHJlc3VsdCkKICAgIHJldHN1YgoKCi8vIHRlc3RzL2FydGlmYWN0cy9wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OlByaW1pdGl2ZU9wc0NvbnRyYWN0LnZlcmlmeV9iaWd1aW50X29yX3VpbnQ2NChhOiBieXRlcywgYjogdWludDY0KSAtPiBieXRlczoKdmVyaWZ5X2JpZ3VpbnRfb3JfdWludDY0OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoyNzYtMjc3CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gcHVibGljIHZlcmlmeV9iaWd1aW50X29yX3VpbnQ2NChhOiBieXRlcywgYjogdWludDY0KTogYnl0ZXMgewogICAgcHJvdG8gMiAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjI3OQogICAgLy8gY29uc3QgYl9iaWd1aW50ID0gQmlnVWludChiKQogICAgZnJhbWVfZGlnIC0xCiAgICBpdG9iCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjI4MAogICAgLy8gY29uc3QgcmVzdWx0OiBiaWd1aW50ID0gYV9iaWd1aW50IHwgYl9iaWd1aW50CiAgICBmcmFtZV9kaWcgLTIKICAgIGJ8CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjI4MQogICAgLy8gcmV0dXJuIEJ5dGVzKHJlc3VsdCkKICAgIHJldHN1YgoKCi8vIHRlc3RzL2FydGlmYWN0cy9wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OlByaW1pdGl2ZU9wc0NvbnRyYWN0LnZlcmlmeV9iaWd1aW50X3hvcihhOiBieXRlcywgYjogYnl0ZXMpIC0+IGJ5dGVzOgp2ZXJpZnlfYmlndWludF94b3I6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjI4NC0yODUKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBwdWJsaWMgdmVyaWZ5X2JpZ3VpbnRfeG9yKGE6IGJ5dGVzLCBiOiBieXRlcyk6IGJ5dGVzIHsKICAgIHByb3RvIDIgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoyODgKICAgIC8vIGNvbnN0IHJlc3VsdDogYmlndWludCA9IGFfYmlndWludCBeIGJfYmlndWludAogICAgZnJhbWVfZGlnIC0yCiAgICBmcmFtZV9kaWcgLTEKICAgIGJeCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjI4OQogICAgLy8gcmV0dXJuIEJ5dGVzKHJlc3VsdCkKICAgIHJldHN1YgoKCi8vIHRlc3RzL2FydGlmYWN0cy9wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OlByaW1pdGl2ZU9wc0NvbnRyYWN0LnZlcmlmeV9iaWd1aW50X3hvcl91aW50NjQoYTogYnl0ZXMsIGI6IHVpbnQ2NCkgLT4gYnl0ZXM6CnZlcmlmeV9iaWd1aW50X3hvcl91aW50NjQ6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjI5Mi0yOTMKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBwdWJsaWMgdmVyaWZ5X2JpZ3VpbnRfeG9yX3VpbnQ2NChhOiBieXRlcywgYjogdWludDY0KTogYnl0ZXMgewogICAgcHJvdG8gMiAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjI5NQogICAgLy8gY29uc3QgYl9iaWd1aW50ID0gQmlnVWludChiKQogICAgZnJhbWVfZGlnIC0xCiAgICBpdG9iCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjI5NgogICAgLy8gY29uc3QgcmVzdWx0OiBiaWd1aW50ID0gYV9iaWd1aW50IF4gYl9iaWd1aW50CiAgICBmcmFtZV9kaWcgLTIKICAgIGJeCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjI5NwogICAgLy8gcmV0dXJuIEJ5dGVzKHJlc3VsdCkKICAgIHJldHN1YgoKCi8vIHRlc3RzL2FydGlmYWN0cy9wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OlByaW1pdGl2ZU9wc0NvbnRyYWN0LnZlcmlmeV9iaWd1aW50X2VxKGE6IGJ5dGVzLCBiOiBieXRlcykgLT4gdWludDY0Ogp2ZXJpZnlfYmlndWludF9lcToKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MzAwLTMwMQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIHB1YmxpYyB2ZXJpZnlfYmlndWludF9lcShhOiBieXRlcywgYjogYnl0ZXMpOiBib29sZWFuIHsKICAgIHByb3RvIDIgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czozMDQKICAgIC8vIGNvbnN0IHJlc3VsdCA9IGFfYmlndWludCA9PT0gYl9iaWd1aW50CiAgICBmcmFtZV9kaWcgLTIKICAgIGZyYW1lX2RpZyAtMQogICAgYj09CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjMwNQogICAgLy8gcmV0dXJuIHJlc3VsdAogICAgcmV0c3ViCgoKLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo6UHJpbWl0aXZlT3BzQ29udHJhY3QudmVyaWZ5X2JpZ3VpbnRfZXFfdWludDY0KGE6IGJ5dGVzLCBiOiB1aW50NjQpIC0+IHVpbnQ2NDoKdmVyaWZ5X2JpZ3VpbnRfZXFfdWludDY0OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czozMDgtMzA5CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gcHVibGljIHZlcmlmeV9iaWd1aW50X2VxX3VpbnQ2NChhOiBieXRlcywgYjogdWludDY0KTogYm9vbGVhbiB7CiAgICBwcm90byAyIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MzExCiAgICAvLyBjb25zdCByZXN1bHQgPSBhX2JpZ3VpbnQgPT09IEJpZ1VpbnQoYikKICAgIGZyYW1lX2RpZyAtMQogICAgaXRvYgogICAgZnJhbWVfZGlnIC0yCiAgICBiPT0KICAgIC8vIHRlc3RzL2FydGlmYWN0cy9wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MzEyCiAgICAvLyByZXR1cm4gcmVzdWx0CiAgICByZXRzdWIKCgovLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjpQcmltaXRpdmVPcHNDb250cmFjdC52ZXJpZnlfYmlndWludF9uZShhOiBieXRlcywgYjogYnl0ZXMpIC0+IHVpbnQ2NDoKdmVyaWZ5X2JpZ3VpbnRfbmU6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjMxNS0zMTYKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBwdWJsaWMgdmVyaWZ5X2JpZ3VpbnRfbmUoYTogYnl0ZXMsIGI6IGJ5dGVzKTogYm9vbGVhbiB7CiAgICBwcm90byAyIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MzE5CiAgICAvLyBjb25zdCByZXN1bHQgPSBhX2JpZ3VpbnQgIT09IGJfYmlndWludAogICAgZnJhbWVfZGlnIC0yCiAgICBmcmFtZV9kaWcgLTEKICAgIGIhPQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czozMjAKICAgIC8vIHJldHVybiByZXN1bHQKICAgIHJldHN1YgoKCi8vIHRlc3RzL2FydGlmYWN0cy9wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OlByaW1pdGl2ZU9wc0NvbnRyYWN0LnZlcmlmeV9iaWd1aW50X25lX3VpbnQ2NChhOiBieXRlcywgYjogdWludDY0KSAtPiB1aW50NjQ6CnZlcmlmeV9iaWd1aW50X25lX3VpbnQ2NDoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MzIzLTMyNAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIHB1YmxpYyB2ZXJpZnlfYmlndWludF9uZV91aW50NjQoYTogYnl0ZXMsIGI6IHVpbnQ2NCk6IGJvb2xlYW4gewogICAgcHJvdG8gMiAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjMyNgogICAgLy8gY29uc3QgcmVzdWx0ID0gYV9iaWd1aW50ICE9PSBCaWdVaW50KGIpCiAgICBmcmFtZV9kaWcgLTEKICAgIGl0b2IKICAgIGZyYW1lX2RpZyAtMgogICAgYiE9CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjMyNwogICAgLy8gcmV0dXJuIHJlc3VsdAogICAgcmV0c3ViCgoKLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo6UHJpbWl0aXZlT3BzQ29udHJhY3QudmVyaWZ5X2JpZ3VpbnRfbHQoYTogYnl0ZXMsIGI6IGJ5dGVzKSAtPiB1aW50NjQ6CnZlcmlmeV9iaWd1aW50X2x0OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czozMzAtMzMxCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gcHVibGljIHZlcmlmeV9iaWd1aW50X2x0KGE6IGJ5dGVzLCBiOiBieXRlcyk6IGJvb2xlYW4gewogICAgcHJvdG8gMiAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjMzNAogICAgLy8gY29uc3QgcmVzdWx0ID0gYV9iaWd1aW50IDwgYl9iaWd1aW50CiAgICBmcmFtZV9kaWcgLTIKICAgIGZyYW1lX2RpZyAtMQogICAgYjwKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MzM1CiAgICAvLyByZXR1cm4gcmVzdWx0CiAgICByZXRzdWIKCgovLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjpQcmltaXRpdmVPcHNDb250cmFjdC52ZXJpZnlfYmlndWludF9sdF91aW50NjQoYTogYnl0ZXMsIGI6IHVpbnQ2NCkgLT4gdWludDY0Ogp2ZXJpZnlfYmlndWludF9sdF91aW50NjQ6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjMzOC0zMzkKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBwdWJsaWMgdmVyaWZ5X2JpZ3VpbnRfbHRfdWludDY0KGE6IGJ5dGVzLCBiOiB1aW50NjQpOiBib29sZWFuIHsKICAgIHByb3RvIDIgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czozNDEKICAgIC8vIGNvbnN0IGJfYmlndWludCA9IEJpZ1VpbnQoYikKICAgIGZyYW1lX2RpZyAtMQogICAgaXRvYgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czozNDIKICAgIC8vIGNvbnN0IHJlc3VsdCA9IGFfYmlndWludCA8IGJfYmlndWludAogICAgZnJhbWVfZGlnIC0yCiAgICBiPgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czozNDMKICAgIC8vIHJldHVybiByZXN1bHQKICAgIHJldHN1YgoKCi8vIHRlc3RzL2FydGlmYWN0cy9wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OlByaW1pdGl2ZU9wc0NvbnRyYWN0LnZlcmlmeV9iaWd1aW50X2xlKGE6IGJ5dGVzLCBiOiBieXRlcykgLT4gdWludDY0Ogp2ZXJpZnlfYmlndWludF9sZToKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MzQ2LTM0NwogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIHB1YmxpYyB2ZXJpZnlfYmlndWludF9sZShhOiBieXRlcywgYjogYnl0ZXMpOiBib29sZWFuIHsKICAgIHByb3RvIDIgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czozNTAKICAgIC8vIGNvbnN0IHJlc3VsdCA9IGFfYmlndWludCA8PSBiX2JpZ3VpbnQKICAgIGZyYW1lX2RpZyAtMgogICAgZnJhbWVfZGlnIC0xCiAgICBiPD0KICAgIC8vIHRlc3RzL2FydGlmYWN0cy9wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MzUxCiAgICAvLyByZXR1cm4gcmVzdWx0CiAgICByZXRzdWIKCgovLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjpQcmltaXRpdmVPcHNDb250cmFjdC52ZXJpZnlfYmlndWludF9sZV91aW50NjQoYTogYnl0ZXMsIGI6IHVpbnQ2NCkgLT4gdWludDY0Ogp2ZXJpZnlfYmlndWludF9sZV91aW50NjQ6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjM1NC0zNTUKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBwdWJsaWMgdmVyaWZ5X2JpZ3VpbnRfbGVfdWludDY0KGE6IGJ5dGVzLCBiOiB1aW50NjQpOiBib29sZWFuIHsKICAgIHByb3RvIDIgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czozNTcKICAgIC8vIGNvbnN0IGJfYmlndWludCA9IEJpZ1VpbnQoYikKICAgIGZyYW1lX2RpZyAtMQogICAgaXRvYgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czozNTgKICAgIC8vIGNvbnN0IHJlc3VsdCA9IGFfYmlndWludCA8PSBiX2JpZ3VpbnQKICAgIGZyYW1lX2RpZyAtMgogICAgYj49CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjM1OQogICAgLy8gcmV0dXJuIHJlc3VsdAogICAgcmV0c3ViCgoKLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo6UHJpbWl0aXZlT3BzQ29udHJhY3QudmVyaWZ5X2JpZ3VpbnRfZ3QoYTogYnl0ZXMsIGI6IGJ5dGVzKSAtPiB1aW50NjQ6CnZlcmlmeV9iaWd1aW50X2d0OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czozNjItMzYzCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gcHVibGljIHZlcmlmeV9iaWd1aW50X2d0KGE6IGJ5dGVzLCBiOiBieXRlcyk6IGJvb2xlYW4gewogICAgcHJvdG8gMiAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjM2NgogICAgLy8gY29uc3QgcmVzdWx0ID0gYV9iaWd1aW50ID4gYl9iaWd1aW50CiAgICBmcmFtZV9kaWcgLTIKICAgIGZyYW1lX2RpZyAtMQogICAgYj4KICAgIC8vIHRlc3RzL2FydGlmYWN0cy9wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MzY3CiAgICAvLyByZXR1cm4gcmVzdWx0CiAgICByZXRzdWIKCgovLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjpQcmltaXRpdmVPcHNDb250cmFjdC52ZXJpZnlfYmlndWludF9ndF91aW50NjQoYTogYnl0ZXMsIGI6IHVpbnQ2NCkgLT4gdWludDY0Ogp2ZXJpZnlfYmlndWludF9ndF91aW50NjQ6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjM3MC0zNzEKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBwdWJsaWMgdmVyaWZ5X2JpZ3VpbnRfZ3RfdWludDY0KGE6IGJ5dGVzLCBiOiB1aW50NjQpOiBib29sZWFuIHsKICAgIHByb3RvIDIgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czozNzMKICAgIC8vIGNvbnN0IGJfYmlndWludCA9IEJpZ1VpbnQoYikKICAgIGZyYW1lX2RpZyAtMQogICAgaXRvYgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czozNzQKICAgIC8vIGNvbnN0IHJlc3VsdCA9IGFfYmlndWludCA+IGJfYmlndWludAogICAgZnJhbWVfZGlnIC0yCiAgICBiPAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czozNzUKICAgIC8vIHJldHVybiByZXN1bHQKICAgIHJldHN1YgoKCi8vIHRlc3RzL2FydGlmYWN0cy9wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OlByaW1pdGl2ZU9wc0NvbnRyYWN0LnZlcmlmeV9iaWd1aW50X2dlKGE6IGJ5dGVzLCBiOiBieXRlcykgLT4gdWludDY0Ogp2ZXJpZnlfYmlndWludF9nZToKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6Mzc4LTM3OQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIHB1YmxpYyB2ZXJpZnlfYmlndWludF9nZShhOiBieXRlcywgYjogYnl0ZXMpOiBib29sZWFuIHsKICAgIHByb3RvIDIgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czozODIKICAgIC8vIGNvbnN0IHJlc3VsdCA9IGFfYmlndWludCA+PSBiX2JpZ3VpbnQKICAgIGZyYW1lX2RpZyAtMgogICAgZnJhbWVfZGlnIC0xCiAgICBiPj0KICAgIC8vIHRlc3RzL2FydGlmYWN0cy9wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MzgzCiAgICAvLyByZXR1cm4gcmVzdWx0CiAgICByZXRzdWIKCgovLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjpQcmltaXRpdmVPcHNDb250cmFjdC52ZXJpZnlfYmlndWludF9nZV91aW50NjQoYTogYnl0ZXMsIGI6IHVpbnQ2NCkgLT4gdWludDY0Ogp2ZXJpZnlfYmlndWludF9nZV91aW50NjQ6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjM4Ni0zODcKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBwdWJsaWMgdmVyaWZ5X2JpZ3VpbnRfZ2VfdWludDY0KGE6IGJ5dGVzLCBiOiB1aW50NjQpOiBib29sZWFuIHsKICAgIHByb3RvIDIgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czozODkKICAgIC8vIGNvbnN0IGJfYmlndWludCA9IEJpZ1VpbnQoYikKICAgIGZyYW1lX2RpZyAtMQogICAgaXRvYgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czozOTAKICAgIC8vIGNvbnN0IHJlc3VsdCA9IGFfYmlndWludCA+PSBiX2JpZ3VpbnQKICAgIGZyYW1lX2RpZyAtMgogICAgYjw9CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjM5MQogICAgLy8gcmV0dXJuIHJlc3VsdAogICAgcmV0c3ViCgoKLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo6UHJpbWl0aXZlT3BzQ29udHJhY3QudmVyaWZ5X2xvZyhhOiBieXRlcywgYjogdWludDY0LCBjOiBieXRlcywgZDogYnl0ZXMsIGU6IGJ5dGVzLCBmOiBieXRlcywgZzogYnl0ZXMsIGg6IGJ5dGVzLCBpOiBieXRlcywgajogYnl0ZXMsIGs6IGJ5dGVzLCBtOiBieXRlcywgbjogYnl0ZXMpIC0+IHZvaWQ6CnZlcmlmeV9sb2c6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjM5NS00MTAKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBwdWJsaWMgdmVyaWZ5X2xvZygKICAgIC8vICAgYTogc3RyaW5nLAogICAgLy8gICBiOiB1aW50NjQsCiAgICAvLyAgIGM6IGJ5dGVzLAogICAgLy8gICBkOiBieXRlcywKICAgIC8vICAgZTogQm9vbCwKICAgIC8vICAgZjogU3RyLAogICAgLy8gICBnOiBVaW50Tjw2ND4sCiAgICAvLyAgIGg6IFVpbnROPDI1Nj4sCiAgICAvLyAgIGk6IFVGaXhlZE54TTwzMiwgOD4sCiAgICAvLyAgIGo6IFVGaXhlZE54TTwyNTYsIDE2PiwKICAgIC8vICAgazogYnl0ZXMsCiAgICAvLyAgIG06IGJ5dGVzLAogICAgLy8gICBuOiBieXRlcywKICAgIC8vICkgewogICAgcHJvdG8gMTMgMAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo0MTUKICAgIC8vIGxvZyhhLCBiLCBjLCBkX2JpZ3VpbnQsIGUsIGYsIGcsIGgsIGksIGosIGFyYzRfaywgYXJjNF9tLCBhcmM0X24pCiAgICBmcmFtZV9kaWcgLTEyCiAgICBpdG9iCiAgICBmcmFtZV9kaWcgLTEzCiAgICBzd2FwCiAgICBjb25jYXQKICAgIGZyYW1lX2RpZyAtMTEKICAgIGNvbmNhdAogICAgZnJhbWVfZGlnIC0xMAogICAgY29uY2F0CiAgICBmcmFtZV9kaWcgLTkKICAgIGNvbmNhdAogICAgZnJhbWVfZGlnIC04CiAgICBjb25jYXQKICAgIGZyYW1lX2RpZyAtNwogICAgY29uY2F0CiAgICBmcmFtZV9kaWcgLTYKICAgIGNvbmNhdAogICAgZnJhbWVfZGlnIC01CiAgICBjb25jYXQKICAgIGZyYW1lX2RpZyAtNAogICAgY29uY2F0CiAgICBmcmFtZV9kaWcgLTMKICAgIGNvbmNhdAogICAgZnJhbWVfZGlnIC0yCiAgICBjb25jYXQKICAgIGZyYW1lX2RpZyAtMQogICAgY29uY2F0CiAgICBsb2cKICAgIHJldHN1Ygo=", - "clear": "I3ByYWdtYSB2ZXJzaW9uIDEwCgp0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjpQcmltaXRpdmVPcHNDb250cmFjdC5jbGVhclN0YXRlUHJvZ3JhbToKICAgIHB1c2hpbnQgMSAvLyAxCiAgICByZXR1cm4K" - }, - "events": [], - "templateVariables": {} -} \ No newline at end of file diff --git a/tests/artifacts/primitive-ops/data/PrimitiveOpsContract.clear.teal b/tests/artifacts/primitive-ops/data/PrimitiveOpsContract.clear.teal deleted file mode 100644 index c9f60d3..0000000 --- a/tests/artifacts/primitive-ops/data/PrimitiveOpsContract.clear.teal +++ /dev/null @@ -1,5 +0,0 @@ -#pragma version 10 - -tests/artifacts/primitive-ops/contract.algo.ts::PrimitiveOpsContract.clearStateProgram: - pushint 1 // 1 - return diff --git a/tests/artifacts/state-ops/contract.algo.ts b/tests/artifacts/state-ops/contract.algo.ts index ac97863..840a54d 100644 --- a/tests/artifacts/state-ops/contract.algo.ts +++ b/tests/artifacts/state-ops/contract.algo.ts @@ -1,21 +1,19 @@ +import type { Account, Application, Asset, bytes, uint64 } from '@algorandfoundation/algorand-typescript' import { - Account, - Application, arc4, assert, - Asset, BaseContract, Bytes, - bytes, + contract, Global, GlobalState, itxn, LocalState, + OnCompleteAction, op, TransactionType, Txn, Uint64, - uint64, } from '@algorandfoundation/algorand-typescript' import { Address, Bool, Byte, DynamicBytes, Str, UintN128, UintN64 } from '@algorandfoundation/algorand-typescript/arc4' @@ -23,6 +21,7 @@ function get_1st_ref_index(): uint64 { return op.btoi(Txn.applicationArgs(1)) } +@contract({ name: 'StateAcctParamsGetContract', avmVersion: 11 }) export class StateAcctParamsGetContract extends arc4.Contract { @arc4.abimethod() public verify_acct_balance(a: Account): uint64 { @@ -137,6 +136,15 @@ export class StateAcctParamsGetContract extends arc4.Contract { assert(funded === funded_index, 'expected funded by index to match') return value } + + @arc4.abimethod() + public verify_acct_incentive_eligible(a: Account): boolean { + const [value, funded] = op.AcctParams.acctIncentiveEligible(a) + const [value_index, funded_index] = op.AcctParams.acctIncentiveEligible(get_1st_ref_index()) + assert(value === value_index, 'expected value by index to match') + assert(funded === funded_index, 'expected funded by index to match') + return value + } } export class StateAssetHoldingContract extends arc4.Contract { @@ -471,7 +479,7 @@ export class ITxnOpsContract extends arc4.Contract { public verify_itxn_ops() { op.ITxnCreate.begin() op.ITxnCreate.setTypeEnum(TransactionType.ApplicationCall) - op.ITxnCreate.setOnCompletion(arc4.OnCompleteAction.DeleteApplication) + op.ITxnCreate.setOnCompletion(OnCompleteAction.DeleteApplication) op.ITxnCreate.setApprovalProgram(Bytes.fromHex('068101')) // pages essentially appends @@ -485,7 +493,7 @@ export class ITxnOpsContract extends arc4.Contract { op.ITxnCreate.submit() assert(op.ITxn.receiver === op.Global.creatorAddress) - assert(op.ITxn.amount === Uint64(1000)) + assert(op.ITxn.amount === 1000) assert(op.ITxn.typeEnum === TransactionType.Payment) assert(op.GITxn.typeEnum(0) === TransactionType.ApplicationCall) @@ -570,7 +578,7 @@ export class ItxnDemoContract extends BaseContract { approvalProgram: APPROVE, clearStateProgram: APPROVE, appArgs: args, - onCompletion: arc4.OnCompleteAction.NoOp, + onCompletion: OnCompleteAction.NoOp, note: 'with args param set', }) } else { diff --git a/tests/artifacts/state-ops/data/GlobalStateContract.approval.teal b/tests/artifacts/state-ops/data/GlobalStateContract.approval.teal deleted file mode 100644 index caeee01..0000000 --- a/tests/artifacts/state-ops/data/GlobalStateContract.approval.teal +++ /dev/null @@ -1,1073 +0,0 @@ -#pragma version 10 - -tests/artifacts/state-ops/contract.algo.ts::GlobalStateContract.approvalProgram: - intcblock 1 0 - bytecblock 0x151f7c75 "implicitKeyArc4UintN64" "implicitKeyArc4Str" "implicitKeyArc4Byte" "implicitKeyArc4Bool" "implicitKeyArc4Address" "implicitKeyArc4UintN128" "implicitKeyArc4DynamicBytes" "explicit_key_arc4_uintn64" "explicit_key_arc4_str" "explicit_key_arc4_byte" "explicit_key_arc4_bool" "explicit_key_arc4_address" "explicit_key_arc4_uintn128" "explicit_key_arc4_dynamic_bytes" 0x0000000000000539 0x000548656c6c6f 0x00000010000000000000000000000000 0x000d64796e616d6963206279746573 - txn ApplicationID - bnz main_after_if_else@2 - callsub constructor - -main_after_if_else@2: - callsub __puya_arc4_router__ - return - - -// tests/artifacts/state-ops/contract.algo.ts::GlobalStateContract.constructor() -> void: -constructor: - // tests/artifacts/state-ops/contract.algo.ts:591 - // export class GlobalStateContract extends arc4.Contract { - proto 0 0 - // tests/artifacts/state-ops/contract.algo.ts:593 - // implicitKeyArc4UintN64 = GlobalState({ initialValue: new UintN64(1337) }) - bytec_1 // "implicitKeyArc4UintN64" - bytec 15 // 0x0000000000000539 - app_global_put - // tests/artifacts/state-ops/contract.algo.ts:594 - // implicitKeyArc4Str = GlobalState({ initialValue: new Str('Hello') }) - bytec_2 // "implicitKeyArc4Str" - bytec 16 // 0x000548656c6c6f - app_global_put - // tests/artifacts/state-ops/contract.algo.ts:595 - // implicitKeyArc4Byte = GlobalState({ initialValue: new Byte(0) }) - bytec_3 // "implicitKeyArc4Byte" - pushbytes 0x00 - app_global_put - // tests/artifacts/state-ops/contract.algo.ts:596 - // implicitKeyArc4Bool = GlobalState({ initialValue: new Bool(true) }) - bytec 4 // "implicitKeyArc4Bool" - pushbytes 0x80 - app_global_put - // tests/artifacts/state-ops/contract.algo.ts:597 - // implicitKeyArc4Address = GlobalState({ initialValue: new Address(Global.creatorAddress) }) - bytec 5 // "implicitKeyArc4Address" - global CreatorAddress - app_global_put - // tests/artifacts/state-ops/contract.algo.ts:598 - // implicitKeyArc4UintN128 = GlobalState({ initialValue: new UintN128(2n ** 100n) }) - bytec 6 // "implicitKeyArc4UintN128" - bytec 17 // 0x00000010000000000000000000000000 - app_global_put - // tests/artifacts/state-ops/contract.algo.ts:599 - // implicitKeyArc4DynamicBytes = GlobalState({ initialValue: new DynamicBytes('dynamic bytes') }) - bytec 7 // "implicitKeyArc4DynamicBytes" - bytec 18 // 0x000d64796e616d6963206279746573 - app_global_put - // tests/artifacts/state-ops/contract.algo.ts:602 - // arc4UintN64 = GlobalState({ initialValue: new UintN64(1337), key: 'explicit_key_arc4_uintn64' }) - bytec 8 // "explicit_key_arc4_uintn64" - bytec 15 // 0x0000000000000539 - app_global_put - // tests/artifacts/state-ops/contract.algo.ts:603 - // arc4Str = GlobalState({ initialValue: new Str('Hello'), key: 'explicit_key_arc4_str' }) - bytec 9 // "explicit_key_arc4_str" - bytec 16 // 0x000548656c6c6f - app_global_put - // tests/artifacts/state-ops/contract.algo.ts:604 - // arc4Byte = GlobalState({ initialValue: new Byte(0), key: 'explicit_key_arc4_byte' }) - bytec 10 // "explicit_key_arc4_byte" - pushbytes 0x00 - app_global_put - // tests/artifacts/state-ops/contract.algo.ts:605 - // arc4Bool = GlobalState({ initialValue: new Bool(true), key: 'explicit_key_arc4_bool' }) - bytec 11 // "explicit_key_arc4_bool" - pushbytes 0x80 - app_global_put - // tests/artifacts/state-ops/contract.algo.ts:606 - // arc4Address = GlobalState({ initialValue: new Address(Global.creatorAddress), key: 'explicit_key_arc4_address' }) - bytec 12 // "explicit_key_arc4_address" - global CreatorAddress - app_global_put - // tests/artifacts/state-ops/contract.algo.ts:607 - // arc4UintN128 = GlobalState({ initialValue: new UintN128(2n ** 100n), key: 'explicit_key_arc4_uintn128' }) - bytec 13 // "explicit_key_arc4_uintn128" - bytec 17 // 0x00000010000000000000000000000000 - app_global_put - // tests/artifacts/state-ops/contract.algo.ts:608 - // arc4DynamicBytes = GlobalState({ initialValue: new DynamicBytes('dynamic bytes'), key: 'explicit_key_arc4_dynamic_bytes' }) - bytec 14 // "explicit_key_arc4_dynamic_bytes" - bytec 18 // 0x000d64796e616d6963206279746573 - app_global_put - retsub - - -// tests/artifacts/state-ops/contract.algo.ts::GlobalStateContract.__puya_arc4_router__() -> uint64: -__puya_arc4_router__: - // tests/artifacts/state-ops/contract.algo.ts:591 - // export class GlobalStateContract extends arc4.Contract { - proto 0 1 - txn NumAppArgs - bz __puya_arc4_router___bare_routing@32 - pushbytess 0x8ab7f8bf 0x86ec24f3 0x69128e90 0x68d590e2 0x44ef0681 0x5c21bd60 0xaac8ecb1 0xa15288ce 0x5f23acfd 0xded75033 0x66279e93 0x096e927b 0x106bc00b 0x6ea3f996 0x3df0a2cd 0x8c4d8f80 0x5ec3116d 0x20f56eee 0x1c149a43 0x8e6a1dde 0x87f0869b 0x026469a1 0xf054ab7b 0xd2e646ef 0xe674a270 0xa87e540d 0x58a7404a 0x257708f7 // method "get_implicit_key_arc4_uintn64()uint64", method "get_implicit_key_arc4_str()string", method "get_implicit_key_arc4_byte()byte", method "get_implicit_key_arc4_bool()bool", method "get_implicit_key_arc4_address()address", method "get_implicit_key_arc4_uintn128()uint128", method "get_implicit_key_arc4_dynamic_bytes()byte[]", method "get_arc4_uintn64()uint64", method "get_arc4_str()string", method "get_arc4_byte()byte", method "get_arc4_bool()bool", method "get_arc4_address()address", method "get_arc4_uintn128()uint128", method "get_arc4_dynamic_bytes()byte[]", method "set_implicit_key_arc4_uintn64(uint64)void", method "set_implicit_key_arc4_str(string)void", method "set_implicit_key_arc4_byte(byte)void", method "set_implicit_key_arc4_bool(bool)void", method "set_implicit_key_arc4_address(address)void", method "set_implicit_key_arc4_uintn128(uint128)void", method "set_implicit_key_arc4_dynamic_bytes(byte[])void", method "set_arc4_uintn64(uint64)void", method "set_arc4_str(string)void", method "set_arc4_byte(byte)void", method "set_arc4_bool(bool)void", method "set_arc4_address(address)void", method "set_arc4_uintn128(uint128)void", method "set_arc4_dynamic_bytes(byte[])void" - txna ApplicationArgs 0 - match __puya_arc4_router___get_implicit_key_arc4_uintn64_route@2 __puya_arc4_router___get_implicit_key_arc4_str_route@3 __puya_arc4_router___get_implicit_key_arc4_byte_route@4 __puya_arc4_router___get_implicit_key_arc4_bool_route@5 __puya_arc4_router___get_implicit_key_arc4_address_route@6 __puya_arc4_router___get_implicit_key_arc4_uintn128_route@7 __puya_arc4_router___get_implicit_key_arc4_dynamic_bytes_route@8 __puya_arc4_router___get_arc4_uintn64_route@9 __puya_arc4_router___get_arc4_str_route@10 __puya_arc4_router___get_arc4_byte_route@11 __puya_arc4_router___get_arc4_bool_route@12 __puya_arc4_router___get_arc4_address_route@13 __puya_arc4_router___get_arc4_uintn128_route@14 __puya_arc4_router___get_arc4_dynamic_bytes_route@15 __puya_arc4_router___set_implicit_key_arc4_uintn64_route@16 __puya_arc4_router___set_implicit_key_arc4_str_route@17 __puya_arc4_router___set_implicit_key_arc4_byte_route@18 __puya_arc4_router___set_implicit_key_arc4_bool_route@19 __puya_arc4_router___set_implicit_key_arc4_address_route@20 __puya_arc4_router___set_implicit_key_arc4_uintn128_route@21 __puya_arc4_router___set_implicit_key_arc4_dynamic_bytes_route@22 __puya_arc4_router___set_arc4_uintn64_route@23 __puya_arc4_router___set_arc4_str_route@24 __puya_arc4_router___set_arc4_byte_route@25 __puya_arc4_router___set_arc4_bool_route@26 __puya_arc4_router___set_arc4_address_route@27 __puya_arc4_router___set_arc4_uintn128_route@28 __puya_arc4_router___set_arc4_dynamic_bytes_route@29 - intc_1 // 0 - retsub - -__puya_arc4_router___get_implicit_key_arc4_uintn64_route@2: - // tests/artifacts/state-ops/contract.algo.ts:611 - // @arc4.abimethod() - txn OnCompletion - ! - assert // OnCompletion is not NoOp - txn ApplicationID - assert // can only call when not creating - callsub get_implicit_key_arc4_uintn64 - bytec_0 // 0x151f7c75 - swap - concat - log - intc_0 // 1 - retsub - -__puya_arc4_router___get_implicit_key_arc4_str_route@3: - // tests/artifacts/state-ops/contract.algo.ts:616 - // @arc4.abimethod() - txn OnCompletion - ! - assert // OnCompletion is not NoOp - txn ApplicationID - assert // can only call when not creating - callsub get_implicit_key_arc4_str - bytec_0 // 0x151f7c75 - swap - concat - log - intc_0 // 1 - retsub - -__puya_arc4_router___get_implicit_key_arc4_byte_route@4: - // tests/artifacts/state-ops/contract.algo.ts:621 - // @arc4.abimethod() - txn OnCompletion - ! - assert // OnCompletion is not NoOp - txn ApplicationID - assert // can only call when not creating - callsub get_implicit_key_arc4_byte - bytec_0 // 0x151f7c75 - swap - concat - log - intc_0 // 1 - retsub - -__puya_arc4_router___get_implicit_key_arc4_bool_route@5: - // tests/artifacts/state-ops/contract.algo.ts:626 - // @arc4.abimethod() - txn OnCompletion - ! - assert // OnCompletion is not NoOp - txn ApplicationID - assert // can only call when not creating - callsub get_implicit_key_arc4_bool - bytec_0 // 0x151f7c75 - swap - concat - log - intc_0 // 1 - retsub - -__puya_arc4_router___get_implicit_key_arc4_address_route@6: - // tests/artifacts/state-ops/contract.algo.ts:631 - // @arc4.abimethod() - txn OnCompletion - ! - assert // OnCompletion is not NoOp - txn ApplicationID - assert // can only call when not creating - callsub get_implicit_key_arc4_address - bytec_0 // 0x151f7c75 - swap - concat - log - intc_0 // 1 - retsub - -__puya_arc4_router___get_implicit_key_arc4_uintn128_route@7: - // tests/artifacts/state-ops/contract.algo.ts:636 - // @arc4.abimethod() - txn OnCompletion - ! - assert // OnCompletion is not NoOp - txn ApplicationID - assert // can only call when not creating - callsub get_implicit_key_arc4_uintn128 - bytec_0 // 0x151f7c75 - swap - concat - log - intc_0 // 1 - retsub - -__puya_arc4_router___get_implicit_key_arc4_dynamic_bytes_route@8: - // tests/artifacts/state-ops/contract.algo.ts:641 - // @arc4.abimethod() - txn OnCompletion - ! - assert // OnCompletion is not NoOp - txn ApplicationID - assert // can only call when not creating - callsub get_implicit_key_arc4_dynamic_bytes - bytec_0 // 0x151f7c75 - swap - concat - log - intc_0 // 1 - retsub - -__puya_arc4_router___get_arc4_uintn64_route@9: - // tests/artifacts/state-ops/contract.algo.ts:647 - // @arc4.abimethod() - txn OnCompletion - ! - assert // OnCompletion is not NoOp - txn ApplicationID - assert // can only call when not creating - callsub get_arc4_uintn64 - bytec_0 // 0x151f7c75 - swap - concat - log - intc_0 // 1 - retsub - -__puya_arc4_router___get_arc4_str_route@10: - // tests/artifacts/state-ops/contract.algo.ts:652 - // @arc4.abimethod() - txn OnCompletion - ! - assert // OnCompletion is not NoOp - txn ApplicationID - assert // can only call when not creating - callsub get_arc4_str - bytec_0 // 0x151f7c75 - swap - concat - log - intc_0 // 1 - retsub - -__puya_arc4_router___get_arc4_byte_route@11: - // tests/artifacts/state-ops/contract.algo.ts:657 - // @arc4.abimethod() - txn OnCompletion - ! - assert // OnCompletion is not NoOp - txn ApplicationID - assert // can only call when not creating - callsub get_arc4_byte - bytec_0 // 0x151f7c75 - swap - concat - log - intc_0 // 1 - retsub - -__puya_arc4_router___get_arc4_bool_route@12: - // tests/artifacts/state-ops/contract.algo.ts:662 - // @arc4.abimethod() - txn OnCompletion - ! - assert // OnCompletion is not NoOp - txn ApplicationID - assert // can only call when not creating - callsub get_arc4_bool - bytec_0 // 0x151f7c75 - swap - concat - log - intc_0 // 1 - retsub - -__puya_arc4_router___get_arc4_address_route@13: - // tests/artifacts/state-ops/contract.algo.ts:667 - // @arc4.abimethod() - txn OnCompletion - ! - assert // OnCompletion is not NoOp - txn ApplicationID - assert // can only call when not creating - callsub get_arc4_address - bytec_0 // 0x151f7c75 - swap - concat - log - intc_0 // 1 - retsub - -__puya_arc4_router___get_arc4_uintn128_route@14: - // tests/artifacts/state-ops/contract.algo.ts:672 - // @arc4.abimethod() - txn OnCompletion - ! - assert // OnCompletion is not NoOp - txn ApplicationID - assert // can only call when not creating - callsub get_arc4_uintn128 - bytec_0 // 0x151f7c75 - swap - concat - log - intc_0 // 1 - retsub - -__puya_arc4_router___get_arc4_dynamic_bytes_route@15: - // tests/artifacts/state-ops/contract.algo.ts:677 - // @arc4.abimethod() - txn OnCompletion - ! - assert // OnCompletion is not NoOp - txn ApplicationID - assert // can only call when not creating - callsub get_arc4_dynamic_bytes - bytec_0 // 0x151f7c75 - swap - concat - log - intc_0 // 1 - retsub - -__puya_arc4_router___set_implicit_key_arc4_uintn64_route@16: - // tests/artifacts/state-ops/contract.algo.ts:683 - // @arc4.abimethod() - txn OnCompletion - ! - assert // OnCompletion is not NoOp - txn ApplicationID - assert // can only call when not creating - // tests/artifacts/state-ops/contract.algo.ts:591 - // export class GlobalStateContract extends arc4.Contract { - txna ApplicationArgs 1 - // tests/artifacts/state-ops/contract.algo.ts:683 - // @arc4.abimethod() - callsub set_implicit_key_arc4_uintn64 - intc_0 // 1 - retsub - -__puya_arc4_router___set_implicit_key_arc4_str_route@17: - // tests/artifacts/state-ops/contract.algo.ts:688 - // @arc4.abimethod() - txn OnCompletion - ! - assert // OnCompletion is not NoOp - txn ApplicationID - assert // can only call when not creating - // tests/artifacts/state-ops/contract.algo.ts:591 - // export class GlobalStateContract extends arc4.Contract { - txna ApplicationArgs 1 - // tests/artifacts/state-ops/contract.algo.ts:688 - // @arc4.abimethod() - callsub set_implicit_key_arc4_str - intc_0 // 1 - retsub - -__puya_arc4_router___set_implicit_key_arc4_byte_route@18: - // tests/artifacts/state-ops/contract.algo.ts:693 - // @arc4.abimethod() - txn OnCompletion - ! - assert // OnCompletion is not NoOp - txn ApplicationID - assert // can only call when not creating - // tests/artifacts/state-ops/contract.algo.ts:591 - // export class GlobalStateContract extends arc4.Contract { - txna ApplicationArgs 1 - // tests/artifacts/state-ops/contract.algo.ts:693 - // @arc4.abimethod() - callsub set_implicit_key_arc4_byte - intc_0 // 1 - retsub - -__puya_arc4_router___set_implicit_key_arc4_bool_route@19: - // tests/artifacts/state-ops/contract.algo.ts:698 - // @arc4.abimethod() - txn OnCompletion - ! - assert // OnCompletion is not NoOp - txn ApplicationID - assert // can only call when not creating - // tests/artifacts/state-ops/contract.algo.ts:591 - // export class GlobalStateContract extends arc4.Contract { - txna ApplicationArgs 1 - // tests/artifacts/state-ops/contract.algo.ts:698 - // @arc4.abimethod() - callsub set_implicit_key_arc4_bool - intc_0 // 1 - retsub - -__puya_arc4_router___set_implicit_key_arc4_address_route@20: - // tests/artifacts/state-ops/contract.algo.ts:703 - // @arc4.abimethod() - txn OnCompletion - ! - assert // OnCompletion is not NoOp - txn ApplicationID - assert // can only call when not creating - // tests/artifacts/state-ops/contract.algo.ts:591 - // export class GlobalStateContract extends arc4.Contract { - txna ApplicationArgs 1 - // tests/artifacts/state-ops/contract.algo.ts:703 - // @arc4.abimethod() - callsub set_implicit_key_arc4_address - intc_0 // 1 - retsub - -__puya_arc4_router___set_implicit_key_arc4_uintn128_route@21: - // tests/artifacts/state-ops/contract.algo.ts:708 - // @arc4.abimethod() - txn OnCompletion - ! - assert // OnCompletion is not NoOp - txn ApplicationID - assert // can only call when not creating - // tests/artifacts/state-ops/contract.algo.ts:591 - // export class GlobalStateContract extends arc4.Contract { - txna ApplicationArgs 1 - // tests/artifacts/state-ops/contract.algo.ts:708 - // @arc4.abimethod() - callsub set_implicit_key_arc4_uintn128 - intc_0 // 1 - retsub - -__puya_arc4_router___set_implicit_key_arc4_dynamic_bytes_route@22: - // tests/artifacts/state-ops/contract.algo.ts:713 - // @arc4.abimethod() - txn OnCompletion - ! - assert // OnCompletion is not NoOp - txn ApplicationID - assert // can only call when not creating - // tests/artifacts/state-ops/contract.algo.ts:591 - // export class GlobalStateContract extends arc4.Contract { - txna ApplicationArgs 1 - // tests/artifacts/state-ops/contract.algo.ts:713 - // @arc4.abimethod() - callsub set_implicit_key_arc4_dynamic_bytes - intc_0 // 1 - retsub - -__puya_arc4_router___set_arc4_uintn64_route@23: - // tests/artifacts/state-ops/contract.algo.ts:719 - // @arc4.abimethod() - txn OnCompletion - ! - assert // OnCompletion is not NoOp - txn ApplicationID - assert // can only call when not creating - // tests/artifacts/state-ops/contract.algo.ts:591 - // export class GlobalStateContract extends arc4.Contract { - txna ApplicationArgs 1 - // tests/artifacts/state-ops/contract.algo.ts:719 - // @arc4.abimethod() - callsub set_arc4_uintn64 - intc_0 // 1 - retsub - -__puya_arc4_router___set_arc4_str_route@24: - // tests/artifacts/state-ops/contract.algo.ts:724 - // @arc4.abimethod() - txn OnCompletion - ! - assert // OnCompletion is not NoOp - txn ApplicationID - assert // can only call when not creating - // tests/artifacts/state-ops/contract.algo.ts:591 - // export class GlobalStateContract extends arc4.Contract { - txna ApplicationArgs 1 - // tests/artifacts/state-ops/contract.algo.ts:724 - // @arc4.abimethod() - callsub set_arc4_str - intc_0 // 1 - retsub - -__puya_arc4_router___set_arc4_byte_route@25: - // tests/artifacts/state-ops/contract.algo.ts:729 - // @arc4.abimethod() - txn OnCompletion - ! - assert // OnCompletion is not NoOp - txn ApplicationID - assert // can only call when not creating - // tests/artifacts/state-ops/contract.algo.ts:591 - // export class GlobalStateContract extends arc4.Contract { - txna ApplicationArgs 1 - // tests/artifacts/state-ops/contract.algo.ts:729 - // @arc4.abimethod() - callsub set_arc4_byte - intc_0 // 1 - retsub - -__puya_arc4_router___set_arc4_bool_route@26: - // tests/artifacts/state-ops/contract.algo.ts:734 - // @arc4.abimethod() - txn OnCompletion - ! - assert // OnCompletion is not NoOp - txn ApplicationID - assert // can only call when not creating - // tests/artifacts/state-ops/contract.algo.ts:591 - // export class GlobalStateContract extends arc4.Contract { - txna ApplicationArgs 1 - // tests/artifacts/state-ops/contract.algo.ts:734 - // @arc4.abimethod() - callsub set_arc4_bool - intc_0 // 1 - retsub - -__puya_arc4_router___set_arc4_address_route@27: - // tests/artifacts/state-ops/contract.algo.ts:739 - // @arc4.abimethod() - txn OnCompletion - ! - assert // OnCompletion is not NoOp - txn ApplicationID - assert // can only call when not creating - // tests/artifacts/state-ops/contract.algo.ts:591 - // export class GlobalStateContract extends arc4.Contract { - txna ApplicationArgs 1 - // tests/artifacts/state-ops/contract.algo.ts:739 - // @arc4.abimethod() - callsub set_arc4_address - intc_0 // 1 - retsub - -__puya_arc4_router___set_arc4_uintn128_route@28: - // tests/artifacts/state-ops/contract.algo.ts:744 - // @arc4.abimethod() - txn OnCompletion - ! - assert // OnCompletion is not NoOp - txn ApplicationID - assert // can only call when not creating - // tests/artifacts/state-ops/contract.algo.ts:591 - // export class GlobalStateContract extends arc4.Contract { - txna ApplicationArgs 1 - // tests/artifacts/state-ops/contract.algo.ts:744 - // @arc4.abimethod() - callsub set_arc4_uintn128 - intc_0 // 1 - retsub - -__puya_arc4_router___set_arc4_dynamic_bytes_route@29: - // tests/artifacts/state-ops/contract.algo.ts:749 - // @arc4.abimethod() - txn OnCompletion - ! - assert // OnCompletion is not NoOp - txn ApplicationID - assert // can only call when not creating - // tests/artifacts/state-ops/contract.algo.ts:591 - // export class GlobalStateContract extends arc4.Contract { - txna ApplicationArgs 1 - // tests/artifacts/state-ops/contract.algo.ts:749 - // @arc4.abimethod() - callsub set_arc4_dynamic_bytes - intc_0 // 1 - retsub - -__puya_arc4_router___bare_routing@32: - // tests/artifacts/state-ops/contract.algo.ts:591 - // export class GlobalStateContract extends arc4.Contract { - txn OnCompletion - bnz __puya_arc4_router___after_if_else@36 - txn ApplicationID - ! - assert // can only call when creating - intc_0 // 1 - retsub - -__puya_arc4_router___after_if_else@36: - // tests/artifacts/state-ops/contract.algo.ts:591 - // export class GlobalStateContract extends arc4.Contract { - intc_1 // 0 - retsub - - -// tests/artifacts/state-ops/contract.algo.ts::GlobalStateContract.get_implicit_key_arc4_uintn64() -> bytes: -get_implicit_key_arc4_uintn64: - // tests/artifacts/state-ops/contract.algo.ts:611-612 - // @arc4.abimethod() - // get_implicit_key_arc4_uintn64(): UintN64 { - proto 0 1 - // tests/artifacts/state-ops/contract.algo.ts:613 - // return this.implicitKeyArc4UintN64.value - intc_1 // 0 - // tests/artifacts/state-ops/contract.algo.ts:593 - // implicitKeyArc4UintN64 = GlobalState({ initialValue: new UintN64(1337) }) - bytec_1 // "implicitKeyArc4UintN64" - // tests/artifacts/state-ops/contract.algo.ts:613 - // return this.implicitKeyArc4UintN64.value - app_global_get_ex - assert // check GlobalState exists - retsub - - -// tests/artifacts/state-ops/contract.algo.ts::GlobalStateContract.get_implicit_key_arc4_str() -> bytes: -get_implicit_key_arc4_str: - // tests/artifacts/state-ops/contract.algo.ts:616-617 - // @arc4.abimethod() - // get_implicit_key_arc4_str(): Str { - proto 0 1 - // tests/artifacts/state-ops/contract.algo.ts:618 - // return this.implicitKeyArc4Str.value - intc_1 // 0 - // tests/artifacts/state-ops/contract.algo.ts:594 - // implicitKeyArc4Str = GlobalState({ initialValue: new Str('Hello') }) - bytec_2 // "implicitKeyArc4Str" - // tests/artifacts/state-ops/contract.algo.ts:618 - // return this.implicitKeyArc4Str.value - app_global_get_ex - assert // check GlobalState exists - retsub - - -// tests/artifacts/state-ops/contract.algo.ts::GlobalStateContract.get_implicit_key_arc4_byte() -> bytes: -get_implicit_key_arc4_byte: - // tests/artifacts/state-ops/contract.algo.ts:621-622 - // @arc4.abimethod() - // get_implicit_key_arc4_byte(): Byte { - proto 0 1 - // tests/artifacts/state-ops/contract.algo.ts:623 - // return this.implicitKeyArc4Byte.value - intc_1 // 0 - // tests/artifacts/state-ops/contract.algo.ts:595 - // implicitKeyArc4Byte = GlobalState({ initialValue: new Byte(0) }) - bytec_3 // "implicitKeyArc4Byte" - // tests/artifacts/state-ops/contract.algo.ts:623 - // return this.implicitKeyArc4Byte.value - app_global_get_ex - assert // check GlobalState exists - retsub - - -// tests/artifacts/state-ops/contract.algo.ts::GlobalStateContract.get_implicit_key_arc4_bool() -> bytes: -get_implicit_key_arc4_bool: - // tests/artifacts/state-ops/contract.algo.ts:626-627 - // @arc4.abimethod() - // get_implicit_key_arc4_bool(): arc4.Bool { - proto 0 1 - // tests/artifacts/state-ops/contract.algo.ts:628 - // return this.implicitKeyArc4Bool.value - intc_1 // 0 - // tests/artifacts/state-ops/contract.algo.ts:596 - // implicitKeyArc4Bool = GlobalState({ initialValue: new Bool(true) }) - bytec 4 // "implicitKeyArc4Bool" - // tests/artifacts/state-ops/contract.algo.ts:628 - // return this.implicitKeyArc4Bool.value - app_global_get_ex - assert // check GlobalState exists - retsub - - -// tests/artifacts/state-ops/contract.algo.ts::GlobalStateContract.get_implicit_key_arc4_address() -> bytes: -get_implicit_key_arc4_address: - // tests/artifacts/state-ops/contract.algo.ts:631-632 - // @arc4.abimethod() - // get_implicit_key_arc4_address(): Address { - proto 0 1 - // tests/artifacts/state-ops/contract.algo.ts:633 - // return this.implicitKeyArc4Address.value - intc_1 // 0 - // tests/artifacts/state-ops/contract.algo.ts:597 - // implicitKeyArc4Address = GlobalState({ initialValue: new Address(Global.creatorAddress) }) - bytec 5 // "implicitKeyArc4Address" - // tests/artifacts/state-ops/contract.algo.ts:633 - // return this.implicitKeyArc4Address.value - app_global_get_ex - assert // check GlobalState exists - retsub - - -// tests/artifacts/state-ops/contract.algo.ts::GlobalStateContract.get_implicit_key_arc4_uintn128() -> bytes: -get_implicit_key_arc4_uintn128: - // tests/artifacts/state-ops/contract.algo.ts:636-637 - // @arc4.abimethod() - // get_implicit_key_arc4_uintn128(): UintN128 { - proto 0 1 - // tests/artifacts/state-ops/contract.algo.ts:638 - // return this.implicitKeyArc4UintN128.value - intc_1 // 0 - // tests/artifacts/state-ops/contract.algo.ts:598 - // implicitKeyArc4UintN128 = GlobalState({ initialValue: new UintN128(2n ** 100n) }) - bytec 6 // "implicitKeyArc4UintN128" - // tests/artifacts/state-ops/contract.algo.ts:638 - // return this.implicitKeyArc4UintN128.value - app_global_get_ex - assert // check GlobalState exists - retsub - - -// tests/artifacts/state-ops/contract.algo.ts::GlobalStateContract.get_implicit_key_arc4_dynamic_bytes() -> bytes: -get_implicit_key_arc4_dynamic_bytes: - // tests/artifacts/state-ops/contract.algo.ts:641-642 - // @arc4.abimethod() - // get_implicit_key_arc4_dynamic_bytes(): DynamicBytes { - proto 0 1 - // tests/artifacts/state-ops/contract.algo.ts:643 - // return this.implicitKeyArc4DynamicBytes.value - intc_1 // 0 - // tests/artifacts/state-ops/contract.algo.ts:599 - // implicitKeyArc4DynamicBytes = GlobalState({ initialValue: new DynamicBytes('dynamic bytes') }) - bytec 7 // "implicitKeyArc4DynamicBytes" - // tests/artifacts/state-ops/contract.algo.ts:643 - // return this.implicitKeyArc4DynamicBytes.value - app_global_get_ex - assert // check GlobalState exists - retsub - - -// tests/artifacts/state-ops/contract.algo.ts::GlobalStateContract.get_arc4_uintn64() -> bytes: -get_arc4_uintn64: - // tests/artifacts/state-ops/contract.algo.ts:647-648 - // @arc4.abimethod() - // get_arc4_uintn64(): UintN64 { - proto 0 1 - // tests/artifacts/state-ops/contract.algo.ts:649 - // return this.arc4UintN64.value - intc_1 // 0 - // tests/artifacts/state-ops/contract.algo.ts:602 - // arc4UintN64 = GlobalState({ initialValue: new UintN64(1337), key: 'explicit_key_arc4_uintn64' }) - bytec 8 // "explicit_key_arc4_uintn64" - // tests/artifacts/state-ops/contract.algo.ts:649 - // return this.arc4UintN64.value - app_global_get_ex - assert // check GlobalState exists - retsub - - -// tests/artifacts/state-ops/contract.algo.ts::GlobalStateContract.get_arc4_str() -> bytes: -get_arc4_str: - // tests/artifacts/state-ops/contract.algo.ts:652-653 - // @arc4.abimethod() - // get_arc4_str(): Str { - proto 0 1 - // tests/artifacts/state-ops/contract.algo.ts:654 - // return this.arc4Str.value - intc_1 // 0 - // tests/artifacts/state-ops/contract.algo.ts:603 - // arc4Str = GlobalState({ initialValue: new Str('Hello'), key: 'explicit_key_arc4_str' }) - bytec 9 // "explicit_key_arc4_str" - // tests/artifacts/state-ops/contract.algo.ts:654 - // return this.arc4Str.value - app_global_get_ex - assert // check GlobalState exists - retsub - - -// tests/artifacts/state-ops/contract.algo.ts::GlobalStateContract.get_arc4_byte() -> bytes: -get_arc4_byte: - // tests/artifacts/state-ops/contract.algo.ts:657-658 - // @arc4.abimethod() - // get_arc4_byte(): Byte { - proto 0 1 - // tests/artifacts/state-ops/contract.algo.ts:659 - // return this.arc4Byte.value - intc_1 // 0 - // tests/artifacts/state-ops/contract.algo.ts:604 - // arc4Byte = GlobalState({ initialValue: new Byte(0), key: 'explicit_key_arc4_byte' }) - bytec 10 // "explicit_key_arc4_byte" - // tests/artifacts/state-ops/contract.algo.ts:659 - // return this.arc4Byte.value - app_global_get_ex - assert // check GlobalState exists - retsub - - -// tests/artifacts/state-ops/contract.algo.ts::GlobalStateContract.get_arc4_bool() -> bytes: -get_arc4_bool: - // tests/artifacts/state-ops/contract.algo.ts:662-663 - // @arc4.abimethod() - // get_arc4_bool(): arc4.Bool { - proto 0 1 - // tests/artifacts/state-ops/contract.algo.ts:664 - // return this.arc4Bool.value - intc_1 // 0 - // tests/artifacts/state-ops/contract.algo.ts:605 - // arc4Bool = GlobalState({ initialValue: new Bool(true), key: 'explicit_key_arc4_bool' }) - bytec 11 // "explicit_key_arc4_bool" - // tests/artifacts/state-ops/contract.algo.ts:664 - // return this.arc4Bool.value - app_global_get_ex - assert // check GlobalState exists - retsub - - -// tests/artifacts/state-ops/contract.algo.ts::GlobalStateContract.get_arc4_address() -> bytes: -get_arc4_address: - // tests/artifacts/state-ops/contract.algo.ts:667-668 - // @arc4.abimethod() - // get_arc4_address(): Address { - proto 0 1 - // tests/artifacts/state-ops/contract.algo.ts:669 - // return this.arc4Address.value - intc_1 // 0 - // tests/artifacts/state-ops/contract.algo.ts:606 - // arc4Address = GlobalState({ initialValue: new Address(Global.creatorAddress), key: 'explicit_key_arc4_address' }) - bytec 12 // "explicit_key_arc4_address" - // tests/artifacts/state-ops/contract.algo.ts:669 - // return this.arc4Address.value - app_global_get_ex - assert // check GlobalState exists - retsub - - -// tests/artifacts/state-ops/contract.algo.ts::GlobalStateContract.get_arc4_uintn128() -> bytes: -get_arc4_uintn128: - // tests/artifacts/state-ops/contract.algo.ts:672-673 - // @arc4.abimethod() - // get_arc4_uintn128(): UintN128 { - proto 0 1 - // tests/artifacts/state-ops/contract.algo.ts:674 - // return this.arc4UintN128.value - intc_1 // 0 - // tests/artifacts/state-ops/contract.algo.ts:607 - // arc4UintN128 = GlobalState({ initialValue: new UintN128(2n ** 100n), key: 'explicit_key_arc4_uintn128' }) - bytec 13 // "explicit_key_arc4_uintn128" - // tests/artifacts/state-ops/contract.algo.ts:674 - // return this.arc4UintN128.value - app_global_get_ex - assert // check GlobalState exists - retsub - - -// tests/artifacts/state-ops/contract.algo.ts::GlobalStateContract.get_arc4_dynamic_bytes() -> bytes: -get_arc4_dynamic_bytes: - // tests/artifacts/state-ops/contract.algo.ts:677-678 - // @arc4.abimethod() - // get_arc4_dynamic_bytes(): DynamicBytes { - proto 0 1 - // tests/artifacts/state-ops/contract.algo.ts:679 - // return this.arc4DynamicBytes.value - intc_1 // 0 - // tests/artifacts/state-ops/contract.algo.ts:608 - // arc4DynamicBytes = GlobalState({ initialValue: new DynamicBytes('dynamic bytes'), key: 'explicit_key_arc4_dynamic_bytes' }) - bytec 14 // "explicit_key_arc4_dynamic_bytes" - // tests/artifacts/state-ops/contract.algo.ts:679 - // return this.arc4DynamicBytes.value - app_global_get_ex - assert // check GlobalState exists - retsub - - -// tests/artifacts/state-ops/contract.algo.ts::GlobalStateContract.set_implicit_key_arc4_uintn64(value: bytes) -> void: -set_implicit_key_arc4_uintn64: - // tests/artifacts/state-ops/contract.algo.ts:683-684 - // @arc4.abimethod() - // set_implicit_key_arc4_uintn64(value: UintN64) { - proto 1 0 - // tests/artifacts/state-ops/contract.algo.ts:593 - // implicitKeyArc4UintN64 = GlobalState({ initialValue: new UintN64(1337) }) - bytec_1 // "implicitKeyArc4UintN64" - // tests/artifacts/state-ops/contract.algo.ts:685 - // this.implicitKeyArc4UintN64.value = value - frame_dig -1 - app_global_put - retsub - - -// tests/artifacts/state-ops/contract.algo.ts::GlobalStateContract.set_implicit_key_arc4_str(value: bytes) -> void: -set_implicit_key_arc4_str: - // tests/artifacts/state-ops/contract.algo.ts:688-689 - // @arc4.abimethod() - // set_implicit_key_arc4_str(value: Str) { - proto 1 0 - // tests/artifacts/state-ops/contract.algo.ts:594 - // implicitKeyArc4Str = GlobalState({ initialValue: new Str('Hello') }) - bytec_2 // "implicitKeyArc4Str" - // tests/artifacts/state-ops/contract.algo.ts:690 - // this.implicitKeyArc4Str.value = value - frame_dig -1 - app_global_put - retsub - - -// tests/artifacts/state-ops/contract.algo.ts::GlobalStateContract.set_implicit_key_arc4_byte(value: bytes) -> void: -set_implicit_key_arc4_byte: - // tests/artifacts/state-ops/contract.algo.ts:693-694 - // @arc4.abimethod() - // set_implicit_key_arc4_byte(value: Byte) { - proto 1 0 - // tests/artifacts/state-ops/contract.algo.ts:595 - // implicitKeyArc4Byte = GlobalState({ initialValue: new Byte(0) }) - bytec_3 // "implicitKeyArc4Byte" - // tests/artifacts/state-ops/contract.algo.ts:695 - // this.implicitKeyArc4Byte.value = value - frame_dig -1 - app_global_put - retsub - - -// tests/artifacts/state-ops/contract.algo.ts::GlobalStateContract.set_implicit_key_arc4_bool(value: bytes) -> void: -set_implicit_key_arc4_bool: - // tests/artifacts/state-ops/contract.algo.ts:698-699 - // @arc4.abimethod() - // set_implicit_key_arc4_bool(value: Bool) { - proto 1 0 - // tests/artifacts/state-ops/contract.algo.ts:596 - // implicitKeyArc4Bool = GlobalState({ initialValue: new Bool(true) }) - bytec 4 // "implicitKeyArc4Bool" - // tests/artifacts/state-ops/contract.algo.ts:700 - // this.implicitKeyArc4Bool.value = value - frame_dig -1 - app_global_put - retsub - - -// tests/artifacts/state-ops/contract.algo.ts::GlobalStateContract.set_implicit_key_arc4_address(value: bytes) -> void: -set_implicit_key_arc4_address: - // tests/artifacts/state-ops/contract.algo.ts:703-704 - // @arc4.abimethod() - // set_implicit_key_arc4_address(value: Address) { - proto 1 0 - // tests/artifacts/state-ops/contract.algo.ts:597 - // implicitKeyArc4Address = GlobalState({ initialValue: new Address(Global.creatorAddress) }) - bytec 5 // "implicitKeyArc4Address" - // tests/artifacts/state-ops/contract.algo.ts:705 - // this.implicitKeyArc4Address.value = value - frame_dig -1 - app_global_put - retsub - - -// tests/artifacts/state-ops/contract.algo.ts::GlobalStateContract.set_implicit_key_arc4_uintn128(value: bytes) -> void: -set_implicit_key_arc4_uintn128: - // tests/artifacts/state-ops/contract.algo.ts:708-709 - // @arc4.abimethod() - // set_implicit_key_arc4_uintn128(value: UintN128) { - proto 1 0 - // tests/artifacts/state-ops/contract.algo.ts:598 - // implicitKeyArc4UintN128 = GlobalState({ initialValue: new UintN128(2n ** 100n) }) - bytec 6 // "implicitKeyArc4UintN128" - // tests/artifacts/state-ops/contract.algo.ts:710 - // this.implicitKeyArc4UintN128.value = value - frame_dig -1 - app_global_put - retsub - - -// tests/artifacts/state-ops/contract.algo.ts::GlobalStateContract.set_implicit_key_arc4_dynamic_bytes(value: bytes) -> void: -set_implicit_key_arc4_dynamic_bytes: - // tests/artifacts/state-ops/contract.algo.ts:713-714 - // @arc4.abimethod() - // set_implicit_key_arc4_dynamic_bytes(value: DynamicBytes) { - proto 1 0 - // tests/artifacts/state-ops/contract.algo.ts:599 - // implicitKeyArc4DynamicBytes = GlobalState({ initialValue: new DynamicBytes('dynamic bytes') }) - bytec 7 // "implicitKeyArc4DynamicBytes" - // tests/artifacts/state-ops/contract.algo.ts:715 - // this.implicitKeyArc4DynamicBytes.value = value - frame_dig -1 - app_global_put - retsub - - -// tests/artifacts/state-ops/contract.algo.ts::GlobalStateContract.set_arc4_uintn64(value: bytes) -> void: -set_arc4_uintn64: - // tests/artifacts/state-ops/contract.algo.ts:719-720 - // @arc4.abimethod() - // set_arc4_uintn64(value: UintN64) { - proto 1 0 - // tests/artifacts/state-ops/contract.algo.ts:602 - // arc4UintN64 = GlobalState({ initialValue: new UintN64(1337), key: 'explicit_key_arc4_uintn64' }) - bytec 8 // "explicit_key_arc4_uintn64" - // tests/artifacts/state-ops/contract.algo.ts:721 - // this.arc4UintN64.value = value - frame_dig -1 - app_global_put - retsub - - -// tests/artifacts/state-ops/contract.algo.ts::GlobalStateContract.set_arc4_str(value: bytes) -> void: -set_arc4_str: - // tests/artifacts/state-ops/contract.algo.ts:724-725 - // @arc4.abimethod() - // set_arc4_str(value: Str) { - proto 1 0 - // tests/artifacts/state-ops/contract.algo.ts:603 - // arc4Str = GlobalState({ initialValue: new Str('Hello'), key: 'explicit_key_arc4_str' }) - bytec 9 // "explicit_key_arc4_str" - // tests/artifacts/state-ops/contract.algo.ts:726 - // this.arc4Str.value = value - frame_dig -1 - app_global_put - retsub - - -// tests/artifacts/state-ops/contract.algo.ts::GlobalStateContract.set_arc4_byte(value: bytes) -> void: -set_arc4_byte: - // tests/artifacts/state-ops/contract.algo.ts:729-730 - // @arc4.abimethod() - // set_arc4_byte(value: Byte) { - proto 1 0 - // tests/artifacts/state-ops/contract.algo.ts:604 - // arc4Byte = GlobalState({ initialValue: new Byte(0), key: 'explicit_key_arc4_byte' }) - bytec 10 // "explicit_key_arc4_byte" - // tests/artifacts/state-ops/contract.algo.ts:731 - // this.arc4Byte.value = value - frame_dig -1 - app_global_put - retsub - - -// tests/artifacts/state-ops/contract.algo.ts::GlobalStateContract.set_arc4_bool(value: bytes) -> void: -set_arc4_bool: - // tests/artifacts/state-ops/contract.algo.ts:734-735 - // @arc4.abimethod() - // set_arc4_bool(value: Bool) { - proto 1 0 - // tests/artifacts/state-ops/contract.algo.ts:605 - // arc4Bool = GlobalState({ initialValue: new Bool(true), key: 'explicit_key_arc4_bool' }) - bytec 11 // "explicit_key_arc4_bool" - // tests/artifacts/state-ops/contract.algo.ts:736 - // this.arc4Bool.value = value - frame_dig -1 - app_global_put - retsub - - -// tests/artifacts/state-ops/contract.algo.ts::GlobalStateContract.set_arc4_address(value: bytes) -> void: -set_arc4_address: - // tests/artifacts/state-ops/contract.algo.ts:739-740 - // @arc4.abimethod() - // set_arc4_address(value: Address) { - proto 1 0 - // tests/artifacts/state-ops/contract.algo.ts:606 - // arc4Address = GlobalState({ initialValue: new Address(Global.creatorAddress), key: 'explicit_key_arc4_address' }) - bytec 12 // "explicit_key_arc4_address" - // tests/artifacts/state-ops/contract.algo.ts:741 - // this.arc4Address.value = value - frame_dig -1 - app_global_put - retsub - - -// tests/artifacts/state-ops/contract.algo.ts::GlobalStateContract.set_arc4_uintn128(value: bytes) -> void: -set_arc4_uintn128: - // tests/artifacts/state-ops/contract.algo.ts:744-745 - // @arc4.abimethod() - // set_arc4_uintn128(value: UintN128) { - proto 1 0 - // tests/artifacts/state-ops/contract.algo.ts:607 - // arc4UintN128 = GlobalState({ initialValue: new UintN128(2n ** 100n), key: 'explicit_key_arc4_uintn128' }) - bytec 13 // "explicit_key_arc4_uintn128" - // tests/artifacts/state-ops/contract.algo.ts:746 - // this.arc4UintN128.value = value - frame_dig -1 - app_global_put - retsub - - -// tests/artifacts/state-ops/contract.algo.ts::GlobalStateContract.set_arc4_dynamic_bytes(value: bytes) -> void: -set_arc4_dynamic_bytes: - // tests/artifacts/state-ops/contract.algo.ts:749-750 - // @arc4.abimethod() - // set_arc4_dynamic_bytes(value: DynamicBytes) { - proto 1 0 - // tests/artifacts/state-ops/contract.algo.ts:608 - // arc4DynamicBytes = GlobalState({ initialValue: new DynamicBytes('dynamic bytes'), key: 'explicit_key_arc4_dynamic_bytes' }) - bytec 14 // "explicit_key_arc4_dynamic_bytes" - // tests/artifacts/state-ops/contract.algo.ts:751 - // this.arc4DynamicBytes.value = value - frame_dig -1 - app_global_put - retsub diff --git a/tests/artifacts/state-ops/data/GlobalStateContract.arc32.json b/tests/artifacts/state-ops/data/GlobalStateContract.arc32.json deleted file mode 100644 index 84d439a..0000000 --- a/tests/artifacts/state-ops/data/GlobalStateContract.arc32.json +++ /dev/null @@ -1,528 +0,0 @@ -{ - "hints": { - "get_implicit_key_arc4_uintn64()uint64": { - "call_config": { - "no_op": "CALL" - } - }, - "get_implicit_key_arc4_str()string": { - "call_config": { - "no_op": "CALL" - } - }, - "get_implicit_key_arc4_byte()byte": { - "call_config": { - "no_op": "CALL" - } - }, - "get_implicit_key_arc4_bool()bool": { - "call_config": { - "no_op": "CALL" - } - }, - "get_implicit_key_arc4_address()address": { - "call_config": { - "no_op": "CALL" - } - }, - "get_implicit_key_arc4_uintn128()uint128": { - "call_config": { - "no_op": "CALL" - } - }, - "get_implicit_key_arc4_dynamic_bytes()byte[]": { - "call_config": { - "no_op": "CALL" - } - }, - "get_arc4_uintn64()uint64": { - "call_config": { - "no_op": "CALL" - } - }, - "get_arc4_str()string": { - "call_config": { - "no_op": "CALL" - } - }, - "get_arc4_byte()byte": { - "call_config": { - "no_op": "CALL" - } - }, - "get_arc4_bool()bool": { - "call_config": { - "no_op": "CALL" - } - }, - "get_arc4_address()address": { - "call_config": { - "no_op": "CALL" - } - }, - "get_arc4_uintn128()uint128": { - "call_config": { - "no_op": "CALL" - } - }, - "get_arc4_dynamic_bytes()byte[]": { - "call_config": { - "no_op": "CALL" - } - }, - "set_implicit_key_arc4_uintn64(uint64)void": { - "call_config": { - "no_op": "CALL" - } - }, - "set_implicit_key_arc4_str(string)void": { - "call_config": { - "no_op": "CALL" - } - }, - "set_implicit_key_arc4_byte(byte)void": { - "call_config": { - "no_op": "CALL" - } - }, - "set_implicit_key_arc4_bool(bool)void": { - "call_config": { - "no_op": "CALL" - } - }, - "set_implicit_key_arc4_address(address)void": { - "call_config": { - "no_op": "CALL" - } - }, - "set_implicit_key_arc4_uintn128(uint128)void": { - "call_config": { - "no_op": "CALL" - } - }, - "set_implicit_key_arc4_dynamic_bytes(byte[])void": { - "call_config": { - "no_op": "CALL" - } - }, - "set_arc4_uintn64(uint64)void": { - "call_config": { - "no_op": "CALL" - } - }, - "set_arc4_str(string)void": { - "call_config": { - "no_op": "CALL" - } - }, - "set_arc4_byte(byte)void": { - "call_config": { - "no_op": "CALL" - } - }, - "set_arc4_bool(bool)void": { - "call_config": { - "no_op": "CALL" - } - }, - "set_arc4_address(address)void": { - "call_config": { - "no_op": "CALL" - } - }, - "set_arc4_uintn128(uint128)void": { - "call_config": { - "no_op": "CALL" - } - }, - "set_arc4_dynamic_bytes(byte[])void": { - "call_config": { - "no_op": "CALL" - } - } - }, - "source": { - "approval": "I3ByYWdtYSB2ZXJzaW9uIDEwCgp0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6Okdsb2JhbFN0YXRlQ29udHJhY3QuYXBwcm92YWxQcm9ncmFtOgogICAgaW50Y2Jsb2NrIDEgMAogICAgYnl0ZWNibG9jayAweDE1MWY3Yzc1ICJpbXBsaWNpdEtleUFyYzRVaW50TjY0IiAiaW1wbGljaXRLZXlBcmM0U3RyIiAiaW1wbGljaXRLZXlBcmM0Qnl0ZSIgImltcGxpY2l0S2V5QXJjNEJvb2wiICJpbXBsaWNpdEtleUFyYzRBZGRyZXNzIiAiaW1wbGljaXRLZXlBcmM0VWludE4xMjgiICJpbXBsaWNpdEtleUFyYzREeW5hbWljQnl0ZXMiICJleHBsaWNpdF9rZXlfYXJjNF91aW50bjY0IiAiZXhwbGljaXRfa2V5X2FyYzRfc3RyIiAiZXhwbGljaXRfa2V5X2FyYzRfYnl0ZSIgImV4cGxpY2l0X2tleV9hcmM0X2Jvb2wiICJleHBsaWNpdF9rZXlfYXJjNF9hZGRyZXNzIiAiZXhwbGljaXRfa2V5X2FyYzRfdWludG4xMjgiICJleHBsaWNpdF9rZXlfYXJjNF9keW5hbWljX2J5dGVzIiAweDAwMDAwMDAwMDAwMDA1MzkgMHgwMDA1NDg2NTZjNmM2ZiAweDAwMDAwMDEwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwIDB4MDAwZDY0Nzk2ZTYxNmQ2OTYzMjA2Mjc5NzQ2NTczCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYm56IG1haW5fYWZ0ZXJfaWZfZWxzZUAyCiAgICBjYWxsc3ViIGNvbnN0cnVjdG9yCgptYWluX2FmdGVyX2lmX2Vsc2VAMjoKICAgIGNhbGxzdWIgX19wdXlhX2FyYzRfcm91dGVyX18KICAgIHJldHVybgoKCi8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo6R2xvYmFsU3RhdGVDb250cmFjdC5jb25zdHJ1Y3RvcigpIC0+IHZvaWQ6CmNvbnN0cnVjdG9yOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjU5MQogICAgLy8gZXhwb3J0IGNsYXNzIEdsb2JhbFN0YXRlQ29udHJhY3QgZXh0ZW5kcyBhcmM0LkNvbnRyYWN0IHsKICAgIHByb3RvIDAgMAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjU5MwogICAgLy8gaW1wbGljaXRLZXlBcmM0VWludE42NCA9IEdsb2JhbFN0YXRlKHsgaW5pdGlhbFZhbHVlOiBuZXcgVWludE42NCgxMzM3KSB9KQogICAgYnl0ZWNfMSAvLyAiaW1wbGljaXRLZXlBcmM0VWludE42NCIKICAgIGJ5dGVjIDE1IC8vIDB4MDAwMDAwMDAwMDAwMDUzOQogICAgYXBwX2dsb2JhbF9wdXQKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo1OTQKICAgIC8vIGltcGxpY2l0S2V5QXJjNFN0ciA9IEdsb2JhbFN0YXRlKHsgaW5pdGlhbFZhbHVlOiBuZXcgU3RyKCdIZWxsbycpIH0pCiAgICBieXRlY18yIC8vICJpbXBsaWNpdEtleUFyYzRTdHIiCiAgICBieXRlYyAxNiAvLyAweDAwMDU0ODY1NmM2YzZmCiAgICBhcHBfZ2xvYmFsX3B1dAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjU5NQogICAgLy8gaW1wbGljaXRLZXlBcmM0Qnl0ZSA9IEdsb2JhbFN0YXRlKHsgaW5pdGlhbFZhbHVlOiBuZXcgQnl0ZSgwKSB9KQogICAgYnl0ZWNfMyAvLyAiaW1wbGljaXRLZXlBcmM0Qnl0ZSIKICAgIHB1c2hieXRlcyAweDAwCiAgICBhcHBfZ2xvYmFsX3B1dAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjU5NgogICAgLy8gaW1wbGljaXRLZXlBcmM0Qm9vbCA9IEdsb2JhbFN0YXRlKHsgaW5pdGlhbFZhbHVlOiBuZXcgQm9vbCh0cnVlKSB9KQogICAgYnl0ZWMgNCAvLyAiaW1wbGljaXRLZXlBcmM0Qm9vbCIKICAgIHB1c2hieXRlcyAweDgwCiAgICBhcHBfZ2xvYmFsX3B1dAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjU5NwogICAgLy8gaW1wbGljaXRLZXlBcmM0QWRkcmVzcyA9IEdsb2JhbFN0YXRlKHsgaW5pdGlhbFZhbHVlOiBuZXcgQWRkcmVzcyhHbG9iYWwuY3JlYXRvckFkZHJlc3MpIH0pCiAgICBieXRlYyA1IC8vICJpbXBsaWNpdEtleUFyYzRBZGRyZXNzIgogICAgZ2xvYmFsIENyZWF0b3JBZGRyZXNzCiAgICBhcHBfZ2xvYmFsX3B1dAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjU5OAogICAgLy8gaW1wbGljaXRLZXlBcmM0VWludE4xMjggPSBHbG9iYWxTdGF0ZSh7IGluaXRpYWxWYWx1ZTogbmV3IFVpbnROMTI4KDJuICoqIDEwMG4pIH0pCiAgICBieXRlYyA2IC8vICJpbXBsaWNpdEtleUFyYzRVaW50TjEyOCIKICAgIGJ5dGVjIDE3IC8vIDB4MDAwMDAwMTAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAKICAgIGFwcF9nbG9iYWxfcHV0CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NTk5CiAgICAvLyBpbXBsaWNpdEtleUFyYzREeW5hbWljQnl0ZXMgPSBHbG9iYWxTdGF0ZSh7IGluaXRpYWxWYWx1ZTogbmV3IER5bmFtaWNCeXRlcygnZHluYW1pYyBieXRlcycpIH0pCiAgICBieXRlYyA3IC8vICJpbXBsaWNpdEtleUFyYzREeW5hbWljQnl0ZXMiCiAgICBieXRlYyAxOCAvLyAweDAwMGQ2NDc5NmU2MTZkNjk2MzIwNjI3OTc0NjU3MwogICAgYXBwX2dsb2JhbF9wdXQKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo2MDIKICAgIC8vIGFyYzRVaW50TjY0ID0gR2xvYmFsU3RhdGUoeyBpbml0aWFsVmFsdWU6IG5ldyBVaW50TjY0KDEzMzcpLCBrZXk6ICdleHBsaWNpdF9rZXlfYXJjNF91aW50bjY0JyB9KQogICAgYnl0ZWMgOCAvLyAiZXhwbGljaXRfa2V5X2FyYzRfdWludG42NCIKICAgIGJ5dGVjIDE1IC8vIDB4MDAwMDAwMDAwMDAwMDUzOQogICAgYXBwX2dsb2JhbF9wdXQKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo2MDMKICAgIC8vIGFyYzRTdHIgPSBHbG9iYWxTdGF0ZSh7IGluaXRpYWxWYWx1ZTogbmV3IFN0cignSGVsbG8nKSwga2V5OiAnZXhwbGljaXRfa2V5X2FyYzRfc3RyJyB9KQogICAgYnl0ZWMgOSAvLyAiZXhwbGljaXRfa2V5X2FyYzRfc3RyIgogICAgYnl0ZWMgMTYgLy8gMHgwMDA1NDg2NTZjNmM2ZgogICAgYXBwX2dsb2JhbF9wdXQKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo2MDQKICAgIC8vIGFyYzRCeXRlID0gR2xvYmFsU3RhdGUoeyBpbml0aWFsVmFsdWU6IG5ldyBCeXRlKDApLCBrZXk6ICdleHBsaWNpdF9rZXlfYXJjNF9ieXRlJyB9KQogICAgYnl0ZWMgMTAgLy8gImV4cGxpY2l0X2tleV9hcmM0X2J5dGUiCiAgICBwdXNoYnl0ZXMgMHgwMAogICAgYXBwX2dsb2JhbF9wdXQKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo2MDUKICAgIC8vIGFyYzRCb29sID0gR2xvYmFsU3RhdGUoeyBpbml0aWFsVmFsdWU6IG5ldyBCb29sKHRydWUpLCBrZXk6ICdleHBsaWNpdF9rZXlfYXJjNF9ib29sJyB9KQogICAgYnl0ZWMgMTEgLy8gImV4cGxpY2l0X2tleV9hcmM0X2Jvb2wiCiAgICBwdXNoYnl0ZXMgMHg4MAogICAgYXBwX2dsb2JhbF9wdXQKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo2MDYKICAgIC8vIGFyYzRBZGRyZXNzID0gR2xvYmFsU3RhdGUoeyBpbml0aWFsVmFsdWU6IG5ldyBBZGRyZXNzKEdsb2JhbC5jcmVhdG9yQWRkcmVzcyksIGtleTogJ2V4cGxpY2l0X2tleV9hcmM0X2FkZHJlc3MnIH0pCiAgICBieXRlYyAxMiAvLyAiZXhwbGljaXRfa2V5X2FyYzRfYWRkcmVzcyIKICAgIGdsb2JhbCBDcmVhdG9yQWRkcmVzcwogICAgYXBwX2dsb2JhbF9wdXQKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo2MDcKICAgIC8vIGFyYzRVaW50TjEyOCA9IEdsb2JhbFN0YXRlKHsgaW5pdGlhbFZhbHVlOiBuZXcgVWludE4xMjgoMm4gKiogMTAwbiksIGtleTogJ2V4cGxpY2l0X2tleV9hcmM0X3VpbnRuMTI4JyB9KQogICAgYnl0ZWMgMTMgLy8gImV4cGxpY2l0X2tleV9hcmM0X3VpbnRuMTI4IgogICAgYnl0ZWMgMTcgLy8gMHgwMDAwMDAxMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMAogICAgYXBwX2dsb2JhbF9wdXQKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo2MDgKICAgIC8vIGFyYzREeW5hbWljQnl0ZXMgPSBHbG9iYWxTdGF0ZSh7IGluaXRpYWxWYWx1ZTogbmV3IER5bmFtaWNCeXRlcygnZHluYW1pYyBieXRlcycpLCBrZXk6ICdleHBsaWNpdF9rZXlfYXJjNF9keW5hbWljX2J5dGVzJyB9KQogICAgYnl0ZWMgMTQgLy8gImV4cGxpY2l0X2tleV9hcmM0X2R5bmFtaWNfYnl0ZXMiCiAgICBieXRlYyAxOCAvLyAweDAwMGQ2NDc5NmU2MTZkNjk2MzIwNjI3OTc0NjU3MwogICAgYXBwX2dsb2JhbF9wdXQKICAgIHJldHN1YgoKCi8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo6R2xvYmFsU3RhdGVDb250cmFjdC5fX3B1eWFfYXJjNF9yb3V0ZXJfXygpIC0+IHVpbnQ2NDoKX19wdXlhX2FyYzRfcm91dGVyX186CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NTkxCiAgICAvLyBleHBvcnQgY2xhc3MgR2xvYmFsU3RhdGVDb250cmFjdCBleHRlbmRzIGFyYzQuQ29udHJhY3QgewogICAgcHJvdG8gMCAxCiAgICB0eG4gTnVtQXBwQXJncwogICAgYnogX19wdXlhX2FyYzRfcm91dGVyX19fYmFyZV9yb3V0aW5nQDMyCiAgICBwdXNoYnl0ZXNzIDB4OGFiN2Y4YmYgMHg4NmVjMjRmMyAweDY5MTI4ZTkwIDB4NjhkNTkwZTIgMHg0NGVmMDY4MSAweDVjMjFiZDYwIDB4YWFjOGVjYjEgMHhhMTUyODhjZSAweDVmMjNhY2ZkIDB4ZGVkNzUwMzMgMHg2NjI3OWU5MyAweDA5NmU5MjdiIDB4MTA2YmMwMGIgMHg2ZWEzZjk5NiAweDNkZjBhMmNkIDB4OGM0ZDhmODAgMHg1ZWMzMTE2ZCAweDIwZjU2ZWVlIDB4MWMxNDlhNDMgMHg4ZTZhMWRkZSAweDg3ZjA4NjliIDB4MDI2NDY5YTEgMHhmMDU0YWI3YiAweGQyZTY0NmVmIDB4ZTY3NGEyNzAgMHhhODdlNTQwZCAweDU4YTc0MDRhIDB4MjU3NzA4ZjcgLy8gbWV0aG9kICJnZXRfaW1wbGljaXRfa2V5X2FyYzRfdWludG42NCgpdWludDY0IiwgbWV0aG9kICJnZXRfaW1wbGljaXRfa2V5X2FyYzRfc3RyKClzdHJpbmciLCBtZXRob2QgImdldF9pbXBsaWNpdF9rZXlfYXJjNF9ieXRlKClieXRlIiwgbWV0aG9kICJnZXRfaW1wbGljaXRfa2V5X2FyYzRfYm9vbCgpYm9vbCIsIG1ldGhvZCAiZ2V0X2ltcGxpY2l0X2tleV9hcmM0X2FkZHJlc3MoKWFkZHJlc3MiLCBtZXRob2QgImdldF9pbXBsaWNpdF9rZXlfYXJjNF91aW50bjEyOCgpdWludDEyOCIsIG1ldGhvZCAiZ2V0X2ltcGxpY2l0X2tleV9hcmM0X2R5bmFtaWNfYnl0ZXMoKWJ5dGVbXSIsIG1ldGhvZCAiZ2V0X2FyYzRfdWludG42NCgpdWludDY0IiwgbWV0aG9kICJnZXRfYXJjNF9zdHIoKXN0cmluZyIsIG1ldGhvZCAiZ2V0X2FyYzRfYnl0ZSgpYnl0ZSIsIG1ldGhvZCAiZ2V0X2FyYzRfYm9vbCgpYm9vbCIsIG1ldGhvZCAiZ2V0X2FyYzRfYWRkcmVzcygpYWRkcmVzcyIsIG1ldGhvZCAiZ2V0X2FyYzRfdWludG4xMjgoKXVpbnQxMjgiLCBtZXRob2QgImdldF9hcmM0X2R5bmFtaWNfYnl0ZXMoKWJ5dGVbXSIsIG1ldGhvZCAic2V0X2ltcGxpY2l0X2tleV9hcmM0X3VpbnRuNjQodWludDY0KXZvaWQiLCBtZXRob2QgInNldF9pbXBsaWNpdF9rZXlfYXJjNF9zdHIoc3RyaW5nKXZvaWQiLCBtZXRob2QgInNldF9pbXBsaWNpdF9rZXlfYXJjNF9ieXRlKGJ5dGUpdm9pZCIsIG1ldGhvZCAic2V0X2ltcGxpY2l0X2tleV9hcmM0X2Jvb2woYm9vbCl2b2lkIiwgbWV0aG9kICJzZXRfaW1wbGljaXRfa2V5X2FyYzRfYWRkcmVzcyhhZGRyZXNzKXZvaWQiLCBtZXRob2QgInNldF9pbXBsaWNpdF9rZXlfYXJjNF91aW50bjEyOCh1aW50MTI4KXZvaWQiLCBtZXRob2QgInNldF9pbXBsaWNpdF9rZXlfYXJjNF9keW5hbWljX2J5dGVzKGJ5dGVbXSl2b2lkIiwgbWV0aG9kICJzZXRfYXJjNF91aW50bjY0KHVpbnQ2NCl2b2lkIiwgbWV0aG9kICJzZXRfYXJjNF9zdHIoc3RyaW5nKXZvaWQiLCBtZXRob2QgInNldF9hcmM0X2J5dGUoYnl0ZSl2b2lkIiwgbWV0aG9kICJzZXRfYXJjNF9ib29sKGJvb2wpdm9pZCIsIG1ldGhvZCAic2V0X2FyYzRfYWRkcmVzcyhhZGRyZXNzKXZvaWQiLCBtZXRob2QgInNldF9hcmM0X3VpbnRuMTI4KHVpbnQxMjgpdm9pZCIsIG1ldGhvZCAic2V0X2FyYzRfZHluYW1pY19ieXRlcyhieXRlW10pdm9pZCIKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDAKICAgIG1hdGNoIF9fcHV5YV9hcmM0X3JvdXRlcl9fX2dldF9pbXBsaWNpdF9rZXlfYXJjNF91aW50bjY0X3JvdXRlQDIgX19wdXlhX2FyYzRfcm91dGVyX19fZ2V0X2ltcGxpY2l0X2tleV9hcmM0X3N0cl9yb3V0ZUAzIF9fcHV5YV9hcmM0X3JvdXRlcl9fX2dldF9pbXBsaWNpdF9rZXlfYXJjNF9ieXRlX3JvdXRlQDQgX19wdXlhX2FyYzRfcm91dGVyX19fZ2V0X2ltcGxpY2l0X2tleV9hcmM0X2Jvb2xfcm91dGVANSBfX3B1eWFfYXJjNF9yb3V0ZXJfX19nZXRfaW1wbGljaXRfa2V5X2FyYzRfYWRkcmVzc19yb3V0ZUA2IF9fcHV5YV9hcmM0X3JvdXRlcl9fX2dldF9pbXBsaWNpdF9rZXlfYXJjNF91aW50bjEyOF9yb3V0ZUA3IF9fcHV5YV9hcmM0X3JvdXRlcl9fX2dldF9pbXBsaWNpdF9rZXlfYXJjNF9keW5hbWljX2J5dGVzX3JvdXRlQDggX19wdXlhX2FyYzRfcm91dGVyX19fZ2V0X2FyYzRfdWludG42NF9yb3V0ZUA5IF9fcHV5YV9hcmM0X3JvdXRlcl9fX2dldF9hcmM0X3N0cl9yb3V0ZUAxMCBfX3B1eWFfYXJjNF9yb3V0ZXJfX19nZXRfYXJjNF9ieXRlX3JvdXRlQDExIF9fcHV5YV9hcmM0X3JvdXRlcl9fX2dldF9hcmM0X2Jvb2xfcm91dGVAMTIgX19wdXlhX2FyYzRfcm91dGVyX19fZ2V0X2FyYzRfYWRkcmVzc19yb3V0ZUAxMyBfX3B1eWFfYXJjNF9yb3V0ZXJfX19nZXRfYXJjNF91aW50bjEyOF9yb3V0ZUAxNCBfX3B1eWFfYXJjNF9yb3V0ZXJfX19nZXRfYXJjNF9keW5hbWljX2J5dGVzX3JvdXRlQDE1IF9fcHV5YV9hcmM0X3JvdXRlcl9fX3NldF9pbXBsaWNpdF9rZXlfYXJjNF91aW50bjY0X3JvdXRlQDE2IF9fcHV5YV9hcmM0X3JvdXRlcl9fX3NldF9pbXBsaWNpdF9rZXlfYXJjNF9zdHJfcm91dGVAMTcgX19wdXlhX2FyYzRfcm91dGVyX19fc2V0X2ltcGxpY2l0X2tleV9hcmM0X2J5dGVfcm91dGVAMTggX19wdXlhX2FyYzRfcm91dGVyX19fc2V0X2ltcGxpY2l0X2tleV9hcmM0X2Jvb2xfcm91dGVAMTkgX19wdXlhX2FyYzRfcm91dGVyX19fc2V0X2ltcGxpY2l0X2tleV9hcmM0X2FkZHJlc3Nfcm91dGVAMjAgX19wdXlhX2FyYzRfcm91dGVyX19fc2V0X2ltcGxpY2l0X2tleV9hcmM0X3VpbnRuMTI4X3JvdXRlQDIxIF9fcHV5YV9hcmM0X3JvdXRlcl9fX3NldF9pbXBsaWNpdF9rZXlfYXJjNF9keW5hbWljX2J5dGVzX3JvdXRlQDIyIF9fcHV5YV9hcmM0X3JvdXRlcl9fX3NldF9hcmM0X3VpbnRuNjRfcm91dGVAMjMgX19wdXlhX2FyYzRfcm91dGVyX19fc2V0X2FyYzRfc3RyX3JvdXRlQDI0IF9fcHV5YV9hcmM0X3JvdXRlcl9fX3NldF9hcmM0X2J5dGVfcm91dGVAMjUgX19wdXlhX2FyYzRfcm91dGVyX19fc2V0X2FyYzRfYm9vbF9yb3V0ZUAyNiBfX3B1eWFfYXJjNF9yb3V0ZXJfX19zZXRfYXJjNF9hZGRyZXNzX3JvdXRlQDI3IF9fcHV5YV9hcmM0X3JvdXRlcl9fX3NldF9hcmM0X3VpbnRuMTI4X3JvdXRlQDI4IF9fcHV5YV9hcmM0X3JvdXRlcl9fX3NldF9hcmM0X2R5bmFtaWNfYnl0ZXNfcm91dGVAMjkKICAgIGludGNfMSAvLyAwCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX2dldF9pbXBsaWNpdF9rZXlfYXJjNF91aW50bjY0X3JvdXRlQDI6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NjExCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBub3QgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBjYW4gb25seSBjYWxsIHdoZW4gbm90IGNyZWF0aW5nCiAgICBjYWxsc3ViIGdldF9pbXBsaWNpdF9rZXlfYXJjNF91aW50bjY0CiAgICBieXRlY18wIC8vIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnRjXzAgLy8gMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX19nZXRfaW1wbGljaXRfa2V5X2FyYzRfc3RyX3JvdXRlQDM6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NjE2CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBub3QgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBjYW4gb25seSBjYWxsIHdoZW4gbm90IGNyZWF0aW5nCiAgICBjYWxsc3ViIGdldF9pbXBsaWNpdF9rZXlfYXJjNF9zdHIKICAgIGJ5dGVjXzAgLy8gMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludGNfMCAvLyAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX2dldF9pbXBsaWNpdF9rZXlfYXJjNF9ieXRlX3JvdXRlQDQ6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NjIxCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBub3QgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBjYW4gb25seSBjYWxsIHdoZW4gbm90IGNyZWF0aW5nCiAgICBjYWxsc3ViIGdldF9pbXBsaWNpdF9rZXlfYXJjNF9ieXRlCiAgICBieXRlY18wIC8vIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnRjXzAgLy8gMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX19nZXRfaW1wbGljaXRfa2V5X2FyYzRfYm9vbF9yb3V0ZUA1OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjYyNgogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgbm90IE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gY2FuIG9ubHkgY2FsbCB3aGVuIG5vdCBjcmVhdGluZwogICAgY2FsbHN1YiBnZXRfaW1wbGljaXRfa2V5X2FyYzRfYm9vbAogICAgYnl0ZWNfMCAvLyAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50Y18wIC8vIDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fZ2V0X2ltcGxpY2l0X2tleV9hcmM0X2FkZHJlc3Nfcm91dGVANjoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo2MzEKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIG5vdCBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGNhbiBvbmx5IGNhbGwgd2hlbiBub3QgY3JlYXRpbmcKICAgIGNhbGxzdWIgZ2V0X2ltcGxpY2l0X2tleV9hcmM0X2FkZHJlc3MKICAgIGJ5dGVjXzAgLy8gMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludGNfMCAvLyAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX2dldF9pbXBsaWNpdF9rZXlfYXJjNF91aW50bjEyOF9yb3V0ZUA3OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjYzNgogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgbm90IE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gY2FuIG9ubHkgY2FsbCB3aGVuIG5vdCBjcmVhdGluZwogICAgY2FsbHN1YiBnZXRfaW1wbGljaXRfa2V5X2FyYzRfdWludG4xMjgKICAgIGJ5dGVjXzAgLy8gMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludGNfMCAvLyAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX2dldF9pbXBsaWNpdF9rZXlfYXJjNF9keW5hbWljX2J5dGVzX3JvdXRlQDg6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NjQxCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBub3QgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBjYW4gb25seSBjYWxsIHdoZW4gbm90IGNyZWF0aW5nCiAgICBjYWxsc3ViIGdldF9pbXBsaWNpdF9rZXlfYXJjNF9keW5hbWljX2J5dGVzCiAgICBieXRlY18wIC8vIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnRjXzAgLy8gMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX19nZXRfYXJjNF91aW50bjY0X3JvdXRlQDk6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NjQ3CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBub3QgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBjYW4gb25seSBjYWxsIHdoZW4gbm90IGNyZWF0aW5nCiAgICBjYWxsc3ViIGdldF9hcmM0X3VpbnRuNjQKICAgIGJ5dGVjXzAgLy8gMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludGNfMCAvLyAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX2dldF9hcmM0X3N0cl9yb3V0ZUAxMDoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo2NTIKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIG5vdCBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGNhbiBvbmx5IGNhbGwgd2hlbiBub3QgY3JlYXRpbmcKICAgIGNhbGxzdWIgZ2V0X2FyYzRfc3RyCiAgICBieXRlY18wIC8vIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnRjXzAgLy8gMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX19nZXRfYXJjNF9ieXRlX3JvdXRlQDExOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjY1NwogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgbm90IE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gY2FuIG9ubHkgY2FsbCB3aGVuIG5vdCBjcmVhdGluZwogICAgY2FsbHN1YiBnZXRfYXJjNF9ieXRlCiAgICBieXRlY18wIC8vIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnRjXzAgLy8gMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX19nZXRfYXJjNF9ib29sX3JvdXRlQDEyOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjY2MgogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgbm90IE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gY2FuIG9ubHkgY2FsbCB3aGVuIG5vdCBjcmVhdGluZwogICAgY2FsbHN1YiBnZXRfYXJjNF9ib29sCiAgICBieXRlY18wIC8vIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnRjXzAgLy8gMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX19nZXRfYXJjNF9hZGRyZXNzX3JvdXRlQDEzOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjY2NwogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgbm90IE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gY2FuIG9ubHkgY2FsbCB3aGVuIG5vdCBjcmVhdGluZwogICAgY2FsbHN1YiBnZXRfYXJjNF9hZGRyZXNzCiAgICBieXRlY18wIC8vIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnRjXzAgLy8gMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX19nZXRfYXJjNF91aW50bjEyOF9yb3V0ZUAxNDoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo2NzIKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIG5vdCBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGNhbiBvbmx5IGNhbGwgd2hlbiBub3QgY3JlYXRpbmcKICAgIGNhbGxzdWIgZ2V0X2FyYzRfdWludG4xMjgKICAgIGJ5dGVjXzAgLy8gMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludGNfMCAvLyAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX2dldF9hcmM0X2R5bmFtaWNfYnl0ZXNfcm91dGVAMTU6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6Njc3CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBub3QgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBjYW4gb25seSBjYWxsIHdoZW4gbm90IGNyZWF0aW5nCiAgICBjYWxsc3ViIGdldF9hcmM0X2R5bmFtaWNfYnl0ZXMKICAgIGJ5dGVjXzAgLy8gMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludGNfMCAvLyAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX3NldF9pbXBsaWNpdF9rZXlfYXJjNF91aW50bjY0X3JvdXRlQDE2OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjY4MwogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgbm90IE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gY2FuIG9ubHkgY2FsbCB3aGVuIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjU5MQogICAgLy8gZXhwb3J0IGNsYXNzIEdsb2JhbFN0YXRlQ29udHJhY3QgZXh0ZW5kcyBhcmM0LkNvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo2ODMKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHNldF9pbXBsaWNpdF9rZXlfYXJjNF91aW50bjY0CiAgICBpbnRjXzAgLy8gMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX19zZXRfaW1wbGljaXRfa2V5X2FyYzRfc3RyX3JvdXRlQDE3OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjY4OAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgbm90IE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gY2FuIG9ubHkgY2FsbCB3aGVuIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjU5MQogICAgLy8gZXhwb3J0IGNsYXNzIEdsb2JhbFN0YXRlQ29udHJhY3QgZXh0ZW5kcyBhcmM0LkNvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo2ODgKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHNldF9pbXBsaWNpdF9rZXlfYXJjNF9zdHIKICAgIGludGNfMCAvLyAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX3NldF9pbXBsaWNpdF9rZXlfYXJjNF9ieXRlX3JvdXRlQDE4OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjY5MwogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgbm90IE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gY2FuIG9ubHkgY2FsbCB3aGVuIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjU5MQogICAgLy8gZXhwb3J0IGNsYXNzIEdsb2JhbFN0YXRlQ29udHJhY3QgZXh0ZW5kcyBhcmM0LkNvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo2OTMKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHNldF9pbXBsaWNpdF9rZXlfYXJjNF9ieXRlCiAgICBpbnRjXzAgLy8gMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX19zZXRfaW1wbGljaXRfa2V5X2FyYzRfYm9vbF9yb3V0ZUAxOToKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo2OTgKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIG5vdCBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGNhbiBvbmx5IGNhbGwgd2hlbiBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo1OTEKICAgIC8vIGV4cG9ydCBjbGFzcyBHbG9iYWxTdGF0ZUNvbnRyYWN0IGV4dGVuZHMgYXJjNC5Db250cmFjdCB7CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6Njk4CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiBzZXRfaW1wbGljaXRfa2V5X2FyYzRfYm9vbAogICAgaW50Y18wIC8vIDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fc2V0X2ltcGxpY2l0X2tleV9hcmM0X2FkZHJlc3Nfcm91dGVAMjA6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NzAzCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBub3QgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBjYW4gb25seSBjYWxsIHdoZW4gbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NTkxCiAgICAvLyBleHBvcnQgY2xhc3MgR2xvYmFsU3RhdGVDb250cmFjdCBleHRlbmRzIGFyYzQuQ29udHJhY3QgewogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjcwMwogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgc2V0X2ltcGxpY2l0X2tleV9hcmM0X2FkZHJlc3MKICAgIGludGNfMCAvLyAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX3NldF9pbXBsaWNpdF9rZXlfYXJjNF91aW50bjEyOF9yb3V0ZUAyMToKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo3MDgKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIG5vdCBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGNhbiBvbmx5IGNhbGwgd2hlbiBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo1OTEKICAgIC8vIGV4cG9ydCBjbGFzcyBHbG9iYWxTdGF0ZUNvbnRyYWN0IGV4dGVuZHMgYXJjNC5Db250cmFjdCB7CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NzA4CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiBzZXRfaW1wbGljaXRfa2V5X2FyYzRfdWludG4xMjgKICAgIGludGNfMCAvLyAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX3NldF9pbXBsaWNpdF9rZXlfYXJjNF9keW5hbWljX2J5dGVzX3JvdXRlQDIyOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjcxMwogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgbm90IE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gY2FuIG9ubHkgY2FsbCB3aGVuIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjU5MQogICAgLy8gZXhwb3J0IGNsYXNzIEdsb2JhbFN0YXRlQ29udHJhY3QgZXh0ZW5kcyBhcmM0LkNvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo3MTMKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHNldF9pbXBsaWNpdF9rZXlfYXJjNF9keW5hbWljX2J5dGVzCiAgICBpbnRjXzAgLy8gMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX19zZXRfYXJjNF91aW50bjY0X3JvdXRlQDIzOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjcxOQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgbm90IE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gY2FuIG9ubHkgY2FsbCB3aGVuIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjU5MQogICAgLy8gZXhwb3J0IGNsYXNzIEdsb2JhbFN0YXRlQ29udHJhY3QgZXh0ZW5kcyBhcmM0LkNvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo3MTkKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHNldF9hcmM0X3VpbnRuNjQKICAgIGludGNfMCAvLyAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX3NldF9hcmM0X3N0cl9yb3V0ZUAyNDoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo3MjQKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIG5vdCBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGNhbiBvbmx5IGNhbGwgd2hlbiBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo1OTEKICAgIC8vIGV4cG9ydCBjbGFzcyBHbG9iYWxTdGF0ZUNvbnRyYWN0IGV4dGVuZHMgYXJjNC5Db250cmFjdCB7CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NzI0CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiBzZXRfYXJjNF9zdHIKICAgIGludGNfMCAvLyAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX3NldF9hcmM0X2J5dGVfcm91dGVAMjU6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NzI5CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBub3QgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBjYW4gb25seSBjYWxsIHdoZW4gbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NTkxCiAgICAvLyBleHBvcnQgY2xhc3MgR2xvYmFsU3RhdGVDb250cmFjdCBleHRlbmRzIGFyYzQuQ29udHJhY3QgewogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjcyOQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgc2V0X2FyYzRfYnl0ZQogICAgaW50Y18wIC8vIDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fc2V0X2FyYzRfYm9vbF9yb3V0ZUAyNjoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo3MzQKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIG5vdCBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGNhbiBvbmx5IGNhbGwgd2hlbiBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo1OTEKICAgIC8vIGV4cG9ydCBjbGFzcyBHbG9iYWxTdGF0ZUNvbnRyYWN0IGV4dGVuZHMgYXJjNC5Db250cmFjdCB7CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NzM0CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiBzZXRfYXJjNF9ib29sCiAgICBpbnRjXzAgLy8gMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX19zZXRfYXJjNF9hZGRyZXNzX3JvdXRlQDI3OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjczOQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgbm90IE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gY2FuIG9ubHkgY2FsbCB3aGVuIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjU5MQogICAgLy8gZXhwb3J0IGNsYXNzIEdsb2JhbFN0YXRlQ29udHJhY3QgZXh0ZW5kcyBhcmM0LkNvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo3MzkKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHNldF9hcmM0X2FkZHJlc3MKICAgIGludGNfMCAvLyAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX3NldF9hcmM0X3VpbnRuMTI4X3JvdXRlQDI4OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjc0NAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgbm90IE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gY2FuIG9ubHkgY2FsbCB3aGVuIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjU5MQogICAgLy8gZXhwb3J0IGNsYXNzIEdsb2JhbFN0YXRlQ29udHJhY3QgZXh0ZW5kcyBhcmM0LkNvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo3NDQKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHNldF9hcmM0X3VpbnRuMTI4CiAgICBpbnRjXzAgLy8gMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX19zZXRfYXJjNF9keW5hbWljX2J5dGVzX3JvdXRlQDI5OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjc0OQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgbm90IE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gY2FuIG9ubHkgY2FsbCB3aGVuIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjU5MQogICAgLy8gZXhwb3J0IGNsYXNzIEdsb2JhbFN0YXRlQ29udHJhY3QgZXh0ZW5kcyBhcmM0LkNvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo3NDkKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHNldF9hcmM0X2R5bmFtaWNfYnl0ZXMKICAgIGludGNfMCAvLyAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX2JhcmVfcm91dGluZ0AzMjoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo1OTEKICAgIC8vIGV4cG9ydCBjbGFzcyBHbG9iYWxTdGF0ZUNvbnRyYWN0IGV4dGVuZHMgYXJjNC5Db250cmFjdCB7CiAgICB0eG4gT25Db21wbGV0aW9uCiAgICBibnogX19wdXlhX2FyYzRfcm91dGVyX19fYWZ0ZXJfaWZfZWxzZUAzNgogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgICEKICAgIGFzc2VydCAvLyBjYW4gb25seSBjYWxsIHdoZW4gY3JlYXRpbmcKICAgIGludGNfMCAvLyAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX2FmdGVyX2lmX2Vsc2VAMzY6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NTkxCiAgICAvLyBleHBvcnQgY2xhc3MgR2xvYmFsU3RhdGVDb250cmFjdCBleHRlbmRzIGFyYzQuQ29udHJhY3QgewogICAgaW50Y18xIC8vIDAKICAgIHJldHN1YgoKCi8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo6R2xvYmFsU3RhdGVDb250cmFjdC5nZXRfaW1wbGljaXRfa2V5X2FyYzRfdWludG42NCgpIC0+IGJ5dGVzOgpnZXRfaW1wbGljaXRfa2V5X2FyYzRfdWludG42NDoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo2MTEtNjEyCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gZ2V0X2ltcGxpY2l0X2tleV9hcmM0X3VpbnRuNjQoKTogVWludE42NCB7CiAgICBwcm90byAwIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo2MTMKICAgIC8vIHJldHVybiB0aGlzLmltcGxpY2l0S2V5QXJjNFVpbnRONjQudmFsdWUKICAgIGludGNfMSAvLyAwCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NTkzCiAgICAvLyBpbXBsaWNpdEtleUFyYzRVaW50TjY0ID0gR2xvYmFsU3RhdGUoeyBpbml0aWFsVmFsdWU6IG5ldyBVaW50TjY0KDEzMzcpIH0pCiAgICBieXRlY18xIC8vICJpbXBsaWNpdEtleUFyYzRVaW50TjY0IgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjYxMwogICAgLy8gcmV0dXJuIHRoaXMuaW1wbGljaXRLZXlBcmM0VWludE42NC52YWx1ZQogICAgYXBwX2dsb2JhbF9nZXRfZXgKICAgIGFzc2VydCAvLyBjaGVjayBHbG9iYWxTdGF0ZSBleGlzdHMKICAgIHJldHN1YgoKCi8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo6R2xvYmFsU3RhdGVDb250cmFjdC5nZXRfaW1wbGljaXRfa2V5X2FyYzRfc3RyKCkgLT4gYnl0ZXM6CmdldF9pbXBsaWNpdF9rZXlfYXJjNF9zdHI6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NjE2LTYxNwogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIGdldF9pbXBsaWNpdF9rZXlfYXJjNF9zdHIoKTogU3RyIHsKICAgIHByb3RvIDAgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjYxOAogICAgLy8gcmV0dXJuIHRoaXMuaW1wbGljaXRLZXlBcmM0U3RyLnZhbHVlCiAgICBpbnRjXzEgLy8gMAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjU5NAogICAgLy8gaW1wbGljaXRLZXlBcmM0U3RyID0gR2xvYmFsU3RhdGUoeyBpbml0aWFsVmFsdWU6IG5ldyBTdHIoJ0hlbGxvJykgfSkKICAgIGJ5dGVjXzIgLy8gImltcGxpY2l0S2V5QXJjNFN0ciIKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo2MTgKICAgIC8vIHJldHVybiB0aGlzLmltcGxpY2l0S2V5QXJjNFN0ci52YWx1ZQogICAgYXBwX2dsb2JhbF9nZXRfZXgKICAgIGFzc2VydCAvLyBjaGVjayBHbG9iYWxTdGF0ZSBleGlzdHMKICAgIHJldHN1YgoKCi8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo6R2xvYmFsU3RhdGVDb250cmFjdC5nZXRfaW1wbGljaXRfa2V5X2FyYzRfYnl0ZSgpIC0+IGJ5dGVzOgpnZXRfaW1wbGljaXRfa2V5X2FyYzRfYnl0ZToKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo2MjEtNjIyCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gZ2V0X2ltcGxpY2l0X2tleV9hcmM0X2J5dGUoKTogQnl0ZSB7CiAgICBwcm90byAwIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo2MjMKICAgIC8vIHJldHVybiB0aGlzLmltcGxpY2l0S2V5QXJjNEJ5dGUudmFsdWUKICAgIGludGNfMSAvLyAwCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NTk1CiAgICAvLyBpbXBsaWNpdEtleUFyYzRCeXRlID0gR2xvYmFsU3RhdGUoeyBpbml0aWFsVmFsdWU6IG5ldyBCeXRlKDApIH0pCiAgICBieXRlY18zIC8vICJpbXBsaWNpdEtleUFyYzRCeXRlIgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjYyMwogICAgLy8gcmV0dXJuIHRoaXMuaW1wbGljaXRLZXlBcmM0Qnl0ZS52YWx1ZQogICAgYXBwX2dsb2JhbF9nZXRfZXgKICAgIGFzc2VydCAvLyBjaGVjayBHbG9iYWxTdGF0ZSBleGlzdHMKICAgIHJldHN1YgoKCi8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo6R2xvYmFsU3RhdGVDb250cmFjdC5nZXRfaW1wbGljaXRfa2V5X2FyYzRfYm9vbCgpIC0+IGJ5dGVzOgpnZXRfaW1wbGljaXRfa2V5X2FyYzRfYm9vbDoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo2MjYtNjI3CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gZ2V0X2ltcGxpY2l0X2tleV9hcmM0X2Jvb2woKTogYXJjNC5Cb29sIHsKICAgIHByb3RvIDAgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjYyOAogICAgLy8gcmV0dXJuIHRoaXMuaW1wbGljaXRLZXlBcmM0Qm9vbC52YWx1ZQogICAgaW50Y18xIC8vIDAKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo1OTYKICAgIC8vIGltcGxpY2l0S2V5QXJjNEJvb2wgPSBHbG9iYWxTdGF0ZSh7IGluaXRpYWxWYWx1ZTogbmV3IEJvb2wodHJ1ZSkgfSkKICAgIGJ5dGVjIDQgLy8gImltcGxpY2l0S2V5QXJjNEJvb2wiCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NjI4CiAgICAvLyByZXR1cm4gdGhpcy5pbXBsaWNpdEtleUFyYzRCb29sLnZhbHVlCiAgICBhcHBfZ2xvYmFsX2dldF9leAogICAgYXNzZXJ0IC8vIGNoZWNrIEdsb2JhbFN0YXRlIGV4aXN0cwogICAgcmV0c3ViCgoKLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjpHbG9iYWxTdGF0ZUNvbnRyYWN0LmdldF9pbXBsaWNpdF9rZXlfYXJjNF9hZGRyZXNzKCkgLT4gYnl0ZXM6CmdldF9pbXBsaWNpdF9rZXlfYXJjNF9hZGRyZXNzOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjYzMS02MzIKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBnZXRfaW1wbGljaXRfa2V5X2FyYzRfYWRkcmVzcygpOiBBZGRyZXNzIHsKICAgIHByb3RvIDAgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjYzMwogICAgLy8gcmV0dXJuIHRoaXMuaW1wbGljaXRLZXlBcmM0QWRkcmVzcy52YWx1ZQogICAgaW50Y18xIC8vIDAKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo1OTcKICAgIC8vIGltcGxpY2l0S2V5QXJjNEFkZHJlc3MgPSBHbG9iYWxTdGF0ZSh7IGluaXRpYWxWYWx1ZTogbmV3IEFkZHJlc3MoR2xvYmFsLmNyZWF0b3JBZGRyZXNzKSB9KQogICAgYnl0ZWMgNSAvLyAiaW1wbGljaXRLZXlBcmM0QWRkcmVzcyIKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo2MzMKICAgIC8vIHJldHVybiB0aGlzLmltcGxpY2l0S2V5QXJjNEFkZHJlc3MudmFsdWUKICAgIGFwcF9nbG9iYWxfZ2V0X2V4CiAgICBhc3NlcnQgLy8gY2hlY2sgR2xvYmFsU3RhdGUgZXhpc3RzCiAgICByZXRzdWIKCgovLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6Okdsb2JhbFN0YXRlQ29udHJhY3QuZ2V0X2ltcGxpY2l0X2tleV9hcmM0X3VpbnRuMTI4KCkgLT4gYnl0ZXM6CmdldF9pbXBsaWNpdF9rZXlfYXJjNF91aW50bjEyODoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo2MzYtNjM3CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gZ2V0X2ltcGxpY2l0X2tleV9hcmM0X3VpbnRuMTI4KCk6IFVpbnROMTI4IHsKICAgIHByb3RvIDAgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjYzOAogICAgLy8gcmV0dXJuIHRoaXMuaW1wbGljaXRLZXlBcmM0VWludE4xMjgudmFsdWUKICAgIGludGNfMSAvLyAwCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NTk4CiAgICAvLyBpbXBsaWNpdEtleUFyYzRVaW50TjEyOCA9IEdsb2JhbFN0YXRlKHsgaW5pdGlhbFZhbHVlOiBuZXcgVWludE4xMjgoMm4gKiogMTAwbikgfSkKICAgIGJ5dGVjIDYgLy8gImltcGxpY2l0S2V5QXJjNFVpbnROMTI4IgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjYzOAogICAgLy8gcmV0dXJuIHRoaXMuaW1wbGljaXRLZXlBcmM0VWludE4xMjgudmFsdWUKICAgIGFwcF9nbG9iYWxfZ2V0X2V4CiAgICBhc3NlcnQgLy8gY2hlY2sgR2xvYmFsU3RhdGUgZXhpc3RzCiAgICByZXRzdWIKCgovLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6Okdsb2JhbFN0YXRlQ29udHJhY3QuZ2V0X2ltcGxpY2l0X2tleV9hcmM0X2R5bmFtaWNfYnl0ZXMoKSAtPiBieXRlczoKZ2V0X2ltcGxpY2l0X2tleV9hcmM0X2R5bmFtaWNfYnl0ZXM6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NjQxLTY0MgogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIGdldF9pbXBsaWNpdF9rZXlfYXJjNF9keW5hbWljX2J5dGVzKCk6IER5bmFtaWNCeXRlcyB7CiAgICBwcm90byAwIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo2NDMKICAgIC8vIHJldHVybiB0aGlzLmltcGxpY2l0S2V5QXJjNER5bmFtaWNCeXRlcy52YWx1ZQogICAgaW50Y18xIC8vIDAKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo1OTkKICAgIC8vIGltcGxpY2l0S2V5QXJjNER5bmFtaWNCeXRlcyA9IEdsb2JhbFN0YXRlKHsgaW5pdGlhbFZhbHVlOiBuZXcgRHluYW1pY0J5dGVzKCdkeW5hbWljIGJ5dGVzJykgfSkKICAgIGJ5dGVjIDcgLy8gImltcGxpY2l0S2V5QXJjNER5bmFtaWNCeXRlcyIKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo2NDMKICAgIC8vIHJldHVybiB0aGlzLmltcGxpY2l0S2V5QXJjNER5bmFtaWNCeXRlcy52YWx1ZQogICAgYXBwX2dsb2JhbF9nZXRfZXgKICAgIGFzc2VydCAvLyBjaGVjayBHbG9iYWxTdGF0ZSBleGlzdHMKICAgIHJldHN1YgoKCi8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo6R2xvYmFsU3RhdGVDb250cmFjdC5nZXRfYXJjNF91aW50bjY0KCkgLT4gYnl0ZXM6CmdldF9hcmM0X3VpbnRuNjQ6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NjQ3LTY0OAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIGdldF9hcmM0X3VpbnRuNjQoKTogVWludE42NCB7CiAgICBwcm90byAwIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo2NDkKICAgIC8vIHJldHVybiB0aGlzLmFyYzRVaW50TjY0LnZhbHVlCiAgICBpbnRjXzEgLy8gMAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjYwMgogICAgLy8gYXJjNFVpbnRONjQgPSBHbG9iYWxTdGF0ZSh7IGluaXRpYWxWYWx1ZTogbmV3IFVpbnRONjQoMTMzNyksIGtleTogJ2V4cGxpY2l0X2tleV9hcmM0X3VpbnRuNjQnIH0pCiAgICBieXRlYyA4IC8vICJleHBsaWNpdF9rZXlfYXJjNF91aW50bjY0IgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjY0OQogICAgLy8gcmV0dXJuIHRoaXMuYXJjNFVpbnRONjQudmFsdWUKICAgIGFwcF9nbG9iYWxfZ2V0X2V4CiAgICBhc3NlcnQgLy8gY2hlY2sgR2xvYmFsU3RhdGUgZXhpc3RzCiAgICByZXRzdWIKCgovLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6Okdsb2JhbFN0YXRlQ29udHJhY3QuZ2V0X2FyYzRfc3RyKCkgLT4gYnl0ZXM6CmdldF9hcmM0X3N0cjoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo2NTItNjUzCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gZ2V0X2FyYzRfc3RyKCk6IFN0ciB7CiAgICBwcm90byAwIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo2NTQKICAgIC8vIHJldHVybiB0aGlzLmFyYzRTdHIudmFsdWUKICAgIGludGNfMSAvLyAwCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NjAzCiAgICAvLyBhcmM0U3RyID0gR2xvYmFsU3RhdGUoeyBpbml0aWFsVmFsdWU6IG5ldyBTdHIoJ0hlbGxvJyksIGtleTogJ2V4cGxpY2l0X2tleV9hcmM0X3N0cicgfSkKICAgIGJ5dGVjIDkgLy8gImV4cGxpY2l0X2tleV9hcmM0X3N0ciIKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo2NTQKICAgIC8vIHJldHVybiB0aGlzLmFyYzRTdHIudmFsdWUKICAgIGFwcF9nbG9iYWxfZ2V0X2V4CiAgICBhc3NlcnQgLy8gY2hlY2sgR2xvYmFsU3RhdGUgZXhpc3RzCiAgICByZXRzdWIKCgovLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6Okdsb2JhbFN0YXRlQ29udHJhY3QuZ2V0X2FyYzRfYnl0ZSgpIC0+IGJ5dGVzOgpnZXRfYXJjNF9ieXRlOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjY1Ny02NTgKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBnZXRfYXJjNF9ieXRlKCk6IEJ5dGUgewogICAgcHJvdG8gMCAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NjU5CiAgICAvLyByZXR1cm4gdGhpcy5hcmM0Qnl0ZS52YWx1ZQogICAgaW50Y18xIC8vIDAKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo2MDQKICAgIC8vIGFyYzRCeXRlID0gR2xvYmFsU3RhdGUoeyBpbml0aWFsVmFsdWU6IG5ldyBCeXRlKDApLCBrZXk6ICdleHBsaWNpdF9rZXlfYXJjNF9ieXRlJyB9KQogICAgYnl0ZWMgMTAgLy8gImV4cGxpY2l0X2tleV9hcmM0X2J5dGUiCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NjU5CiAgICAvLyByZXR1cm4gdGhpcy5hcmM0Qnl0ZS52YWx1ZQogICAgYXBwX2dsb2JhbF9nZXRfZXgKICAgIGFzc2VydCAvLyBjaGVjayBHbG9iYWxTdGF0ZSBleGlzdHMKICAgIHJldHN1YgoKCi8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo6R2xvYmFsU3RhdGVDb250cmFjdC5nZXRfYXJjNF9ib29sKCkgLT4gYnl0ZXM6CmdldF9hcmM0X2Jvb2w6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NjYyLTY2MwogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIGdldF9hcmM0X2Jvb2woKTogYXJjNC5Cb29sIHsKICAgIHByb3RvIDAgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjY2NAogICAgLy8gcmV0dXJuIHRoaXMuYXJjNEJvb2wudmFsdWUKICAgIGludGNfMSAvLyAwCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NjA1CiAgICAvLyBhcmM0Qm9vbCA9IEdsb2JhbFN0YXRlKHsgaW5pdGlhbFZhbHVlOiBuZXcgQm9vbCh0cnVlKSwga2V5OiAnZXhwbGljaXRfa2V5X2FyYzRfYm9vbCcgfSkKICAgIGJ5dGVjIDExIC8vICJleHBsaWNpdF9rZXlfYXJjNF9ib29sIgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjY2NAogICAgLy8gcmV0dXJuIHRoaXMuYXJjNEJvb2wudmFsdWUKICAgIGFwcF9nbG9iYWxfZ2V0X2V4CiAgICBhc3NlcnQgLy8gY2hlY2sgR2xvYmFsU3RhdGUgZXhpc3RzCiAgICByZXRzdWIKCgovLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6Okdsb2JhbFN0YXRlQ29udHJhY3QuZ2V0X2FyYzRfYWRkcmVzcygpIC0+IGJ5dGVzOgpnZXRfYXJjNF9hZGRyZXNzOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjY2Ny02NjgKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBnZXRfYXJjNF9hZGRyZXNzKCk6IEFkZHJlc3MgewogICAgcHJvdG8gMCAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NjY5CiAgICAvLyByZXR1cm4gdGhpcy5hcmM0QWRkcmVzcy52YWx1ZQogICAgaW50Y18xIC8vIDAKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo2MDYKICAgIC8vIGFyYzRBZGRyZXNzID0gR2xvYmFsU3RhdGUoeyBpbml0aWFsVmFsdWU6IG5ldyBBZGRyZXNzKEdsb2JhbC5jcmVhdG9yQWRkcmVzcyksIGtleTogJ2V4cGxpY2l0X2tleV9hcmM0X2FkZHJlc3MnIH0pCiAgICBieXRlYyAxMiAvLyAiZXhwbGljaXRfa2V5X2FyYzRfYWRkcmVzcyIKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo2NjkKICAgIC8vIHJldHVybiB0aGlzLmFyYzRBZGRyZXNzLnZhbHVlCiAgICBhcHBfZ2xvYmFsX2dldF9leAogICAgYXNzZXJ0IC8vIGNoZWNrIEdsb2JhbFN0YXRlIGV4aXN0cwogICAgcmV0c3ViCgoKLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjpHbG9iYWxTdGF0ZUNvbnRyYWN0LmdldF9hcmM0X3VpbnRuMTI4KCkgLT4gYnl0ZXM6CmdldF9hcmM0X3VpbnRuMTI4OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjY3Mi02NzMKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBnZXRfYXJjNF91aW50bjEyOCgpOiBVaW50TjEyOCB7CiAgICBwcm90byAwIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo2NzQKICAgIC8vIHJldHVybiB0aGlzLmFyYzRVaW50TjEyOC52YWx1ZQogICAgaW50Y18xIC8vIDAKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo2MDcKICAgIC8vIGFyYzRVaW50TjEyOCA9IEdsb2JhbFN0YXRlKHsgaW5pdGlhbFZhbHVlOiBuZXcgVWludE4xMjgoMm4gKiogMTAwbiksIGtleTogJ2V4cGxpY2l0X2tleV9hcmM0X3VpbnRuMTI4JyB9KQogICAgYnl0ZWMgMTMgLy8gImV4cGxpY2l0X2tleV9hcmM0X3VpbnRuMTI4IgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjY3NAogICAgLy8gcmV0dXJuIHRoaXMuYXJjNFVpbnROMTI4LnZhbHVlCiAgICBhcHBfZ2xvYmFsX2dldF9leAogICAgYXNzZXJ0IC8vIGNoZWNrIEdsb2JhbFN0YXRlIGV4aXN0cwogICAgcmV0c3ViCgoKLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjpHbG9iYWxTdGF0ZUNvbnRyYWN0LmdldF9hcmM0X2R5bmFtaWNfYnl0ZXMoKSAtPiBieXRlczoKZ2V0X2FyYzRfZHluYW1pY19ieXRlczoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo2NzctNjc4CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gZ2V0X2FyYzRfZHluYW1pY19ieXRlcygpOiBEeW5hbWljQnl0ZXMgewogICAgcHJvdG8gMCAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6Njc5CiAgICAvLyByZXR1cm4gdGhpcy5hcmM0RHluYW1pY0J5dGVzLnZhbHVlCiAgICBpbnRjXzEgLy8gMAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjYwOAogICAgLy8gYXJjNER5bmFtaWNCeXRlcyA9IEdsb2JhbFN0YXRlKHsgaW5pdGlhbFZhbHVlOiBuZXcgRHluYW1pY0J5dGVzKCdkeW5hbWljIGJ5dGVzJyksIGtleTogJ2V4cGxpY2l0X2tleV9hcmM0X2R5bmFtaWNfYnl0ZXMnIH0pCiAgICBieXRlYyAxNCAvLyAiZXhwbGljaXRfa2V5X2FyYzRfZHluYW1pY19ieXRlcyIKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo2NzkKICAgIC8vIHJldHVybiB0aGlzLmFyYzREeW5hbWljQnl0ZXMudmFsdWUKICAgIGFwcF9nbG9iYWxfZ2V0X2V4CiAgICBhc3NlcnQgLy8gY2hlY2sgR2xvYmFsU3RhdGUgZXhpc3RzCiAgICByZXRzdWIKCgovLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6Okdsb2JhbFN0YXRlQ29udHJhY3Quc2V0X2ltcGxpY2l0X2tleV9hcmM0X3VpbnRuNjQodmFsdWU6IGJ5dGVzKSAtPiB2b2lkOgpzZXRfaW1wbGljaXRfa2V5X2FyYzRfdWludG42NDoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo2ODMtNjg0CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gc2V0X2ltcGxpY2l0X2tleV9hcmM0X3VpbnRuNjQodmFsdWU6IFVpbnRONjQpIHsKICAgIHByb3RvIDEgMAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjU5MwogICAgLy8gaW1wbGljaXRLZXlBcmM0VWludE42NCA9IEdsb2JhbFN0YXRlKHsgaW5pdGlhbFZhbHVlOiBuZXcgVWludE42NCgxMzM3KSB9KQogICAgYnl0ZWNfMSAvLyAiaW1wbGljaXRLZXlBcmM0VWludE42NCIKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo2ODUKICAgIC8vIHRoaXMuaW1wbGljaXRLZXlBcmM0VWludE42NC52YWx1ZSA9IHZhbHVlCiAgICBmcmFtZV9kaWcgLTEKICAgIGFwcF9nbG9iYWxfcHV0CiAgICByZXRzdWIKCgovLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6Okdsb2JhbFN0YXRlQ29udHJhY3Quc2V0X2ltcGxpY2l0X2tleV9hcmM0X3N0cih2YWx1ZTogYnl0ZXMpIC0+IHZvaWQ6CnNldF9pbXBsaWNpdF9rZXlfYXJjNF9zdHI6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6Njg4LTY4OQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIHNldF9pbXBsaWNpdF9rZXlfYXJjNF9zdHIodmFsdWU6IFN0cikgewogICAgcHJvdG8gMSAwCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NTk0CiAgICAvLyBpbXBsaWNpdEtleUFyYzRTdHIgPSBHbG9iYWxTdGF0ZSh7IGluaXRpYWxWYWx1ZTogbmV3IFN0cignSGVsbG8nKSB9KQogICAgYnl0ZWNfMiAvLyAiaW1wbGljaXRLZXlBcmM0U3RyIgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjY5MAogICAgLy8gdGhpcy5pbXBsaWNpdEtleUFyYzRTdHIudmFsdWUgPSB2YWx1ZQogICAgZnJhbWVfZGlnIC0xCiAgICBhcHBfZ2xvYmFsX3B1dAogICAgcmV0c3ViCgoKLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjpHbG9iYWxTdGF0ZUNvbnRyYWN0LnNldF9pbXBsaWNpdF9rZXlfYXJjNF9ieXRlKHZhbHVlOiBieXRlcykgLT4gdm9pZDoKc2V0X2ltcGxpY2l0X2tleV9hcmM0X2J5dGU6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NjkzLTY5NAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIHNldF9pbXBsaWNpdF9rZXlfYXJjNF9ieXRlKHZhbHVlOiBCeXRlKSB7CiAgICBwcm90byAxIDAKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo1OTUKICAgIC8vIGltcGxpY2l0S2V5QXJjNEJ5dGUgPSBHbG9iYWxTdGF0ZSh7IGluaXRpYWxWYWx1ZTogbmV3IEJ5dGUoMCkgfSkKICAgIGJ5dGVjXzMgLy8gImltcGxpY2l0S2V5QXJjNEJ5dGUiCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6Njk1CiAgICAvLyB0aGlzLmltcGxpY2l0S2V5QXJjNEJ5dGUudmFsdWUgPSB2YWx1ZQogICAgZnJhbWVfZGlnIC0xCiAgICBhcHBfZ2xvYmFsX3B1dAogICAgcmV0c3ViCgoKLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjpHbG9iYWxTdGF0ZUNvbnRyYWN0LnNldF9pbXBsaWNpdF9rZXlfYXJjNF9ib29sKHZhbHVlOiBieXRlcykgLT4gdm9pZDoKc2V0X2ltcGxpY2l0X2tleV9hcmM0X2Jvb2w6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6Njk4LTY5OQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIHNldF9pbXBsaWNpdF9rZXlfYXJjNF9ib29sKHZhbHVlOiBCb29sKSB7CiAgICBwcm90byAxIDAKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo1OTYKICAgIC8vIGltcGxpY2l0S2V5QXJjNEJvb2wgPSBHbG9iYWxTdGF0ZSh7IGluaXRpYWxWYWx1ZTogbmV3IEJvb2wodHJ1ZSkgfSkKICAgIGJ5dGVjIDQgLy8gImltcGxpY2l0S2V5QXJjNEJvb2wiCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NzAwCiAgICAvLyB0aGlzLmltcGxpY2l0S2V5QXJjNEJvb2wudmFsdWUgPSB2YWx1ZQogICAgZnJhbWVfZGlnIC0xCiAgICBhcHBfZ2xvYmFsX3B1dAogICAgcmV0c3ViCgoKLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjpHbG9iYWxTdGF0ZUNvbnRyYWN0LnNldF9pbXBsaWNpdF9rZXlfYXJjNF9hZGRyZXNzKHZhbHVlOiBieXRlcykgLT4gdm9pZDoKc2V0X2ltcGxpY2l0X2tleV9hcmM0X2FkZHJlc3M6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NzAzLTcwNAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIHNldF9pbXBsaWNpdF9rZXlfYXJjNF9hZGRyZXNzKHZhbHVlOiBBZGRyZXNzKSB7CiAgICBwcm90byAxIDAKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo1OTcKICAgIC8vIGltcGxpY2l0S2V5QXJjNEFkZHJlc3MgPSBHbG9iYWxTdGF0ZSh7IGluaXRpYWxWYWx1ZTogbmV3IEFkZHJlc3MoR2xvYmFsLmNyZWF0b3JBZGRyZXNzKSB9KQogICAgYnl0ZWMgNSAvLyAiaW1wbGljaXRLZXlBcmM0QWRkcmVzcyIKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo3MDUKICAgIC8vIHRoaXMuaW1wbGljaXRLZXlBcmM0QWRkcmVzcy52YWx1ZSA9IHZhbHVlCiAgICBmcmFtZV9kaWcgLTEKICAgIGFwcF9nbG9iYWxfcHV0CiAgICByZXRzdWIKCgovLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6Okdsb2JhbFN0YXRlQ29udHJhY3Quc2V0X2ltcGxpY2l0X2tleV9hcmM0X3VpbnRuMTI4KHZhbHVlOiBieXRlcykgLT4gdm9pZDoKc2V0X2ltcGxpY2l0X2tleV9hcmM0X3VpbnRuMTI4OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjcwOC03MDkKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBzZXRfaW1wbGljaXRfa2V5X2FyYzRfdWludG4xMjgodmFsdWU6IFVpbnROMTI4KSB7CiAgICBwcm90byAxIDAKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo1OTgKICAgIC8vIGltcGxpY2l0S2V5QXJjNFVpbnROMTI4ID0gR2xvYmFsU3RhdGUoeyBpbml0aWFsVmFsdWU6IG5ldyBVaW50TjEyOCgybiAqKiAxMDBuKSB9KQogICAgYnl0ZWMgNiAvLyAiaW1wbGljaXRLZXlBcmM0VWludE4xMjgiCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NzEwCiAgICAvLyB0aGlzLmltcGxpY2l0S2V5QXJjNFVpbnROMTI4LnZhbHVlID0gdmFsdWUKICAgIGZyYW1lX2RpZyAtMQogICAgYXBwX2dsb2JhbF9wdXQKICAgIHJldHN1YgoKCi8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo6R2xvYmFsU3RhdGVDb250cmFjdC5zZXRfaW1wbGljaXRfa2V5X2FyYzRfZHluYW1pY19ieXRlcyh2YWx1ZTogYnl0ZXMpIC0+IHZvaWQ6CnNldF9pbXBsaWNpdF9rZXlfYXJjNF9keW5hbWljX2J5dGVzOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjcxMy03MTQKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBzZXRfaW1wbGljaXRfa2V5X2FyYzRfZHluYW1pY19ieXRlcyh2YWx1ZTogRHluYW1pY0J5dGVzKSB7CiAgICBwcm90byAxIDAKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo1OTkKICAgIC8vIGltcGxpY2l0S2V5QXJjNER5bmFtaWNCeXRlcyA9IEdsb2JhbFN0YXRlKHsgaW5pdGlhbFZhbHVlOiBuZXcgRHluYW1pY0J5dGVzKCdkeW5hbWljIGJ5dGVzJykgfSkKICAgIGJ5dGVjIDcgLy8gImltcGxpY2l0S2V5QXJjNER5bmFtaWNCeXRlcyIKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo3MTUKICAgIC8vIHRoaXMuaW1wbGljaXRLZXlBcmM0RHluYW1pY0J5dGVzLnZhbHVlID0gdmFsdWUKICAgIGZyYW1lX2RpZyAtMQogICAgYXBwX2dsb2JhbF9wdXQKICAgIHJldHN1YgoKCi8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo6R2xvYmFsU3RhdGVDb250cmFjdC5zZXRfYXJjNF91aW50bjY0KHZhbHVlOiBieXRlcykgLT4gdm9pZDoKc2V0X2FyYzRfdWludG42NDoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo3MTktNzIwCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gc2V0X2FyYzRfdWludG42NCh2YWx1ZTogVWludE42NCkgewogICAgcHJvdG8gMSAwCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NjAyCiAgICAvLyBhcmM0VWludE42NCA9IEdsb2JhbFN0YXRlKHsgaW5pdGlhbFZhbHVlOiBuZXcgVWludE42NCgxMzM3KSwga2V5OiAnZXhwbGljaXRfa2V5X2FyYzRfdWludG42NCcgfSkKICAgIGJ5dGVjIDggLy8gImV4cGxpY2l0X2tleV9hcmM0X3VpbnRuNjQiCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NzIxCiAgICAvLyB0aGlzLmFyYzRVaW50TjY0LnZhbHVlID0gdmFsdWUKICAgIGZyYW1lX2RpZyAtMQogICAgYXBwX2dsb2JhbF9wdXQKICAgIHJldHN1YgoKCi8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo6R2xvYmFsU3RhdGVDb250cmFjdC5zZXRfYXJjNF9zdHIodmFsdWU6IGJ5dGVzKSAtPiB2b2lkOgpzZXRfYXJjNF9zdHI6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NzI0LTcyNQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIHNldF9hcmM0X3N0cih2YWx1ZTogU3RyKSB7CiAgICBwcm90byAxIDAKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo2MDMKICAgIC8vIGFyYzRTdHIgPSBHbG9iYWxTdGF0ZSh7IGluaXRpYWxWYWx1ZTogbmV3IFN0cignSGVsbG8nKSwga2V5OiAnZXhwbGljaXRfa2V5X2FyYzRfc3RyJyB9KQogICAgYnl0ZWMgOSAvLyAiZXhwbGljaXRfa2V5X2FyYzRfc3RyIgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjcyNgogICAgLy8gdGhpcy5hcmM0U3RyLnZhbHVlID0gdmFsdWUKICAgIGZyYW1lX2RpZyAtMQogICAgYXBwX2dsb2JhbF9wdXQKICAgIHJldHN1YgoKCi8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo6R2xvYmFsU3RhdGVDb250cmFjdC5zZXRfYXJjNF9ieXRlKHZhbHVlOiBieXRlcykgLT4gdm9pZDoKc2V0X2FyYzRfYnl0ZToKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo3MjktNzMwCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gc2V0X2FyYzRfYnl0ZSh2YWx1ZTogQnl0ZSkgewogICAgcHJvdG8gMSAwCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NjA0CiAgICAvLyBhcmM0Qnl0ZSA9IEdsb2JhbFN0YXRlKHsgaW5pdGlhbFZhbHVlOiBuZXcgQnl0ZSgwKSwga2V5OiAnZXhwbGljaXRfa2V5X2FyYzRfYnl0ZScgfSkKICAgIGJ5dGVjIDEwIC8vICJleHBsaWNpdF9rZXlfYXJjNF9ieXRlIgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjczMQogICAgLy8gdGhpcy5hcmM0Qnl0ZS52YWx1ZSA9IHZhbHVlCiAgICBmcmFtZV9kaWcgLTEKICAgIGFwcF9nbG9iYWxfcHV0CiAgICByZXRzdWIKCgovLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6Okdsb2JhbFN0YXRlQ29udHJhY3Quc2V0X2FyYzRfYm9vbCh2YWx1ZTogYnl0ZXMpIC0+IHZvaWQ6CnNldF9hcmM0X2Jvb2w6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NzM0LTczNQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIHNldF9hcmM0X2Jvb2wodmFsdWU6IEJvb2wpIHsKICAgIHByb3RvIDEgMAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjYwNQogICAgLy8gYXJjNEJvb2wgPSBHbG9iYWxTdGF0ZSh7IGluaXRpYWxWYWx1ZTogbmV3IEJvb2wodHJ1ZSksIGtleTogJ2V4cGxpY2l0X2tleV9hcmM0X2Jvb2wnIH0pCiAgICBieXRlYyAxMSAvLyAiZXhwbGljaXRfa2V5X2FyYzRfYm9vbCIKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo3MzYKICAgIC8vIHRoaXMuYXJjNEJvb2wudmFsdWUgPSB2YWx1ZQogICAgZnJhbWVfZGlnIC0xCiAgICBhcHBfZ2xvYmFsX3B1dAogICAgcmV0c3ViCgoKLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjpHbG9iYWxTdGF0ZUNvbnRyYWN0LnNldF9hcmM0X2FkZHJlc3ModmFsdWU6IGJ5dGVzKSAtPiB2b2lkOgpzZXRfYXJjNF9hZGRyZXNzOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjczOS03NDAKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBzZXRfYXJjNF9hZGRyZXNzKHZhbHVlOiBBZGRyZXNzKSB7CiAgICBwcm90byAxIDAKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo2MDYKICAgIC8vIGFyYzRBZGRyZXNzID0gR2xvYmFsU3RhdGUoeyBpbml0aWFsVmFsdWU6IG5ldyBBZGRyZXNzKEdsb2JhbC5jcmVhdG9yQWRkcmVzcyksIGtleTogJ2V4cGxpY2l0X2tleV9hcmM0X2FkZHJlc3MnIH0pCiAgICBieXRlYyAxMiAvLyAiZXhwbGljaXRfa2V5X2FyYzRfYWRkcmVzcyIKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo3NDEKICAgIC8vIHRoaXMuYXJjNEFkZHJlc3MudmFsdWUgPSB2YWx1ZQogICAgZnJhbWVfZGlnIC0xCiAgICBhcHBfZ2xvYmFsX3B1dAogICAgcmV0c3ViCgoKLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjpHbG9iYWxTdGF0ZUNvbnRyYWN0LnNldF9hcmM0X3VpbnRuMTI4KHZhbHVlOiBieXRlcykgLT4gdm9pZDoKc2V0X2FyYzRfdWludG4xMjg6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NzQ0LTc0NQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIHNldF9hcmM0X3VpbnRuMTI4KHZhbHVlOiBVaW50TjEyOCkgewogICAgcHJvdG8gMSAwCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NjA3CiAgICAvLyBhcmM0VWludE4xMjggPSBHbG9iYWxTdGF0ZSh7IGluaXRpYWxWYWx1ZTogbmV3IFVpbnROMTI4KDJuICoqIDEwMG4pLCBrZXk6ICdleHBsaWNpdF9rZXlfYXJjNF91aW50bjEyOCcgfSkKICAgIGJ5dGVjIDEzIC8vICJleHBsaWNpdF9rZXlfYXJjNF91aW50bjEyOCIKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo3NDYKICAgIC8vIHRoaXMuYXJjNFVpbnROMTI4LnZhbHVlID0gdmFsdWUKICAgIGZyYW1lX2RpZyAtMQogICAgYXBwX2dsb2JhbF9wdXQKICAgIHJldHN1YgoKCi8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo6R2xvYmFsU3RhdGVDb250cmFjdC5zZXRfYXJjNF9keW5hbWljX2J5dGVzKHZhbHVlOiBieXRlcykgLT4gdm9pZDoKc2V0X2FyYzRfZHluYW1pY19ieXRlczoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo3NDktNzUwCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gc2V0X2FyYzRfZHluYW1pY19ieXRlcyh2YWx1ZTogRHluYW1pY0J5dGVzKSB7CiAgICBwcm90byAxIDAKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo2MDgKICAgIC8vIGFyYzREeW5hbWljQnl0ZXMgPSBHbG9iYWxTdGF0ZSh7IGluaXRpYWxWYWx1ZTogbmV3IER5bmFtaWNCeXRlcygnZHluYW1pYyBieXRlcycpLCBrZXk6ICdleHBsaWNpdF9rZXlfYXJjNF9keW5hbWljX2J5dGVzJyB9KQogICAgYnl0ZWMgMTQgLy8gImV4cGxpY2l0X2tleV9hcmM0X2R5bmFtaWNfYnl0ZXMiCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NzUxCiAgICAvLyB0aGlzLmFyYzREeW5hbWljQnl0ZXMudmFsdWUgPSB2YWx1ZQogICAgZnJhbWVfZGlnIC0xCiAgICBhcHBfZ2xvYmFsX3B1dAogICAgcmV0c3ViCg==", - "clear": "I3ByYWdtYSB2ZXJzaW9uIDEwCgp0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6Okdsb2JhbFN0YXRlQ29udHJhY3QuY2xlYXJTdGF0ZVByb2dyYW06CiAgICBwdXNoaW50IDEgLy8gMQogICAgcmV0dXJuCg==" - }, - "state": { - "global": { - "num_byte_slices": 14, - "num_uints": 0 - }, - "local": { - "num_byte_slices": 0, - "num_uints": 0 - } - }, - "schema": { - "global": { - "declared": { - "arc4Address": { - "type": "bytes", - "key": "explicit_key_arc4_address" - }, - "arc4Bool": { - "type": "bytes", - "key": "explicit_key_arc4_bool" - }, - "arc4Byte": { - "type": "bytes", - "key": "explicit_key_arc4_byte" - }, - "arc4DynamicBytes": { - "type": "bytes", - "key": "explicit_key_arc4_dynamic_bytes" - }, - "arc4Str": { - "type": "bytes", - "key": "explicit_key_arc4_str" - }, - "arc4UintN128": { - "type": "bytes", - "key": "explicit_key_arc4_uintn128" - }, - "arc4UintN64": { - "type": "bytes", - "key": "explicit_key_arc4_uintn64" - }, - "implicitKeyArc4Address": { - "type": "bytes", - "key": "implicitKeyArc4Address" - }, - "implicitKeyArc4Bool": { - "type": "bytes", - "key": "implicitKeyArc4Bool" - }, - "implicitKeyArc4Byte": { - "type": "bytes", - "key": "implicitKeyArc4Byte" - }, - "implicitKeyArc4DynamicBytes": { - "type": "bytes", - "key": "implicitKeyArc4DynamicBytes" - }, - "implicitKeyArc4Str": { - "type": "bytes", - "key": "implicitKeyArc4Str" - }, - "implicitKeyArc4UintN128": { - "type": "bytes", - "key": "implicitKeyArc4UintN128" - }, - "implicitKeyArc4UintN64": { - "type": "bytes", - "key": "implicitKeyArc4UintN64" - } - }, - "reserved": {} - }, - "local": { - "declared": {}, - "reserved": {} - } - }, - "contract": { - "name": "GlobalStateContract", - "methods": [ - { - "name": "get_implicit_key_arc4_uintn64", - "args": [], - "readonly": false, - "returns": { - "type": "uint64" - } - }, - { - "name": "get_implicit_key_arc4_str", - "args": [], - "readonly": false, - "returns": { - "type": "string" - } - }, - { - "name": "get_implicit_key_arc4_byte", - "args": [], - "readonly": false, - "returns": { - "type": "byte" - } - }, - { - "name": "get_implicit_key_arc4_bool", - "args": [], - "readonly": false, - "returns": { - "type": "bool" - } - }, - { - "name": "get_implicit_key_arc4_address", - "args": [], - "readonly": false, - "returns": { - "type": "address" - } - }, - { - "name": "get_implicit_key_arc4_uintn128", - "args": [], - "readonly": false, - "returns": { - "type": "uint128" - } - }, - { - "name": "get_implicit_key_arc4_dynamic_bytes", - "args": [], - "readonly": false, - "returns": { - "type": "byte[]" - } - }, - { - "name": "get_arc4_uintn64", - "args": [], - "readonly": false, - "returns": { - "type": "uint64" - } - }, - { - "name": "get_arc4_str", - "args": [], - "readonly": false, - "returns": { - "type": "string" - } - }, - { - "name": "get_arc4_byte", - "args": [], - "readonly": false, - "returns": { - "type": "byte" - } - }, - { - "name": "get_arc4_bool", - "args": [], - "readonly": false, - "returns": { - "type": "bool" - } - }, - { - "name": "get_arc4_address", - "args": [], - "readonly": false, - "returns": { - "type": "address" - } - }, - { - "name": "get_arc4_uintn128", - "args": [], - "readonly": false, - "returns": { - "type": "uint128" - } - }, - { - "name": "get_arc4_dynamic_bytes", - "args": [], - "readonly": false, - "returns": { - "type": "byte[]" - } - }, - { - "name": "set_implicit_key_arc4_uintn64", - "args": [ - { - "type": "uint64", - "name": "value" - } - ], - "readonly": false, - "returns": { - "type": "void" - } - }, - { - "name": "set_implicit_key_arc4_str", - "args": [ - { - "type": "string", - "name": "value" - } - ], - "readonly": false, - "returns": { - "type": "void" - } - }, - { - "name": "set_implicit_key_arc4_byte", - "args": [ - { - "type": "byte", - "name": "value" - } - ], - "readonly": false, - "returns": { - "type": "void" - } - }, - { - "name": "set_implicit_key_arc4_bool", - "args": [ - { - "type": "bool", - "name": "value" - } - ], - "readonly": false, - "returns": { - "type": "void" - } - }, - { - "name": "set_implicit_key_arc4_address", - "args": [ - { - "type": "address", - "name": "value" - } - ], - "readonly": false, - "returns": { - "type": "void" - } - }, - { - "name": "set_implicit_key_arc4_uintn128", - "args": [ - { - "type": "uint128", - "name": "value" - } - ], - "readonly": false, - "returns": { - "type": "void" - } - }, - { - "name": "set_implicit_key_arc4_dynamic_bytes", - "args": [ - { - "type": "byte[]", - "name": "value" - } - ], - "readonly": false, - "returns": { - "type": "void" - } - }, - { - "name": "set_arc4_uintn64", - "args": [ - { - "type": "uint64", - "name": "value" - } - ], - "readonly": false, - "returns": { - "type": "void" - } - }, - { - "name": "set_arc4_str", - "args": [ - { - "type": "string", - "name": "value" - } - ], - "readonly": false, - "returns": { - "type": "void" - } - }, - { - "name": "set_arc4_byte", - "args": [ - { - "type": "byte", - "name": "value" - } - ], - "readonly": false, - "returns": { - "type": "void" - } - }, - { - "name": "set_arc4_bool", - "args": [ - { - "type": "bool", - "name": "value" - } - ], - "readonly": false, - "returns": { - "type": "void" - } - }, - { - "name": "set_arc4_address", - "args": [ - { - "type": "address", - "name": "value" - } - ], - "readonly": false, - "returns": { - "type": "void" - } - }, - { - "name": "set_arc4_uintn128", - "args": [ - { - "type": "uint128", - "name": "value" - } - ], - "readonly": false, - "returns": { - "type": "void" - } - }, - { - "name": "set_arc4_dynamic_bytes", - "args": [ - { - "type": "byte[]", - "name": "value" - } - ], - "readonly": false, - "returns": { - "type": "void" - } - } - ], - "networks": {} - }, - "bare_call_config": { - "no_op": "CREATE" - } -} \ No newline at end of file diff --git a/tests/artifacts/state-ops/data/GlobalStateContract.arc56.json b/tests/artifacts/state-ops/data/GlobalStateContract.arc56.json deleted file mode 100644 index 261d8c7..0000000 --- a/tests/artifacts/state-ops/data/GlobalStateContract.arc56.json +++ /dev/null @@ -1,736 +0,0 @@ -{ - "name": "GlobalStateContract", - "structs": {}, - "methods": [ - { - "name": "get_implicit_key_arc4_uintn64", - "args": [], - "returns": { - "type": "uint64" - }, - "actions": { - "create": [], - "call": [ - "NoOp" - ] - }, - "readonly": false, - "events": [], - "recommendations": {} - }, - { - "name": "get_implicit_key_arc4_str", - "args": [], - "returns": { - "type": "string" - }, - "actions": { - "create": [], - "call": [ - "NoOp" - ] - }, - "readonly": false, - "events": [], - "recommendations": {} - }, - { - "name": "get_implicit_key_arc4_byte", - "args": [], - "returns": { - "type": "byte" - }, - "actions": { - "create": [], - "call": [ - "NoOp" - ] - }, - "readonly": false, - "events": [], - "recommendations": {} - }, - { - "name": "get_implicit_key_arc4_bool", - "args": [], - "returns": { - "type": "bool" - }, - "actions": { - "create": [], - "call": [ - "NoOp" - ] - }, - "readonly": false, - "events": [], - "recommendations": {} - }, - { - "name": "get_implicit_key_arc4_address", - "args": [], - "returns": { - "type": "address" - }, - "actions": { - "create": [], - "call": [ - "NoOp" - ] - }, - "readonly": false, - "events": [], - "recommendations": {} - }, - { - "name": "get_implicit_key_arc4_uintn128", - "args": [], - "returns": { - "type": "uint128" - }, - "actions": { - "create": [], - "call": [ - "NoOp" - ] - }, - "readonly": false, - "events": [], - "recommendations": {} - }, - { - "name": "get_implicit_key_arc4_dynamic_bytes", - "args": [], - "returns": { - "type": "byte[]" - }, - "actions": { - "create": [], - "call": [ - "NoOp" - ] - }, - "readonly": false, - "events": [], - "recommendations": {} - }, - { - "name": "get_arc4_uintn64", - "args": [], - "returns": { - "type": "uint64" - }, - "actions": { - "create": [], - "call": [ - "NoOp" - ] - }, - "readonly": false, - "events": [], - "recommendations": {} - }, - { - "name": "get_arc4_str", - "args": [], - "returns": { - "type": "string" - }, - "actions": { - "create": [], - "call": [ - "NoOp" - ] - }, - "readonly": false, - "events": [], - "recommendations": {} - }, - { - "name": "get_arc4_byte", - "args": [], - "returns": { - "type": "byte" - }, - "actions": { - "create": [], - "call": [ - "NoOp" - ] - }, - "readonly": false, - "events": [], - "recommendations": {} - }, - { - "name": "get_arc4_bool", - "args": [], - "returns": { - "type": "bool" - }, - "actions": { - "create": [], - "call": [ - "NoOp" - ] - }, - "readonly": false, - "events": [], - "recommendations": {} - }, - { - "name": "get_arc4_address", - "args": [], - "returns": { - "type": "address" - }, - "actions": { - "create": [], - "call": [ - "NoOp" - ] - }, - "readonly": false, - "events": [], - "recommendations": {} - }, - { - "name": "get_arc4_uintn128", - "args": [], - "returns": { - "type": "uint128" - }, - "actions": { - "create": [], - "call": [ - "NoOp" - ] - }, - "readonly": false, - "events": [], - "recommendations": {} - }, - { - "name": "get_arc4_dynamic_bytes", - "args": [], - "returns": { - "type": "byte[]" - }, - "actions": { - "create": [], - "call": [ - "NoOp" - ] - }, - "readonly": false, - "events": [], - "recommendations": {} - }, - { - "name": "set_implicit_key_arc4_uintn64", - "args": [ - { - "type": "uint64", - "name": "value" - } - ], - "returns": { - "type": "void" - }, - "actions": { - "create": [], - "call": [ - "NoOp" - ] - }, - "readonly": false, - "events": [], - "recommendations": {} - }, - { - "name": "set_implicit_key_arc4_str", - "args": [ - { - "type": "string", - "name": "value" - } - ], - "returns": { - "type": "void" - }, - "actions": { - "create": [], - "call": [ - "NoOp" - ] - }, - "readonly": false, - "events": [], - "recommendations": {} - }, - { - "name": "set_implicit_key_arc4_byte", - "args": [ - { - "type": "byte", - "name": "value" - } - ], - "returns": { - "type": "void" - }, - "actions": { - "create": [], - "call": [ - "NoOp" - ] - }, - "readonly": false, - "events": [], - "recommendations": {} - }, - { - "name": "set_implicit_key_arc4_bool", - "args": [ - { - "type": "bool", - "name": "value" - } - ], - "returns": { - "type": "void" - }, - "actions": { - "create": [], - "call": [ - "NoOp" - ] - }, - "readonly": false, - "events": [], - "recommendations": {} - }, - { - "name": "set_implicit_key_arc4_address", - "args": [ - { - "type": "address", - "name": "value" - } - ], - "returns": { - "type": "void" - }, - "actions": { - "create": [], - "call": [ - "NoOp" - ] - }, - "readonly": false, - "events": [], - "recommendations": {} - }, - { - "name": "set_implicit_key_arc4_uintn128", - "args": [ - { - "type": "uint128", - "name": "value" - } - ], - "returns": { - "type": "void" - }, - "actions": { - "create": [], - "call": [ - "NoOp" - ] - }, - "readonly": false, - "events": [], - "recommendations": {} - }, - { - "name": "set_implicit_key_arc4_dynamic_bytes", - "args": [ - { - "type": "byte[]", - "name": "value" - } - ], - "returns": { - "type": "void" - }, - "actions": { - "create": [], - "call": [ - "NoOp" - ] - }, - "readonly": false, - "events": [], - "recommendations": {} - }, - { - "name": "set_arc4_uintn64", - "args": [ - { - "type": "uint64", - "name": "value" - } - ], - "returns": { - "type": "void" - }, - "actions": { - "create": [], - "call": [ - "NoOp" - ] - }, - "readonly": false, - "events": [], - "recommendations": {} - }, - { - "name": "set_arc4_str", - "args": [ - { - "type": "string", - "name": "value" - } - ], - "returns": { - "type": "void" - }, - "actions": { - "create": [], - "call": [ - "NoOp" - ] - }, - "readonly": false, - "events": [], - "recommendations": {} - }, - { - "name": "set_arc4_byte", - "args": [ - { - "type": "byte", - "name": "value" - } - ], - "returns": { - "type": "void" - }, - "actions": { - "create": [], - "call": [ - "NoOp" - ] - }, - "readonly": false, - "events": [], - "recommendations": {} - }, - { - "name": "set_arc4_bool", - "args": [ - { - "type": "bool", - "name": "value" - } - ], - "returns": { - "type": "void" - }, - "actions": { - "create": [], - "call": [ - "NoOp" - ] - }, - "readonly": false, - "events": [], - "recommendations": {} - }, - { - "name": "set_arc4_address", - "args": [ - { - "type": "address", - "name": "value" - } - ], - "returns": { - "type": "void" - }, - "actions": { - "create": [], - "call": [ - "NoOp" - ] - }, - "readonly": false, - "events": [], - "recommendations": {} - }, - { - "name": "set_arc4_uintn128", - "args": [ - { - "type": "uint128", - "name": "value" - } - ], - "returns": { - "type": "void" - }, - "actions": { - "create": [], - "call": [ - "NoOp" - ] - }, - "readonly": false, - "events": [], - "recommendations": {} - }, - { - "name": "set_arc4_dynamic_bytes", - "args": [ - { - "type": "byte[]", - "name": "value" - } - ], - "returns": { - "type": "void" - }, - "actions": { - "create": [], - "call": [ - "NoOp" - ] - }, - "readonly": false, - "events": [], - "recommendations": {} - } - ], - "arcs": [ - 22, - 28 - ], - "networks": {}, - "state": { - "schema": { - "global": { - "ints": 0, - "bytes": 14 - }, - "local": { - "ints": 0, - "bytes": 0 - } - }, - "keys": { - "global": { - "implicitKeyArc4UintN64": { - "keyType": "AVMString", - "valueType": "uint64", - "key": "aW1wbGljaXRLZXlBcmM0VWludE42NA==" - }, - "implicitKeyArc4Str": { - "keyType": "AVMString", - "valueType": "string", - "key": "aW1wbGljaXRLZXlBcmM0U3Ry" - }, - "implicitKeyArc4Byte": { - "keyType": "AVMString", - "valueType": "byte", - "key": "aW1wbGljaXRLZXlBcmM0Qnl0ZQ==" - }, - "implicitKeyArc4Bool": { - "keyType": "AVMString", - "valueType": "bool", - "key": "aW1wbGljaXRLZXlBcmM0Qm9vbA==" - }, - "implicitKeyArc4Address": { - "keyType": "AVMString", - "valueType": "address", - "key": "aW1wbGljaXRLZXlBcmM0QWRkcmVzcw==" - }, - "implicitKeyArc4UintN128": { - "keyType": "AVMString", - "valueType": "uint128", - "key": "aW1wbGljaXRLZXlBcmM0VWludE4xMjg=" - }, - "implicitKeyArc4DynamicBytes": { - "keyType": "AVMString", - "valueType": "byte[]", - "key": "aW1wbGljaXRLZXlBcmM0RHluYW1pY0J5dGVz" - }, - "arc4UintN64": { - "keyType": "AVMString", - "valueType": "uint64", - "key": "ZXhwbGljaXRfa2V5X2FyYzRfdWludG42NA==" - }, - "arc4Str": { - "keyType": "AVMString", - "valueType": "string", - "key": "ZXhwbGljaXRfa2V5X2FyYzRfc3Ry" - }, - "arc4Byte": { - "keyType": "AVMString", - "valueType": "byte", - "key": "ZXhwbGljaXRfa2V5X2FyYzRfYnl0ZQ==" - }, - "arc4Bool": { - "keyType": "AVMString", - "valueType": "bool", - "key": "ZXhwbGljaXRfa2V5X2FyYzRfYm9vbA==" - }, - "arc4Address": { - "keyType": "AVMString", - "valueType": "address", - "key": "ZXhwbGljaXRfa2V5X2FyYzRfYWRkcmVzcw==" - }, - "arc4UintN128": { - "keyType": "AVMString", - "valueType": "uint128", - "key": "ZXhwbGljaXRfa2V5X2FyYzRfdWludG4xMjg=" - }, - "arc4DynamicBytes": { - "keyType": "AVMString", - "valueType": "byte[]", - "key": "ZXhwbGljaXRfa2V5X2FyYzRfZHluYW1pY19ieXRlcw==" - } - }, - "local": {}, - "box": {} - }, - "maps": { - "global": {}, - "local": {}, - "box": {} - } - }, - "bareActions": { - "create": [ - "NoOp" - ], - "call": [] - }, - "sourceInfo": { - "approval": { - "sourceInfo": [ - { - "pc": [ - 701, - 717, - 733, - 749, - 765, - 781, - 797, - 813, - 829, - 845, - 861, - 877, - 893, - 909, - 925, - 940, - 955, - 970, - 985, - 1000, - 1015, - 1030, - 1045, - 1060, - 1075, - 1090, - 1105, - 1120 - ], - "errorMessage": "OnCompletion is not NoOp" - }, - { - "pc": [ - 1140 - ], - "errorMessage": "can only call when creating" - }, - { - "pc": [ - 704, - 720, - 736, - 752, - 768, - 784, - 800, - 816, - 832, - 848, - 864, - 880, - 896, - 912, - 928, - 943, - 958, - 973, - 988, - 1003, - 1018, - 1033, - 1048, - 1063, - 1078, - 1093, - 1108, - 1123 - ], - "errorMessage": "can only call when not creating" - }, - { - "pc": [ - 1151, - 1159, - 1167, - 1176, - 1185, - 1194, - 1203, - 1212, - 1221, - 1230, - 1239, - 1248, - 1257, - 1266 - ], - "errorMessage": "check GlobalState exists" - } - ], - "pcOffsetMethod": "none" - }, - "clear": { - "sourceInfo": [], - "pcOffsetMethod": "none" - } - }, - "source": { - "approval": "I3ByYWdtYSB2ZXJzaW9uIDEwCgp0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6Okdsb2JhbFN0YXRlQ29udHJhY3QuYXBwcm92YWxQcm9ncmFtOgogICAgaW50Y2Jsb2NrIDEgMAogICAgYnl0ZWNibG9jayAweDE1MWY3Yzc1ICJpbXBsaWNpdEtleUFyYzRVaW50TjY0IiAiaW1wbGljaXRLZXlBcmM0U3RyIiAiaW1wbGljaXRLZXlBcmM0Qnl0ZSIgImltcGxpY2l0S2V5QXJjNEJvb2wiICJpbXBsaWNpdEtleUFyYzRBZGRyZXNzIiAiaW1wbGljaXRLZXlBcmM0VWludE4xMjgiICJpbXBsaWNpdEtleUFyYzREeW5hbWljQnl0ZXMiICJleHBsaWNpdF9rZXlfYXJjNF91aW50bjY0IiAiZXhwbGljaXRfa2V5X2FyYzRfc3RyIiAiZXhwbGljaXRfa2V5X2FyYzRfYnl0ZSIgImV4cGxpY2l0X2tleV9hcmM0X2Jvb2wiICJleHBsaWNpdF9rZXlfYXJjNF9hZGRyZXNzIiAiZXhwbGljaXRfa2V5X2FyYzRfdWludG4xMjgiICJleHBsaWNpdF9rZXlfYXJjNF9keW5hbWljX2J5dGVzIiAweDAwMDAwMDAwMDAwMDA1MzkgMHgwMDA1NDg2NTZjNmM2ZiAweDAwMDAwMDEwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwIDB4MDAwZDY0Nzk2ZTYxNmQ2OTYzMjA2Mjc5NzQ2NTczCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYm56IG1haW5fYWZ0ZXJfaWZfZWxzZUAyCiAgICBjYWxsc3ViIGNvbnN0cnVjdG9yCgptYWluX2FmdGVyX2lmX2Vsc2VAMjoKICAgIGNhbGxzdWIgX19wdXlhX2FyYzRfcm91dGVyX18KICAgIHJldHVybgoKCi8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo6R2xvYmFsU3RhdGVDb250cmFjdC5jb25zdHJ1Y3RvcigpIC0+IHZvaWQ6CmNvbnN0cnVjdG9yOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjU5MQogICAgLy8gZXhwb3J0IGNsYXNzIEdsb2JhbFN0YXRlQ29udHJhY3QgZXh0ZW5kcyBhcmM0LkNvbnRyYWN0IHsKICAgIHByb3RvIDAgMAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjU5MwogICAgLy8gaW1wbGljaXRLZXlBcmM0VWludE42NCA9IEdsb2JhbFN0YXRlKHsgaW5pdGlhbFZhbHVlOiBuZXcgVWludE42NCgxMzM3KSB9KQogICAgYnl0ZWNfMSAvLyAiaW1wbGljaXRLZXlBcmM0VWludE42NCIKICAgIGJ5dGVjIDE1IC8vIDB4MDAwMDAwMDAwMDAwMDUzOQogICAgYXBwX2dsb2JhbF9wdXQKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo1OTQKICAgIC8vIGltcGxpY2l0S2V5QXJjNFN0ciA9IEdsb2JhbFN0YXRlKHsgaW5pdGlhbFZhbHVlOiBuZXcgU3RyKCdIZWxsbycpIH0pCiAgICBieXRlY18yIC8vICJpbXBsaWNpdEtleUFyYzRTdHIiCiAgICBieXRlYyAxNiAvLyAweDAwMDU0ODY1NmM2YzZmCiAgICBhcHBfZ2xvYmFsX3B1dAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjU5NQogICAgLy8gaW1wbGljaXRLZXlBcmM0Qnl0ZSA9IEdsb2JhbFN0YXRlKHsgaW5pdGlhbFZhbHVlOiBuZXcgQnl0ZSgwKSB9KQogICAgYnl0ZWNfMyAvLyAiaW1wbGljaXRLZXlBcmM0Qnl0ZSIKICAgIHB1c2hieXRlcyAweDAwCiAgICBhcHBfZ2xvYmFsX3B1dAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjU5NgogICAgLy8gaW1wbGljaXRLZXlBcmM0Qm9vbCA9IEdsb2JhbFN0YXRlKHsgaW5pdGlhbFZhbHVlOiBuZXcgQm9vbCh0cnVlKSB9KQogICAgYnl0ZWMgNCAvLyAiaW1wbGljaXRLZXlBcmM0Qm9vbCIKICAgIHB1c2hieXRlcyAweDgwCiAgICBhcHBfZ2xvYmFsX3B1dAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjU5NwogICAgLy8gaW1wbGljaXRLZXlBcmM0QWRkcmVzcyA9IEdsb2JhbFN0YXRlKHsgaW5pdGlhbFZhbHVlOiBuZXcgQWRkcmVzcyhHbG9iYWwuY3JlYXRvckFkZHJlc3MpIH0pCiAgICBieXRlYyA1IC8vICJpbXBsaWNpdEtleUFyYzRBZGRyZXNzIgogICAgZ2xvYmFsIENyZWF0b3JBZGRyZXNzCiAgICBhcHBfZ2xvYmFsX3B1dAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjU5OAogICAgLy8gaW1wbGljaXRLZXlBcmM0VWludE4xMjggPSBHbG9iYWxTdGF0ZSh7IGluaXRpYWxWYWx1ZTogbmV3IFVpbnROMTI4KDJuICoqIDEwMG4pIH0pCiAgICBieXRlYyA2IC8vICJpbXBsaWNpdEtleUFyYzRVaW50TjEyOCIKICAgIGJ5dGVjIDE3IC8vIDB4MDAwMDAwMTAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAKICAgIGFwcF9nbG9iYWxfcHV0CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NTk5CiAgICAvLyBpbXBsaWNpdEtleUFyYzREeW5hbWljQnl0ZXMgPSBHbG9iYWxTdGF0ZSh7IGluaXRpYWxWYWx1ZTogbmV3IER5bmFtaWNCeXRlcygnZHluYW1pYyBieXRlcycpIH0pCiAgICBieXRlYyA3IC8vICJpbXBsaWNpdEtleUFyYzREeW5hbWljQnl0ZXMiCiAgICBieXRlYyAxOCAvLyAweDAwMGQ2NDc5NmU2MTZkNjk2MzIwNjI3OTc0NjU3MwogICAgYXBwX2dsb2JhbF9wdXQKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo2MDIKICAgIC8vIGFyYzRVaW50TjY0ID0gR2xvYmFsU3RhdGUoeyBpbml0aWFsVmFsdWU6IG5ldyBVaW50TjY0KDEzMzcpLCBrZXk6ICdleHBsaWNpdF9rZXlfYXJjNF91aW50bjY0JyB9KQogICAgYnl0ZWMgOCAvLyAiZXhwbGljaXRfa2V5X2FyYzRfdWludG42NCIKICAgIGJ5dGVjIDE1IC8vIDB4MDAwMDAwMDAwMDAwMDUzOQogICAgYXBwX2dsb2JhbF9wdXQKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo2MDMKICAgIC8vIGFyYzRTdHIgPSBHbG9iYWxTdGF0ZSh7IGluaXRpYWxWYWx1ZTogbmV3IFN0cignSGVsbG8nKSwga2V5OiAnZXhwbGljaXRfa2V5X2FyYzRfc3RyJyB9KQogICAgYnl0ZWMgOSAvLyAiZXhwbGljaXRfa2V5X2FyYzRfc3RyIgogICAgYnl0ZWMgMTYgLy8gMHgwMDA1NDg2NTZjNmM2ZgogICAgYXBwX2dsb2JhbF9wdXQKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo2MDQKICAgIC8vIGFyYzRCeXRlID0gR2xvYmFsU3RhdGUoeyBpbml0aWFsVmFsdWU6IG5ldyBCeXRlKDApLCBrZXk6ICdleHBsaWNpdF9rZXlfYXJjNF9ieXRlJyB9KQogICAgYnl0ZWMgMTAgLy8gImV4cGxpY2l0X2tleV9hcmM0X2J5dGUiCiAgICBwdXNoYnl0ZXMgMHgwMAogICAgYXBwX2dsb2JhbF9wdXQKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo2MDUKICAgIC8vIGFyYzRCb29sID0gR2xvYmFsU3RhdGUoeyBpbml0aWFsVmFsdWU6IG5ldyBCb29sKHRydWUpLCBrZXk6ICdleHBsaWNpdF9rZXlfYXJjNF9ib29sJyB9KQogICAgYnl0ZWMgMTEgLy8gImV4cGxpY2l0X2tleV9hcmM0X2Jvb2wiCiAgICBwdXNoYnl0ZXMgMHg4MAogICAgYXBwX2dsb2JhbF9wdXQKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo2MDYKICAgIC8vIGFyYzRBZGRyZXNzID0gR2xvYmFsU3RhdGUoeyBpbml0aWFsVmFsdWU6IG5ldyBBZGRyZXNzKEdsb2JhbC5jcmVhdG9yQWRkcmVzcyksIGtleTogJ2V4cGxpY2l0X2tleV9hcmM0X2FkZHJlc3MnIH0pCiAgICBieXRlYyAxMiAvLyAiZXhwbGljaXRfa2V5X2FyYzRfYWRkcmVzcyIKICAgIGdsb2JhbCBDcmVhdG9yQWRkcmVzcwogICAgYXBwX2dsb2JhbF9wdXQKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo2MDcKICAgIC8vIGFyYzRVaW50TjEyOCA9IEdsb2JhbFN0YXRlKHsgaW5pdGlhbFZhbHVlOiBuZXcgVWludE4xMjgoMm4gKiogMTAwbiksIGtleTogJ2V4cGxpY2l0X2tleV9hcmM0X3VpbnRuMTI4JyB9KQogICAgYnl0ZWMgMTMgLy8gImV4cGxpY2l0X2tleV9hcmM0X3VpbnRuMTI4IgogICAgYnl0ZWMgMTcgLy8gMHgwMDAwMDAxMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMAogICAgYXBwX2dsb2JhbF9wdXQKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo2MDgKICAgIC8vIGFyYzREeW5hbWljQnl0ZXMgPSBHbG9iYWxTdGF0ZSh7IGluaXRpYWxWYWx1ZTogbmV3IER5bmFtaWNCeXRlcygnZHluYW1pYyBieXRlcycpLCBrZXk6ICdleHBsaWNpdF9rZXlfYXJjNF9keW5hbWljX2J5dGVzJyB9KQogICAgYnl0ZWMgMTQgLy8gImV4cGxpY2l0X2tleV9hcmM0X2R5bmFtaWNfYnl0ZXMiCiAgICBieXRlYyAxOCAvLyAweDAwMGQ2NDc5NmU2MTZkNjk2MzIwNjI3OTc0NjU3MwogICAgYXBwX2dsb2JhbF9wdXQKICAgIHJldHN1YgoKCi8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo6R2xvYmFsU3RhdGVDb250cmFjdC5fX3B1eWFfYXJjNF9yb3V0ZXJfXygpIC0+IHVpbnQ2NDoKX19wdXlhX2FyYzRfcm91dGVyX186CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NTkxCiAgICAvLyBleHBvcnQgY2xhc3MgR2xvYmFsU3RhdGVDb250cmFjdCBleHRlbmRzIGFyYzQuQ29udHJhY3QgewogICAgcHJvdG8gMCAxCiAgICB0eG4gTnVtQXBwQXJncwogICAgYnogX19wdXlhX2FyYzRfcm91dGVyX19fYmFyZV9yb3V0aW5nQDMyCiAgICBwdXNoYnl0ZXNzIDB4OGFiN2Y4YmYgMHg4NmVjMjRmMyAweDY5MTI4ZTkwIDB4NjhkNTkwZTIgMHg0NGVmMDY4MSAweDVjMjFiZDYwIDB4YWFjOGVjYjEgMHhhMTUyODhjZSAweDVmMjNhY2ZkIDB4ZGVkNzUwMzMgMHg2NjI3OWU5MyAweDA5NmU5MjdiIDB4MTA2YmMwMGIgMHg2ZWEzZjk5NiAweDNkZjBhMmNkIDB4OGM0ZDhmODAgMHg1ZWMzMTE2ZCAweDIwZjU2ZWVlIDB4MWMxNDlhNDMgMHg4ZTZhMWRkZSAweDg3ZjA4NjliIDB4MDI2NDY5YTEgMHhmMDU0YWI3YiAweGQyZTY0NmVmIDB4ZTY3NGEyNzAgMHhhODdlNTQwZCAweDU4YTc0MDRhIDB4MjU3NzA4ZjcgLy8gbWV0aG9kICJnZXRfaW1wbGljaXRfa2V5X2FyYzRfdWludG42NCgpdWludDY0IiwgbWV0aG9kICJnZXRfaW1wbGljaXRfa2V5X2FyYzRfc3RyKClzdHJpbmciLCBtZXRob2QgImdldF9pbXBsaWNpdF9rZXlfYXJjNF9ieXRlKClieXRlIiwgbWV0aG9kICJnZXRfaW1wbGljaXRfa2V5X2FyYzRfYm9vbCgpYm9vbCIsIG1ldGhvZCAiZ2V0X2ltcGxpY2l0X2tleV9hcmM0X2FkZHJlc3MoKWFkZHJlc3MiLCBtZXRob2QgImdldF9pbXBsaWNpdF9rZXlfYXJjNF91aW50bjEyOCgpdWludDEyOCIsIG1ldGhvZCAiZ2V0X2ltcGxpY2l0X2tleV9hcmM0X2R5bmFtaWNfYnl0ZXMoKWJ5dGVbXSIsIG1ldGhvZCAiZ2V0X2FyYzRfdWludG42NCgpdWludDY0IiwgbWV0aG9kICJnZXRfYXJjNF9zdHIoKXN0cmluZyIsIG1ldGhvZCAiZ2V0X2FyYzRfYnl0ZSgpYnl0ZSIsIG1ldGhvZCAiZ2V0X2FyYzRfYm9vbCgpYm9vbCIsIG1ldGhvZCAiZ2V0X2FyYzRfYWRkcmVzcygpYWRkcmVzcyIsIG1ldGhvZCAiZ2V0X2FyYzRfdWludG4xMjgoKXVpbnQxMjgiLCBtZXRob2QgImdldF9hcmM0X2R5bmFtaWNfYnl0ZXMoKWJ5dGVbXSIsIG1ldGhvZCAic2V0X2ltcGxpY2l0X2tleV9hcmM0X3VpbnRuNjQodWludDY0KXZvaWQiLCBtZXRob2QgInNldF9pbXBsaWNpdF9rZXlfYXJjNF9zdHIoc3RyaW5nKXZvaWQiLCBtZXRob2QgInNldF9pbXBsaWNpdF9rZXlfYXJjNF9ieXRlKGJ5dGUpdm9pZCIsIG1ldGhvZCAic2V0X2ltcGxpY2l0X2tleV9hcmM0X2Jvb2woYm9vbCl2b2lkIiwgbWV0aG9kICJzZXRfaW1wbGljaXRfa2V5X2FyYzRfYWRkcmVzcyhhZGRyZXNzKXZvaWQiLCBtZXRob2QgInNldF9pbXBsaWNpdF9rZXlfYXJjNF91aW50bjEyOCh1aW50MTI4KXZvaWQiLCBtZXRob2QgInNldF9pbXBsaWNpdF9rZXlfYXJjNF9keW5hbWljX2J5dGVzKGJ5dGVbXSl2b2lkIiwgbWV0aG9kICJzZXRfYXJjNF91aW50bjY0KHVpbnQ2NCl2b2lkIiwgbWV0aG9kICJzZXRfYXJjNF9zdHIoc3RyaW5nKXZvaWQiLCBtZXRob2QgInNldF9hcmM0X2J5dGUoYnl0ZSl2b2lkIiwgbWV0aG9kICJzZXRfYXJjNF9ib29sKGJvb2wpdm9pZCIsIG1ldGhvZCAic2V0X2FyYzRfYWRkcmVzcyhhZGRyZXNzKXZvaWQiLCBtZXRob2QgInNldF9hcmM0X3VpbnRuMTI4KHVpbnQxMjgpdm9pZCIsIG1ldGhvZCAic2V0X2FyYzRfZHluYW1pY19ieXRlcyhieXRlW10pdm9pZCIKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDAKICAgIG1hdGNoIF9fcHV5YV9hcmM0X3JvdXRlcl9fX2dldF9pbXBsaWNpdF9rZXlfYXJjNF91aW50bjY0X3JvdXRlQDIgX19wdXlhX2FyYzRfcm91dGVyX19fZ2V0X2ltcGxpY2l0X2tleV9hcmM0X3N0cl9yb3V0ZUAzIF9fcHV5YV9hcmM0X3JvdXRlcl9fX2dldF9pbXBsaWNpdF9rZXlfYXJjNF9ieXRlX3JvdXRlQDQgX19wdXlhX2FyYzRfcm91dGVyX19fZ2V0X2ltcGxpY2l0X2tleV9hcmM0X2Jvb2xfcm91dGVANSBfX3B1eWFfYXJjNF9yb3V0ZXJfX19nZXRfaW1wbGljaXRfa2V5X2FyYzRfYWRkcmVzc19yb3V0ZUA2IF9fcHV5YV9hcmM0X3JvdXRlcl9fX2dldF9pbXBsaWNpdF9rZXlfYXJjNF91aW50bjEyOF9yb3V0ZUA3IF9fcHV5YV9hcmM0X3JvdXRlcl9fX2dldF9pbXBsaWNpdF9rZXlfYXJjNF9keW5hbWljX2J5dGVzX3JvdXRlQDggX19wdXlhX2FyYzRfcm91dGVyX19fZ2V0X2FyYzRfdWludG42NF9yb3V0ZUA5IF9fcHV5YV9hcmM0X3JvdXRlcl9fX2dldF9hcmM0X3N0cl9yb3V0ZUAxMCBfX3B1eWFfYXJjNF9yb3V0ZXJfX19nZXRfYXJjNF9ieXRlX3JvdXRlQDExIF9fcHV5YV9hcmM0X3JvdXRlcl9fX2dldF9hcmM0X2Jvb2xfcm91dGVAMTIgX19wdXlhX2FyYzRfcm91dGVyX19fZ2V0X2FyYzRfYWRkcmVzc19yb3V0ZUAxMyBfX3B1eWFfYXJjNF9yb3V0ZXJfX19nZXRfYXJjNF91aW50bjEyOF9yb3V0ZUAxNCBfX3B1eWFfYXJjNF9yb3V0ZXJfX19nZXRfYXJjNF9keW5hbWljX2J5dGVzX3JvdXRlQDE1IF9fcHV5YV9hcmM0X3JvdXRlcl9fX3NldF9pbXBsaWNpdF9rZXlfYXJjNF91aW50bjY0X3JvdXRlQDE2IF9fcHV5YV9hcmM0X3JvdXRlcl9fX3NldF9pbXBsaWNpdF9rZXlfYXJjNF9zdHJfcm91dGVAMTcgX19wdXlhX2FyYzRfcm91dGVyX19fc2V0X2ltcGxpY2l0X2tleV9hcmM0X2J5dGVfcm91dGVAMTggX19wdXlhX2FyYzRfcm91dGVyX19fc2V0X2ltcGxpY2l0X2tleV9hcmM0X2Jvb2xfcm91dGVAMTkgX19wdXlhX2FyYzRfcm91dGVyX19fc2V0X2ltcGxpY2l0X2tleV9hcmM0X2FkZHJlc3Nfcm91dGVAMjAgX19wdXlhX2FyYzRfcm91dGVyX19fc2V0X2ltcGxpY2l0X2tleV9hcmM0X3VpbnRuMTI4X3JvdXRlQDIxIF9fcHV5YV9hcmM0X3JvdXRlcl9fX3NldF9pbXBsaWNpdF9rZXlfYXJjNF9keW5hbWljX2J5dGVzX3JvdXRlQDIyIF9fcHV5YV9hcmM0X3JvdXRlcl9fX3NldF9hcmM0X3VpbnRuNjRfcm91dGVAMjMgX19wdXlhX2FyYzRfcm91dGVyX19fc2V0X2FyYzRfc3RyX3JvdXRlQDI0IF9fcHV5YV9hcmM0X3JvdXRlcl9fX3NldF9hcmM0X2J5dGVfcm91dGVAMjUgX19wdXlhX2FyYzRfcm91dGVyX19fc2V0X2FyYzRfYm9vbF9yb3V0ZUAyNiBfX3B1eWFfYXJjNF9yb3V0ZXJfX19zZXRfYXJjNF9hZGRyZXNzX3JvdXRlQDI3IF9fcHV5YV9hcmM0X3JvdXRlcl9fX3NldF9hcmM0X3VpbnRuMTI4X3JvdXRlQDI4IF9fcHV5YV9hcmM0X3JvdXRlcl9fX3NldF9hcmM0X2R5bmFtaWNfYnl0ZXNfcm91dGVAMjkKICAgIGludGNfMSAvLyAwCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX2dldF9pbXBsaWNpdF9rZXlfYXJjNF91aW50bjY0X3JvdXRlQDI6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NjExCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBub3QgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBjYW4gb25seSBjYWxsIHdoZW4gbm90IGNyZWF0aW5nCiAgICBjYWxsc3ViIGdldF9pbXBsaWNpdF9rZXlfYXJjNF91aW50bjY0CiAgICBieXRlY18wIC8vIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnRjXzAgLy8gMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX19nZXRfaW1wbGljaXRfa2V5X2FyYzRfc3RyX3JvdXRlQDM6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NjE2CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBub3QgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBjYW4gb25seSBjYWxsIHdoZW4gbm90IGNyZWF0aW5nCiAgICBjYWxsc3ViIGdldF9pbXBsaWNpdF9rZXlfYXJjNF9zdHIKICAgIGJ5dGVjXzAgLy8gMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludGNfMCAvLyAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX2dldF9pbXBsaWNpdF9rZXlfYXJjNF9ieXRlX3JvdXRlQDQ6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NjIxCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBub3QgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBjYW4gb25seSBjYWxsIHdoZW4gbm90IGNyZWF0aW5nCiAgICBjYWxsc3ViIGdldF9pbXBsaWNpdF9rZXlfYXJjNF9ieXRlCiAgICBieXRlY18wIC8vIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnRjXzAgLy8gMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX19nZXRfaW1wbGljaXRfa2V5X2FyYzRfYm9vbF9yb3V0ZUA1OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjYyNgogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgbm90IE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gY2FuIG9ubHkgY2FsbCB3aGVuIG5vdCBjcmVhdGluZwogICAgY2FsbHN1YiBnZXRfaW1wbGljaXRfa2V5X2FyYzRfYm9vbAogICAgYnl0ZWNfMCAvLyAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50Y18wIC8vIDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fZ2V0X2ltcGxpY2l0X2tleV9hcmM0X2FkZHJlc3Nfcm91dGVANjoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo2MzEKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIG5vdCBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGNhbiBvbmx5IGNhbGwgd2hlbiBub3QgY3JlYXRpbmcKICAgIGNhbGxzdWIgZ2V0X2ltcGxpY2l0X2tleV9hcmM0X2FkZHJlc3MKICAgIGJ5dGVjXzAgLy8gMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludGNfMCAvLyAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX2dldF9pbXBsaWNpdF9rZXlfYXJjNF91aW50bjEyOF9yb3V0ZUA3OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjYzNgogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgbm90IE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gY2FuIG9ubHkgY2FsbCB3aGVuIG5vdCBjcmVhdGluZwogICAgY2FsbHN1YiBnZXRfaW1wbGljaXRfa2V5X2FyYzRfdWludG4xMjgKICAgIGJ5dGVjXzAgLy8gMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludGNfMCAvLyAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX2dldF9pbXBsaWNpdF9rZXlfYXJjNF9keW5hbWljX2J5dGVzX3JvdXRlQDg6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NjQxCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBub3QgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBjYW4gb25seSBjYWxsIHdoZW4gbm90IGNyZWF0aW5nCiAgICBjYWxsc3ViIGdldF9pbXBsaWNpdF9rZXlfYXJjNF9keW5hbWljX2J5dGVzCiAgICBieXRlY18wIC8vIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnRjXzAgLy8gMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX19nZXRfYXJjNF91aW50bjY0X3JvdXRlQDk6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NjQ3CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBub3QgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBjYW4gb25seSBjYWxsIHdoZW4gbm90IGNyZWF0aW5nCiAgICBjYWxsc3ViIGdldF9hcmM0X3VpbnRuNjQKICAgIGJ5dGVjXzAgLy8gMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludGNfMCAvLyAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX2dldF9hcmM0X3N0cl9yb3V0ZUAxMDoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo2NTIKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIG5vdCBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGNhbiBvbmx5IGNhbGwgd2hlbiBub3QgY3JlYXRpbmcKICAgIGNhbGxzdWIgZ2V0X2FyYzRfc3RyCiAgICBieXRlY18wIC8vIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnRjXzAgLy8gMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX19nZXRfYXJjNF9ieXRlX3JvdXRlQDExOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjY1NwogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgbm90IE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gY2FuIG9ubHkgY2FsbCB3aGVuIG5vdCBjcmVhdGluZwogICAgY2FsbHN1YiBnZXRfYXJjNF9ieXRlCiAgICBieXRlY18wIC8vIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnRjXzAgLy8gMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX19nZXRfYXJjNF9ib29sX3JvdXRlQDEyOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjY2MgogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgbm90IE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gY2FuIG9ubHkgY2FsbCB3aGVuIG5vdCBjcmVhdGluZwogICAgY2FsbHN1YiBnZXRfYXJjNF9ib29sCiAgICBieXRlY18wIC8vIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnRjXzAgLy8gMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX19nZXRfYXJjNF9hZGRyZXNzX3JvdXRlQDEzOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjY2NwogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgbm90IE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gY2FuIG9ubHkgY2FsbCB3aGVuIG5vdCBjcmVhdGluZwogICAgY2FsbHN1YiBnZXRfYXJjNF9hZGRyZXNzCiAgICBieXRlY18wIC8vIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnRjXzAgLy8gMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX19nZXRfYXJjNF91aW50bjEyOF9yb3V0ZUAxNDoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo2NzIKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIG5vdCBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGNhbiBvbmx5IGNhbGwgd2hlbiBub3QgY3JlYXRpbmcKICAgIGNhbGxzdWIgZ2V0X2FyYzRfdWludG4xMjgKICAgIGJ5dGVjXzAgLy8gMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludGNfMCAvLyAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX2dldF9hcmM0X2R5bmFtaWNfYnl0ZXNfcm91dGVAMTU6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6Njc3CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBub3QgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBjYW4gb25seSBjYWxsIHdoZW4gbm90IGNyZWF0aW5nCiAgICBjYWxsc3ViIGdldF9hcmM0X2R5bmFtaWNfYnl0ZXMKICAgIGJ5dGVjXzAgLy8gMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludGNfMCAvLyAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX3NldF9pbXBsaWNpdF9rZXlfYXJjNF91aW50bjY0X3JvdXRlQDE2OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjY4MwogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgbm90IE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gY2FuIG9ubHkgY2FsbCB3aGVuIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjU5MQogICAgLy8gZXhwb3J0IGNsYXNzIEdsb2JhbFN0YXRlQ29udHJhY3QgZXh0ZW5kcyBhcmM0LkNvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo2ODMKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHNldF9pbXBsaWNpdF9rZXlfYXJjNF91aW50bjY0CiAgICBpbnRjXzAgLy8gMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX19zZXRfaW1wbGljaXRfa2V5X2FyYzRfc3RyX3JvdXRlQDE3OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjY4OAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgbm90IE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gY2FuIG9ubHkgY2FsbCB3aGVuIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjU5MQogICAgLy8gZXhwb3J0IGNsYXNzIEdsb2JhbFN0YXRlQ29udHJhY3QgZXh0ZW5kcyBhcmM0LkNvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo2ODgKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHNldF9pbXBsaWNpdF9rZXlfYXJjNF9zdHIKICAgIGludGNfMCAvLyAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX3NldF9pbXBsaWNpdF9rZXlfYXJjNF9ieXRlX3JvdXRlQDE4OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjY5MwogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgbm90IE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gY2FuIG9ubHkgY2FsbCB3aGVuIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjU5MQogICAgLy8gZXhwb3J0IGNsYXNzIEdsb2JhbFN0YXRlQ29udHJhY3QgZXh0ZW5kcyBhcmM0LkNvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo2OTMKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHNldF9pbXBsaWNpdF9rZXlfYXJjNF9ieXRlCiAgICBpbnRjXzAgLy8gMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX19zZXRfaW1wbGljaXRfa2V5X2FyYzRfYm9vbF9yb3V0ZUAxOToKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo2OTgKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIG5vdCBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGNhbiBvbmx5IGNhbGwgd2hlbiBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo1OTEKICAgIC8vIGV4cG9ydCBjbGFzcyBHbG9iYWxTdGF0ZUNvbnRyYWN0IGV4dGVuZHMgYXJjNC5Db250cmFjdCB7CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6Njk4CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiBzZXRfaW1wbGljaXRfa2V5X2FyYzRfYm9vbAogICAgaW50Y18wIC8vIDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fc2V0X2ltcGxpY2l0X2tleV9hcmM0X2FkZHJlc3Nfcm91dGVAMjA6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NzAzCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBub3QgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBjYW4gb25seSBjYWxsIHdoZW4gbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NTkxCiAgICAvLyBleHBvcnQgY2xhc3MgR2xvYmFsU3RhdGVDb250cmFjdCBleHRlbmRzIGFyYzQuQ29udHJhY3QgewogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjcwMwogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgc2V0X2ltcGxpY2l0X2tleV9hcmM0X2FkZHJlc3MKICAgIGludGNfMCAvLyAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX3NldF9pbXBsaWNpdF9rZXlfYXJjNF91aW50bjEyOF9yb3V0ZUAyMToKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo3MDgKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIG5vdCBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGNhbiBvbmx5IGNhbGwgd2hlbiBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo1OTEKICAgIC8vIGV4cG9ydCBjbGFzcyBHbG9iYWxTdGF0ZUNvbnRyYWN0IGV4dGVuZHMgYXJjNC5Db250cmFjdCB7CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NzA4CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiBzZXRfaW1wbGljaXRfa2V5X2FyYzRfdWludG4xMjgKICAgIGludGNfMCAvLyAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX3NldF9pbXBsaWNpdF9rZXlfYXJjNF9keW5hbWljX2J5dGVzX3JvdXRlQDIyOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjcxMwogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgbm90IE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gY2FuIG9ubHkgY2FsbCB3aGVuIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjU5MQogICAgLy8gZXhwb3J0IGNsYXNzIEdsb2JhbFN0YXRlQ29udHJhY3QgZXh0ZW5kcyBhcmM0LkNvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo3MTMKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHNldF9pbXBsaWNpdF9rZXlfYXJjNF9keW5hbWljX2J5dGVzCiAgICBpbnRjXzAgLy8gMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX19zZXRfYXJjNF91aW50bjY0X3JvdXRlQDIzOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjcxOQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgbm90IE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gY2FuIG9ubHkgY2FsbCB3aGVuIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjU5MQogICAgLy8gZXhwb3J0IGNsYXNzIEdsb2JhbFN0YXRlQ29udHJhY3QgZXh0ZW5kcyBhcmM0LkNvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo3MTkKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHNldF9hcmM0X3VpbnRuNjQKICAgIGludGNfMCAvLyAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX3NldF9hcmM0X3N0cl9yb3V0ZUAyNDoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo3MjQKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIG5vdCBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGNhbiBvbmx5IGNhbGwgd2hlbiBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo1OTEKICAgIC8vIGV4cG9ydCBjbGFzcyBHbG9iYWxTdGF0ZUNvbnRyYWN0IGV4dGVuZHMgYXJjNC5Db250cmFjdCB7CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NzI0CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiBzZXRfYXJjNF9zdHIKICAgIGludGNfMCAvLyAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX3NldF9hcmM0X2J5dGVfcm91dGVAMjU6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NzI5CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBub3QgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBjYW4gb25seSBjYWxsIHdoZW4gbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NTkxCiAgICAvLyBleHBvcnQgY2xhc3MgR2xvYmFsU3RhdGVDb250cmFjdCBleHRlbmRzIGFyYzQuQ29udHJhY3QgewogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjcyOQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgc2V0X2FyYzRfYnl0ZQogICAgaW50Y18wIC8vIDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fc2V0X2FyYzRfYm9vbF9yb3V0ZUAyNjoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo3MzQKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIG5vdCBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGNhbiBvbmx5IGNhbGwgd2hlbiBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo1OTEKICAgIC8vIGV4cG9ydCBjbGFzcyBHbG9iYWxTdGF0ZUNvbnRyYWN0IGV4dGVuZHMgYXJjNC5Db250cmFjdCB7CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NzM0CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiBzZXRfYXJjNF9ib29sCiAgICBpbnRjXzAgLy8gMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX19zZXRfYXJjNF9hZGRyZXNzX3JvdXRlQDI3OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjczOQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgbm90IE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gY2FuIG9ubHkgY2FsbCB3aGVuIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjU5MQogICAgLy8gZXhwb3J0IGNsYXNzIEdsb2JhbFN0YXRlQ29udHJhY3QgZXh0ZW5kcyBhcmM0LkNvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo3MzkKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHNldF9hcmM0X2FkZHJlc3MKICAgIGludGNfMCAvLyAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX3NldF9hcmM0X3VpbnRuMTI4X3JvdXRlQDI4OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjc0NAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgbm90IE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gY2FuIG9ubHkgY2FsbCB3aGVuIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjU5MQogICAgLy8gZXhwb3J0IGNsYXNzIEdsb2JhbFN0YXRlQ29udHJhY3QgZXh0ZW5kcyBhcmM0LkNvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo3NDQKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHNldF9hcmM0X3VpbnRuMTI4CiAgICBpbnRjXzAgLy8gMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX19zZXRfYXJjNF9keW5hbWljX2J5dGVzX3JvdXRlQDI5OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjc0OQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgbm90IE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gY2FuIG9ubHkgY2FsbCB3aGVuIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjU5MQogICAgLy8gZXhwb3J0IGNsYXNzIEdsb2JhbFN0YXRlQ29udHJhY3QgZXh0ZW5kcyBhcmM0LkNvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo3NDkKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHNldF9hcmM0X2R5bmFtaWNfYnl0ZXMKICAgIGludGNfMCAvLyAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX2JhcmVfcm91dGluZ0AzMjoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo1OTEKICAgIC8vIGV4cG9ydCBjbGFzcyBHbG9iYWxTdGF0ZUNvbnRyYWN0IGV4dGVuZHMgYXJjNC5Db250cmFjdCB7CiAgICB0eG4gT25Db21wbGV0aW9uCiAgICBibnogX19wdXlhX2FyYzRfcm91dGVyX19fYWZ0ZXJfaWZfZWxzZUAzNgogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgICEKICAgIGFzc2VydCAvLyBjYW4gb25seSBjYWxsIHdoZW4gY3JlYXRpbmcKICAgIGludGNfMCAvLyAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX2FmdGVyX2lmX2Vsc2VAMzY6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NTkxCiAgICAvLyBleHBvcnQgY2xhc3MgR2xvYmFsU3RhdGVDb250cmFjdCBleHRlbmRzIGFyYzQuQ29udHJhY3QgewogICAgaW50Y18xIC8vIDAKICAgIHJldHN1YgoKCi8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo6R2xvYmFsU3RhdGVDb250cmFjdC5nZXRfaW1wbGljaXRfa2V5X2FyYzRfdWludG42NCgpIC0+IGJ5dGVzOgpnZXRfaW1wbGljaXRfa2V5X2FyYzRfdWludG42NDoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo2MTEtNjEyCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gZ2V0X2ltcGxpY2l0X2tleV9hcmM0X3VpbnRuNjQoKTogVWludE42NCB7CiAgICBwcm90byAwIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo2MTMKICAgIC8vIHJldHVybiB0aGlzLmltcGxpY2l0S2V5QXJjNFVpbnRONjQudmFsdWUKICAgIGludGNfMSAvLyAwCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NTkzCiAgICAvLyBpbXBsaWNpdEtleUFyYzRVaW50TjY0ID0gR2xvYmFsU3RhdGUoeyBpbml0aWFsVmFsdWU6IG5ldyBVaW50TjY0KDEzMzcpIH0pCiAgICBieXRlY18xIC8vICJpbXBsaWNpdEtleUFyYzRVaW50TjY0IgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjYxMwogICAgLy8gcmV0dXJuIHRoaXMuaW1wbGljaXRLZXlBcmM0VWludE42NC52YWx1ZQogICAgYXBwX2dsb2JhbF9nZXRfZXgKICAgIGFzc2VydCAvLyBjaGVjayBHbG9iYWxTdGF0ZSBleGlzdHMKICAgIHJldHN1YgoKCi8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo6R2xvYmFsU3RhdGVDb250cmFjdC5nZXRfaW1wbGljaXRfa2V5X2FyYzRfc3RyKCkgLT4gYnl0ZXM6CmdldF9pbXBsaWNpdF9rZXlfYXJjNF9zdHI6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NjE2LTYxNwogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIGdldF9pbXBsaWNpdF9rZXlfYXJjNF9zdHIoKTogU3RyIHsKICAgIHByb3RvIDAgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjYxOAogICAgLy8gcmV0dXJuIHRoaXMuaW1wbGljaXRLZXlBcmM0U3RyLnZhbHVlCiAgICBpbnRjXzEgLy8gMAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjU5NAogICAgLy8gaW1wbGljaXRLZXlBcmM0U3RyID0gR2xvYmFsU3RhdGUoeyBpbml0aWFsVmFsdWU6IG5ldyBTdHIoJ0hlbGxvJykgfSkKICAgIGJ5dGVjXzIgLy8gImltcGxpY2l0S2V5QXJjNFN0ciIKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo2MTgKICAgIC8vIHJldHVybiB0aGlzLmltcGxpY2l0S2V5QXJjNFN0ci52YWx1ZQogICAgYXBwX2dsb2JhbF9nZXRfZXgKICAgIGFzc2VydCAvLyBjaGVjayBHbG9iYWxTdGF0ZSBleGlzdHMKICAgIHJldHN1YgoKCi8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo6R2xvYmFsU3RhdGVDb250cmFjdC5nZXRfaW1wbGljaXRfa2V5X2FyYzRfYnl0ZSgpIC0+IGJ5dGVzOgpnZXRfaW1wbGljaXRfa2V5X2FyYzRfYnl0ZToKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo2MjEtNjIyCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gZ2V0X2ltcGxpY2l0X2tleV9hcmM0X2J5dGUoKTogQnl0ZSB7CiAgICBwcm90byAwIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo2MjMKICAgIC8vIHJldHVybiB0aGlzLmltcGxpY2l0S2V5QXJjNEJ5dGUudmFsdWUKICAgIGludGNfMSAvLyAwCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NTk1CiAgICAvLyBpbXBsaWNpdEtleUFyYzRCeXRlID0gR2xvYmFsU3RhdGUoeyBpbml0aWFsVmFsdWU6IG5ldyBCeXRlKDApIH0pCiAgICBieXRlY18zIC8vICJpbXBsaWNpdEtleUFyYzRCeXRlIgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjYyMwogICAgLy8gcmV0dXJuIHRoaXMuaW1wbGljaXRLZXlBcmM0Qnl0ZS52YWx1ZQogICAgYXBwX2dsb2JhbF9nZXRfZXgKICAgIGFzc2VydCAvLyBjaGVjayBHbG9iYWxTdGF0ZSBleGlzdHMKICAgIHJldHN1YgoKCi8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo6R2xvYmFsU3RhdGVDb250cmFjdC5nZXRfaW1wbGljaXRfa2V5X2FyYzRfYm9vbCgpIC0+IGJ5dGVzOgpnZXRfaW1wbGljaXRfa2V5X2FyYzRfYm9vbDoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo2MjYtNjI3CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gZ2V0X2ltcGxpY2l0X2tleV9hcmM0X2Jvb2woKTogYXJjNC5Cb29sIHsKICAgIHByb3RvIDAgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjYyOAogICAgLy8gcmV0dXJuIHRoaXMuaW1wbGljaXRLZXlBcmM0Qm9vbC52YWx1ZQogICAgaW50Y18xIC8vIDAKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo1OTYKICAgIC8vIGltcGxpY2l0S2V5QXJjNEJvb2wgPSBHbG9iYWxTdGF0ZSh7IGluaXRpYWxWYWx1ZTogbmV3IEJvb2wodHJ1ZSkgfSkKICAgIGJ5dGVjIDQgLy8gImltcGxpY2l0S2V5QXJjNEJvb2wiCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NjI4CiAgICAvLyByZXR1cm4gdGhpcy5pbXBsaWNpdEtleUFyYzRCb29sLnZhbHVlCiAgICBhcHBfZ2xvYmFsX2dldF9leAogICAgYXNzZXJ0IC8vIGNoZWNrIEdsb2JhbFN0YXRlIGV4aXN0cwogICAgcmV0c3ViCgoKLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjpHbG9iYWxTdGF0ZUNvbnRyYWN0LmdldF9pbXBsaWNpdF9rZXlfYXJjNF9hZGRyZXNzKCkgLT4gYnl0ZXM6CmdldF9pbXBsaWNpdF9rZXlfYXJjNF9hZGRyZXNzOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjYzMS02MzIKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBnZXRfaW1wbGljaXRfa2V5X2FyYzRfYWRkcmVzcygpOiBBZGRyZXNzIHsKICAgIHByb3RvIDAgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjYzMwogICAgLy8gcmV0dXJuIHRoaXMuaW1wbGljaXRLZXlBcmM0QWRkcmVzcy52YWx1ZQogICAgaW50Y18xIC8vIDAKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo1OTcKICAgIC8vIGltcGxpY2l0S2V5QXJjNEFkZHJlc3MgPSBHbG9iYWxTdGF0ZSh7IGluaXRpYWxWYWx1ZTogbmV3IEFkZHJlc3MoR2xvYmFsLmNyZWF0b3JBZGRyZXNzKSB9KQogICAgYnl0ZWMgNSAvLyAiaW1wbGljaXRLZXlBcmM0QWRkcmVzcyIKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo2MzMKICAgIC8vIHJldHVybiB0aGlzLmltcGxpY2l0S2V5QXJjNEFkZHJlc3MudmFsdWUKICAgIGFwcF9nbG9iYWxfZ2V0X2V4CiAgICBhc3NlcnQgLy8gY2hlY2sgR2xvYmFsU3RhdGUgZXhpc3RzCiAgICByZXRzdWIKCgovLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6Okdsb2JhbFN0YXRlQ29udHJhY3QuZ2V0X2ltcGxpY2l0X2tleV9hcmM0X3VpbnRuMTI4KCkgLT4gYnl0ZXM6CmdldF9pbXBsaWNpdF9rZXlfYXJjNF91aW50bjEyODoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo2MzYtNjM3CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gZ2V0X2ltcGxpY2l0X2tleV9hcmM0X3VpbnRuMTI4KCk6IFVpbnROMTI4IHsKICAgIHByb3RvIDAgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjYzOAogICAgLy8gcmV0dXJuIHRoaXMuaW1wbGljaXRLZXlBcmM0VWludE4xMjgudmFsdWUKICAgIGludGNfMSAvLyAwCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NTk4CiAgICAvLyBpbXBsaWNpdEtleUFyYzRVaW50TjEyOCA9IEdsb2JhbFN0YXRlKHsgaW5pdGlhbFZhbHVlOiBuZXcgVWludE4xMjgoMm4gKiogMTAwbikgfSkKICAgIGJ5dGVjIDYgLy8gImltcGxpY2l0S2V5QXJjNFVpbnROMTI4IgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjYzOAogICAgLy8gcmV0dXJuIHRoaXMuaW1wbGljaXRLZXlBcmM0VWludE4xMjgudmFsdWUKICAgIGFwcF9nbG9iYWxfZ2V0X2V4CiAgICBhc3NlcnQgLy8gY2hlY2sgR2xvYmFsU3RhdGUgZXhpc3RzCiAgICByZXRzdWIKCgovLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6Okdsb2JhbFN0YXRlQ29udHJhY3QuZ2V0X2ltcGxpY2l0X2tleV9hcmM0X2R5bmFtaWNfYnl0ZXMoKSAtPiBieXRlczoKZ2V0X2ltcGxpY2l0X2tleV9hcmM0X2R5bmFtaWNfYnl0ZXM6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NjQxLTY0MgogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIGdldF9pbXBsaWNpdF9rZXlfYXJjNF9keW5hbWljX2J5dGVzKCk6IER5bmFtaWNCeXRlcyB7CiAgICBwcm90byAwIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo2NDMKICAgIC8vIHJldHVybiB0aGlzLmltcGxpY2l0S2V5QXJjNER5bmFtaWNCeXRlcy52YWx1ZQogICAgaW50Y18xIC8vIDAKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo1OTkKICAgIC8vIGltcGxpY2l0S2V5QXJjNER5bmFtaWNCeXRlcyA9IEdsb2JhbFN0YXRlKHsgaW5pdGlhbFZhbHVlOiBuZXcgRHluYW1pY0J5dGVzKCdkeW5hbWljIGJ5dGVzJykgfSkKICAgIGJ5dGVjIDcgLy8gImltcGxpY2l0S2V5QXJjNER5bmFtaWNCeXRlcyIKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo2NDMKICAgIC8vIHJldHVybiB0aGlzLmltcGxpY2l0S2V5QXJjNER5bmFtaWNCeXRlcy52YWx1ZQogICAgYXBwX2dsb2JhbF9nZXRfZXgKICAgIGFzc2VydCAvLyBjaGVjayBHbG9iYWxTdGF0ZSBleGlzdHMKICAgIHJldHN1YgoKCi8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo6R2xvYmFsU3RhdGVDb250cmFjdC5nZXRfYXJjNF91aW50bjY0KCkgLT4gYnl0ZXM6CmdldF9hcmM0X3VpbnRuNjQ6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NjQ3LTY0OAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIGdldF9hcmM0X3VpbnRuNjQoKTogVWludE42NCB7CiAgICBwcm90byAwIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo2NDkKICAgIC8vIHJldHVybiB0aGlzLmFyYzRVaW50TjY0LnZhbHVlCiAgICBpbnRjXzEgLy8gMAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjYwMgogICAgLy8gYXJjNFVpbnRONjQgPSBHbG9iYWxTdGF0ZSh7IGluaXRpYWxWYWx1ZTogbmV3IFVpbnRONjQoMTMzNyksIGtleTogJ2V4cGxpY2l0X2tleV9hcmM0X3VpbnRuNjQnIH0pCiAgICBieXRlYyA4IC8vICJleHBsaWNpdF9rZXlfYXJjNF91aW50bjY0IgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjY0OQogICAgLy8gcmV0dXJuIHRoaXMuYXJjNFVpbnRONjQudmFsdWUKICAgIGFwcF9nbG9iYWxfZ2V0X2V4CiAgICBhc3NlcnQgLy8gY2hlY2sgR2xvYmFsU3RhdGUgZXhpc3RzCiAgICByZXRzdWIKCgovLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6Okdsb2JhbFN0YXRlQ29udHJhY3QuZ2V0X2FyYzRfc3RyKCkgLT4gYnl0ZXM6CmdldF9hcmM0X3N0cjoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo2NTItNjUzCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gZ2V0X2FyYzRfc3RyKCk6IFN0ciB7CiAgICBwcm90byAwIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo2NTQKICAgIC8vIHJldHVybiB0aGlzLmFyYzRTdHIudmFsdWUKICAgIGludGNfMSAvLyAwCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NjAzCiAgICAvLyBhcmM0U3RyID0gR2xvYmFsU3RhdGUoeyBpbml0aWFsVmFsdWU6IG5ldyBTdHIoJ0hlbGxvJyksIGtleTogJ2V4cGxpY2l0X2tleV9hcmM0X3N0cicgfSkKICAgIGJ5dGVjIDkgLy8gImV4cGxpY2l0X2tleV9hcmM0X3N0ciIKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo2NTQKICAgIC8vIHJldHVybiB0aGlzLmFyYzRTdHIudmFsdWUKICAgIGFwcF9nbG9iYWxfZ2V0X2V4CiAgICBhc3NlcnQgLy8gY2hlY2sgR2xvYmFsU3RhdGUgZXhpc3RzCiAgICByZXRzdWIKCgovLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6Okdsb2JhbFN0YXRlQ29udHJhY3QuZ2V0X2FyYzRfYnl0ZSgpIC0+IGJ5dGVzOgpnZXRfYXJjNF9ieXRlOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjY1Ny02NTgKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBnZXRfYXJjNF9ieXRlKCk6IEJ5dGUgewogICAgcHJvdG8gMCAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NjU5CiAgICAvLyByZXR1cm4gdGhpcy5hcmM0Qnl0ZS52YWx1ZQogICAgaW50Y18xIC8vIDAKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo2MDQKICAgIC8vIGFyYzRCeXRlID0gR2xvYmFsU3RhdGUoeyBpbml0aWFsVmFsdWU6IG5ldyBCeXRlKDApLCBrZXk6ICdleHBsaWNpdF9rZXlfYXJjNF9ieXRlJyB9KQogICAgYnl0ZWMgMTAgLy8gImV4cGxpY2l0X2tleV9hcmM0X2J5dGUiCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NjU5CiAgICAvLyByZXR1cm4gdGhpcy5hcmM0Qnl0ZS52YWx1ZQogICAgYXBwX2dsb2JhbF9nZXRfZXgKICAgIGFzc2VydCAvLyBjaGVjayBHbG9iYWxTdGF0ZSBleGlzdHMKICAgIHJldHN1YgoKCi8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo6R2xvYmFsU3RhdGVDb250cmFjdC5nZXRfYXJjNF9ib29sKCkgLT4gYnl0ZXM6CmdldF9hcmM0X2Jvb2w6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NjYyLTY2MwogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIGdldF9hcmM0X2Jvb2woKTogYXJjNC5Cb29sIHsKICAgIHByb3RvIDAgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjY2NAogICAgLy8gcmV0dXJuIHRoaXMuYXJjNEJvb2wudmFsdWUKICAgIGludGNfMSAvLyAwCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NjA1CiAgICAvLyBhcmM0Qm9vbCA9IEdsb2JhbFN0YXRlKHsgaW5pdGlhbFZhbHVlOiBuZXcgQm9vbCh0cnVlKSwga2V5OiAnZXhwbGljaXRfa2V5X2FyYzRfYm9vbCcgfSkKICAgIGJ5dGVjIDExIC8vICJleHBsaWNpdF9rZXlfYXJjNF9ib29sIgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjY2NAogICAgLy8gcmV0dXJuIHRoaXMuYXJjNEJvb2wudmFsdWUKICAgIGFwcF9nbG9iYWxfZ2V0X2V4CiAgICBhc3NlcnQgLy8gY2hlY2sgR2xvYmFsU3RhdGUgZXhpc3RzCiAgICByZXRzdWIKCgovLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6Okdsb2JhbFN0YXRlQ29udHJhY3QuZ2V0X2FyYzRfYWRkcmVzcygpIC0+IGJ5dGVzOgpnZXRfYXJjNF9hZGRyZXNzOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjY2Ny02NjgKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBnZXRfYXJjNF9hZGRyZXNzKCk6IEFkZHJlc3MgewogICAgcHJvdG8gMCAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NjY5CiAgICAvLyByZXR1cm4gdGhpcy5hcmM0QWRkcmVzcy52YWx1ZQogICAgaW50Y18xIC8vIDAKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo2MDYKICAgIC8vIGFyYzRBZGRyZXNzID0gR2xvYmFsU3RhdGUoeyBpbml0aWFsVmFsdWU6IG5ldyBBZGRyZXNzKEdsb2JhbC5jcmVhdG9yQWRkcmVzcyksIGtleTogJ2V4cGxpY2l0X2tleV9hcmM0X2FkZHJlc3MnIH0pCiAgICBieXRlYyAxMiAvLyAiZXhwbGljaXRfa2V5X2FyYzRfYWRkcmVzcyIKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo2NjkKICAgIC8vIHJldHVybiB0aGlzLmFyYzRBZGRyZXNzLnZhbHVlCiAgICBhcHBfZ2xvYmFsX2dldF9leAogICAgYXNzZXJ0IC8vIGNoZWNrIEdsb2JhbFN0YXRlIGV4aXN0cwogICAgcmV0c3ViCgoKLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjpHbG9iYWxTdGF0ZUNvbnRyYWN0LmdldF9hcmM0X3VpbnRuMTI4KCkgLT4gYnl0ZXM6CmdldF9hcmM0X3VpbnRuMTI4OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjY3Mi02NzMKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBnZXRfYXJjNF91aW50bjEyOCgpOiBVaW50TjEyOCB7CiAgICBwcm90byAwIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo2NzQKICAgIC8vIHJldHVybiB0aGlzLmFyYzRVaW50TjEyOC52YWx1ZQogICAgaW50Y18xIC8vIDAKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo2MDcKICAgIC8vIGFyYzRVaW50TjEyOCA9IEdsb2JhbFN0YXRlKHsgaW5pdGlhbFZhbHVlOiBuZXcgVWludE4xMjgoMm4gKiogMTAwbiksIGtleTogJ2V4cGxpY2l0X2tleV9hcmM0X3VpbnRuMTI4JyB9KQogICAgYnl0ZWMgMTMgLy8gImV4cGxpY2l0X2tleV9hcmM0X3VpbnRuMTI4IgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjY3NAogICAgLy8gcmV0dXJuIHRoaXMuYXJjNFVpbnROMTI4LnZhbHVlCiAgICBhcHBfZ2xvYmFsX2dldF9leAogICAgYXNzZXJ0IC8vIGNoZWNrIEdsb2JhbFN0YXRlIGV4aXN0cwogICAgcmV0c3ViCgoKLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjpHbG9iYWxTdGF0ZUNvbnRyYWN0LmdldF9hcmM0X2R5bmFtaWNfYnl0ZXMoKSAtPiBieXRlczoKZ2V0X2FyYzRfZHluYW1pY19ieXRlczoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo2NzctNjc4CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gZ2V0X2FyYzRfZHluYW1pY19ieXRlcygpOiBEeW5hbWljQnl0ZXMgewogICAgcHJvdG8gMCAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6Njc5CiAgICAvLyByZXR1cm4gdGhpcy5hcmM0RHluYW1pY0J5dGVzLnZhbHVlCiAgICBpbnRjXzEgLy8gMAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjYwOAogICAgLy8gYXJjNER5bmFtaWNCeXRlcyA9IEdsb2JhbFN0YXRlKHsgaW5pdGlhbFZhbHVlOiBuZXcgRHluYW1pY0J5dGVzKCdkeW5hbWljIGJ5dGVzJyksIGtleTogJ2V4cGxpY2l0X2tleV9hcmM0X2R5bmFtaWNfYnl0ZXMnIH0pCiAgICBieXRlYyAxNCAvLyAiZXhwbGljaXRfa2V5X2FyYzRfZHluYW1pY19ieXRlcyIKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo2NzkKICAgIC8vIHJldHVybiB0aGlzLmFyYzREeW5hbWljQnl0ZXMudmFsdWUKICAgIGFwcF9nbG9iYWxfZ2V0X2V4CiAgICBhc3NlcnQgLy8gY2hlY2sgR2xvYmFsU3RhdGUgZXhpc3RzCiAgICByZXRzdWIKCgovLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6Okdsb2JhbFN0YXRlQ29udHJhY3Quc2V0X2ltcGxpY2l0X2tleV9hcmM0X3VpbnRuNjQodmFsdWU6IGJ5dGVzKSAtPiB2b2lkOgpzZXRfaW1wbGljaXRfa2V5X2FyYzRfdWludG42NDoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo2ODMtNjg0CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gc2V0X2ltcGxpY2l0X2tleV9hcmM0X3VpbnRuNjQodmFsdWU6IFVpbnRONjQpIHsKICAgIHByb3RvIDEgMAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjU5MwogICAgLy8gaW1wbGljaXRLZXlBcmM0VWludE42NCA9IEdsb2JhbFN0YXRlKHsgaW5pdGlhbFZhbHVlOiBuZXcgVWludE42NCgxMzM3KSB9KQogICAgYnl0ZWNfMSAvLyAiaW1wbGljaXRLZXlBcmM0VWludE42NCIKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo2ODUKICAgIC8vIHRoaXMuaW1wbGljaXRLZXlBcmM0VWludE42NC52YWx1ZSA9IHZhbHVlCiAgICBmcmFtZV9kaWcgLTEKICAgIGFwcF9nbG9iYWxfcHV0CiAgICByZXRzdWIKCgovLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6Okdsb2JhbFN0YXRlQ29udHJhY3Quc2V0X2ltcGxpY2l0X2tleV9hcmM0X3N0cih2YWx1ZTogYnl0ZXMpIC0+IHZvaWQ6CnNldF9pbXBsaWNpdF9rZXlfYXJjNF9zdHI6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6Njg4LTY4OQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIHNldF9pbXBsaWNpdF9rZXlfYXJjNF9zdHIodmFsdWU6IFN0cikgewogICAgcHJvdG8gMSAwCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NTk0CiAgICAvLyBpbXBsaWNpdEtleUFyYzRTdHIgPSBHbG9iYWxTdGF0ZSh7IGluaXRpYWxWYWx1ZTogbmV3IFN0cignSGVsbG8nKSB9KQogICAgYnl0ZWNfMiAvLyAiaW1wbGljaXRLZXlBcmM0U3RyIgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjY5MAogICAgLy8gdGhpcy5pbXBsaWNpdEtleUFyYzRTdHIudmFsdWUgPSB2YWx1ZQogICAgZnJhbWVfZGlnIC0xCiAgICBhcHBfZ2xvYmFsX3B1dAogICAgcmV0c3ViCgoKLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjpHbG9iYWxTdGF0ZUNvbnRyYWN0LnNldF9pbXBsaWNpdF9rZXlfYXJjNF9ieXRlKHZhbHVlOiBieXRlcykgLT4gdm9pZDoKc2V0X2ltcGxpY2l0X2tleV9hcmM0X2J5dGU6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NjkzLTY5NAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIHNldF9pbXBsaWNpdF9rZXlfYXJjNF9ieXRlKHZhbHVlOiBCeXRlKSB7CiAgICBwcm90byAxIDAKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo1OTUKICAgIC8vIGltcGxpY2l0S2V5QXJjNEJ5dGUgPSBHbG9iYWxTdGF0ZSh7IGluaXRpYWxWYWx1ZTogbmV3IEJ5dGUoMCkgfSkKICAgIGJ5dGVjXzMgLy8gImltcGxpY2l0S2V5QXJjNEJ5dGUiCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6Njk1CiAgICAvLyB0aGlzLmltcGxpY2l0S2V5QXJjNEJ5dGUudmFsdWUgPSB2YWx1ZQogICAgZnJhbWVfZGlnIC0xCiAgICBhcHBfZ2xvYmFsX3B1dAogICAgcmV0c3ViCgoKLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjpHbG9iYWxTdGF0ZUNvbnRyYWN0LnNldF9pbXBsaWNpdF9rZXlfYXJjNF9ib29sKHZhbHVlOiBieXRlcykgLT4gdm9pZDoKc2V0X2ltcGxpY2l0X2tleV9hcmM0X2Jvb2w6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6Njk4LTY5OQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIHNldF9pbXBsaWNpdF9rZXlfYXJjNF9ib29sKHZhbHVlOiBCb29sKSB7CiAgICBwcm90byAxIDAKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo1OTYKICAgIC8vIGltcGxpY2l0S2V5QXJjNEJvb2wgPSBHbG9iYWxTdGF0ZSh7IGluaXRpYWxWYWx1ZTogbmV3IEJvb2wodHJ1ZSkgfSkKICAgIGJ5dGVjIDQgLy8gImltcGxpY2l0S2V5QXJjNEJvb2wiCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NzAwCiAgICAvLyB0aGlzLmltcGxpY2l0S2V5QXJjNEJvb2wudmFsdWUgPSB2YWx1ZQogICAgZnJhbWVfZGlnIC0xCiAgICBhcHBfZ2xvYmFsX3B1dAogICAgcmV0c3ViCgoKLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjpHbG9iYWxTdGF0ZUNvbnRyYWN0LnNldF9pbXBsaWNpdF9rZXlfYXJjNF9hZGRyZXNzKHZhbHVlOiBieXRlcykgLT4gdm9pZDoKc2V0X2ltcGxpY2l0X2tleV9hcmM0X2FkZHJlc3M6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NzAzLTcwNAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIHNldF9pbXBsaWNpdF9rZXlfYXJjNF9hZGRyZXNzKHZhbHVlOiBBZGRyZXNzKSB7CiAgICBwcm90byAxIDAKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo1OTcKICAgIC8vIGltcGxpY2l0S2V5QXJjNEFkZHJlc3MgPSBHbG9iYWxTdGF0ZSh7IGluaXRpYWxWYWx1ZTogbmV3IEFkZHJlc3MoR2xvYmFsLmNyZWF0b3JBZGRyZXNzKSB9KQogICAgYnl0ZWMgNSAvLyAiaW1wbGljaXRLZXlBcmM0QWRkcmVzcyIKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo3MDUKICAgIC8vIHRoaXMuaW1wbGljaXRLZXlBcmM0QWRkcmVzcy52YWx1ZSA9IHZhbHVlCiAgICBmcmFtZV9kaWcgLTEKICAgIGFwcF9nbG9iYWxfcHV0CiAgICByZXRzdWIKCgovLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6Okdsb2JhbFN0YXRlQ29udHJhY3Quc2V0X2ltcGxpY2l0X2tleV9hcmM0X3VpbnRuMTI4KHZhbHVlOiBieXRlcykgLT4gdm9pZDoKc2V0X2ltcGxpY2l0X2tleV9hcmM0X3VpbnRuMTI4OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjcwOC03MDkKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBzZXRfaW1wbGljaXRfa2V5X2FyYzRfdWludG4xMjgodmFsdWU6IFVpbnROMTI4KSB7CiAgICBwcm90byAxIDAKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo1OTgKICAgIC8vIGltcGxpY2l0S2V5QXJjNFVpbnROMTI4ID0gR2xvYmFsU3RhdGUoeyBpbml0aWFsVmFsdWU6IG5ldyBVaW50TjEyOCgybiAqKiAxMDBuKSB9KQogICAgYnl0ZWMgNiAvLyAiaW1wbGljaXRLZXlBcmM0VWludE4xMjgiCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NzEwCiAgICAvLyB0aGlzLmltcGxpY2l0S2V5QXJjNFVpbnROMTI4LnZhbHVlID0gdmFsdWUKICAgIGZyYW1lX2RpZyAtMQogICAgYXBwX2dsb2JhbF9wdXQKICAgIHJldHN1YgoKCi8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo6R2xvYmFsU3RhdGVDb250cmFjdC5zZXRfaW1wbGljaXRfa2V5X2FyYzRfZHluYW1pY19ieXRlcyh2YWx1ZTogYnl0ZXMpIC0+IHZvaWQ6CnNldF9pbXBsaWNpdF9rZXlfYXJjNF9keW5hbWljX2J5dGVzOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjcxMy03MTQKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBzZXRfaW1wbGljaXRfa2V5X2FyYzRfZHluYW1pY19ieXRlcyh2YWx1ZTogRHluYW1pY0J5dGVzKSB7CiAgICBwcm90byAxIDAKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo1OTkKICAgIC8vIGltcGxpY2l0S2V5QXJjNER5bmFtaWNCeXRlcyA9IEdsb2JhbFN0YXRlKHsgaW5pdGlhbFZhbHVlOiBuZXcgRHluYW1pY0J5dGVzKCdkeW5hbWljIGJ5dGVzJykgfSkKICAgIGJ5dGVjIDcgLy8gImltcGxpY2l0S2V5QXJjNER5bmFtaWNCeXRlcyIKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo3MTUKICAgIC8vIHRoaXMuaW1wbGljaXRLZXlBcmM0RHluYW1pY0J5dGVzLnZhbHVlID0gdmFsdWUKICAgIGZyYW1lX2RpZyAtMQogICAgYXBwX2dsb2JhbF9wdXQKICAgIHJldHN1YgoKCi8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo6R2xvYmFsU3RhdGVDb250cmFjdC5zZXRfYXJjNF91aW50bjY0KHZhbHVlOiBieXRlcykgLT4gdm9pZDoKc2V0X2FyYzRfdWludG42NDoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo3MTktNzIwCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gc2V0X2FyYzRfdWludG42NCh2YWx1ZTogVWludE42NCkgewogICAgcHJvdG8gMSAwCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NjAyCiAgICAvLyBhcmM0VWludE42NCA9IEdsb2JhbFN0YXRlKHsgaW5pdGlhbFZhbHVlOiBuZXcgVWludE42NCgxMzM3KSwga2V5OiAnZXhwbGljaXRfa2V5X2FyYzRfdWludG42NCcgfSkKICAgIGJ5dGVjIDggLy8gImV4cGxpY2l0X2tleV9hcmM0X3VpbnRuNjQiCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NzIxCiAgICAvLyB0aGlzLmFyYzRVaW50TjY0LnZhbHVlID0gdmFsdWUKICAgIGZyYW1lX2RpZyAtMQogICAgYXBwX2dsb2JhbF9wdXQKICAgIHJldHN1YgoKCi8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo6R2xvYmFsU3RhdGVDb250cmFjdC5zZXRfYXJjNF9zdHIodmFsdWU6IGJ5dGVzKSAtPiB2b2lkOgpzZXRfYXJjNF9zdHI6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NzI0LTcyNQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIHNldF9hcmM0X3N0cih2YWx1ZTogU3RyKSB7CiAgICBwcm90byAxIDAKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo2MDMKICAgIC8vIGFyYzRTdHIgPSBHbG9iYWxTdGF0ZSh7IGluaXRpYWxWYWx1ZTogbmV3IFN0cignSGVsbG8nKSwga2V5OiAnZXhwbGljaXRfa2V5X2FyYzRfc3RyJyB9KQogICAgYnl0ZWMgOSAvLyAiZXhwbGljaXRfa2V5X2FyYzRfc3RyIgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjcyNgogICAgLy8gdGhpcy5hcmM0U3RyLnZhbHVlID0gdmFsdWUKICAgIGZyYW1lX2RpZyAtMQogICAgYXBwX2dsb2JhbF9wdXQKICAgIHJldHN1YgoKCi8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo6R2xvYmFsU3RhdGVDb250cmFjdC5zZXRfYXJjNF9ieXRlKHZhbHVlOiBieXRlcykgLT4gdm9pZDoKc2V0X2FyYzRfYnl0ZToKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo3MjktNzMwCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gc2V0X2FyYzRfYnl0ZSh2YWx1ZTogQnl0ZSkgewogICAgcHJvdG8gMSAwCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NjA0CiAgICAvLyBhcmM0Qnl0ZSA9IEdsb2JhbFN0YXRlKHsgaW5pdGlhbFZhbHVlOiBuZXcgQnl0ZSgwKSwga2V5OiAnZXhwbGljaXRfa2V5X2FyYzRfYnl0ZScgfSkKICAgIGJ5dGVjIDEwIC8vICJleHBsaWNpdF9rZXlfYXJjNF9ieXRlIgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjczMQogICAgLy8gdGhpcy5hcmM0Qnl0ZS52YWx1ZSA9IHZhbHVlCiAgICBmcmFtZV9kaWcgLTEKICAgIGFwcF9nbG9iYWxfcHV0CiAgICByZXRzdWIKCgovLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6Okdsb2JhbFN0YXRlQ29udHJhY3Quc2V0X2FyYzRfYm9vbCh2YWx1ZTogYnl0ZXMpIC0+IHZvaWQ6CnNldF9hcmM0X2Jvb2w6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NzM0LTczNQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIHNldF9hcmM0X2Jvb2wodmFsdWU6IEJvb2wpIHsKICAgIHByb3RvIDEgMAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjYwNQogICAgLy8gYXJjNEJvb2wgPSBHbG9iYWxTdGF0ZSh7IGluaXRpYWxWYWx1ZTogbmV3IEJvb2wodHJ1ZSksIGtleTogJ2V4cGxpY2l0X2tleV9hcmM0X2Jvb2wnIH0pCiAgICBieXRlYyAxMSAvLyAiZXhwbGljaXRfa2V5X2FyYzRfYm9vbCIKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo3MzYKICAgIC8vIHRoaXMuYXJjNEJvb2wudmFsdWUgPSB2YWx1ZQogICAgZnJhbWVfZGlnIC0xCiAgICBhcHBfZ2xvYmFsX3B1dAogICAgcmV0c3ViCgoKLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjpHbG9iYWxTdGF0ZUNvbnRyYWN0LnNldF9hcmM0X2FkZHJlc3ModmFsdWU6IGJ5dGVzKSAtPiB2b2lkOgpzZXRfYXJjNF9hZGRyZXNzOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjczOS03NDAKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBzZXRfYXJjNF9hZGRyZXNzKHZhbHVlOiBBZGRyZXNzKSB7CiAgICBwcm90byAxIDAKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo2MDYKICAgIC8vIGFyYzRBZGRyZXNzID0gR2xvYmFsU3RhdGUoeyBpbml0aWFsVmFsdWU6IG5ldyBBZGRyZXNzKEdsb2JhbC5jcmVhdG9yQWRkcmVzcyksIGtleTogJ2V4cGxpY2l0X2tleV9hcmM0X2FkZHJlc3MnIH0pCiAgICBieXRlYyAxMiAvLyAiZXhwbGljaXRfa2V5X2FyYzRfYWRkcmVzcyIKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo3NDEKICAgIC8vIHRoaXMuYXJjNEFkZHJlc3MudmFsdWUgPSB2YWx1ZQogICAgZnJhbWVfZGlnIC0xCiAgICBhcHBfZ2xvYmFsX3B1dAogICAgcmV0c3ViCgoKLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjpHbG9iYWxTdGF0ZUNvbnRyYWN0LnNldF9hcmM0X3VpbnRuMTI4KHZhbHVlOiBieXRlcykgLT4gdm9pZDoKc2V0X2FyYzRfdWludG4xMjg6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NzQ0LTc0NQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIHNldF9hcmM0X3VpbnRuMTI4KHZhbHVlOiBVaW50TjEyOCkgewogICAgcHJvdG8gMSAwCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NjA3CiAgICAvLyBhcmM0VWludE4xMjggPSBHbG9iYWxTdGF0ZSh7IGluaXRpYWxWYWx1ZTogbmV3IFVpbnROMTI4KDJuICoqIDEwMG4pLCBrZXk6ICdleHBsaWNpdF9rZXlfYXJjNF91aW50bjEyOCcgfSkKICAgIGJ5dGVjIDEzIC8vICJleHBsaWNpdF9rZXlfYXJjNF91aW50bjEyOCIKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo3NDYKICAgIC8vIHRoaXMuYXJjNFVpbnROMTI4LnZhbHVlID0gdmFsdWUKICAgIGZyYW1lX2RpZyAtMQogICAgYXBwX2dsb2JhbF9wdXQKICAgIHJldHN1YgoKCi8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo6R2xvYmFsU3RhdGVDb250cmFjdC5zZXRfYXJjNF9keW5hbWljX2J5dGVzKHZhbHVlOiBieXRlcykgLT4gdm9pZDoKc2V0X2FyYzRfZHluYW1pY19ieXRlczoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo3NDktNzUwCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gc2V0X2FyYzRfZHluYW1pY19ieXRlcyh2YWx1ZTogRHluYW1pY0J5dGVzKSB7CiAgICBwcm90byAxIDAKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo2MDgKICAgIC8vIGFyYzREeW5hbWljQnl0ZXMgPSBHbG9iYWxTdGF0ZSh7IGluaXRpYWxWYWx1ZTogbmV3IER5bmFtaWNCeXRlcygnZHluYW1pYyBieXRlcycpLCBrZXk6ICdleHBsaWNpdF9rZXlfYXJjNF9keW5hbWljX2J5dGVzJyB9KQogICAgYnl0ZWMgMTQgLy8gImV4cGxpY2l0X2tleV9hcmM0X2R5bmFtaWNfYnl0ZXMiCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NzUxCiAgICAvLyB0aGlzLmFyYzREeW5hbWljQnl0ZXMudmFsdWUgPSB2YWx1ZQogICAgZnJhbWVfZGlnIC0xCiAgICBhcHBfZ2xvYmFsX3B1dAogICAgcmV0c3ViCg==", - "clear": "I3ByYWdtYSB2ZXJzaW9uIDEwCgp0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6Okdsb2JhbFN0YXRlQ29udHJhY3QuY2xlYXJTdGF0ZVByb2dyYW06CiAgICBwdXNoaW50IDEgLy8gMQogICAgcmV0dXJuCg==" - }, - "events": [], - "templateVariables": {} -} \ No newline at end of file diff --git a/tests/artifacts/state-ops/data/GlobalStateContract.clear.teal b/tests/artifacts/state-ops/data/GlobalStateContract.clear.teal deleted file mode 100644 index cccf7dc..0000000 --- a/tests/artifacts/state-ops/data/GlobalStateContract.clear.teal +++ /dev/null @@ -1,5 +0,0 @@ -#pragma version 10 - -tests/artifacts/state-ops/contract.algo.ts::GlobalStateContract.clearStateProgram: - pushint 1 // 1 - return diff --git a/tests/artifacts/state-ops/data/ITxnOpsContract.approval.teal b/tests/artifacts/state-ops/data/ITxnOpsContract.approval.teal deleted file mode 100644 index 52978e5..0000000 --- a/tests/artifacts/state-ops/data/ITxnOpsContract.approval.teal +++ /dev/null @@ -1,134 +0,0 @@ -#pragma version 10 - -tests/artifacts/state-ops/contract.algo.ts::ITxnOpsContract.approvalProgram: - intcblock 1 0 6 1000 - bytecblock 0x068101 - callsub __puya_arc4_router__ - return - - -// tests/artifacts/state-ops/contract.algo.ts::ITxnOpsContract.__puya_arc4_router__() -> uint64: -__puya_arc4_router__: - // tests/artifacts/state-ops/contract.algo.ts:469 - // export class ITxnOpsContract extends arc4.Contract { - proto 0 1 - txn NumAppArgs - bz __puya_arc4_router___bare_routing@5 - pushbytes 0x4e7cd9cb // method "verify_itxn_ops()void" - txna ApplicationArgs 0 - match __puya_arc4_router___verify_itxn_ops_route@2 - intc_1 // 0 - retsub - -__puya_arc4_router___verify_itxn_ops_route@2: - // tests/artifacts/state-ops/contract.algo.ts:470 - // @arc4.abimethod() - txn OnCompletion - ! - assert // OnCompletion is not NoOp - txn ApplicationID - assert // can only call when not creating - callsub verify_itxn_ops - intc_0 // 1 - retsub - -__puya_arc4_router___bare_routing@5: - // tests/artifacts/state-ops/contract.algo.ts:469 - // export class ITxnOpsContract extends arc4.Contract { - txn OnCompletion - bnz __puya_arc4_router___after_if_else@9 - txn ApplicationID - ! - assert // can only call when creating - intc_0 // 1 - retsub - -__puya_arc4_router___after_if_else@9: - // tests/artifacts/state-ops/contract.algo.ts:469 - // export class ITxnOpsContract extends arc4.Contract { - intc_1 // 0 - retsub - - -// tests/artifacts/state-ops/contract.algo.ts::ITxnOpsContract.verify_itxn_ops() -> void: -verify_itxn_ops: - // tests/artifacts/state-ops/contract.algo.ts:470-471 - // @arc4.abimethod() - // public verify_itxn_ops() { - proto 0 0 - // tests/artifacts/state-ops/contract.algo.ts:472 - // op.ITxnCreate.begin() - itxn_begin - // tests/artifacts/state-ops/contract.algo.ts:473 - // op.ITxnCreate.setTypeEnum(TransactionType.ApplicationCall) - intc_2 // 6 - itxn_field TypeEnum - // tests/artifacts/state-ops/contract.algo.ts:474 - // op.ITxnCreate.setOnCompletion(arc4.OnCompleteAction.DeleteApplication) - pushint 5 // 5 - itxn_field OnCompletion - // tests/artifacts/state-ops/contract.algo.ts:475 - // op.ITxnCreate.setApprovalProgram(Bytes.fromHex('068101')) - bytec_0 // 0x068101 - itxn_field ApprovalProgram - // tests/artifacts/state-ops/contract.algo.ts:478 - // op.ITxnCreate.setApprovalProgramPages(Bytes.fromHex('068101')) - bytec_0 // 0x068101 - itxn_field ApprovalProgramPages - // tests/artifacts/state-ops/contract.algo.ts:479 - // op.ITxnCreate.setClearStateProgram(Bytes.fromHex('068101')) - bytec_0 // 0x068101 - itxn_field ClearStateProgram - // tests/artifacts/state-ops/contract.algo.ts:480 - // op.ITxnCreate.setFee(op.Global.minTxnFee) - global MinTxnFee - itxn_field Fee - // tests/artifacts/state-ops/contract.algo.ts:481 - // op.ITxnCreate.next() - itxn_next - // tests/artifacts/state-ops/contract.algo.ts:482 - // op.ITxnCreate.setTypeEnum(TransactionType.Payment) - intc_0 // 1 - itxn_field TypeEnum - // tests/artifacts/state-ops/contract.algo.ts:483 - // op.ITxnCreate.setReceiver(op.Global.creatorAddress) - global CreatorAddress - itxn_field Receiver - // tests/artifacts/state-ops/contract.algo.ts:484 - // op.ITxnCreate.setAmount(Uint64(1000)) - intc_3 // 1000 - itxn_field Amount - // tests/artifacts/state-ops/contract.algo.ts:485 - // op.ITxnCreate.submit() - itxn_submit - // tests/artifacts/state-ops/contract.algo.ts:487 - // assert(op.ITxn.receiver === op.Global.creatorAddress) - itxn Receiver - global CreatorAddress - == - assert - // tests/artifacts/state-ops/contract.algo.ts:488 - // assert(op.ITxn.amount === Uint64(1000)) - itxn Amount - intc_3 // 1000 - == - assert - // tests/artifacts/state-ops/contract.algo.ts:489 - // assert(op.ITxn.typeEnum === TransactionType.Payment) - itxn TypeEnum - intc_0 // 1 - == - assert - // tests/artifacts/state-ops/contract.algo.ts:491 - // assert(op.GITxn.typeEnum(0) === TransactionType.ApplicationCall) - gitxn 0 TypeEnum - intc_2 // 6 - == - assert - // tests/artifacts/state-ops/contract.algo.ts:492 - // assert(op.GITxn.typeEnum(1) === TransactionType.Payment) - gitxn 1 TypeEnum - intc_0 // 1 - == - assert - retsub diff --git a/tests/artifacts/state-ops/data/ITxnOpsContract.arc32.json b/tests/artifacts/state-ops/data/ITxnOpsContract.arc32.json deleted file mode 100644 index 7d19134..0000000 --- a/tests/artifacts/state-ops/data/ITxnOpsContract.arc32.json +++ /dev/null @@ -1,50 +0,0 @@ -{ - "hints": { - "verify_itxn_ops()void": { - "call_config": { - "no_op": "CALL" - } - } - }, - "source": { - "approval": "I3ByYWdtYSB2ZXJzaW9uIDEwCgp0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OklUeG5PcHNDb250cmFjdC5hcHByb3ZhbFByb2dyYW06CiAgICBpbnRjYmxvY2sgMSAwIDYgMTAwMAogICAgYnl0ZWNibG9jayAweDA2ODEwMQogICAgY2FsbHN1YiBfX3B1eWFfYXJjNF9yb3V0ZXJfXwogICAgcmV0dXJuCgoKLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjpJVHhuT3BzQ29udHJhY3QuX19wdXlhX2FyYzRfcm91dGVyX18oKSAtPiB1aW50NjQ6Cl9fcHV5YV9hcmM0X3JvdXRlcl9fOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjQ2OQogICAgLy8gZXhwb3J0IGNsYXNzIElUeG5PcHNDb250cmFjdCBleHRlbmRzIGFyYzQuQ29udHJhY3QgewogICAgcHJvdG8gMCAxCiAgICB0eG4gTnVtQXBwQXJncwogICAgYnogX19wdXlhX2FyYzRfcm91dGVyX19fYmFyZV9yb3V0aW5nQDUKICAgIHB1c2hieXRlcyAweDRlN2NkOWNiIC8vIG1ldGhvZCAidmVyaWZ5X2l0eG5fb3BzKCl2b2lkIgogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMAogICAgbWF0Y2ggX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2l0eG5fb3BzX3JvdXRlQDIKICAgIGludGNfMSAvLyAwCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9pdHhuX29wc19yb3V0ZUAyOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjQ3MAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgbm90IE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gY2FuIG9ubHkgY2FsbCB3aGVuIG5vdCBjcmVhdGluZwogICAgY2FsbHN1YiB2ZXJpZnlfaXR4bl9vcHMKICAgIGludGNfMCAvLyAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX2JhcmVfcm91dGluZ0A1OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjQ2OQogICAgLy8gZXhwb3J0IGNsYXNzIElUeG5PcHNDb250cmFjdCBleHRlbmRzIGFyYzQuQ29udHJhY3QgewogICAgdHhuIE9uQ29tcGxldGlvbgogICAgYm56IF9fcHV5YV9hcmM0X3JvdXRlcl9fX2FmdGVyX2lmX2Vsc2VAOQogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgICEKICAgIGFzc2VydCAvLyBjYW4gb25seSBjYWxsIHdoZW4gY3JlYXRpbmcKICAgIGludGNfMCAvLyAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX2FmdGVyX2lmX2Vsc2VAOToKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo0NjkKICAgIC8vIGV4cG9ydCBjbGFzcyBJVHhuT3BzQ29udHJhY3QgZXh0ZW5kcyBhcmM0LkNvbnRyYWN0IHsKICAgIGludGNfMSAvLyAwCiAgICByZXRzdWIKCgovLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OklUeG5PcHNDb250cmFjdC52ZXJpZnlfaXR4bl9vcHMoKSAtPiB2b2lkOgp2ZXJpZnlfaXR4bl9vcHM6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NDcwLTQ3MQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIHB1YmxpYyB2ZXJpZnlfaXR4bl9vcHMoKSB7CiAgICBwcm90byAwIDAKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo0NzIKICAgIC8vIG9wLklUeG5DcmVhdGUuYmVnaW4oKQogICAgaXR4bl9iZWdpbgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjQ3MwogICAgLy8gb3AuSVR4bkNyZWF0ZS5zZXRUeXBlRW51bShUcmFuc2FjdGlvblR5cGUuQXBwbGljYXRpb25DYWxsKQogICAgaW50Y18yIC8vIDYKICAgIGl0eG5fZmllbGQgVHlwZUVudW0KICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo0NzQKICAgIC8vIG9wLklUeG5DcmVhdGUuc2V0T25Db21wbGV0aW9uKGFyYzQuT25Db21wbGV0ZUFjdGlvbi5EZWxldGVBcHBsaWNhdGlvbikKICAgIHB1c2hpbnQgNSAvLyA1CiAgICBpdHhuX2ZpZWxkIE9uQ29tcGxldGlvbgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjQ3NQogICAgLy8gb3AuSVR4bkNyZWF0ZS5zZXRBcHByb3ZhbFByb2dyYW0oQnl0ZXMuZnJvbUhleCgnMDY4MTAxJykpCiAgICBieXRlY18wIC8vIDB4MDY4MTAxCiAgICBpdHhuX2ZpZWxkIEFwcHJvdmFsUHJvZ3JhbQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjQ3OAogICAgLy8gb3AuSVR4bkNyZWF0ZS5zZXRBcHByb3ZhbFByb2dyYW1QYWdlcyhCeXRlcy5mcm9tSGV4KCcwNjgxMDEnKSkKICAgIGJ5dGVjXzAgLy8gMHgwNjgxMDEKICAgIGl0eG5fZmllbGQgQXBwcm92YWxQcm9ncmFtUGFnZXMKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo0NzkKICAgIC8vIG9wLklUeG5DcmVhdGUuc2V0Q2xlYXJTdGF0ZVByb2dyYW0oQnl0ZXMuZnJvbUhleCgnMDY4MTAxJykpCiAgICBieXRlY18wIC8vIDB4MDY4MTAxCiAgICBpdHhuX2ZpZWxkIENsZWFyU3RhdGVQcm9ncmFtCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NDgwCiAgICAvLyBvcC5JVHhuQ3JlYXRlLnNldEZlZShvcC5HbG9iYWwubWluVHhuRmVlKQogICAgZ2xvYmFsIE1pblR4bkZlZQogICAgaXR4bl9maWVsZCBGZWUKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo0ODEKICAgIC8vIG9wLklUeG5DcmVhdGUubmV4dCgpCiAgICBpdHhuX25leHQKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo0ODIKICAgIC8vIG9wLklUeG5DcmVhdGUuc2V0VHlwZUVudW0oVHJhbnNhY3Rpb25UeXBlLlBheW1lbnQpCiAgICBpbnRjXzAgLy8gMQogICAgaXR4bl9maWVsZCBUeXBlRW51bQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjQ4MwogICAgLy8gb3AuSVR4bkNyZWF0ZS5zZXRSZWNlaXZlcihvcC5HbG9iYWwuY3JlYXRvckFkZHJlc3MpCiAgICBnbG9iYWwgQ3JlYXRvckFkZHJlc3MKICAgIGl0eG5fZmllbGQgUmVjZWl2ZXIKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo0ODQKICAgIC8vIG9wLklUeG5DcmVhdGUuc2V0QW1vdW50KFVpbnQ2NCgxMDAwKSkKICAgIGludGNfMyAvLyAxMDAwCiAgICBpdHhuX2ZpZWxkIEFtb3VudAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjQ4NQogICAgLy8gb3AuSVR4bkNyZWF0ZS5zdWJtaXQoKQogICAgaXR4bl9zdWJtaXQKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo0ODcKICAgIC8vIGFzc2VydChvcC5JVHhuLnJlY2VpdmVyID09PSBvcC5HbG9iYWwuY3JlYXRvckFkZHJlc3MpCiAgICBpdHhuIFJlY2VpdmVyCiAgICBnbG9iYWwgQ3JlYXRvckFkZHJlc3MKICAgID09CiAgICBhc3NlcnQKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo0ODgKICAgIC8vIGFzc2VydChvcC5JVHhuLmFtb3VudCA9PT0gVWludDY0KDEwMDApKQogICAgaXR4biBBbW91bnQKICAgIGludGNfMyAvLyAxMDAwCiAgICA9PQogICAgYXNzZXJ0CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NDg5CiAgICAvLyBhc3NlcnQob3AuSVR4bi50eXBlRW51bSA9PT0gVHJhbnNhY3Rpb25UeXBlLlBheW1lbnQpCiAgICBpdHhuIFR5cGVFbnVtCiAgICBpbnRjXzAgLy8gMQogICAgPT0KICAgIGFzc2VydAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjQ5MQogICAgLy8gYXNzZXJ0KG9wLkdJVHhuLnR5cGVFbnVtKDApID09PSBUcmFuc2FjdGlvblR5cGUuQXBwbGljYXRpb25DYWxsKQogICAgZ2l0eG4gMCBUeXBlRW51bQogICAgaW50Y18yIC8vIDYKICAgID09CiAgICBhc3NlcnQKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo0OTIKICAgIC8vIGFzc2VydChvcC5HSVR4bi50eXBlRW51bSgxKSA9PT0gVHJhbnNhY3Rpb25UeXBlLlBheW1lbnQpCiAgICBnaXR4biAxIFR5cGVFbnVtCiAgICBpbnRjXzAgLy8gMQogICAgPT0KICAgIGFzc2VydAogICAgcmV0c3ViCg==", - "clear": "I3ByYWdtYSB2ZXJzaW9uIDEwCgp0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OklUeG5PcHNDb250cmFjdC5jbGVhclN0YXRlUHJvZ3JhbToKICAgIHB1c2hpbnQgMSAvLyAxCiAgICByZXR1cm4K" - }, - "state": { - "global": { - "num_byte_slices": 0, - "num_uints": 0 - }, - "local": { - "num_byte_slices": 0, - "num_uints": 0 - } - }, - "schema": { - "global": { - "declared": {}, - "reserved": {} - }, - "local": { - "declared": {}, - "reserved": {} - } - }, - "contract": { - "name": "ITxnOpsContract", - "methods": [ - { - "name": "verify_itxn_ops", - "args": [], - "readonly": false, - "returns": { - "type": "void" - } - } - ], - "networks": {} - }, - "bare_call_config": { - "no_op": "CREATE" - } -} \ No newline at end of file diff --git a/tests/artifacts/state-ops/data/ITxnOpsContract.arc56.json b/tests/artifacts/state-ops/data/ITxnOpsContract.arc56.json deleted file mode 100644 index 185eb45..0000000 --- a/tests/artifacts/state-ops/data/ITxnOpsContract.arc56.json +++ /dev/null @@ -1,90 +0,0 @@ -{ - "name": "ITxnOpsContract", - "structs": {}, - "methods": [ - { - "name": "verify_itxn_ops", - "args": [], - "returns": { - "type": "void" - }, - "actions": { - "create": [], - "call": [ - "NoOp" - ] - }, - "readonly": false, - "events": [], - "recommendations": {} - } - ], - "arcs": [ - 22, - 28 - ], - "networks": {}, - "state": { - "schema": { - "global": { - "ints": 0, - "bytes": 0 - }, - "local": { - "ints": 0, - "bytes": 0 - } - }, - "keys": { - "global": {}, - "local": {}, - "box": {} - }, - "maps": { - "global": {}, - "local": {}, - "box": {} - } - }, - "bareActions": { - "create": [ - "NoOp" - ], - "call": [] - }, - "sourceInfo": { - "approval": { - "sourceInfo": [ - { - "pc": [ - 44 - ], - "errorMessage": "OnCompletion is not NoOp" - }, - { - "pc": [ - 61 - ], - "errorMessage": "can only call when creating" - }, - { - "pc": [ - 47 - ], - "errorMessage": "can only call when not creating" - } - ], - "pcOffsetMethod": "none" - }, - "clear": { - "sourceInfo": [], - "pcOffsetMethod": "none" - } - }, - "source": { - "approval": "I3ByYWdtYSB2ZXJzaW9uIDEwCgp0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OklUeG5PcHNDb250cmFjdC5hcHByb3ZhbFByb2dyYW06CiAgICBpbnRjYmxvY2sgMSAwIDYgMTAwMAogICAgYnl0ZWNibG9jayAweDA2ODEwMQogICAgY2FsbHN1YiBfX3B1eWFfYXJjNF9yb3V0ZXJfXwogICAgcmV0dXJuCgoKLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjpJVHhuT3BzQ29udHJhY3QuX19wdXlhX2FyYzRfcm91dGVyX18oKSAtPiB1aW50NjQ6Cl9fcHV5YV9hcmM0X3JvdXRlcl9fOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjQ2OQogICAgLy8gZXhwb3J0IGNsYXNzIElUeG5PcHNDb250cmFjdCBleHRlbmRzIGFyYzQuQ29udHJhY3QgewogICAgcHJvdG8gMCAxCiAgICB0eG4gTnVtQXBwQXJncwogICAgYnogX19wdXlhX2FyYzRfcm91dGVyX19fYmFyZV9yb3V0aW5nQDUKICAgIHB1c2hieXRlcyAweDRlN2NkOWNiIC8vIG1ldGhvZCAidmVyaWZ5X2l0eG5fb3BzKCl2b2lkIgogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMAogICAgbWF0Y2ggX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2l0eG5fb3BzX3JvdXRlQDIKICAgIGludGNfMSAvLyAwCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9pdHhuX29wc19yb3V0ZUAyOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjQ3MAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgbm90IE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gY2FuIG9ubHkgY2FsbCB3aGVuIG5vdCBjcmVhdGluZwogICAgY2FsbHN1YiB2ZXJpZnlfaXR4bl9vcHMKICAgIGludGNfMCAvLyAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX2JhcmVfcm91dGluZ0A1OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjQ2OQogICAgLy8gZXhwb3J0IGNsYXNzIElUeG5PcHNDb250cmFjdCBleHRlbmRzIGFyYzQuQ29udHJhY3QgewogICAgdHhuIE9uQ29tcGxldGlvbgogICAgYm56IF9fcHV5YV9hcmM0X3JvdXRlcl9fX2FmdGVyX2lmX2Vsc2VAOQogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgICEKICAgIGFzc2VydCAvLyBjYW4gb25seSBjYWxsIHdoZW4gY3JlYXRpbmcKICAgIGludGNfMCAvLyAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX2FmdGVyX2lmX2Vsc2VAOToKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo0NjkKICAgIC8vIGV4cG9ydCBjbGFzcyBJVHhuT3BzQ29udHJhY3QgZXh0ZW5kcyBhcmM0LkNvbnRyYWN0IHsKICAgIGludGNfMSAvLyAwCiAgICByZXRzdWIKCgovLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OklUeG5PcHNDb250cmFjdC52ZXJpZnlfaXR4bl9vcHMoKSAtPiB2b2lkOgp2ZXJpZnlfaXR4bl9vcHM6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NDcwLTQ3MQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIHB1YmxpYyB2ZXJpZnlfaXR4bl9vcHMoKSB7CiAgICBwcm90byAwIDAKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo0NzIKICAgIC8vIG9wLklUeG5DcmVhdGUuYmVnaW4oKQogICAgaXR4bl9iZWdpbgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjQ3MwogICAgLy8gb3AuSVR4bkNyZWF0ZS5zZXRUeXBlRW51bShUcmFuc2FjdGlvblR5cGUuQXBwbGljYXRpb25DYWxsKQogICAgaW50Y18yIC8vIDYKICAgIGl0eG5fZmllbGQgVHlwZUVudW0KICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo0NzQKICAgIC8vIG9wLklUeG5DcmVhdGUuc2V0T25Db21wbGV0aW9uKGFyYzQuT25Db21wbGV0ZUFjdGlvbi5EZWxldGVBcHBsaWNhdGlvbikKICAgIHB1c2hpbnQgNSAvLyA1CiAgICBpdHhuX2ZpZWxkIE9uQ29tcGxldGlvbgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjQ3NQogICAgLy8gb3AuSVR4bkNyZWF0ZS5zZXRBcHByb3ZhbFByb2dyYW0oQnl0ZXMuZnJvbUhleCgnMDY4MTAxJykpCiAgICBieXRlY18wIC8vIDB4MDY4MTAxCiAgICBpdHhuX2ZpZWxkIEFwcHJvdmFsUHJvZ3JhbQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjQ3OAogICAgLy8gb3AuSVR4bkNyZWF0ZS5zZXRBcHByb3ZhbFByb2dyYW1QYWdlcyhCeXRlcy5mcm9tSGV4KCcwNjgxMDEnKSkKICAgIGJ5dGVjXzAgLy8gMHgwNjgxMDEKICAgIGl0eG5fZmllbGQgQXBwcm92YWxQcm9ncmFtUGFnZXMKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo0NzkKICAgIC8vIG9wLklUeG5DcmVhdGUuc2V0Q2xlYXJTdGF0ZVByb2dyYW0oQnl0ZXMuZnJvbUhleCgnMDY4MTAxJykpCiAgICBieXRlY18wIC8vIDB4MDY4MTAxCiAgICBpdHhuX2ZpZWxkIENsZWFyU3RhdGVQcm9ncmFtCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NDgwCiAgICAvLyBvcC5JVHhuQ3JlYXRlLnNldEZlZShvcC5HbG9iYWwubWluVHhuRmVlKQogICAgZ2xvYmFsIE1pblR4bkZlZQogICAgaXR4bl9maWVsZCBGZWUKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo0ODEKICAgIC8vIG9wLklUeG5DcmVhdGUubmV4dCgpCiAgICBpdHhuX25leHQKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo0ODIKICAgIC8vIG9wLklUeG5DcmVhdGUuc2V0VHlwZUVudW0oVHJhbnNhY3Rpb25UeXBlLlBheW1lbnQpCiAgICBpbnRjXzAgLy8gMQogICAgaXR4bl9maWVsZCBUeXBlRW51bQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjQ4MwogICAgLy8gb3AuSVR4bkNyZWF0ZS5zZXRSZWNlaXZlcihvcC5HbG9iYWwuY3JlYXRvckFkZHJlc3MpCiAgICBnbG9iYWwgQ3JlYXRvckFkZHJlc3MKICAgIGl0eG5fZmllbGQgUmVjZWl2ZXIKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo0ODQKICAgIC8vIG9wLklUeG5DcmVhdGUuc2V0QW1vdW50KFVpbnQ2NCgxMDAwKSkKICAgIGludGNfMyAvLyAxMDAwCiAgICBpdHhuX2ZpZWxkIEFtb3VudAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjQ4NQogICAgLy8gb3AuSVR4bkNyZWF0ZS5zdWJtaXQoKQogICAgaXR4bl9zdWJtaXQKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo0ODcKICAgIC8vIGFzc2VydChvcC5JVHhuLnJlY2VpdmVyID09PSBvcC5HbG9iYWwuY3JlYXRvckFkZHJlc3MpCiAgICBpdHhuIFJlY2VpdmVyCiAgICBnbG9iYWwgQ3JlYXRvckFkZHJlc3MKICAgID09CiAgICBhc3NlcnQKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo0ODgKICAgIC8vIGFzc2VydChvcC5JVHhuLmFtb3VudCA9PT0gVWludDY0KDEwMDApKQogICAgaXR4biBBbW91bnQKICAgIGludGNfMyAvLyAxMDAwCiAgICA9PQogICAgYXNzZXJ0CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NDg5CiAgICAvLyBhc3NlcnQob3AuSVR4bi50eXBlRW51bSA9PT0gVHJhbnNhY3Rpb25UeXBlLlBheW1lbnQpCiAgICBpdHhuIFR5cGVFbnVtCiAgICBpbnRjXzAgLy8gMQogICAgPT0KICAgIGFzc2VydAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjQ5MQogICAgLy8gYXNzZXJ0KG9wLkdJVHhuLnR5cGVFbnVtKDApID09PSBUcmFuc2FjdGlvblR5cGUuQXBwbGljYXRpb25DYWxsKQogICAgZ2l0eG4gMCBUeXBlRW51bQogICAgaW50Y18yIC8vIDYKICAgID09CiAgICBhc3NlcnQKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo0OTIKICAgIC8vIGFzc2VydChvcC5HSVR4bi50eXBlRW51bSgxKSA9PT0gVHJhbnNhY3Rpb25UeXBlLlBheW1lbnQpCiAgICBnaXR4biAxIFR5cGVFbnVtCiAgICBpbnRjXzAgLy8gMQogICAgPT0KICAgIGFzc2VydAogICAgcmV0c3ViCg==", - "clear": "I3ByYWdtYSB2ZXJzaW9uIDEwCgp0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OklUeG5PcHNDb250cmFjdC5jbGVhclN0YXRlUHJvZ3JhbToKICAgIHB1c2hpbnQgMSAvLyAxCiAgICByZXR1cm4K" - }, - "events": [], - "templateVariables": {} -} \ No newline at end of file diff --git a/tests/artifacts/state-ops/data/ITxnOpsContract.clear.teal b/tests/artifacts/state-ops/data/ITxnOpsContract.clear.teal deleted file mode 100644 index b00b7bf..0000000 --- a/tests/artifacts/state-ops/data/ITxnOpsContract.clear.teal +++ /dev/null @@ -1,5 +0,0 @@ -#pragma version 10 - -tests/artifacts/state-ops/contract.algo.ts::ITxnOpsContract.clearStateProgram: - pushint 1 // 1 - return diff --git a/tests/artifacts/state-ops/data/ItxnDemoContract.approval.teal b/tests/artifacts/state-ops/data/ItxnDemoContract.approval.teal deleted file mode 100644 index a844d3a..0000000 --- a/tests/artifacts/state-ops/data/ItxnDemoContract.approval.teal +++ /dev/null @@ -1,485 +0,0 @@ -#pragma version 10 - -tests/artifacts/state-ops/contract.algo.ts::ItxnDemoContract.approvalProgram: - intcblock 0 3 1 1000 - bytecblock "name" "unit" 0x098101 "AST1" "AST2" "AST3" "3rd" "with args param set" "\t\xc2\x81\x01" - txn ApplicationID - bnz main_after_if_else@2 - callsub constructor - -main_after_if_else@2: - // tests/artifacts/state-ops/contract.algo.ts:501 - // if (Txn.numAppArgs) { - txn NumAppArgs - bz main_after_if_else@15 - // tests/artifacts/state-ops/contract.algo.ts:502 - // switch (Txn.applicationArgs(0)) { - intc_0 // 0 - txnas ApplicationArgs - // tests/artifacts/state-ops/contract.algo.ts:503 - // case Bytes('test1'): - pushbytess "test1" "test2" "test3" "test4" // "test1", "test2", "test3", "test4" - // tests/artifacts/state-ops/contract.algo.ts:502-512 - // switch (Txn.applicationArgs(0)) { - // case Bytes('test1'): - // this.test1() - // break - // case Bytes('test2'): - // this.test2() - // break - // case Bytes('test3'): - // case Bytes('test4'): - // break - // } - uncover 4 - match main_switch_case_0@4 main_switch_case_1@6 main_after_if_else@15 main_after_if_else@15 - // tests/artifacts/state-ops/contract.algo.ts:514 - // return true - intc_2 // 1 - return - -main_switch_case_0@4: - // tests/artifacts/state-ops/contract.algo.ts:504 - // this.test1() - callsub test1 - // tests/artifacts/state-ops/contract.algo.ts:505 - // break - b main_after_if_else@15 - -main_switch_case_1@6: - // tests/artifacts/state-ops/contract.algo.ts:507 - // this.test2() - callsub test2 - -main_after_if_else@15: - // tests/artifacts/state-ops/contract.algo.ts:514 - // return true - intc_2 // 1 - return - - -// tests/artifacts/state-ops/contract.algo.ts::ItxnDemoContract.constructor() -> void: -constructor: - // tests/artifacts/state-ops/contract.algo.ts:497 - // export class ItxnDemoContract extends BaseContract { - proto 0 0 - // tests/artifacts/state-ops/contract.algo.ts:498 - // name = GlobalState({ initialValue: Bytes() }) - bytec_0 // "name" - pushbytes 0x - app_global_put - retsub - - -// tests/artifacts/state-ops/contract.algo.ts::ItxnDemoContract.test1() -> void: -test1: - // tests/artifacts/state-ops/contract.algo.ts:517 - // private test1() { - proto 0 0 - // tests/artifacts/state-ops/contract.algo.ts:498 - // name = GlobalState({ initialValue: Bytes() }) - bytec_0 // "name" - // tests/artifacts/state-ops/contract.algo.ts:518 - // this.name.value = Bytes('AST1') - bytec_3 // "AST1" - app_global_put - // tests/artifacts/state-ops/contract.algo.ts:522 - // assetName: this.name.value, - intc_0 // 0 - // tests/artifacts/state-ops/contract.algo.ts:498 - // name = GlobalState({ initialValue: Bytes() }) - bytec_0 // "name" - // tests/artifacts/state-ops/contract.algo.ts:522 - // assetName: this.name.value, - app_global_get_ex - assert // check GlobalState exists - // tests/artifacts/state-ops/contract.algo.ts:525 - // manager: Global.currentApplicationAddress, - global CurrentApplicationAddress - // tests/artifacts/state-ops/contract.algo.ts:526 - // reserve: Global.currentApplicationAddress, - dup - // tests/artifacts/state-ops/contract.algo.ts:498 - // name = GlobalState({ initialValue: Bytes() }) - bytec_0 // "name" - // tests/artifacts/state-ops/contract.algo.ts:529 - // this.name.value = Bytes('AST2') - bytec 4 // "AST2" - app_global_put - // tests/artifacts/state-ops/contract.algo.ts:530 - // const asset1_txn = assetParams.submit() - itxn_begin - dup - itxn_field ConfigAssetReserve - dig 1 - itxn_field ConfigAssetManager - // tests/artifacts/state-ops/contract.algo.ts:524 - // decimals: 3, - intc_1 // 3 - itxn_field ConfigAssetDecimals - // tests/artifacts/state-ops/contract.algo.ts:523 - // unitName: 'unit', - bytec_1 // "unit" - itxn_field ConfigAssetUnitName - uncover 2 - itxn_field ConfigAssetName - // tests/artifacts/state-ops/contract.algo.ts:521 - // total: 1000, - intc_3 // 1000 - itxn_field ConfigAssetTotal - // tests/artifacts/state-ops/contract.algo.ts:520-527 - // const assetParams = itxn.assetConfig({ - // total: 1000, - // assetName: this.name.value, - // unitName: 'unit', - // decimals: 3, - // manager: Global.currentApplicationAddress, - // reserve: Global.currentApplicationAddress, - // }) - intc_1 // 3 - itxn_field TypeEnum - intc_0 // 0 - itxn_field Fee - // tests/artifacts/state-ops/contract.algo.ts:530 - // const asset1_txn = assetParams.submit() - itxn_submit - itxn ConfigAssetName - itxn CreatedAssetID - // tests/artifacts/state-ops/contract.algo.ts:532 - // assetName: this.name.value, - intc_0 // 0 - // tests/artifacts/state-ops/contract.algo.ts:498 - // name = GlobalState({ initialValue: Bytes() }) - bytec_0 // "name" - // tests/artifacts/state-ops/contract.algo.ts:532 - // assetName: this.name.value, - app_global_get_ex - assert // check GlobalState exists - // tests/artifacts/state-ops/contract.algo.ts:534 - // const asset2_txn = assetParams.submit() - itxn_begin - dig 3 - itxn_field ConfigAssetReserve - dig 4 - itxn_field ConfigAssetManager - // tests/artifacts/state-ops/contract.algo.ts:524 - // decimals: 3, - intc_1 // 3 - itxn_field ConfigAssetDecimals - // tests/artifacts/state-ops/contract.algo.ts:523 - // unitName: 'unit', - bytec_1 // "unit" - itxn_field ConfigAssetUnitName - itxn_field ConfigAssetName - // tests/artifacts/state-ops/contract.algo.ts:521 - // total: 1000, - intc_3 // 1000 - itxn_field ConfigAssetTotal - // tests/artifacts/state-ops/contract.algo.ts:520-527 - // const assetParams = itxn.assetConfig({ - // total: 1000, - // assetName: this.name.value, - // unitName: 'unit', - // decimals: 3, - // manager: Global.currentApplicationAddress, - // reserve: Global.currentApplicationAddress, - // }) - intc_1 // 3 - itxn_field TypeEnum - intc_0 // 0 - itxn_field Fee - // tests/artifacts/state-ops/contract.algo.ts:534 - // const asset2_txn = assetParams.submit() - itxn_submit - itxn ConfigAssetName - itxn CreatedAssetID - // tests/artifacts/state-ops/contract.algo.ts:536 - // assert(asset1_txn.assetName === Bytes('AST1'), 'asset1_txn is correct') - uncover 3 - bytec_3 // "AST1" - == - assert // asset1_txn is correct - // tests/artifacts/state-ops/contract.algo.ts:537 - // assert(asset2_txn.assetName === Bytes('AST2'), 'asset2_txn is correct') - swap - bytec 4 // "AST2" - == - assert // asset2_txn is correct - // tests/artifacts/state-ops/contract.algo.ts:538 - // assert(asset1_txn.createdAsset.name === Bytes('AST1'), 'created asset 1 is correct') - swap - asset_params_get AssetName - assert // asset exists - bytec_3 // "AST1" - == - assert // created asset 1 is correct - // tests/artifacts/state-ops/contract.algo.ts:539 - // assert(asset2_txn.createdAsset.name === Bytes('AST2'), 'created asset 2 is correct') - asset_params_get AssetName - assert // asset exists - bytec 4 // "AST2" - == - assert // created asset 2 is correct - // tests/artifacts/state-ops/contract.algo.ts:551 - // const [appCreateTxn, asset3_txn] = itxn.submitGroup(appCreateParams, assetParams) - itxn_begin - // tests/artifacts/state-ops/contract.algo.ts:543 - // clearStateProgram: Bytes.fromHex('098101'), - bytec_2 // 0x098101 - itxn_field ClearStateProgramPages - // tests/artifacts/state-ops/contract.algo.ts:542 - // approvalProgram: Bytes.fromHex('098101'), - bytec_2 // 0x098101 - itxn_field ApprovalProgramPages - // tests/artifacts/state-ops/contract.algo.ts:541-545 - // const appCreateParams = itxn.applicationCall({ - // approvalProgram: Bytes.fromHex('098101'), - // clearStateProgram: Bytes.fromHex('098101'), - // fee: 0, - // }) - pushint 6 // 6 - itxn_field TypeEnum - // tests/artifacts/state-ops/contract.algo.ts:544 - // fee: 0, - intc_0 // 0 - itxn_field Fee - // tests/artifacts/state-ops/contract.algo.ts:551 - // const [appCreateTxn, asset3_txn] = itxn.submitGroup(appCreateParams, assetParams) - itxn_next - dup - itxn_field ConfigAssetReserve - dig 1 - itxn_field ConfigAssetManager - // tests/artifacts/state-ops/contract.algo.ts:524 - // decimals: 3, - intc_1 // 3 - itxn_field ConfigAssetDecimals - // tests/artifacts/state-ops/contract.algo.ts:523 - // unitName: 'unit', - bytec_1 // "unit" - itxn_field ConfigAssetUnitName - // tests/artifacts/state-ops/contract.algo.ts:548 - // assetName: 'AST3', - bytec 5 // "AST3" - itxn_field ConfigAssetName - // tests/artifacts/state-ops/contract.algo.ts:521 - // total: 1000, - intc_3 // 1000 - itxn_field ConfigAssetTotal - // tests/artifacts/state-ops/contract.algo.ts:520-527 - // const assetParams = itxn.assetConfig({ - // total: 1000, - // assetName: this.name.value, - // unitName: 'unit', - // decimals: 3, - // manager: Global.currentApplicationAddress, - // reserve: Global.currentApplicationAddress, - // }) - intc_1 // 3 - itxn_field TypeEnum - intc_0 // 0 - itxn_field Fee - // tests/artifacts/state-ops/contract.algo.ts:551 - // const [appCreateTxn, asset3_txn] = itxn.submitGroup(appCreateParams, assetParams) - itxn_submit - itxn ConfigAssetName - gitxn 0 ApplicationID - // tests/artifacts/state-ops/contract.algo.ts:553 - // assert(appCreateTxn.appId, 'app is created') - assert // app is created - // tests/artifacts/state-ops/contract.algo.ts:554 - // assert(asset3_txn.assetName === Bytes('AST3'), 'asset3_txn is correct') - bytec 5 // "AST3" - == - assert // asset3_txn is correct - // tests/artifacts/state-ops/contract.algo.ts:562 - // itxn.submitGroup(appCreateParams, assetParams) - itxn_begin - // tests/artifacts/state-ops/contract.algo.ts:557 - // note: '3rd', - bytec 6 // "3rd" - itxn_field Note - // tests/artifacts/state-ops/contract.algo.ts:543 - // clearStateProgram: Bytes.fromHex('098101'), - bytec_2 // 0x098101 - itxn_field ClearStateProgramPages - // tests/artifacts/state-ops/contract.algo.ts:542 - // approvalProgram: Bytes.fromHex('098101'), - bytec_2 // 0x098101 - itxn_field ApprovalProgramPages - // tests/artifacts/state-ops/contract.algo.ts:541-545 - // const appCreateParams = itxn.applicationCall({ - // approvalProgram: Bytes.fromHex('098101'), - // clearStateProgram: Bytes.fromHex('098101'), - // fee: 0, - // }) - pushint 6 // 6 - itxn_field TypeEnum - // tests/artifacts/state-ops/contract.algo.ts:544 - // fee: 0, - intc_0 // 0 - itxn_field Fee - // tests/artifacts/state-ops/contract.algo.ts:562 - // itxn.submitGroup(appCreateParams, assetParams) - itxn_next - // tests/artifacts/state-ops/contract.algo.ts:560 - // note: '3rd', - bytec 6 // "3rd" - itxn_field Note - itxn_field ConfigAssetReserve - itxn_field ConfigAssetManager - // tests/artifacts/state-ops/contract.algo.ts:524 - // decimals: 3, - intc_1 // 3 - itxn_field ConfigAssetDecimals - // tests/artifacts/state-ops/contract.algo.ts:523 - // unitName: 'unit', - bytec_1 // "unit" - itxn_field ConfigAssetUnitName - // tests/artifacts/state-ops/contract.algo.ts:548 - // assetName: 'AST3', - bytec 5 // "AST3" - itxn_field ConfigAssetName - // tests/artifacts/state-ops/contract.algo.ts:521 - // total: 1000, - intc_3 // 1000 - itxn_field ConfigAssetTotal - // tests/artifacts/state-ops/contract.algo.ts:520-527 - // const assetParams = itxn.assetConfig({ - // total: 1000, - // assetName: this.name.value, - // unitName: 'unit', - // decimals: 3, - // manager: Global.currentApplicationAddress, - // reserve: Global.currentApplicationAddress, - // }) - intc_1 // 3 - itxn_field TypeEnum - intc_0 // 0 - itxn_field Fee - // tests/artifacts/state-ops/contract.algo.ts:562 - // itxn.submitGroup(appCreateParams, assetParams) - itxn_submit - retsub - - -// tests/artifacts/state-ops/contract.algo.ts::ItxnDemoContract.test2() -> void: -test2: - // tests/artifacts/state-ops/contract.algo.ts:565 - // private test2() { - proto 0 0 - intc_0 // 0 - dupn 2 - pushbytes "" - dupn 2 - // tests/artifacts/state-ops/contract.algo.ts:567 - // if (Txn.numAppArgs) { - txn NumAppArgs - bz test2_else_body@2 - // tests/artifacts/state-ops/contract.algo.ts:568 - // const args = [Bytes('1'), Bytes('2')] as const - pushbytes "1" - frame_bury 0 - pushbytes "2" - frame_bury 1 - // tests/artifacts/state-ops/contract.algo.ts:572 - // appArgs: args, - pushint 2 // 2 - frame_bury 3 - // tests/artifacts/state-ops/contract.algo.ts:573 - // onCompletion: arc4.OnCompleteAction.NoOp, - intc_0 // 0 - frame_bury 5 - intc_2 // 1 - frame_bury 4 - // tests/artifacts/state-ops/contract.algo.ts:574 - // note: 'with args param set', - bytec 7 // "with args param set" - b test2_after_if_else@3 - -test2_else_body@2: - // tests/artifacts/state-ops/contract.algo.ts:580 - // appArgs: [Bytes('3'), '4', Bytes('5')], - pushbytes "3" - frame_bury 0 - pushbytes "4" - frame_bury 1 - pushbytes "5" - frame_bury 2 - intc_1 // 3 - frame_bury 3 - // tests/artifacts/state-ops/contract.algo.ts:581 - // note: 'no args param set', - pushbytes "no args param set" - // tests/artifacts/state-ops/contract.algo.ts:577 - // createAppParams = itxn.applicationCall({ - intc_0 // 0 - frame_bury 4 - -test2_after_if_else@3: - // tests/artifacts/state-ops/contract.algo.ts:584 - // const createAppTxn = createAppParams.submit() - itxn_begin - itxn_field Note - frame_dig 4 - intc_2 // 1 - >= - bz test2_next_field@5 - frame_dig 5 - itxn_field OnCompletion - -test2_next_field@5: - frame_dig 0 - itxn_field ApplicationArgs - frame_dig 1 - itxn_field ApplicationArgs - frame_dig 3 - intc_1 // 3 - >= - // tests/artifacts/state-ops/contract.algo.ts:584 - // const createAppTxn = createAppParams.submit() - bz test2_next_field@7 - frame_dig 2 - itxn_field ApplicationArgs - -test2_next_field@7: - // tests/artifacts/state-ops/contract.algo.ts:496 - // const APPROVE = Bytes('\x09\x81\x01') - bytec 8 // "\t\xc2\x81\x01" - itxn_field ClearStateProgramPages - bytec 8 // "\t\xc2\x81\x01" - itxn_field ApprovalProgramPages - // tests/artifacts/state-ops/contract.algo.ts:569-575 - // createAppParams = itxn.applicationCall({ - // approvalProgram: APPROVE, - // clearStateProgram: APPROVE, - // appArgs: args, - // onCompletion: arc4.OnCompleteAction.NoOp, - // note: 'with args param set', - // }) - pushint 6 // 6 - itxn_field TypeEnum - intc_0 // 0 - itxn_field Fee - // tests/artifacts/state-ops/contract.algo.ts:584 - // const createAppTxn = createAppParams.submit() - itxn_submit - itxn Note - // tests/artifacts/state-ops/contract.algo.ts:585 - // assert(createAppTxn.appArgs(0) === Bytes('1'), 'correct args used 1') - itxna ApplicationArgs 0 - pushbytes "1" - == - assert // correct args used 1 - // tests/artifacts/state-ops/contract.algo.ts:586 - // assert(createAppTxn.appArgs(1) === Bytes('2'), 'correct args used 2') - itxna ApplicationArgs 1 - pushbytes "2" - == - assert // correct args used 2 - // tests/artifacts/state-ops/contract.algo.ts:587 - // assert(createAppTxn.note === Bytes('with args param set')) - bytec 7 // "with args param set" - == - assert - retsub diff --git a/tests/artifacts/state-ops/data/ItxnDemoContract.clear.teal b/tests/artifacts/state-ops/data/ItxnDemoContract.clear.teal deleted file mode 100644 index d7fd8f9..0000000 --- a/tests/artifacts/state-ops/data/ItxnDemoContract.clear.teal +++ /dev/null @@ -1,5 +0,0 @@ -#pragma version 10 - -tests/artifacts/state-ops/contract.algo.ts::ItxnDemoContract.clearStateProgram: - pushint 1 // 1 - return diff --git a/tests/artifacts/state-ops/data/LocalStateContract.approval.teal b/tests/artifacts/state-ops/data/LocalStateContract.approval.teal deleted file mode 100644 index 625363e..0000000 --- a/tests/artifacts/state-ops/data/LocalStateContract.approval.teal +++ /dev/null @@ -1,802 +0,0 @@ -#pragma version 10 - -tests/artifacts/state-ops/contract.algo.ts::LocalStateContract.approvalProgram: - intcblock 1 0 - bytecblock 0x151f7c75 "implicitKeyArc4UintN64" 0x0000000000000539 "implicitKeyArc4Str" 0x000548656c6c6f "implicitKeyArc4Byte" "implicitKeyArc4Bool" "implicitKeyArc4Address" "implicitKeyArc4UintN128" 0x00000010000000000000000000000000 "implicitKeyArc4DynamicBytes" 0x000d64796e616d6963206279746573 "explicit_key_arc4_uintn64" "explicit_key_arc4_str" "explicit_key_arc4_byte" "explicit_key_arc4_bool" "explicit_key_arc4_address" "explicit_key_arc4_uintn128" "explicit_key_arc4_dynamic_bytes" - callsub __puya_arc4_router__ - return - - -// tests/artifacts/state-ops/contract.algo.ts::LocalStateContract.__puya_arc4_router__() -> uint64: -__puya_arc4_router__: - // tests/artifacts/state-ops/contract.algo.ts:755 - // export class LocalStateContract extends arc4.Contract { - proto 0 1 - txn NumAppArgs - bz __puya_arc4_router___bare_routing@19 - pushbytess 0x30c6d58a 0xeecdf0a0 0x6c6f17da 0xecf633b0 0x3e531223 0x3ed6799d 0x6fecdd80 0x676a87c2 0x1e0f8951 0x42e85fd7 0x6521d49b 0xe07c56cd 0xaa19d2b5 0xb922312d 0xfc0feed9 // method "opt_in()void", method "get_implicit_key_arc4_uintn64(account)uint64", method "get_implicit_key_arc4_str(account)string", method "get_implicit_key_arc4_byte(account)byte", method "get_implicit_key_arc4_bool(account)bool", method "get_implicit_key_arc4_address(account)address", method "get_implicit_key_arc4_uintn128(account)uint128", method "get_implicit_key_arc4_dynamic_bytes(account)byte[]", method "get_arc4_uintn64(account)uint64", method "get_arc4_str(account)string", method "get_arc4_byte(account)byte", method "get_arc4_bool(account)bool", method "get_arc4_address(account)address", method "get_arc4_uintn128(account)uint128", method "get_arc4_dynamic_bytes(account)byte[]" - txna ApplicationArgs 0 - match __puya_arc4_router___opt_in_route@2 __puya_arc4_router___get_implicit_key_arc4_uintn64_route@3 __puya_arc4_router___get_implicit_key_arc4_str_route@4 __puya_arc4_router___get_implicit_key_arc4_byte_route@5 __puya_arc4_router___get_implicit_key_arc4_bool_route@6 __puya_arc4_router___get_implicit_key_arc4_address_route@7 __puya_arc4_router___get_implicit_key_arc4_uintn128_route@8 __puya_arc4_router___get_implicit_key_arc4_dynamic_bytes_route@9 __puya_arc4_router___get_arc4_uintn64_route@10 __puya_arc4_router___get_arc4_str_route@11 __puya_arc4_router___get_arc4_byte_route@12 __puya_arc4_router___get_arc4_bool_route@13 __puya_arc4_router___get_arc4_address_route@14 __puya_arc4_router___get_arc4_uintn128_route@15 __puya_arc4_router___get_arc4_dynamic_bytes_route@16 - intc_1 // 0 - retsub - -__puya_arc4_router___opt_in_route@2: - // tests/artifacts/state-ops/contract.algo.ts:774 - // @arc4.abimethod({ allowActions: ['OptIn'] }) - txn OnCompletion - intc_0 // OptIn - == - assert // OnCompletion is not OptIn - txn ApplicationID - assert // can only call when not creating - callsub opt_in - intc_0 // 1 - retsub - -__puya_arc4_router___get_implicit_key_arc4_uintn64_route@3: - // tests/artifacts/state-ops/contract.algo.ts:794 - // @arc4.abimethod() - txn OnCompletion - ! - assert // OnCompletion is not NoOp - txn ApplicationID - assert // can only call when not creating - // tests/artifacts/state-ops/contract.algo.ts:755 - // export class LocalStateContract extends arc4.Contract { - txna ApplicationArgs 1 - btoi - txnas Accounts - // tests/artifacts/state-ops/contract.algo.ts:794 - // @arc4.abimethod() - callsub get_implicit_key_arc4_uintn64 - bytec_0 // 0x151f7c75 - swap - concat - log - intc_0 // 1 - retsub - -__puya_arc4_router___get_implicit_key_arc4_str_route@4: - // tests/artifacts/state-ops/contract.algo.ts:799 - // @arc4.abimethod() - txn OnCompletion - ! - assert // OnCompletion is not NoOp - txn ApplicationID - assert // can only call when not creating - // tests/artifacts/state-ops/contract.algo.ts:755 - // export class LocalStateContract extends arc4.Contract { - txna ApplicationArgs 1 - btoi - txnas Accounts - // tests/artifacts/state-ops/contract.algo.ts:799 - // @arc4.abimethod() - callsub get_implicit_key_arc4_str - bytec_0 // 0x151f7c75 - swap - concat - log - intc_0 // 1 - retsub - -__puya_arc4_router___get_implicit_key_arc4_byte_route@5: - // tests/artifacts/state-ops/contract.algo.ts:804 - // @arc4.abimethod() - txn OnCompletion - ! - assert // OnCompletion is not NoOp - txn ApplicationID - assert // can only call when not creating - // tests/artifacts/state-ops/contract.algo.ts:755 - // export class LocalStateContract extends arc4.Contract { - txna ApplicationArgs 1 - btoi - txnas Accounts - // tests/artifacts/state-ops/contract.algo.ts:804 - // @arc4.abimethod() - callsub get_implicit_key_arc4_byte - bytec_0 // 0x151f7c75 - swap - concat - log - intc_0 // 1 - retsub - -__puya_arc4_router___get_implicit_key_arc4_bool_route@6: - // tests/artifacts/state-ops/contract.algo.ts:809 - // @arc4.abimethod() - txn OnCompletion - ! - assert // OnCompletion is not NoOp - txn ApplicationID - assert // can only call when not creating - // tests/artifacts/state-ops/contract.algo.ts:755 - // export class LocalStateContract extends arc4.Contract { - txna ApplicationArgs 1 - btoi - txnas Accounts - // tests/artifacts/state-ops/contract.algo.ts:809 - // @arc4.abimethod() - callsub get_implicit_key_arc4_bool - bytec_0 // 0x151f7c75 - swap - concat - log - intc_0 // 1 - retsub - -__puya_arc4_router___get_implicit_key_arc4_address_route@7: - // tests/artifacts/state-ops/contract.algo.ts:814 - // @arc4.abimethod() - txn OnCompletion - ! - assert // OnCompletion is not NoOp - txn ApplicationID - assert // can only call when not creating - // tests/artifacts/state-ops/contract.algo.ts:755 - // export class LocalStateContract extends arc4.Contract { - txna ApplicationArgs 1 - btoi - txnas Accounts - // tests/artifacts/state-ops/contract.algo.ts:814 - // @arc4.abimethod() - callsub get_implicit_key_arc4_address - bytec_0 // 0x151f7c75 - swap - concat - log - intc_0 // 1 - retsub - -__puya_arc4_router___get_implicit_key_arc4_uintn128_route@8: - // tests/artifacts/state-ops/contract.algo.ts:819 - // @arc4.abimethod() - txn OnCompletion - ! - assert // OnCompletion is not NoOp - txn ApplicationID - assert // can only call when not creating - // tests/artifacts/state-ops/contract.algo.ts:755 - // export class LocalStateContract extends arc4.Contract { - txna ApplicationArgs 1 - btoi - txnas Accounts - // tests/artifacts/state-ops/contract.algo.ts:819 - // @arc4.abimethod() - callsub get_implicit_key_arc4_uintn128 - bytec_0 // 0x151f7c75 - swap - concat - log - intc_0 // 1 - retsub - -__puya_arc4_router___get_implicit_key_arc4_dynamic_bytes_route@9: - // tests/artifacts/state-ops/contract.algo.ts:824 - // @arc4.abimethod() - txn OnCompletion - ! - assert // OnCompletion is not NoOp - txn ApplicationID - assert // can only call when not creating - // tests/artifacts/state-ops/contract.algo.ts:755 - // export class LocalStateContract extends arc4.Contract { - txna ApplicationArgs 1 - btoi - txnas Accounts - // tests/artifacts/state-ops/contract.algo.ts:824 - // @arc4.abimethod() - callsub get_implicit_key_arc4_dynamic_bytes - bytec_0 // 0x151f7c75 - swap - concat - log - intc_0 // 1 - retsub - -__puya_arc4_router___get_arc4_uintn64_route@10: - // tests/artifacts/state-ops/contract.algo.ts:830 - // @arc4.abimethod() - txn OnCompletion - ! - assert // OnCompletion is not NoOp - txn ApplicationID - assert // can only call when not creating - // tests/artifacts/state-ops/contract.algo.ts:755 - // export class LocalStateContract extends arc4.Contract { - txna ApplicationArgs 1 - btoi - txnas Accounts - // tests/artifacts/state-ops/contract.algo.ts:830 - // @arc4.abimethod() - callsub get_arc4_uintn64 - bytec_0 // 0x151f7c75 - swap - concat - log - intc_0 // 1 - retsub - -__puya_arc4_router___get_arc4_str_route@11: - // tests/artifacts/state-ops/contract.algo.ts:835 - // @arc4.abimethod() - txn OnCompletion - ! - assert // OnCompletion is not NoOp - txn ApplicationID - assert // can only call when not creating - // tests/artifacts/state-ops/contract.algo.ts:755 - // export class LocalStateContract extends arc4.Contract { - txna ApplicationArgs 1 - btoi - txnas Accounts - // tests/artifacts/state-ops/contract.algo.ts:835 - // @arc4.abimethod() - callsub get_arc4_str - bytec_0 // 0x151f7c75 - swap - concat - log - intc_0 // 1 - retsub - -__puya_arc4_router___get_arc4_byte_route@12: - // tests/artifacts/state-ops/contract.algo.ts:840 - // @arc4.abimethod() - txn OnCompletion - ! - assert // OnCompletion is not NoOp - txn ApplicationID - assert // can only call when not creating - // tests/artifacts/state-ops/contract.algo.ts:755 - // export class LocalStateContract extends arc4.Contract { - txna ApplicationArgs 1 - btoi - txnas Accounts - // tests/artifacts/state-ops/contract.algo.ts:840 - // @arc4.abimethod() - callsub get_arc4_byte - bytec_0 // 0x151f7c75 - swap - concat - log - intc_0 // 1 - retsub - -__puya_arc4_router___get_arc4_bool_route@13: - // tests/artifacts/state-ops/contract.algo.ts:845 - // @arc4.abimethod() - txn OnCompletion - ! - assert // OnCompletion is not NoOp - txn ApplicationID - assert // can only call when not creating - // tests/artifacts/state-ops/contract.algo.ts:755 - // export class LocalStateContract extends arc4.Contract { - txna ApplicationArgs 1 - btoi - txnas Accounts - // tests/artifacts/state-ops/contract.algo.ts:845 - // @arc4.abimethod() - callsub get_arc4_bool - bytec_0 // 0x151f7c75 - swap - concat - log - intc_0 // 1 - retsub - -__puya_arc4_router___get_arc4_address_route@14: - // tests/artifacts/state-ops/contract.algo.ts:850 - // @arc4.abimethod() - txn OnCompletion - ! - assert // OnCompletion is not NoOp - txn ApplicationID - assert // can only call when not creating - // tests/artifacts/state-ops/contract.algo.ts:755 - // export class LocalStateContract extends arc4.Contract { - txna ApplicationArgs 1 - btoi - txnas Accounts - // tests/artifacts/state-ops/contract.algo.ts:850 - // @arc4.abimethod() - callsub get_arc4_address - bytec_0 // 0x151f7c75 - swap - concat - log - intc_0 // 1 - retsub - -__puya_arc4_router___get_arc4_uintn128_route@15: - // tests/artifacts/state-ops/contract.algo.ts:855 - // @arc4.abimethod() - txn OnCompletion - ! - assert // OnCompletion is not NoOp - txn ApplicationID - assert // can only call when not creating - // tests/artifacts/state-ops/contract.algo.ts:755 - // export class LocalStateContract extends arc4.Contract { - txna ApplicationArgs 1 - btoi - txnas Accounts - // tests/artifacts/state-ops/contract.algo.ts:855 - // @arc4.abimethod() - callsub get_arc4_uintn128 - bytec_0 // 0x151f7c75 - swap - concat - log - intc_0 // 1 - retsub - -__puya_arc4_router___get_arc4_dynamic_bytes_route@16: - // tests/artifacts/state-ops/contract.algo.ts:860 - // @arc4.abimethod() - txn OnCompletion - ! - assert // OnCompletion is not NoOp - txn ApplicationID - assert // can only call when not creating - // tests/artifacts/state-ops/contract.algo.ts:755 - // export class LocalStateContract extends arc4.Contract { - txna ApplicationArgs 1 - btoi - txnas Accounts - // tests/artifacts/state-ops/contract.algo.ts:860 - // @arc4.abimethod() - callsub get_arc4_dynamic_bytes - bytec_0 // 0x151f7c75 - swap - concat - log - intc_0 // 1 - retsub - -__puya_arc4_router___bare_routing@19: - // tests/artifacts/state-ops/contract.algo.ts:755 - // export class LocalStateContract extends arc4.Contract { - txn OnCompletion - bnz __puya_arc4_router___after_if_else@23 - txn ApplicationID - ! - assert // can only call when creating - intc_0 // 1 - retsub - -__puya_arc4_router___after_if_else@23: - // tests/artifacts/state-ops/contract.algo.ts:755 - // export class LocalStateContract extends arc4.Contract { - intc_1 // 0 - retsub - - -// tests/artifacts/state-ops/contract.algo.ts::LocalStateContract.opt_in() -> void: -opt_in: - // tests/artifacts/state-ops/contract.algo.ts:774-775 - // @arc4.abimethod({ allowActions: ['OptIn'] }) - // opt_in(): void { - proto 0 0 - // tests/artifacts/state-ops/contract.algo.ts:776 - // this.implicitKeyArc4UintN64(Global.creatorAddress).value = new UintN64(1337) - global CreatorAddress - // tests/artifacts/state-ops/contract.algo.ts:757 - // implicitKeyArc4UintN64 = LocalState() - bytec_1 // "implicitKeyArc4UintN64" - // tests/artifacts/state-ops/contract.algo.ts:776 - // this.implicitKeyArc4UintN64(Global.creatorAddress).value = new UintN64(1337) - bytec_2 // 0x0000000000000539 - app_local_put - // tests/artifacts/state-ops/contract.algo.ts:777 - // this.implicitKeyArc4Str(Global.creatorAddress).value = new Str('Hello') - global CreatorAddress - // tests/artifacts/state-ops/contract.algo.ts:758 - // implicitKeyArc4Str = LocalState() - bytec_3 // "implicitKeyArc4Str" - // tests/artifacts/state-ops/contract.algo.ts:777 - // this.implicitKeyArc4Str(Global.creatorAddress).value = new Str('Hello') - bytec 4 // 0x000548656c6c6f - app_local_put - // tests/artifacts/state-ops/contract.algo.ts:778 - // this.implicitKeyArc4Byte(Global.creatorAddress).value = new Byte(0) - global CreatorAddress - // tests/artifacts/state-ops/contract.algo.ts:759 - // implicitKeyArc4Byte = LocalState() - bytec 5 // "implicitKeyArc4Byte" - // tests/artifacts/state-ops/contract.algo.ts:778 - // this.implicitKeyArc4Byte(Global.creatorAddress).value = new Byte(0) - pushbytes 0x00 - app_local_put - // tests/artifacts/state-ops/contract.algo.ts:779 - // this.implicitKeyArc4Bool(Global.creatorAddress).value = new Bool(true) - global CreatorAddress - // tests/artifacts/state-ops/contract.algo.ts:760 - // implicitKeyArc4Bool = LocalState() - bytec 6 // "implicitKeyArc4Bool" - // tests/artifacts/state-ops/contract.algo.ts:779 - // this.implicitKeyArc4Bool(Global.creatorAddress).value = new Bool(true) - pushbytes 0x80 - app_local_put - // tests/artifacts/state-ops/contract.algo.ts:780 - // this.implicitKeyArc4Address(Global.creatorAddress).value = new Address(Global.creatorAddress) - global CreatorAddress - // tests/artifacts/state-ops/contract.algo.ts:761 - // implicitKeyArc4Address = LocalState
() - bytec 7 // "implicitKeyArc4Address" - // tests/artifacts/state-ops/contract.algo.ts:780 - // this.implicitKeyArc4Address(Global.creatorAddress).value = new Address(Global.creatorAddress) - global CreatorAddress - app_local_put - // tests/artifacts/state-ops/contract.algo.ts:781 - // this.implicitKeyArc4UintN128(Global.creatorAddress).value = new UintN128(2n ** 100n) - global CreatorAddress - // tests/artifacts/state-ops/contract.algo.ts:762 - // implicitKeyArc4UintN128 = LocalState() - bytec 8 // "implicitKeyArc4UintN128" - // tests/artifacts/state-ops/contract.algo.ts:781 - // this.implicitKeyArc4UintN128(Global.creatorAddress).value = new UintN128(2n ** 100n) - bytec 9 // 0x00000010000000000000000000000000 - app_local_put - // tests/artifacts/state-ops/contract.algo.ts:782 - // this.implicitKeyArc4DynamicBytes(Global.creatorAddress).value = new DynamicBytes('dynamic bytes') - global CreatorAddress - // tests/artifacts/state-ops/contract.algo.ts:763 - // implicitKeyArc4DynamicBytes = LocalState() - bytec 10 // "implicitKeyArc4DynamicBytes" - // tests/artifacts/state-ops/contract.algo.ts:782 - // this.implicitKeyArc4DynamicBytes(Global.creatorAddress).value = new DynamicBytes('dynamic bytes') - bytec 11 // 0x000d64796e616d6963206279746573 - app_local_put - // tests/artifacts/state-ops/contract.algo.ts:784 - // this.arc4UintN64(Global.creatorAddress).value = new UintN64(1337) - global CreatorAddress - // tests/artifacts/state-ops/contract.algo.ts:766 - // arc4UintN64 = LocalState({ key: 'explicit_key_arc4_uintn64' }) - bytec 12 // "explicit_key_arc4_uintn64" - // tests/artifacts/state-ops/contract.algo.ts:784 - // this.arc4UintN64(Global.creatorAddress).value = new UintN64(1337) - bytec_2 // 0x0000000000000539 - app_local_put - // tests/artifacts/state-ops/contract.algo.ts:785 - // this.arc4Str(Global.creatorAddress).value = new Str('Hello') - global CreatorAddress - // tests/artifacts/state-ops/contract.algo.ts:767 - // arc4Str = LocalState({ key: 'explicit_key_arc4_str' }) - bytec 13 // "explicit_key_arc4_str" - // tests/artifacts/state-ops/contract.algo.ts:785 - // this.arc4Str(Global.creatorAddress).value = new Str('Hello') - bytec 4 // 0x000548656c6c6f - app_local_put - // tests/artifacts/state-ops/contract.algo.ts:786 - // this.arc4Byte(Global.creatorAddress).value = new Byte(0) - global CreatorAddress - // tests/artifacts/state-ops/contract.algo.ts:768 - // arc4Byte = LocalState({ key: 'explicit_key_arc4_byte' }) - bytec 14 // "explicit_key_arc4_byte" - // tests/artifacts/state-ops/contract.algo.ts:786 - // this.arc4Byte(Global.creatorAddress).value = new Byte(0) - pushbytes 0x00 - app_local_put - // tests/artifacts/state-ops/contract.algo.ts:787 - // this.arc4Bool(Global.creatorAddress).value = new Bool(true) - global CreatorAddress - // tests/artifacts/state-ops/contract.algo.ts:769 - // arc4Bool = LocalState({ key: 'explicit_key_arc4_bool' }) - bytec 15 // "explicit_key_arc4_bool" - // tests/artifacts/state-ops/contract.algo.ts:787 - // this.arc4Bool(Global.creatorAddress).value = new Bool(true) - pushbytes 0x80 - app_local_put - // tests/artifacts/state-ops/contract.algo.ts:788 - // this.arc4Address(Global.creatorAddress).value = new Address(Global.creatorAddress) - global CreatorAddress - // tests/artifacts/state-ops/contract.algo.ts:770 - // arc4Address = LocalState
({ key: 'explicit_key_arc4_address' }) - bytec 16 // "explicit_key_arc4_address" - // tests/artifacts/state-ops/contract.algo.ts:788 - // this.arc4Address(Global.creatorAddress).value = new Address(Global.creatorAddress) - global CreatorAddress - app_local_put - // tests/artifacts/state-ops/contract.algo.ts:789 - // this.arc4UintN128(Global.creatorAddress).value = new UintN128(2n ** 100n) - global CreatorAddress - // tests/artifacts/state-ops/contract.algo.ts:771 - // arc4UintN128 = LocalState({ key: 'explicit_key_arc4_uintn128' }) - bytec 17 // "explicit_key_arc4_uintn128" - // tests/artifacts/state-ops/contract.algo.ts:789 - // this.arc4UintN128(Global.creatorAddress).value = new UintN128(2n ** 100n) - bytec 9 // 0x00000010000000000000000000000000 - app_local_put - // tests/artifacts/state-ops/contract.algo.ts:790 - // this.arc4DynamicBytes(Global.creatorAddress).value = new DynamicBytes('dynamic bytes') - global CreatorAddress - // tests/artifacts/state-ops/contract.algo.ts:772 - // arc4DynamicBytes = LocalState({ key: 'explicit_key_arc4_dynamic_bytes' }) - bytec 18 // "explicit_key_arc4_dynamic_bytes" - // tests/artifacts/state-ops/contract.algo.ts:790 - // this.arc4DynamicBytes(Global.creatorAddress).value = new DynamicBytes('dynamic bytes') - bytec 11 // 0x000d64796e616d6963206279746573 - app_local_put - retsub - - -// tests/artifacts/state-ops/contract.algo.ts::LocalStateContract.get_implicit_key_arc4_uintn64(a: bytes) -> bytes: -get_implicit_key_arc4_uintn64: - // tests/artifacts/state-ops/contract.algo.ts:794-795 - // @arc4.abimethod() - // get_implicit_key_arc4_uintn64(a: Account): UintN64 { - proto 1 1 - // tests/artifacts/state-ops/contract.algo.ts:796 - // return this.implicitKeyArc4UintN64(a).value - frame_dig -1 - intc_1 // 0 - // tests/artifacts/state-ops/contract.algo.ts:757 - // implicitKeyArc4UintN64 = LocalState() - bytec_1 // "implicitKeyArc4UintN64" - // tests/artifacts/state-ops/contract.algo.ts:796 - // return this.implicitKeyArc4UintN64(a).value - app_local_get_ex - assert // check LocalState exists - retsub - - -// tests/artifacts/state-ops/contract.algo.ts::LocalStateContract.get_implicit_key_arc4_str(a: bytes) -> bytes: -get_implicit_key_arc4_str: - // tests/artifacts/state-ops/contract.algo.ts:799-800 - // @arc4.abimethod() - // get_implicit_key_arc4_str(a: Account): Str { - proto 1 1 - // tests/artifacts/state-ops/contract.algo.ts:801 - // return this.implicitKeyArc4Str(a).value - frame_dig -1 - intc_1 // 0 - // tests/artifacts/state-ops/contract.algo.ts:758 - // implicitKeyArc4Str = LocalState() - bytec_3 // "implicitKeyArc4Str" - // tests/artifacts/state-ops/contract.algo.ts:801 - // return this.implicitKeyArc4Str(a).value - app_local_get_ex - assert // check LocalState exists - retsub - - -// tests/artifacts/state-ops/contract.algo.ts::LocalStateContract.get_implicit_key_arc4_byte(a: bytes) -> bytes: -get_implicit_key_arc4_byte: - // tests/artifacts/state-ops/contract.algo.ts:804-805 - // @arc4.abimethod() - // get_implicit_key_arc4_byte(a: Account): Byte { - proto 1 1 - // tests/artifacts/state-ops/contract.algo.ts:806 - // return this.implicitKeyArc4Byte(a).value - frame_dig -1 - intc_1 // 0 - // tests/artifacts/state-ops/contract.algo.ts:759 - // implicitKeyArc4Byte = LocalState() - bytec 5 // "implicitKeyArc4Byte" - // tests/artifacts/state-ops/contract.algo.ts:806 - // return this.implicitKeyArc4Byte(a).value - app_local_get_ex - assert // check LocalState exists - retsub - - -// tests/artifacts/state-ops/contract.algo.ts::LocalStateContract.get_implicit_key_arc4_bool(a: bytes) -> bytes: -get_implicit_key_arc4_bool: - // tests/artifacts/state-ops/contract.algo.ts:809-810 - // @arc4.abimethod() - // get_implicit_key_arc4_bool(a: Account): Bool { - proto 1 1 - // tests/artifacts/state-ops/contract.algo.ts:811 - // return this.implicitKeyArc4Bool(a).value - frame_dig -1 - intc_1 // 0 - // tests/artifacts/state-ops/contract.algo.ts:760 - // implicitKeyArc4Bool = LocalState() - bytec 6 // "implicitKeyArc4Bool" - // tests/artifacts/state-ops/contract.algo.ts:811 - // return this.implicitKeyArc4Bool(a).value - app_local_get_ex - assert // check LocalState exists - retsub - - -// tests/artifacts/state-ops/contract.algo.ts::LocalStateContract.get_implicit_key_arc4_address(a: bytes) -> bytes: -get_implicit_key_arc4_address: - // tests/artifacts/state-ops/contract.algo.ts:814-815 - // @arc4.abimethod() - // get_implicit_key_arc4_address(a: Account): Address { - proto 1 1 - // tests/artifacts/state-ops/contract.algo.ts:816 - // return this.implicitKeyArc4Address(a).value - frame_dig -1 - intc_1 // 0 - // tests/artifacts/state-ops/contract.algo.ts:761 - // implicitKeyArc4Address = LocalState
() - bytec 7 // "implicitKeyArc4Address" - // tests/artifacts/state-ops/contract.algo.ts:816 - // return this.implicitKeyArc4Address(a).value - app_local_get_ex - assert // check LocalState exists - retsub - - -// tests/artifacts/state-ops/contract.algo.ts::LocalStateContract.get_implicit_key_arc4_uintn128(a: bytes) -> bytes: -get_implicit_key_arc4_uintn128: - // tests/artifacts/state-ops/contract.algo.ts:819-820 - // @arc4.abimethod() - // get_implicit_key_arc4_uintn128(a: Account): UintN128 { - proto 1 1 - // tests/artifacts/state-ops/contract.algo.ts:821 - // return this.implicitKeyArc4UintN128(a).value - frame_dig -1 - intc_1 // 0 - // tests/artifacts/state-ops/contract.algo.ts:762 - // implicitKeyArc4UintN128 = LocalState() - bytec 8 // "implicitKeyArc4UintN128" - // tests/artifacts/state-ops/contract.algo.ts:821 - // return this.implicitKeyArc4UintN128(a).value - app_local_get_ex - assert // check LocalState exists - retsub - - -// tests/artifacts/state-ops/contract.algo.ts::LocalStateContract.get_implicit_key_arc4_dynamic_bytes(a: bytes) -> bytes: -get_implicit_key_arc4_dynamic_bytes: - // tests/artifacts/state-ops/contract.algo.ts:824-825 - // @arc4.abimethod() - // get_implicit_key_arc4_dynamic_bytes(a: Account): DynamicBytes { - proto 1 1 - // tests/artifacts/state-ops/contract.algo.ts:826 - // return this.implicitKeyArc4DynamicBytes(a).value - frame_dig -1 - intc_1 // 0 - // tests/artifacts/state-ops/contract.algo.ts:763 - // implicitKeyArc4DynamicBytes = LocalState() - bytec 10 // "implicitKeyArc4DynamicBytes" - // tests/artifacts/state-ops/contract.algo.ts:826 - // return this.implicitKeyArc4DynamicBytes(a).value - app_local_get_ex - assert // check LocalState exists - retsub - - -// tests/artifacts/state-ops/contract.algo.ts::LocalStateContract.get_arc4_uintn64(a: bytes) -> bytes: -get_arc4_uintn64: - // tests/artifacts/state-ops/contract.algo.ts:830-831 - // @arc4.abimethod() - // get_arc4_uintn64(a: Account): arc4.UintN64 { - proto 1 1 - // tests/artifacts/state-ops/contract.algo.ts:832 - // return this.arc4UintN64(a).value - frame_dig -1 - intc_1 // 0 - // tests/artifacts/state-ops/contract.algo.ts:766 - // arc4UintN64 = LocalState({ key: 'explicit_key_arc4_uintn64' }) - bytec 12 // "explicit_key_arc4_uintn64" - // tests/artifacts/state-ops/contract.algo.ts:832 - // return this.arc4UintN64(a).value - app_local_get_ex - assert // check LocalState exists - retsub - - -// tests/artifacts/state-ops/contract.algo.ts::LocalStateContract.get_arc4_str(a: bytes) -> bytes: -get_arc4_str: - // tests/artifacts/state-ops/contract.algo.ts:835-836 - // @arc4.abimethod() - // get_arc4_str(a: Account): Str { - proto 1 1 - // tests/artifacts/state-ops/contract.algo.ts:837 - // return this.arc4Str(a).value - frame_dig -1 - intc_1 // 0 - // tests/artifacts/state-ops/contract.algo.ts:767 - // arc4Str = LocalState({ key: 'explicit_key_arc4_str' }) - bytec 13 // "explicit_key_arc4_str" - // tests/artifacts/state-ops/contract.algo.ts:837 - // return this.arc4Str(a).value - app_local_get_ex - assert // check LocalState exists - retsub - - -// tests/artifacts/state-ops/contract.algo.ts::LocalStateContract.get_arc4_byte(a: bytes) -> bytes: -get_arc4_byte: - // tests/artifacts/state-ops/contract.algo.ts:840-841 - // @arc4.abimethod() - // get_arc4_byte(a: Account): Byte { - proto 1 1 - // tests/artifacts/state-ops/contract.algo.ts:842 - // return this.arc4Byte(a).value - frame_dig -1 - intc_1 // 0 - // tests/artifacts/state-ops/contract.algo.ts:768 - // arc4Byte = LocalState({ key: 'explicit_key_arc4_byte' }) - bytec 14 // "explicit_key_arc4_byte" - // tests/artifacts/state-ops/contract.algo.ts:842 - // return this.arc4Byte(a).value - app_local_get_ex - assert // check LocalState exists - retsub - - -// tests/artifacts/state-ops/contract.algo.ts::LocalStateContract.get_arc4_bool(a: bytes) -> bytes: -get_arc4_bool: - // tests/artifacts/state-ops/contract.algo.ts:845-846 - // @arc4.abimethod() - // get_arc4_bool(a: Account): Bool { - proto 1 1 - // tests/artifacts/state-ops/contract.algo.ts:847 - // return this.arc4Bool(a).value - frame_dig -1 - intc_1 // 0 - // tests/artifacts/state-ops/contract.algo.ts:769 - // arc4Bool = LocalState({ key: 'explicit_key_arc4_bool' }) - bytec 15 // "explicit_key_arc4_bool" - // tests/artifacts/state-ops/contract.algo.ts:847 - // return this.arc4Bool(a).value - app_local_get_ex - assert // check LocalState exists - retsub - - -// tests/artifacts/state-ops/contract.algo.ts::LocalStateContract.get_arc4_address(a: bytes) -> bytes: -get_arc4_address: - // tests/artifacts/state-ops/contract.algo.ts:850-851 - // @arc4.abimethod() - // get_arc4_address(a: Account): Address { - proto 1 1 - // tests/artifacts/state-ops/contract.algo.ts:852 - // return this.arc4Address(a).value - frame_dig -1 - intc_1 // 0 - // tests/artifacts/state-ops/contract.algo.ts:770 - // arc4Address = LocalState
({ key: 'explicit_key_arc4_address' }) - bytec 16 // "explicit_key_arc4_address" - // tests/artifacts/state-ops/contract.algo.ts:852 - // return this.arc4Address(a).value - app_local_get_ex - assert // check LocalState exists - retsub - - -// tests/artifacts/state-ops/contract.algo.ts::LocalStateContract.get_arc4_uintn128(a: bytes) -> bytes: -get_arc4_uintn128: - // tests/artifacts/state-ops/contract.algo.ts:855-856 - // @arc4.abimethod() - // get_arc4_uintn128(a: Account): UintN128 { - proto 1 1 - // tests/artifacts/state-ops/contract.algo.ts:857 - // return this.arc4UintN128(a).value - frame_dig -1 - intc_1 // 0 - // tests/artifacts/state-ops/contract.algo.ts:771 - // arc4UintN128 = LocalState({ key: 'explicit_key_arc4_uintn128' }) - bytec 17 // "explicit_key_arc4_uintn128" - // tests/artifacts/state-ops/contract.algo.ts:857 - // return this.arc4UintN128(a).value - app_local_get_ex - assert // check LocalState exists - retsub - - -// tests/artifacts/state-ops/contract.algo.ts::LocalStateContract.get_arc4_dynamic_bytes(a: bytes) -> bytes: -get_arc4_dynamic_bytes: - // tests/artifacts/state-ops/contract.algo.ts:860-861 - // @arc4.abimethod() - // get_arc4_dynamic_bytes(a: Account): DynamicBytes { - proto 1 1 - // tests/artifacts/state-ops/contract.algo.ts:862 - // return this.arc4DynamicBytes(a).value - frame_dig -1 - intc_1 // 0 - // tests/artifacts/state-ops/contract.algo.ts:772 - // arc4DynamicBytes = LocalState({ key: 'explicit_key_arc4_dynamic_bytes' }) - bytec 18 // "explicit_key_arc4_dynamic_bytes" - // tests/artifacts/state-ops/contract.algo.ts:862 - // return this.arc4DynamicBytes(a).value - app_local_get_ex - assert // check LocalState exists - retsub diff --git a/tests/artifacts/state-ops/data/LocalStateContract.arc32.json b/tests/artifacts/state-ops/data/LocalStateContract.arc32.json deleted file mode 100644 index 5bc511d..0000000 --- a/tests/artifacts/state-ops/data/LocalStateContract.arc32.json +++ /dev/null @@ -1,359 +0,0 @@ -{ - "hints": { - "opt_in()void": { - "call_config": { - "opt_in": "CALL" - } - }, - "get_implicit_key_arc4_uintn64(account)uint64": { - "call_config": { - "no_op": "CALL" - } - }, - "get_implicit_key_arc4_str(account)string": { - "call_config": { - "no_op": "CALL" - } - }, - "get_implicit_key_arc4_byte(account)byte": { - "call_config": { - "no_op": "CALL" - } - }, - "get_implicit_key_arc4_bool(account)bool": { - "call_config": { - "no_op": "CALL" - } - }, - "get_implicit_key_arc4_address(account)address": { - "call_config": { - "no_op": "CALL" - } - }, - "get_implicit_key_arc4_uintn128(account)uint128": { - "call_config": { - "no_op": "CALL" - } - }, - "get_implicit_key_arc4_dynamic_bytes(account)byte[]": { - "call_config": { - "no_op": "CALL" - } - }, - "get_arc4_uintn64(account)uint64": { - "call_config": { - "no_op": "CALL" - } - }, - "get_arc4_str(account)string": { - "call_config": { - "no_op": "CALL" - } - }, - "get_arc4_byte(account)byte": { - "call_config": { - "no_op": "CALL" - } - }, - "get_arc4_bool(account)bool": { - "call_config": { - "no_op": "CALL" - } - }, - "get_arc4_address(account)address": { - "call_config": { - "no_op": "CALL" - } - }, - "get_arc4_uintn128(account)uint128": { - "call_config": { - "no_op": "CALL" - } - }, - "get_arc4_dynamic_bytes(account)byte[]": { - "call_config": { - "no_op": "CALL" - } - } - }, - "source": { - "approval": "I3ByYWdtYSB2ZXJzaW9uIDEwCgp0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OkxvY2FsU3RhdGVDb250cmFjdC5hcHByb3ZhbFByb2dyYW06CiAgICBpbnRjYmxvY2sgMSAwCiAgICBieXRlY2Jsb2NrIDB4MTUxZjdjNzUgImltcGxpY2l0S2V5QXJjNFVpbnRONjQiIDB4MDAwMDAwMDAwMDAwMDUzOSAiaW1wbGljaXRLZXlBcmM0U3RyIiAweDAwMDU0ODY1NmM2YzZmICJpbXBsaWNpdEtleUFyYzRCeXRlIiAiaW1wbGljaXRLZXlBcmM0Qm9vbCIgImltcGxpY2l0S2V5QXJjNEFkZHJlc3MiICJpbXBsaWNpdEtleUFyYzRVaW50TjEyOCIgMHgwMDAwMDAxMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMCAiaW1wbGljaXRLZXlBcmM0RHluYW1pY0J5dGVzIiAweDAwMGQ2NDc5NmU2MTZkNjk2MzIwNjI3OTc0NjU3MyAiZXhwbGljaXRfa2V5X2FyYzRfdWludG42NCIgImV4cGxpY2l0X2tleV9hcmM0X3N0ciIgImV4cGxpY2l0X2tleV9hcmM0X2J5dGUiICJleHBsaWNpdF9rZXlfYXJjNF9ib29sIiAiZXhwbGljaXRfa2V5X2FyYzRfYWRkcmVzcyIgImV4cGxpY2l0X2tleV9hcmM0X3VpbnRuMTI4IiAiZXhwbGljaXRfa2V5X2FyYzRfZHluYW1pY19ieXRlcyIKICAgIGNhbGxzdWIgX19wdXlhX2FyYzRfcm91dGVyX18KICAgIHJldHVybgoKCi8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo6TG9jYWxTdGF0ZUNvbnRyYWN0Ll9fcHV5YV9hcmM0X3JvdXRlcl9fKCkgLT4gdWludDY0OgpfX3B1eWFfYXJjNF9yb3V0ZXJfXzoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo3NTUKICAgIC8vIGV4cG9ydCBjbGFzcyBMb2NhbFN0YXRlQ29udHJhY3QgZXh0ZW5kcyBhcmM0LkNvbnRyYWN0IHsKICAgIHByb3RvIDAgMQogICAgdHhuIE51bUFwcEFyZ3MKICAgIGJ6IF9fcHV5YV9hcmM0X3JvdXRlcl9fX2JhcmVfcm91dGluZ0AxOQogICAgcHVzaGJ5dGVzcyAweDMwYzZkNThhIDB4ZWVjZGYwYTAgMHg2YzZmMTdkYSAweGVjZjYzM2IwIDB4M2U1MzEyMjMgMHgzZWQ2Nzk5ZCAweDZmZWNkZDgwIDB4Njc2YTg3YzIgMHgxZTBmODk1MSAweDQyZTg1ZmQ3IDB4NjUyMWQ0OWIgMHhlMDdjNTZjZCAweGFhMTlkMmI1IDB4YjkyMjMxMmQgMHhmYzBmZWVkOSAvLyBtZXRob2QgIm9wdF9pbigpdm9pZCIsIG1ldGhvZCAiZ2V0X2ltcGxpY2l0X2tleV9hcmM0X3VpbnRuNjQoYWNjb3VudCl1aW50NjQiLCBtZXRob2QgImdldF9pbXBsaWNpdF9rZXlfYXJjNF9zdHIoYWNjb3VudClzdHJpbmciLCBtZXRob2QgImdldF9pbXBsaWNpdF9rZXlfYXJjNF9ieXRlKGFjY291bnQpYnl0ZSIsIG1ldGhvZCAiZ2V0X2ltcGxpY2l0X2tleV9hcmM0X2Jvb2woYWNjb3VudClib29sIiwgbWV0aG9kICJnZXRfaW1wbGljaXRfa2V5X2FyYzRfYWRkcmVzcyhhY2NvdW50KWFkZHJlc3MiLCBtZXRob2QgImdldF9pbXBsaWNpdF9rZXlfYXJjNF91aW50bjEyOChhY2NvdW50KXVpbnQxMjgiLCBtZXRob2QgImdldF9pbXBsaWNpdF9rZXlfYXJjNF9keW5hbWljX2J5dGVzKGFjY291bnQpYnl0ZVtdIiwgbWV0aG9kICJnZXRfYXJjNF91aW50bjY0KGFjY291bnQpdWludDY0IiwgbWV0aG9kICJnZXRfYXJjNF9zdHIoYWNjb3VudClzdHJpbmciLCBtZXRob2QgImdldF9hcmM0X2J5dGUoYWNjb3VudClieXRlIiwgbWV0aG9kICJnZXRfYXJjNF9ib29sKGFjY291bnQpYm9vbCIsIG1ldGhvZCAiZ2V0X2FyYzRfYWRkcmVzcyhhY2NvdW50KWFkZHJlc3MiLCBtZXRob2QgImdldF9hcmM0X3VpbnRuMTI4KGFjY291bnQpdWludDEyOCIsIG1ldGhvZCAiZ2V0X2FyYzRfZHluYW1pY19ieXRlcyhhY2NvdW50KWJ5dGVbXSIKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDAKICAgIG1hdGNoIF9fcHV5YV9hcmM0X3JvdXRlcl9fX29wdF9pbl9yb3V0ZUAyIF9fcHV5YV9hcmM0X3JvdXRlcl9fX2dldF9pbXBsaWNpdF9rZXlfYXJjNF91aW50bjY0X3JvdXRlQDMgX19wdXlhX2FyYzRfcm91dGVyX19fZ2V0X2ltcGxpY2l0X2tleV9hcmM0X3N0cl9yb3V0ZUA0IF9fcHV5YV9hcmM0X3JvdXRlcl9fX2dldF9pbXBsaWNpdF9rZXlfYXJjNF9ieXRlX3JvdXRlQDUgX19wdXlhX2FyYzRfcm91dGVyX19fZ2V0X2ltcGxpY2l0X2tleV9hcmM0X2Jvb2xfcm91dGVANiBfX3B1eWFfYXJjNF9yb3V0ZXJfX19nZXRfaW1wbGljaXRfa2V5X2FyYzRfYWRkcmVzc19yb3V0ZUA3IF9fcHV5YV9hcmM0X3JvdXRlcl9fX2dldF9pbXBsaWNpdF9rZXlfYXJjNF91aW50bjEyOF9yb3V0ZUA4IF9fcHV5YV9hcmM0X3JvdXRlcl9fX2dldF9pbXBsaWNpdF9rZXlfYXJjNF9keW5hbWljX2J5dGVzX3JvdXRlQDkgX19wdXlhX2FyYzRfcm91dGVyX19fZ2V0X2FyYzRfdWludG42NF9yb3V0ZUAxMCBfX3B1eWFfYXJjNF9yb3V0ZXJfX19nZXRfYXJjNF9zdHJfcm91dGVAMTEgX19wdXlhX2FyYzRfcm91dGVyX19fZ2V0X2FyYzRfYnl0ZV9yb3V0ZUAxMiBfX3B1eWFfYXJjNF9yb3V0ZXJfX19nZXRfYXJjNF9ib29sX3JvdXRlQDEzIF9fcHV5YV9hcmM0X3JvdXRlcl9fX2dldF9hcmM0X2FkZHJlc3Nfcm91dGVAMTQgX19wdXlhX2FyYzRfcm91dGVyX19fZ2V0X2FyYzRfdWludG4xMjhfcm91dGVAMTUgX19wdXlhX2FyYzRfcm91dGVyX19fZ2V0X2FyYzRfZHluYW1pY19ieXRlc19yb3V0ZUAxNgogICAgaW50Y18xIC8vIDAKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fb3B0X2luX3JvdXRlQDI6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6Nzc0CiAgICAvLyBAYXJjNC5hYmltZXRob2QoeyBhbGxvd0FjdGlvbnM6IFsnT3B0SW4nXSB9KQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgaW50Y18wIC8vIE9wdEluCiAgICA9PQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBub3QgT3B0SW4KICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gY2FuIG9ubHkgY2FsbCB3aGVuIG5vdCBjcmVhdGluZwogICAgY2FsbHN1YiBvcHRfaW4KICAgIGludGNfMCAvLyAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX2dldF9pbXBsaWNpdF9rZXlfYXJjNF91aW50bjY0X3JvdXRlQDM6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6Nzk0CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBub3QgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBjYW4gb25seSBjYWxsIHdoZW4gbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NzU1CiAgICAvLyBleHBvcnQgY2xhc3MgTG9jYWxTdGF0ZUNvbnRyYWN0IGV4dGVuZHMgYXJjNC5Db250cmFjdCB7CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBidG9pCiAgICB0eG5hcyBBY2NvdW50cwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjc5NAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgZ2V0X2ltcGxpY2l0X2tleV9hcmM0X3VpbnRuNjQKICAgIGJ5dGVjXzAgLy8gMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludGNfMCAvLyAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX2dldF9pbXBsaWNpdF9rZXlfYXJjNF9zdHJfcm91dGVANDoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo3OTkKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIG5vdCBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGNhbiBvbmx5IGNhbGwgd2hlbiBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo3NTUKICAgIC8vIGV4cG9ydCBjbGFzcyBMb2NhbFN0YXRlQ29udHJhY3QgZXh0ZW5kcyBhcmM0LkNvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGJ0b2kKICAgIHR4bmFzIEFjY291bnRzCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6Nzk5CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiBnZXRfaW1wbGljaXRfa2V5X2FyYzRfc3RyCiAgICBieXRlY18wIC8vIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnRjXzAgLy8gMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX19nZXRfaW1wbGljaXRfa2V5X2FyYzRfYnl0ZV9yb3V0ZUA1OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjgwNAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgbm90IE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gY2FuIG9ubHkgY2FsbCB3aGVuIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjc1NQogICAgLy8gZXhwb3J0IGNsYXNzIExvY2FsU3RhdGVDb250cmFjdCBleHRlbmRzIGFyYzQuQ29udHJhY3QgewogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgYnRvaQogICAgdHhuYXMgQWNjb3VudHMKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo4MDQKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIGdldF9pbXBsaWNpdF9rZXlfYXJjNF9ieXRlCiAgICBieXRlY18wIC8vIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnRjXzAgLy8gMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX19nZXRfaW1wbGljaXRfa2V5X2FyYzRfYm9vbF9yb3V0ZUA2OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjgwOQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgbm90IE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gY2FuIG9ubHkgY2FsbCB3aGVuIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjc1NQogICAgLy8gZXhwb3J0IGNsYXNzIExvY2FsU3RhdGVDb250cmFjdCBleHRlbmRzIGFyYzQuQ29udHJhY3QgewogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgYnRvaQogICAgdHhuYXMgQWNjb3VudHMKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo4MDkKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIGdldF9pbXBsaWNpdF9rZXlfYXJjNF9ib29sCiAgICBieXRlY18wIC8vIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnRjXzAgLy8gMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX19nZXRfaW1wbGljaXRfa2V5X2FyYzRfYWRkcmVzc19yb3V0ZUA3OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjgxNAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgbm90IE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gY2FuIG9ubHkgY2FsbCB3aGVuIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjc1NQogICAgLy8gZXhwb3J0IGNsYXNzIExvY2FsU3RhdGVDb250cmFjdCBleHRlbmRzIGFyYzQuQ29udHJhY3QgewogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgYnRvaQogICAgdHhuYXMgQWNjb3VudHMKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo4MTQKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIGdldF9pbXBsaWNpdF9rZXlfYXJjNF9hZGRyZXNzCiAgICBieXRlY18wIC8vIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnRjXzAgLy8gMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX19nZXRfaW1wbGljaXRfa2V5X2FyYzRfdWludG4xMjhfcm91dGVAODoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo4MTkKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIG5vdCBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGNhbiBvbmx5IGNhbGwgd2hlbiBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo3NTUKICAgIC8vIGV4cG9ydCBjbGFzcyBMb2NhbFN0YXRlQ29udHJhY3QgZXh0ZW5kcyBhcmM0LkNvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGJ0b2kKICAgIHR4bmFzIEFjY291bnRzCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6ODE5CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiBnZXRfaW1wbGljaXRfa2V5X2FyYzRfdWludG4xMjgKICAgIGJ5dGVjXzAgLy8gMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludGNfMCAvLyAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX2dldF9pbXBsaWNpdF9rZXlfYXJjNF9keW5hbWljX2J5dGVzX3JvdXRlQDk6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6ODI0CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBub3QgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBjYW4gb25seSBjYWxsIHdoZW4gbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NzU1CiAgICAvLyBleHBvcnQgY2xhc3MgTG9jYWxTdGF0ZUNvbnRyYWN0IGV4dGVuZHMgYXJjNC5Db250cmFjdCB7CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBidG9pCiAgICB0eG5hcyBBY2NvdW50cwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjgyNAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgZ2V0X2ltcGxpY2l0X2tleV9hcmM0X2R5bmFtaWNfYnl0ZXMKICAgIGJ5dGVjXzAgLy8gMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludGNfMCAvLyAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX2dldF9hcmM0X3VpbnRuNjRfcm91dGVAMTA6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6ODMwCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBub3QgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBjYW4gb25seSBjYWxsIHdoZW4gbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NzU1CiAgICAvLyBleHBvcnQgY2xhc3MgTG9jYWxTdGF0ZUNvbnRyYWN0IGV4dGVuZHMgYXJjNC5Db250cmFjdCB7CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBidG9pCiAgICB0eG5hcyBBY2NvdW50cwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjgzMAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgZ2V0X2FyYzRfdWludG42NAogICAgYnl0ZWNfMCAvLyAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50Y18wIC8vIDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fZ2V0X2FyYzRfc3RyX3JvdXRlQDExOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjgzNQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgbm90IE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gY2FuIG9ubHkgY2FsbCB3aGVuIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjc1NQogICAgLy8gZXhwb3J0IGNsYXNzIExvY2FsU3RhdGVDb250cmFjdCBleHRlbmRzIGFyYzQuQ29udHJhY3QgewogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgYnRvaQogICAgdHhuYXMgQWNjb3VudHMKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo4MzUKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIGdldF9hcmM0X3N0cgogICAgYnl0ZWNfMCAvLyAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50Y18wIC8vIDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fZ2V0X2FyYzRfYnl0ZV9yb3V0ZUAxMjoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo4NDAKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIG5vdCBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGNhbiBvbmx5IGNhbGwgd2hlbiBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo3NTUKICAgIC8vIGV4cG9ydCBjbGFzcyBMb2NhbFN0YXRlQ29udHJhY3QgZXh0ZW5kcyBhcmM0LkNvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGJ0b2kKICAgIHR4bmFzIEFjY291bnRzCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6ODQwCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiBnZXRfYXJjNF9ieXRlCiAgICBieXRlY18wIC8vIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnRjXzAgLy8gMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX19nZXRfYXJjNF9ib29sX3JvdXRlQDEzOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjg0NQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgbm90IE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gY2FuIG9ubHkgY2FsbCB3aGVuIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjc1NQogICAgLy8gZXhwb3J0IGNsYXNzIExvY2FsU3RhdGVDb250cmFjdCBleHRlbmRzIGFyYzQuQ29udHJhY3QgewogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgYnRvaQogICAgdHhuYXMgQWNjb3VudHMKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo4NDUKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIGdldF9hcmM0X2Jvb2wKICAgIGJ5dGVjXzAgLy8gMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludGNfMCAvLyAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX2dldF9hcmM0X2FkZHJlc3Nfcm91dGVAMTQ6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6ODUwCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBub3QgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBjYW4gb25seSBjYWxsIHdoZW4gbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NzU1CiAgICAvLyBleHBvcnQgY2xhc3MgTG9jYWxTdGF0ZUNvbnRyYWN0IGV4dGVuZHMgYXJjNC5Db250cmFjdCB7CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBidG9pCiAgICB0eG5hcyBBY2NvdW50cwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjg1MAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgZ2V0X2FyYzRfYWRkcmVzcwogICAgYnl0ZWNfMCAvLyAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50Y18wIC8vIDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fZ2V0X2FyYzRfdWludG4xMjhfcm91dGVAMTU6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6ODU1CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBub3QgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBjYW4gb25seSBjYWxsIHdoZW4gbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NzU1CiAgICAvLyBleHBvcnQgY2xhc3MgTG9jYWxTdGF0ZUNvbnRyYWN0IGV4dGVuZHMgYXJjNC5Db250cmFjdCB7CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBidG9pCiAgICB0eG5hcyBBY2NvdW50cwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjg1NQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgZ2V0X2FyYzRfdWludG4xMjgKICAgIGJ5dGVjXzAgLy8gMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludGNfMCAvLyAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX2dldF9hcmM0X2R5bmFtaWNfYnl0ZXNfcm91dGVAMTY6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6ODYwCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBub3QgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBjYW4gb25seSBjYWxsIHdoZW4gbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NzU1CiAgICAvLyBleHBvcnQgY2xhc3MgTG9jYWxTdGF0ZUNvbnRyYWN0IGV4dGVuZHMgYXJjNC5Db250cmFjdCB7CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBidG9pCiAgICB0eG5hcyBBY2NvdW50cwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjg2MAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgZ2V0X2FyYzRfZHluYW1pY19ieXRlcwogICAgYnl0ZWNfMCAvLyAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50Y18wIC8vIDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fYmFyZV9yb3V0aW5nQDE5OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjc1NQogICAgLy8gZXhwb3J0IGNsYXNzIExvY2FsU3RhdGVDb250cmFjdCBleHRlbmRzIGFyYzQuQ29udHJhY3QgewogICAgdHhuIE9uQ29tcGxldGlvbgogICAgYm56IF9fcHV5YV9hcmM0X3JvdXRlcl9fX2FmdGVyX2lmX2Vsc2VAMjMKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICAhCiAgICBhc3NlcnQgLy8gY2FuIG9ubHkgY2FsbCB3aGVuIGNyZWF0aW5nCiAgICBpbnRjXzAgLy8gMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX19hZnRlcl9pZl9lbHNlQDIzOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjc1NQogICAgLy8gZXhwb3J0IGNsYXNzIExvY2FsU3RhdGVDb250cmFjdCBleHRlbmRzIGFyYzQuQ29udHJhY3QgewogICAgaW50Y18xIC8vIDAKICAgIHJldHN1YgoKCi8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo6TG9jYWxTdGF0ZUNvbnRyYWN0Lm9wdF9pbigpIC0+IHZvaWQ6Cm9wdF9pbjoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo3NzQtNzc1CiAgICAvLyBAYXJjNC5hYmltZXRob2QoeyBhbGxvd0FjdGlvbnM6IFsnT3B0SW4nXSB9KQogICAgLy8gb3B0X2luKCk6IHZvaWQgewogICAgcHJvdG8gMCAwCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6Nzc2CiAgICAvLyB0aGlzLmltcGxpY2l0S2V5QXJjNFVpbnRONjQoR2xvYmFsLmNyZWF0b3JBZGRyZXNzKS52YWx1ZSA9IG5ldyBVaW50TjY0KDEzMzcpCiAgICBnbG9iYWwgQ3JlYXRvckFkZHJlc3MKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo3NTcKICAgIC8vIGltcGxpY2l0S2V5QXJjNFVpbnRONjQgPSBMb2NhbFN0YXRlPFVpbnRONjQ+KCkKICAgIGJ5dGVjXzEgLy8gImltcGxpY2l0S2V5QXJjNFVpbnRONjQiCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6Nzc2CiAgICAvLyB0aGlzLmltcGxpY2l0S2V5QXJjNFVpbnRONjQoR2xvYmFsLmNyZWF0b3JBZGRyZXNzKS52YWx1ZSA9IG5ldyBVaW50TjY0KDEzMzcpCiAgICBieXRlY18yIC8vIDB4MDAwMDAwMDAwMDAwMDUzOQogICAgYXBwX2xvY2FsX3B1dAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjc3NwogICAgLy8gdGhpcy5pbXBsaWNpdEtleUFyYzRTdHIoR2xvYmFsLmNyZWF0b3JBZGRyZXNzKS52YWx1ZSA9IG5ldyBTdHIoJ0hlbGxvJykKICAgIGdsb2JhbCBDcmVhdG9yQWRkcmVzcwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjc1OAogICAgLy8gaW1wbGljaXRLZXlBcmM0U3RyID0gTG9jYWxTdGF0ZTxTdHI+KCkKICAgIGJ5dGVjXzMgLy8gImltcGxpY2l0S2V5QXJjNFN0ciIKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo3NzcKICAgIC8vIHRoaXMuaW1wbGljaXRLZXlBcmM0U3RyKEdsb2JhbC5jcmVhdG9yQWRkcmVzcykudmFsdWUgPSBuZXcgU3RyKCdIZWxsbycpCiAgICBieXRlYyA0IC8vIDB4MDAwNTQ4NjU2YzZjNmYKICAgIGFwcF9sb2NhbF9wdXQKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo3NzgKICAgIC8vIHRoaXMuaW1wbGljaXRLZXlBcmM0Qnl0ZShHbG9iYWwuY3JlYXRvckFkZHJlc3MpLnZhbHVlID0gbmV3IEJ5dGUoMCkKICAgIGdsb2JhbCBDcmVhdG9yQWRkcmVzcwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjc1OQogICAgLy8gaW1wbGljaXRLZXlBcmM0Qnl0ZSA9IExvY2FsU3RhdGU8Qnl0ZT4oKQogICAgYnl0ZWMgNSAvLyAiaW1wbGljaXRLZXlBcmM0Qnl0ZSIKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo3NzgKICAgIC8vIHRoaXMuaW1wbGljaXRLZXlBcmM0Qnl0ZShHbG9iYWwuY3JlYXRvckFkZHJlc3MpLnZhbHVlID0gbmV3IEJ5dGUoMCkKICAgIHB1c2hieXRlcyAweDAwCiAgICBhcHBfbG9jYWxfcHV0CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6Nzc5CiAgICAvLyB0aGlzLmltcGxpY2l0S2V5QXJjNEJvb2woR2xvYmFsLmNyZWF0b3JBZGRyZXNzKS52YWx1ZSA9IG5ldyBCb29sKHRydWUpCiAgICBnbG9iYWwgQ3JlYXRvckFkZHJlc3MKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo3NjAKICAgIC8vIGltcGxpY2l0S2V5QXJjNEJvb2wgPSBMb2NhbFN0YXRlPEJvb2w+KCkKICAgIGJ5dGVjIDYgLy8gImltcGxpY2l0S2V5QXJjNEJvb2wiCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6Nzc5CiAgICAvLyB0aGlzLmltcGxpY2l0S2V5QXJjNEJvb2woR2xvYmFsLmNyZWF0b3JBZGRyZXNzKS52YWx1ZSA9IG5ldyBCb29sKHRydWUpCiAgICBwdXNoYnl0ZXMgMHg4MAogICAgYXBwX2xvY2FsX3B1dAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjc4MAogICAgLy8gdGhpcy5pbXBsaWNpdEtleUFyYzRBZGRyZXNzKEdsb2JhbC5jcmVhdG9yQWRkcmVzcykudmFsdWUgPSBuZXcgQWRkcmVzcyhHbG9iYWwuY3JlYXRvckFkZHJlc3MpCiAgICBnbG9iYWwgQ3JlYXRvckFkZHJlc3MKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo3NjEKICAgIC8vIGltcGxpY2l0S2V5QXJjNEFkZHJlc3MgPSBMb2NhbFN0YXRlPEFkZHJlc3M+KCkKICAgIGJ5dGVjIDcgLy8gImltcGxpY2l0S2V5QXJjNEFkZHJlc3MiCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NzgwCiAgICAvLyB0aGlzLmltcGxpY2l0S2V5QXJjNEFkZHJlc3MoR2xvYmFsLmNyZWF0b3JBZGRyZXNzKS52YWx1ZSA9IG5ldyBBZGRyZXNzKEdsb2JhbC5jcmVhdG9yQWRkcmVzcykKICAgIGdsb2JhbCBDcmVhdG9yQWRkcmVzcwogICAgYXBwX2xvY2FsX3B1dAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjc4MQogICAgLy8gdGhpcy5pbXBsaWNpdEtleUFyYzRVaW50TjEyOChHbG9iYWwuY3JlYXRvckFkZHJlc3MpLnZhbHVlID0gbmV3IFVpbnROMTI4KDJuICoqIDEwMG4pCiAgICBnbG9iYWwgQ3JlYXRvckFkZHJlc3MKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo3NjIKICAgIC8vIGltcGxpY2l0S2V5QXJjNFVpbnROMTI4ID0gTG9jYWxTdGF0ZTxVaW50TjEyOD4oKQogICAgYnl0ZWMgOCAvLyAiaW1wbGljaXRLZXlBcmM0VWludE4xMjgiCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NzgxCiAgICAvLyB0aGlzLmltcGxpY2l0S2V5QXJjNFVpbnROMTI4KEdsb2JhbC5jcmVhdG9yQWRkcmVzcykudmFsdWUgPSBuZXcgVWludE4xMjgoMm4gKiogMTAwbikKICAgIGJ5dGVjIDkgLy8gMHgwMDAwMDAxMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMAogICAgYXBwX2xvY2FsX3B1dAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjc4MgogICAgLy8gdGhpcy5pbXBsaWNpdEtleUFyYzREeW5hbWljQnl0ZXMoR2xvYmFsLmNyZWF0b3JBZGRyZXNzKS52YWx1ZSA9IG5ldyBEeW5hbWljQnl0ZXMoJ2R5bmFtaWMgYnl0ZXMnKQogICAgZ2xvYmFsIENyZWF0b3JBZGRyZXNzCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NzYzCiAgICAvLyBpbXBsaWNpdEtleUFyYzREeW5hbWljQnl0ZXMgPSBMb2NhbFN0YXRlPER5bmFtaWNCeXRlcz4oKQogICAgYnl0ZWMgMTAgLy8gImltcGxpY2l0S2V5QXJjNER5bmFtaWNCeXRlcyIKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo3ODIKICAgIC8vIHRoaXMuaW1wbGljaXRLZXlBcmM0RHluYW1pY0J5dGVzKEdsb2JhbC5jcmVhdG9yQWRkcmVzcykudmFsdWUgPSBuZXcgRHluYW1pY0J5dGVzKCdkeW5hbWljIGJ5dGVzJykKICAgIGJ5dGVjIDExIC8vIDB4MDAwZDY0Nzk2ZTYxNmQ2OTYzMjA2Mjc5NzQ2NTczCiAgICBhcHBfbG9jYWxfcHV0CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6Nzg0CiAgICAvLyB0aGlzLmFyYzRVaW50TjY0KEdsb2JhbC5jcmVhdG9yQWRkcmVzcykudmFsdWUgPSBuZXcgVWludE42NCgxMzM3KQogICAgZ2xvYmFsIENyZWF0b3JBZGRyZXNzCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NzY2CiAgICAvLyBhcmM0VWludE42NCA9IExvY2FsU3RhdGU8VWludE42ND4oeyBrZXk6ICdleHBsaWNpdF9rZXlfYXJjNF91aW50bjY0JyB9KQogICAgYnl0ZWMgMTIgLy8gImV4cGxpY2l0X2tleV9hcmM0X3VpbnRuNjQiCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6Nzg0CiAgICAvLyB0aGlzLmFyYzRVaW50TjY0KEdsb2JhbC5jcmVhdG9yQWRkcmVzcykudmFsdWUgPSBuZXcgVWludE42NCgxMzM3KQogICAgYnl0ZWNfMiAvLyAweDAwMDAwMDAwMDAwMDA1MzkKICAgIGFwcF9sb2NhbF9wdXQKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo3ODUKICAgIC8vIHRoaXMuYXJjNFN0cihHbG9iYWwuY3JlYXRvckFkZHJlc3MpLnZhbHVlID0gbmV3IFN0cignSGVsbG8nKQogICAgZ2xvYmFsIENyZWF0b3JBZGRyZXNzCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NzY3CiAgICAvLyBhcmM0U3RyID0gTG9jYWxTdGF0ZTxTdHI+KHsga2V5OiAnZXhwbGljaXRfa2V5X2FyYzRfc3RyJyB9KQogICAgYnl0ZWMgMTMgLy8gImV4cGxpY2l0X2tleV9hcmM0X3N0ciIKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo3ODUKICAgIC8vIHRoaXMuYXJjNFN0cihHbG9iYWwuY3JlYXRvckFkZHJlc3MpLnZhbHVlID0gbmV3IFN0cignSGVsbG8nKQogICAgYnl0ZWMgNCAvLyAweDAwMDU0ODY1NmM2YzZmCiAgICBhcHBfbG9jYWxfcHV0CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6Nzg2CiAgICAvLyB0aGlzLmFyYzRCeXRlKEdsb2JhbC5jcmVhdG9yQWRkcmVzcykudmFsdWUgPSBuZXcgQnl0ZSgwKQogICAgZ2xvYmFsIENyZWF0b3JBZGRyZXNzCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NzY4CiAgICAvLyBhcmM0Qnl0ZSA9IExvY2FsU3RhdGU8Qnl0ZT4oeyBrZXk6ICdleHBsaWNpdF9rZXlfYXJjNF9ieXRlJyB9KQogICAgYnl0ZWMgMTQgLy8gImV4cGxpY2l0X2tleV9hcmM0X2J5dGUiCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6Nzg2CiAgICAvLyB0aGlzLmFyYzRCeXRlKEdsb2JhbC5jcmVhdG9yQWRkcmVzcykudmFsdWUgPSBuZXcgQnl0ZSgwKQogICAgcHVzaGJ5dGVzIDB4MDAKICAgIGFwcF9sb2NhbF9wdXQKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo3ODcKICAgIC8vIHRoaXMuYXJjNEJvb2woR2xvYmFsLmNyZWF0b3JBZGRyZXNzKS52YWx1ZSA9IG5ldyBCb29sKHRydWUpCiAgICBnbG9iYWwgQ3JlYXRvckFkZHJlc3MKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo3NjkKICAgIC8vIGFyYzRCb29sID0gTG9jYWxTdGF0ZTxCb29sPih7IGtleTogJ2V4cGxpY2l0X2tleV9hcmM0X2Jvb2wnIH0pCiAgICBieXRlYyAxNSAvLyAiZXhwbGljaXRfa2V5X2FyYzRfYm9vbCIKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo3ODcKICAgIC8vIHRoaXMuYXJjNEJvb2woR2xvYmFsLmNyZWF0b3JBZGRyZXNzKS52YWx1ZSA9IG5ldyBCb29sKHRydWUpCiAgICBwdXNoYnl0ZXMgMHg4MAogICAgYXBwX2xvY2FsX3B1dAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjc4OAogICAgLy8gdGhpcy5hcmM0QWRkcmVzcyhHbG9iYWwuY3JlYXRvckFkZHJlc3MpLnZhbHVlID0gbmV3IEFkZHJlc3MoR2xvYmFsLmNyZWF0b3JBZGRyZXNzKQogICAgZ2xvYmFsIENyZWF0b3JBZGRyZXNzCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NzcwCiAgICAvLyBhcmM0QWRkcmVzcyA9IExvY2FsU3RhdGU8QWRkcmVzcz4oeyBrZXk6ICdleHBsaWNpdF9rZXlfYXJjNF9hZGRyZXNzJyB9KQogICAgYnl0ZWMgMTYgLy8gImV4cGxpY2l0X2tleV9hcmM0X2FkZHJlc3MiCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6Nzg4CiAgICAvLyB0aGlzLmFyYzRBZGRyZXNzKEdsb2JhbC5jcmVhdG9yQWRkcmVzcykudmFsdWUgPSBuZXcgQWRkcmVzcyhHbG9iYWwuY3JlYXRvckFkZHJlc3MpCiAgICBnbG9iYWwgQ3JlYXRvckFkZHJlc3MKICAgIGFwcF9sb2NhbF9wdXQKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo3ODkKICAgIC8vIHRoaXMuYXJjNFVpbnROMTI4KEdsb2JhbC5jcmVhdG9yQWRkcmVzcykudmFsdWUgPSBuZXcgVWludE4xMjgoMm4gKiogMTAwbikKICAgIGdsb2JhbCBDcmVhdG9yQWRkcmVzcwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjc3MQogICAgLy8gYXJjNFVpbnROMTI4ID0gTG9jYWxTdGF0ZTxVaW50TjEyOD4oeyBrZXk6ICdleHBsaWNpdF9rZXlfYXJjNF91aW50bjEyOCcgfSkKICAgIGJ5dGVjIDE3IC8vICJleHBsaWNpdF9rZXlfYXJjNF91aW50bjEyOCIKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo3ODkKICAgIC8vIHRoaXMuYXJjNFVpbnROMTI4KEdsb2JhbC5jcmVhdG9yQWRkcmVzcykudmFsdWUgPSBuZXcgVWludE4xMjgoMm4gKiogMTAwbikKICAgIGJ5dGVjIDkgLy8gMHgwMDAwMDAxMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMAogICAgYXBwX2xvY2FsX3B1dAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjc5MAogICAgLy8gdGhpcy5hcmM0RHluYW1pY0J5dGVzKEdsb2JhbC5jcmVhdG9yQWRkcmVzcykudmFsdWUgPSBuZXcgRHluYW1pY0J5dGVzKCdkeW5hbWljIGJ5dGVzJykKICAgIGdsb2JhbCBDcmVhdG9yQWRkcmVzcwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjc3MgogICAgLy8gYXJjNER5bmFtaWNCeXRlcyA9IExvY2FsU3RhdGU8RHluYW1pY0J5dGVzPih7IGtleTogJ2V4cGxpY2l0X2tleV9hcmM0X2R5bmFtaWNfYnl0ZXMnIH0pCiAgICBieXRlYyAxOCAvLyAiZXhwbGljaXRfa2V5X2FyYzRfZHluYW1pY19ieXRlcyIKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo3OTAKICAgIC8vIHRoaXMuYXJjNER5bmFtaWNCeXRlcyhHbG9iYWwuY3JlYXRvckFkZHJlc3MpLnZhbHVlID0gbmV3IER5bmFtaWNCeXRlcygnZHluYW1pYyBieXRlcycpCiAgICBieXRlYyAxMSAvLyAweDAwMGQ2NDc5NmU2MTZkNjk2MzIwNjI3OTc0NjU3MwogICAgYXBwX2xvY2FsX3B1dAogICAgcmV0c3ViCgoKLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjpMb2NhbFN0YXRlQ29udHJhY3QuZ2V0X2ltcGxpY2l0X2tleV9hcmM0X3VpbnRuNjQoYTogYnl0ZXMpIC0+IGJ5dGVzOgpnZXRfaW1wbGljaXRfa2V5X2FyYzRfdWludG42NDoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo3OTQtNzk1CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gZ2V0X2ltcGxpY2l0X2tleV9hcmM0X3VpbnRuNjQoYTogQWNjb3VudCk6IFVpbnRONjQgewogICAgcHJvdG8gMSAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6Nzk2CiAgICAvLyByZXR1cm4gdGhpcy5pbXBsaWNpdEtleUFyYzRVaW50TjY0KGEpLnZhbHVlCiAgICBmcmFtZV9kaWcgLTEKICAgIGludGNfMSAvLyAwCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NzU3CiAgICAvLyBpbXBsaWNpdEtleUFyYzRVaW50TjY0ID0gTG9jYWxTdGF0ZTxVaW50TjY0PigpCiAgICBieXRlY18xIC8vICJpbXBsaWNpdEtleUFyYzRVaW50TjY0IgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjc5NgogICAgLy8gcmV0dXJuIHRoaXMuaW1wbGljaXRLZXlBcmM0VWludE42NChhKS52YWx1ZQogICAgYXBwX2xvY2FsX2dldF9leAogICAgYXNzZXJ0IC8vIGNoZWNrIExvY2FsU3RhdGUgZXhpc3RzCiAgICByZXRzdWIKCgovLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OkxvY2FsU3RhdGVDb250cmFjdC5nZXRfaW1wbGljaXRfa2V5X2FyYzRfc3RyKGE6IGJ5dGVzKSAtPiBieXRlczoKZ2V0X2ltcGxpY2l0X2tleV9hcmM0X3N0cjoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo3OTktODAwCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gZ2V0X2ltcGxpY2l0X2tleV9hcmM0X3N0cihhOiBBY2NvdW50KTogU3RyIHsKICAgIHByb3RvIDEgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjgwMQogICAgLy8gcmV0dXJuIHRoaXMuaW1wbGljaXRLZXlBcmM0U3RyKGEpLnZhbHVlCiAgICBmcmFtZV9kaWcgLTEKICAgIGludGNfMSAvLyAwCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NzU4CiAgICAvLyBpbXBsaWNpdEtleUFyYzRTdHIgPSBMb2NhbFN0YXRlPFN0cj4oKQogICAgYnl0ZWNfMyAvLyAiaW1wbGljaXRLZXlBcmM0U3RyIgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjgwMQogICAgLy8gcmV0dXJuIHRoaXMuaW1wbGljaXRLZXlBcmM0U3RyKGEpLnZhbHVlCiAgICBhcHBfbG9jYWxfZ2V0X2V4CiAgICBhc3NlcnQgLy8gY2hlY2sgTG9jYWxTdGF0ZSBleGlzdHMKICAgIHJldHN1YgoKCi8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo6TG9jYWxTdGF0ZUNvbnRyYWN0LmdldF9pbXBsaWNpdF9rZXlfYXJjNF9ieXRlKGE6IGJ5dGVzKSAtPiBieXRlczoKZ2V0X2ltcGxpY2l0X2tleV9hcmM0X2J5dGU6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6ODA0LTgwNQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIGdldF9pbXBsaWNpdF9rZXlfYXJjNF9ieXRlKGE6IEFjY291bnQpOiBCeXRlIHsKICAgIHByb3RvIDEgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjgwNgogICAgLy8gcmV0dXJuIHRoaXMuaW1wbGljaXRLZXlBcmM0Qnl0ZShhKS52YWx1ZQogICAgZnJhbWVfZGlnIC0xCiAgICBpbnRjXzEgLy8gMAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjc1OQogICAgLy8gaW1wbGljaXRLZXlBcmM0Qnl0ZSA9IExvY2FsU3RhdGU8Qnl0ZT4oKQogICAgYnl0ZWMgNSAvLyAiaW1wbGljaXRLZXlBcmM0Qnl0ZSIKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo4MDYKICAgIC8vIHJldHVybiB0aGlzLmltcGxpY2l0S2V5QXJjNEJ5dGUoYSkudmFsdWUKICAgIGFwcF9sb2NhbF9nZXRfZXgKICAgIGFzc2VydCAvLyBjaGVjayBMb2NhbFN0YXRlIGV4aXN0cwogICAgcmV0c3ViCgoKLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjpMb2NhbFN0YXRlQ29udHJhY3QuZ2V0X2ltcGxpY2l0X2tleV9hcmM0X2Jvb2woYTogYnl0ZXMpIC0+IGJ5dGVzOgpnZXRfaW1wbGljaXRfa2V5X2FyYzRfYm9vbDoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo4MDktODEwCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gZ2V0X2ltcGxpY2l0X2tleV9hcmM0X2Jvb2woYTogQWNjb3VudCk6IEJvb2wgewogICAgcHJvdG8gMSAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6ODExCiAgICAvLyByZXR1cm4gdGhpcy5pbXBsaWNpdEtleUFyYzRCb29sKGEpLnZhbHVlCiAgICBmcmFtZV9kaWcgLTEKICAgIGludGNfMSAvLyAwCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NzYwCiAgICAvLyBpbXBsaWNpdEtleUFyYzRCb29sID0gTG9jYWxTdGF0ZTxCb29sPigpCiAgICBieXRlYyA2IC8vICJpbXBsaWNpdEtleUFyYzRCb29sIgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjgxMQogICAgLy8gcmV0dXJuIHRoaXMuaW1wbGljaXRLZXlBcmM0Qm9vbChhKS52YWx1ZQogICAgYXBwX2xvY2FsX2dldF9leAogICAgYXNzZXJ0IC8vIGNoZWNrIExvY2FsU3RhdGUgZXhpc3RzCiAgICByZXRzdWIKCgovLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OkxvY2FsU3RhdGVDb250cmFjdC5nZXRfaW1wbGljaXRfa2V5X2FyYzRfYWRkcmVzcyhhOiBieXRlcykgLT4gYnl0ZXM6CmdldF9pbXBsaWNpdF9rZXlfYXJjNF9hZGRyZXNzOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjgxNC04MTUKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBnZXRfaW1wbGljaXRfa2V5X2FyYzRfYWRkcmVzcyhhOiBBY2NvdW50KTogQWRkcmVzcyB7CiAgICBwcm90byAxIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo4MTYKICAgIC8vIHJldHVybiB0aGlzLmltcGxpY2l0S2V5QXJjNEFkZHJlc3MoYSkudmFsdWUKICAgIGZyYW1lX2RpZyAtMQogICAgaW50Y18xIC8vIDAKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo3NjEKICAgIC8vIGltcGxpY2l0S2V5QXJjNEFkZHJlc3MgPSBMb2NhbFN0YXRlPEFkZHJlc3M+KCkKICAgIGJ5dGVjIDcgLy8gImltcGxpY2l0S2V5QXJjNEFkZHJlc3MiCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6ODE2CiAgICAvLyByZXR1cm4gdGhpcy5pbXBsaWNpdEtleUFyYzRBZGRyZXNzKGEpLnZhbHVlCiAgICBhcHBfbG9jYWxfZ2V0X2V4CiAgICBhc3NlcnQgLy8gY2hlY2sgTG9jYWxTdGF0ZSBleGlzdHMKICAgIHJldHN1YgoKCi8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo6TG9jYWxTdGF0ZUNvbnRyYWN0LmdldF9pbXBsaWNpdF9rZXlfYXJjNF91aW50bjEyOChhOiBieXRlcykgLT4gYnl0ZXM6CmdldF9pbXBsaWNpdF9rZXlfYXJjNF91aW50bjEyODoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo4MTktODIwCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gZ2V0X2ltcGxpY2l0X2tleV9hcmM0X3VpbnRuMTI4KGE6IEFjY291bnQpOiBVaW50TjEyOCB7CiAgICBwcm90byAxIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo4MjEKICAgIC8vIHJldHVybiB0aGlzLmltcGxpY2l0S2V5QXJjNFVpbnROMTI4KGEpLnZhbHVlCiAgICBmcmFtZV9kaWcgLTEKICAgIGludGNfMSAvLyAwCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NzYyCiAgICAvLyBpbXBsaWNpdEtleUFyYzRVaW50TjEyOCA9IExvY2FsU3RhdGU8VWludE4xMjg+KCkKICAgIGJ5dGVjIDggLy8gImltcGxpY2l0S2V5QXJjNFVpbnROMTI4IgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjgyMQogICAgLy8gcmV0dXJuIHRoaXMuaW1wbGljaXRLZXlBcmM0VWludE4xMjgoYSkudmFsdWUKICAgIGFwcF9sb2NhbF9nZXRfZXgKICAgIGFzc2VydCAvLyBjaGVjayBMb2NhbFN0YXRlIGV4aXN0cwogICAgcmV0c3ViCgoKLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjpMb2NhbFN0YXRlQ29udHJhY3QuZ2V0X2ltcGxpY2l0X2tleV9hcmM0X2R5bmFtaWNfYnl0ZXMoYTogYnl0ZXMpIC0+IGJ5dGVzOgpnZXRfaW1wbGljaXRfa2V5X2FyYzRfZHluYW1pY19ieXRlczoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo4MjQtODI1CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gZ2V0X2ltcGxpY2l0X2tleV9hcmM0X2R5bmFtaWNfYnl0ZXMoYTogQWNjb3VudCk6IER5bmFtaWNCeXRlcyB7CiAgICBwcm90byAxIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo4MjYKICAgIC8vIHJldHVybiB0aGlzLmltcGxpY2l0S2V5QXJjNER5bmFtaWNCeXRlcyhhKS52YWx1ZQogICAgZnJhbWVfZGlnIC0xCiAgICBpbnRjXzEgLy8gMAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjc2MwogICAgLy8gaW1wbGljaXRLZXlBcmM0RHluYW1pY0J5dGVzID0gTG9jYWxTdGF0ZTxEeW5hbWljQnl0ZXM+KCkKICAgIGJ5dGVjIDEwIC8vICJpbXBsaWNpdEtleUFyYzREeW5hbWljQnl0ZXMiCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6ODI2CiAgICAvLyByZXR1cm4gdGhpcy5pbXBsaWNpdEtleUFyYzREeW5hbWljQnl0ZXMoYSkudmFsdWUKICAgIGFwcF9sb2NhbF9nZXRfZXgKICAgIGFzc2VydCAvLyBjaGVjayBMb2NhbFN0YXRlIGV4aXN0cwogICAgcmV0c3ViCgoKLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjpMb2NhbFN0YXRlQ29udHJhY3QuZ2V0X2FyYzRfdWludG42NChhOiBieXRlcykgLT4gYnl0ZXM6CmdldF9hcmM0X3VpbnRuNjQ6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6ODMwLTgzMQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIGdldF9hcmM0X3VpbnRuNjQoYTogQWNjb3VudCk6IGFyYzQuVWludE42NCB7CiAgICBwcm90byAxIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo4MzIKICAgIC8vIHJldHVybiB0aGlzLmFyYzRVaW50TjY0KGEpLnZhbHVlCiAgICBmcmFtZV9kaWcgLTEKICAgIGludGNfMSAvLyAwCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NzY2CiAgICAvLyBhcmM0VWludE42NCA9IExvY2FsU3RhdGU8VWludE42ND4oeyBrZXk6ICdleHBsaWNpdF9rZXlfYXJjNF91aW50bjY0JyB9KQogICAgYnl0ZWMgMTIgLy8gImV4cGxpY2l0X2tleV9hcmM0X3VpbnRuNjQiCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6ODMyCiAgICAvLyByZXR1cm4gdGhpcy5hcmM0VWludE42NChhKS52YWx1ZQogICAgYXBwX2xvY2FsX2dldF9leAogICAgYXNzZXJ0IC8vIGNoZWNrIExvY2FsU3RhdGUgZXhpc3RzCiAgICByZXRzdWIKCgovLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OkxvY2FsU3RhdGVDb250cmFjdC5nZXRfYXJjNF9zdHIoYTogYnl0ZXMpIC0+IGJ5dGVzOgpnZXRfYXJjNF9zdHI6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6ODM1LTgzNgogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIGdldF9hcmM0X3N0cihhOiBBY2NvdW50KTogU3RyIHsKICAgIHByb3RvIDEgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjgzNwogICAgLy8gcmV0dXJuIHRoaXMuYXJjNFN0cihhKS52YWx1ZQogICAgZnJhbWVfZGlnIC0xCiAgICBpbnRjXzEgLy8gMAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjc2NwogICAgLy8gYXJjNFN0ciA9IExvY2FsU3RhdGU8U3RyPih7IGtleTogJ2V4cGxpY2l0X2tleV9hcmM0X3N0cicgfSkKICAgIGJ5dGVjIDEzIC8vICJleHBsaWNpdF9rZXlfYXJjNF9zdHIiCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6ODM3CiAgICAvLyByZXR1cm4gdGhpcy5hcmM0U3RyKGEpLnZhbHVlCiAgICBhcHBfbG9jYWxfZ2V0X2V4CiAgICBhc3NlcnQgLy8gY2hlY2sgTG9jYWxTdGF0ZSBleGlzdHMKICAgIHJldHN1YgoKCi8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo6TG9jYWxTdGF0ZUNvbnRyYWN0LmdldF9hcmM0X2J5dGUoYTogYnl0ZXMpIC0+IGJ5dGVzOgpnZXRfYXJjNF9ieXRlOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjg0MC04NDEKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBnZXRfYXJjNF9ieXRlKGE6IEFjY291bnQpOiBCeXRlIHsKICAgIHByb3RvIDEgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjg0MgogICAgLy8gcmV0dXJuIHRoaXMuYXJjNEJ5dGUoYSkudmFsdWUKICAgIGZyYW1lX2RpZyAtMQogICAgaW50Y18xIC8vIDAKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo3NjgKICAgIC8vIGFyYzRCeXRlID0gTG9jYWxTdGF0ZTxCeXRlPih7IGtleTogJ2V4cGxpY2l0X2tleV9hcmM0X2J5dGUnIH0pCiAgICBieXRlYyAxNCAvLyAiZXhwbGljaXRfa2V5X2FyYzRfYnl0ZSIKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo4NDIKICAgIC8vIHJldHVybiB0aGlzLmFyYzRCeXRlKGEpLnZhbHVlCiAgICBhcHBfbG9jYWxfZ2V0X2V4CiAgICBhc3NlcnQgLy8gY2hlY2sgTG9jYWxTdGF0ZSBleGlzdHMKICAgIHJldHN1YgoKCi8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo6TG9jYWxTdGF0ZUNvbnRyYWN0LmdldF9hcmM0X2Jvb2woYTogYnl0ZXMpIC0+IGJ5dGVzOgpnZXRfYXJjNF9ib29sOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjg0NS04NDYKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBnZXRfYXJjNF9ib29sKGE6IEFjY291bnQpOiBCb29sIHsKICAgIHByb3RvIDEgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjg0NwogICAgLy8gcmV0dXJuIHRoaXMuYXJjNEJvb2woYSkudmFsdWUKICAgIGZyYW1lX2RpZyAtMQogICAgaW50Y18xIC8vIDAKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo3NjkKICAgIC8vIGFyYzRCb29sID0gTG9jYWxTdGF0ZTxCb29sPih7IGtleTogJ2V4cGxpY2l0X2tleV9hcmM0X2Jvb2wnIH0pCiAgICBieXRlYyAxNSAvLyAiZXhwbGljaXRfa2V5X2FyYzRfYm9vbCIKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo4NDcKICAgIC8vIHJldHVybiB0aGlzLmFyYzRCb29sKGEpLnZhbHVlCiAgICBhcHBfbG9jYWxfZ2V0X2V4CiAgICBhc3NlcnQgLy8gY2hlY2sgTG9jYWxTdGF0ZSBleGlzdHMKICAgIHJldHN1YgoKCi8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo6TG9jYWxTdGF0ZUNvbnRyYWN0LmdldF9hcmM0X2FkZHJlc3MoYTogYnl0ZXMpIC0+IGJ5dGVzOgpnZXRfYXJjNF9hZGRyZXNzOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjg1MC04NTEKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBnZXRfYXJjNF9hZGRyZXNzKGE6IEFjY291bnQpOiBBZGRyZXNzIHsKICAgIHByb3RvIDEgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjg1MgogICAgLy8gcmV0dXJuIHRoaXMuYXJjNEFkZHJlc3MoYSkudmFsdWUKICAgIGZyYW1lX2RpZyAtMQogICAgaW50Y18xIC8vIDAKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo3NzAKICAgIC8vIGFyYzRBZGRyZXNzID0gTG9jYWxTdGF0ZTxBZGRyZXNzPih7IGtleTogJ2V4cGxpY2l0X2tleV9hcmM0X2FkZHJlc3MnIH0pCiAgICBieXRlYyAxNiAvLyAiZXhwbGljaXRfa2V5X2FyYzRfYWRkcmVzcyIKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo4NTIKICAgIC8vIHJldHVybiB0aGlzLmFyYzRBZGRyZXNzKGEpLnZhbHVlCiAgICBhcHBfbG9jYWxfZ2V0X2V4CiAgICBhc3NlcnQgLy8gY2hlY2sgTG9jYWxTdGF0ZSBleGlzdHMKICAgIHJldHN1YgoKCi8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo6TG9jYWxTdGF0ZUNvbnRyYWN0LmdldF9hcmM0X3VpbnRuMTI4KGE6IGJ5dGVzKSAtPiBieXRlczoKZ2V0X2FyYzRfdWludG4xMjg6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6ODU1LTg1NgogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIGdldF9hcmM0X3VpbnRuMTI4KGE6IEFjY291bnQpOiBVaW50TjEyOCB7CiAgICBwcm90byAxIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo4NTcKICAgIC8vIHJldHVybiB0aGlzLmFyYzRVaW50TjEyOChhKS52YWx1ZQogICAgZnJhbWVfZGlnIC0xCiAgICBpbnRjXzEgLy8gMAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjc3MQogICAgLy8gYXJjNFVpbnROMTI4ID0gTG9jYWxTdGF0ZTxVaW50TjEyOD4oeyBrZXk6ICdleHBsaWNpdF9rZXlfYXJjNF91aW50bjEyOCcgfSkKICAgIGJ5dGVjIDE3IC8vICJleHBsaWNpdF9rZXlfYXJjNF91aW50bjEyOCIKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo4NTcKICAgIC8vIHJldHVybiB0aGlzLmFyYzRVaW50TjEyOChhKS52YWx1ZQogICAgYXBwX2xvY2FsX2dldF9leAogICAgYXNzZXJ0IC8vIGNoZWNrIExvY2FsU3RhdGUgZXhpc3RzCiAgICByZXRzdWIKCgovLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OkxvY2FsU3RhdGVDb250cmFjdC5nZXRfYXJjNF9keW5hbWljX2J5dGVzKGE6IGJ5dGVzKSAtPiBieXRlczoKZ2V0X2FyYzRfZHluYW1pY19ieXRlczoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo4NjAtODYxCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gZ2V0X2FyYzRfZHluYW1pY19ieXRlcyhhOiBBY2NvdW50KTogRHluYW1pY0J5dGVzIHsKICAgIHByb3RvIDEgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjg2MgogICAgLy8gcmV0dXJuIHRoaXMuYXJjNER5bmFtaWNCeXRlcyhhKS52YWx1ZQogICAgZnJhbWVfZGlnIC0xCiAgICBpbnRjXzEgLy8gMAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjc3MgogICAgLy8gYXJjNER5bmFtaWNCeXRlcyA9IExvY2FsU3RhdGU8RHluYW1pY0J5dGVzPih7IGtleTogJ2V4cGxpY2l0X2tleV9hcmM0X2R5bmFtaWNfYnl0ZXMnIH0pCiAgICBieXRlYyAxOCAvLyAiZXhwbGljaXRfa2V5X2FyYzRfZHluYW1pY19ieXRlcyIKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo4NjIKICAgIC8vIHJldHVybiB0aGlzLmFyYzREeW5hbWljQnl0ZXMoYSkudmFsdWUKICAgIGFwcF9sb2NhbF9nZXRfZXgKICAgIGFzc2VydCAvLyBjaGVjayBMb2NhbFN0YXRlIGV4aXN0cwogICAgcmV0c3ViCg==", - "clear": "I3ByYWdtYSB2ZXJzaW9uIDEwCgp0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OkxvY2FsU3RhdGVDb250cmFjdC5jbGVhclN0YXRlUHJvZ3JhbToKICAgIHB1c2hpbnQgMSAvLyAxCiAgICByZXR1cm4K" - }, - "state": { - "global": { - "num_byte_slices": 0, - "num_uints": 0 - }, - "local": { - "num_byte_slices": 14, - "num_uints": 0 - } - }, - "schema": { - "global": { - "declared": {}, - "reserved": {} - }, - "local": { - "declared": { - "arc4Address": { - "type": "bytes", - "key": "explicit_key_arc4_address" - }, - "arc4Bool": { - "type": "bytes", - "key": "explicit_key_arc4_bool" - }, - "arc4Byte": { - "type": "bytes", - "key": "explicit_key_arc4_byte" - }, - "arc4DynamicBytes": { - "type": "bytes", - "key": "explicit_key_arc4_dynamic_bytes" - }, - "arc4Str": { - "type": "bytes", - "key": "explicit_key_arc4_str" - }, - "arc4UintN128": { - "type": "bytes", - "key": "explicit_key_arc4_uintn128" - }, - "arc4UintN64": { - "type": "bytes", - "key": "explicit_key_arc4_uintn64" - }, - "implicitKeyArc4Address": { - "type": "bytes", - "key": "implicitKeyArc4Address" - }, - "implicitKeyArc4Bool": { - "type": "bytes", - "key": "implicitKeyArc4Bool" - }, - "implicitKeyArc4Byte": { - "type": "bytes", - "key": "implicitKeyArc4Byte" - }, - "implicitKeyArc4DynamicBytes": { - "type": "bytes", - "key": "implicitKeyArc4DynamicBytes" - }, - "implicitKeyArc4Str": { - "type": "bytes", - "key": "implicitKeyArc4Str" - }, - "implicitKeyArc4UintN128": { - "type": "bytes", - "key": "implicitKeyArc4UintN128" - }, - "implicitKeyArc4UintN64": { - "type": "bytes", - "key": "implicitKeyArc4UintN64" - } - }, - "reserved": {} - } - }, - "contract": { - "name": "LocalStateContract", - "methods": [ - { - "name": "opt_in", - "args": [], - "readonly": false, - "returns": { - "type": "void" - } - }, - { - "name": "get_implicit_key_arc4_uintn64", - "args": [ - { - "type": "account", - "name": "a" - } - ], - "readonly": false, - "returns": { - "type": "uint64" - } - }, - { - "name": "get_implicit_key_arc4_str", - "args": [ - { - "type": "account", - "name": "a" - } - ], - "readonly": false, - "returns": { - "type": "string" - } - }, - { - "name": "get_implicit_key_arc4_byte", - "args": [ - { - "type": "account", - "name": "a" - } - ], - "readonly": false, - "returns": { - "type": "byte" - } - }, - { - "name": "get_implicit_key_arc4_bool", - "args": [ - { - "type": "account", - "name": "a" - } - ], - "readonly": false, - "returns": { - "type": "bool" - } - }, - { - "name": "get_implicit_key_arc4_address", - "args": [ - { - "type": "account", - "name": "a" - } - ], - "readonly": false, - "returns": { - "type": "address" - } - }, - { - "name": "get_implicit_key_arc4_uintn128", - "args": [ - { - "type": "account", - "name": "a" - } - ], - "readonly": false, - "returns": { - "type": "uint128" - } - }, - { - "name": "get_implicit_key_arc4_dynamic_bytes", - "args": [ - { - "type": "account", - "name": "a" - } - ], - "readonly": false, - "returns": { - "type": "byte[]" - } - }, - { - "name": "get_arc4_uintn64", - "args": [ - { - "type": "account", - "name": "a" - } - ], - "readonly": false, - "returns": { - "type": "uint64" - } - }, - { - "name": "get_arc4_str", - "args": [ - { - "type": "account", - "name": "a" - } - ], - "readonly": false, - "returns": { - "type": "string" - } - }, - { - "name": "get_arc4_byte", - "args": [ - { - "type": "account", - "name": "a" - } - ], - "readonly": false, - "returns": { - "type": "byte" - } - }, - { - "name": "get_arc4_bool", - "args": [ - { - "type": "account", - "name": "a" - } - ], - "readonly": false, - "returns": { - "type": "bool" - } - }, - { - "name": "get_arc4_address", - "args": [ - { - "type": "account", - "name": "a" - } - ], - "readonly": false, - "returns": { - "type": "address" - } - }, - { - "name": "get_arc4_uintn128", - "args": [ - { - "type": "account", - "name": "a" - } - ], - "readonly": false, - "returns": { - "type": "uint128" - } - }, - { - "name": "get_arc4_dynamic_bytes", - "args": [ - { - "type": "account", - "name": "a" - } - ], - "readonly": false, - "returns": { - "type": "byte[]" - } - } - ], - "networks": {} - }, - "bare_call_config": { - "no_op": "CREATE" - } -} \ No newline at end of file diff --git a/tests/artifacts/state-ops/data/LocalStateContract.arc56.json b/tests/artifacts/state-ops/data/LocalStateContract.arc56.json deleted file mode 100644 index f2de7ea..0000000 --- a/tests/artifacts/state-ops/data/LocalStateContract.arc56.json +++ /dev/null @@ -1,507 +0,0 @@ -{ - "name": "LocalStateContract", - "structs": {}, - "methods": [ - { - "name": "opt_in", - "args": [], - "returns": { - "type": "void" - }, - "actions": { - "create": [], - "call": [ - "OptIn" - ] - }, - "readonly": false, - "events": [], - "recommendations": {} - }, - { - "name": "get_implicit_key_arc4_uintn64", - "args": [ - { - "type": "account", - "name": "a" - } - ], - "returns": { - "type": "uint64" - }, - "actions": { - "create": [], - "call": [ - "NoOp" - ] - }, - "readonly": false, - "events": [], - "recommendations": {} - }, - { - "name": "get_implicit_key_arc4_str", - "args": [ - { - "type": "account", - "name": "a" - } - ], - "returns": { - "type": "string" - }, - "actions": { - "create": [], - "call": [ - "NoOp" - ] - }, - "readonly": false, - "events": [], - "recommendations": {} - }, - { - "name": "get_implicit_key_arc4_byte", - "args": [ - { - "type": "account", - "name": "a" - } - ], - "returns": { - "type": "byte" - }, - "actions": { - "create": [], - "call": [ - "NoOp" - ] - }, - "readonly": false, - "events": [], - "recommendations": {} - }, - { - "name": "get_implicit_key_arc4_bool", - "args": [ - { - "type": "account", - "name": "a" - } - ], - "returns": { - "type": "bool" - }, - "actions": { - "create": [], - "call": [ - "NoOp" - ] - }, - "readonly": false, - "events": [], - "recommendations": {} - }, - { - "name": "get_implicit_key_arc4_address", - "args": [ - { - "type": "account", - "name": "a" - } - ], - "returns": { - "type": "address" - }, - "actions": { - "create": [], - "call": [ - "NoOp" - ] - }, - "readonly": false, - "events": [], - "recommendations": {} - }, - { - "name": "get_implicit_key_arc4_uintn128", - "args": [ - { - "type": "account", - "name": "a" - } - ], - "returns": { - "type": "uint128" - }, - "actions": { - "create": [], - "call": [ - "NoOp" - ] - }, - "readonly": false, - "events": [], - "recommendations": {} - }, - { - "name": "get_implicit_key_arc4_dynamic_bytes", - "args": [ - { - "type": "account", - "name": "a" - } - ], - "returns": { - "type": "byte[]" - }, - "actions": { - "create": [], - "call": [ - "NoOp" - ] - }, - "readonly": false, - "events": [], - "recommendations": {} - }, - { - "name": "get_arc4_uintn64", - "args": [ - { - "type": "account", - "name": "a" - } - ], - "returns": { - "type": "uint64" - }, - "actions": { - "create": [], - "call": [ - "NoOp" - ] - }, - "readonly": false, - "events": [], - "recommendations": {} - }, - { - "name": "get_arc4_str", - "args": [ - { - "type": "account", - "name": "a" - } - ], - "returns": { - "type": "string" - }, - "actions": { - "create": [], - "call": [ - "NoOp" - ] - }, - "readonly": false, - "events": [], - "recommendations": {} - }, - { - "name": "get_arc4_byte", - "args": [ - { - "type": "account", - "name": "a" - } - ], - "returns": { - "type": "byte" - }, - "actions": { - "create": [], - "call": [ - "NoOp" - ] - }, - "readonly": false, - "events": [], - "recommendations": {} - }, - { - "name": "get_arc4_bool", - "args": [ - { - "type": "account", - "name": "a" - } - ], - "returns": { - "type": "bool" - }, - "actions": { - "create": [], - "call": [ - "NoOp" - ] - }, - "readonly": false, - "events": [], - "recommendations": {} - }, - { - "name": "get_arc4_address", - "args": [ - { - "type": "account", - "name": "a" - } - ], - "returns": { - "type": "address" - }, - "actions": { - "create": [], - "call": [ - "NoOp" - ] - }, - "readonly": false, - "events": [], - "recommendations": {} - }, - { - "name": "get_arc4_uintn128", - "args": [ - { - "type": "account", - "name": "a" - } - ], - "returns": { - "type": "uint128" - }, - "actions": { - "create": [], - "call": [ - "NoOp" - ] - }, - "readonly": false, - "events": [], - "recommendations": {} - }, - { - "name": "get_arc4_dynamic_bytes", - "args": [ - { - "type": "account", - "name": "a" - } - ], - "returns": { - "type": "byte[]" - }, - "actions": { - "create": [], - "call": [ - "NoOp" - ] - }, - "readonly": false, - "events": [], - "recommendations": {} - } - ], - "arcs": [ - 22, - 28 - ], - "networks": {}, - "state": { - "schema": { - "global": { - "ints": 0, - "bytes": 0 - }, - "local": { - "ints": 0, - "bytes": 14 - } - }, - "keys": { - "global": {}, - "local": { - "implicitKeyArc4UintN64": { - "keyType": "AVMString", - "valueType": "uint64", - "key": "aW1wbGljaXRLZXlBcmM0VWludE42NA==" - }, - "implicitKeyArc4Str": { - "keyType": "AVMString", - "valueType": "string", - "key": "aW1wbGljaXRLZXlBcmM0U3Ry" - }, - "implicitKeyArc4Byte": { - "keyType": "AVMString", - "valueType": "byte", - "key": "aW1wbGljaXRLZXlBcmM0Qnl0ZQ==" - }, - "implicitKeyArc4Bool": { - "keyType": "AVMString", - "valueType": "bool", - "key": "aW1wbGljaXRLZXlBcmM0Qm9vbA==" - }, - "implicitKeyArc4Address": { - "keyType": "AVMString", - "valueType": "address", - "key": "aW1wbGljaXRLZXlBcmM0QWRkcmVzcw==" - }, - "implicitKeyArc4UintN128": { - "keyType": "AVMString", - "valueType": "uint128", - "key": "aW1wbGljaXRLZXlBcmM0VWludE4xMjg=" - }, - "implicitKeyArc4DynamicBytes": { - "keyType": "AVMString", - "valueType": "byte[]", - "key": "aW1wbGljaXRLZXlBcmM0RHluYW1pY0J5dGVz" - }, - "arc4UintN64": { - "keyType": "AVMString", - "valueType": "uint64", - "key": "ZXhwbGljaXRfa2V5X2FyYzRfdWludG42NA==" - }, - "arc4Str": { - "keyType": "AVMString", - "valueType": "string", - "key": "ZXhwbGljaXRfa2V5X2FyYzRfc3Ry" - }, - "arc4Byte": { - "keyType": "AVMString", - "valueType": "byte", - "key": "ZXhwbGljaXRfa2V5X2FyYzRfYnl0ZQ==" - }, - "arc4Bool": { - "keyType": "AVMString", - "valueType": "bool", - "key": "ZXhwbGljaXRfa2V5X2FyYzRfYm9vbA==" - }, - "arc4Address": { - "keyType": "AVMString", - "valueType": "address", - "key": "ZXhwbGljaXRfa2V5X2FyYzRfYWRkcmVzcw==" - }, - "arc4UintN128": { - "keyType": "AVMString", - "valueType": "uint128", - "key": "ZXhwbGljaXRfa2V5X2FyYzRfdWludG4xMjg=" - }, - "arc4DynamicBytes": { - "keyType": "AVMString", - "valueType": "byte[]", - "key": "ZXhwbGljaXRfa2V5X2FyYzRfZHluYW1pY19ieXRlcw==" - } - }, - "box": {} - }, - "maps": { - "global": {}, - "local": {}, - "box": {} - } - }, - "bareActions": { - "create": [ - "NoOp" - ], - "call": [] - }, - "sourceInfo": { - "approval": { - "sourceInfo": [ - { - "pc": [ - 540, - 562, - 584, - 606, - 628, - 650, - 672, - 694, - 716, - 738, - 760, - 782, - 804, - 826 - ], - "errorMessage": "OnCompletion is not NoOp" - }, - { - "pc": [ - 528 - ], - "errorMessage": "OnCompletion is not OptIn" - }, - { - "pc": [ - 853 - ], - "errorMessage": "can only call when creating" - }, - { - "pc": [ - 531, - 543, - 565, - 587, - 609, - 631, - 653, - 675, - 697, - 719, - 741, - 763, - 785, - 807, - 829 - ], - "errorMessage": "can only call when not creating" - }, - { - "pc": [ - 968, - 978, - 989, - 1000, - 1011, - 1022, - 1033, - 1044, - 1055, - 1066, - 1077, - 1088, - 1099, - 1110 - ], - "errorMessage": "check LocalState exists" - } - ], - "pcOffsetMethod": "none" - }, - "clear": { - "sourceInfo": [], - "pcOffsetMethod": "none" - } - }, - "source": { - "approval": "I3ByYWdtYSB2ZXJzaW9uIDEwCgp0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OkxvY2FsU3RhdGVDb250cmFjdC5hcHByb3ZhbFByb2dyYW06CiAgICBpbnRjYmxvY2sgMSAwCiAgICBieXRlY2Jsb2NrIDB4MTUxZjdjNzUgImltcGxpY2l0S2V5QXJjNFVpbnRONjQiIDB4MDAwMDAwMDAwMDAwMDUzOSAiaW1wbGljaXRLZXlBcmM0U3RyIiAweDAwMDU0ODY1NmM2YzZmICJpbXBsaWNpdEtleUFyYzRCeXRlIiAiaW1wbGljaXRLZXlBcmM0Qm9vbCIgImltcGxpY2l0S2V5QXJjNEFkZHJlc3MiICJpbXBsaWNpdEtleUFyYzRVaW50TjEyOCIgMHgwMDAwMDAxMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMCAiaW1wbGljaXRLZXlBcmM0RHluYW1pY0J5dGVzIiAweDAwMGQ2NDc5NmU2MTZkNjk2MzIwNjI3OTc0NjU3MyAiZXhwbGljaXRfa2V5X2FyYzRfdWludG42NCIgImV4cGxpY2l0X2tleV9hcmM0X3N0ciIgImV4cGxpY2l0X2tleV9hcmM0X2J5dGUiICJleHBsaWNpdF9rZXlfYXJjNF9ib29sIiAiZXhwbGljaXRfa2V5X2FyYzRfYWRkcmVzcyIgImV4cGxpY2l0X2tleV9hcmM0X3VpbnRuMTI4IiAiZXhwbGljaXRfa2V5X2FyYzRfZHluYW1pY19ieXRlcyIKICAgIGNhbGxzdWIgX19wdXlhX2FyYzRfcm91dGVyX18KICAgIHJldHVybgoKCi8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo6TG9jYWxTdGF0ZUNvbnRyYWN0Ll9fcHV5YV9hcmM0X3JvdXRlcl9fKCkgLT4gdWludDY0OgpfX3B1eWFfYXJjNF9yb3V0ZXJfXzoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo3NTUKICAgIC8vIGV4cG9ydCBjbGFzcyBMb2NhbFN0YXRlQ29udHJhY3QgZXh0ZW5kcyBhcmM0LkNvbnRyYWN0IHsKICAgIHByb3RvIDAgMQogICAgdHhuIE51bUFwcEFyZ3MKICAgIGJ6IF9fcHV5YV9hcmM0X3JvdXRlcl9fX2JhcmVfcm91dGluZ0AxOQogICAgcHVzaGJ5dGVzcyAweDMwYzZkNThhIDB4ZWVjZGYwYTAgMHg2YzZmMTdkYSAweGVjZjYzM2IwIDB4M2U1MzEyMjMgMHgzZWQ2Nzk5ZCAweDZmZWNkZDgwIDB4Njc2YTg3YzIgMHgxZTBmODk1MSAweDQyZTg1ZmQ3IDB4NjUyMWQ0OWIgMHhlMDdjNTZjZCAweGFhMTlkMmI1IDB4YjkyMjMxMmQgMHhmYzBmZWVkOSAvLyBtZXRob2QgIm9wdF9pbigpdm9pZCIsIG1ldGhvZCAiZ2V0X2ltcGxpY2l0X2tleV9hcmM0X3VpbnRuNjQoYWNjb3VudCl1aW50NjQiLCBtZXRob2QgImdldF9pbXBsaWNpdF9rZXlfYXJjNF9zdHIoYWNjb3VudClzdHJpbmciLCBtZXRob2QgImdldF9pbXBsaWNpdF9rZXlfYXJjNF9ieXRlKGFjY291bnQpYnl0ZSIsIG1ldGhvZCAiZ2V0X2ltcGxpY2l0X2tleV9hcmM0X2Jvb2woYWNjb3VudClib29sIiwgbWV0aG9kICJnZXRfaW1wbGljaXRfa2V5X2FyYzRfYWRkcmVzcyhhY2NvdW50KWFkZHJlc3MiLCBtZXRob2QgImdldF9pbXBsaWNpdF9rZXlfYXJjNF91aW50bjEyOChhY2NvdW50KXVpbnQxMjgiLCBtZXRob2QgImdldF9pbXBsaWNpdF9rZXlfYXJjNF9keW5hbWljX2J5dGVzKGFjY291bnQpYnl0ZVtdIiwgbWV0aG9kICJnZXRfYXJjNF91aW50bjY0KGFjY291bnQpdWludDY0IiwgbWV0aG9kICJnZXRfYXJjNF9zdHIoYWNjb3VudClzdHJpbmciLCBtZXRob2QgImdldF9hcmM0X2J5dGUoYWNjb3VudClieXRlIiwgbWV0aG9kICJnZXRfYXJjNF9ib29sKGFjY291bnQpYm9vbCIsIG1ldGhvZCAiZ2V0X2FyYzRfYWRkcmVzcyhhY2NvdW50KWFkZHJlc3MiLCBtZXRob2QgImdldF9hcmM0X3VpbnRuMTI4KGFjY291bnQpdWludDEyOCIsIG1ldGhvZCAiZ2V0X2FyYzRfZHluYW1pY19ieXRlcyhhY2NvdW50KWJ5dGVbXSIKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDAKICAgIG1hdGNoIF9fcHV5YV9hcmM0X3JvdXRlcl9fX29wdF9pbl9yb3V0ZUAyIF9fcHV5YV9hcmM0X3JvdXRlcl9fX2dldF9pbXBsaWNpdF9rZXlfYXJjNF91aW50bjY0X3JvdXRlQDMgX19wdXlhX2FyYzRfcm91dGVyX19fZ2V0X2ltcGxpY2l0X2tleV9hcmM0X3N0cl9yb3V0ZUA0IF9fcHV5YV9hcmM0X3JvdXRlcl9fX2dldF9pbXBsaWNpdF9rZXlfYXJjNF9ieXRlX3JvdXRlQDUgX19wdXlhX2FyYzRfcm91dGVyX19fZ2V0X2ltcGxpY2l0X2tleV9hcmM0X2Jvb2xfcm91dGVANiBfX3B1eWFfYXJjNF9yb3V0ZXJfX19nZXRfaW1wbGljaXRfa2V5X2FyYzRfYWRkcmVzc19yb3V0ZUA3IF9fcHV5YV9hcmM0X3JvdXRlcl9fX2dldF9pbXBsaWNpdF9rZXlfYXJjNF91aW50bjEyOF9yb3V0ZUA4IF9fcHV5YV9hcmM0X3JvdXRlcl9fX2dldF9pbXBsaWNpdF9rZXlfYXJjNF9keW5hbWljX2J5dGVzX3JvdXRlQDkgX19wdXlhX2FyYzRfcm91dGVyX19fZ2V0X2FyYzRfdWludG42NF9yb3V0ZUAxMCBfX3B1eWFfYXJjNF9yb3V0ZXJfX19nZXRfYXJjNF9zdHJfcm91dGVAMTEgX19wdXlhX2FyYzRfcm91dGVyX19fZ2V0X2FyYzRfYnl0ZV9yb3V0ZUAxMiBfX3B1eWFfYXJjNF9yb3V0ZXJfX19nZXRfYXJjNF9ib29sX3JvdXRlQDEzIF9fcHV5YV9hcmM0X3JvdXRlcl9fX2dldF9hcmM0X2FkZHJlc3Nfcm91dGVAMTQgX19wdXlhX2FyYzRfcm91dGVyX19fZ2V0X2FyYzRfdWludG4xMjhfcm91dGVAMTUgX19wdXlhX2FyYzRfcm91dGVyX19fZ2V0X2FyYzRfZHluYW1pY19ieXRlc19yb3V0ZUAxNgogICAgaW50Y18xIC8vIDAKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fb3B0X2luX3JvdXRlQDI6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6Nzc0CiAgICAvLyBAYXJjNC5hYmltZXRob2QoeyBhbGxvd0FjdGlvbnM6IFsnT3B0SW4nXSB9KQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgaW50Y18wIC8vIE9wdEluCiAgICA9PQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBub3QgT3B0SW4KICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gY2FuIG9ubHkgY2FsbCB3aGVuIG5vdCBjcmVhdGluZwogICAgY2FsbHN1YiBvcHRfaW4KICAgIGludGNfMCAvLyAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX2dldF9pbXBsaWNpdF9rZXlfYXJjNF91aW50bjY0X3JvdXRlQDM6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6Nzk0CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBub3QgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBjYW4gb25seSBjYWxsIHdoZW4gbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NzU1CiAgICAvLyBleHBvcnQgY2xhc3MgTG9jYWxTdGF0ZUNvbnRyYWN0IGV4dGVuZHMgYXJjNC5Db250cmFjdCB7CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBidG9pCiAgICB0eG5hcyBBY2NvdW50cwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjc5NAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgZ2V0X2ltcGxpY2l0X2tleV9hcmM0X3VpbnRuNjQKICAgIGJ5dGVjXzAgLy8gMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludGNfMCAvLyAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX2dldF9pbXBsaWNpdF9rZXlfYXJjNF9zdHJfcm91dGVANDoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo3OTkKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIG5vdCBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGNhbiBvbmx5IGNhbGwgd2hlbiBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo3NTUKICAgIC8vIGV4cG9ydCBjbGFzcyBMb2NhbFN0YXRlQ29udHJhY3QgZXh0ZW5kcyBhcmM0LkNvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGJ0b2kKICAgIHR4bmFzIEFjY291bnRzCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6Nzk5CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiBnZXRfaW1wbGljaXRfa2V5X2FyYzRfc3RyCiAgICBieXRlY18wIC8vIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnRjXzAgLy8gMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX19nZXRfaW1wbGljaXRfa2V5X2FyYzRfYnl0ZV9yb3V0ZUA1OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjgwNAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgbm90IE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gY2FuIG9ubHkgY2FsbCB3aGVuIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjc1NQogICAgLy8gZXhwb3J0IGNsYXNzIExvY2FsU3RhdGVDb250cmFjdCBleHRlbmRzIGFyYzQuQ29udHJhY3QgewogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgYnRvaQogICAgdHhuYXMgQWNjb3VudHMKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo4MDQKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIGdldF9pbXBsaWNpdF9rZXlfYXJjNF9ieXRlCiAgICBieXRlY18wIC8vIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnRjXzAgLy8gMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX19nZXRfaW1wbGljaXRfa2V5X2FyYzRfYm9vbF9yb3V0ZUA2OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjgwOQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgbm90IE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gY2FuIG9ubHkgY2FsbCB3aGVuIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjc1NQogICAgLy8gZXhwb3J0IGNsYXNzIExvY2FsU3RhdGVDb250cmFjdCBleHRlbmRzIGFyYzQuQ29udHJhY3QgewogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgYnRvaQogICAgdHhuYXMgQWNjb3VudHMKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo4MDkKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIGdldF9pbXBsaWNpdF9rZXlfYXJjNF9ib29sCiAgICBieXRlY18wIC8vIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnRjXzAgLy8gMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX19nZXRfaW1wbGljaXRfa2V5X2FyYzRfYWRkcmVzc19yb3V0ZUA3OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjgxNAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgbm90IE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gY2FuIG9ubHkgY2FsbCB3aGVuIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjc1NQogICAgLy8gZXhwb3J0IGNsYXNzIExvY2FsU3RhdGVDb250cmFjdCBleHRlbmRzIGFyYzQuQ29udHJhY3QgewogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgYnRvaQogICAgdHhuYXMgQWNjb3VudHMKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo4MTQKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIGdldF9pbXBsaWNpdF9rZXlfYXJjNF9hZGRyZXNzCiAgICBieXRlY18wIC8vIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnRjXzAgLy8gMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX19nZXRfaW1wbGljaXRfa2V5X2FyYzRfdWludG4xMjhfcm91dGVAODoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo4MTkKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIG5vdCBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGNhbiBvbmx5IGNhbGwgd2hlbiBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo3NTUKICAgIC8vIGV4cG9ydCBjbGFzcyBMb2NhbFN0YXRlQ29udHJhY3QgZXh0ZW5kcyBhcmM0LkNvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGJ0b2kKICAgIHR4bmFzIEFjY291bnRzCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6ODE5CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiBnZXRfaW1wbGljaXRfa2V5X2FyYzRfdWludG4xMjgKICAgIGJ5dGVjXzAgLy8gMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludGNfMCAvLyAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX2dldF9pbXBsaWNpdF9rZXlfYXJjNF9keW5hbWljX2J5dGVzX3JvdXRlQDk6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6ODI0CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBub3QgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBjYW4gb25seSBjYWxsIHdoZW4gbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NzU1CiAgICAvLyBleHBvcnQgY2xhc3MgTG9jYWxTdGF0ZUNvbnRyYWN0IGV4dGVuZHMgYXJjNC5Db250cmFjdCB7CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBidG9pCiAgICB0eG5hcyBBY2NvdW50cwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjgyNAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgZ2V0X2ltcGxpY2l0X2tleV9hcmM0X2R5bmFtaWNfYnl0ZXMKICAgIGJ5dGVjXzAgLy8gMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludGNfMCAvLyAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX2dldF9hcmM0X3VpbnRuNjRfcm91dGVAMTA6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6ODMwCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBub3QgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBjYW4gb25seSBjYWxsIHdoZW4gbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NzU1CiAgICAvLyBleHBvcnQgY2xhc3MgTG9jYWxTdGF0ZUNvbnRyYWN0IGV4dGVuZHMgYXJjNC5Db250cmFjdCB7CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBidG9pCiAgICB0eG5hcyBBY2NvdW50cwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjgzMAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgZ2V0X2FyYzRfdWludG42NAogICAgYnl0ZWNfMCAvLyAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50Y18wIC8vIDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fZ2V0X2FyYzRfc3RyX3JvdXRlQDExOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjgzNQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgbm90IE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gY2FuIG9ubHkgY2FsbCB3aGVuIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjc1NQogICAgLy8gZXhwb3J0IGNsYXNzIExvY2FsU3RhdGVDb250cmFjdCBleHRlbmRzIGFyYzQuQ29udHJhY3QgewogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgYnRvaQogICAgdHhuYXMgQWNjb3VudHMKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo4MzUKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIGdldF9hcmM0X3N0cgogICAgYnl0ZWNfMCAvLyAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50Y18wIC8vIDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fZ2V0X2FyYzRfYnl0ZV9yb3V0ZUAxMjoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo4NDAKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIG5vdCBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGNhbiBvbmx5IGNhbGwgd2hlbiBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo3NTUKICAgIC8vIGV4cG9ydCBjbGFzcyBMb2NhbFN0YXRlQ29udHJhY3QgZXh0ZW5kcyBhcmM0LkNvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGJ0b2kKICAgIHR4bmFzIEFjY291bnRzCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6ODQwCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiBnZXRfYXJjNF9ieXRlCiAgICBieXRlY18wIC8vIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnRjXzAgLy8gMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX19nZXRfYXJjNF9ib29sX3JvdXRlQDEzOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjg0NQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgbm90IE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gY2FuIG9ubHkgY2FsbCB3aGVuIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjc1NQogICAgLy8gZXhwb3J0IGNsYXNzIExvY2FsU3RhdGVDb250cmFjdCBleHRlbmRzIGFyYzQuQ29udHJhY3QgewogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgYnRvaQogICAgdHhuYXMgQWNjb3VudHMKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo4NDUKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIGdldF9hcmM0X2Jvb2wKICAgIGJ5dGVjXzAgLy8gMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludGNfMCAvLyAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX2dldF9hcmM0X2FkZHJlc3Nfcm91dGVAMTQ6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6ODUwCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBub3QgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBjYW4gb25seSBjYWxsIHdoZW4gbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NzU1CiAgICAvLyBleHBvcnQgY2xhc3MgTG9jYWxTdGF0ZUNvbnRyYWN0IGV4dGVuZHMgYXJjNC5Db250cmFjdCB7CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBidG9pCiAgICB0eG5hcyBBY2NvdW50cwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjg1MAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgZ2V0X2FyYzRfYWRkcmVzcwogICAgYnl0ZWNfMCAvLyAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50Y18wIC8vIDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fZ2V0X2FyYzRfdWludG4xMjhfcm91dGVAMTU6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6ODU1CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBub3QgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBjYW4gb25seSBjYWxsIHdoZW4gbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NzU1CiAgICAvLyBleHBvcnQgY2xhc3MgTG9jYWxTdGF0ZUNvbnRyYWN0IGV4dGVuZHMgYXJjNC5Db250cmFjdCB7CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBidG9pCiAgICB0eG5hcyBBY2NvdW50cwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjg1NQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgZ2V0X2FyYzRfdWludG4xMjgKICAgIGJ5dGVjXzAgLy8gMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludGNfMCAvLyAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX2dldF9hcmM0X2R5bmFtaWNfYnl0ZXNfcm91dGVAMTY6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6ODYwCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBub3QgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBjYW4gb25seSBjYWxsIHdoZW4gbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NzU1CiAgICAvLyBleHBvcnQgY2xhc3MgTG9jYWxTdGF0ZUNvbnRyYWN0IGV4dGVuZHMgYXJjNC5Db250cmFjdCB7CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBidG9pCiAgICB0eG5hcyBBY2NvdW50cwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjg2MAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgZ2V0X2FyYzRfZHluYW1pY19ieXRlcwogICAgYnl0ZWNfMCAvLyAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50Y18wIC8vIDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fYmFyZV9yb3V0aW5nQDE5OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjc1NQogICAgLy8gZXhwb3J0IGNsYXNzIExvY2FsU3RhdGVDb250cmFjdCBleHRlbmRzIGFyYzQuQ29udHJhY3QgewogICAgdHhuIE9uQ29tcGxldGlvbgogICAgYm56IF9fcHV5YV9hcmM0X3JvdXRlcl9fX2FmdGVyX2lmX2Vsc2VAMjMKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICAhCiAgICBhc3NlcnQgLy8gY2FuIG9ubHkgY2FsbCB3aGVuIGNyZWF0aW5nCiAgICBpbnRjXzAgLy8gMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX19hZnRlcl9pZl9lbHNlQDIzOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjc1NQogICAgLy8gZXhwb3J0IGNsYXNzIExvY2FsU3RhdGVDb250cmFjdCBleHRlbmRzIGFyYzQuQ29udHJhY3QgewogICAgaW50Y18xIC8vIDAKICAgIHJldHN1YgoKCi8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo6TG9jYWxTdGF0ZUNvbnRyYWN0Lm9wdF9pbigpIC0+IHZvaWQ6Cm9wdF9pbjoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo3NzQtNzc1CiAgICAvLyBAYXJjNC5hYmltZXRob2QoeyBhbGxvd0FjdGlvbnM6IFsnT3B0SW4nXSB9KQogICAgLy8gb3B0X2luKCk6IHZvaWQgewogICAgcHJvdG8gMCAwCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6Nzc2CiAgICAvLyB0aGlzLmltcGxpY2l0S2V5QXJjNFVpbnRONjQoR2xvYmFsLmNyZWF0b3JBZGRyZXNzKS52YWx1ZSA9IG5ldyBVaW50TjY0KDEzMzcpCiAgICBnbG9iYWwgQ3JlYXRvckFkZHJlc3MKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo3NTcKICAgIC8vIGltcGxpY2l0S2V5QXJjNFVpbnRONjQgPSBMb2NhbFN0YXRlPFVpbnRONjQ+KCkKICAgIGJ5dGVjXzEgLy8gImltcGxpY2l0S2V5QXJjNFVpbnRONjQiCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6Nzc2CiAgICAvLyB0aGlzLmltcGxpY2l0S2V5QXJjNFVpbnRONjQoR2xvYmFsLmNyZWF0b3JBZGRyZXNzKS52YWx1ZSA9IG5ldyBVaW50TjY0KDEzMzcpCiAgICBieXRlY18yIC8vIDB4MDAwMDAwMDAwMDAwMDUzOQogICAgYXBwX2xvY2FsX3B1dAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjc3NwogICAgLy8gdGhpcy5pbXBsaWNpdEtleUFyYzRTdHIoR2xvYmFsLmNyZWF0b3JBZGRyZXNzKS52YWx1ZSA9IG5ldyBTdHIoJ0hlbGxvJykKICAgIGdsb2JhbCBDcmVhdG9yQWRkcmVzcwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjc1OAogICAgLy8gaW1wbGljaXRLZXlBcmM0U3RyID0gTG9jYWxTdGF0ZTxTdHI+KCkKICAgIGJ5dGVjXzMgLy8gImltcGxpY2l0S2V5QXJjNFN0ciIKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo3NzcKICAgIC8vIHRoaXMuaW1wbGljaXRLZXlBcmM0U3RyKEdsb2JhbC5jcmVhdG9yQWRkcmVzcykudmFsdWUgPSBuZXcgU3RyKCdIZWxsbycpCiAgICBieXRlYyA0IC8vIDB4MDAwNTQ4NjU2YzZjNmYKICAgIGFwcF9sb2NhbF9wdXQKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo3NzgKICAgIC8vIHRoaXMuaW1wbGljaXRLZXlBcmM0Qnl0ZShHbG9iYWwuY3JlYXRvckFkZHJlc3MpLnZhbHVlID0gbmV3IEJ5dGUoMCkKICAgIGdsb2JhbCBDcmVhdG9yQWRkcmVzcwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjc1OQogICAgLy8gaW1wbGljaXRLZXlBcmM0Qnl0ZSA9IExvY2FsU3RhdGU8Qnl0ZT4oKQogICAgYnl0ZWMgNSAvLyAiaW1wbGljaXRLZXlBcmM0Qnl0ZSIKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo3NzgKICAgIC8vIHRoaXMuaW1wbGljaXRLZXlBcmM0Qnl0ZShHbG9iYWwuY3JlYXRvckFkZHJlc3MpLnZhbHVlID0gbmV3IEJ5dGUoMCkKICAgIHB1c2hieXRlcyAweDAwCiAgICBhcHBfbG9jYWxfcHV0CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6Nzc5CiAgICAvLyB0aGlzLmltcGxpY2l0S2V5QXJjNEJvb2woR2xvYmFsLmNyZWF0b3JBZGRyZXNzKS52YWx1ZSA9IG5ldyBCb29sKHRydWUpCiAgICBnbG9iYWwgQ3JlYXRvckFkZHJlc3MKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo3NjAKICAgIC8vIGltcGxpY2l0S2V5QXJjNEJvb2wgPSBMb2NhbFN0YXRlPEJvb2w+KCkKICAgIGJ5dGVjIDYgLy8gImltcGxpY2l0S2V5QXJjNEJvb2wiCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6Nzc5CiAgICAvLyB0aGlzLmltcGxpY2l0S2V5QXJjNEJvb2woR2xvYmFsLmNyZWF0b3JBZGRyZXNzKS52YWx1ZSA9IG5ldyBCb29sKHRydWUpCiAgICBwdXNoYnl0ZXMgMHg4MAogICAgYXBwX2xvY2FsX3B1dAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjc4MAogICAgLy8gdGhpcy5pbXBsaWNpdEtleUFyYzRBZGRyZXNzKEdsb2JhbC5jcmVhdG9yQWRkcmVzcykudmFsdWUgPSBuZXcgQWRkcmVzcyhHbG9iYWwuY3JlYXRvckFkZHJlc3MpCiAgICBnbG9iYWwgQ3JlYXRvckFkZHJlc3MKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo3NjEKICAgIC8vIGltcGxpY2l0S2V5QXJjNEFkZHJlc3MgPSBMb2NhbFN0YXRlPEFkZHJlc3M+KCkKICAgIGJ5dGVjIDcgLy8gImltcGxpY2l0S2V5QXJjNEFkZHJlc3MiCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NzgwCiAgICAvLyB0aGlzLmltcGxpY2l0S2V5QXJjNEFkZHJlc3MoR2xvYmFsLmNyZWF0b3JBZGRyZXNzKS52YWx1ZSA9IG5ldyBBZGRyZXNzKEdsb2JhbC5jcmVhdG9yQWRkcmVzcykKICAgIGdsb2JhbCBDcmVhdG9yQWRkcmVzcwogICAgYXBwX2xvY2FsX3B1dAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjc4MQogICAgLy8gdGhpcy5pbXBsaWNpdEtleUFyYzRVaW50TjEyOChHbG9iYWwuY3JlYXRvckFkZHJlc3MpLnZhbHVlID0gbmV3IFVpbnROMTI4KDJuICoqIDEwMG4pCiAgICBnbG9iYWwgQ3JlYXRvckFkZHJlc3MKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo3NjIKICAgIC8vIGltcGxpY2l0S2V5QXJjNFVpbnROMTI4ID0gTG9jYWxTdGF0ZTxVaW50TjEyOD4oKQogICAgYnl0ZWMgOCAvLyAiaW1wbGljaXRLZXlBcmM0VWludE4xMjgiCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NzgxCiAgICAvLyB0aGlzLmltcGxpY2l0S2V5QXJjNFVpbnROMTI4KEdsb2JhbC5jcmVhdG9yQWRkcmVzcykudmFsdWUgPSBuZXcgVWludE4xMjgoMm4gKiogMTAwbikKICAgIGJ5dGVjIDkgLy8gMHgwMDAwMDAxMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMAogICAgYXBwX2xvY2FsX3B1dAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjc4MgogICAgLy8gdGhpcy5pbXBsaWNpdEtleUFyYzREeW5hbWljQnl0ZXMoR2xvYmFsLmNyZWF0b3JBZGRyZXNzKS52YWx1ZSA9IG5ldyBEeW5hbWljQnl0ZXMoJ2R5bmFtaWMgYnl0ZXMnKQogICAgZ2xvYmFsIENyZWF0b3JBZGRyZXNzCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NzYzCiAgICAvLyBpbXBsaWNpdEtleUFyYzREeW5hbWljQnl0ZXMgPSBMb2NhbFN0YXRlPER5bmFtaWNCeXRlcz4oKQogICAgYnl0ZWMgMTAgLy8gImltcGxpY2l0S2V5QXJjNER5bmFtaWNCeXRlcyIKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo3ODIKICAgIC8vIHRoaXMuaW1wbGljaXRLZXlBcmM0RHluYW1pY0J5dGVzKEdsb2JhbC5jcmVhdG9yQWRkcmVzcykudmFsdWUgPSBuZXcgRHluYW1pY0J5dGVzKCdkeW5hbWljIGJ5dGVzJykKICAgIGJ5dGVjIDExIC8vIDB4MDAwZDY0Nzk2ZTYxNmQ2OTYzMjA2Mjc5NzQ2NTczCiAgICBhcHBfbG9jYWxfcHV0CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6Nzg0CiAgICAvLyB0aGlzLmFyYzRVaW50TjY0KEdsb2JhbC5jcmVhdG9yQWRkcmVzcykudmFsdWUgPSBuZXcgVWludE42NCgxMzM3KQogICAgZ2xvYmFsIENyZWF0b3JBZGRyZXNzCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NzY2CiAgICAvLyBhcmM0VWludE42NCA9IExvY2FsU3RhdGU8VWludE42ND4oeyBrZXk6ICdleHBsaWNpdF9rZXlfYXJjNF91aW50bjY0JyB9KQogICAgYnl0ZWMgMTIgLy8gImV4cGxpY2l0X2tleV9hcmM0X3VpbnRuNjQiCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6Nzg0CiAgICAvLyB0aGlzLmFyYzRVaW50TjY0KEdsb2JhbC5jcmVhdG9yQWRkcmVzcykudmFsdWUgPSBuZXcgVWludE42NCgxMzM3KQogICAgYnl0ZWNfMiAvLyAweDAwMDAwMDAwMDAwMDA1MzkKICAgIGFwcF9sb2NhbF9wdXQKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo3ODUKICAgIC8vIHRoaXMuYXJjNFN0cihHbG9iYWwuY3JlYXRvckFkZHJlc3MpLnZhbHVlID0gbmV3IFN0cignSGVsbG8nKQogICAgZ2xvYmFsIENyZWF0b3JBZGRyZXNzCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NzY3CiAgICAvLyBhcmM0U3RyID0gTG9jYWxTdGF0ZTxTdHI+KHsga2V5OiAnZXhwbGljaXRfa2V5X2FyYzRfc3RyJyB9KQogICAgYnl0ZWMgMTMgLy8gImV4cGxpY2l0X2tleV9hcmM0X3N0ciIKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo3ODUKICAgIC8vIHRoaXMuYXJjNFN0cihHbG9iYWwuY3JlYXRvckFkZHJlc3MpLnZhbHVlID0gbmV3IFN0cignSGVsbG8nKQogICAgYnl0ZWMgNCAvLyAweDAwMDU0ODY1NmM2YzZmCiAgICBhcHBfbG9jYWxfcHV0CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6Nzg2CiAgICAvLyB0aGlzLmFyYzRCeXRlKEdsb2JhbC5jcmVhdG9yQWRkcmVzcykudmFsdWUgPSBuZXcgQnl0ZSgwKQogICAgZ2xvYmFsIENyZWF0b3JBZGRyZXNzCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NzY4CiAgICAvLyBhcmM0Qnl0ZSA9IExvY2FsU3RhdGU8Qnl0ZT4oeyBrZXk6ICdleHBsaWNpdF9rZXlfYXJjNF9ieXRlJyB9KQogICAgYnl0ZWMgMTQgLy8gImV4cGxpY2l0X2tleV9hcmM0X2J5dGUiCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6Nzg2CiAgICAvLyB0aGlzLmFyYzRCeXRlKEdsb2JhbC5jcmVhdG9yQWRkcmVzcykudmFsdWUgPSBuZXcgQnl0ZSgwKQogICAgcHVzaGJ5dGVzIDB4MDAKICAgIGFwcF9sb2NhbF9wdXQKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo3ODcKICAgIC8vIHRoaXMuYXJjNEJvb2woR2xvYmFsLmNyZWF0b3JBZGRyZXNzKS52YWx1ZSA9IG5ldyBCb29sKHRydWUpCiAgICBnbG9iYWwgQ3JlYXRvckFkZHJlc3MKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo3NjkKICAgIC8vIGFyYzRCb29sID0gTG9jYWxTdGF0ZTxCb29sPih7IGtleTogJ2V4cGxpY2l0X2tleV9hcmM0X2Jvb2wnIH0pCiAgICBieXRlYyAxNSAvLyAiZXhwbGljaXRfa2V5X2FyYzRfYm9vbCIKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo3ODcKICAgIC8vIHRoaXMuYXJjNEJvb2woR2xvYmFsLmNyZWF0b3JBZGRyZXNzKS52YWx1ZSA9IG5ldyBCb29sKHRydWUpCiAgICBwdXNoYnl0ZXMgMHg4MAogICAgYXBwX2xvY2FsX3B1dAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjc4OAogICAgLy8gdGhpcy5hcmM0QWRkcmVzcyhHbG9iYWwuY3JlYXRvckFkZHJlc3MpLnZhbHVlID0gbmV3IEFkZHJlc3MoR2xvYmFsLmNyZWF0b3JBZGRyZXNzKQogICAgZ2xvYmFsIENyZWF0b3JBZGRyZXNzCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NzcwCiAgICAvLyBhcmM0QWRkcmVzcyA9IExvY2FsU3RhdGU8QWRkcmVzcz4oeyBrZXk6ICdleHBsaWNpdF9rZXlfYXJjNF9hZGRyZXNzJyB9KQogICAgYnl0ZWMgMTYgLy8gImV4cGxpY2l0X2tleV9hcmM0X2FkZHJlc3MiCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6Nzg4CiAgICAvLyB0aGlzLmFyYzRBZGRyZXNzKEdsb2JhbC5jcmVhdG9yQWRkcmVzcykudmFsdWUgPSBuZXcgQWRkcmVzcyhHbG9iYWwuY3JlYXRvckFkZHJlc3MpCiAgICBnbG9iYWwgQ3JlYXRvckFkZHJlc3MKICAgIGFwcF9sb2NhbF9wdXQKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo3ODkKICAgIC8vIHRoaXMuYXJjNFVpbnROMTI4KEdsb2JhbC5jcmVhdG9yQWRkcmVzcykudmFsdWUgPSBuZXcgVWludE4xMjgoMm4gKiogMTAwbikKICAgIGdsb2JhbCBDcmVhdG9yQWRkcmVzcwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjc3MQogICAgLy8gYXJjNFVpbnROMTI4ID0gTG9jYWxTdGF0ZTxVaW50TjEyOD4oeyBrZXk6ICdleHBsaWNpdF9rZXlfYXJjNF91aW50bjEyOCcgfSkKICAgIGJ5dGVjIDE3IC8vICJleHBsaWNpdF9rZXlfYXJjNF91aW50bjEyOCIKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo3ODkKICAgIC8vIHRoaXMuYXJjNFVpbnROMTI4KEdsb2JhbC5jcmVhdG9yQWRkcmVzcykudmFsdWUgPSBuZXcgVWludE4xMjgoMm4gKiogMTAwbikKICAgIGJ5dGVjIDkgLy8gMHgwMDAwMDAxMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMAogICAgYXBwX2xvY2FsX3B1dAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjc5MAogICAgLy8gdGhpcy5hcmM0RHluYW1pY0J5dGVzKEdsb2JhbC5jcmVhdG9yQWRkcmVzcykudmFsdWUgPSBuZXcgRHluYW1pY0J5dGVzKCdkeW5hbWljIGJ5dGVzJykKICAgIGdsb2JhbCBDcmVhdG9yQWRkcmVzcwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjc3MgogICAgLy8gYXJjNER5bmFtaWNCeXRlcyA9IExvY2FsU3RhdGU8RHluYW1pY0J5dGVzPih7IGtleTogJ2V4cGxpY2l0X2tleV9hcmM0X2R5bmFtaWNfYnl0ZXMnIH0pCiAgICBieXRlYyAxOCAvLyAiZXhwbGljaXRfa2V5X2FyYzRfZHluYW1pY19ieXRlcyIKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo3OTAKICAgIC8vIHRoaXMuYXJjNER5bmFtaWNCeXRlcyhHbG9iYWwuY3JlYXRvckFkZHJlc3MpLnZhbHVlID0gbmV3IER5bmFtaWNCeXRlcygnZHluYW1pYyBieXRlcycpCiAgICBieXRlYyAxMSAvLyAweDAwMGQ2NDc5NmU2MTZkNjk2MzIwNjI3OTc0NjU3MwogICAgYXBwX2xvY2FsX3B1dAogICAgcmV0c3ViCgoKLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjpMb2NhbFN0YXRlQ29udHJhY3QuZ2V0X2ltcGxpY2l0X2tleV9hcmM0X3VpbnRuNjQoYTogYnl0ZXMpIC0+IGJ5dGVzOgpnZXRfaW1wbGljaXRfa2V5X2FyYzRfdWludG42NDoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo3OTQtNzk1CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gZ2V0X2ltcGxpY2l0X2tleV9hcmM0X3VpbnRuNjQoYTogQWNjb3VudCk6IFVpbnRONjQgewogICAgcHJvdG8gMSAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6Nzk2CiAgICAvLyByZXR1cm4gdGhpcy5pbXBsaWNpdEtleUFyYzRVaW50TjY0KGEpLnZhbHVlCiAgICBmcmFtZV9kaWcgLTEKICAgIGludGNfMSAvLyAwCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NzU3CiAgICAvLyBpbXBsaWNpdEtleUFyYzRVaW50TjY0ID0gTG9jYWxTdGF0ZTxVaW50TjY0PigpCiAgICBieXRlY18xIC8vICJpbXBsaWNpdEtleUFyYzRVaW50TjY0IgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjc5NgogICAgLy8gcmV0dXJuIHRoaXMuaW1wbGljaXRLZXlBcmM0VWludE42NChhKS52YWx1ZQogICAgYXBwX2xvY2FsX2dldF9leAogICAgYXNzZXJ0IC8vIGNoZWNrIExvY2FsU3RhdGUgZXhpc3RzCiAgICByZXRzdWIKCgovLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OkxvY2FsU3RhdGVDb250cmFjdC5nZXRfaW1wbGljaXRfa2V5X2FyYzRfc3RyKGE6IGJ5dGVzKSAtPiBieXRlczoKZ2V0X2ltcGxpY2l0X2tleV9hcmM0X3N0cjoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo3OTktODAwCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gZ2V0X2ltcGxpY2l0X2tleV9hcmM0X3N0cihhOiBBY2NvdW50KTogU3RyIHsKICAgIHByb3RvIDEgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjgwMQogICAgLy8gcmV0dXJuIHRoaXMuaW1wbGljaXRLZXlBcmM0U3RyKGEpLnZhbHVlCiAgICBmcmFtZV9kaWcgLTEKICAgIGludGNfMSAvLyAwCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NzU4CiAgICAvLyBpbXBsaWNpdEtleUFyYzRTdHIgPSBMb2NhbFN0YXRlPFN0cj4oKQogICAgYnl0ZWNfMyAvLyAiaW1wbGljaXRLZXlBcmM0U3RyIgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjgwMQogICAgLy8gcmV0dXJuIHRoaXMuaW1wbGljaXRLZXlBcmM0U3RyKGEpLnZhbHVlCiAgICBhcHBfbG9jYWxfZ2V0X2V4CiAgICBhc3NlcnQgLy8gY2hlY2sgTG9jYWxTdGF0ZSBleGlzdHMKICAgIHJldHN1YgoKCi8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo6TG9jYWxTdGF0ZUNvbnRyYWN0LmdldF9pbXBsaWNpdF9rZXlfYXJjNF9ieXRlKGE6IGJ5dGVzKSAtPiBieXRlczoKZ2V0X2ltcGxpY2l0X2tleV9hcmM0X2J5dGU6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6ODA0LTgwNQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIGdldF9pbXBsaWNpdF9rZXlfYXJjNF9ieXRlKGE6IEFjY291bnQpOiBCeXRlIHsKICAgIHByb3RvIDEgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjgwNgogICAgLy8gcmV0dXJuIHRoaXMuaW1wbGljaXRLZXlBcmM0Qnl0ZShhKS52YWx1ZQogICAgZnJhbWVfZGlnIC0xCiAgICBpbnRjXzEgLy8gMAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjc1OQogICAgLy8gaW1wbGljaXRLZXlBcmM0Qnl0ZSA9IExvY2FsU3RhdGU8Qnl0ZT4oKQogICAgYnl0ZWMgNSAvLyAiaW1wbGljaXRLZXlBcmM0Qnl0ZSIKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo4MDYKICAgIC8vIHJldHVybiB0aGlzLmltcGxpY2l0S2V5QXJjNEJ5dGUoYSkudmFsdWUKICAgIGFwcF9sb2NhbF9nZXRfZXgKICAgIGFzc2VydCAvLyBjaGVjayBMb2NhbFN0YXRlIGV4aXN0cwogICAgcmV0c3ViCgoKLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjpMb2NhbFN0YXRlQ29udHJhY3QuZ2V0X2ltcGxpY2l0X2tleV9hcmM0X2Jvb2woYTogYnl0ZXMpIC0+IGJ5dGVzOgpnZXRfaW1wbGljaXRfa2V5X2FyYzRfYm9vbDoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo4MDktODEwCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gZ2V0X2ltcGxpY2l0X2tleV9hcmM0X2Jvb2woYTogQWNjb3VudCk6IEJvb2wgewogICAgcHJvdG8gMSAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6ODExCiAgICAvLyByZXR1cm4gdGhpcy5pbXBsaWNpdEtleUFyYzRCb29sKGEpLnZhbHVlCiAgICBmcmFtZV9kaWcgLTEKICAgIGludGNfMSAvLyAwCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NzYwCiAgICAvLyBpbXBsaWNpdEtleUFyYzRCb29sID0gTG9jYWxTdGF0ZTxCb29sPigpCiAgICBieXRlYyA2IC8vICJpbXBsaWNpdEtleUFyYzRCb29sIgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjgxMQogICAgLy8gcmV0dXJuIHRoaXMuaW1wbGljaXRLZXlBcmM0Qm9vbChhKS52YWx1ZQogICAgYXBwX2xvY2FsX2dldF9leAogICAgYXNzZXJ0IC8vIGNoZWNrIExvY2FsU3RhdGUgZXhpc3RzCiAgICByZXRzdWIKCgovLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OkxvY2FsU3RhdGVDb250cmFjdC5nZXRfaW1wbGljaXRfa2V5X2FyYzRfYWRkcmVzcyhhOiBieXRlcykgLT4gYnl0ZXM6CmdldF9pbXBsaWNpdF9rZXlfYXJjNF9hZGRyZXNzOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjgxNC04MTUKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBnZXRfaW1wbGljaXRfa2V5X2FyYzRfYWRkcmVzcyhhOiBBY2NvdW50KTogQWRkcmVzcyB7CiAgICBwcm90byAxIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo4MTYKICAgIC8vIHJldHVybiB0aGlzLmltcGxpY2l0S2V5QXJjNEFkZHJlc3MoYSkudmFsdWUKICAgIGZyYW1lX2RpZyAtMQogICAgaW50Y18xIC8vIDAKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo3NjEKICAgIC8vIGltcGxpY2l0S2V5QXJjNEFkZHJlc3MgPSBMb2NhbFN0YXRlPEFkZHJlc3M+KCkKICAgIGJ5dGVjIDcgLy8gImltcGxpY2l0S2V5QXJjNEFkZHJlc3MiCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6ODE2CiAgICAvLyByZXR1cm4gdGhpcy5pbXBsaWNpdEtleUFyYzRBZGRyZXNzKGEpLnZhbHVlCiAgICBhcHBfbG9jYWxfZ2V0X2V4CiAgICBhc3NlcnQgLy8gY2hlY2sgTG9jYWxTdGF0ZSBleGlzdHMKICAgIHJldHN1YgoKCi8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo6TG9jYWxTdGF0ZUNvbnRyYWN0LmdldF9pbXBsaWNpdF9rZXlfYXJjNF91aW50bjEyOChhOiBieXRlcykgLT4gYnl0ZXM6CmdldF9pbXBsaWNpdF9rZXlfYXJjNF91aW50bjEyODoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo4MTktODIwCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gZ2V0X2ltcGxpY2l0X2tleV9hcmM0X3VpbnRuMTI4KGE6IEFjY291bnQpOiBVaW50TjEyOCB7CiAgICBwcm90byAxIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo4MjEKICAgIC8vIHJldHVybiB0aGlzLmltcGxpY2l0S2V5QXJjNFVpbnROMTI4KGEpLnZhbHVlCiAgICBmcmFtZV9kaWcgLTEKICAgIGludGNfMSAvLyAwCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NzYyCiAgICAvLyBpbXBsaWNpdEtleUFyYzRVaW50TjEyOCA9IExvY2FsU3RhdGU8VWludE4xMjg+KCkKICAgIGJ5dGVjIDggLy8gImltcGxpY2l0S2V5QXJjNFVpbnROMTI4IgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjgyMQogICAgLy8gcmV0dXJuIHRoaXMuaW1wbGljaXRLZXlBcmM0VWludE4xMjgoYSkudmFsdWUKICAgIGFwcF9sb2NhbF9nZXRfZXgKICAgIGFzc2VydCAvLyBjaGVjayBMb2NhbFN0YXRlIGV4aXN0cwogICAgcmV0c3ViCgoKLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjpMb2NhbFN0YXRlQ29udHJhY3QuZ2V0X2ltcGxpY2l0X2tleV9hcmM0X2R5bmFtaWNfYnl0ZXMoYTogYnl0ZXMpIC0+IGJ5dGVzOgpnZXRfaW1wbGljaXRfa2V5X2FyYzRfZHluYW1pY19ieXRlczoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo4MjQtODI1CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gZ2V0X2ltcGxpY2l0X2tleV9hcmM0X2R5bmFtaWNfYnl0ZXMoYTogQWNjb3VudCk6IER5bmFtaWNCeXRlcyB7CiAgICBwcm90byAxIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo4MjYKICAgIC8vIHJldHVybiB0aGlzLmltcGxpY2l0S2V5QXJjNER5bmFtaWNCeXRlcyhhKS52YWx1ZQogICAgZnJhbWVfZGlnIC0xCiAgICBpbnRjXzEgLy8gMAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjc2MwogICAgLy8gaW1wbGljaXRLZXlBcmM0RHluYW1pY0J5dGVzID0gTG9jYWxTdGF0ZTxEeW5hbWljQnl0ZXM+KCkKICAgIGJ5dGVjIDEwIC8vICJpbXBsaWNpdEtleUFyYzREeW5hbWljQnl0ZXMiCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6ODI2CiAgICAvLyByZXR1cm4gdGhpcy5pbXBsaWNpdEtleUFyYzREeW5hbWljQnl0ZXMoYSkudmFsdWUKICAgIGFwcF9sb2NhbF9nZXRfZXgKICAgIGFzc2VydCAvLyBjaGVjayBMb2NhbFN0YXRlIGV4aXN0cwogICAgcmV0c3ViCgoKLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjpMb2NhbFN0YXRlQ29udHJhY3QuZ2V0X2FyYzRfdWludG42NChhOiBieXRlcykgLT4gYnl0ZXM6CmdldF9hcmM0X3VpbnRuNjQ6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6ODMwLTgzMQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIGdldF9hcmM0X3VpbnRuNjQoYTogQWNjb3VudCk6IGFyYzQuVWludE42NCB7CiAgICBwcm90byAxIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo4MzIKICAgIC8vIHJldHVybiB0aGlzLmFyYzRVaW50TjY0KGEpLnZhbHVlCiAgICBmcmFtZV9kaWcgLTEKICAgIGludGNfMSAvLyAwCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NzY2CiAgICAvLyBhcmM0VWludE42NCA9IExvY2FsU3RhdGU8VWludE42ND4oeyBrZXk6ICdleHBsaWNpdF9rZXlfYXJjNF91aW50bjY0JyB9KQogICAgYnl0ZWMgMTIgLy8gImV4cGxpY2l0X2tleV9hcmM0X3VpbnRuNjQiCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6ODMyCiAgICAvLyByZXR1cm4gdGhpcy5hcmM0VWludE42NChhKS52YWx1ZQogICAgYXBwX2xvY2FsX2dldF9leAogICAgYXNzZXJ0IC8vIGNoZWNrIExvY2FsU3RhdGUgZXhpc3RzCiAgICByZXRzdWIKCgovLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OkxvY2FsU3RhdGVDb250cmFjdC5nZXRfYXJjNF9zdHIoYTogYnl0ZXMpIC0+IGJ5dGVzOgpnZXRfYXJjNF9zdHI6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6ODM1LTgzNgogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIGdldF9hcmM0X3N0cihhOiBBY2NvdW50KTogU3RyIHsKICAgIHByb3RvIDEgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjgzNwogICAgLy8gcmV0dXJuIHRoaXMuYXJjNFN0cihhKS52YWx1ZQogICAgZnJhbWVfZGlnIC0xCiAgICBpbnRjXzEgLy8gMAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjc2NwogICAgLy8gYXJjNFN0ciA9IExvY2FsU3RhdGU8U3RyPih7IGtleTogJ2V4cGxpY2l0X2tleV9hcmM0X3N0cicgfSkKICAgIGJ5dGVjIDEzIC8vICJleHBsaWNpdF9rZXlfYXJjNF9zdHIiCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6ODM3CiAgICAvLyByZXR1cm4gdGhpcy5hcmM0U3RyKGEpLnZhbHVlCiAgICBhcHBfbG9jYWxfZ2V0X2V4CiAgICBhc3NlcnQgLy8gY2hlY2sgTG9jYWxTdGF0ZSBleGlzdHMKICAgIHJldHN1YgoKCi8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo6TG9jYWxTdGF0ZUNvbnRyYWN0LmdldF9hcmM0X2J5dGUoYTogYnl0ZXMpIC0+IGJ5dGVzOgpnZXRfYXJjNF9ieXRlOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjg0MC04NDEKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBnZXRfYXJjNF9ieXRlKGE6IEFjY291bnQpOiBCeXRlIHsKICAgIHByb3RvIDEgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjg0MgogICAgLy8gcmV0dXJuIHRoaXMuYXJjNEJ5dGUoYSkudmFsdWUKICAgIGZyYW1lX2RpZyAtMQogICAgaW50Y18xIC8vIDAKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo3NjgKICAgIC8vIGFyYzRCeXRlID0gTG9jYWxTdGF0ZTxCeXRlPih7IGtleTogJ2V4cGxpY2l0X2tleV9hcmM0X2J5dGUnIH0pCiAgICBieXRlYyAxNCAvLyAiZXhwbGljaXRfa2V5X2FyYzRfYnl0ZSIKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo4NDIKICAgIC8vIHJldHVybiB0aGlzLmFyYzRCeXRlKGEpLnZhbHVlCiAgICBhcHBfbG9jYWxfZ2V0X2V4CiAgICBhc3NlcnQgLy8gY2hlY2sgTG9jYWxTdGF0ZSBleGlzdHMKICAgIHJldHN1YgoKCi8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo6TG9jYWxTdGF0ZUNvbnRyYWN0LmdldF9hcmM0X2Jvb2woYTogYnl0ZXMpIC0+IGJ5dGVzOgpnZXRfYXJjNF9ib29sOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjg0NS04NDYKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBnZXRfYXJjNF9ib29sKGE6IEFjY291bnQpOiBCb29sIHsKICAgIHByb3RvIDEgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjg0NwogICAgLy8gcmV0dXJuIHRoaXMuYXJjNEJvb2woYSkudmFsdWUKICAgIGZyYW1lX2RpZyAtMQogICAgaW50Y18xIC8vIDAKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo3NjkKICAgIC8vIGFyYzRCb29sID0gTG9jYWxTdGF0ZTxCb29sPih7IGtleTogJ2V4cGxpY2l0X2tleV9hcmM0X2Jvb2wnIH0pCiAgICBieXRlYyAxNSAvLyAiZXhwbGljaXRfa2V5X2FyYzRfYm9vbCIKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo4NDcKICAgIC8vIHJldHVybiB0aGlzLmFyYzRCb29sKGEpLnZhbHVlCiAgICBhcHBfbG9jYWxfZ2V0X2V4CiAgICBhc3NlcnQgLy8gY2hlY2sgTG9jYWxTdGF0ZSBleGlzdHMKICAgIHJldHN1YgoKCi8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo6TG9jYWxTdGF0ZUNvbnRyYWN0LmdldF9hcmM0X2FkZHJlc3MoYTogYnl0ZXMpIC0+IGJ5dGVzOgpnZXRfYXJjNF9hZGRyZXNzOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjg1MC04NTEKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBnZXRfYXJjNF9hZGRyZXNzKGE6IEFjY291bnQpOiBBZGRyZXNzIHsKICAgIHByb3RvIDEgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjg1MgogICAgLy8gcmV0dXJuIHRoaXMuYXJjNEFkZHJlc3MoYSkudmFsdWUKICAgIGZyYW1lX2RpZyAtMQogICAgaW50Y18xIC8vIDAKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo3NzAKICAgIC8vIGFyYzRBZGRyZXNzID0gTG9jYWxTdGF0ZTxBZGRyZXNzPih7IGtleTogJ2V4cGxpY2l0X2tleV9hcmM0X2FkZHJlc3MnIH0pCiAgICBieXRlYyAxNiAvLyAiZXhwbGljaXRfa2V5X2FyYzRfYWRkcmVzcyIKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo4NTIKICAgIC8vIHJldHVybiB0aGlzLmFyYzRBZGRyZXNzKGEpLnZhbHVlCiAgICBhcHBfbG9jYWxfZ2V0X2V4CiAgICBhc3NlcnQgLy8gY2hlY2sgTG9jYWxTdGF0ZSBleGlzdHMKICAgIHJldHN1YgoKCi8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo6TG9jYWxTdGF0ZUNvbnRyYWN0LmdldF9hcmM0X3VpbnRuMTI4KGE6IGJ5dGVzKSAtPiBieXRlczoKZ2V0X2FyYzRfdWludG4xMjg6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6ODU1LTg1NgogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIGdldF9hcmM0X3VpbnRuMTI4KGE6IEFjY291bnQpOiBVaW50TjEyOCB7CiAgICBwcm90byAxIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo4NTcKICAgIC8vIHJldHVybiB0aGlzLmFyYzRVaW50TjEyOChhKS52YWx1ZQogICAgZnJhbWVfZGlnIC0xCiAgICBpbnRjXzEgLy8gMAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjc3MQogICAgLy8gYXJjNFVpbnROMTI4ID0gTG9jYWxTdGF0ZTxVaW50TjEyOD4oeyBrZXk6ICdleHBsaWNpdF9rZXlfYXJjNF91aW50bjEyOCcgfSkKICAgIGJ5dGVjIDE3IC8vICJleHBsaWNpdF9rZXlfYXJjNF91aW50bjEyOCIKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo4NTcKICAgIC8vIHJldHVybiB0aGlzLmFyYzRVaW50TjEyOChhKS52YWx1ZQogICAgYXBwX2xvY2FsX2dldF9leAogICAgYXNzZXJ0IC8vIGNoZWNrIExvY2FsU3RhdGUgZXhpc3RzCiAgICByZXRzdWIKCgovLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OkxvY2FsU3RhdGVDb250cmFjdC5nZXRfYXJjNF9keW5hbWljX2J5dGVzKGE6IGJ5dGVzKSAtPiBieXRlczoKZ2V0X2FyYzRfZHluYW1pY19ieXRlczoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo4NjAtODYxCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gZ2V0X2FyYzRfZHluYW1pY19ieXRlcyhhOiBBY2NvdW50KTogRHluYW1pY0J5dGVzIHsKICAgIHByb3RvIDEgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjg2MgogICAgLy8gcmV0dXJuIHRoaXMuYXJjNER5bmFtaWNCeXRlcyhhKS52YWx1ZQogICAgZnJhbWVfZGlnIC0xCiAgICBpbnRjXzEgLy8gMAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjc3MgogICAgLy8gYXJjNER5bmFtaWNCeXRlcyA9IExvY2FsU3RhdGU8RHluYW1pY0J5dGVzPih7IGtleTogJ2V4cGxpY2l0X2tleV9hcmM0X2R5bmFtaWNfYnl0ZXMnIH0pCiAgICBieXRlYyAxOCAvLyAiZXhwbGljaXRfa2V5X2FyYzRfZHluYW1pY19ieXRlcyIKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo4NjIKICAgIC8vIHJldHVybiB0aGlzLmFyYzREeW5hbWljQnl0ZXMoYSkudmFsdWUKICAgIGFwcF9sb2NhbF9nZXRfZXgKICAgIGFzc2VydCAvLyBjaGVjayBMb2NhbFN0YXRlIGV4aXN0cwogICAgcmV0c3ViCg==", - "clear": "I3ByYWdtYSB2ZXJzaW9uIDEwCgp0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OkxvY2FsU3RhdGVDb250cmFjdC5jbGVhclN0YXRlUHJvZ3JhbToKICAgIHB1c2hpbnQgMSAvLyAxCiAgICByZXR1cm4K" - }, - "events": [], - "templateVariables": {} -} \ No newline at end of file diff --git a/tests/artifacts/state-ops/data/LocalStateContract.clear.teal b/tests/artifacts/state-ops/data/LocalStateContract.clear.teal deleted file mode 100644 index 277d4be..0000000 --- a/tests/artifacts/state-ops/data/LocalStateContract.clear.teal +++ /dev/null @@ -1,5 +0,0 @@ -#pragma version 10 - -tests/artifacts/state-ops/contract.algo.ts::LocalStateContract.clearStateProgram: - pushint 1 // 1 - return diff --git a/tests/artifacts/state-ops/data/StateAcctParamsGetContract.approval.teal b/tests/artifacts/state-ops/data/StateAcctParamsGetContract.approval.teal deleted file mode 100644 index dceec00..0000000 --- a/tests/artifacts/state-ops/data/StateAcctParamsGetContract.approval.teal +++ /dev/null @@ -1,730 +0,0 @@ -#pragma version 10 - -tests/artifacts/state-ops/contract.algo.ts::StateAcctParamsGetContract.approvalProgram: - intcblock 1 0 - bytecblock 0x151f7c75 - callsub __puya_arc4_router__ - return - - -// tests/artifacts/state-ops/contract.algo.ts::StateAcctParamsGetContract.__puya_arc4_router__() -> uint64: -__puya_arc4_router__: - // tests/artifacts/state-ops/contract.algo.ts:26 - // export class StateAcctParamsGetContract extends arc4.Contract { - proto 0 1 - txn NumAppArgs - bz __puya_arc4_router___bare_routing@16 - pushbytess 0x5f5b43e4 0x73dc93c7 0x5626dfeb 0xdc8a25bf 0x198ebd8c 0x2301ab26 0x9f68fca6 0xa975c2d1 0xd1e04801 0xb6966be5 0x195d5418 0x6adae3f1 // method "verify_acct_balance(account)uint64", method "verify_acct_min_balance(account)uint64", method "verify_acct_auth_addr(account)address", method "verify_acct_total_num_uint(account)uint64", method "verify_acct_total_num_byte_slice(account)uint64", method "verify_acct_total_extra_app_pages(account)uint64", method "verify_acct_total_apps_created(account)uint64", method "verify_acct_total_apps_opted_in(account)uint64", method "verify_acct_total_assets_created(account)uint64", method "verify_acct_total_assets(account)uint64", method "verify_acct_total_boxes(account)uint64", method "verify_acct_total_box_bytes(account)uint64" - txna ApplicationArgs 0 - match __puya_arc4_router___verify_acct_balance_route@2 __puya_arc4_router___verify_acct_min_balance_route@3 __puya_arc4_router___verify_acct_auth_addr_route@4 __puya_arc4_router___verify_acct_total_num_uint_route@5 __puya_arc4_router___verify_acct_total_num_byte_slice_route@6 __puya_arc4_router___verify_acct_total_extra_app_pages_route@7 __puya_arc4_router___verify_acct_total_apps_created_route@8 __puya_arc4_router___verify_acct_total_apps_opted_in_route@9 __puya_arc4_router___verify_acct_total_assets_created_route@10 __puya_arc4_router___verify_acct_total_assets_route@11 __puya_arc4_router___verify_acct_total_boxes_route@12 __puya_arc4_router___verify_acct_total_box_bytes_route@13 - intc_1 // 0 - retsub - -__puya_arc4_router___verify_acct_balance_route@2: - // tests/artifacts/state-ops/contract.algo.ts:27 - // @arc4.abimethod() - txn OnCompletion - ! - assert // OnCompletion is not NoOp - txn ApplicationID - assert // can only call when not creating - // tests/artifacts/state-ops/contract.algo.ts:26 - // export class StateAcctParamsGetContract extends arc4.Contract { - txna ApplicationArgs 1 - btoi - txnas Accounts - // tests/artifacts/state-ops/contract.algo.ts:27 - // @arc4.abimethod() - callsub verify_acct_balance - itob - bytec_0 // 0x151f7c75 - swap - concat - log - intc_0 // 1 - retsub - -__puya_arc4_router___verify_acct_min_balance_route@3: - // tests/artifacts/state-ops/contract.algo.ts:39 - // @arc4.abimethod() - txn OnCompletion - ! - assert // OnCompletion is not NoOp - txn ApplicationID - assert // can only call when not creating - // tests/artifacts/state-ops/contract.algo.ts:26 - // export class StateAcctParamsGetContract extends arc4.Contract { - txna ApplicationArgs 1 - btoi - txnas Accounts - // tests/artifacts/state-ops/contract.algo.ts:39 - // @arc4.abimethod() - callsub verify_acct_min_balance - itob - bytec_0 // 0x151f7c75 - swap - concat - log - intc_0 // 1 - retsub - -__puya_arc4_router___verify_acct_auth_addr_route@4: - // tests/artifacts/state-ops/contract.algo.ts:51 - // @arc4.abimethod() - txn OnCompletion - ! - assert // OnCompletion is not NoOp - txn ApplicationID - assert // can only call when not creating - // tests/artifacts/state-ops/contract.algo.ts:26 - // export class StateAcctParamsGetContract extends arc4.Contract { - txna ApplicationArgs 1 - btoi - txnas Accounts - // tests/artifacts/state-ops/contract.algo.ts:51 - // @arc4.abimethod() - callsub verify_acct_auth_addr - bytec_0 // 0x151f7c75 - swap - concat - log - intc_0 // 1 - retsub - -__puya_arc4_router___verify_acct_total_num_uint_route@5: - // tests/artifacts/state-ops/contract.algo.ts:60 - // @arc4.abimethod() - txn OnCompletion - ! - assert // OnCompletion is not NoOp - txn ApplicationID - assert // can only call when not creating - // tests/artifacts/state-ops/contract.algo.ts:26 - // export class StateAcctParamsGetContract extends arc4.Contract { - txna ApplicationArgs 1 - btoi - txnas Accounts - // tests/artifacts/state-ops/contract.algo.ts:60 - // @arc4.abimethod() - callsub verify_acct_total_num_uint - itob - bytec_0 // 0x151f7c75 - swap - concat - log - intc_0 // 1 - retsub - -__puya_arc4_router___verify_acct_total_num_byte_slice_route@6: - // tests/artifacts/state-ops/contract.algo.ts:69 - // @arc4.abimethod() - txn OnCompletion - ! - assert // OnCompletion is not NoOp - txn ApplicationID - assert // can only call when not creating - // tests/artifacts/state-ops/contract.algo.ts:26 - // export class StateAcctParamsGetContract extends arc4.Contract { - txna ApplicationArgs 1 - btoi - txnas Accounts - // tests/artifacts/state-ops/contract.algo.ts:69 - // @arc4.abimethod() - callsub verify_acct_total_num_byte_slice - itob - bytec_0 // 0x151f7c75 - swap - concat - log - intc_0 // 1 - retsub - -__puya_arc4_router___verify_acct_total_extra_app_pages_route@7: - // tests/artifacts/state-ops/contract.algo.ts:78 - // @arc4.abimethod() - txn OnCompletion - ! - assert // OnCompletion is not NoOp - txn ApplicationID - assert // can only call when not creating - // tests/artifacts/state-ops/contract.algo.ts:26 - // export class StateAcctParamsGetContract extends arc4.Contract { - txna ApplicationArgs 1 - btoi - txnas Accounts - // tests/artifacts/state-ops/contract.algo.ts:78 - // @arc4.abimethod() - callsub verify_acct_total_extra_app_pages - itob - bytec_0 // 0x151f7c75 - swap - concat - log - intc_0 // 1 - retsub - -__puya_arc4_router___verify_acct_total_apps_created_route@8: - // tests/artifacts/state-ops/contract.algo.ts:87 - // @arc4.abimethod() - txn OnCompletion - ! - assert // OnCompletion is not NoOp - txn ApplicationID - assert // can only call when not creating - // tests/artifacts/state-ops/contract.algo.ts:26 - // export class StateAcctParamsGetContract extends arc4.Contract { - txna ApplicationArgs 1 - btoi - txnas Accounts - // tests/artifacts/state-ops/contract.algo.ts:87 - // @arc4.abimethod() - callsub verify_acct_total_apps_created - itob - bytec_0 // 0x151f7c75 - swap - concat - log - intc_0 // 1 - retsub - -__puya_arc4_router___verify_acct_total_apps_opted_in_route@9: - // tests/artifacts/state-ops/contract.algo.ts:96 - // @arc4.abimethod() - txn OnCompletion - ! - assert // OnCompletion is not NoOp - txn ApplicationID - assert // can only call when not creating - // tests/artifacts/state-ops/contract.algo.ts:26 - // export class StateAcctParamsGetContract extends arc4.Contract { - txna ApplicationArgs 1 - btoi - txnas Accounts - // tests/artifacts/state-ops/contract.algo.ts:96 - // @arc4.abimethod() - callsub verify_acct_total_apps_opted_in - itob - bytec_0 // 0x151f7c75 - swap - concat - log - intc_0 // 1 - retsub - -__puya_arc4_router___verify_acct_total_assets_created_route@10: - // tests/artifacts/state-ops/contract.algo.ts:105 - // @arc4.abimethod() - txn OnCompletion - ! - assert // OnCompletion is not NoOp - txn ApplicationID - assert // can only call when not creating - // tests/artifacts/state-ops/contract.algo.ts:26 - // export class StateAcctParamsGetContract extends arc4.Contract { - txna ApplicationArgs 1 - btoi - txnas Accounts - // tests/artifacts/state-ops/contract.algo.ts:105 - // @arc4.abimethod() - callsub verify_acct_total_assets_created - itob - bytec_0 // 0x151f7c75 - swap - concat - log - intc_0 // 1 - retsub - -__puya_arc4_router___verify_acct_total_assets_route@11: - // tests/artifacts/state-ops/contract.algo.ts:114 - // @arc4.abimethod() - txn OnCompletion - ! - assert // OnCompletion is not NoOp - txn ApplicationID - assert // can only call when not creating - // tests/artifacts/state-ops/contract.algo.ts:26 - // export class StateAcctParamsGetContract extends arc4.Contract { - txna ApplicationArgs 1 - btoi - txnas Accounts - // tests/artifacts/state-ops/contract.algo.ts:114 - // @arc4.abimethod() - callsub verify_acct_total_assets - itob - bytec_0 // 0x151f7c75 - swap - concat - log - intc_0 // 1 - retsub - -__puya_arc4_router___verify_acct_total_boxes_route@12: - // tests/artifacts/state-ops/contract.algo.ts:123 - // @arc4.abimethod() - txn OnCompletion - ! - assert // OnCompletion is not NoOp - txn ApplicationID - assert // can only call when not creating - // tests/artifacts/state-ops/contract.algo.ts:26 - // export class StateAcctParamsGetContract extends arc4.Contract { - txna ApplicationArgs 1 - btoi - txnas Accounts - // tests/artifacts/state-ops/contract.algo.ts:123 - // @arc4.abimethod() - callsub verify_acct_total_boxes - itob - bytec_0 // 0x151f7c75 - swap - concat - log - intc_0 // 1 - retsub - -__puya_arc4_router___verify_acct_total_box_bytes_route@13: - // tests/artifacts/state-ops/contract.algo.ts:132 - // @arc4.abimethod() - txn OnCompletion - ! - assert // OnCompletion is not NoOp - txn ApplicationID - assert // can only call when not creating - // tests/artifacts/state-ops/contract.algo.ts:26 - // export class StateAcctParamsGetContract extends arc4.Contract { - txna ApplicationArgs 1 - btoi - txnas Accounts - // tests/artifacts/state-ops/contract.algo.ts:132 - // @arc4.abimethod() - callsub verify_acct_total_box_bytes - itob - bytec_0 // 0x151f7c75 - swap - concat - log - intc_0 // 1 - retsub - -__puya_arc4_router___bare_routing@16: - // tests/artifacts/state-ops/contract.algo.ts:26 - // export class StateAcctParamsGetContract extends arc4.Contract { - txn OnCompletion - bnz __puya_arc4_router___after_if_else@20 - txn ApplicationID - ! - assert // can only call when creating - intc_0 // 1 - retsub - -__puya_arc4_router___after_if_else@20: - // tests/artifacts/state-ops/contract.algo.ts:26 - // export class StateAcctParamsGetContract extends arc4.Contract { - intc_1 // 0 - retsub - - -// tests/artifacts/state-ops/contract.algo.ts::StateAcctParamsGetContract.verify_acct_balance(a: bytes) -> uint64: -verify_acct_balance: - // tests/artifacts/state-ops/contract.algo.ts:27-28 - // @arc4.abimethod() - // public verify_acct_balance(a: Account): uint64 { - proto 1 1 - // tests/artifacts/state-ops/contract.algo.ts:29 - // const [value, funded] = op.AcctParams.acctBalance(a) - frame_dig -1 - acct_params_get AcctBalance - // tests/artifacts/state-ops/contract.algo.ts:30 - // const [value_index, funded_index] = op.AcctParams.acctBalance(get_1st_ref_index()) - callsub get_1st_ref_index - acct_params_get AcctBalance - // tests/artifacts/state-ops/contract.algo.ts:31 - // assert(value === value_index, 'expected value by index to match') - dig 3 - uncover 2 - == - assert // expected value by index to match - // tests/artifacts/state-ops/contract.algo.ts:32 - // assert(funded === funded_index, 'expected funded by index to match') - == - assert // expected funded by index to match - // tests/artifacts/state-ops/contract.algo.ts:33 - // assert(value === a.balance, 'expected Account balance to match') - frame_dig -1 - acct_params_get AcctBalance - assert // account funded - dig 1 - == - assert // expected Account balance to match - // tests/artifacts/state-ops/contract.algo.ts:34 - // assert(value === op.balance(a), 'expected op.balance to match') - frame_dig -1 - balance - dig 1 - == - assert // expected op.balance to match - // tests/artifacts/state-ops/contract.algo.ts:35 - // assert(value === op.balance(get_1st_ref_index()), 'expected op.balance by index to match') - callsub get_1st_ref_index - balance - dig 1 - == - assert // expected op.balance by index to match - // tests/artifacts/state-ops/contract.algo.ts:36 - // return value - retsub - - -// tests/artifacts/state-ops/contract.algo.ts::get_1st_ref_index() -> uint64: -get_1st_ref_index: - // tests/artifacts/state-ops/contract.algo.ts:22 - // function get_1st_ref_index(): uint64 { - proto 0 1 - // tests/artifacts/state-ops/contract.algo.ts:23 - // return op.btoi(Txn.applicationArgs(1)) - intc_0 // 1 - txnas ApplicationArgs - btoi - retsub - - -// tests/artifacts/state-ops/contract.algo.ts::StateAcctParamsGetContract.verify_acct_min_balance(a: bytes) -> uint64: -verify_acct_min_balance: - // tests/artifacts/state-ops/contract.algo.ts:39-40 - // @arc4.abimethod() - // public verify_acct_min_balance(a: Account): uint64 { - proto 1 1 - // tests/artifacts/state-ops/contract.algo.ts:41 - // const [value, funded] = op.AcctParams.acctMinBalance(a) - frame_dig -1 - acct_params_get AcctMinBalance - // tests/artifacts/state-ops/contract.algo.ts:42 - // const [value_index, funded_index] = op.AcctParams.acctMinBalance(get_1st_ref_index()) - callsub get_1st_ref_index - acct_params_get AcctMinBalance - // tests/artifacts/state-ops/contract.algo.ts:43 - // assert(value === value_index, 'expected value by index to match') - dig 3 - uncover 2 - == - assert // expected value by index to match - // tests/artifacts/state-ops/contract.algo.ts:44 - // assert(funded === funded_index, 'expected funded by index to match') - == - assert // expected funded by index to match - // tests/artifacts/state-ops/contract.algo.ts:45 - // assert(value === a.minBalance, 'expected Account min_balance to match') - frame_dig -1 - acct_params_get AcctMinBalance - assert // account funded - dig 1 - == - assert // expected Account min_balance to match - // tests/artifacts/state-ops/contract.algo.ts:46 - // assert(value === op.minBalance(a), 'expected op.min_balance to match') - frame_dig -1 - min_balance - dig 1 - == - assert // expected op.min_balance to match - // tests/artifacts/state-ops/contract.algo.ts:47 - // assert(value === op.minBalance(get_1st_ref_index()), 'expected op.min_balance by index to match') - callsub get_1st_ref_index - min_balance - dig 1 - == - assert // expected op.min_balance by index to match - // tests/artifacts/state-ops/contract.algo.ts:48 - // return value - retsub - - -// tests/artifacts/state-ops/contract.algo.ts::StateAcctParamsGetContract.verify_acct_auth_addr(a: bytes) -> bytes: -verify_acct_auth_addr: - // tests/artifacts/state-ops/contract.algo.ts:51-52 - // @arc4.abimethod() - // public verify_acct_auth_addr(a: Account): Address { - proto 1 1 - // tests/artifacts/state-ops/contract.algo.ts:53 - // const [value, funded] = op.AcctParams.acctAuthAddr(a) - frame_dig -1 - acct_params_get AcctAuthAddr - // tests/artifacts/state-ops/contract.algo.ts:54 - // const [value_index, funded_index] = op.AcctParams.acctAuthAddr(get_1st_ref_index()) - callsub get_1st_ref_index - acct_params_get AcctAuthAddr - // tests/artifacts/state-ops/contract.algo.ts:55 - // assert(value === value_index, 'expected value by index to match') - dig 3 - uncover 2 - == - assert // expected value by index to match - // tests/artifacts/state-ops/contract.algo.ts:56 - // assert(funded === funded_index, 'expected funded by index to match') - == - assert // expected funded by index to match - // tests/artifacts/state-ops/contract.algo.ts:57 - // return new Address(value) - retsub - - -// tests/artifacts/state-ops/contract.algo.ts::StateAcctParamsGetContract.verify_acct_total_num_uint(a: bytes) -> uint64: -verify_acct_total_num_uint: - // tests/artifacts/state-ops/contract.algo.ts:60-61 - // @arc4.abimethod() - // public verify_acct_total_num_uint(a: Account): uint64 { - proto 1 1 - // tests/artifacts/state-ops/contract.algo.ts:62 - // const [value, funded] = op.AcctParams.acctTotalNumUint(a) - frame_dig -1 - acct_params_get AcctTotalNumUint - // tests/artifacts/state-ops/contract.algo.ts:63 - // const [value_index, funded_index] = op.AcctParams.acctTotalNumUint(get_1st_ref_index()) - callsub get_1st_ref_index - acct_params_get AcctTotalNumUint - // tests/artifacts/state-ops/contract.algo.ts:64 - // assert(value === value_index, 'expected value by index to match') - dig 3 - uncover 2 - == - assert // expected value by index to match - // tests/artifacts/state-ops/contract.algo.ts:65 - // assert(funded === funded_index, 'expected funded by index to match') - == - assert // expected funded by index to match - // tests/artifacts/state-ops/contract.algo.ts:66 - // return value - retsub - - -// tests/artifacts/state-ops/contract.algo.ts::StateAcctParamsGetContract.verify_acct_total_num_byte_slice(a: bytes) -> uint64: -verify_acct_total_num_byte_slice: - // tests/artifacts/state-ops/contract.algo.ts:69-70 - // @arc4.abimethod() - // public verify_acct_total_num_byte_slice(a: Account): uint64 { - proto 1 1 - // tests/artifacts/state-ops/contract.algo.ts:71 - // const [value, funded] = op.AcctParams.acctTotalNumByteSlice(a) - frame_dig -1 - acct_params_get AcctTotalNumByteSlice - // tests/artifacts/state-ops/contract.algo.ts:72 - // const [value_index, funded_index] = op.AcctParams.acctTotalNumByteSlice(get_1st_ref_index()) - callsub get_1st_ref_index - acct_params_get AcctTotalNumByteSlice - // tests/artifacts/state-ops/contract.algo.ts:73 - // assert(value === value_index, 'expected value by index to match') - dig 3 - uncover 2 - == - assert // expected value by index to match - // tests/artifacts/state-ops/contract.algo.ts:74 - // assert(funded === funded_index, 'expected funded by index to match') - == - assert // expected funded by index to match - // tests/artifacts/state-ops/contract.algo.ts:75 - // return value - retsub - - -// tests/artifacts/state-ops/contract.algo.ts::StateAcctParamsGetContract.verify_acct_total_extra_app_pages(a: bytes) -> uint64: -verify_acct_total_extra_app_pages: - // tests/artifacts/state-ops/contract.algo.ts:78-79 - // @arc4.abimethod() - // public verify_acct_total_extra_app_pages(a: Account): uint64 { - proto 1 1 - // tests/artifacts/state-ops/contract.algo.ts:80 - // const [value, funded] = op.AcctParams.acctTotalExtraAppPages(a) - frame_dig -1 - acct_params_get AcctTotalExtraAppPages - // tests/artifacts/state-ops/contract.algo.ts:81 - // const [value_index, funded_index] = op.AcctParams.acctTotalExtraAppPages(get_1st_ref_index()) - callsub get_1st_ref_index - acct_params_get AcctTotalExtraAppPages - // tests/artifacts/state-ops/contract.algo.ts:82 - // assert(value === value_index, 'expected value by index to match') - dig 3 - uncover 2 - == - assert // expected value by index to match - // tests/artifacts/state-ops/contract.algo.ts:83 - // assert(funded === funded_index, 'expected funded by index to match') - == - assert // expected funded by index to match - // tests/artifacts/state-ops/contract.algo.ts:84 - // return value - retsub - - -// tests/artifacts/state-ops/contract.algo.ts::StateAcctParamsGetContract.verify_acct_total_apps_created(a: bytes) -> uint64: -verify_acct_total_apps_created: - // tests/artifacts/state-ops/contract.algo.ts:87-88 - // @arc4.abimethod() - // public verify_acct_total_apps_created(a: Account): uint64 { - proto 1 1 - // tests/artifacts/state-ops/contract.algo.ts:89 - // const [value, funded] = op.AcctParams.acctTotalAppsCreated(a) - frame_dig -1 - acct_params_get AcctTotalAppsCreated - // tests/artifacts/state-ops/contract.algo.ts:90 - // const [value_index, funded_index] = op.AcctParams.acctTotalAppsCreated(get_1st_ref_index()) - callsub get_1st_ref_index - acct_params_get AcctTotalAppsCreated - // tests/artifacts/state-ops/contract.algo.ts:91 - // assert(value === value_index, 'expected value by index to match') - dig 3 - uncover 2 - == - assert // expected value by index to match - // tests/artifacts/state-ops/contract.algo.ts:92 - // assert(funded === funded_index, 'expected funded by index to match') - == - assert // expected funded by index to match - // tests/artifacts/state-ops/contract.algo.ts:93 - // return value - retsub - - -// tests/artifacts/state-ops/contract.algo.ts::StateAcctParamsGetContract.verify_acct_total_apps_opted_in(a: bytes) -> uint64: -verify_acct_total_apps_opted_in: - // tests/artifacts/state-ops/contract.algo.ts:96-97 - // @arc4.abimethod() - // public verify_acct_total_apps_opted_in(a: Account): uint64 { - proto 1 1 - // tests/artifacts/state-ops/contract.algo.ts:98 - // const [value, funded] = op.AcctParams.acctTotalAppsOptedIn(a) - frame_dig -1 - acct_params_get AcctTotalAppsOptedIn - // tests/artifacts/state-ops/contract.algo.ts:99 - // const [value_index, funded_index] = op.AcctParams.acctTotalAppsOptedIn(get_1st_ref_index()) - callsub get_1st_ref_index - acct_params_get AcctTotalAppsOptedIn - // tests/artifacts/state-ops/contract.algo.ts:100 - // assert(value === value_index, 'expected value by index to match') - dig 3 - uncover 2 - == - assert // expected value by index to match - // tests/artifacts/state-ops/contract.algo.ts:101 - // assert(funded === funded_index, 'expected funded by index to match') - == - assert // expected funded by index to match - // tests/artifacts/state-ops/contract.algo.ts:102 - // return value - retsub - - -// tests/artifacts/state-ops/contract.algo.ts::StateAcctParamsGetContract.verify_acct_total_assets_created(a: bytes) -> uint64: -verify_acct_total_assets_created: - // tests/artifacts/state-ops/contract.algo.ts:105-106 - // @arc4.abimethod() - // public verify_acct_total_assets_created(a: Account): uint64 { - proto 1 1 - // tests/artifacts/state-ops/contract.algo.ts:107 - // const [value, funded] = op.AcctParams.acctTotalAssetsCreated(a) - frame_dig -1 - acct_params_get AcctTotalAssetsCreated - // tests/artifacts/state-ops/contract.algo.ts:108 - // const [value_index, funded_index] = op.AcctParams.acctTotalAssetsCreated(get_1st_ref_index()) - callsub get_1st_ref_index - acct_params_get AcctTotalAssetsCreated - // tests/artifacts/state-ops/contract.algo.ts:109 - // assert(value === value_index, 'expected value by index to match') - dig 3 - uncover 2 - == - assert // expected value by index to match - // tests/artifacts/state-ops/contract.algo.ts:110 - // assert(funded === funded_index, 'expected funded by index to match') - == - assert // expected funded by index to match - // tests/artifacts/state-ops/contract.algo.ts:111 - // return value - retsub - - -// tests/artifacts/state-ops/contract.algo.ts::StateAcctParamsGetContract.verify_acct_total_assets(a: bytes) -> uint64: -verify_acct_total_assets: - // tests/artifacts/state-ops/contract.algo.ts:114-115 - // @arc4.abimethod() - // public verify_acct_total_assets(a: Account): uint64 { - proto 1 1 - // tests/artifacts/state-ops/contract.algo.ts:116 - // const [value, funded] = op.AcctParams.acctTotalAssets(a) - frame_dig -1 - acct_params_get AcctTotalAssets - // tests/artifacts/state-ops/contract.algo.ts:117 - // const [value_index, funded_index] = op.AcctParams.acctTotalAssets(get_1st_ref_index()) - callsub get_1st_ref_index - acct_params_get AcctTotalAssets - // tests/artifacts/state-ops/contract.algo.ts:118 - // assert(value === value_index, 'expected value by index to match') - dig 3 - uncover 2 - == - assert // expected value by index to match - // tests/artifacts/state-ops/contract.algo.ts:119 - // assert(funded === funded_index, 'expected funded by index to match') - == - assert // expected funded by index to match - // tests/artifacts/state-ops/contract.algo.ts:120 - // return value - retsub - - -// tests/artifacts/state-ops/contract.algo.ts::StateAcctParamsGetContract.verify_acct_total_boxes(a: bytes) -> uint64: -verify_acct_total_boxes: - // tests/artifacts/state-ops/contract.algo.ts:123-124 - // @arc4.abimethod() - // public verify_acct_total_boxes(a: Account): uint64 { - proto 1 1 - // tests/artifacts/state-ops/contract.algo.ts:125 - // const [value, funded] = op.AcctParams.acctTotalBoxes(a) - frame_dig -1 - acct_params_get AcctTotalBoxes - // tests/artifacts/state-ops/contract.algo.ts:126 - // const [value_index, funded_index] = op.AcctParams.acctTotalBoxes(get_1st_ref_index()) - callsub get_1st_ref_index - acct_params_get AcctTotalBoxes - // tests/artifacts/state-ops/contract.algo.ts:127 - // assert(value === value_index, 'expected value by index to match') - dig 3 - uncover 2 - == - assert // expected value by index to match - // tests/artifacts/state-ops/contract.algo.ts:128 - // assert(funded === funded_index, 'expected funded by index to match') - == - assert // expected funded by index to match - // tests/artifacts/state-ops/contract.algo.ts:129 - // return value - retsub - - -// tests/artifacts/state-ops/contract.algo.ts::StateAcctParamsGetContract.verify_acct_total_box_bytes(a: bytes) -> uint64: -verify_acct_total_box_bytes: - // tests/artifacts/state-ops/contract.algo.ts:132-133 - // @arc4.abimethod() - // public verify_acct_total_box_bytes(a: Account): uint64 { - proto 1 1 - // tests/artifacts/state-ops/contract.algo.ts:134 - // const [value, funded] = op.AcctParams.acctTotalBoxBytes(a) - frame_dig -1 - acct_params_get AcctTotalBoxBytes - // tests/artifacts/state-ops/contract.algo.ts:135 - // const [value_index, funded_index] = op.AcctParams.acctTotalBoxBytes(get_1st_ref_index()) - callsub get_1st_ref_index - acct_params_get AcctTotalBoxBytes - // tests/artifacts/state-ops/contract.algo.ts:136 - // assert(value === value_index, 'expected value by index to match') - dig 3 - uncover 2 - == - assert // expected value by index to match - // tests/artifacts/state-ops/contract.algo.ts:137 - // assert(funded === funded_index, 'expected funded by index to match') - == - assert // expected funded by index to match - // tests/artifacts/state-ops/contract.algo.ts:138 - // return value - retsub diff --git a/tests/artifacts/state-ops/data/StateAcctParamsGetContract.arc32.json b/tests/artifacts/state-ops/data/StateAcctParamsGetContract.arc32.json deleted file mode 100644 index 4fbd3f2..0000000 --- a/tests/artifacts/state-ops/data/StateAcctParamsGetContract.arc32.json +++ /dev/null @@ -1,253 +0,0 @@ -{ - "hints": { - "verify_acct_balance(account)uint64": { - "call_config": { - "no_op": "CALL" - } - }, - "verify_acct_min_balance(account)uint64": { - "call_config": { - "no_op": "CALL" - } - }, - "verify_acct_auth_addr(account)address": { - "call_config": { - "no_op": "CALL" - } - }, - "verify_acct_total_num_uint(account)uint64": { - "call_config": { - "no_op": "CALL" - } - }, - "verify_acct_total_num_byte_slice(account)uint64": { - "call_config": { - "no_op": "CALL" - } - }, - "verify_acct_total_extra_app_pages(account)uint64": { - "call_config": { - "no_op": "CALL" - } - }, - "verify_acct_total_apps_created(account)uint64": { - "call_config": { - "no_op": "CALL" - } - }, - "verify_acct_total_apps_opted_in(account)uint64": { - "call_config": { - "no_op": "CALL" - } - }, - "verify_acct_total_assets_created(account)uint64": { - "call_config": { - "no_op": "CALL" - } - }, - "verify_acct_total_assets(account)uint64": { - "call_config": { - "no_op": "CALL" - } - }, - "verify_acct_total_boxes(account)uint64": { - "call_config": { - "no_op": "CALL" - } - }, - "verify_acct_total_box_bytes(account)uint64": { - "call_config": { - "no_op": "CALL" - } - } - }, - "source": { - "approval": "I3ByYWdtYSB2ZXJzaW9uIDEwCgp0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OlN0YXRlQWNjdFBhcmFtc0dldENvbnRyYWN0LmFwcHJvdmFsUHJvZ3JhbToKICAgIGludGNibG9jayAxIDAKICAgIGJ5dGVjYmxvY2sgMHgxNTFmN2M3NQogICAgY2FsbHN1YiBfX3B1eWFfYXJjNF9yb3V0ZXJfXwogICAgcmV0dXJuCgoKLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjpTdGF0ZUFjY3RQYXJhbXNHZXRDb250cmFjdC5fX3B1eWFfYXJjNF9yb3V0ZXJfXygpIC0+IHVpbnQ2NDoKX19wdXlhX2FyYzRfcm91dGVyX186CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MjYKICAgIC8vIGV4cG9ydCBjbGFzcyBTdGF0ZUFjY3RQYXJhbXNHZXRDb250cmFjdCBleHRlbmRzIGFyYzQuQ29udHJhY3QgewogICAgcHJvdG8gMCAxCiAgICB0eG4gTnVtQXBwQXJncwogICAgYnogX19wdXlhX2FyYzRfcm91dGVyX19fYmFyZV9yb3V0aW5nQDE2CiAgICBwdXNoYnl0ZXNzIDB4NWY1YjQzZTQgMHg3M2RjOTNjNyAweDU2MjZkZmViIDB4ZGM4YTI1YmYgMHgxOThlYmQ4YyAweDIzMDFhYjI2IDB4OWY2OGZjYTYgMHhhOTc1YzJkMSAweGQxZTA0ODAxIDB4YjY5NjZiZTUgMHgxOTVkNTQxOCAweDZhZGFlM2YxIC8vIG1ldGhvZCAidmVyaWZ5X2FjY3RfYmFsYW5jZShhY2NvdW50KXVpbnQ2NCIsIG1ldGhvZCAidmVyaWZ5X2FjY3RfbWluX2JhbGFuY2UoYWNjb3VudCl1aW50NjQiLCBtZXRob2QgInZlcmlmeV9hY2N0X2F1dGhfYWRkcihhY2NvdW50KWFkZHJlc3MiLCBtZXRob2QgInZlcmlmeV9hY2N0X3RvdGFsX251bV91aW50KGFjY291bnQpdWludDY0IiwgbWV0aG9kICJ2ZXJpZnlfYWNjdF90b3RhbF9udW1fYnl0ZV9zbGljZShhY2NvdW50KXVpbnQ2NCIsIG1ldGhvZCAidmVyaWZ5X2FjY3RfdG90YWxfZXh0cmFfYXBwX3BhZ2VzKGFjY291bnQpdWludDY0IiwgbWV0aG9kICJ2ZXJpZnlfYWNjdF90b3RhbF9hcHBzX2NyZWF0ZWQoYWNjb3VudCl1aW50NjQiLCBtZXRob2QgInZlcmlmeV9hY2N0X3RvdGFsX2FwcHNfb3B0ZWRfaW4oYWNjb3VudCl1aW50NjQiLCBtZXRob2QgInZlcmlmeV9hY2N0X3RvdGFsX2Fzc2V0c19jcmVhdGVkKGFjY291bnQpdWludDY0IiwgbWV0aG9kICJ2ZXJpZnlfYWNjdF90b3RhbF9hc3NldHMoYWNjb3VudCl1aW50NjQiLCBtZXRob2QgInZlcmlmeV9hY2N0X3RvdGFsX2JveGVzKGFjY291bnQpdWludDY0IiwgbWV0aG9kICJ2ZXJpZnlfYWNjdF90b3RhbF9ib3hfYnl0ZXMoYWNjb3VudCl1aW50NjQiCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAwCiAgICBtYXRjaCBfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfYWNjdF9iYWxhbmNlX3JvdXRlQDIgX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2FjY3RfbWluX2JhbGFuY2Vfcm91dGVAMyBfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfYWNjdF9hdXRoX2FkZHJfcm91dGVANCBfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfYWNjdF90b3RhbF9udW1fdWludF9yb3V0ZUA1IF9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9hY2N0X3RvdGFsX251bV9ieXRlX3NsaWNlX3JvdXRlQDYgX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2FjY3RfdG90YWxfZXh0cmFfYXBwX3BhZ2VzX3JvdXRlQDcgX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2FjY3RfdG90YWxfYXBwc19jcmVhdGVkX3JvdXRlQDggX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2FjY3RfdG90YWxfYXBwc19vcHRlZF9pbl9yb3V0ZUA5IF9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9hY2N0X3RvdGFsX2Fzc2V0c19jcmVhdGVkX3JvdXRlQDEwIF9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9hY2N0X3RvdGFsX2Fzc2V0c19yb3V0ZUAxMSBfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfYWNjdF90b3RhbF9ib3hlc19yb3V0ZUAxMiBfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfYWNjdF90b3RhbF9ib3hfYnl0ZXNfcm91dGVAMTMKICAgIGludGNfMSAvLyAwCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9hY2N0X2JhbGFuY2Vfcm91dGVAMjoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czoyNwogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgbm90IE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gY2FuIG9ubHkgY2FsbCB3aGVuIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjI2CiAgICAvLyBleHBvcnQgY2xhc3MgU3RhdGVBY2N0UGFyYW1zR2V0Q29udHJhY3QgZXh0ZW5kcyBhcmM0LkNvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGJ0b2kKICAgIHR4bmFzIEFjY291bnRzCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MjcKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV9hY2N0X2JhbGFuY2UKICAgIGl0b2IKICAgIGJ5dGVjXzAgLy8gMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludGNfMCAvLyAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9hY2N0X21pbl9iYWxhbmNlX3JvdXRlQDM6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MzkKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIG5vdCBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGNhbiBvbmx5IGNhbGwgd2hlbiBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czoyNgogICAgLy8gZXhwb3J0IGNsYXNzIFN0YXRlQWNjdFBhcmFtc0dldENvbnRyYWN0IGV4dGVuZHMgYXJjNC5Db250cmFjdCB7CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBidG9pCiAgICB0eG5hcyBBY2NvdW50cwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjM5CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfYWNjdF9taW5fYmFsYW5jZQogICAgaXRvYgogICAgYnl0ZWNfMCAvLyAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50Y18wIC8vIDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2FjY3RfYXV0aF9hZGRyX3JvdXRlQDQ6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NTEKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIG5vdCBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGNhbiBvbmx5IGNhbGwgd2hlbiBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czoyNgogICAgLy8gZXhwb3J0IGNsYXNzIFN0YXRlQWNjdFBhcmFtc0dldENvbnRyYWN0IGV4dGVuZHMgYXJjNC5Db250cmFjdCB7CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBidG9pCiAgICB0eG5hcyBBY2NvdW50cwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjUxCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfYWNjdF9hdXRoX2FkZHIKICAgIGJ5dGVjXzAgLy8gMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludGNfMCAvLyAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9hY2N0X3RvdGFsX251bV91aW50X3JvdXRlQDU6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NjAKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIG5vdCBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGNhbiBvbmx5IGNhbGwgd2hlbiBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czoyNgogICAgLy8gZXhwb3J0IGNsYXNzIFN0YXRlQWNjdFBhcmFtc0dldENvbnRyYWN0IGV4dGVuZHMgYXJjNC5Db250cmFjdCB7CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBidG9pCiAgICB0eG5hcyBBY2NvdW50cwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjYwCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfYWNjdF90b3RhbF9udW1fdWludAogICAgaXRvYgogICAgYnl0ZWNfMCAvLyAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50Y18wIC8vIDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2FjY3RfdG90YWxfbnVtX2J5dGVfc2xpY2Vfcm91dGVANjoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo2OQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgbm90IE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gY2FuIG9ubHkgY2FsbCB3aGVuIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjI2CiAgICAvLyBleHBvcnQgY2xhc3MgU3RhdGVBY2N0UGFyYW1zR2V0Q29udHJhY3QgZXh0ZW5kcyBhcmM0LkNvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGJ0b2kKICAgIHR4bmFzIEFjY291bnRzCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NjkKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV9hY2N0X3RvdGFsX251bV9ieXRlX3NsaWNlCiAgICBpdG9iCiAgICBieXRlY18wIC8vIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnRjXzAgLy8gMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfYWNjdF90b3RhbF9leHRyYV9hcHBfcGFnZXNfcm91dGVANzoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo3OAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgbm90IE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gY2FuIG9ubHkgY2FsbCB3aGVuIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjI2CiAgICAvLyBleHBvcnQgY2xhc3MgU3RhdGVBY2N0UGFyYW1zR2V0Q29udHJhY3QgZXh0ZW5kcyBhcmM0LkNvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGJ0b2kKICAgIHR4bmFzIEFjY291bnRzCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NzgKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV9hY2N0X3RvdGFsX2V4dHJhX2FwcF9wYWdlcwogICAgaXRvYgogICAgYnl0ZWNfMCAvLyAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50Y18wIC8vIDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2FjY3RfdG90YWxfYXBwc19jcmVhdGVkX3JvdXRlQDg6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6ODcKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIG5vdCBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGNhbiBvbmx5IGNhbGwgd2hlbiBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czoyNgogICAgLy8gZXhwb3J0IGNsYXNzIFN0YXRlQWNjdFBhcmFtc0dldENvbnRyYWN0IGV4dGVuZHMgYXJjNC5Db250cmFjdCB7CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBidG9pCiAgICB0eG5hcyBBY2NvdW50cwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjg3CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfYWNjdF90b3RhbF9hcHBzX2NyZWF0ZWQKICAgIGl0b2IKICAgIGJ5dGVjXzAgLy8gMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludGNfMCAvLyAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9hY2N0X3RvdGFsX2FwcHNfb3B0ZWRfaW5fcm91dGVAOToKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo5NgogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgbm90IE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gY2FuIG9ubHkgY2FsbCB3aGVuIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjI2CiAgICAvLyBleHBvcnQgY2xhc3MgU3RhdGVBY2N0UGFyYW1zR2V0Q29udHJhY3QgZXh0ZW5kcyBhcmM0LkNvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGJ0b2kKICAgIHR4bmFzIEFjY291bnRzCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OTYKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV9hY2N0X3RvdGFsX2FwcHNfb3B0ZWRfaW4KICAgIGl0b2IKICAgIGJ5dGVjXzAgLy8gMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludGNfMCAvLyAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9hY2N0X3RvdGFsX2Fzc2V0c19jcmVhdGVkX3JvdXRlQDEwOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjEwNQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgbm90IE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gY2FuIG9ubHkgY2FsbCB3aGVuIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjI2CiAgICAvLyBleHBvcnQgY2xhc3MgU3RhdGVBY2N0UGFyYW1zR2V0Q29udHJhY3QgZXh0ZW5kcyBhcmM0LkNvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGJ0b2kKICAgIHR4bmFzIEFjY291bnRzCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTA1CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfYWNjdF90b3RhbF9hc3NldHNfY3JlYXRlZAogICAgaXRvYgogICAgYnl0ZWNfMCAvLyAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50Y18wIC8vIDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2FjY3RfdG90YWxfYXNzZXRzX3JvdXRlQDExOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjExNAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgbm90IE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gY2FuIG9ubHkgY2FsbCB3aGVuIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjI2CiAgICAvLyBleHBvcnQgY2xhc3MgU3RhdGVBY2N0UGFyYW1zR2V0Q29udHJhY3QgZXh0ZW5kcyBhcmM0LkNvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGJ0b2kKICAgIHR4bmFzIEFjY291bnRzCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTE0CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfYWNjdF90b3RhbF9hc3NldHMKICAgIGl0b2IKICAgIGJ5dGVjXzAgLy8gMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludGNfMCAvLyAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9hY2N0X3RvdGFsX2JveGVzX3JvdXRlQDEyOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjEyMwogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgbm90IE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gY2FuIG9ubHkgY2FsbCB3aGVuIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjI2CiAgICAvLyBleHBvcnQgY2xhc3MgU3RhdGVBY2N0UGFyYW1zR2V0Q29udHJhY3QgZXh0ZW5kcyBhcmM0LkNvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGJ0b2kKICAgIHR4bmFzIEFjY291bnRzCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTIzCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfYWNjdF90b3RhbF9ib3hlcwogICAgaXRvYgogICAgYnl0ZWNfMCAvLyAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50Y18wIC8vIDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2FjY3RfdG90YWxfYm94X2J5dGVzX3JvdXRlQDEzOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjEzMgogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgbm90IE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gY2FuIG9ubHkgY2FsbCB3aGVuIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjI2CiAgICAvLyBleHBvcnQgY2xhc3MgU3RhdGVBY2N0UGFyYW1zR2V0Q29udHJhY3QgZXh0ZW5kcyBhcmM0LkNvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGJ0b2kKICAgIHR4bmFzIEFjY291bnRzCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTMyCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfYWNjdF90b3RhbF9ib3hfYnl0ZXMKICAgIGl0b2IKICAgIGJ5dGVjXzAgLy8gMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludGNfMCAvLyAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX2JhcmVfcm91dGluZ0AxNjoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czoyNgogICAgLy8gZXhwb3J0IGNsYXNzIFN0YXRlQWNjdFBhcmFtc0dldENvbnRyYWN0IGV4dGVuZHMgYXJjNC5Db250cmFjdCB7CiAgICB0eG4gT25Db21wbGV0aW9uCiAgICBibnogX19wdXlhX2FyYzRfcm91dGVyX19fYWZ0ZXJfaWZfZWxzZUAyMAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgICEKICAgIGFzc2VydCAvLyBjYW4gb25seSBjYWxsIHdoZW4gY3JlYXRpbmcKICAgIGludGNfMCAvLyAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX2FmdGVyX2lmX2Vsc2VAMjA6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MjYKICAgIC8vIGV4cG9ydCBjbGFzcyBTdGF0ZUFjY3RQYXJhbXNHZXRDb250cmFjdCBleHRlbmRzIGFyYzQuQ29udHJhY3QgewogICAgaW50Y18xIC8vIDAKICAgIHJldHN1YgoKCi8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo6U3RhdGVBY2N0UGFyYW1zR2V0Q29udHJhY3QudmVyaWZ5X2FjY3RfYmFsYW5jZShhOiBieXRlcykgLT4gdWludDY0Ogp2ZXJpZnlfYWNjdF9iYWxhbmNlOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjI3LTI4CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gcHVibGljIHZlcmlmeV9hY2N0X2JhbGFuY2UoYTogQWNjb3VudCk6IHVpbnQ2NCB7CiAgICBwcm90byAxIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czoyOQogICAgLy8gY29uc3QgW3ZhbHVlLCBmdW5kZWRdID0gb3AuQWNjdFBhcmFtcy5hY2N0QmFsYW5jZShhKQogICAgZnJhbWVfZGlnIC0xCiAgICBhY2N0X3BhcmFtc19nZXQgQWNjdEJhbGFuY2UKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czozMAogICAgLy8gY29uc3QgW3ZhbHVlX2luZGV4LCBmdW5kZWRfaW5kZXhdID0gb3AuQWNjdFBhcmFtcy5hY2N0QmFsYW5jZShnZXRfMXN0X3JlZl9pbmRleCgpKQogICAgY2FsbHN1YiBnZXRfMXN0X3JlZl9pbmRleAogICAgYWNjdF9wYXJhbXNfZ2V0IEFjY3RCYWxhbmNlCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MzEKICAgIC8vIGFzc2VydCh2YWx1ZSA9PT0gdmFsdWVfaW5kZXgsICdleHBlY3RlZCB2YWx1ZSBieSBpbmRleCB0byBtYXRjaCcpCiAgICBkaWcgMwogICAgdW5jb3ZlciAyCiAgICA9PQogICAgYXNzZXJ0IC8vIGV4cGVjdGVkIHZhbHVlIGJ5IGluZGV4IHRvIG1hdGNoCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MzIKICAgIC8vIGFzc2VydChmdW5kZWQgPT09IGZ1bmRlZF9pbmRleCwgJ2V4cGVjdGVkIGZ1bmRlZCBieSBpbmRleCB0byBtYXRjaCcpCiAgICA9PQogICAgYXNzZXJ0IC8vIGV4cGVjdGVkIGZ1bmRlZCBieSBpbmRleCB0byBtYXRjaAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjMzCiAgICAvLyBhc3NlcnQodmFsdWUgPT09IGEuYmFsYW5jZSwgJ2V4cGVjdGVkIEFjY291bnQgYmFsYW5jZSB0byBtYXRjaCcpCiAgICBmcmFtZV9kaWcgLTEKICAgIGFjY3RfcGFyYW1zX2dldCBBY2N0QmFsYW5jZQogICAgYXNzZXJ0IC8vIGFjY291bnQgZnVuZGVkCiAgICBkaWcgMQogICAgPT0KICAgIGFzc2VydCAvLyBleHBlY3RlZCBBY2NvdW50IGJhbGFuY2UgdG8gbWF0Y2gKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czozNAogICAgLy8gYXNzZXJ0KHZhbHVlID09PSBvcC5iYWxhbmNlKGEpLCAnZXhwZWN0ZWQgb3AuYmFsYW5jZSB0byBtYXRjaCcpCiAgICBmcmFtZV9kaWcgLTEKICAgIGJhbGFuY2UKICAgIGRpZyAxCiAgICA9PQogICAgYXNzZXJ0IC8vIGV4cGVjdGVkIG9wLmJhbGFuY2UgdG8gbWF0Y2gKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czozNQogICAgLy8gYXNzZXJ0KHZhbHVlID09PSBvcC5iYWxhbmNlKGdldF8xc3RfcmVmX2luZGV4KCkpLCAnZXhwZWN0ZWQgb3AuYmFsYW5jZSBieSBpbmRleCB0byBtYXRjaCcpCiAgICBjYWxsc3ViIGdldF8xc3RfcmVmX2luZGV4CiAgICBiYWxhbmNlCiAgICBkaWcgMQogICAgPT0KICAgIGFzc2VydCAvLyBleHBlY3RlZCBvcC5iYWxhbmNlIGJ5IGluZGV4IHRvIG1hdGNoCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MzYKICAgIC8vIHJldHVybiB2YWx1ZQogICAgcmV0c3ViCgoKLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjpnZXRfMXN0X3JlZl9pbmRleCgpIC0+IHVpbnQ2NDoKZ2V0XzFzdF9yZWZfaW5kZXg6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MjIKICAgIC8vIGZ1bmN0aW9uIGdldF8xc3RfcmVmX2luZGV4KCk6IHVpbnQ2NCB7CiAgICBwcm90byAwIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czoyMwogICAgLy8gcmV0dXJuIG9wLmJ0b2koVHhuLmFwcGxpY2F0aW9uQXJncygxKSkKICAgIGludGNfMCAvLyAxCiAgICB0eG5hcyBBcHBsaWNhdGlvbkFyZ3MKICAgIGJ0b2kKICAgIHJldHN1YgoKCi8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo6U3RhdGVBY2N0UGFyYW1zR2V0Q29udHJhY3QudmVyaWZ5X2FjY3RfbWluX2JhbGFuY2UoYTogYnl0ZXMpIC0+IHVpbnQ2NDoKdmVyaWZ5X2FjY3RfbWluX2JhbGFuY2U6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MzktNDAKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBwdWJsaWMgdmVyaWZ5X2FjY3RfbWluX2JhbGFuY2UoYTogQWNjb3VudCk6IHVpbnQ2NCB7CiAgICBwcm90byAxIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo0MQogICAgLy8gY29uc3QgW3ZhbHVlLCBmdW5kZWRdID0gb3AuQWNjdFBhcmFtcy5hY2N0TWluQmFsYW5jZShhKQogICAgZnJhbWVfZGlnIC0xCiAgICBhY2N0X3BhcmFtc19nZXQgQWNjdE1pbkJhbGFuY2UKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo0MgogICAgLy8gY29uc3QgW3ZhbHVlX2luZGV4LCBmdW5kZWRfaW5kZXhdID0gb3AuQWNjdFBhcmFtcy5hY2N0TWluQmFsYW5jZShnZXRfMXN0X3JlZl9pbmRleCgpKQogICAgY2FsbHN1YiBnZXRfMXN0X3JlZl9pbmRleAogICAgYWNjdF9wYXJhbXNfZ2V0IEFjY3RNaW5CYWxhbmNlCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NDMKICAgIC8vIGFzc2VydCh2YWx1ZSA9PT0gdmFsdWVfaW5kZXgsICdleHBlY3RlZCB2YWx1ZSBieSBpbmRleCB0byBtYXRjaCcpCiAgICBkaWcgMwogICAgdW5jb3ZlciAyCiAgICA9PQogICAgYXNzZXJ0IC8vIGV4cGVjdGVkIHZhbHVlIGJ5IGluZGV4IHRvIG1hdGNoCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NDQKICAgIC8vIGFzc2VydChmdW5kZWQgPT09IGZ1bmRlZF9pbmRleCwgJ2V4cGVjdGVkIGZ1bmRlZCBieSBpbmRleCB0byBtYXRjaCcpCiAgICA9PQogICAgYXNzZXJ0IC8vIGV4cGVjdGVkIGZ1bmRlZCBieSBpbmRleCB0byBtYXRjaAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjQ1CiAgICAvLyBhc3NlcnQodmFsdWUgPT09IGEubWluQmFsYW5jZSwgJ2V4cGVjdGVkIEFjY291bnQgbWluX2JhbGFuY2UgdG8gbWF0Y2gnKQogICAgZnJhbWVfZGlnIC0xCiAgICBhY2N0X3BhcmFtc19nZXQgQWNjdE1pbkJhbGFuY2UKICAgIGFzc2VydCAvLyBhY2NvdW50IGZ1bmRlZAogICAgZGlnIDEKICAgID09CiAgICBhc3NlcnQgLy8gZXhwZWN0ZWQgQWNjb3VudCBtaW5fYmFsYW5jZSB0byBtYXRjaAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjQ2CiAgICAvLyBhc3NlcnQodmFsdWUgPT09IG9wLm1pbkJhbGFuY2UoYSksICdleHBlY3RlZCBvcC5taW5fYmFsYW5jZSB0byBtYXRjaCcpCiAgICBmcmFtZV9kaWcgLTEKICAgIG1pbl9iYWxhbmNlCiAgICBkaWcgMQogICAgPT0KICAgIGFzc2VydCAvLyBleHBlY3RlZCBvcC5taW5fYmFsYW5jZSB0byBtYXRjaAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjQ3CiAgICAvLyBhc3NlcnQodmFsdWUgPT09IG9wLm1pbkJhbGFuY2UoZ2V0XzFzdF9yZWZfaW5kZXgoKSksICdleHBlY3RlZCBvcC5taW5fYmFsYW5jZSBieSBpbmRleCB0byBtYXRjaCcpCiAgICBjYWxsc3ViIGdldF8xc3RfcmVmX2luZGV4CiAgICBtaW5fYmFsYW5jZQogICAgZGlnIDEKICAgID09CiAgICBhc3NlcnQgLy8gZXhwZWN0ZWQgb3AubWluX2JhbGFuY2UgYnkgaW5kZXggdG8gbWF0Y2gKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo0OAogICAgLy8gcmV0dXJuIHZhbHVlCiAgICByZXRzdWIKCgovLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OlN0YXRlQWNjdFBhcmFtc0dldENvbnRyYWN0LnZlcmlmeV9hY2N0X2F1dGhfYWRkcihhOiBieXRlcykgLT4gYnl0ZXM6CnZlcmlmeV9hY2N0X2F1dGhfYWRkcjoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo1MS01MgogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIHB1YmxpYyB2ZXJpZnlfYWNjdF9hdXRoX2FkZHIoYTogQWNjb3VudCk6IEFkZHJlc3MgewogICAgcHJvdG8gMSAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NTMKICAgIC8vIGNvbnN0IFt2YWx1ZSwgZnVuZGVkXSA9IG9wLkFjY3RQYXJhbXMuYWNjdEF1dGhBZGRyKGEpCiAgICBmcmFtZV9kaWcgLTEKICAgIGFjY3RfcGFyYW1zX2dldCBBY2N0QXV0aEFkZHIKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo1NAogICAgLy8gY29uc3QgW3ZhbHVlX2luZGV4LCBmdW5kZWRfaW5kZXhdID0gb3AuQWNjdFBhcmFtcy5hY2N0QXV0aEFkZHIoZ2V0XzFzdF9yZWZfaW5kZXgoKSkKICAgIGNhbGxzdWIgZ2V0XzFzdF9yZWZfaW5kZXgKICAgIGFjY3RfcGFyYW1zX2dldCBBY2N0QXV0aEFkZHIKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo1NQogICAgLy8gYXNzZXJ0KHZhbHVlID09PSB2YWx1ZV9pbmRleCwgJ2V4cGVjdGVkIHZhbHVlIGJ5IGluZGV4IHRvIG1hdGNoJykKICAgIGRpZyAzCiAgICB1bmNvdmVyIDIKICAgID09CiAgICBhc3NlcnQgLy8gZXhwZWN0ZWQgdmFsdWUgYnkgaW5kZXggdG8gbWF0Y2gKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo1NgogICAgLy8gYXNzZXJ0KGZ1bmRlZCA9PT0gZnVuZGVkX2luZGV4LCAnZXhwZWN0ZWQgZnVuZGVkIGJ5IGluZGV4IHRvIG1hdGNoJykKICAgID09CiAgICBhc3NlcnQgLy8gZXhwZWN0ZWQgZnVuZGVkIGJ5IGluZGV4IHRvIG1hdGNoCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NTcKICAgIC8vIHJldHVybiBuZXcgQWRkcmVzcyh2YWx1ZSkKICAgIHJldHN1YgoKCi8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo6U3RhdGVBY2N0UGFyYW1zR2V0Q29udHJhY3QudmVyaWZ5X2FjY3RfdG90YWxfbnVtX3VpbnQoYTogYnl0ZXMpIC0+IHVpbnQ2NDoKdmVyaWZ5X2FjY3RfdG90YWxfbnVtX3VpbnQ6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NjAtNjEKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBwdWJsaWMgdmVyaWZ5X2FjY3RfdG90YWxfbnVtX3VpbnQoYTogQWNjb3VudCk6IHVpbnQ2NCB7CiAgICBwcm90byAxIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo2MgogICAgLy8gY29uc3QgW3ZhbHVlLCBmdW5kZWRdID0gb3AuQWNjdFBhcmFtcy5hY2N0VG90YWxOdW1VaW50KGEpCiAgICBmcmFtZV9kaWcgLTEKICAgIGFjY3RfcGFyYW1zX2dldCBBY2N0VG90YWxOdW1VaW50CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NjMKICAgIC8vIGNvbnN0IFt2YWx1ZV9pbmRleCwgZnVuZGVkX2luZGV4XSA9IG9wLkFjY3RQYXJhbXMuYWNjdFRvdGFsTnVtVWludChnZXRfMXN0X3JlZl9pbmRleCgpKQogICAgY2FsbHN1YiBnZXRfMXN0X3JlZl9pbmRleAogICAgYWNjdF9wYXJhbXNfZ2V0IEFjY3RUb3RhbE51bVVpbnQKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo2NAogICAgLy8gYXNzZXJ0KHZhbHVlID09PSB2YWx1ZV9pbmRleCwgJ2V4cGVjdGVkIHZhbHVlIGJ5IGluZGV4IHRvIG1hdGNoJykKICAgIGRpZyAzCiAgICB1bmNvdmVyIDIKICAgID09CiAgICBhc3NlcnQgLy8gZXhwZWN0ZWQgdmFsdWUgYnkgaW5kZXggdG8gbWF0Y2gKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo2NQogICAgLy8gYXNzZXJ0KGZ1bmRlZCA9PT0gZnVuZGVkX2luZGV4LCAnZXhwZWN0ZWQgZnVuZGVkIGJ5IGluZGV4IHRvIG1hdGNoJykKICAgID09CiAgICBhc3NlcnQgLy8gZXhwZWN0ZWQgZnVuZGVkIGJ5IGluZGV4IHRvIG1hdGNoCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NjYKICAgIC8vIHJldHVybiB2YWx1ZQogICAgcmV0c3ViCgoKLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjpTdGF0ZUFjY3RQYXJhbXNHZXRDb250cmFjdC52ZXJpZnlfYWNjdF90b3RhbF9udW1fYnl0ZV9zbGljZShhOiBieXRlcykgLT4gdWludDY0Ogp2ZXJpZnlfYWNjdF90b3RhbF9udW1fYnl0ZV9zbGljZToKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo2OS03MAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIHB1YmxpYyB2ZXJpZnlfYWNjdF90b3RhbF9udW1fYnl0ZV9zbGljZShhOiBBY2NvdW50KTogdWludDY0IHsKICAgIHByb3RvIDEgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjcxCiAgICAvLyBjb25zdCBbdmFsdWUsIGZ1bmRlZF0gPSBvcC5BY2N0UGFyYW1zLmFjY3RUb3RhbE51bUJ5dGVTbGljZShhKQogICAgZnJhbWVfZGlnIC0xCiAgICBhY2N0X3BhcmFtc19nZXQgQWNjdFRvdGFsTnVtQnl0ZVNsaWNlCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NzIKICAgIC8vIGNvbnN0IFt2YWx1ZV9pbmRleCwgZnVuZGVkX2luZGV4XSA9IG9wLkFjY3RQYXJhbXMuYWNjdFRvdGFsTnVtQnl0ZVNsaWNlKGdldF8xc3RfcmVmX2luZGV4KCkpCiAgICBjYWxsc3ViIGdldF8xc3RfcmVmX2luZGV4CiAgICBhY2N0X3BhcmFtc19nZXQgQWNjdFRvdGFsTnVtQnl0ZVNsaWNlCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NzMKICAgIC8vIGFzc2VydCh2YWx1ZSA9PT0gdmFsdWVfaW5kZXgsICdleHBlY3RlZCB2YWx1ZSBieSBpbmRleCB0byBtYXRjaCcpCiAgICBkaWcgMwogICAgdW5jb3ZlciAyCiAgICA9PQogICAgYXNzZXJ0IC8vIGV4cGVjdGVkIHZhbHVlIGJ5IGluZGV4IHRvIG1hdGNoCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NzQKICAgIC8vIGFzc2VydChmdW5kZWQgPT09IGZ1bmRlZF9pbmRleCwgJ2V4cGVjdGVkIGZ1bmRlZCBieSBpbmRleCB0byBtYXRjaCcpCiAgICA9PQogICAgYXNzZXJ0IC8vIGV4cGVjdGVkIGZ1bmRlZCBieSBpbmRleCB0byBtYXRjaAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjc1CiAgICAvLyByZXR1cm4gdmFsdWUKICAgIHJldHN1YgoKCi8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo6U3RhdGVBY2N0UGFyYW1zR2V0Q29udHJhY3QudmVyaWZ5X2FjY3RfdG90YWxfZXh0cmFfYXBwX3BhZ2VzKGE6IGJ5dGVzKSAtPiB1aW50NjQ6CnZlcmlmeV9hY2N0X3RvdGFsX2V4dHJhX2FwcF9wYWdlczoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo3OC03OQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIHB1YmxpYyB2ZXJpZnlfYWNjdF90b3RhbF9leHRyYV9hcHBfcGFnZXMoYTogQWNjb3VudCk6IHVpbnQ2NCB7CiAgICBwcm90byAxIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo4MAogICAgLy8gY29uc3QgW3ZhbHVlLCBmdW5kZWRdID0gb3AuQWNjdFBhcmFtcy5hY2N0VG90YWxFeHRyYUFwcFBhZ2VzKGEpCiAgICBmcmFtZV9kaWcgLTEKICAgIGFjY3RfcGFyYW1zX2dldCBBY2N0VG90YWxFeHRyYUFwcFBhZ2VzCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6ODEKICAgIC8vIGNvbnN0IFt2YWx1ZV9pbmRleCwgZnVuZGVkX2luZGV4XSA9IG9wLkFjY3RQYXJhbXMuYWNjdFRvdGFsRXh0cmFBcHBQYWdlcyhnZXRfMXN0X3JlZl9pbmRleCgpKQogICAgY2FsbHN1YiBnZXRfMXN0X3JlZl9pbmRleAogICAgYWNjdF9wYXJhbXNfZ2V0IEFjY3RUb3RhbEV4dHJhQXBwUGFnZXMKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo4MgogICAgLy8gYXNzZXJ0KHZhbHVlID09PSB2YWx1ZV9pbmRleCwgJ2V4cGVjdGVkIHZhbHVlIGJ5IGluZGV4IHRvIG1hdGNoJykKICAgIGRpZyAzCiAgICB1bmNvdmVyIDIKICAgID09CiAgICBhc3NlcnQgLy8gZXhwZWN0ZWQgdmFsdWUgYnkgaW5kZXggdG8gbWF0Y2gKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo4MwogICAgLy8gYXNzZXJ0KGZ1bmRlZCA9PT0gZnVuZGVkX2luZGV4LCAnZXhwZWN0ZWQgZnVuZGVkIGJ5IGluZGV4IHRvIG1hdGNoJykKICAgID09CiAgICBhc3NlcnQgLy8gZXhwZWN0ZWQgZnVuZGVkIGJ5IGluZGV4IHRvIG1hdGNoCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6ODQKICAgIC8vIHJldHVybiB2YWx1ZQogICAgcmV0c3ViCgoKLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjpTdGF0ZUFjY3RQYXJhbXNHZXRDb250cmFjdC52ZXJpZnlfYWNjdF90b3RhbF9hcHBzX2NyZWF0ZWQoYTogYnl0ZXMpIC0+IHVpbnQ2NDoKdmVyaWZ5X2FjY3RfdG90YWxfYXBwc19jcmVhdGVkOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjg3LTg4CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gcHVibGljIHZlcmlmeV9hY2N0X3RvdGFsX2FwcHNfY3JlYXRlZChhOiBBY2NvdW50KTogdWludDY0IHsKICAgIHByb3RvIDEgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjg5CiAgICAvLyBjb25zdCBbdmFsdWUsIGZ1bmRlZF0gPSBvcC5BY2N0UGFyYW1zLmFjY3RUb3RhbEFwcHNDcmVhdGVkKGEpCiAgICBmcmFtZV9kaWcgLTEKICAgIGFjY3RfcGFyYW1zX2dldCBBY2N0VG90YWxBcHBzQ3JlYXRlZAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjkwCiAgICAvLyBjb25zdCBbdmFsdWVfaW5kZXgsIGZ1bmRlZF9pbmRleF0gPSBvcC5BY2N0UGFyYW1zLmFjY3RUb3RhbEFwcHNDcmVhdGVkKGdldF8xc3RfcmVmX2luZGV4KCkpCiAgICBjYWxsc3ViIGdldF8xc3RfcmVmX2luZGV4CiAgICBhY2N0X3BhcmFtc19nZXQgQWNjdFRvdGFsQXBwc0NyZWF0ZWQKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo5MQogICAgLy8gYXNzZXJ0KHZhbHVlID09PSB2YWx1ZV9pbmRleCwgJ2V4cGVjdGVkIHZhbHVlIGJ5IGluZGV4IHRvIG1hdGNoJykKICAgIGRpZyAzCiAgICB1bmNvdmVyIDIKICAgID09CiAgICBhc3NlcnQgLy8gZXhwZWN0ZWQgdmFsdWUgYnkgaW5kZXggdG8gbWF0Y2gKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo5MgogICAgLy8gYXNzZXJ0KGZ1bmRlZCA9PT0gZnVuZGVkX2luZGV4LCAnZXhwZWN0ZWQgZnVuZGVkIGJ5IGluZGV4IHRvIG1hdGNoJykKICAgID09CiAgICBhc3NlcnQgLy8gZXhwZWN0ZWQgZnVuZGVkIGJ5IGluZGV4IHRvIG1hdGNoCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OTMKICAgIC8vIHJldHVybiB2YWx1ZQogICAgcmV0c3ViCgoKLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjpTdGF0ZUFjY3RQYXJhbXNHZXRDb250cmFjdC52ZXJpZnlfYWNjdF90b3RhbF9hcHBzX29wdGVkX2luKGE6IGJ5dGVzKSAtPiB1aW50NjQ6CnZlcmlmeV9hY2N0X3RvdGFsX2FwcHNfb3B0ZWRfaW46CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OTYtOTcKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBwdWJsaWMgdmVyaWZ5X2FjY3RfdG90YWxfYXBwc19vcHRlZF9pbihhOiBBY2NvdW50KTogdWludDY0IHsKICAgIHByb3RvIDEgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjk4CiAgICAvLyBjb25zdCBbdmFsdWUsIGZ1bmRlZF0gPSBvcC5BY2N0UGFyYW1zLmFjY3RUb3RhbEFwcHNPcHRlZEluKGEpCiAgICBmcmFtZV9kaWcgLTEKICAgIGFjY3RfcGFyYW1zX2dldCBBY2N0VG90YWxBcHBzT3B0ZWRJbgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjk5CiAgICAvLyBjb25zdCBbdmFsdWVfaW5kZXgsIGZ1bmRlZF9pbmRleF0gPSBvcC5BY2N0UGFyYW1zLmFjY3RUb3RhbEFwcHNPcHRlZEluKGdldF8xc3RfcmVmX2luZGV4KCkpCiAgICBjYWxsc3ViIGdldF8xc3RfcmVmX2luZGV4CiAgICBhY2N0X3BhcmFtc19nZXQgQWNjdFRvdGFsQXBwc09wdGVkSW4KICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czoxMDAKICAgIC8vIGFzc2VydCh2YWx1ZSA9PT0gdmFsdWVfaW5kZXgsICdleHBlY3RlZCB2YWx1ZSBieSBpbmRleCB0byBtYXRjaCcpCiAgICBkaWcgMwogICAgdW5jb3ZlciAyCiAgICA9PQogICAgYXNzZXJ0IC8vIGV4cGVjdGVkIHZhbHVlIGJ5IGluZGV4IHRvIG1hdGNoCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTAxCiAgICAvLyBhc3NlcnQoZnVuZGVkID09PSBmdW5kZWRfaW5kZXgsICdleHBlY3RlZCBmdW5kZWQgYnkgaW5kZXggdG8gbWF0Y2gnKQogICAgPT0KICAgIGFzc2VydCAvLyBleHBlY3RlZCBmdW5kZWQgYnkgaW5kZXggdG8gbWF0Y2gKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czoxMDIKICAgIC8vIHJldHVybiB2YWx1ZQogICAgcmV0c3ViCgoKLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjpTdGF0ZUFjY3RQYXJhbXNHZXRDb250cmFjdC52ZXJpZnlfYWNjdF90b3RhbF9hc3NldHNfY3JlYXRlZChhOiBieXRlcykgLT4gdWludDY0Ogp2ZXJpZnlfYWNjdF90b3RhbF9hc3NldHNfY3JlYXRlZDoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czoxMDUtMTA2CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gcHVibGljIHZlcmlmeV9hY2N0X3RvdGFsX2Fzc2V0c19jcmVhdGVkKGE6IEFjY291bnQpOiB1aW50NjQgewogICAgcHJvdG8gMSAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTA3CiAgICAvLyBjb25zdCBbdmFsdWUsIGZ1bmRlZF0gPSBvcC5BY2N0UGFyYW1zLmFjY3RUb3RhbEFzc2V0c0NyZWF0ZWQoYSkKICAgIGZyYW1lX2RpZyAtMQogICAgYWNjdF9wYXJhbXNfZ2V0IEFjY3RUb3RhbEFzc2V0c0NyZWF0ZWQKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czoxMDgKICAgIC8vIGNvbnN0IFt2YWx1ZV9pbmRleCwgZnVuZGVkX2luZGV4XSA9IG9wLkFjY3RQYXJhbXMuYWNjdFRvdGFsQXNzZXRzQ3JlYXRlZChnZXRfMXN0X3JlZl9pbmRleCgpKQogICAgY2FsbHN1YiBnZXRfMXN0X3JlZl9pbmRleAogICAgYWNjdF9wYXJhbXNfZ2V0IEFjY3RUb3RhbEFzc2V0c0NyZWF0ZWQKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czoxMDkKICAgIC8vIGFzc2VydCh2YWx1ZSA9PT0gdmFsdWVfaW5kZXgsICdleHBlY3RlZCB2YWx1ZSBieSBpbmRleCB0byBtYXRjaCcpCiAgICBkaWcgMwogICAgdW5jb3ZlciAyCiAgICA9PQogICAgYXNzZXJ0IC8vIGV4cGVjdGVkIHZhbHVlIGJ5IGluZGV4IHRvIG1hdGNoCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTEwCiAgICAvLyBhc3NlcnQoZnVuZGVkID09PSBmdW5kZWRfaW5kZXgsICdleHBlY3RlZCBmdW5kZWQgYnkgaW5kZXggdG8gbWF0Y2gnKQogICAgPT0KICAgIGFzc2VydCAvLyBleHBlY3RlZCBmdW5kZWQgYnkgaW5kZXggdG8gbWF0Y2gKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czoxMTEKICAgIC8vIHJldHVybiB2YWx1ZQogICAgcmV0c3ViCgoKLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjpTdGF0ZUFjY3RQYXJhbXNHZXRDb250cmFjdC52ZXJpZnlfYWNjdF90b3RhbF9hc3NldHMoYTogYnl0ZXMpIC0+IHVpbnQ2NDoKdmVyaWZ5X2FjY3RfdG90YWxfYXNzZXRzOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjExNC0xMTUKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBwdWJsaWMgdmVyaWZ5X2FjY3RfdG90YWxfYXNzZXRzKGE6IEFjY291bnQpOiB1aW50NjQgewogICAgcHJvdG8gMSAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTE2CiAgICAvLyBjb25zdCBbdmFsdWUsIGZ1bmRlZF0gPSBvcC5BY2N0UGFyYW1zLmFjY3RUb3RhbEFzc2V0cyhhKQogICAgZnJhbWVfZGlnIC0xCiAgICBhY2N0X3BhcmFtc19nZXQgQWNjdFRvdGFsQXNzZXRzCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTE3CiAgICAvLyBjb25zdCBbdmFsdWVfaW5kZXgsIGZ1bmRlZF9pbmRleF0gPSBvcC5BY2N0UGFyYW1zLmFjY3RUb3RhbEFzc2V0cyhnZXRfMXN0X3JlZl9pbmRleCgpKQogICAgY2FsbHN1YiBnZXRfMXN0X3JlZl9pbmRleAogICAgYWNjdF9wYXJhbXNfZ2V0IEFjY3RUb3RhbEFzc2V0cwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjExOAogICAgLy8gYXNzZXJ0KHZhbHVlID09PSB2YWx1ZV9pbmRleCwgJ2V4cGVjdGVkIHZhbHVlIGJ5IGluZGV4IHRvIG1hdGNoJykKICAgIGRpZyAzCiAgICB1bmNvdmVyIDIKICAgID09CiAgICBhc3NlcnQgLy8gZXhwZWN0ZWQgdmFsdWUgYnkgaW5kZXggdG8gbWF0Y2gKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czoxMTkKICAgIC8vIGFzc2VydChmdW5kZWQgPT09IGZ1bmRlZF9pbmRleCwgJ2V4cGVjdGVkIGZ1bmRlZCBieSBpbmRleCB0byBtYXRjaCcpCiAgICA9PQogICAgYXNzZXJ0IC8vIGV4cGVjdGVkIGZ1bmRlZCBieSBpbmRleCB0byBtYXRjaAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjEyMAogICAgLy8gcmV0dXJuIHZhbHVlCiAgICByZXRzdWIKCgovLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OlN0YXRlQWNjdFBhcmFtc0dldENvbnRyYWN0LnZlcmlmeV9hY2N0X3RvdGFsX2JveGVzKGE6IGJ5dGVzKSAtPiB1aW50NjQ6CnZlcmlmeV9hY2N0X3RvdGFsX2JveGVzOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjEyMy0xMjQKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBwdWJsaWMgdmVyaWZ5X2FjY3RfdG90YWxfYm94ZXMoYTogQWNjb3VudCk6IHVpbnQ2NCB7CiAgICBwcm90byAxIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czoxMjUKICAgIC8vIGNvbnN0IFt2YWx1ZSwgZnVuZGVkXSA9IG9wLkFjY3RQYXJhbXMuYWNjdFRvdGFsQm94ZXMoYSkKICAgIGZyYW1lX2RpZyAtMQogICAgYWNjdF9wYXJhbXNfZ2V0IEFjY3RUb3RhbEJveGVzCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTI2CiAgICAvLyBjb25zdCBbdmFsdWVfaW5kZXgsIGZ1bmRlZF9pbmRleF0gPSBvcC5BY2N0UGFyYW1zLmFjY3RUb3RhbEJveGVzKGdldF8xc3RfcmVmX2luZGV4KCkpCiAgICBjYWxsc3ViIGdldF8xc3RfcmVmX2luZGV4CiAgICBhY2N0X3BhcmFtc19nZXQgQWNjdFRvdGFsQm94ZXMKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czoxMjcKICAgIC8vIGFzc2VydCh2YWx1ZSA9PT0gdmFsdWVfaW5kZXgsICdleHBlY3RlZCB2YWx1ZSBieSBpbmRleCB0byBtYXRjaCcpCiAgICBkaWcgMwogICAgdW5jb3ZlciAyCiAgICA9PQogICAgYXNzZXJ0IC8vIGV4cGVjdGVkIHZhbHVlIGJ5IGluZGV4IHRvIG1hdGNoCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTI4CiAgICAvLyBhc3NlcnQoZnVuZGVkID09PSBmdW5kZWRfaW5kZXgsICdleHBlY3RlZCBmdW5kZWQgYnkgaW5kZXggdG8gbWF0Y2gnKQogICAgPT0KICAgIGFzc2VydCAvLyBleHBlY3RlZCBmdW5kZWQgYnkgaW5kZXggdG8gbWF0Y2gKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czoxMjkKICAgIC8vIHJldHVybiB2YWx1ZQogICAgcmV0c3ViCgoKLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjpTdGF0ZUFjY3RQYXJhbXNHZXRDb250cmFjdC52ZXJpZnlfYWNjdF90b3RhbF9ib3hfYnl0ZXMoYTogYnl0ZXMpIC0+IHVpbnQ2NDoKdmVyaWZ5X2FjY3RfdG90YWxfYm94X2J5dGVzOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjEzMi0xMzMKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBwdWJsaWMgdmVyaWZ5X2FjY3RfdG90YWxfYm94X2J5dGVzKGE6IEFjY291bnQpOiB1aW50NjQgewogICAgcHJvdG8gMSAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTM0CiAgICAvLyBjb25zdCBbdmFsdWUsIGZ1bmRlZF0gPSBvcC5BY2N0UGFyYW1zLmFjY3RUb3RhbEJveEJ5dGVzKGEpCiAgICBmcmFtZV9kaWcgLTEKICAgIGFjY3RfcGFyYW1zX2dldCBBY2N0VG90YWxCb3hCeXRlcwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjEzNQogICAgLy8gY29uc3QgW3ZhbHVlX2luZGV4LCBmdW5kZWRfaW5kZXhdID0gb3AuQWNjdFBhcmFtcy5hY2N0VG90YWxCb3hCeXRlcyhnZXRfMXN0X3JlZl9pbmRleCgpKQogICAgY2FsbHN1YiBnZXRfMXN0X3JlZl9pbmRleAogICAgYWNjdF9wYXJhbXNfZ2V0IEFjY3RUb3RhbEJveEJ5dGVzCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTM2CiAgICAvLyBhc3NlcnQodmFsdWUgPT09IHZhbHVlX2luZGV4LCAnZXhwZWN0ZWQgdmFsdWUgYnkgaW5kZXggdG8gbWF0Y2gnKQogICAgZGlnIDMKICAgIHVuY292ZXIgMgogICAgPT0KICAgIGFzc2VydCAvLyBleHBlY3RlZCB2YWx1ZSBieSBpbmRleCB0byBtYXRjaAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjEzNwogICAgLy8gYXNzZXJ0KGZ1bmRlZCA9PT0gZnVuZGVkX2luZGV4LCAnZXhwZWN0ZWQgZnVuZGVkIGJ5IGluZGV4IHRvIG1hdGNoJykKICAgID09CiAgICBhc3NlcnQgLy8gZXhwZWN0ZWQgZnVuZGVkIGJ5IGluZGV4IHRvIG1hdGNoCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTM4CiAgICAvLyByZXR1cm4gdmFsdWUKICAgIHJldHN1Ygo=", - "clear": "I3ByYWdtYSB2ZXJzaW9uIDEwCgp0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OlN0YXRlQWNjdFBhcmFtc0dldENvbnRyYWN0LmNsZWFyU3RhdGVQcm9ncmFtOgogICAgcHVzaGludCAxIC8vIDEKICAgIHJldHVybgo=" - }, - "state": { - "global": { - "num_byte_slices": 0, - "num_uints": 0 - }, - "local": { - "num_byte_slices": 0, - "num_uints": 0 - } - }, - "schema": { - "global": { - "declared": {}, - "reserved": {} - }, - "local": { - "declared": {}, - "reserved": {} - } - }, - "contract": { - "name": "StateAcctParamsGetContract", - "methods": [ - { - "name": "verify_acct_balance", - "args": [ - { - "type": "account", - "name": "a" - } - ], - "readonly": false, - "returns": { - "type": "uint64" - } - }, - { - "name": "verify_acct_min_balance", - "args": [ - { - "type": "account", - "name": "a" - } - ], - "readonly": false, - "returns": { - "type": "uint64" - } - }, - { - "name": "verify_acct_auth_addr", - "args": [ - { - "type": "account", - "name": "a" - } - ], - "readonly": false, - "returns": { - "type": "address" - } - }, - { - "name": "verify_acct_total_num_uint", - "args": [ - { - "type": "account", - "name": "a" - } - ], - "readonly": false, - "returns": { - "type": "uint64" - } - }, - { - "name": "verify_acct_total_num_byte_slice", - "args": [ - { - "type": "account", - "name": "a" - } - ], - "readonly": false, - "returns": { - "type": "uint64" - } - }, - { - "name": "verify_acct_total_extra_app_pages", - "args": [ - { - "type": "account", - "name": "a" - } - ], - "readonly": false, - "returns": { - "type": "uint64" - } - }, - { - "name": "verify_acct_total_apps_created", - "args": [ - { - "type": "account", - "name": "a" - } - ], - "readonly": false, - "returns": { - "type": "uint64" - } - }, - { - "name": "verify_acct_total_apps_opted_in", - "args": [ - { - "type": "account", - "name": "a" - } - ], - "readonly": false, - "returns": { - "type": "uint64" - } - }, - { - "name": "verify_acct_total_assets_created", - "args": [ - { - "type": "account", - "name": "a" - } - ], - "readonly": false, - "returns": { - "type": "uint64" - } - }, - { - "name": "verify_acct_total_assets", - "args": [ - { - "type": "account", - "name": "a" - } - ], - "readonly": false, - "returns": { - "type": "uint64" - } - }, - { - "name": "verify_acct_total_boxes", - "args": [ - { - "type": "account", - "name": "a" - } - ], - "readonly": false, - "returns": { - "type": "uint64" - } - }, - { - "name": "verify_acct_total_box_bytes", - "args": [ - { - "type": "account", - "name": "a" - } - ], - "readonly": false, - "returns": { - "type": "uint64" - } - } - ], - "networks": {} - }, - "bare_call_config": { - "no_op": "CREATE" - } -} \ No newline at end of file diff --git a/tests/artifacts/state-ops/data/StateAcctParamsGetContract.arc56.json b/tests/artifacts/state-ops/data/StateAcctParamsGetContract.arc56.json deleted file mode 100644 index 0ad82cf..0000000 --- a/tests/artifacts/state-ops/data/StateAcctParamsGetContract.arc56.json +++ /dev/null @@ -1,425 +0,0 @@ -{ - "name": "StateAcctParamsGetContract", - "structs": {}, - "methods": [ - { - "name": "verify_acct_balance", - "args": [ - { - "type": "account", - "name": "a" - } - ], - "returns": { - "type": "uint64" - }, - "actions": { - "create": [], - "call": [ - "NoOp" - ] - }, - "readonly": false, - "events": [], - "recommendations": {} - }, - { - "name": "verify_acct_min_balance", - "args": [ - { - "type": "account", - "name": "a" - } - ], - "returns": { - "type": "uint64" - }, - "actions": { - "create": [], - "call": [ - "NoOp" - ] - }, - "readonly": false, - "events": [], - "recommendations": {} - }, - { - "name": "verify_acct_auth_addr", - "args": [ - { - "type": "account", - "name": "a" - } - ], - "returns": { - "type": "address" - }, - "actions": { - "create": [], - "call": [ - "NoOp" - ] - }, - "readonly": false, - "events": [], - "recommendations": {} - }, - { - "name": "verify_acct_total_num_uint", - "args": [ - { - "type": "account", - "name": "a" - } - ], - "returns": { - "type": "uint64" - }, - "actions": { - "create": [], - "call": [ - "NoOp" - ] - }, - "readonly": false, - "events": [], - "recommendations": {} - }, - { - "name": "verify_acct_total_num_byte_slice", - "args": [ - { - "type": "account", - "name": "a" - } - ], - "returns": { - "type": "uint64" - }, - "actions": { - "create": [], - "call": [ - "NoOp" - ] - }, - "readonly": false, - "events": [], - "recommendations": {} - }, - { - "name": "verify_acct_total_extra_app_pages", - "args": [ - { - "type": "account", - "name": "a" - } - ], - "returns": { - "type": "uint64" - }, - "actions": { - "create": [], - "call": [ - "NoOp" - ] - }, - "readonly": false, - "events": [], - "recommendations": {} - }, - { - "name": "verify_acct_total_apps_created", - "args": [ - { - "type": "account", - "name": "a" - } - ], - "returns": { - "type": "uint64" - }, - "actions": { - "create": [], - "call": [ - "NoOp" - ] - }, - "readonly": false, - "events": [], - "recommendations": {} - }, - { - "name": "verify_acct_total_apps_opted_in", - "args": [ - { - "type": "account", - "name": "a" - } - ], - "returns": { - "type": "uint64" - }, - "actions": { - "create": [], - "call": [ - "NoOp" - ] - }, - "readonly": false, - "events": [], - "recommendations": {} - }, - { - "name": "verify_acct_total_assets_created", - "args": [ - { - "type": "account", - "name": "a" - } - ], - "returns": { - "type": "uint64" - }, - "actions": { - "create": [], - "call": [ - "NoOp" - ] - }, - "readonly": false, - "events": [], - "recommendations": {} - }, - { - "name": "verify_acct_total_assets", - "args": [ - { - "type": "account", - "name": "a" - } - ], - "returns": { - "type": "uint64" - }, - "actions": { - "create": [], - "call": [ - "NoOp" - ] - }, - "readonly": false, - "events": [], - "recommendations": {} - }, - { - "name": "verify_acct_total_boxes", - "args": [ - { - "type": "account", - "name": "a" - } - ], - "returns": { - "type": "uint64" - }, - "actions": { - "create": [], - "call": [ - "NoOp" - ] - }, - "readonly": false, - "events": [], - "recommendations": {} - }, - { - "name": "verify_acct_total_box_bytes", - "args": [ - { - "type": "account", - "name": "a" - } - ], - "returns": { - "type": "uint64" - }, - "actions": { - "create": [], - "call": [ - "NoOp" - ] - }, - "readonly": false, - "events": [], - "recommendations": {} - } - ], - "arcs": [ - 22, - 28 - ], - "networks": {}, - "state": { - "schema": { - "global": { - "ints": 0, - "bytes": 0 - }, - "local": { - "ints": 0, - "bytes": 0 - } - }, - "keys": { - "global": {}, - "local": {}, - "box": {} - }, - "maps": { - "global": {}, - "local": {}, - "box": {} - } - }, - "bareActions": { - "create": [ - "NoOp" - ], - "call": [] - }, - "sourceInfo": { - "approval": { - "sourceInfo": [ - { - "pc": [ - 120, - 143, - 166, - 188, - 211, - 234, - 257, - 280, - 303, - 326, - 349, - 372 - ], - "errorMessage": "OnCompletion is not NoOp" - }, - { - "pc": [ - 429, - 482 - ], - "errorMessage": "account funded" - }, - { - "pc": [ - 400 - ], - "errorMessage": "can only call when creating" - }, - { - "pc": [ - 123, - 146, - 169, - 191, - 214, - 237, - 260, - 283, - 306, - 329, - 352, - 375 - ], - "errorMessage": "can only call when not creating" - }, - { - "pc": [ - 433 - ], - "errorMessage": "expected Account balance to match" - }, - { - "pc": [ - 486 - ], - "errorMessage": "expected Account min_balance to match" - }, - { - "pc": [ - 424, - 477, - 522, - 543, - 564, - 585, - 606, - 627, - 648, - 669, - 690, - 711 - ], - "errorMessage": "expected funded by index to match" - }, - { - "pc": [ - 448 - ], - "errorMessage": "expected op.balance by index to match" - }, - { - "pc": [ - 440 - ], - "errorMessage": "expected op.balance to match" - }, - { - "pc": [ - 501 - ], - "errorMessage": "expected op.min_balance by index to match" - }, - { - "pc": [ - 493 - ], - "errorMessage": "expected op.min_balance to match" - }, - { - "pc": [ - 422, - 475, - 520, - 541, - 562, - 583, - 604, - 625, - 646, - 667, - 688, - 709 - ], - "errorMessage": "expected value by index to match" - } - ], - "pcOffsetMethod": "none" - }, - "clear": { - "sourceInfo": [], - "pcOffsetMethod": "none" - } - }, - "source": { - "approval": "I3ByYWdtYSB2ZXJzaW9uIDEwCgp0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OlN0YXRlQWNjdFBhcmFtc0dldENvbnRyYWN0LmFwcHJvdmFsUHJvZ3JhbToKICAgIGludGNibG9jayAxIDAKICAgIGJ5dGVjYmxvY2sgMHgxNTFmN2M3NQogICAgY2FsbHN1YiBfX3B1eWFfYXJjNF9yb3V0ZXJfXwogICAgcmV0dXJuCgoKLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjpTdGF0ZUFjY3RQYXJhbXNHZXRDb250cmFjdC5fX3B1eWFfYXJjNF9yb3V0ZXJfXygpIC0+IHVpbnQ2NDoKX19wdXlhX2FyYzRfcm91dGVyX186CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MjYKICAgIC8vIGV4cG9ydCBjbGFzcyBTdGF0ZUFjY3RQYXJhbXNHZXRDb250cmFjdCBleHRlbmRzIGFyYzQuQ29udHJhY3QgewogICAgcHJvdG8gMCAxCiAgICB0eG4gTnVtQXBwQXJncwogICAgYnogX19wdXlhX2FyYzRfcm91dGVyX19fYmFyZV9yb3V0aW5nQDE2CiAgICBwdXNoYnl0ZXNzIDB4NWY1YjQzZTQgMHg3M2RjOTNjNyAweDU2MjZkZmViIDB4ZGM4YTI1YmYgMHgxOThlYmQ4YyAweDIzMDFhYjI2IDB4OWY2OGZjYTYgMHhhOTc1YzJkMSAweGQxZTA0ODAxIDB4YjY5NjZiZTUgMHgxOTVkNTQxOCAweDZhZGFlM2YxIC8vIG1ldGhvZCAidmVyaWZ5X2FjY3RfYmFsYW5jZShhY2NvdW50KXVpbnQ2NCIsIG1ldGhvZCAidmVyaWZ5X2FjY3RfbWluX2JhbGFuY2UoYWNjb3VudCl1aW50NjQiLCBtZXRob2QgInZlcmlmeV9hY2N0X2F1dGhfYWRkcihhY2NvdW50KWFkZHJlc3MiLCBtZXRob2QgInZlcmlmeV9hY2N0X3RvdGFsX251bV91aW50KGFjY291bnQpdWludDY0IiwgbWV0aG9kICJ2ZXJpZnlfYWNjdF90b3RhbF9udW1fYnl0ZV9zbGljZShhY2NvdW50KXVpbnQ2NCIsIG1ldGhvZCAidmVyaWZ5X2FjY3RfdG90YWxfZXh0cmFfYXBwX3BhZ2VzKGFjY291bnQpdWludDY0IiwgbWV0aG9kICJ2ZXJpZnlfYWNjdF90b3RhbF9hcHBzX2NyZWF0ZWQoYWNjb3VudCl1aW50NjQiLCBtZXRob2QgInZlcmlmeV9hY2N0X3RvdGFsX2FwcHNfb3B0ZWRfaW4oYWNjb3VudCl1aW50NjQiLCBtZXRob2QgInZlcmlmeV9hY2N0X3RvdGFsX2Fzc2V0c19jcmVhdGVkKGFjY291bnQpdWludDY0IiwgbWV0aG9kICJ2ZXJpZnlfYWNjdF90b3RhbF9hc3NldHMoYWNjb3VudCl1aW50NjQiLCBtZXRob2QgInZlcmlmeV9hY2N0X3RvdGFsX2JveGVzKGFjY291bnQpdWludDY0IiwgbWV0aG9kICJ2ZXJpZnlfYWNjdF90b3RhbF9ib3hfYnl0ZXMoYWNjb3VudCl1aW50NjQiCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAwCiAgICBtYXRjaCBfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfYWNjdF9iYWxhbmNlX3JvdXRlQDIgX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2FjY3RfbWluX2JhbGFuY2Vfcm91dGVAMyBfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfYWNjdF9hdXRoX2FkZHJfcm91dGVANCBfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfYWNjdF90b3RhbF9udW1fdWludF9yb3V0ZUA1IF9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9hY2N0X3RvdGFsX251bV9ieXRlX3NsaWNlX3JvdXRlQDYgX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2FjY3RfdG90YWxfZXh0cmFfYXBwX3BhZ2VzX3JvdXRlQDcgX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2FjY3RfdG90YWxfYXBwc19jcmVhdGVkX3JvdXRlQDggX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2FjY3RfdG90YWxfYXBwc19vcHRlZF9pbl9yb3V0ZUA5IF9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9hY2N0X3RvdGFsX2Fzc2V0c19jcmVhdGVkX3JvdXRlQDEwIF9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9hY2N0X3RvdGFsX2Fzc2V0c19yb3V0ZUAxMSBfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfYWNjdF90b3RhbF9ib3hlc19yb3V0ZUAxMiBfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfYWNjdF90b3RhbF9ib3hfYnl0ZXNfcm91dGVAMTMKICAgIGludGNfMSAvLyAwCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9hY2N0X2JhbGFuY2Vfcm91dGVAMjoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czoyNwogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgbm90IE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gY2FuIG9ubHkgY2FsbCB3aGVuIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjI2CiAgICAvLyBleHBvcnQgY2xhc3MgU3RhdGVBY2N0UGFyYW1zR2V0Q29udHJhY3QgZXh0ZW5kcyBhcmM0LkNvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGJ0b2kKICAgIHR4bmFzIEFjY291bnRzCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MjcKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV9hY2N0X2JhbGFuY2UKICAgIGl0b2IKICAgIGJ5dGVjXzAgLy8gMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludGNfMCAvLyAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9hY2N0X21pbl9iYWxhbmNlX3JvdXRlQDM6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MzkKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIG5vdCBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGNhbiBvbmx5IGNhbGwgd2hlbiBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czoyNgogICAgLy8gZXhwb3J0IGNsYXNzIFN0YXRlQWNjdFBhcmFtc0dldENvbnRyYWN0IGV4dGVuZHMgYXJjNC5Db250cmFjdCB7CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBidG9pCiAgICB0eG5hcyBBY2NvdW50cwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjM5CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfYWNjdF9taW5fYmFsYW5jZQogICAgaXRvYgogICAgYnl0ZWNfMCAvLyAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50Y18wIC8vIDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2FjY3RfYXV0aF9hZGRyX3JvdXRlQDQ6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NTEKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIG5vdCBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGNhbiBvbmx5IGNhbGwgd2hlbiBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czoyNgogICAgLy8gZXhwb3J0IGNsYXNzIFN0YXRlQWNjdFBhcmFtc0dldENvbnRyYWN0IGV4dGVuZHMgYXJjNC5Db250cmFjdCB7CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBidG9pCiAgICB0eG5hcyBBY2NvdW50cwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjUxCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfYWNjdF9hdXRoX2FkZHIKICAgIGJ5dGVjXzAgLy8gMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludGNfMCAvLyAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9hY2N0X3RvdGFsX251bV91aW50X3JvdXRlQDU6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NjAKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIG5vdCBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGNhbiBvbmx5IGNhbGwgd2hlbiBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czoyNgogICAgLy8gZXhwb3J0IGNsYXNzIFN0YXRlQWNjdFBhcmFtc0dldENvbnRyYWN0IGV4dGVuZHMgYXJjNC5Db250cmFjdCB7CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBidG9pCiAgICB0eG5hcyBBY2NvdW50cwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjYwCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfYWNjdF90b3RhbF9udW1fdWludAogICAgaXRvYgogICAgYnl0ZWNfMCAvLyAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50Y18wIC8vIDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2FjY3RfdG90YWxfbnVtX2J5dGVfc2xpY2Vfcm91dGVANjoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo2OQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgbm90IE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gY2FuIG9ubHkgY2FsbCB3aGVuIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjI2CiAgICAvLyBleHBvcnQgY2xhc3MgU3RhdGVBY2N0UGFyYW1zR2V0Q29udHJhY3QgZXh0ZW5kcyBhcmM0LkNvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGJ0b2kKICAgIHR4bmFzIEFjY291bnRzCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NjkKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV9hY2N0X3RvdGFsX251bV9ieXRlX3NsaWNlCiAgICBpdG9iCiAgICBieXRlY18wIC8vIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnRjXzAgLy8gMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfYWNjdF90b3RhbF9leHRyYV9hcHBfcGFnZXNfcm91dGVANzoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo3OAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgbm90IE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gY2FuIG9ubHkgY2FsbCB3aGVuIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjI2CiAgICAvLyBleHBvcnQgY2xhc3MgU3RhdGVBY2N0UGFyYW1zR2V0Q29udHJhY3QgZXh0ZW5kcyBhcmM0LkNvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGJ0b2kKICAgIHR4bmFzIEFjY291bnRzCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NzgKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV9hY2N0X3RvdGFsX2V4dHJhX2FwcF9wYWdlcwogICAgaXRvYgogICAgYnl0ZWNfMCAvLyAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50Y18wIC8vIDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2FjY3RfdG90YWxfYXBwc19jcmVhdGVkX3JvdXRlQDg6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6ODcKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIG5vdCBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGNhbiBvbmx5IGNhbGwgd2hlbiBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czoyNgogICAgLy8gZXhwb3J0IGNsYXNzIFN0YXRlQWNjdFBhcmFtc0dldENvbnRyYWN0IGV4dGVuZHMgYXJjNC5Db250cmFjdCB7CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBidG9pCiAgICB0eG5hcyBBY2NvdW50cwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjg3CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfYWNjdF90b3RhbF9hcHBzX2NyZWF0ZWQKICAgIGl0b2IKICAgIGJ5dGVjXzAgLy8gMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludGNfMCAvLyAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9hY2N0X3RvdGFsX2FwcHNfb3B0ZWRfaW5fcm91dGVAOToKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo5NgogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgbm90IE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gY2FuIG9ubHkgY2FsbCB3aGVuIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjI2CiAgICAvLyBleHBvcnQgY2xhc3MgU3RhdGVBY2N0UGFyYW1zR2V0Q29udHJhY3QgZXh0ZW5kcyBhcmM0LkNvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGJ0b2kKICAgIHR4bmFzIEFjY291bnRzCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OTYKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV9hY2N0X3RvdGFsX2FwcHNfb3B0ZWRfaW4KICAgIGl0b2IKICAgIGJ5dGVjXzAgLy8gMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludGNfMCAvLyAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9hY2N0X3RvdGFsX2Fzc2V0c19jcmVhdGVkX3JvdXRlQDEwOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjEwNQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgbm90IE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gY2FuIG9ubHkgY2FsbCB3aGVuIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjI2CiAgICAvLyBleHBvcnQgY2xhc3MgU3RhdGVBY2N0UGFyYW1zR2V0Q29udHJhY3QgZXh0ZW5kcyBhcmM0LkNvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGJ0b2kKICAgIHR4bmFzIEFjY291bnRzCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTA1CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfYWNjdF90b3RhbF9hc3NldHNfY3JlYXRlZAogICAgaXRvYgogICAgYnl0ZWNfMCAvLyAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50Y18wIC8vIDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2FjY3RfdG90YWxfYXNzZXRzX3JvdXRlQDExOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjExNAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgbm90IE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gY2FuIG9ubHkgY2FsbCB3aGVuIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjI2CiAgICAvLyBleHBvcnQgY2xhc3MgU3RhdGVBY2N0UGFyYW1zR2V0Q29udHJhY3QgZXh0ZW5kcyBhcmM0LkNvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGJ0b2kKICAgIHR4bmFzIEFjY291bnRzCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTE0CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfYWNjdF90b3RhbF9hc3NldHMKICAgIGl0b2IKICAgIGJ5dGVjXzAgLy8gMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludGNfMCAvLyAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9hY2N0X3RvdGFsX2JveGVzX3JvdXRlQDEyOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjEyMwogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgbm90IE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gY2FuIG9ubHkgY2FsbCB3aGVuIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjI2CiAgICAvLyBleHBvcnQgY2xhc3MgU3RhdGVBY2N0UGFyYW1zR2V0Q29udHJhY3QgZXh0ZW5kcyBhcmM0LkNvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGJ0b2kKICAgIHR4bmFzIEFjY291bnRzCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTIzCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfYWNjdF90b3RhbF9ib3hlcwogICAgaXRvYgogICAgYnl0ZWNfMCAvLyAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50Y18wIC8vIDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2FjY3RfdG90YWxfYm94X2J5dGVzX3JvdXRlQDEzOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjEzMgogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgbm90IE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gY2FuIG9ubHkgY2FsbCB3aGVuIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjI2CiAgICAvLyBleHBvcnQgY2xhc3MgU3RhdGVBY2N0UGFyYW1zR2V0Q29udHJhY3QgZXh0ZW5kcyBhcmM0LkNvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGJ0b2kKICAgIHR4bmFzIEFjY291bnRzCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTMyCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfYWNjdF90b3RhbF9ib3hfYnl0ZXMKICAgIGl0b2IKICAgIGJ5dGVjXzAgLy8gMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludGNfMCAvLyAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX2JhcmVfcm91dGluZ0AxNjoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czoyNgogICAgLy8gZXhwb3J0IGNsYXNzIFN0YXRlQWNjdFBhcmFtc0dldENvbnRyYWN0IGV4dGVuZHMgYXJjNC5Db250cmFjdCB7CiAgICB0eG4gT25Db21wbGV0aW9uCiAgICBibnogX19wdXlhX2FyYzRfcm91dGVyX19fYWZ0ZXJfaWZfZWxzZUAyMAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgICEKICAgIGFzc2VydCAvLyBjYW4gb25seSBjYWxsIHdoZW4gY3JlYXRpbmcKICAgIGludGNfMCAvLyAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX2FmdGVyX2lmX2Vsc2VAMjA6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MjYKICAgIC8vIGV4cG9ydCBjbGFzcyBTdGF0ZUFjY3RQYXJhbXNHZXRDb250cmFjdCBleHRlbmRzIGFyYzQuQ29udHJhY3QgewogICAgaW50Y18xIC8vIDAKICAgIHJldHN1YgoKCi8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo6U3RhdGVBY2N0UGFyYW1zR2V0Q29udHJhY3QudmVyaWZ5X2FjY3RfYmFsYW5jZShhOiBieXRlcykgLT4gdWludDY0Ogp2ZXJpZnlfYWNjdF9iYWxhbmNlOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjI3LTI4CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gcHVibGljIHZlcmlmeV9hY2N0X2JhbGFuY2UoYTogQWNjb3VudCk6IHVpbnQ2NCB7CiAgICBwcm90byAxIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czoyOQogICAgLy8gY29uc3QgW3ZhbHVlLCBmdW5kZWRdID0gb3AuQWNjdFBhcmFtcy5hY2N0QmFsYW5jZShhKQogICAgZnJhbWVfZGlnIC0xCiAgICBhY2N0X3BhcmFtc19nZXQgQWNjdEJhbGFuY2UKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czozMAogICAgLy8gY29uc3QgW3ZhbHVlX2luZGV4LCBmdW5kZWRfaW5kZXhdID0gb3AuQWNjdFBhcmFtcy5hY2N0QmFsYW5jZShnZXRfMXN0X3JlZl9pbmRleCgpKQogICAgY2FsbHN1YiBnZXRfMXN0X3JlZl9pbmRleAogICAgYWNjdF9wYXJhbXNfZ2V0IEFjY3RCYWxhbmNlCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MzEKICAgIC8vIGFzc2VydCh2YWx1ZSA9PT0gdmFsdWVfaW5kZXgsICdleHBlY3RlZCB2YWx1ZSBieSBpbmRleCB0byBtYXRjaCcpCiAgICBkaWcgMwogICAgdW5jb3ZlciAyCiAgICA9PQogICAgYXNzZXJ0IC8vIGV4cGVjdGVkIHZhbHVlIGJ5IGluZGV4IHRvIG1hdGNoCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MzIKICAgIC8vIGFzc2VydChmdW5kZWQgPT09IGZ1bmRlZF9pbmRleCwgJ2V4cGVjdGVkIGZ1bmRlZCBieSBpbmRleCB0byBtYXRjaCcpCiAgICA9PQogICAgYXNzZXJ0IC8vIGV4cGVjdGVkIGZ1bmRlZCBieSBpbmRleCB0byBtYXRjaAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjMzCiAgICAvLyBhc3NlcnQodmFsdWUgPT09IGEuYmFsYW5jZSwgJ2V4cGVjdGVkIEFjY291bnQgYmFsYW5jZSB0byBtYXRjaCcpCiAgICBmcmFtZV9kaWcgLTEKICAgIGFjY3RfcGFyYW1zX2dldCBBY2N0QmFsYW5jZQogICAgYXNzZXJ0IC8vIGFjY291bnQgZnVuZGVkCiAgICBkaWcgMQogICAgPT0KICAgIGFzc2VydCAvLyBleHBlY3RlZCBBY2NvdW50IGJhbGFuY2UgdG8gbWF0Y2gKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czozNAogICAgLy8gYXNzZXJ0KHZhbHVlID09PSBvcC5iYWxhbmNlKGEpLCAnZXhwZWN0ZWQgb3AuYmFsYW5jZSB0byBtYXRjaCcpCiAgICBmcmFtZV9kaWcgLTEKICAgIGJhbGFuY2UKICAgIGRpZyAxCiAgICA9PQogICAgYXNzZXJ0IC8vIGV4cGVjdGVkIG9wLmJhbGFuY2UgdG8gbWF0Y2gKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czozNQogICAgLy8gYXNzZXJ0KHZhbHVlID09PSBvcC5iYWxhbmNlKGdldF8xc3RfcmVmX2luZGV4KCkpLCAnZXhwZWN0ZWQgb3AuYmFsYW5jZSBieSBpbmRleCB0byBtYXRjaCcpCiAgICBjYWxsc3ViIGdldF8xc3RfcmVmX2luZGV4CiAgICBiYWxhbmNlCiAgICBkaWcgMQogICAgPT0KICAgIGFzc2VydCAvLyBleHBlY3RlZCBvcC5iYWxhbmNlIGJ5IGluZGV4IHRvIG1hdGNoCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MzYKICAgIC8vIHJldHVybiB2YWx1ZQogICAgcmV0c3ViCgoKLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjpnZXRfMXN0X3JlZl9pbmRleCgpIC0+IHVpbnQ2NDoKZ2V0XzFzdF9yZWZfaW5kZXg6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MjIKICAgIC8vIGZ1bmN0aW9uIGdldF8xc3RfcmVmX2luZGV4KCk6IHVpbnQ2NCB7CiAgICBwcm90byAwIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czoyMwogICAgLy8gcmV0dXJuIG9wLmJ0b2koVHhuLmFwcGxpY2F0aW9uQXJncygxKSkKICAgIGludGNfMCAvLyAxCiAgICB0eG5hcyBBcHBsaWNhdGlvbkFyZ3MKICAgIGJ0b2kKICAgIHJldHN1YgoKCi8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo6U3RhdGVBY2N0UGFyYW1zR2V0Q29udHJhY3QudmVyaWZ5X2FjY3RfbWluX2JhbGFuY2UoYTogYnl0ZXMpIC0+IHVpbnQ2NDoKdmVyaWZ5X2FjY3RfbWluX2JhbGFuY2U6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MzktNDAKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBwdWJsaWMgdmVyaWZ5X2FjY3RfbWluX2JhbGFuY2UoYTogQWNjb3VudCk6IHVpbnQ2NCB7CiAgICBwcm90byAxIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo0MQogICAgLy8gY29uc3QgW3ZhbHVlLCBmdW5kZWRdID0gb3AuQWNjdFBhcmFtcy5hY2N0TWluQmFsYW5jZShhKQogICAgZnJhbWVfZGlnIC0xCiAgICBhY2N0X3BhcmFtc19nZXQgQWNjdE1pbkJhbGFuY2UKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo0MgogICAgLy8gY29uc3QgW3ZhbHVlX2luZGV4LCBmdW5kZWRfaW5kZXhdID0gb3AuQWNjdFBhcmFtcy5hY2N0TWluQmFsYW5jZShnZXRfMXN0X3JlZl9pbmRleCgpKQogICAgY2FsbHN1YiBnZXRfMXN0X3JlZl9pbmRleAogICAgYWNjdF9wYXJhbXNfZ2V0IEFjY3RNaW5CYWxhbmNlCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NDMKICAgIC8vIGFzc2VydCh2YWx1ZSA9PT0gdmFsdWVfaW5kZXgsICdleHBlY3RlZCB2YWx1ZSBieSBpbmRleCB0byBtYXRjaCcpCiAgICBkaWcgMwogICAgdW5jb3ZlciAyCiAgICA9PQogICAgYXNzZXJ0IC8vIGV4cGVjdGVkIHZhbHVlIGJ5IGluZGV4IHRvIG1hdGNoCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NDQKICAgIC8vIGFzc2VydChmdW5kZWQgPT09IGZ1bmRlZF9pbmRleCwgJ2V4cGVjdGVkIGZ1bmRlZCBieSBpbmRleCB0byBtYXRjaCcpCiAgICA9PQogICAgYXNzZXJ0IC8vIGV4cGVjdGVkIGZ1bmRlZCBieSBpbmRleCB0byBtYXRjaAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjQ1CiAgICAvLyBhc3NlcnQodmFsdWUgPT09IGEubWluQmFsYW5jZSwgJ2V4cGVjdGVkIEFjY291bnQgbWluX2JhbGFuY2UgdG8gbWF0Y2gnKQogICAgZnJhbWVfZGlnIC0xCiAgICBhY2N0X3BhcmFtc19nZXQgQWNjdE1pbkJhbGFuY2UKICAgIGFzc2VydCAvLyBhY2NvdW50IGZ1bmRlZAogICAgZGlnIDEKICAgID09CiAgICBhc3NlcnQgLy8gZXhwZWN0ZWQgQWNjb3VudCBtaW5fYmFsYW5jZSB0byBtYXRjaAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjQ2CiAgICAvLyBhc3NlcnQodmFsdWUgPT09IG9wLm1pbkJhbGFuY2UoYSksICdleHBlY3RlZCBvcC5taW5fYmFsYW5jZSB0byBtYXRjaCcpCiAgICBmcmFtZV9kaWcgLTEKICAgIG1pbl9iYWxhbmNlCiAgICBkaWcgMQogICAgPT0KICAgIGFzc2VydCAvLyBleHBlY3RlZCBvcC5taW5fYmFsYW5jZSB0byBtYXRjaAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjQ3CiAgICAvLyBhc3NlcnQodmFsdWUgPT09IG9wLm1pbkJhbGFuY2UoZ2V0XzFzdF9yZWZfaW5kZXgoKSksICdleHBlY3RlZCBvcC5taW5fYmFsYW5jZSBieSBpbmRleCB0byBtYXRjaCcpCiAgICBjYWxsc3ViIGdldF8xc3RfcmVmX2luZGV4CiAgICBtaW5fYmFsYW5jZQogICAgZGlnIDEKICAgID09CiAgICBhc3NlcnQgLy8gZXhwZWN0ZWQgb3AubWluX2JhbGFuY2UgYnkgaW5kZXggdG8gbWF0Y2gKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo0OAogICAgLy8gcmV0dXJuIHZhbHVlCiAgICByZXRzdWIKCgovLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OlN0YXRlQWNjdFBhcmFtc0dldENvbnRyYWN0LnZlcmlmeV9hY2N0X2F1dGhfYWRkcihhOiBieXRlcykgLT4gYnl0ZXM6CnZlcmlmeV9hY2N0X2F1dGhfYWRkcjoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo1MS01MgogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIHB1YmxpYyB2ZXJpZnlfYWNjdF9hdXRoX2FkZHIoYTogQWNjb3VudCk6IEFkZHJlc3MgewogICAgcHJvdG8gMSAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NTMKICAgIC8vIGNvbnN0IFt2YWx1ZSwgZnVuZGVkXSA9IG9wLkFjY3RQYXJhbXMuYWNjdEF1dGhBZGRyKGEpCiAgICBmcmFtZV9kaWcgLTEKICAgIGFjY3RfcGFyYW1zX2dldCBBY2N0QXV0aEFkZHIKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo1NAogICAgLy8gY29uc3QgW3ZhbHVlX2luZGV4LCBmdW5kZWRfaW5kZXhdID0gb3AuQWNjdFBhcmFtcy5hY2N0QXV0aEFkZHIoZ2V0XzFzdF9yZWZfaW5kZXgoKSkKICAgIGNhbGxzdWIgZ2V0XzFzdF9yZWZfaW5kZXgKICAgIGFjY3RfcGFyYW1zX2dldCBBY2N0QXV0aEFkZHIKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo1NQogICAgLy8gYXNzZXJ0KHZhbHVlID09PSB2YWx1ZV9pbmRleCwgJ2V4cGVjdGVkIHZhbHVlIGJ5IGluZGV4IHRvIG1hdGNoJykKICAgIGRpZyAzCiAgICB1bmNvdmVyIDIKICAgID09CiAgICBhc3NlcnQgLy8gZXhwZWN0ZWQgdmFsdWUgYnkgaW5kZXggdG8gbWF0Y2gKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo1NgogICAgLy8gYXNzZXJ0KGZ1bmRlZCA9PT0gZnVuZGVkX2luZGV4LCAnZXhwZWN0ZWQgZnVuZGVkIGJ5IGluZGV4IHRvIG1hdGNoJykKICAgID09CiAgICBhc3NlcnQgLy8gZXhwZWN0ZWQgZnVuZGVkIGJ5IGluZGV4IHRvIG1hdGNoCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NTcKICAgIC8vIHJldHVybiBuZXcgQWRkcmVzcyh2YWx1ZSkKICAgIHJldHN1YgoKCi8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo6U3RhdGVBY2N0UGFyYW1zR2V0Q29udHJhY3QudmVyaWZ5X2FjY3RfdG90YWxfbnVtX3VpbnQoYTogYnl0ZXMpIC0+IHVpbnQ2NDoKdmVyaWZ5X2FjY3RfdG90YWxfbnVtX3VpbnQ6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NjAtNjEKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBwdWJsaWMgdmVyaWZ5X2FjY3RfdG90YWxfbnVtX3VpbnQoYTogQWNjb3VudCk6IHVpbnQ2NCB7CiAgICBwcm90byAxIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo2MgogICAgLy8gY29uc3QgW3ZhbHVlLCBmdW5kZWRdID0gb3AuQWNjdFBhcmFtcy5hY2N0VG90YWxOdW1VaW50KGEpCiAgICBmcmFtZV9kaWcgLTEKICAgIGFjY3RfcGFyYW1zX2dldCBBY2N0VG90YWxOdW1VaW50CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NjMKICAgIC8vIGNvbnN0IFt2YWx1ZV9pbmRleCwgZnVuZGVkX2luZGV4XSA9IG9wLkFjY3RQYXJhbXMuYWNjdFRvdGFsTnVtVWludChnZXRfMXN0X3JlZl9pbmRleCgpKQogICAgY2FsbHN1YiBnZXRfMXN0X3JlZl9pbmRleAogICAgYWNjdF9wYXJhbXNfZ2V0IEFjY3RUb3RhbE51bVVpbnQKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo2NAogICAgLy8gYXNzZXJ0KHZhbHVlID09PSB2YWx1ZV9pbmRleCwgJ2V4cGVjdGVkIHZhbHVlIGJ5IGluZGV4IHRvIG1hdGNoJykKICAgIGRpZyAzCiAgICB1bmNvdmVyIDIKICAgID09CiAgICBhc3NlcnQgLy8gZXhwZWN0ZWQgdmFsdWUgYnkgaW5kZXggdG8gbWF0Y2gKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo2NQogICAgLy8gYXNzZXJ0KGZ1bmRlZCA9PT0gZnVuZGVkX2luZGV4LCAnZXhwZWN0ZWQgZnVuZGVkIGJ5IGluZGV4IHRvIG1hdGNoJykKICAgID09CiAgICBhc3NlcnQgLy8gZXhwZWN0ZWQgZnVuZGVkIGJ5IGluZGV4IHRvIG1hdGNoCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NjYKICAgIC8vIHJldHVybiB2YWx1ZQogICAgcmV0c3ViCgoKLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjpTdGF0ZUFjY3RQYXJhbXNHZXRDb250cmFjdC52ZXJpZnlfYWNjdF90b3RhbF9udW1fYnl0ZV9zbGljZShhOiBieXRlcykgLT4gdWludDY0Ogp2ZXJpZnlfYWNjdF90b3RhbF9udW1fYnl0ZV9zbGljZToKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo2OS03MAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIHB1YmxpYyB2ZXJpZnlfYWNjdF90b3RhbF9udW1fYnl0ZV9zbGljZShhOiBBY2NvdW50KTogdWludDY0IHsKICAgIHByb3RvIDEgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjcxCiAgICAvLyBjb25zdCBbdmFsdWUsIGZ1bmRlZF0gPSBvcC5BY2N0UGFyYW1zLmFjY3RUb3RhbE51bUJ5dGVTbGljZShhKQogICAgZnJhbWVfZGlnIC0xCiAgICBhY2N0X3BhcmFtc19nZXQgQWNjdFRvdGFsTnVtQnl0ZVNsaWNlCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NzIKICAgIC8vIGNvbnN0IFt2YWx1ZV9pbmRleCwgZnVuZGVkX2luZGV4XSA9IG9wLkFjY3RQYXJhbXMuYWNjdFRvdGFsTnVtQnl0ZVNsaWNlKGdldF8xc3RfcmVmX2luZGV4KCkpCiAgICBjYWxsc3ViIGdldF8xc3RfcmVmX2luZGV4CiAgICBhY2N0X3BhcmFtc19nZXQgQWNjdFRvdGFsTnVtQnl0ZVNsaWNlCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NzMKICAgIC8vIGFzc2VydCh2YWx1ZSA9PT0gdmFsdWVfaW5kZXgsICdleHBlY3RlZCB2YWx1ZSBieSBpbmRleCB0byBtYXRjaCcpCiAgICBkaWcgMwogICAgdW5jb3ZlciAyCiAgICA9PQogICAgYXNzZXJ0IC8vIGV4cGVjdGVkIHZhbHVlIGJ5IGluZGV4IHRvIG1hdGNoCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NzQKICAgIC8vIGFzc2VydChmdW5kZWQgPT09IGZ1bmRlZF9pbmRleCwgJ2V4cGVjdGVkIGZ1bmRlZCBieSBpbmRleCB0byBtYXRjaCcpCiAgICA9PQogICAgYXNzZXJ0IC8vIGV4cGVjdGVkIGZ1bmRlZCBieSBpbmRleCB0byBtYXRjaAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjc1CiAgICAvLyByZXR1cm4gdmFsdWUKICAgIHJldHN1YgoKCi8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo6U3RhdGVBY2N0UGFyYW1zR2V0Q29udHJhY3QudmVyaWZ5X2FjY3RfdG90YWxfZXh0cmFfYXBwX3BhZ2VzKGE6IGJ5dGVzKSAtPiB1aW50NjQ6CnZlcmlmeV9hY2N0X3RvdGFsX2V4dHJhX2FwcF9wYWdlczoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo3OC03OQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIHB1YmxpYyB2ZXJpZnlfYWNjdF90b3RhbF9leHRyYV9hcHBfcGFnZXMoYTogQWNjb3VudCk6IHVpbnQ2NCB7CiAgICBwcm90byAxIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo4MAogICAgLy8gY29uc3QgW3ZhbHVlLCBmdW5kZWRdID0gb3AuQWNjdFBhcmFtcy5hY2N0VG90YWxFeHRyYUFwcFBhZ2VzKGEpCiAgICBmcmFtZV9kaWcgLTEKICAgIGFjY3RfcGFyYW1zX2dldCBBY2N0VG90YWxFeHRyYUFwcFBhZ2VzCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6ODEKICAgIC8vIGNvbnN0IFt2YWx1ZV9pbmRleCwgZnVuZGVkX2luZGV4XSA9IG9wLkFjY3RQYXJhbXMuYWNjdFRvdGFsRXh0cmFBcHBQYWdlcyhnZXRfMXN0X3JlZl9pbmRleCgpKQogICAgY2FsbHN1YiBnZXRfMXN0X3JlZl9pbmRleAogICAgYWNjdF9wYXJhbXNfZ2V0IEFjY3RUb3RhbEV4dHJhQXBwUGFnZXMKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo4MgogICAgLy8gYXNzZXJ0KHZhbHVlID09PSB2YWx1ZV9pbmRleCwgJ2V4cGVjdGVkIHZhbHVlIGJ5IGluZGV4IHRvIG1hdGNoJykKICAgIGRpZyAzCiAgICB1bmNvdmVyIDIKICAgID09CiAgICBhc3NlcnQgLy8gZXhwZWN0ZWQgdmFsdWUgYnkgaW5kZXggdG8gbWF0Y2gKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo4MwogICAgLy8gYXNzZXJ0KGZ1bmRlZCA9PT0gZnVuZGVkX2luZGV4LCAnZXhwZWN0ZWQgZnVuZGVkIGJ5IGluZGV4IHRvIG1hdGNoJykKICAgID09CiAgICBhc3NlcnQgLy8gZXhwZWN0ZWQgZnVuZGVkIGJ5IGluZGV4IHRvIG1hdGNoCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6ODQKICAgIC8vIHJldHVybiB2YWx1ZQogICAgcmV0c3ViCgoKLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjpTdGF0ZUFjY3RQYXJhbXNHZXRDb250cmFjdC52ZXJpZnlfYWNjdF90b3RhbF9hcHBzX2NyZWF0ZWQoYTogYnl0ZXMpIC0+IHVpbnQ2NDoKdmVyaWZ5X2FjY3RfdG90YWxfYXBwc19jcmVhdGVkOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjg3LTg4CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gcHVibGljIHZlcmlmeV9hY2N0X3RvdGFsX2FwcHNfY3JlYXRlZChhOiBBY2NvdW50KTogdWludDY0IHsKICAgIHByb3RvIDEgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjg5CiAgICAvLyBjb25zdCBbdmFsdWUsIGZ1bmRlZF0gPSBvcC5BY2N0UGFyYW1zLmFjY3RUb3RhbEFwcHNDcmVhdGVkKGEpCiAgICBmcmFtZV9kaWcgLTEKICAgIGFjY3RfcGFyYW1zX2dldCBBY2N0VG90YWxBcHBzQ3JlYXRlZAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjkwCiAgICAvLyBjb25zdCBbdmFsdWVfaW5kZXgsIGZ1bmRlZF9pbmRleF0gPSBvcC5BY2N0UGFyYW1zLmFjY3RUb3RhbEFwcHNDcmVhdGVkKGdldF8xc3RfcmVmX2luZGV4KCkpCiAgICBjYWxsc3ViIGdldF8xc3RfcmVmX2luZGV4CiAgICBhY2N0X3BhcmFtc19nZXQgQWNjdFRvdGFsQXBwc0NyZWF0ZWQKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo5MQogICAgLy8gYXNzZXJ0KHZhbHVlID09PSB2YWx1ZV9pbmRleCwgJ2V4cGVjdGVkIHZhbHVlIGJ5IGluZGV4IHRvIG1hdGNoJykKICAgIGRpZyAzCiAgICB1bmNvdmVyIDIKICAgID09CiAgICBhc3NlcnQgLy8gZXhwZWN0ZWQgdmFsdWUgYnkgaW5kZXggdG8gbWF0Y2gKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo5MgogICAgLy8gYXNzZXJ0KGZ1bmRlZCA9PT0gZnVuZGVkX2luZGV4LCAnZXhwZWN0ZWQgZnVuZGVkIGJ5IGluZGV4IHRvIG1hdGNoJykKICAgID09CiAgICBhc3NlcnQgLy8gZXhwZWN0ZWQgZnVuZGVkIGJ5IGluZGV4IHRvIG1hdGNoCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OTMKICAgIC8vIHJldHVybiB2YWx1ZQogICAgcmV0c3ViCgoKLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjpTdGF0ZUFjY3RQYXJhbXNHZXRDb250cmFjdC52ZXJpZnlfYWNjdF90b3RhbF9hcHBzX29wdGVkX2luKGE6IGJ5dGVzKSAtPiB1aW50NjQ6CnZlcmlmeV9hY2N0X3RvdGFsX2FwcHNfb3B0ZWRfaW46CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OTYtOTcKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBwdWJsaWMgdmVyaWZ5X2FjY3RfdG90YWxfYXBwc19vcHRlZF9pbihhOiBBY2NvdW50KTogdWludDY0IHsKICAgIHByb3RvIDEgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjk4CiAgICAvLyBjb25zdCBbdmFsdWUsIGZ1bmRlZF0gPSBvcC5BY2N0UGFyYW1zLmFjY3RUb3RhbEFwcHNPcHRlZEluKGEpCiAgICBmcmFtZV9kaWcgLTEKICAgIGFjY3RfcGFyYW1zX2dldCBBY2N0VG90YWxBcHBzT3B0ZWRJbgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjk5CiAgICAvLyBjb25zdCBbdmFsdWVfaW5kZXgsIGZ1bmRlZF9pbmRleF0gPSBvcC5BY2N0UGFyYW1zLmFjY3RUb3RhbEFwcHNPcHRlZEluKGdldF8xc3RfcmVmX2luZGV4KCkpCiAgICBjYWxsc3ViIGdldF8xc3RfcmVmX2luZGV4CiAgICBhY2N0X3BhcmFtc19nZXQgQWNjdFRvdGFsQXBwc09wdGVkSW4KICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czoxMDAKICAgIC8vIGFzc2VydCh2YWx1ZSA9PT0gdmFsdWVfaW5kZXgsICdleHBlY3RlZCB2YWx1ZSBieSBpbmRleCB0byBtYXRjaCcpCiAgICBkaWcgMwogICAgdW5jb3ZlciAyCiAgICA9PQogICAgYXNzZXJ0IC8vIGV4cGVjdGVkIHZhbHVlIGJ5IGluZGV4IHRvIG1hdGNoCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTAxCiAgICAvLyBhc3NlcnQoZnVuZGVkID09PSBmdW5kZWRfaW5kZXgsICdleHBlY3RlZCBmdW5kZWQgYnkgaW5kZXggdG8gbWF0Y2gnKQogICAgPT0KICAgIGFzc2VydCAvLyBleHBlY3RlZCBmdW5kZWQgYnkgaW5kZXggdG8gbWF0Y2gKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czoxMDIKICAgIC8vIHJldHVybiB2YWx1ZQogICAgcmV0c3ViCgoKLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjpTdGF0ZUFjY3RQYXJhbXNHZXRDb250cmFjdC52ZXJpZnlfYWNjdF90b3RhbF9hc3NldHNfY3JlYXRlZChhOiBieXRlcykgLT4gdWludDY0Ogp2ZXJpZnlfYWNjdF90b3RhbF9hc3NldHNfY3JlYXRlZDoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czoxMDUtMTA2CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gcHVibGljIHZlcmlmeV9hY2N0X3RvdGFsX2Fzc2V0c19jcmVhdGVkKGE6IEFjY291bnQpOiB1aW50NjQgewogICAgcHJvdG8gMSAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTA3CiAgICAvLyBjb25zdCBbdmFsdWUsIGZ1bmRlZF0gPSBvcC5BY2N0UGFyYW1zLmFjY3RUb3RhbEFzc2V0c0NyZWF0ZWQoYSkKICAgIGZyYW1lX2RpZyAtMQogICAgYWNjdF9wYXJhbXNfZ2V0IEFjY3RUb3RhbEFzc2V0c0NyZWF0ZWQKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czoxMDgKICAgIC8vIGNvbnN0IFt2YWx1ZV9pbmRleCwgZnVuZGVkX2luZGV4XSA9IG9wLkFjY3RQYXJhbXMuYWNjdFRvdGFsQXNzZXRzQ3JlYXRlZChnZXRfMXN0X3JlZl9pbmRleCgpKQogICAgY2FsbHN1YiBnZXRfMXN0X3JlZl9pbmRleAogICAgYWNjdF9wYXJhbXNfZ2V0IEFjY3RUb3RhbEFzc2V0c0NyZWF0ZWQKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czoxMDkKICAgIC8vIGFzc2VydCh2YWx1ZSA9PT0gdmFsdWVfaW5kZXgsICdleHBlY3RlZCB2YWx1ZSBieSBpbmRleCB0byBtYXRjaCcpCiAgICBkaWcgMwogICAgdW5jb3ZlciAyCiAgICA9PQogICAgYXNzZXJ0IC8vIGV4cGVjdGVkIHZhbHVlIGJ5IGluZGV4IHRvIG1hdGNoCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTEwCiAgICAvLyBhc3NlcnQoZnVuZGVkID09PSBmdW5kZWRfaW5kZXgsICdleHBlY3RlZCBmdW5kZWQgYnkgaW5kZXggdG8gbWF0Y2gnKQogICAgPT0KICAgIGFzc2VydCAvLyBleHBlY3RlZCBmdW5kZWQgYnkgaW5kZXggdG8gbWF0Y2gKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czoxMTEKICAgIC8vIHJldHVybiB2YWx1ZQogICAgcmV0c3ViCgoKLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjpTdGF0ZUFjY3RQYXJhbXNHZXRDb250cmFjdC52ZXJpZnlfYWNjdF90b3RhbF9hc3NldHMoYTogYnl0ZXMpIC0+IHVpbnQ2NDoKdmVyaWZ5X2FjY3RfdG90YWxfYXNzZXRzOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjExNC0xMTUKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBwdWJsaWMgdmVyaWZ5X2FjY3RfdG90YWxfYXNzZXRzKGE6IEFjY291bnQpOiB1aW50NjQgewogICAgcHJvdG8gMSAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTE2CiAgICAvLyBjb25zdCBbdmFsdWUsIGZ1bmRlZF0gPSBvcC5BY2N0UGFyYW1zLmFjY3RUb3RhbEFzc2V0cyhhKQogICAgZnJhbWVfZGlnIC0xCiAgICBhY2N0X3BhcmFtc19nZXQgQWNjdFRvdGFsQXNzZXRzCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTE3CiAgICAvLyBjb25zdCBbdmFsdWVfaW5kZXgsIGZ1bmRlZF9pbmRleF0gPSBvcC5BY2N0UGFyYW1zLmFjY3RUb3RhbEFzc2V0cyhnZXRfMXN0X3JlZl9pbmRleCgpKQogICAgY2FsbHN1YiBnZXRfMXN0X3JlZl9pbmRleAogICAgYWNjdF9wYXJhbXNfZ2V0IEFjY3RUb3RhbEFzc2V0cwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjExOAogICAgLy8gYXNzZXJ0KHZhbHVlID09PSB2YWx1ZV9pbmRleCwgJ2V4cGVjdGVkIHZhbHVlIGJ5IGluZGV4IHRvIG1hdGNoJykKICAgIGRpZyAzCiAgICB1bmNvdmVyIDIKICAgID09CiAgICBhc3NlcnQgLy8gZXhwZWN0ZWQgdmFsdWUgYnkgaW5kZXggdG8gbWF0Y2gKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czoxMTkKICAgIC8vIGFzc2VydChmdW5kZWQgPT09IGZ1bmRlZF9pbmRleCwgJ2V4cGVjdGVkIGZ1bmRlZCBieSBpbmRleCB0byBtYXRjaCcpCiAgICA9PQogICAgYXNzZXJ0IC8vIGV4cGVjdGVkIGZ1bmRlZCBieSBpbmRleCB0byBtYXRjaAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjEyMAogICAgLy8gcmV0dXJuIHZhbHVlCiAgICByZXRzdWIKCgovLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OlN0YXRlQWNjdFBhcmFtc0dldENvbnRyYWN0LnZlcmlmeV9hY2N0X3RvdGFsX2JveGVzKGE6IGJ5dGVzKSAtPiB1aW50NjQ6CnZlcmlmeV9hY2N0X3RvdGFsX2JveGVzOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjEyMy0xMjQKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBwdWJsaWMgdmVyaWZ5X2FjY3RfdG90YWxfYm94ZXMoYTogQWNjb3VudCk6IHVpbnQ2NCB7CiAgICBwcm90byAxIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czoxMjUKICAgIC8vIGNvbnN0IFt2YWx1ZSwgZnVuZGVkXSA9IG9wLkFjY3RQYXJhbXMuYWNjdFRvdGFsQm94ZXMoYSkKICAgIGZyYW1lX2RpZyAtMQogICAgYWNjdF9wYXJhbXNfZ2V0IEFjY3RUb3RhbEJveGVzCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTI2CiAgICAvLyBjb25zdCBbdmFsdWVfaW5kZXgsIGZ1bmRlZF9pbmRleF0gPSBvcC5BY2N0UGFyYW1zLmFjY3RUb3RhbEJveGVzKGdldF8xc3RfcmVmX2luZGV4KCkpCiAgICBjYWxsc3ViIGdldF8xc3RfcmVmX2luZGV4CiAgICBhY2N0X3BhcmFtc19nZXQgQWNjdFRvdGFsQm94ZXMKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czoxMjcKICAgIC8vIGFzc2VydCh2YWx1ZSA9PT0gdmFsdWVfaW5kZXgsICdleHBlY3RlZCB2YWx1ZSBieSBpbmRleCB0byBtYXRjaCcpCiAgICBkaWcgMwogICAgdW5jb3ZlciAyCiAgICA9PQogICAgYXNzZXJ0IC8vIGV4cGVjdGVkIHZhbHVlIGJ5IGluZGV4IHRvIG1hdGNoCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTI4CiAgICAvLyBhc3NlcnQoZnVuZGVkID09PSBmdW5kZWRfaW5kZXgsICdleHBlY3RlZCBmdW5kZWQgYnkgaW5kZXggdG8gbWF0Y2gnKQogICAgPT0KICAgIGFzc2VydCAvLyBleHBlY3RlZCBmdW5kZWQgYnkgaW5kZXggdG8gbWF0Y2gKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czoxMjkKICAgIC8vIHJldHVybiB2YWx1ZQogICAgcmV0c3ViCgoKLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjpTdGF0ZUFjY3RQYXJhbXNHZXRDb250cmFjdC52ZXJpZnlfYWNjdF90b3RhbF9ib3hfYnl0ZXMoYTogYnl0ZXMpIC0+IHVpbnQ2NDoKdmVyaWZ5X2FjY3RfdG90YWxfYm94X2J5dGVzOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjEzMi0xMzMKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBwdWJsaWMgdmVyaWZ5X2FjY3RfdG90YWxfYm94X2J5dGVzKGE6IEFjY291bnQpOiB1aW50NjQgewogICAgcHJvdG8gMSAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTM0CiAgICAvLyBjb25zdCBbdmFsdWUsIGZ1bmRlZF0gPSBvcC5BY2N0UGFyYW1zLmFjY3RUb3RhbEJveEJ5dGVzKGEpCiAgICBmcmFtZV9kaWcgLTEKICAgIGFjY3RfcGFyYW1zX2dldCBBY2N0VG90YWxCb3hCeXRlcwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjEzNQogICAgLy8gY29uc3QgW3ZhbHVlX2luZGV4LCBmdW5kZWRfaW5kZXhdID0gb3AuQWNjdFBhcmFtcy5hY2N0VG90YWxCb3hCeXRlcyhnZXRfMXN0X3JlZl9pbmRleCgpKQogICAgY2FsbHN1YiBnZXRfMXN0X3JlZl9pbmRleAogICAgYWNjdF9wYXJhbXNfZ2V0IEFjY3RUb3RhbEJveEJ5dGVzCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTM2CiAgICAvLyBhc3NlcnQodmFsdWUgPT09IHZhbHVlX2luZGV4LCAnZXhwZWN0ZWQgdmFsdWUgYnkgaW5kZXggdG8gbWF0Y2gnKQogICAgZGlnIDMKICAgIHVuY292ZXIgMgogICAgPT0KICAgIGFzc2VydCAvLyBleHBlY3RlZCB2YWx1ZSBieSBpbmRleCB0byBtYXRjaAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjEzNwogICAgLy8gYXNzZXJ0KGZ1bmRlZCA9PT0gZnVuZGVkX2luZGV4LCAnZXhwZWN0ZWQgZnVuZGVkIGJ5IGluZGV4IHRvIG1hdGNoJykKICAgID09CiAgICBhc3NlcnQgLy8gZXhwZWN0ZWQgZnVuZGVkIGJ5IGluZGV4IHRvIG1hdGNoCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTM4CiAgICAvLyByZXR1cm4gdmFsdWUKICAgIHJldHN1Ygo=", - "clear": "I3ByYWdtYSB2ZXJzaW9uIDEwCgp0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OlN0YXRlQWNjdFBhcmFtc0dldENvbnRyYWN0LmNsZWFyU3RhdGVQcm9ncmFtOgogICAgcHVzaGludCAxIC8vIDEKICAgIHJldHVybgo=" - }, - "events": [], - "templateVariables": {} -} \ No newline at end of file diff --git a/tests/artifacts/state-ops/data/StateAcctParamsGetContract.clear.teal b/tests/artifacts/state-ops/data/StateAcctParamsGetContract.clear.teal deleted file mode 100644 index c48a376..0000000 --- a/tests/artifacts/state-ops/data/StateAcctParamsGetContract.clear.teal +++ /dev/null @@ -1,5 +0,0 @@ -#pragma version 10 - -tests/artifacts/state-ops/contract.algo.ts::StateAcctParamsGetContract.clearStateProgram: - pushint 1 // 1 - return diff --git a/tests/artifacts/state-ops/data/StateAppGlobalContract.approval.teal b/tests/artifacts/state-ops/data/StateAppGlobalContract.approval.teal deleted file mode 100644 index b48af98..0000000 --- a/tests/artifacts/state-ops/data/StateAppGlobalContract.approval.teal +++ /dev/null @@ -1,318 +0,0 @@ -#pragma version 10 - -tests/artifacts/state-ops/contract.algo.ts::StateAppGlobalContract.approvalProgram: - intcblock 1 0 - bytecblock 0x151f7c75 0x00 - callsub __puya_arc4_router__ - return - - -// tests/artifacts/state-ops/contract.algo.ts::StateAppGlobalContract.__puya_arc4_router__() -> uint64: -__puya_arc4_router__: - // tests/artifacts/state-ops/contract.algo.ts:358 - // export class StateAppGlobalContract extends arc4.Contract { - proto 0 1 - txn NumAppArgs - bz __puya_arc4_router___bare_routing@11 - pushbytess 0xa997a187 0x4db8aa41 0x6693ab92 0x857fd923 0x36996451 0x3920a57b 0x93a852e1 // method "verify_get_bytes(byte[])byte[]", method "verify_get_uint64(byte[])uint64", method "verify_get_ex_bytes(application,byte[])(byte[],bool)", method "verify_get_ex_uint64(application,byte[])(uint64,bool)", method "verify_put_uint64(byte[],uint64)void", method "verify_put_bytes(byte[],byte[])void", method "verify_delete(byte[])void" - txna ApplicationArgs 0 - match __puya_arc4_router___verify_get_bytes_route@2 __puya_arc4_router___verify_get_uint64_route@3 __puya_arc4_router___verify_get_ex_bytes_route@4 __puya_arc4_router___verify_get_ex_uint64_route@5 __puya_arc4_router___verify_put_uint64_route@6 __puya_arc4_router___verify_put_bytes_route@7 __puya_arc4_router___verify_delete_route@8 - intc_1 // 0 - retsub - -__puya_arc4_router___verify_get_bytes_route@2: - // tests/artifacts/state-ops/contract.algo.ts:362 - // @arc4.abimethod() - txn OnCompletion - ! - assert // OnCompletion is not NoOp - txn ApplicationID - assert // can only call when not creating - // tests/artifacts/state-ops/contract.algo.ts:358 - // export class StateAppGlobalContract extends arc4.Contract { - txna ApplicationArgs 1 - extract 2 0 - // tests/artifacts/state-ops/contract.algo.ts:362 - // @arc4.abimethod() - callsub verify_get_bytes - dup - len - itob - extract 6 2 - swap - concat - bytec_0 // 0x151f7c75 - swap - concat - log - intc_0 // 1 - retsub - -__puya_arc4_router___verify_get_uint64_route@3: - // tests/artifacts/state-ops/contract.algo.ts:368 - // @arc4.abimethod() - txn OnCompletion - ! - assert // OnCompletion is not NoOp - txn ApplicationID - assert // can only call when not creating - // tests/artifacts/state-ops/contract.algo.ts:358 - // export class StateAppGlobalContract extends arc4.Contract { - txna ApplicationArgs 1 - extract 2 0 - // tests/artifacts/state-ops/contract.algo.ts:368 - // @arc4.abimethod() - callsub verify_get_uint64 - itob - bytec_0 // 0x151f7c75 - swap - concat - log - intc_0 // 1 - retsub - -__puya_arc4_router___verify_get_ex_bytes_route@4: - // tests/artifacts/state-ops/contract.algo.ts:374 - // @arc4.abimethod() - txn OnCompletion - ! - assert // OnCompletion is not NoOp - txn ApplicationID - assert // can only call when not creating - // tests/artifacts/state-ops/contract.algo.ts:358 - // export class StateAppGlobalContract extends arc4.Contract { - txna ApplicationArgs 1 - btoi - txnas Applications - txna ApplicationArgs 2 - extract 2 0 - // tests/artifacts/state-ops/contract.algo.ts:374 - // @arc4.abimethod() - callsub verify_get_ex_bytes - dig 1 - len - itob - extract 6 2 - uncover 2 - concat - bytec_1 // 0x00 - intc_1 // 0 - uncover 3 - setbit - pushbytes 0x0003 - swap - concat - swap - concat - bytec_0 // 0x151f7c75 - swap - concat - log - intc_0 // 1 - retsub - -__puya_arc4_router___verify_get_ex_uint64_route@5: - // tests/artifacts/state-ops/contract.algo.ts:379 - // @arc4.abimethod() - txn OnCompletion - ! - assert // OnCompletion is not NoOp - txn ApplicationID - assert // can only call when not creating - // tests/artifacts/state-ops/contract.algo.ts:358 - // export class StateAppGlobalContract extends arc4.Contract { - txna ApplicationArgs 1 - btoi - txnas Applications - txna ApplicationArgs 2 - extract 2 0 - // tests/artifacts/state-ops/contract.algo.ts:379 - // @arc4.abimethod() - callsub verify_get_ex_uint64 - swap - itob - bytec_1 // 0x00 - intc_1 // 0 - uncover 3 - setbit - concat - bytec_0 // 0x151f7c75 - swap - concat - log - intc_0 // 1 - retsub - -__puya_arc4_router___verify_put_uint64_route@6: - // tests/artifacts/state-ops/contract.algo.ts:384 - // @arc4.abimethod() - txn OnCompletion - ! - assert // OnCompletion is not NoOp - txn ApplicationID - assert // can only call when not creating - // tests/artifacts/state-ops/contract.algo.ts:358 - // export class StateAppGlobalContract extends arc4.Contract { - txna ApplicationArgs 1 - extract 2 0 - txna ApplicationArgs 2 - btoi - // tests/artifacts/state-ops/contract.algo.ts:384 - // @arc4.abimethod() - callsub verify_put_uint64 - intc_0 // 1 - retsub - -__puya_arc4_router___verify_put_bytes_route@7: - // tests/artifacts/state-ops/contract.algo.ts:389 - // @arc4.abimethod() - txn OnCompletion - ! - assert // OnCompletion is not NoOp - txn ApplicationID - assert // can only call when not creating - // tests/artifacts/state-ops/contract.algo.ts:358 - // export class StateAppGlobalContract extends arc4.Contract { - txna ApplicationArgs 1 - extract 2 0 - txna ApplicationArgs 2 - extract 2 0 - // tests/artifacts/state-ops/contract.algo.ts:389 - // @arc4.abimethod() - callsub verify_put_bytes - intc_0 // 1 - retsub - -__puya_arc4_router___verify_delete_route@8: - // tests/artifacts/state-ops/contract.algo.ts:394 - // @arc4.abimethod() - txn OnCompletion - ! - assert // OnCompletion is not NoOp - txn ApplicationID - assert // can only call when not creating - // tests/artifacts/state-ops/contract.algo.ts:358 - // export class StateAppGlobalContract extends arc4.Contract { - txna ApplicationArgs 1 - extract 2 0 - // tests/artifacts/state-ops/contract.algo.ts:394 - // @arc4.abimethod() - callsub verify_delete - intc_0 // 1 - retsub - -__puya_arc4_router___bare_routing@11: - // tests/artifacts/state-ops/contract.algo.ts:358 - // export class StateAppGlobalContract extends arc4.Contract { - txn OnCompletion - bnz __puya_arc4_router___after_if_else@15 - txn ApplicationID - ! - assert // can only call when creating - intc_0 // 1 - retsub - -__puya_arc4_router___after_if_else@15: - // tests/artifacts/state-ops/contract.algo.ts:358 - // export class StateAppGlobalContract extends arc4.Contract { - intc_1 // 0 - retsub - - -// tests/artifacts/state-ops/contract.algo.ts::StateAppGlobalContract.verify_get_bytes(a: bytes) -> bytes: -verify_get_bytes: - // tests/artifacts/state-ops/contract.algo.ts:362-363 - // @arc4.abimethod() - // verify_get_bytes(a: bytes): bytes { - proto 1 1 - // tests/artifacts/state-ops/contract.algo.ts:364 - // const value = op.AppGlobal.getBytes(a) - frame_dig -1 - app_global_get - // tests/artifacts/state-ops/contract.algo.ts:365 - // return value - retsub - - -// tests/artifacts/state-ops/contract.algo.ts::StateAppGlobalContract.verify_get_uint64(a: bytes) -> uint64: -verify_get_uint64: - // tests/artifacts/state-ops/contract.algo.ts:368-369 - // @arc4.abimethod() - // verify_get_uint64(a: bytes): uint64 { - proto 1 1 - // tests/artifacts/state-ops/contract.algo.ts:370 - // const value = op.AppGlobal.getUint64(a) - frame_dig -1 - app_global_get - // tests/artifacts/state-ops/contract.algo.ts:371 - // return value - retsub - - -// tests/artifacts/state-ops/contract.algo.ts::StateAppGlobalContract.verify_get_ex_bytes(a: uint64, b: bytes) -> bytes, uint64: -verify_get_ex_bytes: - // tests/artifacts/state-ops/contract.algo.ts:374-375 - // @arc4.abimethod() - // verify_get_ex_bytes(a: Application, b: bytes): readonly [bytes, boolean] { - proto 2 2 - // tests/artifacts/state-ops/contract.algo.ts:376 - // return op.AppGlobal.getExBytes(a, b) - frame_dig -2 - frame_dig -1 - app_global_get_ex - retsub - - -// tests/artifacts/state-ops/contract.algo.ts::StateAppGlobalContract.verify_get_ex_uint64(a: uint64, b: bytes) -> uint64, uint64: -verify_get_ex_uint64: - // tests/artifacts/state-ops/contract.algo.ts:379-380 - // @arc4.abimethod() - // verify_get_ex_uint64(a: Application, b: bytes): readonly [uint64, boolean] { - proto 2 2 - // tests/artifacts/state-ops/contract.algo.ts:381 - // return op.AppGlobal.getExUint64(a, b) - frame_dig -2 - frame_dig -1 - app_global_get_ex - retsub - - -// tests/artifacts/state-ops/contract.algo.ts::StateAppGlobalContract.verify_put_uint64(a: bytes, b: uint64) -> void: -verify_put_uint64: - // tests/artifacts/state-ops/contract.algo.ts:384-385 - // @arc4.abimethod() - // verify_put_uint64(a: bytes, b: uint64): void { - proto 2 0 - // tests/artifacts/state-ops/contract.algo.ts:386 - // op.AppGlobal.put(a, b) - frame_dig -2 - frame_dig -1 - app_global_put - retsub - - -// tests/artifacts/state-ops/contract.algo.ts::StateAppGlobalContract.verify_put_bytes(a: bytes, b: bytes) -> void: -verify_put_bytes: - // tests/artifacts/state-ops/contract.algo.ts:389-390 - // @arc4.abimethod() - // verify_put_bytes(a: bytes, b: bytes): void { - proto 2 0 - // tests/artifacts/state-ops/contract.algo.ts:391 - // op.AppGlobal.put(a, b) - frame_dig -2 - frame_dig -1 - app_global_put - retsub - - -// tests/artifacts/state-ops/contract.algo.ts::StateAppGlobalContract.verify_delete(a: bytes) -> void: -verify_delete: - // tests/artifacts/state-ops/contract.algo.ts:394-395 - // @arc4.abimethod() - // verify_delete(a: bytes): void { - proto 1 0 - // tests/artifacts/state-ops/contract.algo.ts:396 - // op.AppGlobal.delete(a) - frame_dig -1 - app_global_del - retsub diff --git a/tests/artifacts/state-ops/data/StateAppGlobalContract.arc32.json b/tests/artifacts/state-ops/data/StateAppGlobalContract.arc32.json deleted file mode 100644 index 479fa1b..0000000 --- a/tests/artifacts/state-ops/data/StateAppGlobalContract.arc32.json +++ /dev/null @@ -1,188 +0,0 @@ -{ - "hints": { - "verify_get_bytes(byte[])byte[]": { - "call_config": { - "no_op": "CALL" - } - }, - "verify_get_uint64(byte[])uint64": { - "call_config": { - "no_op": "CALL" - } - }, - "verify_get_ex_bytes(application,byte[])(byte[],bool)": { - "call_config": { - "no_op": "CALL" - } - }, - "verify_get_ex_uint64(application,byte[])(uint64,bool)": { - "call_config": { - "no_op": "CALL" - } - }, - "verify_put_uint64(byte[],uint64)void": { - "call_config": { - "no_op": "CALL" - } - }, - "verify_put_bytes(byte[],byte[])void": { - "call_config": { - "no_op": "CALL" - } - }, - "verify_delete(byte[])void": { - "call_config": { - "no_op": "CALL" - } - } - }, - "source": { - "approval": "I3ByYWdtYSB2ZXJzaW9uIDEwCgp0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OlN0YXRlQXBwR2xvYmFsQ29udHJhY3QuYXBwcm92YWxQcm9ncmFtOgogICAgaW50Y2Jsb2NrIDEgMAogICAgYnl0ZWNibG9jayAweDE1MWY3Yzc1IDB4MDAKICAgIGNhbGxzdWIgX19wdXlhX2FyYzRfcm91dGVyX18KICAgIHJldHVybgoKCi8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo6U3RhdGVBcHBHbG9iYWxDb250cmFjdC5fX3B1eWFfYXJjNF9yb3V0ZXJfXygpIC0+IHVpbnQ2NDoKX19wdXlhX2FyYzRfcm91dGVyX186CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MzU4CiAgICAvLyBleHBvcnQgY2xhc3MgU3RhdGVBcHBHbG9iYWxDb250cmFjdCBleHRlbmRzIGFyYzQuQ29udHJhY3QgewogICAgcHJvdG8gMCAxCiAgICB0eG4gTnVtQXBwQXJncwogICAgYnogX19wdXlhX2FyYzRfcm91dGVyX19fYmFyZV9yb3V0aW5nQDExCiAgICBwdXNoYnl0ZXNzIDB4YTk5N2ExODcgMHg0ZGI4YWE0MSAweDY2OTNhYjkyIDB4ODU3ZmQ5MjMgMHgzNjk5NjQ1MSAweDM5MjBhNTdiIDB4OTNhODUyZTEgLy8gbWV0aG9kICJ2ZXJpZnlfZ2V0X2J5dGVzKGJ5dGVbXSlieXRlW10iLCBtZXRob2QgInZlcmlmeV9nZXRfdWludDY0KGJ5dGVbXSl1aW50NjQiLCBtZXRob2QgInZlcmlmeV9nZXRfZXhfYnl0ZXMoYXBwbGljYXRpb24sYnl0ZVtdKShieXRlW10sYm9vbCkiLCBtZXRob2QgInZlcmlmeV9nZXRfZXhfdWludDY0KGFwcGxpY2F0aW9uLGJ5dGVbXSkodWludDY0LGJvb2wpIiwgbWV0aG9kICJ2ZXJpZnlfcHV0X3VpbnQ2NChieXRlW10sdWludDY0KXZvaWQiLCBtZXRob2QgInZlcmlmeV9wdXRfYnl0ZXMoYnl0ZVtdLGJ5dGVbXSl2b2lkIiwgbWV0aG9kICJ2ZXJpZnlfZGVsZXRlKGJ5dGVbXSl2b2lkIgogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMAogICAgbWF0Y2ggX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2dldF9ieXRlc19yb3V0ZUAyIF9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9nZXRfdWludDY0X3JvdXRlQDMgX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2dldF9leF9ieXRlc19yb3V0ZUA0IF9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9nZXRfZXhfdWludDY0X3JvdXRlQDUgX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X3B1dF91aW50NjRfcm91dGVANiBfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfcHV0X2J5dGVzX3JvdXRlQDcgX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2RlbGV0ZV9yb3V0ZUA4CiAgICBpbnRjXzEgLy8gMAogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfZ2V0X2J5dGVzX3JvdXRlQDI6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MzYyCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBub3QgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBjYW4gb25seSBjYWxsIHdoZW4gbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MzU4CiAgICAvLyBleHBvcnQgY2xhc3MgU3RhdGVBcHBHbG9iYWxDb250cmFjdCBleHRlbmRzIGFyYzQuQ29udHJhY3QgewogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgZXh0cmFjdCAyIDAKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czozNjIKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV9nZXRfYnl0ZXMKICAgIGR1cAogICAgbGVuCiAgICBpdG9iCiAgICBleHRyYWN0IDYgMgogICAgc3dhcAogICAgY29uY2F0CiAgICBieXRlY18wIC8vIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnRjXzAgLy8gMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfZ2V0X3VpbnQ2NF9yb3V0ZUAzOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjM2OAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgbm90IE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gY2FuIG9ubHkgY2FsbCB3aGVuIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjM1OAogICAgLy8gZXhwb3J0IGNsYXNzIFN0YXRlQXBwR2xvYmFsQ29udHJhY3QgZXh0ZW5kcyBhcmM0LkNvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGV4dHJhY3QgMiAwCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MzY4CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfZ2V0X3VpbnQ2NAogICAgaXRvYgogICAgYnl0ZWNfMCAvLyAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50Y18wIC8vIDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2dldF9leF9ieXRlc19yb3V0ZUA0OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjM3NAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgbm90IE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gY2FuIG9ubHkgY2FsbCB3aGVuIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjM1OAogICAgLy8gZXhwb3J0IGNsYXNzIFN0YXRlQXBwR2xvYmFsQ29udHJhY3QgZXh0ZW5kcyBhcmM0LkNvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGJ0b2kKICAgIHR4bmFzIEFwcGxpY2F0aW9ucwogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMgogICAgZXh0cmFjdCAyIDAKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czozNzQKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV9nZXRfZXhfYnl0ZXMKICAgIGRpZyAxCiAgICBsZW4KICAgIGl0b2IKICAgIGV4dHJhY3QgNiAyCiAgICB1bmNvdmVyIDIKICAgIGNvbmNhdAogICAgYnl0ZWNfMSAvLyAweDAwCiAgICBpbnRjXzEgLy8gMAogICAgdW5jb3ZlciAzCiAgICBzZXRiaXQKICAgIHB1c2hieXRlcyAweDAwMDMKICAgIHN3YXAKICAgIGNvbmNhdAogICAgc3dhcAogICAgY29uY2F0CiAgICBieXRlY18wIC8vIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnRjXzAgLy8gMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfZ2V0X2V4X3VpbnQ2NF9yb3V0ZUA1OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjM3OQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgbm90IE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gY2FuIG9ubHkgY2FsbCB3aGVuIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjM1OAogICAgLy8gZXhwb3J0IGNsYXNzIFN0YXRlQXBwR2xvYmFsQ29udHJhY3QgZXh0ZW5kcyBhcmM0LkNvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGJ0b2kKICAgIHR4bmFzIEFwcGxpY2F0aW9ucwogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMgogICAgZXh0cmFjdCAyIDAKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czozNzkKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV9nZXRfZXhfdWludDY0CiAgICBzd2FwCiAgICBpdG9iCiAgICBieXRlY18xIC8vIDB4MDAKICAgIGludGNfMSAvLyAwCiAgICB1bmNvdmVyIDMKICAgIHNldGJpdAogICAgY29uY2F0CiAgICBieXRlY18wIC8vIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnRjXzAgLy8gMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfcHV0X3VpbnQ2NF9yb3V0ZUA2OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjM4NAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgbm90IE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gY2FuIG9ubHkgY2FsbCB3aGVuIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjM1OAogICAgLy8gZXhwb3J0IGNsYXNzIFN0YXRlQXBwR2xvYmFsQ29udHJhY3QgZXh0ZW5kcyBhcmM0LkNvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGV4dHJhY3QgMiAwCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAyCiAgICBidG9pCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6Mzg0CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfcHV0X3VpbnQ2NAogICAgaW50Y18wIC8vIDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X3B1dF9ieXRlc19yb3V0ZUA3OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjM4OQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgbm90IE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gY2FuIG9ubHkgY2FsbCB3aGVuIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjM1OAogICAgLy8gZXhwb3J0IGNsYXNzIFN0YXRlQXBwR2xvYmFsQ29udHJhY3QgZXh0ZW5kcyBhcmM0LkNvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGV4dHJhY3QgMiAwCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAyCiAgICBleHRyYWN0IDIgMAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjM4OQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X3B1dF9ieXRlcwogICAgaW50Y18wIC8vIDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2RlbGV0ZV9yb3V0ZUA4OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjM5NAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgbm90IE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gY2FuIG9ubHkgY2FsbCB3aGVuIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjM1OAogICAgLy8gZXhwb3J0IGNsYXNzIFN0YXRlQXBwR2xvYmFsQ29udHJhY3QgZXh0ZW5kcyBhcmM0LkNvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGV4dHJhY3QgMiAwCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6Mzk0CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfZGVsZXRlCiAgICBpbnRjXzAgLy8gMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX19iYXJlX3JvdXRpbmdAMTE6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MzU4CiAgICAvLyBleHBvcnQgY2xhc3MgU3RhdGVBcHBHbG9iYWxDb250cmFjdCBleHRlbmRzIGFyYzQuQ29udHJhY3QgewogICAgdHhuIE9uQ29tcGxldGlvbgogICAgYm56IF9fcHV5YV9hcmM0X3JvdXRlcl9fX2FmdGVyX2lmX2Vsc2VAMTUKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICAhCiAgICBhc3NlcnQgLy8gY2FuIG9ubHkgY2FsbCB3aGVuIGNyZWF0aW5nCiAgICBpbnRjXzAgLy8gMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX19hZnRlcl9pZl9lbHNlQDE1OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjM1OAogICAgLy8gZXhwb3J0IGNsYXNzIFN0YXRlQXBwR2xvYmFsQ29udHJhY3QgZXh0ZW5kcyBhcmM0LkNvbnRyYWN0IHsKICAgIGludGNfMSAvLyAwCiAgICByZXRzdWIKCgovLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OlN0YXRlQXBwR2xvYmFsQ29udHJhY3QudmVyaWZ5X2dldF9ieXRlcyhhOiBieXRlcykgLT4gYnl0ZXM6CnZlcmlmeV9nZXRfYnl0ZXM6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MzYyLTM2MwogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIHZlcmlmeV9nZXRfYnl0ZXMoYTogYnl0ZXMpOiBieXRlcyB7CiAgICBwcm90byAxIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czozNjQKICAgIC8vIGNvbnN0IHZhbHVlID0gb3AuQXBwR2xvYmFsLmdldEJ5dGVzKGEpCiAgICBmcmFtZV9kaWcgLTEKICAgIGFwcF9nbG9iYWxfZ2V0CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MzY1CiAgICAvLyByZXR1cm4gdmFsdWUKICAgIHJldHN1YgoKCi8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo6U3RhdGVBcHBHbG9iYWxDb250cmFjdC52ZXJpZnlfZ2V0X3VpbnQ2NChhOiBieXRlcykgLT4gdWludDY0Ogp2ZXJpZnlfZ2V0X3VpbnQ2NDoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czozNjgtMzY5CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gdmVyaWZ5X2dldF91aW50NjQoYTogYnl0ZXMpOiB1aW50NjQgewogICAgcHJvdG8gMSAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MzcwCiAgICAvLyBjb25zdCB2YWx1ZSA9IG9wLkFwcEdsb2JhbC5nZXRVaW50NjQoYSkKICAgIGZyYW1lX2RpZyAtMQogICAgYXBwX2dsb2JhbF9nZXQKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czozNzEKICAgIC8vIHJldHVybiB2YWx1ZQogICAgcmV0c3ViCgoKLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjpTdGF0ZUFwcEdsb2JhbENvbnRyYWN0LnZlcmlmeV9nZXRfZXhfYnl0ZXMoYTogdWludDY0LCBiOiBieXRlcykgLT4gYnl0ZXMsIHVpbnQ2NDoKdmVyaWZ5X2dldF9leF9ieXRlczoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czozNzQtMzc1CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gdmVyaWZ5X2dldF9leF9ieXRlcyhhOiBBcHBsaWNhdGlvbiwgYjogYnl0ZXMpOiByZWFkb25seSBbYnl0ZXMsIGJvb2xlYW5dIHsKICAgIHByb3RvIDIgMgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjM3NgogICAgLy8gcmV0dXJuIG9wLkFwcEdsb2JhbC5nZXRFeEJ5dGVzKGEsIGIpCiAgICBmcmFtZV9kaWcgLTIKICAgIGZyYW1lX2RpZyAtMQogICAgYXBwX2dsb2JhbF9nZXRfZXgKICAgIHJldHN1YgoKCi8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo6U3RhdGVBcHBHbG9iYWxDb250cmFjdC52ZXJpZnlfZ2V0X2V4X3VpbnQ2NChhOiB1aW50NjQsIGI6IGJ5dGVzKSAtPiB1aW50NjQsIHVpbnQ2NDoKdmVyaWZ5X2dldF9leF91aW50NjQ6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6Mzc5LTM4MAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIHZlcmlmeV9nZXRfZXhfdWludDY0KGE6IEFwcGxpY2F0aW9uLCBiOiBieXRlcyk6IHJlYWRvbmx5IFt1aW50NjQsIGJvb2xlYW5dIHsKICAgIHByb3RvIDIgMgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjM4MQogICAgLy8gcmV0dXJuIG9wLkFwcEdsb2JhbC5nZXRFeFVpbnQ2NChhLCBiKQogICAgZnJhbWVfZGlnIC0yCiAgICBmcmFtZV9kaWcgLTEKICAgIGFwcF9nbG9iYWxfZ2V0X2V4CiAgICByZXRzdWIKCgovLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OlN0YXRlQXBwR2xvYmFsQ29udHJhY3QudmVyaWZ5X3B1dF91aW50NjQoYTogYnl0ZXMsIGI6IHVpbnQ2NCkgLT4gdm9pZDoKdmVyaWZ5X3B1dF91aW50NjQ6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6Mzg0LTM4NQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIHZlcmlmeV9wdXRfdWludDY0KGE6IGJ5dGVzLCBiOiB1aW50NjQpOiB2b2lkIHsKICAgIHByb3RvIDIgMAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjM4NgogICAgLy8gb3AuQXBwR2xvYmFsLnB1dChhLCBiKQogICAgZnJhbWVfZGlnIC0yCiAgICBmcmFtZV9kaWcgLTEKICAgIGFwcF9nbG9iYWxfcHV0CiAgICByZXRzdWIKCgovLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OlN0YXRlQXBwR2xvYmFsQ29udHJhY3QudmVyaWZ5X3B1dF9ieXRlcyhhOiBieXRlcywgYjogYnl0ZXMpIC0+IHZvaWQ6CnZlcmlmeV9wdXRfYnl0ZXM6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6Mzg5LTM5MAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIHZlcmlmeV9wdXRfYnl0ZXMoYTogYnl0ZXMsIGI6IGJ5dGVzKTogdm9pZCB7CiAgICBwcm90byAyIDAKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czozOTEKICAgIC8vIG9wLkFwcEdsb2JhbC5wdXQoYSwgYikKICAgIGZyYW1lX2RpZyAtMgogICAgZnJhbWVfZGlnIC0xCiAgICBhcHBfZ2xvYmFsX3B1dAogICAgcmV0c3ViCgoKLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjpTdGF0ZUFwcEdsb2JhbENvbnRyYWN0LnZlcmlmeV9kZWxldGUoYTogYnl0ZXMpIC0+IHZvaWQ6CnZlcmlmeV9kZWxldGU6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6Mzk0LTM5NQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIHZlcmlmeV9kZWxldGUoYTogYnl0ZXMpOiB2b2lkIHsKICAgIHByb3RvIDEgMAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjM5NgogICAgLy8gb3AuQXBwR2xvYmFsLmRlbGV0ZShhKQogICAgZnJhbWVfZGlnIC0xCiAgICBhcHBfZ2xvYmFsX2RlbAogICAgcmV0c3ViCg==", - "clear": "I3ByYWdtYSB2ZXJzaW9uIDEwCgp0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OlN0YXRlQXBwR2xvYmFsQ29udHJhY3QuY2xlYXJTdGF0ZVByb2dyYW06CiAgICBwdXNoaW50IDEgLy8gMQogICAgcmV0dXJuCg==" - }, - "state": { - "global": { - "num_byte_slices": 1, - "num_uints": 1 - }, - "local": { - "num_byte_slices": 0, - "num_uints": 0 - } - }, - "schema": { - "global": { - "declared": { - "globalBytes": { - "type": "bytes", - "key": "global_bytes" - }, - "globalUint64": { - "type": "uint64", - "key": "global_uint64" - } - }, - "reserved": {} - }, - "local": { - "declared": {}, - "reserved": {} - } - }, - "contract": { - "name": "StateAppGlobalContract", - "methods": [ - { - "name": "verify_get_bytes", - "args": [ - { - "type": "byte[]", - "name": "a" - } - ], - "readonly": false, - "returns": { - "type": "byte[]" - } - }, - { - "name": "verify_get_uint64", - "args": [ - { - "type": "byte[]", - "name": "a" - } - ], - "readonly": false, - "returns": { - "type": "uint64" - } - }, - { - "name": "verify_get_ex_bytes", - "args": [ - { - "type": "application", - "name": "a" - }, - { - "type": "byte[]", - "name": "b" - } - ], - "readonly": false, - "returns": { - "type": "(byte[],bool)" - } - }, - { - "name": "verify_get_ex_uint64", - "args": [ - { - "type": "application", - "name": "a" - }, - { - "type": "byte[]", - "name": "b" - } - ], - "readonly": false, - "returns": { - "type": "(uint64,bool)" - } - }, - { - "name": "verify_put_uint64", - "args": [ - { - "type": "byte[]", - "name": "a" - }, - { - "type": "uint64", - "name": "b" - } - ], - "readonly": false, - "returns": { - "type": "void" - } - }, - { - "name": "verify_put_bytes", - "args": [ - { - "type": "byte[]", - "name": "a" - }, - { - "type": "byte[]", - "name": "b" - } - ], - "readonly": false, - "returns": { - "type": "void" - } - }, - { - "name": "verify_delete", - "args": [ - { - "type": "byte[]", - "name": "a" - } - ], - "readonly": false, - "returns": { - "type": "void" - } - } - ], - "networks": {} - }, - "bare_call_config": { - "no_op": "CREATE" - } -} \ No newline at end of file diff --git a/tests/artifacts/state-ops/data/StateAppGlobalContract.arc56.json b/tests/artifacts/state-ops/data/StateAppGlobalContract.arc56.json deleted file mode 100644 index 3d10bba..0000000 --- a/tests/artifacts/state-ops/data/StateAppGlobalContract.arc56.json +++ /dev/null @@ -1,260 +0,0 @@ -{ - "name": "StateAppGlobalContract", - "structs": {}, - "methods": [ - { - "name": "verify_get_bytes", - "args": [ - { - "type": "byte[]", - "name": "a" - } - ], - "returns": { - "type": "byte[]" - }, - "actions": { - "create": [], - "call": [ - "NoOp" - ] - }, - "readonly": false, - "events": [], - "recommendations": {} - }, - { - "name": "verify_get_uint64", - "args": [ - { - "type": "byte[]", - "name": "a" - } - ], - "returns": { - "type": "uint64" - }, - "actions": { - "create": [], - "call": [ - "NoOp" - ] - }, - "readonly": false, - "events": [], - "recommendations": {} - }, - { - "name": "verify_get_ex_bytes", - "args": [ - { - "type": "application", - "name": "a" - }, - { - "type": "byte[]", - "name": "b" - } - ], - "returns": { - "type": "(byte[],bool)" - }, - "actions": { - "create": [], - "call": [ - "NoOp" - ] - }, - "readonly": false, - "events": [], - "recommendations": {} - }, - { - "name": "verify_get_ex_uint64", - "args": [ - { - "type": "application", - "name": "a" - }, - { - "type": "byte[]", - "name": "b" - } - ], - "returns": { - "type": "(uint64,bool)" - }, - "actions": { - "create": [], - "call": [ - "NoOp" - ] - }, - "readonly": false, - "events": [], - "recommendations": {} - }, - { - "name": "verify_put_uint64", - "args": [ - { - "type": "byte[]", - "name": "a" - }, - { - "type": "uint64", - "name": "b" - } - ], - "returns": { - "type": "void" - }, - "actions": { - "create": [], - "call": [ - "NoOp" - ] - }, - "readonly": false, - "events": [], - "recommendations": {} - }, - { - "name": "verify_put_bytes", - "args": [ - { - "type": "byte[]", - "name": "a" - }, - { - "type": "byte[]", - "name": "b" - } - ], - "returns": { - "type": "void" - }, - "actions": { - "create": [], - "call": [ - "NoOp" - ] - }, - "readonly": false, - "events": [], - "recommendations": {} - }, - { - "name": "verify_delete", - "args": [ - { - "type": "byte[]", - "name": "a" - } - ], - "returns": { - "type": "void" - }, - "actions": { - "create": [], - "call": [ - "NoOp" - ] - }, - "readonly": false, - "events": [], - "recommendations": {} - } - ], - "arcs": [ - 22, - 28 - ], - "networks": {}, - "state": { - "schema": { - "global": { - "ints": 1, - "bytes": 1 - }, - "local": { - "ints": 0, - "bytes": 0 - } - }, - "keys": { - "global": { - "globalUint64": { - "keyType": "AVMString", - "valueType": "AVMUint64", - "key": "Z2xvYmFsX3VpbnQ2NA==" - }, - "globalBytes": { - "keyType": "AVMString", - "valueType": "AVMBytes", - "key": "Z2xvYmFsX2J5dGVz" - } - }, - "local": {}, - "box": {} - }, - "maps": { - "global": {}, - "local": {}, - "box": {} - } - }, - "bareActions": { - "create": [ - "NoOp" - ], - "call": [] - }, - "sourceInfo": { - "approval": { - "sourceInfo": [ - { - "pc": [ - 87, - 117, - 140, - 191, - 227, - 249, - 273 - ], - "errorMessage": "OnCompletion is not NoOp" - }, - { - "pc": [ - 296 - ], - "errorMessage": "can only call when creating" - }, - { - "pc": [ - 90, - 120, - 143, - 194, - 230, - 252, - 276 - ], - "errorMessage": "can only call when not creating" - } - ], - "pcOffsetMethod": "none" - }, - "clear": { - "sourceInfo": [], - "pcOffsetMethod": "none" - } - }, - "source": { - "approval": "I3ByYWdtYSB2ZXJzaW9uIDEwCgp0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OlN0YXRlQXBwR2xvYmFsQ29udHJhY3QuYXBwcm92YWxQcm9ncmFtOgogICAgaW50Y2Jsb2NrIDEgMAogICAgYnl0ZWNibG9jayAweDE1MWY3Yzc1IDB4MDAKICAgIGNhbGxzdWIgX19wdXlhX2FyYzRfcm91dGVyX18KICAgIHJldHVybgoKCi8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo6U3RhdGVBcHBHbG9iYWxDb250cmFjdC5fX3B1eWFfYXJjNF9yb3V0ZXJfXygpIC0+IHVpbnQ2NDoKX19wdXlhX2FyYzRfcm91dGVyX186CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MzU4CiAgICAvLyBleHBvcnQgY2xhc3MgU3RhdGVBcHBHbG9iYWxDb250cmFjdCBleHRlbmRzIGFyYzQuQ29udHJhY3QgewogICAgcHJvdG8gMCAxCiAgICB0eG4gTnVtQXBwQXJncwogICAgYnogX19wdXlhX2FyYzRfcm91dGVyX19fYmFyZV9yb3V0aW5nQDExCiAgICBwdXNoYnl0ZXNzIDB4YTk5N2ExODcgMHg0ZGI4YWE0MSAweDY2OTNhYjkyIDB4ODU3ZmQ5MjMgMHgzNjk5NjQ1MSAweDM5MjBhNTdiIDB4OTNhODUyZTEgLy8gbWV0aG9kICJ2ZXJpZnlfZ2V0X2J5dGVzKGJ5dGVbXSlieXRlW10iLCBtZXRob2QgInZlcmlmeV9nZXRfdWludDY0KGJ5dGVbXSl1aW50NjQiLCBtZXRob2QgInZlcmlmeV9nZXRfZXhfYnl0ZXMoYXBwbGljYXRpb24sYnl0ZVtdKShieXRlW10sYm9vbCkiLCBtZXRob2QgInZlcmlmeV9nZXRfZXhfdWludDY0KGFwcGxpY2F0aW9uLGJ5dGVbXSkodWludDY0LGJvb2wpIiwgbWV0aG9kICJ2ZXJpZnlfcHV0X3VpbnQ2NChieXRlW10sdWludDY0KXZvaWQiLCBtZXRob2QgInZlcmlmeV9wdXRfYnl0ZXMoYnl0ZVtdLGJ5dGVbXSl2b2lkIiwgbWV0aG9kICJ2ZXJpZnlfZGVsZXRlKGJ5dGVbXSl2b2lkIgogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMAogICAgbWF0Y2ggX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2dldF9ieXRlc19yb3V0ZUAyIF9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9nZXRfdWludDY0X3JvdXRlQDMgX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2dldF9leF9ieXRlc19yb3V0ZUA0IF9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9nZXRfZXhfdWludDY0X3JvdXRlQDUgX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X3B1dF91aW50NjRfcm91dGVANiBfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfcHV0X2J5dGVzX3JvdXRlQDcgX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2RlbGV0ZV9yb3V0ZUA4CiAgICBpbnRjXzEgLy8gMAogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfZ2V0X2J5dGVzX3JvdXRlQDI6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MzYyCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBub3QgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBjYW4gb25seSBjYWxsIHdoZW4gbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MzU4CiAgICAvLyBleHBvcnQgY2xhc3MgU3RhdGVBcHBHbG9iYWxDb250cmFjdCBleHRlbmRzIGFyYzQuQ29udHJhY3QgewogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgZXh0cmFjdCAyIDAKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czozNjIKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV9nZXRfYnl0ZXMKICAgIGR1cAogICAgbGVuCiAgICBpdG9iCiAgICBleHRyYWN0IDYgMgogICAgc3dhcAogICAgY29uY2F0CiAgICBieXRlY18wIC8vIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnRjXzAgLy8gMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfZ2V0X3VpbnQ2NF9yb3V0ZUAzOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjM2OAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgbm90IE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gY2FuIG9ubHkgY2FsbCB3aGVuIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjM1OAogICAgLy8gZXhwb3J0IGNsYXNzIFN0YXRlQXBwR2xvYmFsQ29udHJhY3QgZXh0ZW5kcyBhcmM0LkNvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGV4dHJhY3QgMiAwCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MzY4CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfZ2V0X3VpbnQ2NAogICAgaXRvYgogICAgYnl0ZWNfMCAvLyAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50Y18wIC8vIDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2dldF9leF9ieXRlc19yb3V0ZUA0OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjM3NAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgbm90IE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gY2FuIG9ubHkgY2FsbCB3aGVuIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjM1OAogICAgLy8gZXhwb3J0IGNsYXNzIFN0YXRlQXBwR2xvYmFsQ29udHJhY3QgZXh0ZW5kcyBhcmM0LkNvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGJ0b2kKICAgIHR4bmFzIEFwcGxpY2F0aW9ucwogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMgogICAgZXh0cmFjdCAyIDAKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czozNzQKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV9nZXRfZXhfYnl0ZXMKICAgIGRpZyAxCiAgICBsZW4KICAgIGl0b2IKICAgIGV4dHJhY3QgNiAyCiAgICB1bmNvdmVyIDIKICAgIGNvbmNhdAogICAgYnl0ZWNfMSAvLyAweDAwCiAgICBpbnRjXzEgLy8gMAogICAgdW5jb3ZlciAzCiAgICBzZXRiaXQKICAgIHB1c2hieXRlcyAweDAwMDMKICAgIHN3YXAKICAgIGNvbmNhdAogICAgc3dhcAogICAgY29uY2F0CiAgICBieXRlY18wIC8vIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnRjXzAgLy8gMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfZ2V0X2V4X3VpbnQ2NF9yb3V0ZUA1OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjM3OQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgbm90IE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gY2FuIG9ubHkgY2FsbCB3aGVuIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjM1OAogICAgLy8gZXhwb3J0IGNsYXNzIFN0YXRlQXBwR2xvYmFsQ29udHJhY3QgZXh0ZW5kcyBhcmM0LkNvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGJ0b2kKICAgIHR4bmFzIEFwcGxpY2F0aW9ucwogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMgogICAgZXh0cmFjdCAyIDAKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czozNzkKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV9nZXRfZXhfdWludDY0CiAgICBzd2FwCiAgICBpdG9iCiAgICBieXRlY18xIC8vIDB4MDAKICAgIGludGNfMSAvLyAwCiAgICB1bmNvdmVyIDMKICAgIHNldGJpdAogICAgY29uY2F0CiAgICBieXRlY18wIC8vIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnRjXzAgLy8gMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfcHV0X3VpbnQ2NF9yb3V0ZUA2OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjM4NAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgbm90IE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gY2FuIG9ubHkgY2FsbCB3aGVuIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjM1OAogICAgLy8gZXhwb3J0IGNsYXNzIFN0YXRlQXBwR2xvYmFsQ29udHJhY3QgZXh0ZW5kcyBhcmM0LkNvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGV4dHJhY3QgMiAwCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAyCiAgICBidG9pCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6Mzg0CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfcHV0X3VpbnQ2NAogICAgaW50Y18wIC8vIDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X3B1dF9ieXRlc19yb3V0ZUA3OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjM4OQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgbm90IE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gY2FuIG9ubHkgY2FsbCB3aGVuIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjM1OAogICAgLy8gZXhwb3J0IGNsYXNzIFN0YXRlQXBwR2xvYmFsQ29udHJhY3QgZXh0ZW5kcyBhcmM0LkNvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGV4dHJhY3QgMiAwCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAyCiAgICBleHRyYWN0IDIgMAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjM4OQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X3B1dF9ieXRlcwogICAgaW50Y18wIC8vIDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2RlbGV0ZV9yb3V0ZUA4OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjM5NAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgbm90IE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gY2FuIG9ubHkgY2FsbCB3aGVuIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjM1OAogICAgLy8gZXhwb3J0IGNsYXNzIFN0YXRlQXBwR2xvYmFsQ29udHJhY3QgZXh0ZW5kcyBhcmM0LkNvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGV4dHJhY3QgMiAwCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6Mzk0CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfZGVsZXRlCiAgICBpbnRjXzAgLy8gMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX19iYXJlX3JvdXRpbmdAMTE6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MzU4CiAgICAvLyBleHBvcnQgY2xhc3MgU3RhdGVBcHBHbG9iYWxDb250cmFjdCBleHRlbmRzIGFyYzQuQ29udHJhY3QgewogICAgdHhuIE9uQ29tcGxldGlvbgogICAgYm56IF9fcHV5YV9hcmM0X3JvdXRlcl9fX2FmdGVyX2lmX2Vsc2VAMTUKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICAhCiAgICBhc3NlcnQgLy8gY2FuIG9ubHkgY2FsbCB3aGVuIGNyZWF0aW5nCiAgICBpbnRjXzAgLy8gMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX19hZnRlcl9pZl9lbHNlQDE1OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjM1OAogICAgLy8gZXhwb3J0IGNsYXNzIFN0YXRlQXBwR2xvYmFsQ29udHJhY3QgZXh0ZW5kcyBhcmM0LkNvbnRyYWN0IHsKICAgIGludGNfMSAvLyAwCiAgICByZXRzdWIKCgovLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OlN0YXRlQXBwR2xvYmFsQ29udHJhY3QudmVyaWZ5X2dldF9ieXRlcyhhOiBieXRlcykgLT4gYnl0ZXM6CnZlcmlmeV9nZXRfYnl0ZXM6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MzYyLTM2MwogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIHZlcmlmeV9nZXRfYnl0ZXMoYTogYnl0ZXMpOiBieXRlcyB7CiAgICBwcm90byAxIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czozNjQKICAgIC8vIGNvbnN0IHZhbHVlID0gb3AuQXBwR2xvYmFsLmdldEJ5dGVzKGEpCiAgICBmcmFtZV9kaWcgLTEKICAgIGFwcF9nbG9iYWxfZ2V0CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MzY1CiAgICAvLyByZXR1cm4gdmFsdWUKICAgIHJldHN1YgoKCi8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo6U3RhdGVBcHBHbG9iYWxDb250cmFjdC52ZXJpZnlfZ2V0X3VpbnQ2NChhOiBieXRlcykgLT4gdWludDY0Ogp2ZXJpZnlfZ2V0X3VpbnQ2NDoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czozNjgtMzY5CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gdmVyaWZ5X2dldF91aW50NjQoYTogYnl0ZXMpOiB1aW50NjQgewogICAgcHJvdG8gMSAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MzcwCiAgICAvLyBjb25zdCB2YWx1ZSA9IG9wLkFwcEdsb2JhbC5nZXRVaW50NjQoYSkKICAgIGZyYW1lX2RpZyAtMQogICAgYXBwX2dsb2JhbF9nZXQKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czozNzEKICAgIC8vIHJldHVybiB2YWx1ZQogICAgcmV0c3ViCgoKLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjpTdGF0ZUFwcEdsb2JhbENvbnRyYWN0LnZlcmlmeV9nZXRfZXhfYnl0ZXMoYTogdWludDY0LCBiOiBieXRlcykgLT4gYnl0ZXMsIHVpbnQ2NDoKdmVyaWZ5X2dldF9leF9ieXRlczoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czozNzQtMzc1CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gdmVyaWZ5X2dldF9leF9ieXRlcyhhOiBBcHBsaWNhdGlvbiwgYjogYnl0ZXMpOiByZWFkb25seSBbYnl0ZXMsIGJvb2xlYW5dIHsKICAgIHByb3RvIDIgMgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjM3NgogICAgLy8gcmV0dXJuIG9wLkFwcEdsb2JhbC5nZXRFeEJ5dGVzKGEsIGIpCiAgICBmcmFtZV9kaWcgLTIKICAgIGZyYW1lX2RpZyAtMQogICAgYXBwX2dsb2JhbF9nZXRfZXgKICAgIHJldHN1YgoKCi8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo6U3RhdGVBcHBHbG9iYWxDb250cmFjdC52ZXJpZnlfZ2V0X2V4X3VpbnQ2NChhOiB1aW50NjQsIGI6IGJ5dGVzKSAtPiB1aW50NjQsIHVpbnQ2NDoKdmVyaWZ5X2dldF9leF91aW50NjQ6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6Mzc5LTM4MAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIHZlcmlmeV9nZXRfZXhfdWludDY0KGE6IEFwcGxpY2F0aW9uLCBiOiBieXRlcyk6IHJlYWRvbmx5IFt1aW50NjQsIGJvb2xlYW5dIHsKICAgIHByb3RvIDIgMgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjM4MQogICAgLy8gcmV0dXJuIG9wLkFwcEdsb2JhbC5nZXRFeFVpbnQ2NChhLCBiKQogICAgZnJhbWVfZGlnIC0yCiAgICBmcmFtZV9kaWcgLTEKICAgIGFwcF9nbG9iYWxfZ2V0X2V4CiAgICByZXRzdWIKCgovLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OlN0YXRlQXBwR2xvYmFsQ29udHJhY3QudmVyaWZ5X3B1dF91aW50NjQoYTogYnl0ZXMsIGI6IHVpbnQ2NCkgLT4gdm9pZDoKdmVyaWZ5X3B1dF91aW50NjQ6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6Mzg0LTM4NQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIHZlcmlmeV9wdXRfdWludDY0KGE6IGJ5dGVzLCBiOiB1aW50NjQpOiB2b2lkIHsKICAgIHByb3RvIDIgMAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjM4NgogICAgLy8gb3AuQXBwR2xvYmFsLnB1dChhLCBiKQogICAgZnJhbWVfZGlnIC0yCiAgICBmcmFtZV9kaWcgLTEKICAgIGFwcF9nbG9iYWxfcHV0CiAgICByZXRzdWIKCgovLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OlN0YXRlQXBwR2xvYmFsQ29udHJhY3QudmVyaWZ5X3B1dF9ieXRlcyhhOiBieXRlcywgYjogYnl0ZXMpIC0+IHZvaWQ6CnZlcmlmeV9wdXRfYnl0ZXM6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6Mzg5LTM5MAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIHZlcmlmeV9wdXRfYnl0ZXMoYTogYnl0ZXMsIGI6IGJ5dGVzKTogdm9pZCB7CiAgICBwcm90byAyIDAKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czozOTEKICAgIC8vIG9wLkFwcEdsb2JhbC5wdXQoYSwgYikKICAgIGZyYW1lX2RpZyAtMgogICAgZnJhbWVfZGlnIC0xCiAgICBhcHBfZ2xvYmFsX3B1dAogICAgcmV0c3ViCgoKLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjpTdGF0ZUFwcEdsb2JhbENvbnRyYWN0LnZlcmlmeV9kZWxldGUoYTogYnl0ZXMpIC0+IHZvaWQ6CnZlcmlmeV9kZWxldGU6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6Mzk0LTM5NQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIHZlcmlmeV9kZWxldGUoYTogYnl0ZXMpOiB2b2lkIHsKICAgIHByb3RvIDEgMAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjM5NgogICAgLy8gb3AuQXBwR2xvYmFsLmRlbGV0ZShhKQogICAgZnJhbWVfZGlnIC0xCiAgICBhcHBfZ2xvYmFsX2RlbAogICAgcmV0c3ViCg==", - "clear": "I3ByYWdtYSB2ZXJzaW9uIDEwCgp0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OlN0YXRlQXBwR2xvYmFsQ29udHJhY3QuY2xlYXJTdGF0ZVByb2dyYW06CiAgICBwdXNoaW50IDEgLy8gMQogICAgcmV0dXJuCg==" - }, - "events": [], - "templateVariables": {} -} \ No newline at end of file diff --git a/tests/artifacts/state-ops/data/StateAppGlobalContract.clear.teal b/tests/artifacts/state-ops/data/StateAppGlobalContract.clear.teal deleted file mode 100644 index 62c9330..0000000 --- a/tests/artifacts/state-ops/data/StateAppGlobalContract.clear.teal +++ /dev/null @@ -1,5 +0,0 @@ -#pragma version 10 - -tests/artifacts/state-ops/contract.algo.ts::StateAppGlobalContract.clearStateProgram: - pushint 1 // 1 - return diff --git a/tests/artifacts/state-ops/data/StateAppGlobalExContract.approval.teal b/tests/artifacts/state-ops/data/StateAppGlobalExContract.approval.teal deleted file mode 100644 index bc81e3d..0000000 --- a/tests/artifacts/state-ops/data/StateAppGlobalExContract.approval.teal +++ /dev/null @@ -1,71 +0,0 @@ -#pragma version 10 - -tests/artifacts/state-ops/contract.algo.ts::StateAppGlobalExContract.approvalProgram: - bytecblock "dummy_bytes" 0x001064756d6d795f617263345f6279746573 - txn ApplicationID - bnz main_after_if_else@2 - callsub constructor - -main_after_if_else@2: - callsub __puya_arc4_router__ - return - - -// tests/artifacts/state-ops/contract.algo.ts::StateAppGlobalExContract.constructor() -> void: -constructor: - // tests/artifacts/state-ops/contract.algo.ts:349 - // export class StateAppGlobalExContract extends arc4.Contract { - proto 0 0 - // tests/artifacts/state-ops/contract.algo.ts:350 - // globalUint64 = GlobalState({ key: Bytes('global_uint64'), initialValue: Uint64(2) }) - pushbytes "global_uint64" - pushint 2 // 2 - app_global_put - // tests/artifacts/state-ops/contract.algo.ts:351 - // globalBytes = GlobalState({ key: Bytes('global_bytes'), initialValue: Bytes('dummy_bytes') }) - pushbytes "global_bytes" - bytec_0 // "dummy_bytes" - app_global_put - // tests/artifacts/state-ops/contract.algo.ts:352 - // global_uint64_explicit = GlobalState({ initialValue: Uint64(2) }) - pushbytes "global_uint64_explicit" - pushint 2 // 2 - app_global_put - // tests/artifacts/state-ops/contract.algo.ts:353 - // global_bytes_explicit = GlobalState({ initialValue: Bytes('dummy_bytes') }) - pushbytes "global_bytes_explicit" - bytec_0 // "dummy_bytes" - app_global_put - // tests/artifacts/state-ops/contract.algo.ts:354 - // globalArc4Bytes = GlobalState({ key: Bytes('global_arc4_bytes'), initialValue: new DynamicBytes('dummy_arc4_bytes') }) - pushbytes "global_arc4_bytes" - bytec_1 // 0x001064756d6d795f617263345f6279746573 - app_global_put - // tests/artifacts/state-ops/contract.algo.ts:355 - // global_arc4_bytes_explicit = GlobalState({ initialValue: new DynamicBytes('dummy_arc4_bytes') }) - pushbytes "global_arc4_bytes_explicit" - bytec_1 // 0x001064756d6d795f617263345f6279746573 - app_global_put - retsub - - -// tests/artifacts/state-ops/contract.algo.ts::StateAppGlobalExContract.__puya_arc4_router__() -> uint64: -__puya_arc4_router__: - // tests/artifacts/state-ops/contract.algo.ts:349 - // export class StateAppGlobalExContract extends arc4.Contract { - proto 0 1 - txn NumAppArgs - bnz __puya_arc4_router___after_if_else@6 - txn OnCompletion - bnz __puya_arc4_router___after_if_else@6 - txn ApplicationID - ! - assert // can only call when creating - pushint 1 // 1 - retsub - -__puya_arc4_router___after_if_else@6: - // tests/artifacts/state-ops/contract.algo.ts:349 - // export class StateAppGlobalExContract extends arc4.Contract { - pushint 0 // 0 - retsub diff --git a/tests/artifacts/state-ops/data/StateAppGlobalExContract.arc32.json b/tests/artifacts/state-ops/data/StateAppGlobalExContract.arc32.json deleted file mode 100644 index 4e8e5d8..0000000 --- a/tests/artifacts/state-ops/data/StateAppGlobalExContract.arc32.json +++ /dev/null @@ -1,60 +0,0 @@ -{ - "hints": {}, - "source": { - "approval": "I3ByYWdtYSB2ZXJzaW9uIDEwCgp0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OlN0YXRlQXBwR2xvYmFsRXhDb250cmFjdC5hcHByb3ZhbFByb2dyYW06CiAgICBieXRlY2Jsb2NrICJkdW1teV9ieXRlcyIgMHgwMDEwNjQ3NTZkNmQ3OTVmNjE3MjYzMzQ1ZjYyNzk3NDY1NzMKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBibnogbWFpbl9hZnRlcl9pZl9lbHNlQDIKICAgIGNhbGxzdWIgY29uc3RydWN0b3IKCm1haW5fYWZ0ZXJfaWZfZWxzZUAyOgogICAgY2FsbHN1YiBfX3B1eWFfYXJjNF9yb3V0ZXJfXwogICAgcmV0dXJuCgoKLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjpTdGF0ZUFwcEdsb2JhbEV4Q29udHJhY3QuY29uc3RydWN0b3IoKSAtPiB2b2lkOgpjb25zdHJ1Y3RvcjoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czozNDkKICAgIC8vIGV4cG9ydCBjbGFzcyBTdGF0ZUFwcEdsb2JhbEV4Q29udHJhY3QgZXh0ZW5kcyBhcmM0LkNvbnRyYWN0IHsKICAgIHByb3RvIDAgMAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjM1MAogICAgLy8gZ2xvYmFsVWludDY0ID0gR2xvYmFsU3RhdGUoeyBrZXk6IEJ5dGVzKCdnbG9iYWxfdWludDY0JyksIGluaXRpYWxWYWx1ZTogVWludDY0KDIpIH0pCiAgICBwdXNoYnl0ZXMgImdsb2JhbF91aW50NjQiCiAgICBwdXNoaW50IDIgLy8gMgogICAgYXBwX2dsb2JhbF9wdXQKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czozNTEKICAgIC8vIGdsb2JhbEJ5dGVzID0gR2xvYmFsU3RhdGUoeyBrZXk6IEJ5dGVzKCdnbG9iYWxfYnl0ZXMnKSwgaW5pdGlhbFZhbHVlOiBCeXRlcygnZHVtbXlfYnl0ZXMnKSB9KQogICAgcHVzaGJ5dGVzICJnbG9iYWxfYnl0ZXMiCiAgICBieXRlY18wIC8vICJkdW1teV9ieXRlcyIKICAgIGFwcF9nbG9iYWxfcHV0CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MzUyCiAgICAvLyBnbG9iYWxfdWludDY0X2V4cGxpY2l0ID0gR2xvYmFsU3RhdGUoeyBpbml0aWFsVmFsdWU6IFVpbnQ2NCgyKSB9KQogICAgcHVzaGJ5dGVzICJnbG9iYWxfdWludDY0X2V4cGxpY2l0IgogICAgcHVzaGludCAyIC8vIDIKICAgIGFwcF9nbG9iYWxfcHV0CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MzUzCiAgICAvLyBnbG9iYWxfYnl0ZXNfZXhwbGljaXQgPSBHbG9iYWxTdGF0ZSh7IGluaXRpYWxWYWx1ZTogQnl0ZXMoJ2R1bW15X2J5dGVzJykgfSkKICAgIHB1c2hieXRlcyAiZ2xvYmFsX2J5dGVzX2V4cGxpY2l0IgogICAgYnl0ZWNfMCAvLyAiZHVtbXlfYnl0ZXMiCiAgICBhcHBfZ2xvYmFsX3B1dAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjM1NAogICAgLy8gZ2xvYmFsQXJjNEJ5dGVzID0gR2xvYmFsU3RhdGUoeyBrZXk6IEJ5dGVzKCdnbG9iYWxfYXJjNF9ieXRlcycpLCBpbml0aWFsVmFsdWU6IG5ldyBEeW5hbWljQnl0ZXMoJ2R1bW15X2FyYzRfYnl0ZXMnKSB9KQogICAgcHVzaGJ5dGVzICJnbG9iYWxfYXJjNF9ieXRlcyIKICAgIGJ5dGVjXzEgLy8gMHgwMDEwNjQ3NTZkNmQ3OTVmNjE3MjYzMzQ1ZjYyNzk3NDY1NzMKICAgIGFwcF9nbG9iYWxfcHV0CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MzU1CiAgICAvLyBnbG9iYWxfYXJjNF9ieXRlc19leHBsaWNpdCA9IEdsb2JhbFN0YXRlKHsgaW5pdGlhbFZhbHVlOiBuZXcgRHluYW1pY0J5dGVzKCdkdW1teV9hcmM0X2J5dGVzJykgfSkKICAgIHB1c2hieXRlcyAiZ2xvYmFsX2FyYzRfYnl0ZXNfZXhwbGljaXQiCiAgICBieXRlY18xIC8vIDB4MDAxMDY0NzU2ZDZkNzk1ZjYxNzI2MzM0NWY2Mjc5NzQ2NTczCiAgICBhcHBfZ2xvYmFsX3B1dAogICAgcmV0c3ViCgoKLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjpTdGF0ZUFwcEdsb2JhbEV4Q29udHJhY3QuX19wdXlhX2FyYzRfcm91dGVyX18oKSAtPiB1aW50NjQ6Cl9fcHV5YV9hcmM0X3JvdXRlcl9fOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjM0OQogICAgLy8gZXhwb3J0IGNsYXNzIFN0YXRlQXBwR2xvYmFsRXhDb250cmFjdCBleHRlbmRzIGFyYzQuQ29udHJhY3QgewogICAgcHJvdG8gMCAxCiAgICB0eG4gTnVtQXBwQXJncwogICAgYm56IF9fcHV5YV9hcmM0X3JvdXRlcl9fX2FmdGVyX2lmX2Vsc2VANgogICAgdHhuIE9uQ29tcGxldGlvbgogICAgYm56IF9fcHV5YV9hcmM0X3JvdXRlcl9fX2FmdGVyX2lmX2Vsc2VANgogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgICEKICAgIGFzc2VydCAvLyBjYW4gb25seSBjYWxsIHdoZW4gY3JlYXRpbmcKICAgIHB1c2hpbnQgMSAvLyAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX2FmdGVyX2lmX2Vsc2VANjoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czozNDkKICAgIC8vIGV4cG9ydCBjbGFzcyBTdGF0ZUFwcEdsb2JhbEV4Q29udHJhY3QgZXh0ZW5kcyBhcmM0LkNvbnRyYWN0IHsKICAgIHB1c2hpbnQgMCAvLyAwCiAgICByZXRzdWIK", - "clear": "I3ByYWdtYSB2ZXJzaW9uIDEwCgp0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OlN0YXRlQXBwR2xvYmFsRXhDb250cmFjdC5jbGVhclN0YXRlUHJvZ3JhbToKICAgIHB1c2hpbnQgMSAvLyAxCiAgICByZXR1cm4K" - }, - "state": { - "global": { - "num_byte_slices": 4, - "num_uints": 2 - }, - "local": { - "num_byte_slices": 0, - "num_uints": 0 - } - }, - "schema": { - "global": { - "declared": { - "globalArc4Bytes": { - "type": "bytes", - "key": "global_arc4_bytes" - }, - "globalBytes": { - "type": "bytes", - "key": "global_bytes" - }, - "globalUint64": { - "type": "uint64", - "key": "global_uint64" - }, - "global_arc4_bytes_explicit": { - "type": "bytes", - "key": "global_arc4_bytes_explicit" - }, - "global_bytes_explicit": { - "type": "bytes", - "key": "global_bytes_explicit" - }, - "global_uint64_explicit": { - "type": "uint64", - "key": "global_uint64_explicit" - } - }, - "reserved": {} - }, - "local": { - "declared": {}, - "reserved": {} - } - }, - "contract": { - "name": "StateAppGlobalExContract", - "methods": [], - "networks": {} - }, - "bare_call_config": { - "no_op": "CREATE" - } -} \ No newline at end of file diff --git a/tests/artifacts/state-ops/data/StateAppGlobalExContract.arc56.json b/tests/artifacts/state-ops/data/StateAppGlobalExContract.arc56.json deleted file mode 100644 index 2f5a1d0..0000000 --- a/tests/artifacts/state-ops/data/StateAppGlobalExContract.arc56.json +++ /dev/null @@ -1,92 +0,0 @@ -{ - "name": "StateAppGlobalExContract", - "structs": {}, - "methods": [], - "arcs": [ - 22, - 28 - ], - "networks": {}, - "state": { - "schema": { - "global": { - "ints": 2, - "bytes": 4 - }, - "local": { - "ints": 0, - "bytes": 0 - } - }, - "keys": { - "global": { - "globalUint64": { - "keyType": "AVMString", - "valueType": "AVMUint64", - "key": "Z2xvYmFsX3VpbnQ2NA==" - }, - "globalBytes": { - "keyType": "AVMString", - "valueType": "AVMBytes", - "key": "Z2xvYmFsX2J5dGVz" - }, - "global_uint64_explicit": { - "keyType": "AVMString", - "valueType": "AVMUint64", - "key": "Z2xvYmFsX3VpbnQ2NF9leHBsaWNpdA==" - }, - "global_bytes_explicit": { - "keyType": "AVMString", - "valueType": "AVMBytes", - "key": "Z2xvYmFsX2J5dGVzX2V4cGxpY2l0" - }, - "globalArc4Bytes": { - "keyType": "AVMString", - "valueType": "byte[]", - "key": "Z2xvYmFsX2FyYzRfYnl0ZXM=" - }, - "global_arc4_bytes_explicit": { - "keyType": "AVMString", - "valueType": "byte[]", - "key": "Z2xvYmFsX2FyYzRfYnl0ZXNfZXhwbGljaXQ=" - } - }, - "local": {}, - "box": {} - }, - "maps": { - "global": {}, - "local": {}, - "box": {} - } - }, - "bareActions": { - "create": [ - "NoOp" - ], - "call": [] - }, - "sourceInfo": { - "approval": { - "sourceInfo": [ - { - "pc": [ - 203 - ], - "errorMessage": "can only call when creating" - } - ], - "pcOffsetMethod": "none" - }, - "clear": { - "sourceInfo": [], - "pcOffsetMethod": "none" - } - }, - "source": { - "approval": "I3ByYWdtYSB2ZXJzaW9uIDEwCgp0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OlN0YXRlQXBwR2xvYmFsRXhDb250cmFjdC5hcHByb3ZhbFByb2dyYW06CiAgICBieXRlY2Jsb2NrICJkdW1teV9ieXRlcyIgMHgwMDEwNjQ3NTZkNmQ3OTVmNjE3MjYzMzQ1ZjYyNzk3NDY1NzMKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBibnogbWFpbl9hZnRlcl9pZl9lbHNlQDIKICAgIGNhbGxzdWIgY29uc3RydWN0b3IKCm1haW5fYWZ0ZXJfaWZfZWxzZUAyOgogICAgY2FsbHN1YiBfX3B1eWFfYXJjNF9yb3V0ZXJfXwogICAgcmV0dXJuCgoKLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjpTdGF0ZUFwcEdsb2JhbEV4Q29udHJhY3QuY29uc3RydWN0b3IoKSAtPiB2b2lkOgpjb25zdHJ1Y3RvcjoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czozNDkKICAgIC8vIGV4cG9ydCBjbGFzcyBTdGF0ZUFwcEdsb2JhbEV4Q29udHJhY3QgZXh0ZW5kcyBhcmM0LkNvbnRyYWN0IHsKICAgIHByb3RvIDAgMAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjM1MAogICAgLy8gZ2xvYmFsVWludDY0ID0gR2xvYmFsU3RhdGUoeyBrZXk6IEJ5dGVzKCdnbG9iYWxfdWludDY0JyksIGluaXRpYWxWYWx1ZTogVWludDY0KDIpIH0pCiAgICBwdXNoYnl0ZXMgImdsb2JhbF91aW50NjQiCiAgICBwdXNoaW50IDIgLy8gMgogICAgYXBwX2dsb2JhbF9wdXQKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czozNTEKICAgIC8vIGdsb2JhbEJ5dGVzID0gR2xvYmFsU3RhdGUoeyBrZXk6IEJ5dGVzKCdnbG9iYWxfYnl0ZXMnKSwgaW5pdGlhbFZhbHVlOiBCeXRlcygnZHVtbXlfYnl0ZXMnKSB9KQogICAgcHVzaGJ5dGVzICJnbG9iYWxfYnl0ZXMiCiAgICBieXRlY18wIC8vICJkdW1teV9ieXRlcyIKICAgIGFwcF9nbG9iYWxfcHV0CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MzUyCiAgICAvLyBnbG9iYWxfdWludDY0X2V4cGxpY2l0ID0gR2xvYmFsU3RhdGUoeyBpbml0aWFsVmFsdWU6IFVpbnQ2NCgyKSB9KQogICAgcHVzaGJ5dGVzICJnbG9iYWxfdWludDY0X2V4cGxpY2l0IgogICAgcHVzaGludCAyIC8vIDIKICAgIGFwcF9nbG9iYWxfcHV0CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MzUzCiAgICAvLyBnbG9iYWxfYnl0ZXNfZXhwbGljaXQgPSBHbG9iYWxTdGF0ZSh7IGluaXRpYWxWYWx1ZTogQnl0ZXMoJ2R1bW15X2J5dGVzJykgfSkKICAgIHB1c2hieXRlcyAiZ2xvYmFsX2J5dGVzX2V4cGxpY2l0IgogICAgYnl0ZWNfMCAvLyAiZHVtbXlfYnl0ZXMiCiAgICBhcHBfZ2xvYmFsX3B1dAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjM1NAogICAgLy8gZ2xvYmFsQXJjNEJ5dGVzID0gR2xvYmFsU3RhdGUoeyBrZXk6IEJ5dGVzKCdnbG9iYWxfYXJjNF9ieXRlcycpLCBpbml0aWFsVmFsdWU6IG5ldyBEeW5hbWljQnl0ZXMoJ2R1bW15X2FyYzRfYnl0ZXMnKSB9KQogICAgcHVzaGJ5dGVzICJnbG9iYWxfYXJjNF9ieXRlcyIKICAgIGJ5dGVjXzEgLy8gMHgwMDEwNjQ3NTZkNmQ3OTVmNjE3MjYzMzQ1ZjYyNzk3NDY1NzMKICAgIGFwcF9nbG9iYWxfcHV0CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MzU1CiAgICAvLyBnbG9iYWxfYXJjNF9ieXRlc19leHBsaWNpdCA9IEdsb2JhbFN0YXRlKHsgaW5pdGlhbFZhbHVlOiBuZXcgRHluYW1pY0J5dGVzKCdkdW1teV9hcmM0X2J5dGVzJykgfSkKICAgIHB1c2hieXRlcyAiZ2xvYmFsX2FyYzRfYnl0ZXNfZXhwbGljaXQiCiAgICBieXRlY18xIC8vIDB4MDAxMDY0NzU2ZDZkNzk1ZjYxNzI2MzM0NWY2Mjc5NzQ2NTczCiAgICBhcHBfZ2xvYmFsX3B1dAogICAgcmV0c3ViCgoKLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjpTdGF0ZUFwcEdsb2JhbEV4Q29udHJhY3QuX19wdXlhX2FyYzRfcm91dGVyX18oKSAtPiB1aW50NjQ6Cl9fcHV5YV9hcmM0X3JvdXRlcl9fOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjM0OQogICAgLy8gZXhwb3J0IGNsYXNzIFN0YXRlQXBwR2xvYmFsRXhDb250cmFjdCBleHRlbmRzIGFyYzQuQ29udHJhY3QgewogICAgcHJvdG8gMCAxCiAgICB0eG4gTnVtQXBwQXJncwogICAgYm56IF9fcHV5YV9hcmM0X3JvdXRlcl9fX2FmdGVyX2lmX2Vsc2VANgogICAgdHhuIE9uQ29tcGxldGlvbgogICAgYm56IF9fcHV5YV9hcmM0X3JvdXRlcl9fX2FmdGVyX2lmX2Vsc2VANgogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgICEKICAgIGFzc2VydCAvLyBjYW4gb25seSBjYWxsIHdoZW4gY3JlYXRpbmcKICAgIHB1c2hpbnQgMSAvLyAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX2FmdGVyX2lmX2Vsc2VANjoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czozNDkKICAgIC8vIGV4cG9ydCBjbGFzcyBTdGF0ZUFwcEdsb2JhbEV4Q29udHJhY3QgZXh0ZW5kcyBhcmM0LkNvbnRyYWN0IHsKICAgIHB1c2hpbnQgMCAvLyAwCiAgICByZXRzdWIK", - "clear": "I3ByYWdtYSB2ZXJzaW9uIDEwCgp0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OlN0YXRlQXBwR2xvYmFsRXhDb250cmFjdC5jbGVhclN0YXRlUHJvZ3JhbToKICAgIHB1c2hpbnQgMSAvLyAxCiAgICByZXR1cm4K" - }, - "events": [], - "templateVariables": {} -} \ No newline at end of file diff --git a/tests/artifacts/state-ops/data/StateAppGlobalExContract.clear.teal b/tests/artifacts/state-ops/data/StateAppGlobalExContract.clear.teal deleted file mode 100644 index c5063ae..0000000 --- a/tests/artifacts/state-ops/data/StateAppGlobalExContract.clear.teal +++ /dev/null @@ -1,5 +0,0 @@ -#pragma version 10 - -tests/artifacts/state-ops/contract.algo.ts::StateAppGlobalExContract.clearStateProgram: - pushint 1 // 1 - return diff --git a/tests/artifacts/state-ops/data/StateAppLocalContract.approval.teal b/tests/artifacts/state-ops/data/StateAppLocalContract.approval.teal deleted file mode 100644 index e9aa093..0000000 --- a/tests/artifacts/state-ops/data/StateAppLocalContract.approval.teal +++ /dev/null @@ -1,425 +0,0 @@ -#pragma version 10 - -tests/artifacts/state-ops/contract.algo.ts::StateAppLocalContract.approvalProgram: - intcblock 1 0 - bytecblock 0x151f7c75 - callsub __puya_arc4_router__ - return - - -// tests/artifacts/state-ops/contract.algo.ts::StateAppLocalContract.__puya_arc4_router__() -> uint64: -__puya_arc4_router__: - // tests/artifacts/state-ops/contract.algo.ts:413 - // export class StateAppLocalContract extends arc4.Contract { - proto 0 1 - txn NumAppArgs - bz __puya_arc4_router___bare_routing@13 - pushbytess 0x30c6d58a 0x937b5e13 0x8d742b86 0x7a6d0b59 0x594ff1d9 0x95a31727 0xaa1f4792 0x46245287 0x7f0fdfdd // method "opt_in()void", method "verify_get_bytes(account,byte[])byte[]", method "verify_get_uint64(account,byte[])uint64", method "verify_get_ex_bytes(account,application,byte[])byte[]", method "verify_get_ex_uint64(account,application,byte[])uint64", method "verify_delete(account,byte[])void", method "verify_exists(account,byte[])bool", method "verify_put_uint64(account,byte[],uint64)void", method "verify_put_bytes(account,byte[],byte[])void" - txna ApplicationArgs 0 - match __puya_arc4_router___opt_in_route@2 __puya_arc4_router___verify_get_bytes_route@3 __puya_arc4_router___verify_get_uint64_route@4 __puya_arc4_router___verify_get_ex_bytes_route@5 __puya_arc4_router___verify_get_ex_uint64_route@6 __puya_arc4_router___verify_delete_route@7 __puya_arc4_router___verify_exists_route@8 __puya_arc4_router___verify_put_uint64_route@9 __puya_arc4_router___verify_put_bytes_route@10 - intc_1 // 0 - retsub - -__puya_arc4_router___opt_in_route@2: - // tests/artifacts/state-ops/contract.algo.ts:417 - // @arc4.abimethod({ allowActions: ['OptIn'] }) - txn OnCompletion - intc_0 // OptIn - == - assert // OnCompletion is not OptIn - txn ApplicationID - assert // can only call when not creating - callsub opt_in - intc_0 // 1 - retsub - -__puya_arc4_router___verify_get_bytes_route@3: - // tests/artifacts/state-ops/contract.algo.ts:423 - // @arc4.abimethod() - txn OnCompletion - ! - assert // OnCompletion is not NoOp - txn ApplicationID - assert // can only call when not creating - // tests/artifacts/state-ops/contract.algo.ts:413 - // export class StateAppLocalContract extends arc4.Contract { - txna ApplicationArgs 1 - btoi - txnas Accounts - txna ApplicationArgs 2 - extract 2 0 - // tests/artifacts/state-ops/contract.algo.ts:423 - // @arc4.abimethod() - callsub verify_get_bytes - dup - len - itob - extract 6 2 - swap - concat - bytec_0 // 0x151f7c75 - swap - concat - log - intc_0 // 1 - retsub - -__puya_arc4_router___verify_get_uint64_route@4: - // tests/artifacts/state-ops/contract.algo.ts:429 - // @arc4.abimethod() - txn OnCompletion - ! - assert // OnCompletion is not NoOp - txn ApplicationID - assert // can only call when not creating - // tests/artifacts/state-ops/contract.algo.ts:413 - // export class StateAppLocalContract extends arc4.Contract { - txna ApplicationArgs 1 - btoi - txnas Accounts - txna ApplicationArgs 2 - extract 2 0 - // tests/artifacts/state-ops/contract.algo.ts:429 - // @arc4.abimethod() - callsub verify_get_uint64 - itob - bytec_0 // 0x151f7c75 - swap - concat - log - intc_0 // 1 - retsub - -__puya_arc4_router___verify_get_ex_bytes_route@5: - // tests/artifacts/state-ops/contract.algo.ts:435 - // @arc4.abimethod() - txn OnCompletion - ! - assert // OnCompletion is not NoOp - txn ApplicationID - assert // can only call when not creating - // tests/artifacts/state-ops/contract.algo.ts:413 - // export class StateAppLocalContract extends arc4.Contract { - txna ApplicationArgs 1 - btoi - txnas Accounts - txna ApplicationArgs 2 - btoi - txnas Applications - txna ApplicationArgs 3 - extract 2 0 - // tests/artifacts/state-ops/contract.algo.ts:435 - // @arc4.abimethod() - callsub verify_get_ex_bytes - dup - len - itob - extract 6 2 - swap - concat - bytec_0 // 0x151f7c75 - swap - concat - log - intc_0 // 1 - retsub - -__puya_arc4_router___verify_get_ex_uint64_route@6: - // tests/artifacts/state-ops/contract.algo.ts:441 - // @arc4.abimethod() - txn OnCompletion - ! - assert // OnCompletion is not NoOp - txn ApplicationID - assert // can only call when not creating - // tests/artifacts/state-ops/contract.algo.ts:413 - // export class StateAppLocalContract extends arc4.Contract { - txna ApplicationArgs 1 - btoi - txnas Accounts - txna ApplicationArgs 2 - btoi - txnas Applications - txna ApplicationArgs 3 - extract 2 0 - // tests/artifacts/state-ops/contract.algo.ts:441 - // @arc4.abimethod() - callsub verify_get_ex_uint64 - itob - bytec_0 // 0x151f7c75 - swap - concat - log - intc_0 // 1 - retsub - -__puya_arc4_router___verify_delete_route@7: - // tests/artifacts/state-ops/contract.algo.ts:447 - // @arc4.abimethod() - txn OnCompletion - ! - assert // OnCompletion is not NoOp - txn ApplicationID - assert // can only call when not creating - // tests/artifacts/state-ops/contract.algo.ts:413 - // export class StateAppLocalContract extends arc4.Contract { - txna ApplicationArgs 1 - btoi - txnas Accounts - txna ApplicationArgs 2 - extract 2 0 - // tests/artifacts/state-ops/contract.algo.ts:447 - // @arc4.abimethod() - callsub verify_delete - intc_0 // 1 - retsub - -__puya_arc4_router___verify_exists_route@8: - // tests/artifacts/state-ops/contract.algo.ts:452 - // @arc4.abimethod() - txn OnCompletion - ! - assert // OnCompletion is not NoOp - txn ApplicationID - assert // can only call when not creating - // tests/artifacts/state-ops/contract.algo.ts:413 - // export class StateAppLocalContract extends arc4.Contract { - txna ApplicationArgs 1 - btoi - txnas Accounts - txna ApplicationArgs 2 - extract 2 0 - // tests/artifacts/state-ops/contract.algo.ts:452 - // @arc4.abimethod() - callsub verify_exists - pushbytes 0x00 - intc_1 // 0 - uncover 2 - setbit - bytec_0 // 0x151f7c75 - swap - concat - log - intc_0 // 1 - retsub - -__puya_arc4_router___verify_put_uint64_route@9: - // tests/artifacts/state-ops/contract.algo.ts:458 - // @arc4.abimethod() - txn OnCompletion - ! - assert // OnCompletion is not NoOp - txn ApplicationID - assert // can only call when not creating - // tests/artifacts/state-ops/contract.algo.ts:413 - // export class StateAppLocalContract extends arc4.Contract { - txna ApplicationArgs 1 - btoi - txnas Accounts - txna ApplicationArgs 2 - extract 2 0 - txna ApplicationArgs 3 - btoi - // tests/artifacts/state-ops/contract.algo.ts:458 - // @arc4.abimethod() - callsub verify_put_uint64 - intc_0 // 1 - retsub - -__puya_arc4_router___verify_put_bytes_route@10: - // tests/artifacts/state-ops/contract.algo.ts:463 - // @arc4.abimethod() - txn OnCompletion - ! - assert // OnCompletion is not NoOp - txn ApplicationID - assert // can only call when not creating - // tests/artifacts/state-ops/contract.algo.ts:413 - // export class StateAppLocalContract extends arc4.Contract { - txna ApplicationArgs 1 - btoi - txnas Accounts - txna ApplicationArgs 2 - extract 2 0 - txna ApplicationArgs 3 - extract 2 0 - // tests/artifacts/state-ops/contract.algo.ts:463 - // @arc4.abimethod() - callsub verify_put_bytes - intc_0 // 1 - retsub - -__puya_arc4_router___bare_routing@13: - // tests/artifacts/state-ops/contract.algo.ts:413 - // export class StateAppLocalContract extends arc4.Contract { - txn OnCompletion - bnz __puya_arc4_router___after_if_else@17 - txn ApplicationID - ! - assert // can only call when creating - intc_0 // 1 - retsub - -__puya_arc4_router___after_if_else@17: - // tests/artifacts/state-ops/contract.algo.ts:413 - // export class StateAppLocalContract extends arc4.Contract { - intc_1 // 0 - retsub - - -// tests/artifacts/state-ops/contract.algo.ts::StateAppLocalContract.opt_in() -> void: -opt_in: - // tests/artifacts/state-ops/contract.algo.ts:417-418 - // @arc4.abimethod({ allowActions: ['OptIn'] }) - // opt_in() { - proto 0 0 - // tests/artifacts/state-ops/contract.algo.ts:419 - // this.localBytes(Global.creatorAddress).value = Bytes('dummy_bytes') - global CreatorAddress - // tests/artifacts/state-ops/contract.algo.ts:415 - // localBytes = LocalState({ key: 'local_bytes' }) - pushbytess "local_bytes" "dummy_bytes" // "local_bytes", "dummy_bytes" - // tests/artifacts/state-ops/contract.algo.ts:419 - // this.localBytes(Global.creatorAddress).value = Bytes('dummy_bytes') - app_local_put - // tests/artifacts/state-ops/contract.algo.ts:420 - // this.localUint64(Global.creatorAddress).value = Uint64(999) - global CreatorAddress - // tests/artifacts/state-ops/contract.algo.ts:414 - // localUint64 = LocalState({ key: 'local_uint64' }) - pushbytes "local_uint64" - // tests/artifacts/state-ops/contract.algo.ts:420 - // this.localUint64(Global.creatorAddress).value = Uint64(999) - pushint 999 // 999 - app_local_put - retsub - - -// tests/artifacts/state-ops/contract.algo.ts::StateAppLocalContract.verify_get_bytes(a: bytes, b: bytes) -> bytes: -verify_get_bytes: - // tests/artifacts/state-ops/contract.algo.ts:423-424 - // @arc4.abimethod() - // verify_get_bytes(a: Account, b: bytes): bytes { - proto 2 1 - // tests/artifacts/state-ops/contract.algo.ts:425 - // const value = op.AppLocal.getBytes(a, b) - frame_dig -2 - frame_dig -1 - app_local_get - // tests/artifacts/state-ops/contract.algo.ts:426 - // return value - retsub - - -// tests/artifacts/state-ops/contract.algo.ts::StateAppLocalContract.verify_get_uint64(a: bytes, b: bytes) -> uint64: -verify_get_uint64: - // tests/artifacts/state-ops/contract.algo.ts:429-430 - // @arc4.abimethod() - // verify_get_uint64(a: Account, b: bytes): uint64 { - proto 2 1 - // tests/artifacts/state-ops/contract.algo.ts:431 - // const value = op.AppLocal.getUint64(a, b) - frame_dig -2 - frame_dig -1 - app_local_get - // tests/artifacts/state-ops/contract.algo.ts:432 - // return value - retsub - - -// tests/artifacts/state-ops/contract.algo.ts::StateAppLocalContract.verify_get_ex_bytes(a: bytes, b: uint64, c: bytes) -> bytes: -verify_get_ex_bytes: - // tests/artifacts/state-ops/contract.algo.ts:435-436 - // @arc4.abimethod() - // verify_get_ex_bytes(a: Account, b: Application, c: bytes): bytes { - proto 3 1 - // tests/artifacts/state-ops/contract.algo.ts:437 - // const [value, _val] = op.AppLocal.getExBytes(a, b, c) - frame_dig -3 - frame_dig -2 - frame_dig -1 - app_local_get_ex - pop - // tests/artifacts/state-ops/contract.algo.ts:438 - // return value - retsub - - -// tests/artifacts/state-ops/contract.algo.ts::StateAppLocalContract.verify_get_ex_uint64(a: bytes, b: uint64, c: bytes) -> uint64: -verify_get_ex_uint64: - // tests/artifacts/state-ops/contract.algo.ts:441-442 - // @arc4.abimethod() - // verify_get_ex_uint64(a: Account, b: Application, c: bytes): uint64 { - proto 3 1 - // tests/artifacts/state-ops/contract.algo.ts:443 - // const [value, _val] = op.AppLocal.getExUint64(a, b, c) - frame_dig -3 - frame_dig -2 - frame_dig -1 - app_local_get_ex - pop - // tests/artifacts/state-ops/contract.algo.ts:444 - // return value - retsub - - -// tests/artifacts/state-ops/contract.algo.ts::StateAppLocalContract.verify_delete(a: bytes, b: bytes) -> void: -verify_delete: - // tests/artifacts/state-ops/contract.algo.ts:447-448 - // @arc4.abimethod() - // verify_delete(a: Account, b: bytes): void { - proto 2 0 - // tests/artifacts/state-ops/contract.algo.ts:449 - // op.AppLocal.delete(a, b) - frame_dig -2 - frame_dig -1 - app_local_del - retsub - - -// tests/artifacts/state-ops/contract.algo.ts::StateAppLocalContract.verify_exists(a: bytes, b: bytes) -> uint64: -verify_exists: - // tests/artifacts/state-ops/contract.algo.ts:452-453 - // @arc4.abimethod() - // verify_exists(a: Account, b: bytes): boolean { - proto 2 1 - // tests/artifacts/state-ops/contract.algo.ts:454 - // const [_value, exists] = op.AppLocal.getExUint64(a, 0, b) - frame_dig -2 - intc_1 // 0 - frame_dig -1 - app_local_get_ex - bury 1 - // tests/artifacts/state-ops/contract.algo.ts:455 - // return exists - retsub - - -// tests/artifacts/state-ops/contract.algo.ts::StateAppLocalContract.verify_put_uint64(a: bytes, b: bytes, c: uint64) -> void: -verify_put_uint64: - // tests/artifacts/state-ops/contract.algo.ts:458-459 - // @arc4.abimethod() - // verify_put_uint64(a: Account, b: bytes, c: uint64): void { - proto 3 0 - // tests/artifacts/state-ops/contract.algo.ts:460 - // op.AppLocal.put(a, b, c) - frame_dig -3 - frame_dig -2 - frame_dig -1 - app_local_put - retsub - - -// tests/artifacts/state-ops/contract.algo.ts::StateAppLocalContract.verify_put_bytes(a: bytes, b: bytes, c: bytes) -> void: -verify_put_bytes: - // tests/artifacts/state-ops/contract.algo.ts:463-464 - // @arc4.abimethod() - // verify_put_bytes(a: Account, b: bytes, c: bytes): void { - proto 3 0 - // tests/artifacts/state-ops/contract.algo.ts:465 - // op.AppLocal.put(a, b, c) - frame_dig -3 - frame_dig -2 - frame_dig -1 - app_local_put - retsub diff --git a/tests/artifacts/state-ops/data/StateAppLocalContract.arc32.json b/tests/artifacts/state-ops/data/StateAppLocalContract.arc32.json deleted file mode 100644 index 01fc23d..0000000 --- a/tests/artifacts/state-ops/data/StateAppLocalContract.arc32.json +++ /dev/null @@ -1,251 +0,0 @@ -{ - "hints": { - "opt_in()void": { - "call_config": { - "opt_in": "CALL" - } - }, - "verify_get_bytes(account,byte[])byte[]": { - "call_config": { - "no_op": "CALL" - } - }, - "verify_get_uint64(account,byte[])uint64": { - "call_config": { - "no_op": "CALL" - } - }, - "verify_get_ex_bytes(account,application,byte[])byte[]": { - "call_config": { - "no_op": "CALL" - } - }, - "verify_get_ex_uint64(account,application,byte[])uint64": { - "call_config": { - "no_op": "CALL" - } - }, - "verify_delete(account,byte[])void": { - "call_config": { - "no_op": "CALL" - } - }, - "verify_exists(account,byte[])bool": { - "call_config": { - "no_op": "CALL" - } - }, - "verify_put_uint64(account,byte[],uint64)void": { - "call_config": { - "no_op": "CALL" - } - }, - "verify_put_bytes(account,byte[],byte[])void": { - "call_config": { - "no_op": "CALL" - } - } - }, - "source": { - "approval": "I3ByYWdtYSB2ZXJzaW9uIDEwCgp0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OlN0YXRlQXBwTG9jYWxDb250cmFjdC5hcHByb3ZhbFByb2dyYW06CiAgICBpbnRjYmxvY2sgMSAwCiAgICBieXRlY2Jsb2NrIDB4MTUxZjdjNzUKICAgIGNhbGxzdWIgX19wdXlhX2FyYzRfcm91dGVyX18KICAgIHJldHVybgoKCi8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo6U3RhdGVBcHBMb2NhbENvbnRyYWN0Ll9fcHV5YV9hcmM0X3JvdXRlcl9fKCkgLT4gdWludDY0OgpfX3B1eWFfYXJjNF9yb3V0ZXJfXzoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo0MTMKICAgIC8vIGV4cG9ydCBjbGFzcyBTdGF0ZUFwcExvY2FsQ29udHJhY3QgZXh0ZW5kcyBhcmM0LkNvbnRyYWN0IHsKICAgIHByb3RvIDAgMQogICAgdHhuIE51bUFwcEFyZ3MKICAgIGJ6IF9fcHV5YV9hcmM0X3JvdXRlcl9fX2JhcmVfcm91dGluZ0AxMwogICAgcHVzaGJ5dGVzcyAweDMwYzZkNThhIDB4OTM3YjVlMTMgMHg4ZDc0MmI4NiAweDdhNmQwYjU5IDB4NTk0ZmYxZDkgMHg5NWEzMTcyNyAweGFhMWY0NzkyIDB4NDYyNDUyODcgMHg3ZjBmZGZkZCAvLyBtZXRob2QgIm9wdF9pbigpdm9pZCIsIG1ldGhvZCAidmVyaWZ5X2dldF9ieXRlcyhhY2NvdW50LGJ5dGVbXSlieXRlW10iLCBtZXRob2QgInZlcmlmeV9nZXRfdWludDY0KGFjY291bnQsYnl0ZVtdKXVpbnQ2NCIsIG1ldGhvZCAidmVyaWZ5X2dldF9leF9ieXRlcyhhY2NvdW50LGFwcGxpY2F0aW9uLGJ5dGVbXSlieXRlW10iLCBtZXRob2QgInZlcmlmeV9nZXRfZXhfdWludDY0KGFjY291bnQsYXBwbGljYXRpb24sYnl0ZVtdKXVpbnQ2NCIsIG1ldGhvZCAidmVyaWZ5X2RlbGV0ZShhY2NvdW50LGJ5dGVbXSl2b2lkIiwgbWV0aG9kICJ2ZXJpZnlfZXhpc3RzKGFjY291bnQsYnl0ZVtdKWJvb2wiLCBtZXRob2QgInZlcmlmeV9wdXRfdWludDY0KGFjY291bnQsYnl0ZVtdLHVpbnQ2NCl2b2lkIiwgbWV0aG9kICJ2ZXJpZnlfcHV0X2J5dGVzKGFjY291bnQsYnl0ZVtdLGJ5dGVbXSl2b2lkIgogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMAogICAgbWF0Y2ggX19wdXlhX2FyYzRfcm91dGVyX19fb3B0X2luX3JvdXRlQDIgX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2dldF9ieXRlc19yb3V0ZUAzIF9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9nZXRfdWludDY0X3JvdXRlQDQgX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2dldF9leF9ieXRlc19yb3V0ZUA1IF9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9nZXRfZXhfdWludDY0X3JvdXRlQDYgX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2RlbGV0ZV9yb3V0ZUA3IF9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9leGlzdHNfcm91dGVAOCBfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfcHV0X3VpbnQ2NF9yb3V0ZUA5IF9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9wdXRfYnl0ZXNfcm91dGVAMTAKICAgIGludGNfMSAvLyAwCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX29wdF9pbl9yb3V0ZUAyOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjQxNwogICAgLy8gQGFyYzQuYWJpbWV0aG9kKHsgYWxsb3dBY3Rpb25zOiBbJ09wdEluJ10gfSkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgIGludGNfMCAvLyBPcHRJbgogICAgPT0KICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgbm90IE9wdEluCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGNhbiBvbmx5IGNhbGwgd2hlbiBub3QgY3JlYXRpbmcKICAgIGNhbGxzdWIgb3B0X2luCiAgICBpbnRjXzAgLy8gMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfZ2V0X2J5dGVzX3JvdXRlQDM6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NDIzCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBub3QgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBjYW4gb25seSBjYWxsIHdoZW4gbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NDEzCiAgICAvLyBleHBvcnQgY2xhc3MgU3RhdGVBcHBMb2NhbENvbnRyYWN0IGV4dGVuZHMgYXJjNC5Db250cmFjdCB7CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBidG9pCiAgICB0eG5hcyBBY2NvdW50cwogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMgogICAgZXh0cmFjdCAyIDAKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo0MjMKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV9nZXRfYnl0ZXMKICAgIGR1cAogICAgbGVuCiAgICBpdG9iCiAgICBleHRyYWN0IDYgMgogICAgc3dhcAogICAgY29uY2F0CiAgICBieXRlY18wIC8vIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnRjXzAgLy8gMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfZ2V0X3VpbnQ2NF9yb3V0ZUA0OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjQyOQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgbm90IE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gY2FuIG9ubHkgY2FsbCB3aGVuIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjQxMwogICAgLy8gZXhwb3J0IGNsYXNzIFN0YXRlQXBwTG9jYWxDb250cmFjdCBleHRlbmRzIGFyYzQuQ29udHJhY3QgewogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgYnRvaQogICAgdHhuYXMgQWNjb3VudHMKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDIKICAgIGV4dHJhY3QgMiAwCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NDI5CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfZ2V0X3VpbnQ2NAogICAgaXRvYgogICAgYnl0ZWNfMCAvLyAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50Y18wIC8vIDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2dldF9leF9ieXRlc19yb3V0ZUA1OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjQzNQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgbm90IE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gY2FuIG9ubHkgY2FsbCB3aGVuIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjQxMwogICAgLy8gZXhwb3J0IGNsYXNzIFN0YXRlQXBwTG9jYWxDb250cmFjdCBleHRlbmRzIGFyYzQuQ29udHJhY3QgewogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgYnRvaQogICAgdHhuYXMgQWNjb3VudHMKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDIKICAgIGJ0b2kKICAgIHR4bmFzIEFwcGxpY2F0aW9ucwogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMwogICAgZXh0cmFjdCAyIDAKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo0MzUKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV9nZXRfZXhfYnl0ZXMKICAgIGR1cAogICAgbGVuCiAgICBpdG9iCiAgICBleHRyYWN0IDYgMgogICAgc3dhcAogICAgY29uY2F0CiAgICBieXRlY18wIC8vIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnRjXzAgLy8gMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfZ2V0X2V4X3VpbnQ2NF9yb3V0ZUA2OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjQ0MQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgbm90IE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gY2FuIG9ubHkgY2FsbCB3aGVuIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjQxMwogICAgLy8gZXhwb3J0IGNsYXNzIFN0YXRlQXBwTG9jYWxDb250cmFjdCBleHRlbmRzIGFyYzQuQ29udHJhY3QgewogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgYnRvaQogICAgdHhuYXMgQWNjb3VudHMKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDIKICAgIGJ0b2kKICAgIHR4bmFzIEFwcGxpY2F0aW9ucwogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMwogICAgZXh0cmFjdCAyIDAKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo0NDEKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV9nZXRfZXhfdWludDY0CiAgICBpdG9iCiAgICBieXRlY18wIC8vIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnRjXzAgLy8gMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfZGVsZXRlX3JvdXRlQDc6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NDQ3CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBub3QgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBjYW4gb25seSBjYWxsIHdoZW4gbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NDEzCiAgICAvLyBleHBvcnQgY2xhc3MgU3RhdGVBcHBMb2NhbENvbnRyYWN0IGV4dGVuZHMgYXJjNC5Db250cmFjdCB7CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBidG9pCiAgICB0eG5hcyBBY2NvdW50cwogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMgogICAgZXh0cmFjdCAyIDAKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo0NDcKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV9kZWxldGUKICAgIGludGNfMCAvLyAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9leGlzdHNfcm91dGVAODoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo0NTIKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIG5vdCBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGNhbiBvbmx5IGNhbGwgd2hlbiBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo0MTMKICAgIC8vIGV4cG9ydCBjbGFzcyBTdGF0ZUFwcExvY2FsQ29udHJhY3QgZXh0ZW5kcyBhcmM0LkNvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGJ0b2kKICAgIHR4bmFzIEFjY291bnRzCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAyCiAgICBleHRyYWN0IDIgMAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjQ1MgogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X2V4aXN0cwogICAgcHVzaGJ5dGVzIDB4MDAKICAgIGludGNfMSAvLyAwCiAgICB1bmNvdmVyIDIKICAgIHNldGJpdAogICAgYnl0ZWNfMCAvLyAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50Y18wIC8vIDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X3B1dF91aW50NjRfcm91dGVAOToKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo0NTgKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIG5vdCBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGNhbiBvbmx5IGNhbGwgd2hlbiBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo0MTMKICAgIC8vIGV4cG9ydCBjbGFzcyBTdGF0ZUFwcExvY2FsQ29udHJhY3QgZXh0ZW5kcyBhcmM0LkNvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGJ0b2kKICAgIHR4bmFzIEFjY291bnRzCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAyCiAgICBleHRyYWN0IDIgMAogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMwogICAgYnRvaQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjQ1OAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X3B1dF91aW50NjQKICAgIGludGNfMCAvLyAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9wdXRfYnl0ZXNfcm91dGVAMTA6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NDYzCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBub3QgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBjYW4gb25seSBjYWxsIHdoZW4gbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NDEzCiAgICAvLyBleHBvcnQgY2xhc3MgU3RhdGVBcHBMb2NhbENvbnRyYWN0IGV4dGVuZHMgYXJjNC5Db250cmFjdCB7CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBidG9pCiAgICB0eG5hcyBBY2NvdW50cwogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMgogICAgZXh0cmFjdCAyIDAKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDMKICAgIGV4dHJhY3QgMiAwCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NDYzCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfcHV0X2J5dGVzCiAgICBpbnRjXzAgLy8gMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX19iYXJlX3JvdXRpbmdAMTM6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NDEzCiAgICAvLyBleHBvcnQgY2xhc3MgU3RhdGVBcHBMb2NhbENvbnRyYWN0IGV4dGVuZHMgYXJjNC5Db250cmFjdCB7CiAgICB0eG4gT25Db21wbGV0aW9uCiAgICBibnogX19wdXlhX2FyYzRfcm91dGVyX19fYWZ0ZXJfaWZfZWxzZUAxNwogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgICEKICAgIGFzc2VydCAvLyBjYW4gb25seSBjYWxsIHdoZW4gY3JlYXRpbmcKICAgIGludGNfMCAvLyAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX2FmdGVyX2lmX2Vsc2VAMTc6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NDEzCiAgICAvLyBleHBvcnQgY2xhc3MgU3RhdGVBcHBMb2NhbENvbnRyYWN0IGV4dGVuZHMgYXJjNC5Db250cmFjdCB7CiAgICBpbnRjXzEgLy8gMAogICAgcmV0c3ViCgoKLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjpTdGF0ZUFwcExvY2FsQ29udHJhY3Qub3B0X2luKCkgLT4gdm9pZDoKb3B0X2luOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjQxNy00MTgKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCh7IGFsbG93QWN0aW9uczogWydPcHRJbiddIH0pCiAgICAvLyBvcHRfaW4oKSB7CiAgICBwcm90byAwIDAKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo0MTkKICAgIC8vIHRoaXMubG9jYWxCeXRlcyhHbG9iYWwuY3JlYXRvckFkZHJlc3MpLnZhbHVlID0gQnl0ZXMoJ2R1bW15X2J5dGVzJykKICAgIGdsb2JhbCBDcmVhdG9yQWRkcmVzcwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjQxNQogICAgLy8gbG9jYWxCeXRlcyA9IExvY2FsU3RhdGU8Ynl0ZXM+KHsga2V5OiAnbG9jYWxfYnl0ZXMnIH0pCiAgICBwdXNoYnl0ZXNzICJsb2NhbF9ieXRlcyIgImR1bW15X2J5dGVzIiAvLyAibG9jYWxfYnl0ZXMiLCAiZHVtbXlfYnl0ZXMiCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NDE5CiAgICAvLyB0aGlzLmxvY2FsQnl0ZXMoR2xvYmFsLmNyZWF0b3JBZGRyZXNzKS52YWx1ZSA9IEJ5dGVzKCdkdW1teV9ieXRlcycpCiAgICBhcHBfbG9jYWxfcHV0CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NDIwCiAgICAvLyB0aGlzLmxvY2FsVWludDY0KEdsb2JhbC5jcmVhdG9yQWRkcmVzcykudmFsdWUgPSBVaW50NjQoOTk5KQogICAgZ2xvYmFsIENyZWF0b3JBZGRyZXNzCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NDE0CiAgICAvLyBsb2NhbFVpbnQ2NCA9IExvY2FsU3RhdGU8dWludDY0Pih7IGtleTogJ2xvY2FsX3VpbnQ2NCcgfSkKICAgIHB1c2hieXRlcyAibG9jYWxfdWludDY0IgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjQyMAogICAgLy8gdGhpcy5sb2NhbFVpbnQ2NChHbG9iYWwuY3JlYXRvckFkZHJlc3MpLnZhbHVlID0gVWludDY0KDk5OSkKICAgIHB1c2hpbnQgOTk5IC8vIDk5OQogICAgYXBwX2xvY2FsX3B1dAogICAgcmV0c3ViCgoKLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjpTdGF0ZUFwcExvY2FsQ29udHJhY3QudmVyaWZ5X2dldF9ieXRlcyhhOiBieXRlcywgYjogYnl0ZXMpIC0+IGJ5dGVzOgp2ZXJpZnlfZ2V0X2J5dGVzOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjQyMy00MjQKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyB2ZXJpZnlfZ2V0X2J5dGVzKGE6IEFjY291bnQsIGI6IGJ5dGVzKTogYnl0ZXMgewogICAgcHJvdG8gMiAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NDI1CiAgICAvLyBjb25zdCB2YWx1ZSA9IG9wLkFwcExvY2FsLmdldEJ5dGVzKGEsIGIpCiAgICBmcmFtZV9kaWcgLTIKICAgIGZyYW1lX2RpZyAtMQogICAgYXBwX2xvY2FsX2dldAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjQyNgogICAgLy8gcmV0dXJuIHZhbHVlCiAgICByZXRzdWIKCgovLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OlN0YXRlQXBwTG9jYWxDb250cmFjdC52ZXJpZnlfZ2V0X3VpbnQ2NChhOiBieXRlcywgYjogYnl0ZXMpIC0+IHVpbnQ2NDoKdmVyaWZ5X2dldF91aW50NjQ6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NDI5LTQzMAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIHZlcmlmeV9nZXRfdWludDY0KGE6IEFjY291bnQsIGI6IGJ5dGVzKTogdWludDY0IHsKICAgIHByb3RvIDIgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjQzMQogICAgLy8gY29uc3QgdmFsdWUgPSBvcC5BcHBMb2NhbC5nZXRVaW50NjQoYSwgYikKICAgIGZyYW1lX2RpZyAtMgogICAgZnJhbWVfZGlnIC0xCiAgICBhcHBfbG9jYWxfZ2V0CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NDMyCiAgICAvLyByZXR1cm4gdmFsdWUKICAgIHJldHN1YgoKCi8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo6U3RhdGVBcHBMb2NhbENvbnRyYWN0LnZlcmlmeV9nZXRfZXhfYnl0ZXMoYTogYnl0ZXMsIGI6IHVpbnQ2NCwgYzogYnl0ZXMpIC0+IGJ5dGVzOgp2ZXJpZnlfZ2V0X2V4X2J5dGVzOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjQzNS00MzYKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyB2ZXJpZnlfZ2V0X2V4X2J5dGVzKGE6IEFjY291bnQsIGI6IEFwcGxpY2F0aW9uLCBjOiBieXRlcyk6IGJ5dGVzIHsKICAgIHByb3RvIDMgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjQzNwogICAgLy8gY29uc3QgW3ZhbHVlLCBfdmFsXSA9IG9wLkFwcExvY2FsLmdldEV4Qnl0ZXMoYSwgYiwgYykKICAgIGZyYW1lX2RpZyAtMwogICAgZnJhbWVfZGlnIC0yCiAgICBmcmFtZV9kaWcgLTEKICAgIGFwcF9sb2NhbF9nZXRfZXgKICAgIHBvcAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjQzOAogICAgLy8gcmV0dXJuIHZhbHVlCiAgICByZXRzdWIKCgovLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OlN0YXRlQXBwTG9jYWxDb250cmFjdC52ZXJpZnlfZ2V0X2V4X3VpbnQ2NChhOiBieXRlcywgYjogdWludDY0LCBjOiBieXRlcykgLT4gdWludDY0Ogp2ZXJpZnlfZ2V0X2V4X3VpbnQ2NDoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo0NDEtNDQyCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gdmVyaWZ5X2dldF9leF91aW50NjQoYTogQWNjb3VudCwgYjogQXBwbGljYXRpb24sIGM6IGJ5dGVzKTogdWludDY0IHsKICAgIHByb3RvIDMgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjQ0MwogICAgLy8gY29uc3QgW3ZhbHVlLCBfdmFsXSA9IG9wLkFwcExvY2FsLmdldEV4VWludDY0KGEsIGIsIGMpCiAgICBmcmFtZV9kaWcgLTMKICAgIGZyYW1lX2RpZyAtMgogICAgZnJhbWVfZGlnIC0xCiAgICBhcHBfbG9jYWxfZ2V0X2V4CiAgICBwb3AKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo0NDQKICAgIC8vIHJldHVybiB2YWx1ZQogICAgcmV0c3ViCgoKLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjpTdGF0ZUFwcExvY2FsQ29udHJhY3QudmVyaWZ5X2RlbGV0ZShhOiBieXRlcywgYjogYnl0ZXMpIC0+IHZvaWQ6CnZlcmlmeV9kZWxldGU6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NDQ3LTQ0OAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIHZlcmlmeV9kZWxldGUoYTogQWNjb3VudCwgYjogYnl0ZXMpOiB2b2lkIHsKICAgIHByb3RvIDIgMAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjQ0OQogICAgLy8gb3AuQXBwTG9jYWwuZGVsZXRlKGEsIGIpCiAgICBmcmFtZV9kaWcgLTIKICAgIGZyYW1lX2RpZyAtMQogICAgYXBwX2xvY2FsX2RlbAogICAgcmV0c3ViCgoKLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjpTdGF0ZUFwcExvY2FsQ29udHJhY3QudmVyaWZ5X2V4aXN0cyhhOiBieXRlcywgYjogYnl0ZXMpIC0+IHVpbnQ2NDoKdmVyaWZ5X2V4aXN0czoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo0NTItNDUzCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gdmVyaWZ5X2V4aXN0cyhhOiBBY2NvdW50LCBiOiBieXRlcyk6IGJvb2xlYW4gewogICAgcHJvdG8gMiAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NDU0CiAgICAvLyBjb25zdCBbX3ZhbHVlLCBleGlzdHNdID0gb3AuQXBwTG9jYWwuZ2V0RXhVaW50NjQoYSwgMCwgYikKICAgIGZyYW1lX2RpZyAtMgogICAgaW50Y18xIC8vIDAKICAgIGZyYW1lX2RpZyAtMQogICAgYXBwX2xvY2FsX2dldF9leAogICAgYnVyeSAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NDU1CiAgICAvLyByZXR1cm4gZXhpc3RzCiAgICByZXRzdWIKCgovLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OlN0YXRlQXBwTG9jYWxDb250cmFjdC52ZXJpZnlfcHV0X3VpbnQ2NChhOiBieXRlcywgYjogYnl0ZXMsIGM6IHVpbnQ2NCkgLT4gdm9pZDoKdmVyaWZ5X3B1dF91aW50NjQ6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NDU4LTQ1OQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIHZlcmlmeV9wdXRfdWludDY0KGE6IEFjY291bnQsIGI6IGJ5dGVzLCBjOiB1aW50NjQpOiB2b2lkIHsKICAgIHByb3RvIDMgMAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjQ2MAogICAgLy8gb3AuQXBwTG9jYWwucHV0KGEsIGIsIGMpCiAgICBmcmFtZV9kaWcgLTMKICAgIGZyYW1lX2RpZyAtMgogICAgZnJhbWVfZGlnIC0xCiAgICBhcHBfbG9jYWxfcHV0CiAgICByZXRzdWIKCgovLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OlN0YXRlQXBwTG9jYWxDb250cmFjdC52ZXJpZnlfcHV0X2J5dGVzKGE6IGJ5dGVzLCBiOiBieXRlcywgYzogYnl0ZXMpIC0+IHZvaWQ6CnZlcmlmeV9wdXRfYnl0ZXM6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NDYzLTQ2NAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIHZlcmlmeV9wdXRfYnl0ZXMoYTogQWNjb3VudCwgYjogYnl0ZXMsIGM6IGJ5dGVzKTogdm9pZCB7CiAgICBwcm90byAzIDAKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo0NjUKICAgIC8vIG9wLkFwcExvY2FsLnB1dChhLCBiLCBjKQogICAgZnJhbWVfZGlnIC0zCiAgICBmcmFtZV9kaWcgLTIKICAgIGZyYW1lX2RpZyAtMQogICAgYXBwX2xvY2FsX3B1dAogICAgcmV0c3ViCg==", - "clear": "I3ByYWdtYSB2ZXJzaW9uIDEwCgp0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OlN0YXRlQXBwTG9jYWxDb250cmFjdC5jbGVhclN0YXRlUHJvZ3JhbToKICAgIHB1c2hpbnQgMSAvLyAxCiAgICByZXR1cm4K" - }, - "state": { - "global": { - "num_byte_slices": 0, - "num_uints": 0 - }, - "local": { - "num_byte_slices": 1, - "num_uints": 1 - } - }, - "schema": { - "global": { - "declared": {}, - "reserved": {} - }, - "local": { - "declared": { - "localBytes": { - "type": "bytes", - "key": "local_bytes" - }, - "localUint64": { - "type": "uint64", - "key": "local_uint64" - } - }, - "reserved": {} - } - }, - "contract": { - "name": "StateAppLocalContract", - "methods": [ - { - "name": "opt_in", - "args": [], - "readonly": false, - "returns": { - "type": "void" - } - }, - { - "name": "verify_get_bytes", - "args": [ - { - "type": "account", - "name": "a" - }, - { - "type": "byte[]", - "name": "b" - } - ], - "readonly": false, - "returns": { - "type": "byte[]" - } - }, - { - "name": "verify_get_uint64", - "args": [ - { - "type": "account", - "name": "a" - }, - { - "type": "byte[]", - "name": "b" - } - ], - "readonly": false, - "returns": { - "type": "uint64" - } - }, - { - "name": "verify_get_ex_bytes", - "args": [ - { - "type": "account", - "name": "a" - }, - { - "type": "application", - "name": "b" - }, - { - "type": "byte[]", - "name": "c" - } - ], - "readonly": false, - "returns": { - "type": "byte[]" - } - }, - { - "name": "verify_get_ex_uint64", - "args": [ - { - "type": "account", - "name": "a" - }, - { - "type": "application", - "name": "b" - }, - { - "type": "byte[]", - "name": "c" - } - ], - "readonly": false, - "returns": { - "type": "uint64" - } - }, - { - "name": "verify_delete", - "args": [ - { - "type": "account", - "name": "a" - }, - { - "type": "byte[]", - "name": "b" - } - ], - "readonly": false, - "returns": { - "type": "void" - } - }, - { - "name": "verify_exists", - "args": [ - { - "type": "account", - "name": "a" - }, - { - "type": "byte[]", - "name": "b" - } - ], - "readonly": false, - "returns": { - "type": "bool" - } - }, - { - "name": "verify_put_uint64", - "args": [ - { - "type": "account", - "name": "a" - }, - { - "type": "byte[]", - "name": "b" - }, - { - "type": "uint64", - "name": "c" - } - ], - "readonly": false, - "returns": { - "type": "void" - } - }, - { - "name": "verify_put_bytes", - "args": [ - { - "type": "account", - "name": "a" - }, - { - "type": "byte[]", - "name": "b" - }, - { - "type": "byte[]", - "name": "c" - } - ], - "readonly": false, - "returns": { - "type": "void" - } - } - ], - "networks": {} - }, - "bare_call_config": { - "no_op": "CREATE" - } -} \ No newline at end of file diff --git a/tests/artifacts/state-ops/data/StateAppLocalContract.arc56.json b/tests/artifacts/state-ops/data/StateAppLocalContract.arc56.json deleted file mode 100644 index 2b5b6a5..0000000 --- a/tests/artifacts/state-ops/data/StateAppLocalContract.arc56.json +++ /dev/null @@ -1,338 +0,0 @@ -{ - "name": "StateAppLocalContract", - "structs": {}, - "methods": [ - { - "name": "opt_in", - "args": [], - "returns": { - "type": "void" - }, - "actions": { - "create": [], - "call": [ - "OptIn" - ] - }, - "readonly": false, - "events": [], - "recommendations": {} - }, - { - "name": "verify_get_bytes", - "args": [ - { - "type": "account", - "name": "a" - }, - { - "type": "byte[]", - "name": "b" - } - ], - "returns": { - "type": "byte[]" - }, - "actions": { - "create": [], - "call": [ - "NoOp" - ] - }, - "readonly": false, - "events": [], - "recommendations": {} - }, - { - "name": "verify_get_uint64", - "args": [ - { - "type": "account", - "name": "a" - }, - { - "type": "byte[]", - "name": "b" - } - ], - "returns": { - "type": "uint64" - }, - "actions": { - "create": [], - "call": [ - "NoOp" - ] - }, - "readonly": false, - "events": [], - "recommendations": {} - }, - { - "name": "verify_get_ex_bytes", - "args": [ - { - "type": "account", - "name": "a" - }, - { - "type": "application", - "name": "b" - }, - { - "type": "byte[]", - "name": "c" - } - ], - "returns": { - "type": "byte[]" - }, - "actions": { - "create": [], - "call": [ - "NoOp" - ] - }, - "readonly": false, - "events": [], - "recommendations": {} - }, - { - "name": "verify_get_ex_uint64", - "args": [ - { - "type": "account", - "name": "a" - }, - { - "type": "application", - "name": "b" - }, - { - "type": "byte[]", - "name": "c" - } - ], - "returns": { - "type": "uint64" - }, - "actions": { - "create": [], - "call": [ - "NoOp" - ] - }, - "readonly": false, - "events": [], - "recommendations": {} - }, - { - "name": "verify_delete", - "args": [ - { - "type": "account", - "name": "a" - }, - { - "type": "byte[]", - "name": "b" - } - ], - "returns": { - "type": "void" - }, - "actions": { - "create": [], - "call": [ - "NoOp" - ] - }, - "readonly": false, - "events": [], - "recommendations": {} - }, - { - "name": "verify_exists", - "args": [ - { - "type": "account", - "name": "a" - }, - { - "type": "byte[]", - "name": "b" - } - ], - "returns": { - "type": "bool" - }, - "actions": { - "create": [], - "call": [ - "NoOp" - ] - }, - "readonly": false, - "events": [], - "recommendations": {} - }, - { - "name": "verify_put_uint64", - "args": [ - { - "type": "account", - "name": "a" - }, - { - "type": "byte[]", - "name": "b" - }, - { - "type": "uint64", - "name": "c" - } - ], - "returns": { - "type": "void" - }, - "actions": { - "create": [], - "call": [ - "NoOp" - ] - }, - "readonly": false, - "events": [], - "recommendations": {} - }, - { - "name": "verify_put_bytes", - "args": [ - { - "type": "account", - "name": "a" - }, - { - "type": "byte[]", - "name": "b" - }, - { - "type": "byte[]", - "name": "c" - } - ], - "returns": { - "type": "void" - }, - "actions": { - "create": [], - "call": [ - "NoOp" - ] - }, - "readonly": false, - "events": [], - "recommendations": {} - } - ], - "arcs": [ - 22, - 28 - ], - "networks": {}, - "state": { - "schema": { - "global": { - "ints": 0, - "bytes": 0 - }, - "local": { - "ints": 1, - "bytes": 1 - } - }, - "keys": { - "global": {}, - "local": { - "localUint64": { - "keyType": "AVMString", - "valueType": "AVMUint64", - "key": "bG9jYWxfdWludDY0" - }, - "localBytes": { - "keyType": "AVMString", - "valueType": "AVMBytes", - "key": "bG9jYWxfYnl0ZXM=" - } - }, - "box": {} - }, - "maps": { - "global": {}, - "local": {}, - "box": {} - } - }, - "bareActions": { - "create": [ - "NoOp" - ], - "call": [] - }, - "sourceInfo": { - "approval": { - "sourceInfo": [ - { - "pc": [ - 112, - 148, - 177, - 219, - 254, - 278, - 313, - 341 - ], - "errorMessage": "OnCompletion is not NoOp" - }, - { - "pc": [ - 100 - ], - "errorMessage": "OnCompletion is not OptIn" - }, - { - "pc": [ - 376 - ], - "errorMessage": "can only call when creating" - }, - { - "pc": [ - 103, - 115, - 151, - 180, - 222, - 257, - 281, - 316, - 344 - ], - "errorMessage": "can only call when not creating" - } - ], - "pcOffsetMethod": "none" - }, - "clear": { - "sourceInfo": [], - "pcOffsetMethod": "none" - } - }, - "source": { - "approval": "I3ByYWdtYSB2ZXJzaW9uIDEwCgp0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OlN0YXRlQXBwTG9jYWxDb250cmFjdC5hcHByb3ZhbFByb2dyYW06CiAgICBpbnRjYmxvY2sgMSAwCiAgICBieXRlY2Jsb2NrIDB4MTUxZjdjNzUKICAgIGNhbGxzdWIgX19wdXlhX2FyYzRfcm91dGVyX18KICAgIHJldHVybgoKCi8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo6U3RhdGVBcHBMb2NhbENvbnRyYWN0Ll9fcHV5YV9hcmM0X3JvdXRlcl9fKCkgLT4gdWludDY0OgpfX3B1eWFfYXJjNF9yb3V0ZXJfXzoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo0MTMKICAgIC8vIGV4cG9ydCBjbGFzcyBTdGF0ZUFwcExvY2FsQ29udHJhY3QgZXh0ZW5kcyBhcmM0LkNvbnRyYWN0IHsKICAgIHByb3RvIDAgMQogICAgdHhuIE51bUFwcEFyZ3MKICAgIGJ6IF9fcHV5YV9hcmM0X3JvdXRlcl9fX2JhcmVfcm91dGluZ0AxMwogICAgcHVzaGJ5dGVzcyAweDMwYzZkNThhIDB4OTM3YjVlMTMgMHg4ZDc0MmI4NiAweDdhNmQwYjU5IDB4NTk0ZmYxZDkgMHg5NWEzMTcyNyAweGFhMWY0NzkyIDB4NDYyNDUyODcgMHg3ZjBmZGZkZCAvLyBtZXRob2QgIm9wdF9pbigpdm9pZCIsIG1ldGhvZCAidmVyaWZ5X2dldF9ieXRlcyhhY2NvdW50LGJ5dGVbXSlieXRlW10iLCBtZXRob2QgInZlcmlmeV9nZXRfdWludDY0KGFjY291bnQsYnl0ZVtdKXVpbnQ2NCIsIG1ldGhvZCAidmVyaWZ5X2dldF9leF9ieXRlcyhhY2NvdW50LGFwcGxpY2F0aW9uLGJ5dGVbXSlieXRlW10iLCBtZXRob2QgInZlcmlmeV9nZXRfZXhfdWludDY0KGFjY291bnQsYXBwbGljYXRpb24sYnl0ZVtdKXVpbnQ2NCIsIG1ldGhvZCAidmVyaWZ5X2RlbGV0ZShhY2NvdW50LGJ5dGVbXSl2b2lkIiwgbWV0aG9kICJ2ZXJpZnlfZXhpc3RzKGFjY291bnQsYnl0ZVtdKWJvb2wiLCBtZXRob2QgInZlcmlmeV9wdXRfdWludDY0KGFjY291bnQsYnl0ZVtdLHVpbnQ2NCl2b2lkIiwgbWV0aG9kICJ2ZXJpZnlfcHV0X2J5dGVzKGFjY291bnQsYnl0ZVtdLGJ5dGVbXSl2b2lkIgogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMAogICAgbWF0Y2ggX19wdXlhX2FyYzRfcm91dGVyX19fb3B0X2luX3JvdXRlQDIgX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2dldF9ieXRlc19yb3V0ZUAzIF9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9nZXRfdWludDY0X3JvdXRlQDQgX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2dldF9leF9ieXRlc19yb3V0ZUA1IF9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9nZXRfZXhfdWludDY0X3JvdXRlQDYgX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2RlbGV0ZV9yb3V0ZUA3IF9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9leGlzdHNfcm91dGVAOCBfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfcHV0X3VpbnQ2NF9yb3V0ZUA5IF9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9wdXRfYnl0ZXNfcm91dGVAMTAKICAgIGludGNfMSAvLyAwCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX29wdF9pbl9yb3V0ZUAyOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjQxNwogICAgLy8gQGFyYzQuYWJpbWV0aG9kKHsgYWxsb3dBY3Rpb25zOiBbJ09wdEluJ10gfSkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgIGludGNfMCAvLyBPcHRJbgogICAgPT0KICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgbm90IE9wdEluCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGNhbiBvbmx5IGNhbGwgd2hlbiBub3QgY3JlYXRpbmcKICAgIGNhbGxzdWIgb3B0X2luCiAgICBpbnRjXzAgLy8gMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfZ2V0X2J5dGVzX3JvdXRlQDM6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NDIzCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBub3QgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBjYW4gb25seSBjYWxsIHdoZW4gbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NDEzCiAgICAvLyBleHBvcnQgY2xhc3MgU3RhdGVBcHBMb2NhbENvbnRyYWN0IGV4dGVuZHMgYXJjNC5Db250cmFjdCB7CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBidG9pCiAgICB0eG5hcyBBY2NvdW50cwogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMgogICAgZXh0cmFjdCAyIDAKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo0MjMKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV9nZXRfYnl0ZXMKICAgIGR1cAogICAgbGVuCiAgICBpdG9iCiAgICBleHRyYWN0IDYgMgogICAgc3dhcAogICAgY29uY2F0CiAgICBieXRlY18wIC8vIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnRjXzAgLy8gMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfZ2V0X3VpbnQ2NF9yb3V0ZUA0OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjQyOQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgbm90IE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gY2FuIG9ubHkgY2FsbCB3aGVuIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjQxMwogICAgLy8gZXhwb3J0IGNsYXNzIFN0YXRlQXBwTG9jYWxDb250cmFjdCBleHRlbmRzIGFyYzQuQ29udHJhY3QgewogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgYnRvaQogICAgdHhuYXMgQWNjb3VudHMKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDIKICAgIGV4dHJhY3QgMiAwCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NDI5CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfZ2V0X3VpbnQ2NAogICAgaXRvYgogICAgYnl0ZWNfMCAvLyAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50Y18wIC8vIDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2dldF9leF9ieXRlc19yb3V0ZUA1OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjQzNQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgbm90IE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gY2FuIG9ubHkgY2FsbCB3aGVuIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjQxMwogICAgLy8gZXhwb3J0IGNsYXNzIFN0YXRlQXBwTG9jYWxDb250cmFjdCBleHRlbmRzIGFyYzQuQ29udHJhY3QgewogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgYnRvaQogICAgdHhuYXMgQWNjb3VudHMKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDIKICAgIGJ0b2kKICAgIHR4bmFzIEFwcGxpY2F0aW9ucwogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMwogICAgZXh0cmFjdCAyIDAKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo0MzUKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV9nZXRfZXhfYnl0ZXMKICAgIGR1cAogICAgbGVuCiAgICBpdG9iCiAgICBleHRyYWN0IDYgMgogICAgc3dhcAogICAgY29uY2F0CiAgICBieXRlY18wIC8vIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnRjXzAgLy8gMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfZ2V0X2V4X3VpbnQ2NF9yb3V0ZUA2OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjQ0MQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgbm90IE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gY2FuIG9ubHkgY2FsbCB3aGVuIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjQxMwogICAgLy8gZXhwb3J0IGNsYXNzIFN0YXRlQXBwTG9jYWxDb250cmFjdCBleHRlbmRzIGFyYzQuQ29udHJhY3QgewogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgYnRvaQogICAgdHhuYXMgQWNjb3VudHMKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDIKICAgIGJ0b2kKICAgIHR4bmFzIEFwcGxpY2F0aW9ucwogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMwogICAgZXh0cmFjdCAyIDAKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo0NDEKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV9nZXRfZXhfdWludDY0CiAgICBpdG9iCiAgICBieXRlY18wIC8vIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnRjXzAgLy8gMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfZGVsZXRlX3JvdXRlQDc6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NDQ3CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBub3QgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBjYW4gb25seSBjYWxsIHdoZW4gbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NDEzCiAgICAvLyBleHBvcnQgY2xhc3MgU3RhdGVBcHBMb2NhbENvbnRyYWN0IGV4dGVuZHMgYXJjNC5Db250cmFjdCB7CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBidG9pCiAgICB0eG5hcyBBY2NvdW50cwogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMgogICAgZXh0cmFjdCAyIDAKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo0NDcKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV9kZWxldGUKICAgIGludGNfMCAvLyAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9leGlzdHNfcm91dGVAODoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo0NTIKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIG5vdCBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGNhbiBvbmx5IGNhbGwgd2hlbiBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo0MTMKICAgIC8vIGV4cG9ydCBjbGFzcyBTdGF0ZUFwcExvY2FsQ29udHJhY3QgZXh0ZW5kcyBhcmM0LkNvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGJ0b2kKICAgIHR4bmFzIEFjY291bnRzCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAyCiAgICBleHRyYWN0IDIgMAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjQ1MgogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X2V4aXN0cwogICAgcHVzaGJ5dGVzIDB4MDAKICAgIGludGNfMSAvLyAwCiAgICB1bmNvdmVyIDIKICAgIHNldGJpdAogICAgYnl0ZWNfMCAvLyAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50Y18wIC8vIDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X3B1dF91aW50NjRfcm91dGVAOToKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo0NTgKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIG5vdCBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGNhbiBvbmx5IGNhbGwgd2hlbiBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo0MTMKICAgIC8vIGV4cG9ydCBjbGFzcyBTdGF0ZUFwcExvY2FsQ29udHJhY3QgZXh0ZW5kcyBhcmM0LkNvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGJ0b2kKICAgIHR4bmFzIEFjY291bnRzCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAyCiAgICBleHRyYWN0IDIgMAogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMwogICAgYnRvaQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjQ1OAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X3B1dF91aW50NjQKICAgIGludGNfMCAvLyAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9wdXRfYnl0ZXNfcm91dGVAMTA6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NDYzCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBub3QgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBjYW4gb25seSBjYWxsIHdoZW4gbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NDEzCiAgICAvLyBleHBvcnQgY2xhc3MgU3RhdGVBcHBMb2NhbENvbnRyYWN0IGV4dGVuZHMgYXJjNC5Db250cmFjdCB7CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBidG9pCiAgICB0eG5hcyBBY2NvdW50cwogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMgogICAgZXh0cmFjdCAyIDAKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDMKICAgIGV4dHJhY3QgMiAwCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NDYzCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfcHV0X2J5dGVzCiAgICBpbnRjXzAgLy8gMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX19iYXJlX3JvdXRpbmdAMTM6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NDEzCiAgICAvLyBleHBvcnQgY2xhc3MgU3RhdGVBcHBMb2NhbENvbnRyYWN0IGV4dGVuZHMgYXJjNC5Db250cmFjdCB7CiAgICB0eG4gT25Db21wbGV0aW9uCiAgICBibnogX19wdXlhX2FyYzRfcm91dGVyX19fYWZ0ZXJfaWZfZWxzZUAxNwogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgICEKICAgIGFzc2VydCAvLyBjYW4gb25seSBjYWxsIHdoZW4gY3JlYXRpbmcKICAgIGludGNfMCAvLyAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX2FmdGVyX2lmX2Vsc2VAMTc6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NDEzCiAgICAvLyBleHBvcnQgY2xhc3MgU3RhdGVBcHBMb2NhbENvbnRyYWN0IGV4dGVuZHMgYXJjNC5Db250cmFjdCB7CiAgICBpbnRjXzEgLy8gMAogICAgcmV0c3ViCgoKLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjpTdGF0ZUFwcExvY2FsQ29udHJhY3Qub3B0X2luKCkgLT4gdm9pZDoKb3B0X2luOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjQxNy00MTgKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCh7IGFsbG93QWN0aW9uczogWydPcHRJbiddIH0pCiAgICAvLyBvcHRfaW4oKSB7CiAgICBwcm90byAwIDAKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo0MTkKICAgIC8vIHRoaXMubG9jYWxCeXRlcyhHbG9iYWwuY3JlYXRvckFkZHJlc3MpLnZhbHVlID0gQnl0ZXMoJ2R1bW15X2J5dGVzJykKICAgIGdsb2JhbCBDcmVhdG9yQWRkcmVzcwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjQxNQogICAgLy8gbG9jYWxCeXRlcyA9IExvY2FsU3RhdGU8Ynl0ZXM+KHsga2V5OiAnbG9jYWxfYnl0ZXMnIH0pCiAgICBwdXNoYnl0ZXNzICJsb2NhbF9ieXRlcyIgImR1bW15X2J5dGVzIiAvLyAibG9jYWxfYnl0ZXMiLCAiZHVtbXlfYnl0ZXMiCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NDE5CiAgICAvLyB0aGlzLmxvY2FsQnl0ZXMoR2xvYmFsLmNyZWF0b3JBZGRyZXNzKS52YWx1ZSA9IEJ5dGVzKCdkdW1teV9ieXRlcycpCiAgICBhcHBfbG9jYWxfcHV0CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NDIwCiAgICAvLyB0aGlzLmxvY2FsVWludDY0KEdsb2JhbC5jcmVhdG9yQWRkcmVzcykudmFsdWUgPSBVaW50NjQoOTk5KQogICAgZ2xvYmFsIENyZWF0b3JBZGRyZXNzCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NDE0CiAgICAvLyBsb2NhbFVpbnQ2NCA9IExvY2FsU3RhdGU8dWludDY0Pih7IGtleTogJ2xvY2FsX3VpbnQ2NCcgfSkKICAgIHB1c2hieXRlcyAibG9jYWxfdWludDY0IgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjQyMAogICAgLy8gdGhpcy5sb2NhbFVpbnQ2NChHbG9iYWwuY3JlYXRvckFkZHJlc3MpLnZhbHVlID0gVWludDY0KDk5OSkKICAgIHB1c2hpbnQgOTk5IC8vIDk5OQogICAgYXBwX2xvY2FsX3B1dAogICAgcmV0c3ViCgoKLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjpTdGF0ZUFwcExvY2FsQ29udHJhY3QudmVyaWZ5X2dldF9ieXRlcyhhOiBieXRlcywgYjogYnl0ZXMpIC0+IGJ5dGVzOgp2ZXJpZnlfZ2V0X2J5dGVzOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjQyMy00MjQKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyB2ZXJpZnlfZ2V0X2J5dGVzKGE6IEFjY291bnQsIGI6IGJ5dGVzKTogYnl0ZXMgewogICAgcHJvdG8gMiAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NDI1CiAgICAvLyBjb25zdCB2YWx1ZSA9IG9wLkFwcExvY2FsLmdldEJ5dGVzKGEsIGIpCiAgICBmcmFtZV9kaWcgLTIKICAgIGZyYW1lX2RpZyAtMQogICAgYXBwX2xvY2FsX2dldAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjQyNgogICAgLy8gcmV0dXJuIHZhbHVlCiAgICByZXRzdWIKCgovLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OlN0YXRlQXBwTG9jYWxDb250cmFjdC52ZXJpZnlfZ2V0X3VpbnQ2NChhOiBieXRlcywgYjogYnl0ZXMpIC0+IHVpbnQ2NDoKdmVyaWZ5X2dldF91aW50NjQ6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NDI5LTQzMAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIHZlcmlmeV9nZXRfdWludDY0KGE6IEFjY291bnQsIGI6IGJ5dGVzKTogdWludDY0IHsKICAgIHByb3RvIDIgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjQzMQogICAgLy8gY29uc3QgdmFsdWUgPSBvcC5BcHBMb2NhbC5nZXRVaW50NjQoYSwgYikKICAgIGZyYW1lX2RpZyAtMgogICAgZnJhbWVfZGlnIC0xCiAgICBhcHBfbG9jYWxfZ2V0CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NDMyCiAgICAvLyByZXR1cm4gdmFsdWUKICAgIHJldHN1YgoKCi8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo6U3RhdGVBcHBMb2NhbENvbnRyYWN0LnZlcmlmeV9nZXRfZXhfYnl0ZXMoYTogYnl0ZXMsIGI6IHVpbnQ2NCwgYzogYnl0ZXMpIC0+IGJ5dGVzOgp2ZXJpZnlfZ2V0X2V4X2J5dGVzOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjQzNS00MzYKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyB2ZXJpZnlfZ2V0X2V4X2J5dGVzKGE6IEFjY291bnQsIGI6IEFwcGxpY2F0aW9uLCBjOiBieXRlcyk6IGJ5dGVzIHsKICAgIHByb3RvIDMgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjQzNwogICAgLy8gY29uc3QgW3ZhbHVlLCBfdmFsXSA9IG9wLkFwcExvY2FsLmdldEV4Qnl0ZXMoYSwgYiwgYykKICAgIGZyYW1lX2RpZyAtMwogICAgZnJhbWVfZGlnIC0yCiAgICBmcmFtZV9kaWcgLTEKICAgIGFwcF9sb2NhbF9nZXRfZXgKICAgIHBvcAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjQzOAogICAgLy8gcmV0dXJuIHZhbHVlCiAgICByZXRzdWIKCgovLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OlN0YXRlQXBwTG9jYWxDb250cmFjdC52ZXJpZnlfZ2V0X2V4X3VpbnQ2NChhOiBieXRlcywgYjogdWludDY0LCBjOiBieXRlcykgLT4gdWludDY0Ogp2ZXJpZnlfZ2V0X2V4X3VpbnQ2NDoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo0NDEtNDQyCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gdmVyaWZ5X2dldF9leF91aW50NjQoYTogQWNjb3VudCwgYjogQXBwbGljYXRpb24sIGM6IGJ5dGVzKTogdWludDY0IHsKICAgIHByb3RvIDMgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjQ0MwogICAgLy8gY29uc3QgW3ZhbHVlLCBfdmFsXSA9IG9wLkFwcExvY2FsLmdldEV4VWludDY0KGEsIGIsIGMpCiAgICBmcmFtZV9kaWcgLTMKICAgIGZyYW1lX2RpZyAtMgogICAgZnJhbWVfZGlnIC0xCiAgICBhcHBfbG9jYWxfZ2V0X2V4CiAgICBwb3AKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo0NDQKICAgIC8vIHJldHVybiB2YWx1ZQogICAgcmV0c3ViCgoKLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjpTdGF0ZUFwcExvY2FsQ29udHJhY3QudmVyaWZ5X2RlbGV0ZShhOiBieXRlcywgYjogYnl0ZXMpIC0+IHZvaWQ6CnZlcmlmeV9kZWxldGU6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NDQ3LTQ0OAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIHZlcmlmeV9kZWxldGUoYTogQWNjb3VudCwgYjogYnl0ZXMpOiB2b2lkIHsKICAgIHByb3RvIDIgMAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjQ0OQogICAgLy8gb3AuQXBwTG9jYWwuZGVsZXRlKGEsIGIpCiAgICBmcmFtZV9kaWcgLTIKICAgIGZyYW1lX2RpZyAtMQogICAgYXBwX2xvY2FsX2RlbAogICAgcmV0c3ViCgoKLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjpTdGF0ZUFwcExvY2FsQ29udHJhY3QudmVyaWZ5X2V4aXN0cyhhOiBieXRlcywgYjogYnl0ZXMpIC0+IHVpbnQ2NDoKdmVyaWZ5X2V4aXN0czoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo0NTItNDUzCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gdmVyaWZ5X2V4aXN0cyhhOiBBY2NvdW50LCBiOiBieXRlcyk6IGJvb2xlYW4gewogICAgcHJvdG8gMiAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NDU0CiAgICAvLyBjb25zdCBbX3ZhbHVlLCBleGlzdHNdID0gb3AuQXBwTG9jYWwuZ2V0RXhVaW50NjQoYSwgMCwgYikKICAgIGZyYW1lX2RpZyAtMgogICAgaW50Y18xIC8vIDAKICAgIGZyYW1lX2RpZyAtMQogICAgYXBwX2xvY2FsX2dldF9leAogICAgYnVyeSAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NDU1CiAgICAvLyByZXR1cm4gZXhpc3RzCiAgICByZXRzdWIKCgovLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OlN0YXRlQXBwTG9jYWxDb250cmFjdC52ZXJpZnlfcHV0X3VpbnQ2NChhOiBieXRlcywgYjogYnl0ZXMsIGM6IHVpbnQ2NCkgLT4gdm9pZDoKdmVyaWZ5X3B1dF91aW50NjQ6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NDU4LTQ1OQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIHZlcmlmeV9wdXRfdWludDY0KGE6IEFjY291bnQsIGI6IGJ5dGVzLCBjOiB1aW50NjQpOiB2b2lkIHsKICAgIHByb3RvIDMgMAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjQ2MAogICAgLy8gb3AuQXBwTG9jYWwucHV0KGEsIGIsIGMpCiAgICBmcmFtZV9kaWcgLTMKICAgIGZyYW1lX2RpZyAtMgogICAgZnJhbWVfZGlnIC0xCiAgICBhcHBfbG9jYWxfcHV0CiAgICByZXRzdWIKCgovLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OlN0YXRlQXBwTG9jYWxDb250cmFjdC52ZXJpZnlfcHV0X2J5dGVzKGE6IGJ5dGVzLCBiOiBieXRlcywgYzogYnl0ZXMpIC0+IHZvaWQ6CnZlcmlmeV9wdXRfYnl0ZXM6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NDYzLTQ2NAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIHZlcmlmeV9wdXRfYnl0ZXMoYTogQWNjb3VudCwgYjogYnl0ZXMsIGM6IGJ5dGVzKTogdm9pZCB7CiAgICBwcm90byAzIDAKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo0NjUKICAgIC8vIG9wLkFwcExvY2FsLnB1dChhLCBiLCBjKQogICAgZnJhbWVfZGlnIC0zCiAgICBmcmFtZV9kaWcgLTIKICAgIGZyYW1lX2RpZyAtMQogICAgYXBwX2xvY2FsX3B1dAogICAgcmV0c3ViCg==", - "clear": "I3ByYWdtYSB2ZXJzaW9uIDEwCgp0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OlN0YXRlQXBwTG9jYWxDb250cmFjdC5jbGVhclN0YXRlUHJvZ3JhbToKICAgIHB1c2hpbnQgMSAvLyAxCiAgICByZXR1cm4K" - }, - "events": [], - "templateVariables": {} -} \ No newline at end of file diff --git a/tests/artifacts/state-ops/data/StateAppLocalContract.clear.teal b/tests/artifacts/state-ops/data/StateAppLocalContract.clear.teal deleted file mode 100644 index fb6bff4..0000000 --- a/tests/artifacts/state-ops/data/StateAppLocalContract.clear.teal +++ /dev/null @@ -1,5 +0,0 @@ -#pragma version 10 - -tests/artifacts/state-ops/contract.algo.ts::StateAppLocalContract.clearStateProgram: - pushint 1 // 1 - return diff --git a/tests/artifacts/state-ops/data/StateAppLocalExContract.approval.teal b/tests/artifacts/state-ops/data/StateAppLocalExContract.approval.teal deleted file mode 100644 index 013cc9f..0000000 --- a/tests/artifacts/state-ops/data/StateAppLocalExContract.approval.teal +++ /dev/null @@ -1,87 +0,0 @@ -#pragma version 10 - -tests/artifacts/state-ops/contract.algo.ts::StateAppLocalExContract.approvalProgram: - intcblock 1 0 - callsub __puya_arc4_router__ - return - - -// tests/artifacts/state-ops/contract.algo.ts::StateAppLocalExContract.__puya_arc4_router__() -> uint64: -__puya_arc4_router__: - // tests/artifacts/state-ops/contract.algo.ts:400 - // export class StateAppLocalExContract extends arc4.Contract { - proto 0 1 - txn NumAppArgs - bz __puya_arc4_router___bare_routing@5 - pushbytes 0x30c6d58a // method "opt_in()void" - txna ApplicationArgs 0 - match __puya_arc4_router___opt_in_route@2 - intc_1 // 0 - retsub - -__puya_arc4_router___opt_in_route@2: - // tests/artifacts/state-ops/contract.algo.ts:405 - // @arc4.abimethod({ allowActions: ['OptIn'] }) - txn OnCompletion - intc_0 // OptIn - == - assert // OnCompletion is not OptIn - txn ApplicationID - assert // can only call when not creating - callsub opt_in - intc_0 // 1 - retsub - -__puya_arc4_router___bare_routing@5: - // tests/artifacts/state-ops/contract.algo.ts:400 - // export class StateAppLocalExContract extends arc4.Contract { - txn OnCompletion - bnz __puya_arc4_router___after_if_else@9 - txn ApplicationID - ! - assert // can only call when creating - intc_0 // 1 - retsub - -__puya_arc4_router___after_if_else@9: - // tests/artifacts/state-ops/contract.algo.ts:400 - // export class StateAppLocalExContract extends arc4.Contract { - intc_1 // 0 - retsub - - -// tests/artifacts/state-ops/contract.algo.ts::StateAppLocalExContract.opt_in() -> void: -opt_in: - // tests/artifacts/state-ops/contract.algo.ts:405-406 - // @arc4.abimethod({ allowActions: ['OptIn'] }) - // opt_in(): void { - proto 0 0 - // tests/artifacts/state-ops/contract.algo.ts:407 - // this.localBytes(Global.creatorAddress).value = Bytes('dummy_bytes_from_external_contract') - global CreatorAddress - // tests/artifacts/state-ops/contract.algo.ts:402 - // localBytes = LocalState({ key: 'local_bytes' }) - pushbytess "local_bytes" "dummy_bytes_from_external_contract" // "local_bytes", "dummy_bytes_from_external_contract" - // tests/artifacts/state-ops/contract.algo.ts:407 - // this.localBytes(Global.creatorAddress).value = Bytes('dummy_bytes_from_external_contract') - app_local_put - // tests/artifacts/state-ops/contract.algo.ts:408 - // this.localUint64(Global.creatorAddress).value = Uint64(99) - global CreatorAddress - // tests/artifacts/state-ops/contract.algo.ts:401 - // localUint64 = LocalState({ key: 'local_uint64' }) - pushbytes "local_uint64" - // tests/artifacts/state-ops/contract.algo.ts:408 - // this.localUint64(Global.creatorAddress).value = Uint64(99) - pushint 99 // 99 - app_local_put - // tests/artifacts/state-ops/contract.algo.ts:409 - // this.localArc4Bytes(Global.creatorAddress).value = new DynamicBytes('dummy_arc4_bytes') - global CreatorAddress - // tests/artifacts/state-ops/contract.algo.ts:403 - // localArc4Bytes = LocalState({ key: 'local_arc4_bytes' }) - pushbytess "local_arc4_bytes" 0x001064756d6d795f617263345f6279746573 // "local_arc4_bytes", 0x001064756d6d795f617263345f6279746573 - // tests/artifacts/state-ops/contract.algo.ts:409 - // this.localArc4Bytes(Global.creatorAddress).value = new DynamicBytes('dummy_arc4_bytes') - app_local_put - retsub diff --git a/tests/artifacts/state-ops/data/StateAppLocalExContract.arc32.json b/tests/artifacts/state-ops/data/StateAppLocalExContract.arc32.json deleted file mode 100644 index 84e8dfe..0000000 --- a/tests/artifacts/state-ops/data/StateAppLocalExContract.arc32.json +++ /dev/null @@ -1,63 +0,0 @@ -{ - "hints": { - "opt_in()void": { - "call_config": { - "opt_in": "CALL" - } - } - }, - "source": { - "approval": "I3ByYWdtYSB2ZXJzaW9uIDEwCgp0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OlN0YXRlQXBwTG9jYWxFeENvbnRyYWN0LmFwcHJvdmFsUHJvZ3JhbToKICAgIGludGNibG9jayAxIDAKICAgIGNhbGxzdWIgX19wdXlhX2FyYzRfcm91dGVyX18KICAgIHJldHVybgoKCi8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo6U3RhdGVBcHBMb2NhbEV4Q29udHJhY3QuX19wdXlhX2FyYzRfcm91dGVyX18oKSAtPiB1aW50NjQ6Cl9fcHV5YV9hcmM0X3JvdXRlcl9fOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjQwMAogICAgLy8gZXhwb3J0IGNsYXNzIFN0YXRlQXBwTG9jYWxFeENvbnRyYWN0IGV4dGVuZHMgYXJjNC5Db250cmFjdCB7CiAgICBwcm90byAwIDEKICAgIHR4biBOdW1BcHBBcmdzCiAgICBieiBfX3B1eWFfYXJjNF9yb3V0ZXJfX19iYXJlX3JvdXRpbmdANQogICAgcHVzaGJ5dGVzIDB4MzBjNmQ1OGEgLy8gbWV0aG9kICJvcHRfaW4oKXZvaWQiCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAwCiAgICBtYXRjaCBfX3B1eWFfYXJjNF9yb3V0ZXJfX19vcHRfaW5fcm91dGVAMgogICAgaW50Y18xIC8vIDAKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fb3B0X2luX3JvdXRlQDI6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NDA1CiAgICAvLyBAYXJjNC5hYmltZXRob2QoeyBhbGxvd0FjdGlvbnM6IFsnT3B0SW4nXSB9KQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgaW50Y18wIC8vIE9wdEluCiAgICA9PQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBub3QgT3B0SW4KICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gY2FuIG9ubHkgY2FsbCB3aGVuIG5vdCBjcmVhdGluZwogICAgY2FsbHN1YiBvcHRfaW4KICAgIGludGNfMCAvLyAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX2JhcmVfcm91dGluZ0A1OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjQwMAogICAgLy8gZXhwb3J0IGNsYXNzIFN0YXRlQXBwTG9jYWxFeENvbnRyYWN0IGV4dGVuZHMgYXJjNC5Db250cmFjdCB7CiAgICB0eG4gT25Db21wbGV0aW9uCiAgICBibnogX19wdXlhX2FyYzRfcm91dGVyX19fYWZ0ZXJfaWZfZWxzZUA5CiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgIQogICAgYXNzZXJ0IC8vIGNhbiBvbmx5IGNhbGwgd2hlbiBjcmVhdGluZwogICAgaW50Y18wIC8vIDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fYWZ0ZXJfaWZfZWxzZUA5OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjQwMAogICAgLy8gZXhwb3J0IGNsYXNzIFN0YXRlQXBwTG9jYWxFeENvbnRyYWN0IGV4dGVuZHMgYXJjNC5Db250cmFjdCB7CiAgICBpbnRjXzEgLy8gMAogICAgcmV0c3ViCgoKLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjpTdGF0ZUFwcExvY2FsRXhDb250cmFjdC5vcHRfaW4oKSAtPiB2b2lkOgpvcHRfaW46CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NDA1LTQwNgogICAgLy8gQGFyYzQuYWJpbWV0aG9kKHsgYWxsb3dBY3Rpb25zOiBbJ09wdEluJ10gfSkKICAgIC8vIG9wdF9pbigpOiB2b2lkIHsKICAgIHByb3RvIDAgMAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjQwNwogICAgLy8gdGhpcy5sb2NhbEJ5dGVzKEdsb2JhbC5jcmVhdG9yQWRkcmVzcykudmFsdWUgPSBCeXRlcygnZHVtbXlfYnl0ZXNfZnJvbV9leHRlcm5hbF9jb250cmFjdCcpCiAgICBnbG9iYWwgQ3JlYXRvckFkZHJlc3MKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo0MDIKICAgIC8vIGxvY2FsQnl0ZXMgPSBMb2NhbFN0YXRlPGJ5dGVzPih7IGtleTogJ2xvY2FsX2J5dGVzJyB9KQogICAgcHVzaGJ5dGVzcyAibG9jYWxfYnl0ZXMiICJkdW1teV9ieXRlc19mcm9tX2V4dGVybmFsX2NvbnRyYWN0IiAvLyAibG9jYWxfYnl0ZXMiLCAiZHVtbXlfYnl0ZXNfZnJvbV9leHRlcm5hbF9jb250cmFjdCIKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo0MDcKICAgIC8vIHRoaXMubG9jYWxCeXRlcyhHbG9iYWwuY3JlYXRvckFkZHJlc3MpLnZhbHVlID0gQnl0ZXMoJ2R1bW15X2J5dGVzX2Zyb21fZXh0ZXJuYWxfY29udHJhY3QnKQogICAgYXBwX2xvY2FsX3B1dAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjQwOAogICAgLy8gdGhpcy5sb2NhbFVpbnQ2NChHbG9iYWwuY3JlYXRvckFkZHJlc3MpLnZhbHVlID0gVWludDY0KDk5KQogICAgZ2xvYmFsIENyZWF0b3JBZGRyZXNzCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NDAxCiAgICAvLyBsb2NhbFVpbnQ2NCA9IExvY2FsU3RhdGU8dWludDY0Pih7IGtleTogJ2xvY2FsX3VpbnQ2NCcgfSkKICAgIHB1c2hieXRlcyAibG9jYWxfdWludDY0IgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjQwOAogICAgLy8gdGhpcy5sb2NhbFVpbnQ2NChHbG9iYWwuY3JlYXRvckFkZHJlc3MpLnZhbHVlID0gVWludDY0KDk5KQogICAgcHVzaGludCA5OSAvLyA5OQogICAgYXBwX2xvY2FsX3B1dAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjQwOQogICAgLy8gdGhpcy5sb2NhbEFyYzRCeXRlcyhHbG9iYWwuY3JlYXRvckFkZHJlc3MpLnZhbHVlID0gbmV3IER5bmFtaWNCeXRlcygnZHVtbXlfYXJjNF9ieXRlcycpCiAgICBnbG9iYWwgQ3JlYXRvckFkZHJlc3MKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo0MDMKICAgIC8vIGxvY2FsQXJjNEJ5dGVzID0gTG9jYWxTdGF0ZTxEeW5hbWljQnl0ZXM+KHsga2V5OiAnbG9jYWxfYXJjNF9ieXRlcycgfSkKICAgIHB1c2hieXRlc3MgImxvY2FsX2FyYzRfYnl0ZXMiIDB4MDAxMDY0NzU2ZDZkNzk1ZjYxNzI2MzM0NWY2Mjc5NzQ2NTczIC8vICJsb2NhbF9hcmM0X2J5dGVzIiwgMHgwMDEwNjQ3NTZkNmQ3OTVmNjE3MjYzMzQ1ZjYyNzk3NDY1NzMKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo0MDkKICAgIC8vIHRoaXMubG9jYWxBcmM0Qnl0ZXMoR2xvYmFsLmNyZWF0b3JBZGRyZXNzKS52YWx1ZSA9IG5ldyBEeW5hbWljQnl0ZXMoJ2R1bW15X2FyYzRfYnl0ZXMnKQogICAgYXBwX2xvY2FsX3B1dAogICAgcmV0c3ViCg==", - "clear": "I3ByYWdtYSB2ZXJzaW9uIDEwCgp0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OlN0YXRlQXBwTG9jYWxFeENvbnRyYWN0LmNsZWFyU3RhdGVQcm9ncmFtOgogICAgcHVzaGludCAxIC8vIDEKICAgIHJldHVybgo=" - }, - "state": { - "global": { - "num_byte_slices": 0, - "num_uints": 0 - }, - "local": { - "num_byte_slices": 2, - "num_uints": 1 - } - }, - "schema": { - "global": { - "declared": {}, - "reserved": {} - }, - "local": { - "declared": { - "localArc4Bytes": { - "type": "bytes", - "key": "local_arc4_bytes" - }, - "localBytes": { - "type": "bytes", - "key": "local_bytes" - }, - "localUint64": { - "type": "uint64", - "key": "local_uint64" - } - }, - "reserved": {} - } - }, - "contract": { - "name": "StateAppLocalExContract", - "methods": [ - { - "name": "opt_in", - "args": [], - "readonly": false, - "returns": { - "type": "void" - } - } - ], - "networks": {} - }, - "bare_call_config": { - "no_op": "CREATE" - } -} \ No newline at end of file diff --git a/tests/artifacts/state-ops/data/StateAppLocalExContract.arc56.json b/tests/artifacts/state-ops/data/StateAppLocalExContract.arc56.json deleted file mode 100644 index 81312e3..0000000 --- a/tests/artifacts/state-ops/data/StateAppLocalExContract.arc56.json +++ /dev/null @@ -1,106 +0,0 @@ -{ - "name": "StateAppLocalExContract", - "structs": {}, - "methods": [ - { - "name": "opt_in", - "args": [], - "returns": { - "type": "void" - }, - "actions": { - "create": [], - "call": [ - "OptIn" - ] - }, - "readonly": false, - "events": [], - "recommendations": {} - } - ], - "arcs": [ - 22, - 28 - ], - "networks": {}, - "state": { - "schema": { - "global": { - "ints": 0, - "bytes": 0 - }, - "local": { - "ints": 1, - "bytes": 2 - } - }, - "keys": { - "global": {}, - "local": { - "localUint64": { - "keyType": "AVMString", - "valueType": "AVMUint64", - "key": "bG9jYWxfdWludDY0" - }, - "localBytes": { - "keyType": "AVMString", - "valueType": "AVMBytes", - "key": "bG9jYWxfYnl0ZXM=" - }, - "localArc4Bytes": { - "keyType": "AVMString", - "valueType": "byte[]", - "key": "bG9jYWxfYXJjNF9ieXRlcw==" - } - }, - "box": {} - }, - "maps": { - "global": {}, - "local": {}, - "box": {} - } - }, - "bareActions": { - "create": [ - "NoOp" - ], - "call": [] - }, - "sourceInfo": { - "approval": { - "sourceInfo": [ - { - "pc": [ - 36 - ], - "errorMessage": "OnCompletion is not OptIn" - }, - { - "pc": [ - 53 - ], - "errorMessage": "can only call when creating" - }, - { - "pc": [ - 39 - ], - "errorMessage": "can only call when not creating" - } - ], - "pcOffsetMethod": "none" - }, - "clear": { - "sourceInfo": [], - "pcOffsetMethod": "none" - } - }, - "source": { - "approval": "I3ByYWdtYSB2ZXJzaW9uIDEwCgp0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OlN0YXRlQXBwTG9jYWxFeENvbnRyYWN0LmFwcHJvdmFsUHJvZ3JhbToKICAgIGludGNibG9jayAxIDAKICAgIGNhbGxzdWIgX19wdXlhX2FyYzRfcm91dGVyX18KICAgIHJldHVybgoKCi8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo6U3RhdGVBcHBMb2NhbEV4Q29udHJhY3QuX19wdXlhX2FyYzRfcm91dGVyX18oKSAtPiB1aW50NjQ6Cl9fcHV5YV9hcmM0X3JvdXRlcl9fOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjQwMAogICAgLy8gZXhwb3J0IGNsYXNzIFN0YXRlQXBwTG9jYWxFeENvbnRyYWN0IGV4dGVuZHMgYXJjNC5Db250cmFjdCB7CiAgICBwcm90byAwIDEKICAgIHR4biBOdW1BcHBBcmdzCiAgICBieiBfX3B1eWFfYXJjNF9yb3V0ZXJfX19iYXJlX3JvdXRpbmdANQogICAgcHVzaGJ5dGVzIDB4MzBjNmQ1OGEgLy8gbWV0aG9kICJvcHRfaW4oKXZvaWQiCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAwCiAgICBtYXRjaCBfX3B1eWFfYXJjNF9yb3V0ZXJfX19vcHRfaW5fcm91dGVAMgogICAgaW50Y18xIC8vIDAKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fb3B0X2luX3JvdXRlQDI6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NDA1CiAgICAvLyBAYXJjNC5hYmltZXRob2QoeyBhbGxvd0FjdGlvbnM6IFsnT3B0SW4nXSB9KQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgaW50Y18wIC8vIE9wdEluCiAgICA9PQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBub3QgT3B0SW4KICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gY2FuIG9ubHkgY2FsbCB3aGVuIG5vdCBjcmVhdGluZwogICAgY2FsbHN1YiBvcHRfaW4KICAgIGludGNfMCAvLyAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX2JhcmVfcm91dGluZ0A1OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjQwMAogICAgLy8gZXhwb3J0IGNsYXNzIFN0YXRlQXBwTG9jYWxFeENvbnRyYWN0IGV4dGVuZHMgYXJjNC5Db250cmFjdCB7CiAgICB0eG4gT25Db21wbGV0aW9uCiAgICBibnogX19wdXlhX2FyYzRfcm91dGVyX19fYWZ0ZXJfaWZfZWxzZUA5CiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgIQogICAgYXNzZXJ0IC8vIGNhbiBvbmx5IGNhbGwgd2hlbiBjcmVhdGluZwogICAgaW50Y18wIC8vIDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fYWZ0ZXJfaWZfZWxzZUA5OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjQwMAogICAgLy8gZXhwb3J0IGNsYXNzIFN0YXRlQXBwTG9jYWxFeENvbnRyYWN0IGV4dGVuZHMgYXJjNC5Db250cmFjdCB7CiAgICBpbnRjXzEgLy8gMAogICAgcmV0c3ViCgoKLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjpTdGF0ZUFwcExvY2FsRXhDb250cmFjdC5vcHRfaW4oKSAtPiB2b2lkOgpvcHRfaW46CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NDA1LTQwNgogICAgLy8gQGFyYzQuYWJpbWV0aG9kKHsgYWxsb3dBY3Rpb25zOiBbJ09wdEluJ10gfSkKICAgIC8vIG9wdF9pbigpOiB2b2lkIHsKICAgIHByb3RvIDAgMAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjQwNwogICAgLy8gdGhpcy5sb2NhbEJ5dGVzKEdsb2JhbC5jcmVhdG9yQWRkcmVzcykudmFsdWUgPSBCeXRlcygnZHVtbXlfYnl0ZXNfZnJvbV9leHRlcm5hbF9jb250cmFjdCcpCiAgICBnbG9iYWwgQ3JlYXRvckFkZHJlc3MKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo0MDIKICAgIC8vIGxvY2FsQnl0ZXMgPSBMb2NhbFN0YXRlPGJ5dGVzPih7IGtleTogJ2xvY2FsX2J5dGVzJyB9KQogICAgcHVzaGJ5dGVzcyAibG9jYWxfYnl0ZXMiICJkdW1teV9ieXRlc19mcm9tX2V4dGVybmFsX2NvbnRyYWN0IiAvLyAibG9jYWxfYnl0ZXMiLCAiZHVtbXlfYnl0ZXNfZnJvbV9leHRlcm5hbF9jb250cmFjdCIKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo0MDcKICAgIC8vIHRoaXMubG9jYWxCeXRlcyhHbG9iYWwuY3JlYXRvckFkZHJlc3MpLnZhbHVlID0gQnl0ZXMoJ2R1bW15X2J5dGVzX2Zyb21fZXh0ZXJuYWxfY29udHJhY3QnKQogICAgYXBwX2xvY2FsX3B1dAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjQwOAogICAgLy8gdGhpcy5sb2NhbFVpbnQ2NChHbG9iYWwuY3JlYXRvckFkZHJlc3MpLnZhbHVlID0gVWludDY0KDk5KQogICAgZ2xvYmFsIENyZWF0b3JBZGRyZXNzCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NDAxCiAgICAvLyBsb2NhbFVpbnQ2NCA9IExvY2FsU3RhdGU8dWludDY0Pih7IGtleTogJ2xvY2FsX3VpbnQ2NCcgfSkKICAgIHB1c2hieXRlcyAibG9jYWxfdWludDY0IgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjQwOAogICAgLy8gdGhpcy5sb2NhbFVpbnQ2NChHbG9iYWwuY3JlYXRvckFkZHJlc3MpLnZhbHVlID0gVWludDY0KDk5KQogICAgcHVzaGludCA5OSAvLyA5OQogICAgYXBwX2xvY2FsX3B1dAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjQwOQogICAgLy8gdGhpcy5sb2NhbEFyYzRCeXRlcyhHbG9iYWwuY3JlYXRvckFkZHJlc3MpLnZhbHVlID0gbmV3IER5bmFtaWNCeXRlcygnZHVtbXlfYXJjNF9ieXRlcycpCiAgICBnbG9iYWwgQ3JlYXRvckFkZHJlc3MKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo0MDMKICAgIC8vIGxvY2FsQXJjNEJ5dGVzID0gTG9jYWxTdGF0ZTxEeW5hbWljQnl0ZXM+KHsga2V5OiAnbG9jYWxfYXJjNF9ieXRlcycgfSkKICAgIHB1c2hieXRlc3MgImxvY2FsX2FyYzRfYnl0ZXMiIDB4MDAxMDY0NzU2ZDZkNzk1ZjYxNzI2MzM0NWY2Mjc5NzQ2NTczIC8vICJsb2NhbF9hcmM0X2J5dGVzIiwgMHgwMDEwNjQ3NTZkNmQ3OTVmNjE3MjYzMzQ1ZjYyNzk3NDY1NzMKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo0MDkKICAgIC8vIHRoaXMubG9jYWxBcmM0Qnl0ZXMoR2xvYmFsLmNyZWF0b3JBZGRyZXNzKS52YWx1ZSA9IG5ldyBEeW5hbWljQnl0ZXMoJ2R1bW15X2FyYzRfYnl0ZXMnKQogICAgYXBwX2xvY2FsX3B1dAogICAgcmV0c3ViCg==", - "clear": "I3ByYWdtYSB2ZXJzaW9uIDEwCgp0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OlN0YXRlQXBwTG9jYWxFeENvbnRyYWN0LmNsZWFyU3RhdGVQcm9ncmFtOgogICAgcHVzaGludCAxIC8vIDEKICAgIHJldHVybgo=" - }, - "events": [], - "templateVariables": {} -} \ No newline at end of file diff --git a/tests/artifacts/state-ops/data/StateAppLocalExContract.clear.teal b/tests/artifacts/state-ops/data/StateAppLocalExContract.clear.teal deleted file mode 100644 index aec0884..0000000 --- a/tests/artifacts/state-ops/data/StateAppLocalExContract.clear.teal +++ /dev/null @@ -1,5 +0,0 @@ -#pragma version 10 - -tests/artifacts/state-ops/contract.algo.ts::StateAppLocalExContract.clearStateProgram: - pushint 1 // 1 - return diff --git a/tests/artifacts/state-ops/data/StateAppParamsContract.approval.teal b/tests/artifacts/state-ops/data/StateAppParamsContract.approval.teal deleted file mode 100644 index 4f346cc..0000000 --- a/tests/artifacts/state-ops/data/StateAppParamsContract.approval.teal +++ /dev/null @@ -1,536 +0,0 @@ -#pragma version 10 - -tests/artifacts/state-ops/contract.algo.ts::StateAppParamsContract.approvalProgram: - intcblock 1 0 - bytecblock 0x151f7c75 - callsub __puya_arc4_router__ - return - - -// tests/artifacts/state-ops/contract.algo.ts::StateAppParamsContract.__puya_arc4_router__() -> uint64: -__puya_arc4_router__: - // tests/artifacts/state-ops/contract.algo.ts:266 - // export class StateAppParamsContract extends arc4.Contract { - proto 0 1 - txn NumAppArgs - bz __puya_arc4_router___bare_routing@13 - pushbytess 0x5e7b7d52 0xe29e30ee 0x58819099 0xca77b59b 0x53c0dd9b 0x5f000703 0xd77bd21f 0xa941a746 0xbd3e9eec // method "verify_app_params_get_approval_program(application)byte[]", method "verify_app_params_get_clear_state_program(application)byte[]", method "verify_app_params_get_global_num_uint(application)uint64", method "verify_app_params_get_global_num_byte_slice(application)uint64", method "verify_app_params_get_local_num_uint(application)uint64", method "verify_app_params_get_local_num_byte_slice(application)uint64", method "verify_app_params_get_extra_program_pages(application)uint64", method "verify_app_params_get_creator(application)address", method "verify_app_params_get_address(application)address" - txna ApplicationArgs 0 - match __puya_arc4_router___verify_app_params_get_approval_program_route@2 __puya_arc4_router___verify_app_params_get_clear_state_program_route@3 __puya_arc4_router___verify_app_params_get_global_num_uint_route@4 __puya_arc4_router___verify_app_params_get_global_num_byte_slice_route@5 __puya_arc4_router___verify_app_params_get_local_num_uint_route@6 __puya_arc4_router___verify_app_params_get_local_num_byte_slice_route@7 __puya_arc4_router___verify_app_params_get_extra_program_pages_route@8 __puya_arc4_router___verify_app_params_get_creator_route@9 __puya_arc4_router___verify_app_params_get_address_route@10 - intc_1 // 0 - retsub - -__puya_arc4_router___verify_app_params_get_approval_program_route@2: - // tests/artifacts/state-ops/contract.algo.ts:267 - // @arc4.abimethod() - txn OnCompletion - ! - assert // OnCompletion is not NoOp - txn ApplicationID - assert // can only call when not creating - // tests/artifacts/state-ops/contract.algo.ts:266 - // export class StateAppParamsContract extends arc4.Contract { - txna ApplicationArgs 1 - btoi - txnas Applications - // tests/artifacts/state-ops/contract.algo.ts:267 - // @arc4.abimethod() - callsub verify_app_params_get_approval_program - dup - len - itob - extract 6 2 - swap - concat - bytec_0 // 0x151f7c75 - swap - concat - log - intc_0 // 1 - retsub - -__puya_arc4_router___verify_app_params_get_clear_state_program_route@3: - // tests/artifacts/state-ops/contract.algo.ts:276 - // @arc4.abimethod() - txn OnCompletion - ! - assert // OnCompletion is not NoOp - txn ApplicationID - assert // can only call when not creating - // tests/artifacts/state-ops/contract.algo.ts:266 - // export class StateAppParamsContract extends arc4.Contract { - txna ApplicationArgs 1 - btoi - txnas Applications - // tests/artifacts/state-ops/contract.algo.ts:276 - // @arc4.abimethod() - callsub verify_app_params_get_clear_state_program - dup - len - itob - extract 6 2 - swap - concat - bytec_0 // 0x151f7c75 - swap - concat - log - intc_0 // 1 - retsub - -__puya_arc4_router___verify_app_params_get_global_num_uint_route@4: - // tests/artifacts/state-ops/contract.algo.ts:285 - // @arc4.abimethod() - txn OnCompletion - ! - assert // OnCompletion is not NoOp - txn ApplicationID - assert // can only call when not creating - // tests/artifacts/state-ops/contract.algo.ts:266 - // export class StateAppParamsContract extends arc4.Contract { - txna ApplicationArgs 1 - btoi - txnas Applications - // tests/artifacts/state-ops/contract.algo.ts:285 - // @arc4.abimethod() - callsub verify_app_params_get_global_num_uint - itob - bytec_0 // 0x151f7c75 - swap - concat - log - intc_0 // 1 - retsub - -__puya_arc4_router___verify_app_params_get_global_num_byte_slice_route@5: - // tests/artifacts/state-ops/contract.algo.ts:294 - // @arc4.abimethod() - txn OnCompletion - ! - assert // OnCompletion is not NoOp - txn ApplicationID - assert // can only call when not creating - // tests/artifacts/state-ops/contract.algo.ts:266 - // export class StateAppParamsContract extends arc4.Contract { - txna ApplicationArgs 1 - btoi - txnas Applications - // tests/artifacts/state-ops/contract.algo.ts:294 - // @arc4.abimethod() - callsub verify_app_params_get_global_num_byte_slice - itob - bytec_0 // 0x151f7c75 - swap - concat - log - intc_0 // 1 - retsub - -__puya_arc4_router___verify_app_params_get_local_num_uint_route@6: - // tests/artifacts/state-ops/contract.algo.ts:303 - // @arc4.abimethod() - txn OnCompletion - ! - assert // OnCompletion is not NoOp - txn ApplicationID - assert // can only call when not creating - // tests/artifacts/state-ops/contract.algo.ts:266 - // export class StateAppParamsContract extends arc4.Contract { - txna ApplicationArgs 1 - btoi - txnas Applications - // tests/artifacts/state-ops/contract.algo.ts:303 - // @arc4.abimethod() - callsub verify_app_params_get_local_num_uint - itob - bytec_0 // 0x151f7c75 - swap - concat - log - intc_0 // 1 - retsub - -__puya_arc4_router___verify_app_params_get_local_num_byte_slice_route@7: - // tests/artifacts/state-ops/contract.algo.ts:312 - // @arc4.abimethod() - txn OnCompletion - ! - assert // OnCompletion is not NoOp - txn ApplicationID - assert // can only call when not creating - // tests/artifacts/state-ops/contract.algo.ts:266 - // export class StateAppParamsContract extends arc4.Contract { - txna ApplicationArgs 1 - btoi - txnas Applications - // tests/artifacts/state-ops/contract.algo.ts:312 - // @arc4.abimethod() - callsub verify_app_params_get_local_num_byte_slice - itob - bytec_0 // 0x151f7c75 - swap - concat - log - intc_0 // 1 - retsub - -__puya_arc4_router___verify_app_params_get_extra_program_pages_route@8: - // tests/artifacts/state-ops/contract.algo.ts:321 - // @arc4.abimethod() - txn OnCompletion - ! - assert // OnCompletion is not NoOp - txn ApplicationID - assert // can only call when not creating - // tests/artifacts/state-ops/contract.algo.ts:266 - // export class StateAppParamsContract extends arc4.Contract { - txna ApplicationArgs 1 - btoi - txnas Applications - // tests/artifacts/state-ops/contract.algo.ts:321 - // @arc4.abimethod() - callsub verify_app_params_get_extra_program_pages - itob - bytec_0 // 0x151f7c75 - swap - concat - log - intc_0 // 1 - retsub - -__puya_arc4_router___verify_app_params_get_creator_route@9: - // tests/artifacts/state-ops/contract.algo.ts:330 - // @arc4.abimethod() - txn OnCompletion - ! - assert // OnCompletion is not NoOp - txn ApplicationID - assert // can only call when not creating - // tests/artifacts/state-ops/contract.algo.ts:266 - // export class StateAppParamsContract extends arc4.Contract { - txna ApplicationArgs 1 - btoi - txnas Applications - // tests/artifacts/state-ops/contract.algo.ts:330 - // @arc4.abimethod() - callsub verify_app_params_get_creator - bytec_0 // 0x151f7c75 - swap - concat - log - intc_0 // 1 - retsub - -__puya_arc4_router___verify_app_params_get_address_route@10: - // tests/artifacts/state-ops/contract.algo.ts:339 - // @arc4.abimethod() - txn OnCompletion - ! - assert // OnCompletion is not NoOp - txn ApplicationID - assert // can only call when not creating - // tests/artifacts/state-ops/contract.algo.ts:266 - // export class StateAppParamsContract extends arc4.Contract { - txna ApplicationArgs 1 - btoi - txnas Applications - // tests/artifacts/state-ops/contract.algo.ts:339 - // @arc4.abimethod() - callsub verify_app_params_get_address - bytec_0 // 0x151f7c75 - swap - concat - log - intc_0 // 1 - retsub - -__puya_arc4_router___bare_routing@13: - // tests/artifacts/state-ops/contract.algo.ts:266 - // export class StateAppParamsContract extends arc4.Contract { - txn OnCompletion - bnz __puya_arc4_router___after_if_else@17 - txn ApplicationID - ! - assert // can only call when creating - intc_0 // 1 - retsub - -__puya_arc4_router___after_if_else@17: - // tests/artifacts/state-ops/contract.algo.ts:266 - // export class StateAppParamsContract extends arc4.Contract { - intc_1 // 0 - retsub - - -// tests/artifacts/state-ops/contract.algo.ts::StateAppParamsContract.verify_app_params_get_approval_program(a: uint64) -> bytes: -verify_app_params_get_approval_program: - // tests/artifacts/state-ops/contract.algo.ts:267-268 - // @arc4.abimethod() - // public verify_app_params_get_approval_program(a: Application): bytes { - proto 1 1 - // tests/artifacts/state-ops/contract.algo.ts:269 - // const [value, exists] = op.AppParams.appApprovalProgram(a) - frame_dig -1 - app_params_get AppApprovalProgram - // tests/artifacts/state-ops/contract.algo.ts:270 - // const [value_index, exists_index] = op.AppParams.appApprovalProgram(get_1st_ref_index()) - callsub get_1st_ref_index - app_params_get AppApprovalProgram - // tests/artifacts/state-ops/contract.algo.ts:271 - // assert(value === value_index, 'expected value by index to match') - dig 3 - uncover 2 - == - assert // expected value by index to match - // tests/artifacts/state-ops/contract.algo.ts:272 - // assert(exists === exists_index, 'expected exists by index to match') - == - assert // expected exists by index to match - // tests/artifacts/state-ops/contract.algo.ts:273 - // return value - retsub - - -// tests/artifacts/state-ops/contract.algo.ts::get_1st_ref_index() -> uint64: -get_1st_ref_index: - // tests/artifacts/state-ops/contract.algo.ts:22 - // function get_1st_ref_index(): uint64 { - proto 0 1 - // tests/artifacts/state-ops/contract.algo.ts:23 - // return op.btoi(Txn.applicationArgs(1)) - intc_0 // 1 - txnas ApplicationArgs - btoi - retsub - - -// tests/artifacts/state-ops/contract.algo.ts::StateAppParamsContract.verify_app_params_get_clear_state_program(a: uint64) -> bytes: -verify_app_params_get_clear_state_program: - // tests/artifacts/state-ops/contract.algo.ts:276-277 - // @arc4.abimethod() - // public verify_app_params_get_clear_state_program(a: Application): bytes { - proto 1 1 - // tests/artifacts/state-ops/contract.algo.ts:278 - // const [value, exists] = op.AppParams.appClearStateProgram(a) - frame_dig -1 - app_params_get AppClearStateProgram - // tests/artifacts/state-ops/contract.algo.ts:279 - // const [value_index, exists_index] = op.AppParams.appClearStateProgram(get_1st_ref_index()) - callsub get_1st_ref_index - app_params_get AppClearStateProgram - // tests/artifacts/state-ops/contract.algo.ts:280 - // assert(value === value_index, 'expected value by index to match') - dig 3 - uncover 2 - == - assert // expected value by index to match - // tests/artifacts/state-ops/contract.algo.ts:281 - // assert(exists === exists_index, 'expected exists by index to match') - == - assert // expected exists by index to match - // tests/artifacts/state-ops/contract.algo.ts:282 - // return value - retsub - - -// tests/artifacts/state-ops/contract.algo.ts::StateAppParamsContract.verify_app_params_get_global_num_uint(a: uint64) -> uint64: -verify_app_params_get_global_num_uint: - // tests/artifacts/state-ops/contract.algo.ts:285-286 - // @arc4.abimethod() - // public verify_app_params_get_global_num_uint(a: Application): uint64 { - proto 1 1 - // tests/artifacts/state-ops/contract.algo.ts:287 - // const [value, exists] = op.AppParams.appGlobalNumUint(a) - frame_dig -1 - app_params_get AppGlobalNumUint - // tests/artifacts/state-ops/contract.algo.ts:288 - // const [value_index, exists_index] = op.AppParams.appGlobalNumUint(get_1st_ref_index()) - callsub get_1st_ref_index - app_params_get AppGlobalNumUint - // tests/artifacts/state-ops/contract.algo.ts:289 - // assert(value === value_index, 'expected value by index to match') - dig 3 - uncover 2 - == - assert // expected value by index to match - // tests/artifacts/state-ops/contract.algo.ts:290 - // assert(exists === exists_index, 'expected exists by index to match') - == - assert // expected exists by index to match - // tests/artifacts/state-ops/contract.algo.ts:291 - // return value - retsub - - -// tests/artifacts/state-ops/contract.algo.ts::StateAppParamsContract.verify_app_params_get_global_num_byte_slice(a: uint64) -> uint64: -verify_app_params_get_global_num_byte_slice: - // tests/artifacts/state-ops/contract.algo.ts:294-295 - // @arc4.abimethod() - // public verify_app_params_get_global_num_byte_slice(a: Application): uint64 { - proto 1 1 - // tests/artifacts/state-ops/contract.algo.ts:296 - // const [value, exists] = op.AppParams.appGlobalNumByteSlice(a) - frame_dig -1 - app_params_get AppGlobalNumByteSlice - // tests/artifacts/state-ops/contract.algo.ts:297 - // const [value_index, exists_index] = op.AppParams.appGlobalNumByteSlice(get_1st_ref_index()) - callsub get_1st_ref_index - app_params_get AppGlobalNumByteSlice - // tests/artifacts/state-ops/contract.algo.ts:298 - // assert(value === value_index, 'expected value by index to match') - dig 3 - uncover 2 - == - assert // expected value by index to match - // tests/artifacts/state-ops/contract.algo.ts:299 - // assert(exists === exists_index, 'expected exists by index to match') - == - assert // expected exists by index to match - // tests/artifacts/state-ops/contract.algo.ts:300 - // return value - retsub - - -// tests/artifacts/state-ops/contract.algo.ts::StateAppParamsContract.verify_app_params_get_local_num_uint(a: uint64) -> uint64: -verify_app_params_get_local_num_uint: - // tests/artifacts/state-ops/contract.algo.ts:303-304 - // @arc4.abimethod() - // public verify_app_params_get_local_num_uint(a: Application): uint64 { - proto 1 1 - // tests/artifacts/state-ops/contract.algo.ts:305 - // const [value, exists] = op.AppParams.appLocalNumUint(a) - frame_dig -1 - app_params_get AppLocalNumUint - // tests/artifacts/state-ops/contract.algo.ts:306 - // const [value_index, exists_index] = op.AppParams.appLocalNumUint(get_1st_ref_index()) - callsub get_1st_ref_index - app_params_get AppLocalNumUint - // tests/artifacts/state-ops/contract.algo.ts:307 - // assert(value === value_index, 'expected value by index to match') - dig 3 - uncover 2 - == - assert // expected value by index to match - // tests/artifacts/state-ops/contract.algo.ts:308 - // assert(exists === exists_index, 'expected exists by index to match') - == - assert // expected exists by index to match - // tests/artifacts/state-ops/contract.algo.ts:309 - // return value - retsub - - -// tests/artifacts/state-ops/contract.algo.ts::StateAppParamsContract.verify_app_params_get_local_num_byte_slice(a: uint64) -> uint64: -verify_app_params_get_local_num_byte_slice: - // tests/artifacts/state-ops/contract.algo.ts:312-313 - // @arc4.abimethod() - // public verify_app_params_get_local_num_byte_slice(a: Application): uint64 { - proto 1 1 - // tests/artifacts/state-ops/contract.algo.ts:314 - // const [value, exists] = op.AppParams.appLocalNumByteSlice(a) - frame_dig -1 - app_params_get AppLocalNumByteSlice - // tests/artifacts/state-ops/contract.algo.ts:315 - // const [value_index, exists_index] = op.AppParams.appLocalNumByteSlice(get_1st_ref_index()) - callsub get_1st_ref_index - app_params_get AppLocalNumByteSlice - // tests/artifacts/state-ops/contract.algo.ts:316 - // assert(value === value_index, 'expected value by index to match') - dig 3 - uncover 2 - == - assert // expected value by index to match - // tests/artifacts/state-ops/contract.algo.ts:317 - // assert(exists === exists_index, 'expected exists by index to match') - == - assert // expected exists by index to match - // tests/artifacts/state-ops/contract.algo.ts:318 - // return value - retsub - - -// tests/artifacts/state-ops/contract.algo.ts::StateAppParamsContract.verify_app_params_get_extra_program_pages(a: uint64) -> uint64: -verify_app_params_get_extra_program_pages: - // tests/artifacts/state-ops/contract.algo.ts:321-322 - // @arc4.abimethod() - // public verify_app_params_get_extra_program_pages(a: Application): uint64 { - proto 1 1 - // tests/artifacts/state-ops/contract.algo.ts:323 - // const [value, exists] = op.AppParams.appExtraProgramPages(a) - frame_dig -1 - app_params_get AppExtraProgramPages - // tests/artifacts/state-ops/contract.algo.ts:324 - // const [value_index, exists_index] = op.AppParams.appExtraProgramPages(get_1st_ref_index()) - callsub get_1st_ref_index - app_params_get AppExtraProgramPages - // tests/artifacts/state-ops/contract.algo.ts:325 - // assert(value === value_index, 'expected value by index to match') - dig 3 - uncover 2 - == - assert // expected value by index to match - // tests/artifacts/state-ops/contract.algo.ts:326 - // assert(exists === exists_index, 'expected exists by index to match') - == - assert // expected exists by index to match - // tests/artifacts/state-ops/contract.algo.ts:327 - // return value - retsub - - -// tests/artifacts/state-ops/contract.algo.ts::StateAppParamsContract.verify_app_params_get_creator(a: uint64) -> bytes: -verify_app_params_get_creator: - // tests/artifacts/state-ops/contract.algo.ts:330-331 - // @arc4.abimethod() - // public verify_app_params_get_creator(a: Application): Address { - proto 1 1 - // tests/artifacts/state-ops/contract.algo.ts:332 - // const [value, exists] = op.AppParams.appCreator(a) - frame_dig -1 - app_params_get AppCreator - // tests/artifacts/state-ops/contract.algo.ts:333 - // const [value_index, exists_index] = op.AppParams.appCreator(get_1st_ref_index()) - callsub get_1st_ref_index - app_params_get AppCreator - // tests/artifacts/state-ops/contract.algo.ts:334 - // assert(value === value_index, 'expected value by index to match') - dig 3 - uncover 2 - == - assert // expected value by index to match - // tests/artifacts/state-ops/contract.algo.ts:335 - // assert(exists === exists_index, 'expected exists by index to match') - == - assert // expected exists by index to match - // tests/artifacts/state-ops/contract.algo.ts:336 - // return new Address(value) - retsub - - -// tests/artifacts/state-ops/contract.algo.ts::StateAppParamsContract.verify_app_params_get_address(a: uint64) -> bytes: -verify_app_params_get_address: - // tests/artifacts/state-ops/contract.algo.ts:339-340 - // @arc4.abimethod() - // public verify_app_params_get_address(a: Application): Address { - proto 1 1 - // tests/artifacts/state-ops/contract.algo.ts:341 - // const [value, exists] = op.AppParams.appAddress(a) - frame_dig -1 - app_params_get AppAddress - // tests/artifacts/state-ops/contract.algo.ts:342 - // const [value_index, exists_index] = op.AppParams.appAddress(get_1st_ref_index()) - callsub get_1st_ref_index - app_params_get AppAddress - // tests/artifacts/state-ops/contract.algo.ts:343 - // assert(value.bytes.toString() === value_index.bytes.toString(), 'expected value by index to match') - dig 3 - uncover 2 - == - assert // expected value by index to match - // tests/artifacts/state-ops/contract.algo.ts:344 - // assert(exists === exists_index, 'expected exists by index to match') - == - assert // expected exists by index to match - // tests/artifacts/state-ops/contract.algo.ts:345 - // return new Address(value) - retsub diff --git a/tests/artifacts/state-ops/data/StateAppParamsContract.arc32.json b/tests/artifacts/state-ops/data/StateAppParamsContract.arc32.json deleted file mode 100644 index 79db0e7..0000000 --- a/tests/artifacts/state-ops/data/StateAppParamsContract.arc32.json +++ /dev/null @@ -1,199 +0,0 @@ -{ - "hints": { - "verify_app_params_get_approval_program(application)byte[]": { - "call_config": { - "no_op": "CALL" - } - }, - "verify_app_params_get_clear_state_program(application)byte[]": { - "call_config": { - "no_op": "CALL" - } - }, - "verify_app_params_get_global_num_uint(application)uint64": { - "call_config": { - "no_op": "CALL" - } - }, - "verify_app_params_get_global_num_byte_slice(application)uint64": { - "call_config": { - "no_op": "CALL" - } - }, - "verify_app_params_get_local_num_uint(application)uint64": { - "call_config": { - "no_op": "CALL" - } - }, - "verify_app_params_get_local_num_byte_slice(application)uint64": { - "call_config": { - "no_op": "CALL" - } - }, - "verify_app_params_get_extra_program_pages(application)uint64": { - "call_config": { - "no_op": "CALL" - } - }, - "verify_app_params_get_creator(application)address": { - "call_config": { - "no_op": "CALL" - } - }, - "verify_app_params_get_address(application)address": { - "call_config": { - "no_op": "CALL" - } - } - }, - "source": { - "approval": "I3ByYWdtYSB2ZXJzaW9uIDEwCgp0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OlN0YXRlQXBwUGFyYW1zQ29udHJhY3QuYXBwcm92YWxQcm9ncmFtOgogICAgaW50Y2Jsb2NrIDEgMAogICAgYnl0ZWNibG9jayAweDE1MWY3Yzc1CiAgICBjYWxsc3ViIF9fcHV5YV9hcmM0X3JvdXRlcl9fCiAgICByZXR1cm4KCgovLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OlN0YXRlQXBwUGFyYW1zQ29udHJhY3QuX19wdXlhX2FyYzRfcm91dGVyX18oKSAtPiB1aW50NjQ6Cl9fcHV5YV9hcmM0X3JvdXRlcl9fOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjI2NgogICAgLy8gZXhwb3J0IGNsYXNzIFN0YXRlQXBwUGFyYW1zQ29udHJhY3QgZXh0ZW5kcyBhcmM0LkNvbnRyYWN0IHsKICAgIHByb3RvIDAgMQogICAgdHhuIE51bUFwcEFyZ3MKICAgIGJ6IF9fcHV5YV9hcmM0X3JvdXRlcl9fX2JhcmVfcm91dGluZ0AxMwogICAgcHVzaGJ5dGVzcyAweDVlN2I3ZDUyIDB4ZTI5ZTMwZWUgMHg1ODgxOTA5OSAweGNhNzdiNTliIDB4NTNjMGRkOWIgMHg1ZjAwMDcwMyAweGQ3N2JkMjFmIDB4YTk0MWE3NDYgMHhiZDNlOWVlYyAvLyBtZXRob2QgInZlcmlmeV9hcHBfcGFyYW1zX2dldF9hcHByb3ZhbF9wcm9ncmFtKGFwcGxpY2F0aW9uKWJ5dGVbXSIsIG1ldGhvZCAidmVyaWZ5X2FwcF9wYXJhbXNfZ2V0X2NsZWFyX3N0YXRlX3Byb2dyYW0oYXBwbGljYXRpb24pYnl0ZVtdIiwgbWV0aG9kICJ2ZXJpZnlfYXBwX3BhcmFtc19nZXRfZ2xvYmFsX251bV91aW50KGFwcGxpY2F0aW9uKXVpbnQ2NCIsIG1ldGhvZCAidmVyaWZ5X2FwcF9wYXJhbXNfZ2V0X2dsb2JhbF9udW1fYnl0ZV9zbGljZShhcHBsaWNhdGlvbil1aW50NjQiLCBtZXRob2QgInZlcmlmeV9hcHBfcGFyYW1zX2dldF9sb2NhbF9udW1fdWludChhcHBsaWNhdGlvbil1aW50NjQiLCBtZXRob2QgInZlcmlmeV9hcHBfcGFyYW1zX2dldF9sb2NhbF9udW1fYnl0ZV9zbGljZShhcHBsaWNhdGlvbil1aW50NjQiLCBtZXRob2QgInZlcmlmeV9hcHBfcGFyYW1zX2dldF9leHRyYV9wcm9ncmFtX3BhZ2VzKGFwcGxpY2F0aW9uKXVpbnQ2NCIsIG1ldGhvZCAidmVyaWZ5X2FwcF9wYXJhbXNfZ2V0X2NyZWF0b3IoYXBwbGljYXRpb24pYWRkcmVzcyIsIG1ldGhvZCAidmVyaWZ5X2FwcF9wYXJhbXNfZ2V0X2FkZHJlc3MoYXBwbGljYXRpb24pYWRkcmVzcyIKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDAKICAgIG1hdGNoIF9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9hcHBfcGFyYW1zX2dldF9hcHByb3ZhbF9wcm9ncmFtX3JvdXRlQDIgX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2FwcF9wYXJhbXNfZ2V0X2NsZWFyX3N0YXRlX3Byb2dyYW1fcm91dGVAMyBfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfYXBwX3BhcmFtc19nZXRfZ2xvYmFsX251bV91aW50X3JvdXRlQDQgX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2FwcF9wYXJhbXNfZ2V0X2dsb2JhbF9udW1fYnl0ZV9zbGljZV9yb3V0ZUA1IF9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9hcHBfcGFyYW1zX2dldF9sb2NhbF9udW1fdWludF9yb3V0ZUA2IF9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9hcHBfcGFyYW1zX2dldF9sb2NhbF9udW1fYnl0ZV9zbGljZV9yb3V0ZUA3IF9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9hcHBfcGFyYW1zX2dldF9leHRyYV9wcm9ncmFtX3BhZ2VzX3JvdXRlQDggX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2FwcF9wYXJhbXNfZ2V0X2NyZWF0b3Jfcm91dGVAOSBfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfYXBwX3BhcmFtc19nZXRfYWRkcmVzc19yb3V0ZUAxMAogICAgaW50Y18xIC8vIDAKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2FwcF9wYXJhbXNfZ2V0X2FwcHJvdmFsX3Byb2dyYW1fcm91dGVAMjoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czoyNjcKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIG5vdCBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGNhbiBvbmx5IGNhbGwgd2hlbiBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czoyNjYKICAgIC8vIGV4cG9ydCBjbGFzcyBTdGF0ZUFwcFBhcmFtc0NvbnRyYWN0IGV4dGVuZHMgYXJjNC5Db250cmFjdCB7CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBidG9pCiAgICB0eG5hcyBBcHBsaWNhdGlvbnMKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czoyNjcKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV9hcHBfcGFyYW1zX2dldF9hcHByb3ZhbF9wcm9ncmFtCiAgICBkdXAKICAgIGxlbgogICAgaXRvYgogICAgZXh0cmFjdCA2IDIKICAgIHN3YXAKICAgIGNvbmNhdAogICAgYnl0ZWNfMCAvLyAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50Y18wIC8vIDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2FwcF9wYXJhbXNfZ2V0X2NsZWFyX3N0YXRlX3Byb2dyYW1fcm91dGVAMzoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czoyNzYKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIG5vdCBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGNhbiBvbmx5IGNhbGwgd2hlbiBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czoyNjYKICAgIC8vIGV4cG9ydCBjbGFzcyBTdGF0ZUFwcFBhcmFtc0NvbnRyYWN0IGV4dGVuZHMgYXJjNC5Db250cmFjdCB7CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBidG9pCiAgICB0eG5hcyBBcHBsaWNhdGlvbnMKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czoyNzYKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV9hcHBfcGFyYW1zX2dldF9jbGVhcl9zdGF0ZV9wcm9ncmFtCiAgICBkdXAKICAgIGxlbgogICAgaXRvYgogICAgZXh0cmFjdCA2IDIKICAgIHN3YXAKICAgIGNvbmNhdAogICAgYnl0ZWNfMCAvLyAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50Y18wIC8vIDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2FwcF9wYXJhbXNfZ2V0X2dsb2JhbF9udW1fdWludF9yb3V0ZUA0OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjI4NQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgbm90IE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gY2FuIG9ubHkgY2FsbCB3aGVuIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjI2NgogICAgLy8gZXhwb3J0IGNsYXNzIFN0YXRlQXBwUGFyYW1zQ29udHJhY3QgZXh0ZW5kcyBhcmM0LkNvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGJ0b2kKICAgIHR4bmFzIEFwcGxpY2F0aW9ucwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjI4NQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X2FwcF9wYXJhbXNfZ2V0X2dsb2JhbF9udW1fdWludAogICAgaXRvYgogICAgYnl0ZWNfMCAvLyAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50Y18wIC8vIDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2FwcF9wYXJhbXNfZ2V0X2dsb2JhbF9udW1fYnl0ZV9zbGljZV9yb3V0ZUA1OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjI5NAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgbm90IE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gY2FuIG9ubHkgY2FsbCB3aGVuIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjI2NgogICAgLy8gZXhwb3J0IGNsYXNzIFN0YXRlQXBwUGFyYW1zQ29udHJhY3QgZXh0ZW5kcyBhcmM0LkNvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGJ0b2kKICAgIHR4bmFzIEFwcGxpY2F0aW9ucwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjI5NAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X2FwcF9wYXJhbXNfZ2V0X2dsb2JhbF9udW1fYnl0ZV9zbGljZQogICAgaXRvYgogICAgYnl0ZWNfMCAvLyAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50Y18wIC8vIDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2FwcF9wYXJhbXNfZ2V0X2xvY2FsX251bV91aW50X3JvdXRlQDY6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MzAzCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBub3QgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBjYW4gb25seSBjYWxsIHdoZW4gbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MjY2CiAgICAvLyBleHBvcnQgY2xhc3MgU3RhdGVBcHBQYXJhbXNDb250cmFjdCBleHRlbmRzIGFyYzQuQ29udHJhY3QgewogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgYnRvaQogICAgdHhuYXMgQXBwbGljYXRpb25zCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MzAzCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfYXBwX3BhcmFtc19nZXRfbG9jYWxfbnVtX3VpbnQKICAgIGl0b2IKICAgIGJ5dGVjXzAgLy8gMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludGNfMCAvLyAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9hcHBfcGFyYW1zX2dldF9sb2NhbF9udW1fYnl0ZV9zbGljZV9yb3V0ZUA3OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjMxMgogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgbm90IE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gY2FuIG9ubHkgY2FsbCB3aGVuIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjI2NgogICAgLy8gZXhwb3J0IGNsYXNzIFN0YXRlQXBwUGFyYW1zQ29udHJhY3QgZXh0ZW5kcyBhcmM0LkNvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGJ0b2kKICAgIHR4bmFzIEFwcGxpY2F0aW9ucwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjMxMgogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X2FwcF9wYXJhbXNfZ2V0X2xvY2FsX251bV9ieXRlX3NsaWNlCiAgICBpdG9iCiAgICBieXRlY18wIC8vIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnRjXzAgLy8gMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfYXBwX3BhcmFtc19nZXRfZXh0cmFfcHJvZ3JhbV9wYWdlc19yb3V0ZUA4OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjMyMQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgbm90IE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gY2FuIG9ubHkgY2FsbCB3aGVuIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjI2NgogICAgLy8gZXhwb3J0IGNsYXNzIFN0YXRlQXBwUGFyYW1zQ29udHJhY3QgZXh0ZW5kcyBhcmM0LkNvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGJ0b2kKICAgIHR4bmFzIEFwcGxpY2F0aW9ucwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjMyMQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X2FwcF9wYXJhbXNfZ2V0X2V4dHJhX3Byb2dyYW1fcGFnZXMKICAgIGl0b2IKICAgIGJ5dGVjXzAgLy8gMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludGNfMCAvLyAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9hcHBfcGFyYW1zX2dldF9jcmVhdG9yX3JvdXRlQDk6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MzMwCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBub3QgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBjYW4gb25seSBjYWxsIHdoZW4gbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MjY2CiAgICAvLyBleHBvcnQgY2xhc3MgU3RhdGVBcHBQYXJhbXNDb250cmFjdCBleHRlbmRzIGFyYzQuQ29udHJhY3QgewogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgYnRvaQogICAgdHhuYXMgQXBwbGljYXRpb25zCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MzMwCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfYXBwX3BhcmFtc19nZXRfY3JlYXRvcgogICAgYnl0ZWNfMCAvLyAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50Y18wIC8vIDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2FwcF9wYXJhbXNfZ2V0X2FkZHJlc3Nfcm91dGVAMTA6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MzM5CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBub3QgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBjYW4gb25seSBjYWxsIHdoZW4gbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MjY2CiAgICAvLyBleHBvcnQgY2xhc3MgU3RhdGVBcHBQYXJhbXNDb250cmFjdCBleHRlbmRzIGFyYzQuQ29udHJhY3QgewogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgYnRvaQogICAgdHhuYXMgQXBwbGljYXRpb25zCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MzM5CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfYXBwX3BhcmFtc19nZXRfYWRkcmVzcwogICAgYnl0ZWNfMCAvLyAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50Y18wIC8vIDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fYmFyZV9yb3V0aW5nQDEzOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjI2NgogICAgLy8gZXhwb3J0IGNsYXNzIFN0YXRlQXBwUGFyYW1zQ29udHJhY3QgZXh0ZW5kcyBhcmM0LkNvbnRyYWN0IHsKICAgIHR4biBPbkNvbXBsZXRpb24KICAgIGJueiBfX3B1eWFfYXJjNF9yb3V0ZXJfX19hZnRlcl9pZl9lbHNlQDE3CiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgIQogICAgYXNzZXJ0IC8vIGNhbiBvbmx5IGNhbGwgd2hlbiBjcmVhdGluZwogICAgaW50Y18wIC8vIDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fYWZ0ZXJfaWZfZWxzZUAxNzoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czoyNjYKICAgIC8vIGV4cG9ydCBjbGFzcyBTdGF0ZUFwcFBhcmFtc0NvbnRyYWN0IGV4dGVuZHMgYXJjNC5Db250cmFjdCB7CiAgICBpbnRjXzEgLy8gMAogICAgcmV0c3ViCgoKLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjpTdGF0ZUFwcFBhcmFtc0NvbnRyYWN0LnZlcmlmeV9hcHBfcGFyYW1zX2dldF9hcHByb3ZhbF9wcm9ncmFtKGE6IHVpbnQ2NCkgLT4gYnl0ZXM6CnZlcmlmeV9hcHBfcGFyYW1zX2dldF9hcHByb3ZhbF9wcm9ncmFtOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjI2Ny0yNjgKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBwdWJsaWMgdmVyaWZ5X2FwcF9wYXJhbXNfZ2V0X2FwcHJvdmFsX3Byb2dyYW0oYTogQXBwbGljYXRpb24pOiBieXRlcyB7CiAgICBwcm90byAxIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czoyNjkKICAgIC8vIGNvbnN0IFt2YWx1ZSwgZXhpc3RzXSA9IG9wLkFwcFBhcmFtcy5hcHBBcHByb3ZhbFByb2dyYW0oYSkKICAgIGZyYW1lX2RpZyAtMQogICAgYXBwX3BhcmFtc19nZXQgQXBwQXBwcm92YWxQcm9ncmFtCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MjcwCiAgICAvLyBjb25zdCBbdmFsdWVfaW5kZXgsIGV4aXN0c19pbmRleF0gPSBvcC5BcHBQYXJhbXMuYXBwQXBwcm92YWxQcm9ncmFtKGdldF8xc3RfcmVmX2luZGV4KCkpCiAgICBjYWxsc3ViIGdldF8xc3RfcmVmX2luZGV4CiAgICBhcHBfcGFyYW1zX2dldCBBcHBBcHByb3ZhbFByb2dyYW0KICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czoyNzEKICAgIC8vIGFzc2VydCh2YWx1ZSA9PT0gdmFsdWVfaW5kZXgsICdleHBlY3RlZCB2YWx1ZSBieSBpbmRleCB0byBtYXRjaCcpCiAgICBkaWcgMwogICAgdW5jb3ZlciAyCiAgICA9PQogICAgYXNzZXJ0IC8vIGV4cGVjdGVkIHZhbHVlIGJ5IGluZGV4IHRvIG1hdGNoCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MjcyCiAgICAvLyBhc3NlcnQoZXhpc3RzID09PSBleGlzdHNfaW5kZXgsICdleHBlY3RlZCBleGlzdHMgYnkgaW5kZXggdG8gbWF0Y2gnKQogICAgPT0KICAgIGFzc2VydCAvLyBleHBlY3RlZCBleGlzdHMgYnkgaW5kZXggdG8gbWF0Y2gKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czoyNzMKICAgIC8vIHJldHVybiB2YWx1ZQogICAgcmV0c3ViCgoKLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjpnZXRfMXN0X3JlZl9pbmRleCgpIC0+IHVpbnQ2NDoKZ2V0XzFzdF9yZWZfaW5kZXg6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MjIKICAgIC8vIGZ1bmN0aW9uIGdldF8xc3RfcmVmX2luZGV4KCk6IHVpbnQ2NCB7CiAgICBwcm90byAwIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czoyMwogICAgLy8gcmV0dXJuIG9wLmJ0b2koVHhuLmFwcGxpY2F0aW9uQXJncygxKSkKICAgIGludGNfMCAvLyAxCiAgICB0eG5hcyBBcHBsaWNhdGlvbkFyZ3MKICAgIGJ0b2kKICAgIHJldHN1YgoKCi8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo6U3RhdGVBcHBQYXJhbXNDb250cmFjdC52ZXJpZnlfYXBwX3BhcmFtc19nZXRfY2xlYXJfc3RhdGVfcHJvZ3JhbShhOiB1aW50NjQpIC0+IGJ5dGVzOgp2ZXJpZnlfYXBwX3BhcmFtc19nZXRfY2xlYXJfc3RhdGVfcHJvZ3JhbToKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czoyNzYtMjc3CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gcHVibGljIHZlcmlmeV9hcHBfcGFyYW1zX2dldF9jbGVhcl9zdGF0ZV9wcm9ncmFtKGE6IEFwcGxpY2F0aW9uKTogYnl0ZXMgewogICAgcHJvdG8gMSAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6Mjc4CiAgICAvLyBjb25zdCBbdmFsdWUsIGV4aXN0c10gPSBvcC5BcHBQYXJhbXMuYXBwQ2xlYXJTdGF0ZVByb2dyYW0oYSkKICAgIGZyYW1lX2RpZyAtMQogICAgYXBwX3BhcmFtc19nZXQgQXBwQ2xlYXJTdGF0ZVByb2dyYW0KICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czoyNzkKICAgIC8vIGNvbnN0IFt2YWx1ZV9pbmRleCwgZXhpc3RzX2luZGV4XSA9IG9wLkFwcFBhcmFtcy5hcHBDbGVhclN0YXRlUHJvZ3JhbShnZXRfMXN0X3JlZl9pbmRleCgpKQogICAgY2FsbHN1YiBnZXRfMXN0X3JlZl9pbmRleAogICAgYXBwX3BhcmFtc19nZXQgQXBwQ2xlYXJTdGF0ZVByb2dyYW0KICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czoyODAKICAgIC8vIGFzc2VydCh2YWx1ZSA9PT0gdmFsdWVfaW5kZXgsICdleHBlY3RlZCB2YWx1ZSBieSBpbmRleCB0byBtYXRjaCcpCiAgICBkaWcgMwogICAgdW5jb3ZlciAyCiAgICA9PQogICAgYXNzZXJ0IC8vIGV4cGVjdGVkIHZhbHVlIGJ5IGluZGV4IHRvIG1hdGNoCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MjgxCiAgICAvLyBhc3NlcnQoZXhpc3RzID09PSBleGlzdHNfaW5kZXgsICdleHBlY3RlZCBleGlzdHMgYnkgaW5kZXggdG8gbWF0Y2gnKQogICAgPT0KICAgIGFzc2VydCAvLyBleHBlY3RlZCBleGlzdHMgYnkgaW5kZXggdG8gbWF0Y2gKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czoyODIKICAgIC8vIHJldHVybiB2YWx1ZQogICAgcmV0c3ViCgoKLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjpTdGF0ZUFwcFBhcmFtc0NvbnRyYWN0LnZlcmlmeV9hcHBfcGFyYW1zX2dldF9nbG9iYWxfbnVtX3VpbnQoYTogdWludDY0KSAtPiB1aW50NjQ6CnZlcmlmeV9hcHBfcGFyYW1zX2dldF9nbG9iYWxfbnVtX3VpbnQ6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6Mjg1LTI4NgogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIHB1YmxpYyB2ZXJpZnlfYXBwX3BhcmFtc19nZXRfZ2xvYmFsX251bV91aW50KGE6IEFwcGxpY2F0aW9uKTogdWludDY0IHsKICAgIHByb3RvIDEgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjI4NwogICAgLy8gY29uc3QgW3ZhbHVlLCBleGlzdHNdID0gb3AuQXBwUGFyYW1zLmFwcEdsb2JhbE51bVVpbnQoYSkKICAgIGZyYW1lX2RpZyAtMQogICAgYXBwX3BhcmFtc19nZXQgQXBwR2xvYmFsTnVtVWludAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjI4OAogICAgLy8gY29uc3QgW3ZhbHVlX2luZGV4LCBleGlzdHNfaW5kZXhdID0gb3AuQXBwUGFyYW1zLmFwcEdsb2JhbE51bVVpbnQoZ2V0XzFzdF9yZWZfaW5kZXgoKSkKICAgIGNhbGxzdWIgZ2V0XzFzdF9yZWZfaW5kZXgKICAgIGFwcF9wYXJhbXNfZ2V0IEFwcEdsb2JhbE51bVVpbnQKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czoyODkKICAgIC8vIGFzc2VydCh2YWx1ZSA9PT0gdmFsdWVfaW5kZXgsICdleHBlY3RlZCB2YWx1ZSBieSBpbmRleCB0byBtYXRjaCcpCiAgICBkaWcgMwogICAgdW5jb3ZlciAyCiAgICA9PQogICAgYXNzZXJ0IC8vIGV4cGVjdGVkIHZhbHVlIGJ5IGluZGV4IHRvIG1hdGNoCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MjkwCiAgICAvLyBhc3NlcnQoZXhpc3RzID09PSBleGlzdHNfaW5kZXgsICdleHBlY3RlZCBleGlzdHMgYnkgaW5kZXggdG8gbWF0Y2gnKQogICAgPT0KICAgIGFzc2VydCAvLyBleHBlY3RlZCBleGlzdHMgYnkgaW5kZXggdG8gbWF0Y2gKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czoyOTEKICAgIC8vIHJldHVybiB2YWx1ZQogICAgcmV0c3ViCgoKLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjpTdGF0ZUFwcFBhcmFtc0NvbnRyYWN0LnZlcmlmeV9hcHBfcGFyYW1zX2dldF9nbG9iYWxfbnVtX2J5dGVfc2xpY2UoYTogdWludDY0KSAtPiB1aW50NjQ6CnZlcmlmeV9hcHBfcGFyYW1zX2dldF9nbG9iYWxfbnVtX2J5dGVfc2xpY2U6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6Mjk0LTI5NQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIHB1YmxpYyB2ZXJpZnlfYXBwX3BhcmFtc19nZXRfZ2xvYmFsX251bV9ieXRlX3NsaWNlKGE6IEFwcGxpY2F0aW9uKTogdWludDY0IHsKICAgIHByb3RvIDEgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjI5NgogICAgLy8gY29uc3QgW3ZhbHVlLCBleGlzdHNdID0gb3AuQXBwUGFyYW1zLmFwcEdsb2JhbE51bUJ5dGVTbGljZShhKQogICAgZnJhbWVfZGlnIC0xCiAgICBhcHBfcGFyYW1zX2dldCBBcHBHbG9iYWxOdW1CeXRlU2xpY2UKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czoyOTcKICAgIC8vIGNvbnN0IFt2YWx1ZV9pbmRleCwgZXhpc3RzX2luZGV4XSA9IG9wLkFwcFBhcmFtcy5hcHBHbG9iYWxOdW1CeXRlU2xpY2UoZ2V0XzFzdF9yZWZfaW5kZXgoKSkKICAgIGNhbGxzdWIgZ2V0XzFzdF9yZWZfaW5kZXgKICAgIGFwcF9wYXJhbXNfZ2V0IEFwcEdsb2JhbE51bUJ5dGVTbGljZQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjI5OAogICAgLy8gYXNzZXJ0KHZhbHVlID09PSB2YWx1ZV9pbmRleCwgJ2V4cGVjdGVkIHZhbHVlIGJ5IGluZGV4IHRvIG1hdGNoJykKICAgIGRpZyAzCiAgICB1bmNvdmVyIDIKICAgID09CiAgICBhc3NlcnQgLy8gZXhwZWN0ZWQgdmFsdWUgYnkgaW5kZXggdG8gbWF0Y2gKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czoyOTkKICAgIC8vIGFzc2VydChleGlzdHMgPT09IGV4aXN0c19pbmRleCwgJ2V4cGVjdGVkIGV4aXN0cyBieSBpbmRleCB0byBtYXRjaCcpCiAgICA9PQogICAgYXNzZXJ0IC8vIGV4cGVjdGVkIGV4aXN0cyBieSBpbmRleCB0byBtYXRjaAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjMwMAogICAgLy8gcmV0dXJuIHZhbHVlCiAgICByZXRzdWIKCgovLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OlN0YXRlQXBwUGFyYW1zQ29udHJhY3QudmVyaWZ5X2FwcF9wYXJhbXNfZ2V0X2xvY2FsX251bV91aW50KGE6IHVpbnQ2NCkgLT4gdWludDY0Ogp2ZXJpZnlfYXBwX3BhcmFtc19nZXRfbG9jYWxfbnVtX3VpbnQ6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MzAzLTMwNAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIHB1YmxpYyB2ZXJpZnlfYXBwX3BhcmFtc19nZXRfbG9jYWxfbnVtX3VpbnQoYTogQXBwbGljYXRpb24pOiB1aW50NjQgewogICAgcHJvdG8gMSAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MzA1CiAgICAvLyBjb25zdCBbdmFsdWUsIGV4aXN0c10gPSBvcC5BcHBQYXJhbXMuYXBwTG9jYWxOdW1VaW50KGEpCiAgICBmcmFtZV9kaWcgLTEKICAgIGFwcF9wYXJhbXNfZ2V0IEFwcExvY2FsTnVtVWludAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjMwNgogICAgLy8gY29uc3QgW3ZhbHVlX2luZGV4LCBleGlzdHNfaW5kZXhdID0gb3AuQXBwUGFyYW1zLmFwcExvY2FsTnVtVWludChnZXRfMXN0X3JlZl9pbmRleCgpKQogICAgY2FsbHN1YiBnZXRfMXN0X3JlZl9pbmRleAogICAgYXBwX3BhcmFtc19nZXQgQXBwTG9jYWxOdW1VaW50CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MzA3CiAgICAvLyBhc3NlcnQodmFsdWUgPT09IHZhbHVlX2luZGV4LCAnZXhwZWN0ZWQgdmFsdWUgYnkgaW5kZXggdG8gbWF0Y2gnKQogICAgZGlnIDMKICAgIHVuY292ZXIgMgogICAgPT0KICAgIGFzc2VydCAvLyBleHBlY3RlZCB2YWx1ZSBieSBpbmRleCB0byBtYXRjaAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjMwOAogICAgLy8gYXNzZXJ0KGV4aXN0cyA9PT0gZXhpc3RzX2luZGV4LCAnZXhwZWN0ZWQgZXhpc3RzIGJ5IGluZGV4IHRvIG1hdGNoJykKICAgID09CiAgICBhc3NlcnQgLy8gZXhwZWN0ZWQgZXhpc3RzIGJ5IGluZGV4IHRvIG1hdGNoCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MzA5CiAgICAvLyByZXR1cm4gdmFsdWUKICAgIHJldHN1YgoKCi8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo6U3RhdGVBcHBQYXJhbXNDb250cmFjdC52ZXJpZnlfYXBwX3BhcmFtc19nZXRfbG9jYWxfbnVtX2J5dGVfc2xpY2UoYTogdWludDY0KSAtPiB1aW50NjQ6CnZlcmlmeV9hcHBfcGFyYW1zX2dldF9sb2NhbF9udW1fYnl0ZV9zbGljZToKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czozMTItMzEzCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gcHVibGljIHZlcmlmeV9hcHBfcGFyYW1zX2dldF9sb2NhbF9udW1fYnl0ZV9zbGljZShhOiBBcHBsaWNhdGlvbik6IHVpbnQ2NCB7CiAgICBwcm90byAxIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czozMTQKICAgIC8vIGNvbnN0IFt2YWx1ZSwgZXhpc3RzXSA9IG9wLkFwcFBhcmFtcy5hcHBMb2NhbE51bUJ5dGVTbGljZShhKQogICAgZnJhbWVfZGlnIC0xCiAgICBhcHBfcGFyYW1zX2dldCBBcHBMb2NhbE51bUJ5dGVTbGljZQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjMxNQogICAgLy8gY29uc3QgW3ZhbHVlX2luZGV4LCBleGlzdHNfaW5kZXhdID0gb3AuQXBwUGFyYW1zLmFwcExvY2FsTnVtQnl0ZVNsaWNlKGdldF8xc3RfcmVmX2luZGV4KCkpCiAgICBjYWxsc3ViIGdldF8xc3RfcmVmX2luZGV4CiAgICBhcHBfcGFyYW1zX2dldCBBcHBMb2NhbE51bUJ5dGVTbGljZQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjMxNgogICAgLy8gYXNzZXJ0KHZhbHVlID09PSB2YWx1ZV9pbmRleCwgJ2V4cGVjdGVkIHZhbHVlIGJ5IGluZGV4IHRvIG1hdGNoJykKICAgIGRpZyAzCiAgICB1bmNvdmVyIDIKICAgID09CiAgICBhc3NlcnQgLy8gZXhwZWN0ZWQgdmFsdWUgYnkgaW5kZXggdG8gbWF0Y2gKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czozMTcKICAgIC8vIGFzc2VydChleGlzdHMgPT09IGV4aXN0c19pbmRleCwgJ2V4cGVjdGVkIGV4aXN0cyBieSBpbmRleCB0byBtYXRjaCcpCiAgICA9PQogICAgYXNzZXJ0IC8vIGV4cGVjdGVkIGV4aXN0cyBieSBpbmRleCB0byBtYXRjaAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjMxOAogICAgLy8gcmV0dXJuIHZhbHVlCiAgICByZXRzdWIKCgovLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OlN0YXRlQXBwUGFyYW1zQ29udHJhY3QudmVyaWZ5X2FwcF9wYXJhbXNfZ2V0X2V4dHJhX3Byb2dyYW1fcGFnZXMoYTogdWludDY0KSAtPiB1aW50NjQ6CnZlcmlmeV9hcHBfcGFyYW1zX2dldF9leHRyYV9wcm9ncmFtX3BhZ2VzOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjMyMS0zMjIKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBwdWJsaWMgdmVyaWZ5X2FwcF9wYXJhbXNfZ2V0X2V4dHJhX3Byb2dyYW1fcGFnZXMoYTogQXBwbGljYXRpb24pOiB1aW50NjQgewogICAgcHJvdG8gMSAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MzIzCiAgICAvLyBjb25zdCBbdmFsdWUsIGV4aXN0c10gPSBvcC5BcHBQYXJhbXMuYXBwRXh0cmFQcm9ncmFtUGFnZXMoYSkKICAgIGZyYW1lX2RpZyAtMQogICAgYXBwX3BhcmFtc19nZXQgQXBwRXh0cmFQcm9ncmFtUGFnZXMKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czozMjQKICAgIC8vIGNvbnN0IFt2YWx1ZV9pbmRleCwgZXhpc3RzX2luZGV4XSA9IG9wLkFwcFBhcmFtcy5hcHBFeHRyYVByb2dyYW1QYWdlcyhnZXRfMXN0X3JlZl9pbmRleCgpKQogICAgY2FsbHN1YiBnZXRfMXN0X3JlZl9pbmRleAogICAgYXBwX3BhcmFtc19nZXQgQXBwRXh0cmFQcm9ncmFtUGFnZXMKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czozMjUKICAgIC8vIGFzc2VydCh2YWx1ZSA9PT0gdmFsdWVfaW5kZXgsICdleHBlY3RlZCB2YWx1ZSBieSBpbmRleCB0byBtYXRjaCcpCiAgICBkaWcgMwogICAgdW5jb3ZlciAyCiAgICA9PQogICAgYXNzZXJ0IC8vIGV4cGVjdGVkIHZhbHVlIGJ5IGluZGV4IHRvIG1hdGNoCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MzI2CiAgICAvLyBhc3NlcnQoZXhpc3RzID09PSBleGlzdHNfaW5kZXgsICdleHBlY3RlZCBleGlzdHMgYnkgaW5kZXggdG8gbWF0Y2gnKQogICAgPT0KICAgIGFzc2VydCAvLyBleHBlY3RlZCBleGlzdHMgYnkgaW5kZXggdG8gbWF0Y2gKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czozMjcKICAgIC8vIHJldHVybiB2YWx1ZQogICAgcmV0c3ViCgoKLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjpTdGF0ZUFwcFBhcmFtc0NvbnRyYWN0LnZlcmlmeV9hcHBfcGFyYW1zX2dldF9jcmVhdG9yKGE6IHVpbnQ2NCkgLT4gYnl0ZXM6CnZlcmlmeV9hcHBfcGFyYW1zX2dldF9jcmVhdG9yOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjMzMC0zMzEKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBwdWJsaWMgdmVyaWZ5X2FwcF9wYXJhbXNfZ2V0X2NyZWF0b3IoYTogQXBwbGljYXRpb24pOiBBZGRyZXNzIHsKICAgIHByb3RvIDEgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjMzMgogICAgLy8gY29uc3QgW3ZhbHVlLCBleGlzdHNdID0gb3AuQXBwUGFyYW1zLmFwcENyZWF0b3IoYSkKICAgIGZyYW1lX2RpZyAtMQogICAgYXBwX3BhcmFtc19nZXQgQXBwQ3JlYXRvcgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjMzMwogICAgLy8gY29uc3QgW3ZhbHVlX2luZGV4LCBleGlzdHNfaW5kZXhdID0gb3AuQXBwUGFyYW1zLmFwcENyZWF0b3IoZ2V0XzFzdF9yZWZfaW5kZXgoKSkKICAgIGNhbGxzdWIgZ2V0XzFzdF9yZWZfaW5kZXgKICAgIGFwcF9wYXJhbXNfZ2V0IEFwcENyZWF0b3IKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czozMzQKICAgIC8vIGFzc2VydCh2YWx1ZSA9PT0gdmFsdWVfaW5kZXgsICdleHBlY3RlZCB2YWx1ZSBieSBpbmRleCB0byBtYXRjaCcpCiAgICBkaWcgMwogICAgdW5jb3ZlciAyCiAgICA9PQogICAgYXNzZXJ0IC8vIGV4cGVjdGVkIHZhbHVlIGJ5IGluZGV4IHRvIG1hdGNoCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MzM1CiAgICAvLyBhc3NlcnQoZXhpc3RzID09PSBleGlzdHNfaW5kZXgsICdleHBlY3RlZCBleGlzdHMgYnkgaW5kZXggdG8gbWF0Y2gnKQogICAgPT0KICAgIGFzc2VydCAvLyBleHBlY3RlZCBleGlzdHMgYnkgaW5kZXggdG8gbWF0Y2gKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czozMzYKICAgIC8vIHJldHVybiBuZXcgQWRkcmVzcyh2YWx1ZSkKICAgIHJldHN1YgoKCi8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo6U3RhdGVBcHBQYXJhbXNDb250cmFjdC52ZXJpZnlfYXBwX3BhcmFtc19nZXRfYWRkcmVzcyhhOiB1aW50NjQpIC0+IGJ5dGVzOgp2ZXJpZnlfYXBwX3BhcmFtc19nZXRfYWRkcmVzczoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czozMzktMzQwCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gcHVibGljIHZlcmlmeV9hcHBfcGFyYW1zX2dldF9hZGRyZXNzKGE6IEFwcGxpY2F0aW9uKTogQWRkcmVzcyB7CiAgICBwcm90byAxIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czozNDEKICAgIC8vIGNvbnN0IFt2YWx1ZSwgZXhpc3RzXSA9IG9wLkFwcFBhcmFtcy5hcHBBZGRyZXNzKGEpCiAgICBmcmFtZV9kaWcgLTEKICAgIGFwcF9wYXJhbXNfZ2V0IEFwcEFkZHJlc3MKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czozNDIKICAgIC8vIGNvbnN0IFt2YWx1ZV9pbmRleCwgZXhpc3RzX2luZGV4XSA9IG9wLkFwcFBhcmFtcy5hcHBBZGRyZXNzKGdldF8xc3RfcmVmX2luZGV4KCkpCiAgICBjYWxsc3ViIGdldF8xc3RfcmVmX2luZGV4CiAgICBhcHBfcGFyYW1zX2dldCBBcHBBZGRyZXNzCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MzQzCiAgICAvLyBhc3NlcnQodmFsdWUuYnl0ZXMudG9TdHJpbmcoKSA9PT0gdmFsdWVfaW5kZXguYnl0ZXMudG9TdHJpbmcoKSwgJ2V4cGVjdGVkIHZhbHVlIGJ5IGluZGV4IHRvIG1hdGNoJykKICAgIGRpZyAzCiAgICB1bmNvdmVyIDIKICAgID09CiAgICBhc3NlcnQgLy8gZXhwZWN0ZWQgdmFsdWUgYnkgaW5kZXggdG8gbWF0Y2gKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czozNDQKICAgIC8vIGFzc2VydChleGlzdHMgPT09IGV4aXN0c19pbmRleCwgJ2V4cGVjdGVkIGV4aXN0cyBieSBpbmRleCB0byBtYXRjaCcpCiAgICA9PQogICAgYXNzZXJ0IC8vIGV4cGVjdGVkIGV4aXN0cyBieSBpbmRleCB0byBtYXRjaAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjM0NQogICAgLy8gcmV0dXJuIG5ldyBBZGRyZXNzKHZhbHVlKQogICAgcmV0c3ViCg==", - "clear": "I3ByYWdtYSB2ZXJzaW9uIDEwCgp0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OlN0YXRlQXBwUGFyYW1zQ29udHJhY3QuY2xlYXJTdGF0ZVByb2dyYW06CiAgICBwdXNoaW50IDEgLy8gMQogICAgcmV0dXJuCg==" - }, - "state": { - "global": { - "num_byte_slices": 0, - "num_uints": 0 - }, - "local": { - "num_byte_slices": 0, - "num_uints": 0 - } - }, - "schema": { - "global": { - "declared": {}, - "reserved": {} - }, - "local": { - "declared": {}, - "reserved": {} - } - }, - "contract": { - "name": "StateAppParamsContract", - "methods": [ - { - "name": "verify_app_params_get_approval_program", - "args": [ - { - "type": "application", - "name": "a" - } - ], - "readonly": false, - "returns": { - "type": "byte[]" - } - }, - { - "name": "verify_app_params_get_clear_state_program", - "args": [ - { - "type": "application", - "name": "a" - } - ], - "readonly": false, - "returns": { - "type": "byte[]" - } - }, - { - "name": "verify_app_params_get_global_num_uint", - "args": [ - { - "type": "application", - "name": "a" - } - ], - "readonly": false, - "returns": { - "type": "uint64" - } - }, - { - "name": "verify_app_params_get_global_num_byte_slice", - "args": [ - { - "type": "application", - "name": "a" - } - ], - "readonly": false, - "returns": { - "type": "uint64" - } - }, - { - "name": "verify_app_params_get_local_num_uint", - "args": [ - { - "type": "application", - "name": "a" - } - ], - "readonly": false, - "returns": { - "type": "uint64" - } - }, - { - "name": "verify_app_params_get_local_num_byte_slice", - "args": [ - { - "type": "application", - "name": "a" - } - ], - "readonly": false, - "returns": { - "type": "uint64" - } - }, - { - "name": "verify_app_params_get_extra_program_pages", - "args": [ - { - "type": "application", - "name": "a" - } - ], - "readonly": false, - "returns": { - "type": "uint64" - } - }, - { - "name": "verify_app_params_get_creator", - "args": [ - { - "type": "application", - "name": "a" - } - ], - "readonly": false, - "returns": { - "type": "address" - } - }, - { - "name": "verify_app_params_get_address", - "args": [ - { - "type": "application", - "name": "a" - } - ], - "readonly": false, - "returns": { - "type": "address" - } - } - ], - "networks": {} - }, - "bare_call_config": { - "no_op": "CREATE" - } -} \ No newline at end of file diff --git a/tests/artifacts/state-ops/data/StateAppParamsContract.arc56.json b/tests/artifacts/state-ops/data/StateAppParamsContract.arc56.json deleted file mode 100644 index 83355d7..0000000 --- a/tests/artifacts/state-ops/data/StateAppParamsContract.arc56.json +++ /dev/null @@ -1,307 +0,0 @@ -{ - "name": "StateAppParamsContract", - "structs": {}, - "methods": [ - { - "name": "verify_app_params_get_approval_program", - "args": [ - { - "type": "application", - "name": "a" - } - ], - "returns": { - "type": "byte[]" - }, - "actions": { - "create": [], - "call": [ - "NoOp" - ] - }, - "readonly": false, - "events": [], - "recommendations": {} - }, - { - "name": "verify_app_params_get_clear_state_program", - "args": [ - { - "type": "application", - "name": "a" - } - ], - "returns": { - "type": "byte[]" - }, - "actions": { - "create": [], - "call": [ - "NoOp" - ] - }, - "readonly": false, - "events": [], - "recommendations": {} - }, - { - "name": "verify_app_params_get_global_num_uint", - "args": [ - { - "type": "application", - "name": "a" - } - ], - "returns": { - "type": "uint64" - }, - "actions": { - "create": [], - "call": [ - "NoOp" - ] - }, - "readonly": false, - "events": [], - "recommendations": {} - }, - { - "name": "verify_app_params_get_global_num_byte_slice", - "args": [ - { - "type": "application", - "name": "a" - } - ], - "returns": { - "type": "uint64" - }, - "actions": { - "create": [], - "call": [ - "NoOp" - ] - }, - "readonly": false, - "events": [], - "recommendations": {} - }, - { - "name": "verify_app_params_get_local_num_uint", - "args": [ - { - "type": "application", - "name": "a" - } - ], - "returns": { - "type": "uint64" - }, - "actions": { - "create": [], - "call": [ - "NoOp" - ] - }, - "readonly": false, - "events": [], - "recommendations": {} - }, - { - "name": "verify_app_params_get_local_num_byte_slice", - "args": [ - { - "type": "application", - "name": "a" - } - ], - "returns": { - "type": "uint64" - }, - "actions": { - "create": [], - "call": [ - "NoOp" - ] - }, - "readonly": false, - "events": [], - "recommendations": {} - }, - { - "name": "verify_app_params_get_extra_program_pages", - "args": [ - { - "type": "application", - "name": "a" - } - ], - "returns": { - "type": "uint64" - }, - "actions": { - "create": [], - "call": [ - "NoOp" - ] - }, - "readonly": false, - "events": [], - "recommendations": {} - }, - { - "name": "verify_app_params_get_creator", - "args": [ - { - "type": "application", - "name": "a" - } - ], - "returns": { - "type": "address" - }, - "actions": { - "create": [], - "call": [ - "NoOp" - ] - }, - "readonly": false, - "events": [], - "recommendations": {} - }, - { - "name": "verify_app_params_get_address", - "args": [ - { - "type": "application", - "name": "a" - } - ], - "returns": { - "type": "address" - }, - "actions": { - "create": [], - "call": [ - "NoOp" - ] - }, - "readonly": false, - "events": [], - "recommendations": {} - } - ], - "arcs": [ - 22, - 28 - ], - "networks": {}, - "state": { - "schema": { - "global": { - "ints": 0, - "bytes": 0 - }, - "local": { - "ints": 0, - "bytes": 0 - } - }, - "keys": { - "global": {}, - "local": {}, - "box": {} - }, - "maps": { - "global": {}, - "local": {}, - "box": {} - } - }, - "bareActions": { - "create": [ - "NoOp" - ], - "call": [] - }, - "sourceInfo": { - "approval": { - "sourceInfo": [ - { - "pc": [ - 99, - 129, - 159, - 182, - 205, - 228, - 251, - 274, - 296 - ], - "errorMessage": "OnCompletion is not NoOp" - }, - { - "pc": [ - 323 - ], - "errorMessage": "can only call when creating" - }, - { - "pc": [ - 102, - 132, - 162, - 185, - 208, - 231, - 254, - 277, - 299 - ], - "errorMessage": "can only call when not creating" - }, - { - "pc": [ - 347, - 376, - 397, - 418, - 439, - 460, - 481, - 502, - 523 - ], - "errorMessage": "expected exists by index to match" - }, - { - "pc": [ - 345, - 374, - 395, - 416, - 437, - 458, - 479, - 500, - 521 - ], - "errorMessage": "expected value by index to match" - } - ], - "pcOffsetMethod": "none" - }, - "clear": { - "sourceInfo": [], - "pcOffsetMethod": "none" - } - }, - "source": { - "approval": "I3ByYWdtYSB2ZXJzaW9uIDEwCgp0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OlN0YXRlQXBwUGFyYW1zQ29udHJhY3QuYXBwcm92YWxQcm9ncmFtOgogICAgaW50Y2Jsb2NrIDEgMAogICAgYnl0ZWNibG9jayAweDE1MWY3Yzc1CiAgICBjYWxsc3ViIF9fcHV5YV9hcmM0X3JvdXRlcl9fCiAgICByZXR1cm4KCgovLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OlN0YXRlQXBwUGFyYW1zQ29udHJhY3QuX19wdXlhX2FyYzRfcm91dGVyX18oKSAtPiB1aW50NjQ6Cl9fcHV5YV9hcmM0X3JvdXRlcl9fOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjI2NgogICAgLy8gZXhwb3J0IGNsYXNzIFN0YXRlQXBwUGFyYW1zQ29udHJhY3QgZXh0ZW5kcyBhcmM0LkNvbnRyYWN0IHsKICAgIHByb3RvIDAgMQogICAgdHhuIE51bUFwcEFyZ3MKICAgIGJ6IF9fcHV5YV9hcmM0X3JvdXRlcl9fX2JhcmVfcm91dGluZ0AxMwogICAgcHVzaGJ5dGVzcyAweDVlN2I3ZDUyIDB4ZTI5ZTMwZWUgMHg1ODgxOTA5OSAweGNhNzdiNTliIDB4NTNjMGRkOWIgMHg1ZjAwMDcwMyAweGQ3N2JkMjFmIDB4YTk0MWE3NDYgMHhiZDNlOWVlYyAvLyBtZXRob2QgInZlcmlmeV9hcHBfcGFyYW1zX2dldF9hcHByb3ZhbF9wcm9ncmFtKGFwcGxpY2F0aW9uKWJ5dGVbXSIsIG1ldGhvZCAidmVyaWZ5X2FwcF9wYXJhbXNfZ2V0X2NsZWFyX3N0YXRlX3Byb2dyYW0oYXBwbGljYXRpb24pYnl0ZVtdIiwgbWV0aG9kICJ2ZXJpZnlfYXBwX3BhcmFtc19nZXRfZ2xvYmFsX251bV91aW50KGFwcGxpY2F0aW9uKXVpbnQ2NCIsIG1ldGhvZCAidmVyaWZ5X2FwcF9wYXJhbXNfZ2V0X2dsb2JhbF9udW1fYnl0ZV9zbGljZShhcHBsaWNhdGlvbil1aW50NjQiLCBtZXRob2QgInZlcmlmeV9hcHBfcGFyYW1zX2dldF9sb2NhbF9udW1fdWludChhcHBsaWNhdGlvbil1aW50NjQiLCBtZXRob2QgInZlcmlmeV9hcHBfcGFyYW1zX2dldF9sb2NhbF9udW1fYnl0ZV9zbGljZShhcHBsaWNhdGlvbil1aW50NjQiLCBtZXRob2QgInZlcmlmeV9hcHBfcGFyYW1zX2dldF9leHRyYV9wcm9ncmFtX3BhZ2VzKGFwcGxpY2F0aW9uKXVpbnQ2NCIsIG1ldGhvZCAidmVyaWZ5X2FwcF9wYXJhbXNfZ2V0X2NyZWF0b3IoYXBwbGljYXRpb24pYWRkcmVzcyIsIG1ldGhvZCAidmVyaWZ5X2FwcF9wYXJhbXNfZ2V0X2FkZHJlc3MoYXBwbGljYXRpb24pYWRkcmVzcyIKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDAKICAgIG1hdGNoIF9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9hcHBfcGFyYW1zX2dldF9hcHByb3ZhbF9wcm9ncmFtX3JvdXRlQDIgX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2FwcF9wYXJhbXNfZ2V0X2NsZWFyX3N0YXRlX3Byb2dyYW1fcm91dGVAMyBfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfYXBwX3BhcmFtc19nZXRfZ2xvYmFsX251bV91aW50X3JvdXRlQDQgX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2FwcF9wYXJhbXNfZ2V0X2dsb2JhbF9udW1fYnl0ZV9zbGljZV9yb3V0ZUA1IF9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9hcHBfcGFyYW1zX2dldF9sb2NhbF9udW1fdWludF9yb3V0ZUA2IF9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9hcHBfcGFyYW1zX2dldF9sb2NhbF9udW1fYnl0ZV9zbGljZV9yb3V0ZUA3IF9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9hcHBfcGFyYW1zX2dldF9leHRyYV9wcm9ncmFtX3BhZ2VzX3JvdXRlQDggX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2FwcF9wYXJhbXNfZ2V0X2NyZWF0b3Jfcm91dGVAOSBfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfYXBwX3BhcmFtc19nZXRfYWRkcmVzc19yb3V0ZUAxMAogICAgaW50Y18xIC8vIDAKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2FwcF9wYXJhbXNfZ2V0X2FwcHJvdmFsX3Byb2dyYW1fcm91dGVAMjoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czoyNjcKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIG5vdCBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGNhbiBvbmx5IGNhbGwgd2hlbiBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czoyNjYKICAgIC8vIGV4cG9ydCBjbGFzcyBTdGF0ZUFwcFBhcmFtc0NvbnRyYWN0IGV4dGVuZHMgYXJjNC5Db250cmFjdCB7CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBidG9pCiAgICB0eG5hcyBBcHBsaWNhdGlvbnMKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czoyNjcKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV9hcHBfcGFyYW1zX2dldF9hcHByb3ZhbF9wcm9ncmFtCiAgICBkdXAKICAgIGxlbgogICAgaXRvYgogICAgZXh0cmFjdCA2IDIKICAgIHN3YXAKICAgIGNvbmNhdAogICAgYnl0ZWNfMCAvLyAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50Y18wIC8vIDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2FwcF9wYXJhbXNfZ2V0X2NsZWFyX3N0YXRlX3Byb2dyYW1fcm91dGVAMzoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czoyNzYKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIG5vdCBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGNhbiBvbmx5IGNhbGwgd2hlbiBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czoyNjYKICAgIC8vIGV4cG9ydCBjbGFzcyBTdGF0ZUFwcFBhcmFtc0NvbnRyYWN0IGV4dGVuZHMgYXJjNC5Db250cmFjdCB7CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBidG9pCiAgICB0eG5hcyBBcHBsaWNhdGlvbnMKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czoyNzYKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV9hcHBfcGFyYW1zX2dldF9jbGVhcl9zdGF0ZV9wcm9ncmFtCiAgICBkdXAKICAgIGxlbgogICAgaXRvYgogICAgZXh0cmFjdCA2IDIKICAgIHN3YXAKICAgIGNvbmNhdAogICAgYnl0ZWNfMCAvLyAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50Y18wIC8vIDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2FwcF9wYXJhbXNfZ2V0X2dsb2JhbF9udW1fdWludF9yb3V0ZUA0OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjI4NQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgbm90IE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gY2FuIG9ubHkgY2FsbCB3aGVuIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjI2NgogICAgLy8gZXhwb3J0IGNsYXNzIFN0YXRlQXBwUGFyYW1zQ29udHJhY3QgZXh0ZW5kcyBhcmM0LkNvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGJ0b2kKICAgIHR4bmFzIEFwcGxpY2F0aW9ucwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjI4NQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X2FwcF9wYXJhbXNfZ2V0X2dsb2JhbF9udW1fdWludAogICAgaXRvYgogICAgYnl0ZWNfMCAvLyAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50Y18wIC8vIDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2FwcF9wYXJhbXNfZ2V0X2dsb2JhbF9udW1fYnl0ZV9zbGljZV9yb3V0ZUA1OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjI5NAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgbm90IE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gY2FuIG9ubHkgY2FsbCB3aGVuIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjI2NgogICAgLy8gZXhwb3J0IGNsYXNzIFN0YXRlQXBwUGFyYW1zQ29udHJhY3QgZXh0ZW5kcyBhcmM0LkNvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGJ0b2kKICAgIHR4bmFzIEFwcGxpY2F0aW9ucwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjI5NAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X2FwcF9wYXJhbXNfZ2V0X2dsb2JhbF9udW1fYnl0ZV9zbGljZQogICAgaXRvYgogICAgYnl0ZWNfMCAvLyAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50Y18wIC8vIDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2FwcF9wYXJhbXNfZ2V0X2xvY2FsX251bV91aW50X3JvdXRlQDY6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MzAzCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBub3QgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBjYW4gb25seSBjYWxsIHdoZW4gbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MjY2CiAgICAvLyBleHBvcnQgY2xhc3MgU3RhdGVBcHBQYXJhbXNDb250cmFjdCBleHRlbmRzIGFyYzQuQ29udHJhY3QgewogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgYnRvaQogICAgdHhuYXMgQXBwbGljYXRpb25zCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MzAzCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfYXBwX3BhcmFtc19nZXRfbG9jYWxfbnVtX3VpbnQKICAgIGl0b2IKICAgIGJ5dGVjXzAgLy8gMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludGNfMCAvLyAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9hcHBfcGFyYW1zX2dldF9sb2NhbF9udW1fYnl0ZV9zbGljZV9yb3V0ZUA3OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjMxMgogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgbm90IE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gY2FuIG9ubHkgY2FsbCB3aGVuIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjI2NgogICAgLy8gZXhwb3J0IGNsYXNzIFN0YXRlQXBwUGFyYW1zQ29udHJhY3QgZXh0ZW5kcyBhcmM0LkNvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGJ0b2kKICAgIHR4bmFzIEFwcGxpY2F0aW9ucwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjMxMgogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X2FwcF9wYXJhbXNfZ2V0X2xvY2FsX251bV9ieXRlX3NsaWNlCiAgICBpdG9iCiAgICBieXRlY18wIC8vIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnRjXzAgLy8gMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfYXBwX3BhcmFtc19nZXRfZXh0cmFfcHJvZ3JhbV9wYWdlc19yb3V0ZUA4OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjMyMQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgbm90IE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gY2FuIG9ubHkgY2FsbCB3aGVuIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjI2NgogICAgLy8gZXhwb3J0IGNsYXNzIFN0YXRlQXBwUGFyYW1zQ29udHJhY3QgZXh0ZW5kcyBhcmM0LkNvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGJ0b2kKICAgIHR4bmFzIEFwcGxpY2F0aW9ucwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjMyMQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X2FwcF9wYXJhbXNfZ2V0X2V4dHJhX3Byb2dyYW1fcGFnZXMKICAgIGl0b2IKICAgIGJ5dGVjXzAgLy8gMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludGNfMCAvLyAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9hcHBfcGFyYW1zX2dldF9jcmVhdG9yX3JvdXRlQDk6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MzMwCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBub3QgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBjYW4gb25seSBjYWxsIHdoZW4gbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MjY2CiAgICAvLyBleHBvcnQgY2xhc3MgU3RhdGVBcHBQYXJhbXNDb250cmFjdCBleHRlbmRzIGFyYzQuQ29udHJhY3QgewogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgYnRvaQogICAgdHhuYXMgQXBwbGljYXRpb25zCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MzMwCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfYXBwX3BhcmFtc19nZXRfY3JlYXRvcgogICAgYnl0ZWNfMCAvLyAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50Y18wIC8vIDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2FwcF9wYXJhbXNfZ2V0X2FkZHJlc3Nfcm91dGVAMTA6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MzM5CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBub3QgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBjYW4gb25seSBjYWxsIHdoZW4gbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MjY2CiAgICAvLyBleHBvcnQgY2xhc3MgU3RhdGVBcHBQYXJhbXNDb250cmFjdCBleHRlbmRzIGFyYzQuQ29udHJhY3QgewogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgYnRvaQogICAgdHhuYXMgQXBwbGljYXRpb25zCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MzM5CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfYXBwX3BhcmFtc19nZXRfYWRkcmVzcwogICAgYnl0ZWNfMCAvLyAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50Y18wIC8vIDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fYmFyZV9yb3V0aW5nQDEzOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjI2NgogICAgLy8gZXhwb3J0IGNsYXNzIFN0YXRlQXBwUGFyYW1zQ29udHJhY3QgZXh0ZW5kcyBhcmM0LkNvbnRyYWN0IHsKICAgIHR4biBPbkNvbXBsZXRpb24KICAgIGJueiBfX3B1eWFfYXJjNF9yb3V0ZXJfX19hZnRlcl9pZl9lbHNlQDE3CiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgIQogICAgYXNzZXJ0IC8vIGNhbiBvbmx5IGNhbGwgd2hlbiBjcmVhdGluZwogICAgaW50Y18wIC8vIDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fYWZ0ZXJfaWZfZWxzZUAxNzoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czoyNjYKICAgIC8vIGV4cG9ydCBjbGFzcyBTdGF0ZUFwcFBhcmFtc0NvbnRyYWN0IGV4dGVuZHMgYXJjNC5Db250cmFjdCB7CiAgICBpbnRjXzEgLy8gMAogICAgcmV0c3ViCgoKLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjpTdGF0ZUFwcFBhcmFtc0NvbnRyYWN0LnZlcmlmeV9hcHBfcGFyYW1zX2dldF9hcHByb3ZhbF9wcm9ncmFtKGE6IHVpbnQ2NCkgLT4gYnl0ZXM6CnZlcmlmeV9hcHBfcGFyYW1zX2dldF9hcHByb3ZhbF9wcm9ncmFtOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjI2Ny0yNjgKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBwdWJsaWMgdmVyaWZ5X2FwcF9wYXJhbXNfZ2V0X2FwcHJvdmFsX3Byb2dyYW0oYTogQXBwbGljYXRpb24pOiBieXRlcyB7CiAgICBwcm90byAxIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czoyNjkKICAgIC8vIGNvbnN0IFt2YWx1ZSwgZXhpc3RzXSA9IG9wLkFwcFBhcmFtcy5hcHBBcHByb3ZhbFByb2dyYW0oYSkKICAgIGZyYW1lX2RpZyAtMQogICAgYXBwX3BhcmFtc19nZXQgQXBwQXBwcm92YWxQcm9ncmFtCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MjcwCiAgICAvLyBjb25zdCBbdmFsdWVfaW5kZXgsIGV4aXN0c19pbmRleF0gPSBvcC5BcHBQYXJhbXMuYXBwQXBwcm92YWxQcm9ncmFtKGdldF8xc3RfcmVmX2luZGV4KCkpCiAgICBjYWxsc3ViIGdldF8xc3RfcmVmX2luZGV4CiAgICBhcHBfcGFyYW1zX2dldCBBcHBBcHByb3ZhbFByb2dyYW0KICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czoyNzEKICAgIC8vIGFzc2VydCh2YWx1ZSA9PT0gdmFsdWVfaW5kZXgsICdleHBlY3RlZCB2YWx1ZSBieSBpbmRleCB0byBtYXRjaCcpCiAgICBkaWcgMwogICAgdW5jb3ZlciAyCiAgICA9PQogICAgYXNzZXJ0IC8vIGV4cGVjdGVkIHZhbHVlIGJ5IGluZGV4IHRvIG1hdGNoCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MjcyCiAgICAvLyBhc3NlcnQoZXhpc3RzID09PSBleGlzdHNfaW5kZXgsICdleHBlY3RlZCBleGlzdHMgYnkgaW5kZXggdG8gbWF0Y2gnKQogICAgPT0KICAgIGFzc2VydCAvLyBleHBlY3RlZCBleGlzdHMgYnkgaW5kZXggdG8gbWF0Y2gKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czoyNzMKICAgIC8vIHJldHVybiB2YWx1ZQogICAgcmV0c3ViCgoKLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjpnZXRfMXN0X3JlZl9pbmRleCgpIC0+IHVpbnQ2NDoKZ2V0XzFzdF9yZWZfaW5kZXg6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MjIKICAgIC8vIGZ1bmN0aW9uIGdldF8xc3RfcmVmX2luZGV4KCk6IHVpbnQ2NCB7CiAgICBwcm90byAwIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czoyMwogICAgLy8gcmV0dXJuIG9wLmJ0b2koVHhuLmFwcGxpY2F0aW9uQXJncygxKSkKICAgIGludGNfMCAvLyAxCiAgICB0eG5hcyBBcHBsaWNhdGlvbkFyZ3MKICAgIGJ0b2kKICAgIHJldHN1YgoKCi8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo6U3RhdGVBcHBQYXJhbXNDb250cmFjdC52ZXJpZnlfYXBwX3BhcmFtc19nZXRfY2xlYXJfc3RhdGVfcHJvZ3JhbShhOiB1aW50NjQpIC0+IGJ5dGVzOgp2ZXJpZnlfYXBwX3BhcmFtc19nZXRfY2xlYXJfc3RhdGVfcHJvZ3JhbToKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czoyNzYtMjc3CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gcHVibGljIHZlcmlmeV9hcHBfcGFyYW1zX2dldF9jbGVhcl9zdGF0ZV9wcm9ncmFtKGE6IEFwcGxpY2F0aW9uKTogYnl0ZXMgewogICAgcHJvdG8gMSAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6Mjc4CiAgICAvLyBjb25zdCBbdmFsdWUsIGV4aXN0c10gPSBvcC5BcHBQYXJhbXMuYXBwQ2xlYXJTdGF0ZVByb2dyYW0oYSkKICAgIGZyYW1lX2RpZyAtMQogICAgYXBwX3BhcmFtc19nZXQgQXBwQ2xlYXJTdGF0ZVByb2dyYW0KICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czoyNzkKICAgIC8vIGNvbnN0IFt2YWx1ZV9pbmRleCwgZXhpc3RzX2luZGV4XSA9IG9wLkFwcFBhcmFtcy5hcHBDbGVhclN0YXRlUHJvZ3JhbShnZXRfMXN0X3JlZl9pbmRleCgpKQogICAgY2FsbHN1YiBnZXRfMXN0X3JlZl9pbmRleAogICAgYXBwX3BhcmFtc19nZXQgQXBwQ2xlYXJTdGF0ZVByb2dyYW0KICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czoyODAKICAgIC8vIGFzc2VydCh2YWx1ZSA9PT0gdmFsdWVfaW5kZXgsICdleHBlY3RlZCB2YWx1ZSBieSBpbmRleCB0byBtYXRjaCcpCiAgICBkaWcgMwogICAgdW5jb3ZlciAyCiAgICA9PQogICAgYXNzZXJ0IC8vIGV4cGVjdGVkIHZhbHVlIGJ5IGluZGV4IHRvIG1hdGNoCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MjgxCiAgICAvLyBhc3NlcnQoZXhpc3RzID09PSBleGlzdHNfaW5kZXgsICdleHBlY3RlZCBleGlzdHMgYnkgaW5kZXggdG8gbWF0Y2gnKQogICAgPT0KICAgIGFzc2VydCAvLyBleHBlY3RlZCBleGlzdHMgYnkgaW5kZXggdG8gbWF0Y2gKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czoyODIKICAgIC8vIHJldHVybiB2YWx1ZQogICAgcmV0c3ViCgoKLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjpTdGF0ZUFwcFBhcmFtc0NvbnRyYWN0LnZlcmlmeV9hcHBfcGFyYW1zX2dldF9nbG9iYWxfbnVtX3VpbnQoYTogdWludDY0KSAtPiB1aW50NjQ6CnZlcmlmeV9hcHBfcGFyYW1zX2dldF9nbG9iYWxfbnVtX3VpbnQ6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6Mjg1LTI4NgogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIHB1YmxpYyB2ZXJpZnlfYXBwX3BhcmFtc19nZXRfZ2xvYmFsX251bV91aW50KGE6IEFwcGxpY2F0aW9uKTogdWludDY0IHsKICAgIHByb3RvIDEgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjI4NwogICAgLy8gY29uc3QgW3ZhbHVlLCBleGlzdHNdID0gb3AuQXBwUGFyYW1zLmFwcEdsb2JhbE51bVVpbnQoYSkKICAgIGZyYW1lX2RpZyAtMQogICAgYXBwX3BhcmFtc19nZXQgQXBwR2xvYmFsTnVtVWludAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjI4OAogICAgLy8gY29uc3QgW3ZhbHVlX2luZGV4LCBleGlzdHNfaW5kZXhdID0gb3AuQXBwUGFyYW1zLmFwcEdsb2JhbE51bVVpbnQoZ2V0XzFzdF9yZWZfaW5kZXgoKSkKICAgIGNhbGxzdWIgZ2V0XzFzdF9yZWZfaW5kZXgKICAgIGFwcF9wYXJhbXNfZ2V0IEFwcEdsb2JhbE51bVVpbnQKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czoyODkKICAgIC8vIGFzc2VydCh2YWx1ZSA9PT0gdmFsdWVfaW5kZXgsICdleHBlY3RlZCB2YWx1ZSBieSBpbmRleCB0byBtYXRjaCcpCiAgICBkaWcgMwogICAgdW5jb3ZlciAyCiAgICA9PQogICAgYXNzZXJ0IC8vIGV4cGVjdGVkIHZhbHVlIGJ5IGluZGV4IHRvIG1hdGNoCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MjkwCiAgICAvLyBhc3NlcnQoZXhpc3RzID09PSBleGlzdHNfaW5kZXgsICdleHBlY3RlZCBleGlzdHMgYnkgaW5kZXggdG8gbWF0Y2gnKQogICAgPT0KICAgIGFzc2VydCAvLyBleHBlY3RlZCBleGlzdHMgYnkgaW5kZXggdG8gbWF0Y2gKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czoyOTEKICAgIC8vIHJldHVybiB2YWx1ZQogICAgcmV0c3ViCgoKLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjpTdGF0ZUFwcFBhcmFtc0NvbnRyYWN0LnZlcmlmeV9hcHBfcGFyYW1zX2dldF9nbG9iYWxfbnVtX2J5dGVfc2xpY2UoYTogdWludDY0KSAtPiB1aW50NjQ6CnZlcmlmeV9hcHBfcGFyYW1zX2dldF9nbG9iYWxfbnVtX2J5dGVfc2xpY2U6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6Mjk0LTI5NQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIHB1YmxpYyB2ZXJpZnlfYXBwX3BhcmFtc19nZXRfZ2xvYmFsX251bV9ieXRlX3NsaWNlKGE6IEFwcGxpY2F0aW9uKTogdWludDY0IHsKICAgIHByb3RvIDEgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjI5NgogICAgLy8gY29uc3QgW3ZhbHVlLCBleGlzdHNdID0gb3AuQXBwUGFyYW1zLmFwcEdsb2JhbE51bUJ5dGVTbGljZShhKQogICAgZnJhbWVfZGlnIC0xCiAgICBhcHBfcGFyYW1zX2dldCBBcHBHbG9iYWxOdW1CeXRlU2xpY2UKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czoyOTcKICAgIC8vIGNvbnN0IFt2YWx1ZV9pbmRleCwgZXhpc3RzX2luZGV4XSA9IG9wLkFwcFBhcmFtcy5hcHBHbG9iYWxOdW1CeXRlU2xpY2UoZ2V0XzFzdF9yZWZfaW5kZXgoKSkKICAgIGNhbGxzdWIgZ2V0XzFzdF9yZWZfaW5kZXgKICAgIGFwcF9wYXJhbXNfZ2V0IEFwcEdsb2JhbE51bUJ5dGVTbGljZQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjI5OAogICAgLy8gYXNzZXJ0KHZhbHVlID09PSB2YWx1ZV9pbmRleCwgJ2V4cGVjdGVkIHZhbHVlIGJ5IGluZGV4IHRvIG1hdGNoJykKICAgIGRpZyAzCiAgICB1bmNvdmVyIDIKICAgID09CiAgICBhc3NlcnQgLy8gZXhwZWN0ZWQgdmFsdWUgYnkgaW5kZXggdG8gbWF0Y2gKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czoyOTkKICAgIC8vIGFzc2VydChleGlzdHMgPT09IGV4aXN0c19pbmRleCwgJ2V4cGVjdGVkIGV4aXN0cyBieSBpbmRleCB0byBtYXRjaCcpCiAgICA9PQogICAgYXNzZXJ0IC8vIGV4cGVjdGVkIGV4aXN0cyBieSBpbmRleCB0byBtYXRjaAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjMwMAogICAgLy8gcmV0dXJuIHZhbHVlCiAgICByZXRzdWIKCgovLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OlN0YXRlQXBwUGFyYW1zQ29udHJhY3QudmVyaWZ5X2FwcF9wYXJhbXNfZ2V0X2xvY2FsX251bV91aW50KGE6IHVpbnQ2NCkgLT4gdWludDY0Ogp2ZXJpZnlfYXBwX3BhcmFtc19nZXRfbG9jYWxfbnVtX3VpbnQ6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MzAzLTMwNAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIHB1YmxpYyB2ZXJpZnlfYXBwX3BhcmFtc19nZXRfbG9jYWxfbnVtX3VpbnQoYTogQXBwbGljYXRpb24pOiB1aW50NjQgewogICAgcHJvdG8gMSAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MzA1CiAgICAvLyBjb25zdCBbdmFsdWUsIGV4aXN0c10gPSBvcC5BcHBQYXJhbXMuYXBwTG9jYWxOdW1VaW50KGEpCiAgICBmcmFtZV9kaWcgLTEKICAgIGFwcF9wYXJhbXNfZ2V0IEFwcExvY2FsTnVtVWludAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjMwNgogICAgLy8gY29uc3QgW3ZhbHVlX2luZGV4LCBleGlzdHNfaW5kZXhdID0gb3AuQXBwUGFyYW1zLmFwcExvY2FsTnVtVWludChnZXRfMXN0X3JlZl9pbmRleCgpKQogICAgY2FsbHN1YiBnZXRfMXN0X3JlZl9pbmRleAogICAgYXBwX3BhcmFtc19nZXQgQXBwTG9jYWxOdW1VaW50CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MzA3CiAgICAvLyBhc3NlcnQodmFsdWUgPT09IHZhbHVlX2luZGV4LCAnZXhwZWN0ZWQgdmFsdWUgYnkgaW5kZXggdG8gbWF0Y2gnKQogICAgZGlnIDMKICAgIHVuY292ZXIgMgogICAgPT0KICAgIGFzc2VydCAvLyBleHBlY3RlZCB2YWx1ZSBieSBpbmRleCB0byBtYXRjaAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjMwOAogICAgLy8gYXNzZXJ0KGV4aXN0cyA9PT0gZXhpc3RzX2luZGV4LCAnZXhwZWN0ZWQgZXhpc3RzIGJ5IGluZGV4IHRvIG1hdGNoJykKICAgID09CiAgICBhc3NlcnQgLy8gZXhwZWN0ZWQgZXhpc3RzIGJ5IGluZGV4IHRvIG1hdGNoCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MzA5CiAgICAvLyByZXR1cm4gdmFsdWUKICAgIHJldHN1YgoKCi8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo6U3RhdGVBcHBQYXJhbXNDb250cmFjdC52ZXJpZnlfYXBwX3BhcmFtc19nZXRfbG9jYWxfbnVtX2J5dGVfc2xpY2UoYTogdWludDY0KSAtPiB1aW50NjQ6CnZlcmlmeV9hcHBfcGFyYW1zX2dldF9sb2NhbF9udW1fYnl0ZV9zbGljZToKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czozMTItMzEzCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gcHVibGljIHZlcmlmeV9hcHBfcGFyYW1zX2dldF9sb2NhbF9udW1fYnl0ZV9zbGljZShhOiBBcHBsaWNhdGlvbik6IHVpbnQ2NCB7CiAgICBwcm90byAxIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czozMTQKICAgIC8vIGNvbnN0IFt2YWx1ZSwgZXhpc3RzXSA9IG9wLkFwcFBhcmFtcy5hcHBMb2NhbE51bUJ5dGVTbGljZShhKQogICAgZnJhbWVfZGlnIC0xCiAgICBhcHBfcGFyYW1zX2dldCBBcHBMb2NhbE51bUJ5dGVTbGljZQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjMxNQogICAgLy8gY29uc3QgW3ZhbHVlX2luZGV4LCBleGlzdHNfaW5kZXhdID0gb3AuQXBwUGFyYW1zLmFwcExvY2FsTnVtQnl0ZVNsaWNlKGdldF8xc3RfcmVmX2luZGV4KCkpCiAgICBjYWxsc3ViIGdldF8xc3RfcmVmX2luZGV4CiAgICBhcHBfcGFyYW1zX2dldCBBcHBMb2NhbE51bUJ5dGVTbGljZQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjMxNgogICAgLy8gYXNzZXJ0KHZhbHVlID09PSB2YWx1ZV9pbmRleCwgJ2V4cGVjdGVkIHZhbHVlIGJ5IGluZGV4IHRvIG1hdGNoJykKICAgIGRpZyAzCiAgICB1bmNvdmVyIDIKICAgID09CiAgICBhc3NlcnQgLy8gZXhwZWN0ZWQgdmFsdWUgYnkgaW5kZXggdG8gbWF0Y2gKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czozMTcKICAgIC8vIGFzc2VydChleGlzdHMgPT09IGV4aXN0c19pbmRleCwgJ2V4cGVjdGVkIGV4aXN0cyBieSBpbmRleCB0byBtYXRjaCcpCiAgICA9PQogICAgYXNzZXJ0IC8vIGV4cGVjdGVkIGV4aXN0cyBieSBpbmRleCB0byBtYXRjaAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjMxOAogICAgLy8gcmV0dXJuIHZhbHVlCiAgICByZXRzdWIKCgovLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OlN0YXRlQXBwUGFyYW1zQ29udHJhY3QudmVyaWZ5X2FwcF9wYXJhbXNfZ2V0X2V4dHJhX3Byb2dyYW1fcGFnZXMoYTogdWludDY0KSAtPiB1aW50NjQ6CnZlcmlmeV9hcHBfcGFyYW1zX2dldF9leHRyYV9wcm9ncmFtX3BhZ2VzOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjMyMS0zMjIKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBwdWJsaWMgdmVyaWZ5X2FwcF9wYXJhbXNfZ2V0X2V4dHJhX3Byb2dyYW1fcGFnZXMoYTogQXBwbGljYXRpb24pOiB1aW50NjQgewogICAgcHJvdG8gMSAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MzIzCiAgICAvLyBjb25zdCBbdmFsdWUsIGV4aXN0c10gPSBvcC5BcHBQYXJhbXMuYXBwRXh0cmFQcm9ncmFtUGFnZXMoYSkKICAgIGZyYW1lX2RpZyAtMQogICAgYXBwX3BhcmFtc19nZXQgQXBwRXh0cmFQcm9ncmFtUGFnZXMKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czozMjQKICAgIC8vIGNvbnN0IFt2YWx1ZV9pbmRleCwgZXhpc3RzX2luZGV4XSA9IG9wLkFwcFBhcmFtcy5hcHBFeHRyYVByb2dyYW1QYWdlcyhnZXRfMXN0X3JlZl9pbmRleCgpKQogICAgY2FsbHN1YiBnZXRfMXN0X3JlZl9pbmRleAogICAgYXBwX3BhcmFtc19nZXQgQXBwRXh0cmFQcm9ncmFtUGFnZXMKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czozMjUKICAgIC8vIGFzc2VydCh2YWx1ZSA9PT0gdmFsdWVfaW5kZXgsICdleHBlY3RlZCB2YWx1ZSBieSBpbmRleCB0byBtYXRjaCcpCiAgICBkaWcgMwogICAgdW5jb3ZlciAyCiAgICA9PQogICAgYXNzZXJ0IC8vIGV4cGVjdGVkIHZhbHVlIGJ5IGluZGV4IHRvIG1hdGNoCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MzI2CiAgICAvLyBhc3NlcnQoZXhpc3RzID09PSBleGlzdHNfaW5kZXgsICdleHBlY3RlZCBleGlzdHMgYnkgaW5kZXggdG8gbWF0Y2gnKQogICAgPT0KICAgIGFzc2VydCAvLyBleHBlY3RlZCBleGlzdHMgYnkgaW5kZXggdG8gbWF0Y2gKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czozMjcKICAgIC8vIHJldHVybiB2YWx1ZQogICAgcmV0c3ViCgoKLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjpTdGF0ZUFwcFBhcmFtc0NvbnRyYWN0LnZlcmlmeV9hcHBfcGFyYW1zX2dldF9jcmVhdG9yKGE6IHVpbnQ2NCkgLT4gYnl0ZXM6CnZlcmlmeV9hcHBfcGFyYW1zX2dldF9jcmVhdG9yOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjMzMC0zMzEKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBwdWJsaWMgdmVyaWZ5X2FwcF9wYXJhbXNfZ2V0X2NyZWF0b3IoYTogQXBwbGljYXRpb24pOiBBZGRyZXNzIHsKICAgIHByb3RvIDEgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjMzMgogICAgLy8gY29uc3QgW3ZhbHVlLCBleGlzdHNdID0gb3AuQXBwUGFyYW1zLmFwcENyZWF0b3IoYSkKICAgIGZyYW1lX2RpZyAtMQogICAgYXBwX3BhcmFtc19nZXQgQXBwQ3JlYXRvcgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjMzMwogICAgLy8gY29uc3QgW3ZhbHVlX2luZGV4LCBleGlzdHNfaW5kZXhdID0gb3AuQXBwUGFyYW1zLmFwcENyZWF0b3IoZ2V0XzFzdF9yZWZfaW5kZXgoKSkKICAgIGNhbGxzdWIgZ2V0XzFzdF9yZWZfaW5kZXgKICAgIGFwcF9wYXJhbXNfZ2V0IEFwcENyZWF0b3IKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czozMzQKICAgIC8vIGFzc2VydCh2YWx1ZSA9PT0gdmFsdWVfaW5kZXgsICdleHBlY3RlZCB2YWx1ZSBieSBpbmRleCB0byBtYXRjaCcpCiAgICBkaWcgMwogICAgdW5jb3ZlciAyCiAgICA9PQogICAgYXNzZXJ0IC8vIGV4cGVjdGVkIHZhbHVlIGJ5IGluZGV4IHRvIG1hdGNoCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MzM1CiAgICAvLyBhc3NlcnQoZXhpc3RzID09PSBleGlzdHNfaW5kZXgsICdleHBlY3RlZCBleGlzdHMgYnkgaW5kZXggdG8gbWF0Y2gnKQogICAgPT0KICAgIGFzc2VydCAvLyBleHBlY3RlZCBleGlzdHMgYnkgaW5kZXggdG8gbWF0Y2gKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czozMzYKICAgIC8vIHJldHVybiBuZXcgQWRkcmVzcyh2YWx1ZSkKICAgIHJldHN1YgoKCi8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo6U3RhdGVBcHBQYXJhbXNDb250cmFjdC52ZXJpZnlfYXBwX3BhcmFtc19nZXRfYWRkcmVzcyhhOiB1aW50NjQpIC0+IGJ5dGVzOgp2ZXJpZnlfYXBwX3BhcmFtc19nZXRfYWRkcmVzczoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czozMzktMzQwCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gcHVibGljIHZlcmlmeV9hcHBfcGFyYW1zX2dldF9hZGRyZXNzKGE6IEFwcGxpY2F0aW9uKTogQWRkcmVzcyB7CiAgICBwcm90byAxIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czozNDEKICAgIC8vIGNvbnN0IFt2YWx1ZSwgZXhpc3RzXSA9IG9wLkFwcFBhcmFtcy5hcHBBZGRyZXNzKGEpCiAgICBmcmFtZV9kaWcgLTEKICAgIGFwcF9wYXJhbXNfZ2V0IEFwcEFkZHJlc3MKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czozNDIKICAgIC8vIGNvbnN0IFt2YWx1ZV9pbmRleCwgZXhpc3RzX2luZGV4XSA9IG9wLkFwcFBhcmFtcy5hcHBBZGRyZXNzKGdldF8xc3RfcmVmX2luZGV4KCkpCiAgICBjYWxsc3ViIGdldF8xc3RfcmVmX2luZGV4CiAgICBhcHBfcGFyYW1zX2dldCBBcHBBZGRyZXNzCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MzQzCiAgICAvLyBhc3NlcnQodmFsdWUuYnl0ZXMudG9TdHJpbmcoKSA9PT0gdmFsdWVfaW5kZXguYnl0ZXMudG9TdHJpbmcoKSwgJ2V4cGVjdGVkIHZhbHVlIGJ5IGluZGV4IHRvIG1hdGNoJykKICAgIGRpZyAzCiAgICB1bmNvdmVyIDIKICAgID09CiAgICBhc3NlcnQgLy8gZXhwZWN0ZWQgdmFsdWUgYnkgaW5kZXggdG8gbWF0Y2gKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czozNDQKICAgIC8vIGFzc2VydChleGlzdHMgPT09IGV4aXN0c19pbmRleCwgJ2V4cGVjdGVkIGV4aXN0cyBieSBpbmRleCB0byBtYXRjaCcpCiAgICA9PQogICAgYXNzZXJ0IC8vIGV4cGVjdGVkIGV4aXN0cyBieSBpbmRleCB0byBtYXRjaAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjM0NQogICAgLy8gcmV0dXJuIG5ldyBBZGRyZXNzKHZhbHVlKQogICAgcmV0c3ViCg==", - "clear": "I3ByYWdtYSB2ZXJzaW9uIDEwCgp0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OlN0YXRlQXBwUGFyYW1zQ29udHJhY3QuY2xlYXJTdGF0ZVByb2dyYW06CiAgICBwdXNoaW50IDEgLy8gMQogICAgcmV0dXJuCg==" - }, - "events": [], - "templateVariables": {} -} \ No newline at end of file diff --git a/tests/artifacts/state-ops/data/StateAppParamsContract.clear.teal b/tests/artifacts/state-ops/data/StateAppParamsContract.clear.teal deleted file mode 100644 index 99ff46e..0000000 --- a/tests/artifacts/state-ops/data/StateAppParamsContract.clear.teal +++ /dev/null @@ -1,5 +0,0 @@ -#pragma version 10 - -tests/artifacts/state-ops/contract.algo.ts::StateAppParamsContract.clearStateProgram: - pushint 1 // 1 - return diff --git a/tests/artifacts/state-ops/data/StateAssetHoldingContract.approval.teal b/tests/artifacts/state-ops/data/StateAssetHoldingContract.approval.teal deleted file mode 100644 index a214d29..0000000 --- a/tests/artifacts/state-ops/data/StateAssetHoldingContract.approval.teal +++ /dev/null @@ -1,129 +0,0 @@ -#pragma version 10 - -tests/artifacts/state-ops/contract.algo.ts::StateAssetHoldingContract.approvalProgram: - intcblock 0 1 - bytecblock 0x151f7c75 - callsub __puya_arc4_router__ - return - - -// tests/artifacts/state-ops/contract.algo.ts::StateAssetHoldingContract.__puya_arc4_router__() -> uint64: -__puya_arc4_router__: - // tests/artifacts/state-ops/contract.algo.ts:142 - // export class StateAssetHoldingContract extends arc4.Contract { - proto 0 1 - txn NumAppArgs - bz __puya_arc4_router___bare_routing@6 - pushbytess 0x68301476 0x784c64eb // method "verify_asset_holding_get(account,asset)uint64", method "verify_asset_frozen_get(account,asset)bool" - txna ApplicationArgs 0 - match __puya_arc4_router___verify_asset_holding_get_route@2 __puya_arc4_router___verify_asset_frozen_get_route@3 - intc_0 // 0 - retsub - -__puya_arc4_router___verify_asset_holding_get_route@2: - // tests/artifacts/state-ops/contract.algo.ts:143 - // @arc4.abimethod() - txn OnCompletion - ! - assert // OnCompletion is not NoOp - txn ApplicationID - assert // can only call when not creating - // tests/artifacts/state-ops/contract.algo.ts:142 - // export class StateAssetHoldingContract extends arc4.Contract { - txna ApplicationArgs 1 - btoi - txnas Accounts - txna ApplicationArgs 2 - btoi - txnas Assets - // tests/artifacts/state-ops/contract.algo.ts:143 - // @arc4.abimethod() - callsub verify_asset_holding_get - itob - bytec_0 // 0x151f7c75 - swap - concat - log - intc_1 // 1 - retsub - -__puya_arc4_router___verify_asset_frozen_get_route@3: - // tests/artifacts/state-ops/contract.algo.ts:149 - // @arc4.abimethod() - txn OnCompletion - ! - assert // OnCompletion is not NoOp - txn ApplicationID - assert // can only call when not creating - // tests/artifacts/state-ops/contract.algo.ts:142 - // export class StateAssetHoldingContract extends arc4.Contract { - txna ApplicationArgs 1 - btoi - txnas Accounts - txna ApplicationArgs 2 - btoi - txnas Assets - // tests/artifacts/state-ops/contract.algo.ts:149 - // @arc4.abimethod() - callsub verify_asset_frozen_get - pushbytes 0x00 - intc_0 // 0 - uncover 2 - setbit - bytec_0 // 0x151f7c75 - swap - concat - log - intc_1 // 1 - retsub - -__puya_arc4_router___bare_routing@6: - // tests/artifacts/state-ops/contract.algo.ts:142 - // export class StateAssetHoldingContract extends arc4.Contract { - txn OnCompletion - bnz __puya_arc4_router___after_if_else@10 - txn ApplicationID - ! - assert // can only call when creating - intc_1 // 1 - retsub - -__puya_arc4_router___after_if_else@10: - // tests/artifacts/state-ops/contract.algo.ts:142 - // export class StateAssetHoldingContract extends arc4.Contract { - intc_0 // 0 - retsub - - -// tests/artifacts/state-ops/contract.algo.ts::StateAssetHoldingContract.verify_asset_holding_get(a: bytes, b: uint64) -> uint64: -verify_asset_holding_get: - // tests/artifacts/state-ops/contract.algo.ts:143-144 - // @arc4.abimethod() - // public verify_asset_holding_get(a: Account, b: Asset): uint64 { - proto 2 1 - // tests/artifacts/state-ops/contract.algo.ts:145 - // const [balance, _val] = op.AssetHolding.assetBalance(a, b) - frame_dig -2 - frame_dig -1 - asset_holding_get AssetBalance - pop - // tests/artifacts/state-ops/contract.algo.ts:146 - // return balance - retsub - - -// tests/artifacts/state-ops/contract.algo.ts::StateAssetHoldingContract.verify_asset_frozen_get(a: bytes, b: uint64) -> uint64: -verify_asset_frozen_get: - // tests/artifacts/state-ops/contract.algo.ts:149-150 - // @arc4.abimethod() - // public verify_asset_frozen_get(a: Account, b: Asset): boolean { - proto 2 1 - // tests/artifacts/state-ops/contract.algo.ts:151 - // const [frozen, _val] = op.AssetHolding.assetFrozen(a, b) - frame_dig -2 - frame_dig -1 - asset_holding_get AssetFrozen - pop - // tests/artifacts/state-ops/contract.algo.ts:152 - // return frozen - retsub diff --git a/tests/artifacts/state-ops/data/StateAssetHoldingContract.arc32.json b/tests/artifacts/state-ops/data/StateAssetHoldingContract.arc32.json deleted file mode 100644 index 2eee37c..0000000 --- a/tests/artifacts/state-ops/data/StateAssetHoldingContract.arc32.json +++ /dev/null @@ -1,81 +0,0 @@ -{ - "hints": { - "verify_asset_holding_get(account,asset)uint64": { - "call_config": { - "no_op": "CALL" - } - }, - "verify_asset_frozen_get(account,asset)bool": { - "call_config": { - "no_op": "CALL" - } - } - }, - "source": { - "approval": "I3ByYWdtYSB2ZXJzaW9uIDEwCgp0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OlN0YXRlQXNzZXRIb2xkaW5nQ29udHJhY3QuYXBwcm92YWxQcm9ncmFtOgogICAgaW50Y2Jsb2NrIDAgMQogICAgYnl0ZWNibG9jayAweDE1MWY3Yzc1CiAgICBjYWxsc3ViIF9fcHV5YV9hcmM0X3JvdXRlcl9fCiAgICByZXR1cm4KCgovLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OlN0YXRlQXNzZXRIb2xkaW5nQ29udHJhY3QuX19wdXlhX2FyYzRfcm91dGVyX18oKSAtPiB1aW50NjQ6Cl9fcHV5YV9hcmM0X3JvdXRlcl9fOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjE0MgogICAgLy8gZXhwb3J0IGNsYXNzIFN0YXRlQXNzZXRIb2xkaW5nQ29udHJhY3QgZXh0ZW5kcyBhcmM0LkNvbnRyYWN0IHsKICAgIHByb3RvIDAgMQogICAgdHhuIE51bUFwcEFyZ3MKICAgIGJ6IF9fcHV5YV9hcmM0X3JvdXRlcl9fX2JhcmVfcm91dGluZ0A2CiAgICBwdXNoYnl0ZXNzIDB4NjgzMDE0NzYgMHg3ODRjNjRlYiAvLyBtZXRob2QgInZlcmlmeV9hc3NldF9ob2xkaW5nX2dldChhY2NvdW50LGFzc2V0KXVpbnQ2NCIsIG1ldGhvZCAidmVyaWZ5X2Fzc2V0X2Zyb3plbl9nZXQoYWNjb3VudCxhc3NldClib29sIgogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMAogICAgbWF0Y2ggX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2Fzc2V0X2hvbGRpbmdfZ2V0X3JvdXRlQDIgX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2Fzc2V0X2Zyb3plbl9nZXRfcm91dGVAMwogICAgaW50Y18wIC8vIDAKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2Fzc2V0X2hvbGRpbmdfZ2V0X3JvdXRlQDI6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTQzCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBub3QgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBjYW4gb25seSBjYWxsIHdoZW4gbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTQyCiAgICAvLyBleHBvcnQgY2xhc3MgU3RhdGVBc3NldEhvbGRpbmdDb250cmFjdCBleHRlbmRzIGFyYzQuQ29udHJhY3QgewogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgYnRvaQogICAgdHhuYXMgQWNjb3VudHMKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDIKICAgIGJ0b2kKICAgIHR4bmFzIEFzc2V0cwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjE0MwogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X2Fzc2V0X2hvbGRpbmdfZ2V0CiAgICBpdG9iCiAgICBieXRlY18wIC8vIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnRjXzEgLy8gMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfYXNzZXRfZnJvemVuX2dldF9yb3V0ZUAzOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjE0OQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgbm90IE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gY2FuIG9ubHkgY2FsbCB3aGVuIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjE0MgogICAgLy8gZXhwb3J0IGNsYXNzIFN0YXRlQXNzZXRIb2xkaW5nQ29udHJhY3QgZXh0ZW5kcyBhcmM0LkNvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGJ0b2kKICAgIHR4bmFzIEFjY291bnRzCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAyCiAgICBidG9pCiAgICB0eG5hcyBBc3NldHMKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czoxNDkKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV9hc3NldF9mcm96ZW5fZ2V0CiAgICBwdXNoYnl0ZXMgMHgwMAogICAgaW50Y18wIC8vIDAKICAgIHVuY292ZXIgMgogICAgc2V0Yml0CiAgICBieXRlY18wIC8vIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnRjXzEgLy8gMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX19iYXJlX3JvdXRpbmdANjoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czoxNDIKICAgIC8vIGV4cG9ydCBjbGFzcyBTdGF0ZUFzc2V0SG9sZGluZ0NvbnRyYWN0IGV4dGVuZHMgYXJjNC5Db250cmFjdCB7CiAgICB0eG4gT25Db21wbGV0aW9uCiAgICBibnogX19wdXlhX2FyYzRfcm91dGVyX19fYWZ0ZXJfaWZfZWxzZUAxMAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgICEKICAgIGFzc2VydCAvLyBjYW4gb25seSBjYWxsIHdoZW4gY3JlYXRpbmcKICAgIGludGNfMSAvLyAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX2FmdGVyX2lmX2Vsc2VAMTA6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTQyCiAgICAvLyBleHBvcnQgY2xhc3MgU3RhdGVBc3NldEhvbGRpbmdDb250cmFjdCBleHRlbmRzIGFyYzQuQ29udHJhY3QgewogICAgaW50Y18wIC8vIDAKICAgIHJldHN1YgoKCi8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo6U3RhdGVBc3NldEhvbGRpbmdDb250cmFjdC52ZXJpZnlfYXNzZXRfaG9sZGluZ19nZXQoYTogYnl0ZXMsIGI6IHVpbnQ2NCkgLT4gdWludDY0Ogp2ZXJpZnlfYXNzZXRfaG9sZGluZ19nZXQ6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTQzLTE0NAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIHB1YmxpYyB2ZXJpZnlfYXNzZXRfaG9sZGluZ19nZXQoYTogQWNjb3VudCwgYjogQXNzZXQpOiB1aW50NjQgewogICAgcHJvdG8gMiAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTQ1CiAgICAvLyBjb25zdCBbYmFsYW5jZSwgX3ZhbF0gPSBvcC5Bc3NldEhvbGRpbmcuYXNzZXRCYWxhbmNlKGEsIGIpCiAgICBmcmFtZV9kaWcgLTIKICAgIGZyYW1lX2RpZyAtMQogICAgYXNzZXRfaG9sZGluZ19nZXQgQXNzZXRCYWxhbmNlCiAgICBwb3AKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czoxNDYKICAgIC8vIHJldHVybiBiYWxhbmNlCiAgICByZXRzdWIKCgovLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OlN0YXRlQXNzZXRIb2xkaW5nQ29udHJhY3QudmVyaWZ5X2Fzc2V0X2Zyb3plbl9nZXQoYTogYnl0ZXMsIGI6IHVpbnQ2NCkgLT4gdWludDY0Ogp2ZXJpZnlfYXNzZXRfZnJvemVuX2dldDoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czoxNDktMTUwCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gcHVibGljIHZlcmlmeV9hc3NldF9mcm96ZW5fZ2V0KGE6IEFjY291bnQsIGI6IEFzc2V0KTogYm9vbGVhbiB7CiAgICBwcm90byAyIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czoxNTEKICAgIC8vIGNvbnN0IFtmcm96ZW4sIF92YWxdID0gb3AuQXNzZXRIb2xkaW5nLmFzc2V0RnJvemVuKGEsIGIpCiAgICBmcmFtZV9kaWcgLTIKICAgIGZyYW1lX2RpZyAtMQogICAgYXNzZXRfaG9sZGluZ19nZXQgQXNzZXRGcm96ZW4KICAgIHBvcAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjE1MgogICAgLy8gcmV0dXJuIGZyb3plbgogICAgcmV0c3ViCg==", - "clear": "I3ByYWdtYSB2ZXJzaW9uIDEwCgp0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OlN0YXRlQXNzZXRIb2xkaW5nQ29udHJhY3QuY2xlYXJTdGF0ZVByb2dyYW06CiAgICBwdXNoaW50IDEgLy8gMQogICAgcmV0dXJuCg==" - }, - "state": { - "global": { - "num_byte_slices": 0, - "num_uints": 0 - }, - "local": { - "num_byte_slices": 0, - "num_uints": 0 - } - }, - "schema": { - "global": { - "declared": {}, - "reserved": {} - }, - "local": { - "declared": {}, - "reserved": {} - } - }, - "contract": { - "name": "StateAssetHoldingContract", - "methods": [ - { - "name": "verify_asset_holding_get", - "args": [ - { - "type": "account", - "name": "a" - }, - { - "type": "asset", - "name": "b" - } - ], - "readonly": false, - "returns": { - "type": "uint64" - } - }, - { - "name": "verify_asset_frozen_get", - "args": [ - { - "type": "account", - "name": "a" - }, - { - "type": "asset", - "name": "b" - } - ], - "readonly": false, - "returns": { - "type": "bool" - } - } - ], - "networks": {} - }, - "bare_call_config": { - "no_op": "CREATE" - } -} \ No newline at end of file diff --git a/tests/artifacts/state-ops/data/StateAssetHoldingContract.arc56.json b/tests/artifacts/state-ops/data/StateAssetHoldingContract.arc56.json deleted file mode 100644 index 6aff1c8..0000000 --- a/tests/artifacts/state-ops/data/StateAssetHoldingContract.arc56.json +++ /dev/null @@ -1,126 +0,0 @@ -{ - "name": "StateAssetHoldingContract", - "structs": {}, - "methods": [ - { - "name": "verify_asset_holding_get", - "args": [ - { - "type": "account", - "name": "a" - }, - { - "type": "asset", - "name": "b" - } - ], - "returns": { - "type": "uint64" - }, - "actions": { - "create": [], - "call": [ - "NoOp" - ] - }, - "readonly": false, - "events": [], - "recommendations": {} - }, - { - "name": "verify_asset_frozen_get", - "args": [ - { - "type": "account", - "name": "a" - }, - { - "type": "asset", - "name": "b" - } - ], - "returns": { - "type": "bool" - }, - "actions": { - "create": [], - "call": [ - "NoOp" - ] - }, - "readonly": false, - "events": [], - "recommendations": {} - } - ], - "arcs": [ - 22, - 28 - ], - "networks": {}, - "state": { - "schema": { - "global": { - "ints": 0, - "bytes": 0 - }, - "local": { - "ints": 0, - "bytes": 0 - } - }, - "keys": { - "global": {}, - "local": {}, - "box": {} - }, - "maps": { - "global": {}, - "local": {}, - "box": {} - } - }, - "bareActions": { - "create": [ - "NoOp" - ], - "call": [] - }, - "sourceInfo": { - "approval": { - "sourceInfo": [ - { - "pc": [ - 50, - 79 - ], - "errorMessage": "OnCompletion is not NoOp" - }, - { - "pc": [ - 119 - ], - "errorMessage": "can only call when creating" - }, - { - "pc": [ - 53, - 82 - ], - "errorMessage": "can only call when not creating" - } - ], - "pcOffsetMethod": "none" - }, - "clear": { - "sourceInfo": [], - "pcOffsetMethod": "none" - } - }, - "source": { - "approval": "I3ByYWdtYSB2ZXJzaW9uIDEwCgp0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OlN0YXRlQXNzZXRIb2xkaW5nQ29udHJhY3QuYXBwcm92YWxQcm9ncmFtOgogICAgaW50Y2Jsb2NrIDAgMQogICAgYnl0ZWNibG9jayAweDE1MWY3Yzc1CiAgICBjYWxsc3ViIF9fcHV5YV9hcmM0X3JvdXRlcl9fCiAgICByZXR1cm4KCgovLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OlN0YXRlQXNzZXRIb2xkaW5nQ29udHJhY3QuX19wdXlhX2FyYzRfcm91dGVyX18oKSAtPiB1aW50NjQ6Cl9fcHV5YV9hcmM0X3JvdXRlcl9fOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjE0MgogICAgLy8gZXhwb3J0IGNsYXNzIFN0YXRlQXNzZXRIb2xkaW5nQ29udHJhY3QgZXh0ZW5kcyBhcmM0LkNvbnRyYWN0IHsKICAgIHByb3RvIDAgMQogICAgdHhuIE51bUFwcEFyZ3MKICAgIGJ6IF9fcHV5YV9hcmM0X3JvdXRlcl9fX2JhcmVfcm91dGluZ0A2CiAgICBwdXNoYnl0ZXNzIDB4NjgzMDE0NzYgMHg3ODRjNjRlYiAvLyBtZXRob2QgInZlcmlmeV9hc3NldF9ob2xkaW5nX2dldChhY2NvdW50LGFzc2V0KXVpbnQ2NCIsIG1ldGhvZCAidmVyaWZ5X2Fzc2V0X2Zyb3plbl9nZXQoYWNjb3VudCxhc3NldClib29sIgogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMAogICAgbWF0Y2ggX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2Fzc2V0X2hvbGRpbmdfZ2V0X3JvdXRlQDIgX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2Fzc2V0X2Zyb3plbl9nZXRfcm91dGVAMwogICAgaW50Y18wIC8vIDAKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2Fzc2V0X2hvbGRpbmdfZ2V0X3JvdXRlQDI6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTQzCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBub3QgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBjYW4gb25seSBjYWxsIHdoZW4gbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTQyCiAgICAvLyBleHBvcnQgY2xhc3MgU3RhdGVBc3NldEhvbGRpbmdDb250cmFjdCBleHRlbmRzIGFyYzQuQ29udHJhY3QgewogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgYnRvaQogICAgdHhuYXMgQWNjb3VudHMKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDIKICAgIGJ0b2kKICAgIHR4bmFzIEFzc2V0cwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjE0MwogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X2Fzc2V0X2hvbGRpbmdfZ2V0CiAgICBpdG9iCiAgICBieXRlY18wIC8vIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnRjXzEgLy8gMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfYXNzZXRfZnJvemVuX2dldF9yb3V0ZUAzOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjE0OQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgbm90IE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gY2FuIG9ubHkgY2FsbCB3aGVuIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjE0MgogICAgLy8gZXhwb3J0IGNsYXNzIFN0YXRlQXNzZXRIb2xkaW5nQ29udHJhY3QgZXh0ZW5kcyBhcmM0LkNvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGJ0b2kKICAgIHR4bmFzIEFjY291bnRzCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAyCiAgICBidG9pCiAgICB0eG5hcyBBc3NldHMKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czoxNDkKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV9hc3NldF9mcm96ZW5fZ2V0CiAgICBwdXNoYnl0ZXMgMHgwMAogICAgaW50Y18wIC8vIDAKICAgIHVuY292ZXIgMgogICAgc2V0Yml0CiAgICBieXRlY18wIC8vIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnRjXzEgLy8gMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX19iYXJlX3JvdXRpbmdANjoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czoxNDIKICAgIC8vIGV4cG9ydCBjbGFzcyBTdGF0ZUFzc2V0SG9sZGluZ0NvbnRyYWN0IGV4dGVuZHMgYXJjNC5Db250cmFjdCB7CiAgICB0eG4gT25Db21wbGV0aW9uCiAgICBibnogX19wdXlhX2FyYzRfcm91dGVyX19fYWZ0ZXJfaWZfZWxzZUAxMAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgICEKICAgIGFzc2VydCAvLyBjYW4gb25seSBjYWxsIHdoZW4gY3JlYXRpbmcKICAgIGludGNfMSAvLyAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX2FmdGVyX2lmX2Vsc2VAMTA6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTQyCiAgICAvLyBleHBvcnQgY2xhc3MgU3RhdGVBc3NldEhvbGRpbmdDb250cmFjdCBleHRlbmRzIGFyYzQuQ29udHJhY3QgewogICAgaW50Y18wIC8vIDAKICAgIHJldHN1YgoKCi8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo6U3RhdGVBc3NldEhvbGRpbmdDb250cmFjdC52ZXJpZnlfYXNzZXRfaG9sZGluZ19nZXQoYTogYnl0ZXMsIGI6IHVpbnQ2NCkgLT4gdWludDY0Ogp2ZXJpZnlfYXNzZXRfaG9sZGluZ19nZXQ6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTQzLTE0NAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIHB1YmxpYyB2ZXJpZnlfYXNzZXRfaG9sZGluZ19nZXQoYTogQWNjb3VudCwgYjogQXNzZXQpOiB1aW50NjQgewogICAgcHJvdG8gMiAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTQ1CiAgICAvLyBjb25zdCBbYmFsYW5jZSwgX3ZhbF0gPSBvcC5Bc3NldEhvbGRpbmcuYXNzZXRCYWxhbmNlKGEsIGIpCiAgICBmcmFtZV9kaWcgLTIKICAgIGZyYW1lX2RpZyAtMQogICAgYXNzZXRfaG9sZGluZ19nZXQgQXNzZXRCYWxhbmNlCiAgICBwb3AKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czoxNDYKICAgIC8vIHJldHVybiBiYWxhbmNlCiAgICByZXRzdWIKCgovLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OlN0YXRlQXNzZXRIb2xkaW5nQ29udHJhY3QudmVyaWZ5X2Fzc2V0X2Zyb3plbl9nZXQoYTogYnl0ZXMsIGI6IHVpbnQ2NCkgLT4gdWludDY0Ogp2ZXJpZnlfYXNzZXRfZnJvemVuX2dldDoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czoxNDktMTUwCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gcHVibGljIHZlcmlmeV9hc3NldF9mcm96ZW5fZ2V0KGE6IEFjY291bnQsIGI6IEFzc2V0KTogYm9vbGVhbiB7CiAgICBwcm90byAyIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czoxNTEKICAgIC8vIGNvbnN0IFtmcm96ZW4sIF92YWxdID0gb3AuQXNzZXRIb2xkaW5nLmFzc2V0RnJvemVuKGEsIGIpCiAgICBmcmFtZV9kaWcgLTIKICAgIGZyYW1lX2RpZyAtMQogICAgYXNzZXRfaG9sZGluZ19nZXQgQXNzZXRGcm96ZW4KICAgIHBvcAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjE1MgogICAgLy8gcmV0dXJuIGZyb3plbgogICAgcmV0c3ViCg==", - "clear": "I3ByYWdtYSB2ZXJzaW9uIDEwCgp0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OlN0YXRlQXNzZXRIb2xkaW5nQ29udHJhY3QuY2xlYXJTdGF0ZVByb2dyYW06CiAgICBwdXNoaW50IDEgLy8gMQogICAgcmV0dXJuCg==" - }, - "events": [], - "templateVariables": {} -} \ No newline at end of file diff --git a/tests/artifacts/state-ops/data/StateAssetHoldingContract.clear.teal b/tests/artifacts/state-ops/data/StateAssetHoldingContract.clear.teal deleted file mode 100644 index 7168de9..0000000 --- a/tests/artifacts/state-ops/data/StateAssetHoldingContract.clear.teal +++ /dev/null @@ -1,5 +0,0 @@ -#pragma version 10 - -tests/artifacts/state-ops/contract.algo.ts::StateAssetHoldingContract.clearStateProgram: - pushint 1 // 1 - return diff --git a/tests/artifacts/state-ops/data/StateAssetParamsContract.approval.teal b/tests/artifacts/state-ops/data/StateAssetParamsContract.approval.teal deleted file mode 100644 index 1bbcffd..0000000 --- a/tests/artifacts/state-ops/data/StateAssetParamsContract.approval.teal +++ /dev/null @@ -1,705 +0,0 @@ -#pragma version 10 - -tests/artifacts/state-ops/contract.algo.ts::StateAssetParamsContract.approvalProgram: - intcblock 1 0 - bytecblock 0x151f7c75 - callsub __puya_arc4_router__ - return - - -// tests/artifacts/state-ops/contract.algo.ts::StateAssetParamsContract.__puya_arc4_router__() -> uint64: -__puya_arc4_router__: - // tests/artifacts/state-ops/contract.algo.ts:156 - // export class StateAssetParamsContract extends arc4.Contract { - proto 0 1 - txn NumAppArgs - bz __puya_arc4_router___bare_routing@16 - pushbytess 0xad719a6f 0x1d603013 0x9fb731cd 0x0f5a4911 0xf5b370c6 0xc7d6af74 0x6b71a263 0x3040ebc8 0x1d07e844 0x3e40cb50 0x340c786b 0xe38a9815 // method "verify_asset_params_get_total(asset)uint64", method "verify_asset_params_get_decimals(asset)uint64", method "verify_asset_params_get_default_frozen(asset)bool", method "verify_asset_params_get_unit_name(asset)byte[]", method "verify_asset_params_get_name(asset)byte[]", method "verify_asset_params_get_url(asset)byte[]", method "verify_asset_params_get_metadata_hash(asset)byte[]", method "verify_asset_params_get_manager(asset)address", method "verify_asset_params_get_reserve(asset)address", method "verify_asset_params_get_freeze(asset)address", method "verify_asset_params_get_clawback(asset)address", method "verify_asset_params_get_creator(asset)address" - txna ApplicationArgs 0 - match __puya_arc4_router___verify_asset_params_get_total_route@2 __puya_arc4_router___verify_asset_params_get_decimals_route@3 __puya_arc4_router___verify_asset_params_get_default_frozen_route@4 __puya_arc4_router___verify_asset_params_get_unit_name_route@5 __puya_arc4_router___verify_asset_params_get_name_route@6 __puya_arc4_router___verify_asset_params_get_url_route@7 __puya_arc4_router___verify_asset_params_get_metadata_hash_route@8 __puya_arc4_router___verify_asset_params_get_manager_route@9 __puya_arc4_router___verify_asset_params_get_reserve_route@10 __puya_arc4_router___verify_asset_params_get_freeze_route@11 __puya_arc4_router___verify_asset_params_get_clawback_route@12 __puya_arc4_router___verify_asset_params_get_creator_route@13 - intc_1 // 0 - retsub - -__puya_arc4_router___verify_asset_params_get_total_route@2: - // tests/artifacts/state-ops/contract.algo.ts:157 - // @arc4.abimethod() - txn OnCompletion - ! - assert // OnCompletion is not NoOp - txn ApplicationID - assert // can only call when not creating - // tests/artifacts/state-ops/contract.algo.ts:156 - // export class StateAssetParamsContract extends arc4.Contract { - txna ApplicationArgs 1 - btoi - txnas Assets - // tests/artifacts/state-ops/contract.algo.ts:157 - // @arc4.abimethod() - callsub verify_asset_params_get_total - itob - bytec_0 // 0x151f7c75 - swap - concat - log - intc_0 // 1 - retsub - -__puya_arc4_router___verify_asset_params_get_decimals_route@3: - // tests/artifacts/state-ops/contract.algo.ts:166 - // @arc4.abimethod() - txn OnCompletion - ! - assert // OnCompletion is not NoOp - txn ApplicationID - assert // can only call when not creating - // tests/artifacts/state-ops/contract.algo.ts:156 - // export class StateAssetParamsContract extends arc4.Contract { - txna ApplicationArgs 1 - btoi - txnas Assets - // tests/artifacts/state-ops/contract.algo.ts:166 - // @arc4.abimethod() - callsub verify_asset_params_get_decimals - itob - bytec_0 // 0x151f7c75 - swap - concat - log - intc_0 // 1 - retsub - -__puya_arc4_router___verify_asset_params_get_default_frozen_route@4: - // tests/artifacts/state-ops/contract.algo.ts:175 - // @arc4.abimethod() - txn OnCompletion - ! - assert // OnCompletion is not NoOp - txn ApplicationID - assert // can only call when not creating - // tests/artifacts/state-ops/contract.algo.ts:156 - // export class StateAssetParamsContract extends arc4.Contract { - txna ApplicationArgs 1 - btoi - txnas Assets - // tests/artifacts/state-ops/contract.algo.ts:175 - // @arc4.abimethod() - callsub verify_asset_params_get_default_frozen - pushbytes 0x00 - intc_1 // 0 - uncover 2 - setbit - bytec_0 // 0x151f7c75 - swap - concat - log - intc_0 // 1 - retsub - -__puya_arc4_router___verify_asset_params_get_unit_name_route@5: - // tests/artifacts/state-ops/contract.algo.ts:184 - // @arc4.abimethod() - txn OnCompletion - ! - assert // OnCompletion is not NoOp - txn ApplicationID - assert // can only call when not creating - // tests/artifacts/state-ops/contract.algo.ts:156 - // export class StateAssetParamsContract extends arc4.Contract { - txna ApplicationArgs 1 - btoi - txnas Assets - // tests/artifacts/state-ops/contract.algo.ts:184 - // @arc4.abimethod() - callsub verify_asset_params_get_unit_name - dup - len - itob - extract 6 2 - swap - concat - bytec_0 // 0x151f7c75 - swap - concat - log - intc_0 // 1 - retsub - -__puya_arc4_router___verify_asset_params_get_name_route@6: - // tests/artifacts/state-ops/contract.algo.ts:193 - // @arc4.abimethod() - txn OnCompletion - ! - assert // OnCompletion is not NoOp - txn ApplicationID - assert // can only call when not creating - // tests/artifacts/state-ops/contract.algo.ts:156 - // export class StateAssetParamsContract extends arc4.Contract { - txna ApplicationArgs 1 - btoi - txnas Assets - // tests/artifacts/state-ops/contract.algo.ts:193 - // @arc4.abimethod() - callsub verify_asset_params_get_name - dup - len - itob - extract 6 2 - swap - concat - bytec_0 // 0x151f7c75 - swap - concat - log - intc_0 // 1 - retsub - -__puya_arc4_router___verify_asset_params_get_url_route@7: - // tests/artifacts/state-ops/contract.algo.ts:202 - // @arc4.abimethod() - txn OnCompletion - ! - assert // OnCompletion is not NoOp - txn ApplicationID - assert // can only call when not creating - // tests/artifacts/state-ops/contract.algo.ts:156 - // export class StateAssetParamsContract extends arc4.Contract { - txna ApplicationArgs 1 - btoi - txnas Assets - // tests/artifacts/state-ops/contract.algo.ts:202 - // @arc4.abimethod() - callsub verify_asset_params_get_url - dup - len - itob - extract 6 2 - swap - concat - bytec_0 // 0x151f7c75 - swap - concat - log - intc_0 // 1 - retsub - -__puya_arc4_router___verify_asset_params_get_metadata_hash_route@8: - // tests/artifacts/state-ops/contract.algo.ts:211 - // @arc4.abimethod() - txn OnCompletion - ! - assert // OnCompletion is not NoOp - txn ApplicationID - assert // can only call when not creating - // tests/artifacts/state-ops/contract.algo.ts:156 - // export class StateAssetParamsContract extends arc4.Contract { - txna ApplicationArgs 1 - btoi - txnas Assets - // tests/artifacts/state-ops/contract.algo.ts:211 - // @arc4.abimethod() - callsub verify_asset_params_get_metadata_hash - dup - len - itob - extract 6 2 - swap - concat - bytec_0 // 0x151f7c75 - swap - concat - log - intc_0 // 1 - retsub - -__puya_arc4_router___verify_asset_params_get_manager_route@9: - // tests/artifacts/state-ops/contract.algo.ts:220 - // @arc4.abimethod() - txn OnCompletion - ! - assert // OnCompletion is not NoOp - txn ApplicationID - assert // can only call when not creating - // tests/artifacts/state-ops/contract.algo.ts:156 - // export class StateAssetParamsContract extends arc4.Contract { - txna ApplicationArgs 1 - btoi - txnas Assets - // tests/artifacts/state-ops/contract.algo.ts:220 - // @arc4.abimethod() - callsub verify_asset_params_get_manager - bytec_0 // 0x151f7c75 - swap - concat - log - intc_0 // 1 - retsub - -__puya_arc4_router___verify_asset_params_get_reserve_route@10: - // tests/artifacts/state-ops/contract.algo.ts:229 - // @arc4.abimethod() - txn OnCompletion - ! - assert // OnCompletion is not NoOp - txn ApplicationID - assert // can only call when not creating - // tests/artifacts/state-ops/contract.algo.ts:156 - // export class StateAssetParamsContract extends arc4.Contract { - txna ApplicationArgs 1 - btoi - txnas Assets - // tests/artifacts/state-ops/contract.algo.ts:229 - // @arc4.abimethod() - callsub verify_asset_params_get_reserve - bytec_0 // 0x151f7c75 - swap - concat - log - intc_0 // 1 - retsub - -__puya_arc4_router___verify_asset_params_get_freeze_route@11: - // tests/artifacts/state-ops/contract.algo.ts:238 - // @arc4.abimethod() - txn OnCompletion - ! - assert // OnCompletion is not NoOp - txn ApplicationID - assert // can only call when not creating - // tests/artifacts/state-ops/contract.algo.ts:156 - // export class StateAssetParamsContract extends arc4.Contract { - txna ApplicationArgs 1 - btoi - txnas Assets - // tests/artifacts/state-ops/contract.algo.ts:238 - // @arc4.abimethod() - callsub verify_asset_params_get_freeze - bytec_0 // 0x151f7c75 - swap - concat - log - intc_0 // 1 - retsub - -__puya_arc4_router___verify_asset_params_get_clawback_route@12: - // tests/artifacts/state-ops/contract.algo.ts:247 - // @arc4.abimethod() - txn OnCompletion - ! - assert // OnCompletion is not NoOp - txn ApplicationID - assert // can only call when not creating - // tests/artifacts/state-ops/contract.algo.ts:156 - // export class StateAssetParamsContract extends arc4.Contract { - txna ApplicationArgs 1 - btoi - txnas Assets - // tests/artifacts/state-ops/contract.algo.ts:247 - // @arc4.abimethod() - callsub verify_asset_params_get_clawback - bytec_0 // 0x151f7c75 - swap - concat - log - intc_0 // 1 - retsub - -__puya_arc4_router___verify_asset_params_get_creator_route@13: - // tests/artifacts/state-ops/contract.algo.ts:256 - // @arc4.abimethod() - txn OnCompletion - ! - assert // OnCompletion is not NoOp - txn ApplicationID - assert // can only call when not creating - // tests/artifacts/state-ops/contract.algo.ts:156 - // export class StateAssetParamsContract extends arc4.Contract { - txna ApplicationArgs 1 - btoi - txnas Assets - // tests/artifacts/state-ops/contract.algo.ts:256 - // @arc4.abimethod() - callsub verify_asset_params_get_creator - bytec_0 // 0x151f7c75 - swap - concat - log - intc_0 // 1 - retsub - -__puya_arc4_router___bare_routing@16: - // tests/artifacts/state-ops/contract.algo.ts:156 - // export class StateAssetParamsContract extends arc4.Contract { - txn OnCompletion - bnz __puya_arc4_router___after_if_else@20 - txn ApplicationID - ! - assert // can only call when creating - intc_0 // 1 - retsub - -__puya_arc4_router___after_if_else@20: - // tests/artifacts/state-ops/contract.algo.ts:156 - // export class StateAssetParamsContract extends arc4.Contract { - intc_1 // 0 - retsub - - -// tests/artifacts/state-ops/contract.algo.ts::StateAssetParamsContract.verify_asset_params_get_total(a: uint64) -> uint64: -verify_asset_params_get_total: - // tests/artifacts/state-ops/contract.algo.ts:157-158 - // @arc4.abimethod() - // public verify_asset_params_get_total(a: Asset): uint64 { - proto 1 1 - // tests/artifacts/state-ops/contract.algo.ts:159 - // const [value, exists] = op.AssetParams.assetTotal(a) - frame_dig -1 - asset_params_get AssetTotal - // tests/artifacts/state-ops/contract.algo.ts:160 - // const [value_index, exists_index] = op.AssetParams.assetTotal(get_1st_ref_index()) - callsub get_1st_ref_index - asset_params_get AssetTotal - // tests/artifacts/state-ops/contract.algo.ts:161 - // assert(value === value_index, 'expected value by index to match') - dig 3 - uncover 2 - == - assert // expected value by index to match - // tests/artifacts/state-ops/contract.algo.ts:162 - // assert(exists === exists_index, 'expected exists by index to match') - == - assert // expected exists by index to match - // tests/artifacts/state-ops/contract.algo.ts:163 - // return value - retsub - - -// tests/artifacts/state-ops/contract.algo.ts::get_1st_ref_index() -> uint64: -get_1st_ref_index: - // tests/artifacts/state-ops/contract.algo.ts:22 - // function get_1st_ref_index(): uint64 { - proto 0 1 - // tests/artifacts/state-ops/contract.algo.ts:23 - // return op.btoi(Txn.applicationArgs(1)) - intc_0 // 1 - txnas ApplicationArgs - btoi - retsub - - -// tests/artifacts/state-ops/contract.algo.ts::StateAssetParamsContract.verify_asset_params_get_decimals(a: uint64) -> uint64: -verify_asset_params_get_decimals: - // tests/artifacts/state-ops/contract.algo.ts:166-167 - // @arc4.abimethod() - // public verify_asset_params_get_decimals(a: Asset): uint64 { - proto 1 1 - // tests/artifacts/state-ops/contract.algo.ts:168 - // const [value, exists] = op.AssetParams.assetDecimals(a) - frame_dig -1 - asset_params_get AssetDecimals - // tests/artifacts/state-ops/contract.algo.ts:169 - // const [value_index, exists_index] = op.AssetParams.assetDecimals(get_1st_ref_index()) - callsub get_1st_ref_index - asset_params_get AssetDecimals - // tests/artifacts/state-ops/contract.algo.ts:170 - // assert(value === value_index, 'expected value by index to match') - dig 3 - uncover 2 - == - assert // expected value by index to match - // tests/artifacts/state-ops/contract.algo.ts:171 - // assert(exists === exists_index, 'expected exists by index to match') - == - assert // expected exists by index to match - // tests/artifacts/state-ops/contract.algo.ts:172 - // return value - retsub - - -// tests/artifacts/state-ops/contract.algo.ts::StateAssetParamsContract.verify_asset_params_get_default_frozen(a: uint64) -> uint64: -verify_asset_params_get_default_frozen: - // tests/artifacts/state-ops/contract.algo.ts:175-176 - // @arc4.abimethod() - // public verify_asset_params_get_default_frozen(a: Asset): boolean { - proto 1 1 - // tests/artifacts/state-ops/contract.algo.ts:177 - // const [value, exists] = op.AssetParams.assetDefaultFrozen(a) - frame_dig -1 - asset_params_get AssetDefaultFrozen - // tests/artifacts/state-ops/contract.algo.ts:178 - // const [value_index, exists_index] = op.AssetParams.assetDefaultFrozen(get_1st_ref_index()) - callsub get_1st_ref_index - asset_params_get AssetDefaultFrozen - // tests/artifacts/state-ops/contract.algo.ts:179 - // assert(value === value_index, 'expected value by index to match') - dig 3 - uncover 2 - == - assert // expected value by index to match - // tests/artifacts/state-ops/contract.algo.ts:180 - // assert(exists === exists_index, 'expected exists by index to match') - == - assert // expected exists by index to match - // tests/artifacts/state-ops/contract.algo.ts:181 - // return value - retsub - - -// tests/artifacts/state-ops/contract.algo.ts::StateAssetParamsContract.verify_asset_params_get_unit_name(a: uint64) -> bytes: -verify_asset_params_get_unit_name: - // tests/artifacts/state-ops/contract.algo.ts:184-185 - // @arc4.abimethod() - // public verify_asset_params_get_unit_name(a: Asset): bytes { - proto 1 1 - // tests/artifacts/state-ops/contract.algo.ts:186 - // const [value, exists] = op.AssetParams.assetUnitName(a) - frame_dig -1 - asset_params_get AssetUnitName - // tests/artifacts/state-ops/contract.algo.ts:187 - // const [value_index, exists_index] = op.AssetParams.assetUnitName(get_1st_ref_index()) - callsub get_1st_ref_index - asset_params_get AssetUnitName - // tests/artifacts/state-ops/contract.algo.ts:188 - // assert(value === value_index, 'expected value by index to match') - dig 3 - uncover 2 - == - assert // expected value by index to match - // tests/artifacts/state-ops/contract.algo.ts:189 - // assert(exists === exists_index, 'expected exists by index to match') - == - assert // expected exists by index to match - // tests/artifacts/state-ops/contract.algo.ts:190 - // return value - retsub - - -// tests/artifacts/state-ops/contract.algo.ts::StateAssetParamsContract.verify_asset_params_get_name(a: uint64) -> bytes: -verify_asset_params_get_name: - // tests/artifacts/state-ops/contract.algo.ts:193-194 - // @arc4.abimethod() - // public verify_asset_params_get_name(a: Asset): bytes { - proto 1 1 - // tests/artifacts/state-ops/contract.algo.ts:195 - // const [value, exists] = op.AssetParams.assetName(a) - frame_dig -1 - asset_params_get AssetName - // tests/artifacts/state-ops/contract.algo.ts:196 - // const [value_index, exists_index] = op.AssetParams.assetName(get_1st_ref_index()) - callsub get_1st_ref_index - asset_params_get AssetName - // tests/artifacts/state-ops/contract.algo.ts:197 - // assert(value === value_index, 'expected value by index to match') - dig 3 - uncover 2 - == - assert // expected value by index to match - // tests/artifacts/state-ops/contract.algo.ts:198 - // assert(exists === exists_index, 'expected exists by index to match') - == - assert // expected exists by index to match - // tests/artifacts/state-ops/contract.algo.ts:199 - // return value - retsub - - -// tests/artifacts/state-ops/contract.algo.ts::StateAssetParamsContract.verify_asset_params_get_url(a: uint64) -> bytes: -verify_asset_params_get_url: - // tests/artifacts/state-ops/contract.algo.ts:202-203 - // @arc4.abimethod() - // public verify_asset_params_get_url(a: Asset): bytes { - proto 1 1 - // tests/artifacts/state-ops/contract.algo.ts:204 - // const [value, exists] = op.AssetParams.assetUrl(a) - frame_dig -1 - asset_params_get AssetURL - // tests/artifacts/state-ops/contract.algo.ts:205 - // const [value_index, exists_index] = op.AssetParams.assetUrl(get_1st_ref_index()) - callsub get_1st_ref_index - asset_params_get AssetURL - // tests/artifacts/state-ops/contract.algo.ts:206 - // assert(value === value_index, 'expected value by index to match') - dig 3 - uncover 2 - == - assert // expected value by index to match - // tests/artifacts/state-ops/contract.algo.ts:207 - // assert(exists === exists_index, 'expected exists by index to match') - == - assert // expected exists by index to match - // tests/artifacts/state-ops/contract.algo.ts:208 - // return value - retsub - - -// tests/artifacts/state-ops/contract.algo.ts::StateAssetParamsContract.verify_asset_params_get_metadata_hash(a: uint64) -> bytes: -verify_asset_params_get_metadata_hash: - // tests/artifacts/state-ops/contract.algo.ts:211-212 - // @arc4.abimethod() - // public verify_asset_params_get_metadata_hash(a: Asset): bytes { - proto 1 1 - // tests/artifacts/state-ops/contract.algo.ts:213 - // const [value, exists] = op.AssetParams.assetMetadataHash(a) - frame_dig -1 - asset_params_get AssetMetadataHash - // tests/artifacts/state-ops/contract.algo.ts:214 - // const [value_index, exists_index] = op.AssetParams.assetMetadataHash(get_1st_ref_index()) - callsub get_1st_ref_index - asset_params_get AssetMetadataHash - // tests/artifacts/state-ops/contract.algo.ts:215 - // assert(value === value_index, 'expected value by index to match') - dig 3 - uncover 2 - == - assert // expected value by index to match - // tests/artifacts/state-ops/contract.algo.ts:216 - // assert(exists === exists_index, 'expected exists by index to match') - == - assert // expected exists by index to match - // tests/artifacts/state-ops/contract.algo.ts:217 - // return value - retsub - - -// tests/artifacts/state-ops/contract.algo.ts::StateAssetParamsContract.verify_asset_params_get_manager(a: uint64) -> bytes: -verify_asset_params_get_manager: - // tests/artifacts/state-ops/contract.algo.ts:220-221 - // @arc4.abimethod() - // public verify_asset_params_get_manager(a: Asset): Address { - proto 1 1 - // tests/artifacts/state-ops/contract.algo.ts:222 - // const [value, exists] = op.AssetParams.assetManager(a) - frame_dig -1 - asset_params_get AssetManager - // tests/artifacts/state-ops/contract.algo.ts:223 - // const [value_index, exists_index] = op.AssetParams.assetManager(get_1st_ref_index()) - callsub get_1st_ref_index - asset_params_get AssetManager - // tests/artifacts/state-ops/contract.algo.ts:224 - // assert(value === value_index, 'expected value by index to match') - dig 3 - uncover 2 - == - assert // expected value by index to match - // tests/artifacts/state-ops/contract.algo.ts:225 - // assert(exists === exists_index, 'expected exists by index to match') - == - assert // expected exists by index to match - // tests/artifacts/state-ops/contract.algo.ts:226 - // return new Address(value) - retsub - - -// tests/artifacts/state-ops/contract.algo.ts::StateAssetParamsContract.verify_asset_params_get_reserve(a: uint64) -> bytes: -verify_asset_params_get_reserve: - // tests/artifacts/state-ops/contract.algo.ts:229-230 - // @arc4.abimethod() - // public verify_asset_params_get_reserve(a: Asset): Address { - proto 1 1 - // tests/artifacts/state-ops/contract.algo.ts:231 - // const [value, exists] = op.AssetParams.assetReserve(a) - frame_dig -1 - asset_params_get AssetReserve - // tests/artifacts/state-ops/contract.algo.ts:232 - // const [value_index, exists_index] = op.AssetParams.assetReserve(get_1st_ref_index()) - callsub get_1st_ref_index - asset_params_get AssetReserve - // tests/artifacts/state-ops/contract.algo.ts:233 - // assert(value === value_index, 'expected value by index to match') - dig 3 - uncover 2 - == - assert // expected value by index to match - // tests/artifacts/state-ops/contract.algo.ts:234 - // assert(exists === exists_index, 'expected exists by index to match') - == - assert // expected exists by index to match - // tests/artifacts/state-ops/contract.algo.ts:235 - // return new Address(value) - retsub - - -// tests/artifacts/state-ops/contract.algo.ts::StateAssetParamsContract.verify_asset_params_get_freeze(a: uint64) -> bytes: -verify_asset_params_get_freeze: - // tests/artifacts/state-ops/contract.algo.ts:238-239 - // @arc4.abimethod() - // public verify_asset_params_get_freeze(a: Asset): Address { - proto 1 1 - // tests/artifacts/state-ops/contract.algo.ts:240 - // const [value, exists] = op.AssetParams.assetFreeze(a) - frame_dig -1 - asset_params_get AssetFreeze - // tests/artifacts/state-ops/contract.algo.ts:241 - // const [value_index, exists_index] = op.AssetParams.assetFreeze(get_1st_ref_index()) - callsub get_1st_ref_index - asset_params_get AssetFreeze - // tests/artifacts/state-ops/contract.algo.ts:242 - // assert(value === value_index, 'expected value by index to match') - dig 3 - uncover 2 - == - assert // expected value by index to match - // tests/artifacts/state-ops/contract.algo.ts:243 - // assert(exists === exists_index, 'expected exists by index to match') - == - assert // expected exists by index to match - // tests/artifacts/state-ops/contract.algo.ts:244 - // return new Address(value) - retsub - - -// tests/artifacts/state-ops/contract.algo.ts::StateAssetParamsContract.verify_asset_params_get_clawback(a: uint64) -> bytes: -verify_asset_params_get_clawback: - // tests/artifacts/state-ops/contract.algo.ts:247-248 - // @arc4.abimethod() - // public verify_asset_params_get_clawback(a: Asset): Address { - proto 1 1 - // tests/artifacts/state-ops/contract.algo.ts:249 - // const [value, exists] = op.AssetParams.assetClawback(a) - frame_dig -1 - asset_params_get AssetClawback - // tests/artifacts/state-ops/contract.algo.ts:250 - // const [value_index, exists_index] = op.AssetParams.assetClawback(get_1st_ref_index()) - callsub get_1st_ref_index - asset_params_get AssetClawback - // tests/artifacts/state-ops/contract.algo.ts:251 - // assert(value === value_index, 'expected value by index to match') - dig 3 - uncover 2 - == - assert // expected value by index to match - // tests/artifacts/state-ops/contract.algo.ts:252 - // assert(exists === exists_index, 'expected exists by index to match') - == - assert // expected exists by index to match - // tests/artifacts/state-ops/contract.algo.ts:253 - // return new Address(value) - retsub - - -// tests/artifacts/state-ops/contract.algo.ts::StateAssetParamsContract.verify_asset_params_get_creator(a: uint64) -> bytes: -verify_asset_params_get_creator: - // tests/artifacts/state-ops/contract.algo.ts:256-257 - // @arc4.abimethod() - // public verify_asset_params_get_creator(a: Asset): Address { - proto 1 1 - // tests/artifacts/state-ops/contract.algo.ts:258 - // const [value, exists] = op.AssetParams.assetCreator(a) - frame_dig -1 - asset_params_get AssetCreator - // tests/artifacts/state-ops/contract.algo.ts:259 - // const [value_index, exists_index] = op.AssetParams.assetCreator(get_1st_ref_index()) - callsub get_1st_ref_index - asset_params_get AssetCreator - // tests/artifacts/state-ops/contract.algo.ts:260 - // assert(value === value_index, 'expected value by index to match') - dig 3 - uncover 2 - == - assert // expected value by index to match - // tests/artifacts/state-ops/contract.algo.ts:261 - // assert(exists === exists_index, 'expected exists by index to match') - == - assert // expected exists by index to match - // tests/artifacts/state-ops/contract.algo.ts:262 - // return new Address(value) - retsub diff --git a/tests/artifacts/state-ops/data/StateAssetParamsContract.arc32.json b/tests/artifacts/state-ops/data/StateAssetParamsContract.arc32.json deleted file mode 100644 index 0d0d9d2..0000000 --- a/tests/artifacts/state-ops/data/StateAssetParamsContract.arc32.json +++ /dev/null @@ -1,253 +0,0 @@ -{ - "hints": { - "verify_asset_params_get_total(asset)uint64": { - "call_config": { - "no_op": "CALL" - } - }, - "verify_asset_params_get_decimals(asset)uint64": { - "call_config": { - "no_op": "CALL" - } - }, - "verify_asset_params_get_default_frozen(asset)bool": { - "call_config": { - "no_op": "CALL" - } - }, - "verify_asset_params_get_unit_name(asset)byte[]": { - "call_config": { - "no_op": "CALL" - } - }, - "verify_asset_params_get_name(asset)byte[]": { - "call_config": { - "no_op": "CALL" - } - }, - "verify_asset_params_get_url(asset)byte[]": { - "call_config": { - "no_op": "CALL" - } - }, - "verify_asset_params_get_metadata_hash(asset)byte[]": { - "call_config": { - "no_op": "CALL" - } - }, - "verify_asset_params_get_manager(asset)address": { - "call_config": { - "no_op": "CALL" - } - }, - "verify_asset_params_get_reserve(asset)address": { - "call_config": { - "no_op": "CALL" - } - }, - "verify_asset_params_get_freeze(asset)address": { - "call_config": { - "no_op": "CALL" - } - }, - "verify_asset_params_get_clawback(asset)address": { - "call_config": { - "no_op": "CALL" - } - }, - "verify_asset_params_get_creator(asset)address": { - "call_config": { - "no_op": "CALL" - } - } - }, - "source": { - "approval": "I3ByYWdtYSB2ZXJzaW9uIDEwCgp0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OlN0YXRlQXNzZXRQYXJhbXNDb250cmFjdC5hcHByb3ZhbFByb2dyYW06CiAgICBpbnRjYmxvY2sgMSAwCiAgICBieXRlY2Jsb2NrIDB4MTUxZjdjNzUKICAgIGNhbGxzdWIgX19wdXlhX2FyYzRfcm91dGVyX18KICAgIHJldHVybgoKCi8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo6U3RhdGVBc3NldFBhcmFtc0NvbnRyYWN0Ll9fcHV5YV9hcmM0X3JvdXRlcl9fKCkgLT4gdWludDY0OgpfX3B1eWFfYXJjNF9yb3V0ZXJfXzoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czoxNTYKICAgIC8vIGV4cG9ydCBjbGFzcyBTdGF0ZUFzc2V0UGFyYW1zQ29udHJhY3QgZXh0ZW5kcyBhcmM0LkNvbnRyYWN0IHsKICAgIHByb3RvIDAgMQogICAgdHhuIE51bUFwcEFyZ3MKICAgIGJ6IF9fcHV5YV9hcmM0X3JvdXRlcl9fX2JhcmVfcm91dGluZ0AxNgogICAgcHVzaGJ5dGVzcyAweGFkNzE5YTZmIDB4MWQ2MDMwMTMgMHg5ZmI3MzFjZCAweDBmNWE0OTExIDB4ZjViMzcwYzYgMHhjN2Q2YWY3NCAweDZiNzFhMjYzIDB4MzA0MGViYzggMHgxZDA3ZTg0NCAweDNlNDBjYjUwIDB4MzQwYzc4NmIgMHhlMzhhOTgxNSAvLyBtZXRob2QgInZlcmlmeV9hc3NldF9wYXJhbXNfZ2V0X3RvdGFsKGFzc2V0KXVpbnQ2NCIsIG1ldGhvZCAidmVyaWZ5X2Fzc2V0X3BhcmFtc19nZXRfZGVjaW1hbHMoYXNzZXQpdWludDY0IiwgbWV0aG9kICJ2ZXJpZnlfYXNzZXRfcGFyYW1zX2dldF9kZWZhdWx0X2Zyb3plbihhc3NldClib29sIiwgbWV0aG9kICJ2ZXJpZnlfYXNzZXRfcGFyYW1zX2dldF91bml0X25hbWUoYXNzZXQpYnl0ZVtdIiwgbWV0aG9kICJ2ZXJpZnlfYXNzZXRfcGFyYW1zX2dldF9uYW1lKGFzc2V0KWJ5dGVbXSIsIG1ldGhvZCAidmVyaWZ5X2Fzc2V0X3BhcmFtc19nZXRfdXJsKGFzc2V0KWJ5dGVbXSIsIG1ldGhvZCAidmVyaWZ5X2Fzc2V0X3BhcmFtc19nZXRfbWV0YWRhdGFfaGFzaChhc3NldClieXRlW10iLCBtZXRob2QgInZlcmlmeV9hc3NldF9wYXJhbXNfZ2V0X21hbmFnZXIoYXNzZXQpYWRkcmVzcyIsIG1ldGhvZCAidmVyaWZ5X2Fzc2V0X3BhcmFtc19nZXRfcmVzZXJ2ZShhc3NldClhZGRyZXNzIiwgbWV0aG9kICJ2ZXJpZnlfYXNzZXRfcGFyYW1zX2dldF9mcmVlemUoYXNzZXQpYWRkcmVzcyIsIG1ldGhvZCAidmVyaWZ5X2Fzc2V0X3BhcmFtc19nZXRfY2xhd2JhY2soYXNzZXQpYWRkcmVzcyIsIG1ldGhvZCAidmVyaWZ5X2Fzc2V0X3BhcmFtc19nZXRfY3JlYXRvcihhc3NldClhZGRyZXNzIgogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMAogICAgbWF0Y2ggX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2Fzc2V0X3BhcmFtc19nZXRfdG90YWxfcm91dGVAMiBfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfYXNzZXRfcGFyYW1zX2dldF9kZWNpbWFsc19yb3V0ZUAzIF9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9hc3NldF9wYXJhbXNfZ2V0X2RlZmF1bHRfZnJvemVuX3JvdXRlQDQgX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2Fzc2V0X3BhcmFtc19nZXRfdW5pdF9uYW1lX3JvdXRlQDUgX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2Fzc2V0X3BhcmFtc19nZXRfbmFtZV9yb3V0ZUA2IF9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9hc3NldF9wYXJhbXNfZ2V0X3VybF9yb3V0ZUA3IF9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9hc3NldF9wYXJhbXNfZ2V0X21ldGFkYXRhX2hhc2hfcm91dGVAOCBfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfYXNzZXRfcGFyYW1zX2dldF9tYW5hZ2VyX3JvdXRlQDkgX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2Fzc2V0X3BhcmFtc19nZXRfcmVzZXJ2ZV9yb3V0ZUAxMCBfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfYXNzZXRfcGFyYW1zX2dldF9mcmVlemVfcm91dGVAMTEgX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2Fzc2V0X3BhcmFtc19nZXRfY2xhd2JhY2tfcm91dGVAMTIgX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2Fzc2V0X3BhcmFtc19nZXRfY3JlYXRvcl9yb3V0ZUAxMwogICAgaW50Y18xIC8vIDAKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2Fzc2V0X3BhcmFtc19nZXRfdG90YWxfcm91dGVAMjoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czoxNTcKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIG5vdCBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGNhbiBvbmx5IGNhbGwgd2hlbiBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czoxNTYKICAgIC8vIGV4cG9ydCBjbGFzcyBTdGF0ZUFzc2V0UGFyYW1zQ29udHJhY3QgZXh0ZW5kcyBhcmM0LkNvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGJ0b2kKICAgIHR4bmFzIEFzc2V0cwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjE1NwogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X2Fzc2V0X3BhcmFtc19nZXRfdG90YWwKICAgIGl0b2IKICAgIGJ5dGVjXzAgLy8gMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludGNfMCAvLyAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9hc3NldF9wYXJhbXNfZ2V0X2RlY2ltYWxzX3JvdXRlQDM6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTY2CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBub3QgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBjYW4gb25seSBjYWxsIHdoZW4gbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTU2CiAgICAvLyBleHBvcnQgY2xhc3MgU3RhdGVBc3NldFBhcmFtc0NvbnRyYWN0IGV4dGVuZHMgYXJjNC5Db250cmFjdCB7CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBidG9pCiAgICB0eG5hcyBBc3NldHMKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czoxNjYKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV9hc3NldF9wYXJhbXNfZ2V0X2RlY2ltYWxzCiAgICBpdG9iCiAgICBieXRlY18wIC8vIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnRjXzAgLy8gMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfYXNzZXRfcGFyYW1zX2dldF9kZWZhdWx0X2Zyb3plbl9yb3V0ZUA0OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjE3NQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgbm90IE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gY2FuIG9ubHkgY2FsbCB3aGVuIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjE1NgogICAgLy8gZXhwb3J0IGNsYXNzIFN0YXRlQXNzZXRQYXJhbXNDb250cmFjdCBleHRlbmRzIGFyYzQuQ29udHJhY3QgewogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgYnRvaQogICAgdHhuYXMgQXNzZXRzCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTc1CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfYXNzZXRfcGFyYW1zX2dldF9kZWZhdWx0X2Zyb3plbgogICAgcHVzaGJ5dGVzIDB4MDAKICAgIGludGNfMSAvLyAwCiAgICB1bmNvdmVyIDIKICAgIHNldGJpdAogICAgYnl0ZWNfMCAvLyAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50Y18wIC8vIDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2Fzc2V0X3BhcmFtc19nZXRfdW5pdF9uYW1lX3JvdXRlQDU6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTg0CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBub3QgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBjYW4gb25seSBjYWxsIHdoZW4gbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTU2CiAgICAvLyBleHBvcnQgY2xhc3MgU3RhdGVBc3NldFBhcmFtc0NvbnRyYWN0IGV4dGVuZHMgYXJjNC5Db250cmFjdCB7CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBidG9pCiAgICB0eG5hcyBBc3NldHMKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czoxODQKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV9hc3NldF9wYXJhbXNfZ2V0X3VuaXRfbmFtZQogICAgZHVwCiAgICBsZW4KICAgIGl0b2IKICAgIGV4dHJhY3QgNiAyCiAgICBzd2FwCiAgICBjb25jYXQKICAgIGJ5dGVjXzAgLy8gMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludGNfMCAvLyAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9hc3NldF9wYXJhbXNfZ2V0X25hbWVfcm91dGVANjoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czoxOTMKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIG5vdCBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGNhbiBvbmx5IGNhbGwgd2hlbiBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czoxNTYKICAgIC8vIGV4cG9ydCBjbGFzcyBTdGF0ZUFzc2V0UGFyYW1zQ29udHJhY3QgZXh0ZW5kcyBhcmM0LkNvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGJ0b2kKICAgIHR4bmFzIEFzc2V0cwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjE5MwogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X2Fzc2V0X3BhcmFtc19nZXRfbmFtZQogICAgZHVwCiAgICBsZW4KICAgIGl0b2IKICAgIGV4dHJhY3QgNiAyCiAgICBzd2FwCiAgICBjb25jYXQKICAgIGJ5dGVjXzAgLy8gMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludGNfMCAvLyAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9hc3NldF9wYXJhbXNfZ2V0X3VybF9yb3V0ZUA3OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjIwMgogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgbm90IE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gY2FuIG9ubHkgY2FsbCB3aGVuIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjE1NgogICAgLy8gZXhwb3J0IGNsYXNzIFN0YXRlQXNzZXRQYXJhbXNDb250cmFjdCBleHRlbmRzIGFyYzQuQ29udHJhY3QgewogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgYnRvaQogICAgdHhuYXMgQXNzZXRzCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MjAyCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfYXNzZXRfcGFyYW1zX2dldF91cmwKICAgIGR1cAogICAgbGVuCiAgICBpdG9iCiAgICBleHRyYWN0IDYgMgogICAgc3dhcAogICAgY29uY2F0CiAgICBieXRlY18wIC8vIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnRjXzAgLy8gMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfYXNzZXRfcGFyYW1zX2dldF9tZXRhZGF0YV9oYXNoX3JvdXRlQDg6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MjExCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBub3QgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBjYW4gb25seSBjYWxsIHdoZW4gbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTU2CiAgICAvLyBleHBvcnQgY2xhc3MgU3RhdGVBc3NldFBhcmFtc0NvbnRyYWN0IGV4dGVuZHMgYXJjNC5Db250cmFjdCB7CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBidG9pCiAgICB0eG5hcyBBc3NldHMKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czoyMTEKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV9hc3NldF9wYXJhbXNfZ2V0X21ldGFkYXRhX2hhc2gKICAgIGR1cAogICAgbGVuCiAgICBpdG9iCiAgICBleHRyYWN0IDYgMgogICAgc3dhcAogICAgY29uY2F0CiAgICBieXRlY18wIC8vIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnRjXzAgLy8gMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfYXNzZXRfcGFyYW1zX2dldF9tYW5hZ2VyX3JvdXRlQDk6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MjIwCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBub3QgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBjYW4gb25seSBjYWxsIHdoZW4gbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTU2CiAgICAvLyBleHBvcnQgY2xhc3MgU3RhdGVBc3NldFBhcmFtc0NvbnRyYWN0IGV4dGVuZHMgYXJjNC5Db250cmFjdCB7CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBidG9pCiAgICB0eG5hcyBBc3NldHMKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czoyMjAKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV9hc3NldF9wYXJhbXNfZ2V0X21hbmFnZXIKICAgIGJ5dGVjXzAgLy8gMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludGNfMCAvLyAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9hc3NldF9wYXJhbXNfZ2V0X3Jlc2VydmVfcm91dGVAMTA6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MjI5CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBub3QgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBjYW4gb25seSBjYWxsIHdoZW4gbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTU2CiAgICAvLyBleHBvcnQgY2xhc3MgU3RhdGVBc3NldFBhcmFtc0NvbnRyYWN0IGV4dGVuZHMgYXJjNC5Db250cmFjdCB7CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBidG9pCiAgICB0eG5hcyBBc3NldHMKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czoyMjkKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV9hc3NldF9wYXJhbXNfZ2V0X3Jlc2VydmUKICAgIGJ5dGVjXzAgLy8gMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludGNfMCAvLyAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9hc3NldF9wYXJhbXNfZ2V0X2ZyZWV6ZV9yb3V0ZUAxMToKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czoyMzgKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIG5vdCBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGNhbiBvbmx5IGNhbGwgd2hlbiBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czoxNTYKICAgIC8vIGV4cG9ydCBjbGFzcyBTdGF0ZUFzc2V0UGFyYW1zQ29udHJhY3QgZXh0ZW5kcyBhcmM0LkNvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGJ0b2kKICAgIHR4bmFzIEFzc2V0cwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjIzOAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X2Fzc2V0X3BhcmFtc19nZXRfZnJlZXplCiAgICBieXRlY18wIC8vIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnRjXzAgLy8gMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfYXNzZXRfcGFyYW1zX2dldF9jbGF3YmFja19yb3V0ZUAxMjoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czoyNDcKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIG5vdCBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGNhbiBvbmx5IGNhbGwgd2hlbiBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czoxNTYKICAgIC8vIGV4cG9ydCBjbGFzcyBTdGF0ZUFzc2V0UGFyYW1zQ29udHJhY3QgZXh0ZW5kcyBhcmM0LkNvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGJ0b2kKICAgIHR4bmFzIEFzc2V0cwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjI0NwogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X2Fzc2V0X3BhcmFtc19nZXRfY2xhd2JhY2sKICAgIGJ5dGVjXzAgLy8gMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludGNfMCAvLyAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9hc3NldF9wYXJhbXNfZ2V0X2NyZWF0b3Jfcm91dGVAMTM6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MjU2CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBub3QgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBjYW4gb25seSBjYWxsIHdoZW4gbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTU2CiAgICAvLyBleHBvcnQgY2xhc3MgU3RhdGVBc3NldFBhcmFtc0NvbnRyYWN0IGV4dGVuZHMgYXJjNC5Db250cmFjdCB7CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBidG9pCiAgICB0eG5hcyBBc3NldHMKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czoyNTYKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV9hc3NldF9wYXJhbXNfZ2V0X2NyZWF0b3IKICAgIGJ5dGVjXzAgLy8gMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludGNfMCAvLyAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX2JhcmVfcm91dGluZ0AxNjoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czoxNTYKICAgIC8vIGV4cG9ydCBjbGFzcyBTdGF0ZUFzc2V0UGFyYW1zQ29udHJhY3QgZXh0ZW5kcyBhcmM0LkNvbnRyYWN0IHsKICAgIHR4biBPbkNvbXBsZXRpb24KICAgIGJueiBfX3B1eWFfYXJjNF9yb3V0ZXJfX19hZnRlcl9pZl9lbHNlQDIwCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgIQogICAgYXNzZXJ0IC8vIGNhbiBvbmx5IGNhbGwgd2hlbiBjcmVhdGluZwogICAgaW50Y18wIC8vIDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fYWZ0ZXJfaWZfZWxzZUAyMDoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czoxNTYKICAgIC8vIGV4cG9ydCBjbGFzcyBTdGF0ZUFzc2V0UGFyYW1zQ29udHJhY3QgZXh0ZW5kcyBhcmM0LkNvbnRyYWN0IHsKICAgIGludGNfMSAvLyAwCiAgICByZXRzdWIKCgovLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OlN0YXRlQXNzZXRQYXJhbXNDb250cmFjdC52ZXJpZnlfYXNzZXRfcGFyYW1zX2dldF90b3RhbChhOiB1aW50NjQpIC0+IHVpbnQ2NDoKdmVyaWZ5X2Fzc2V0X3BhcmFtc19nZXRfdG90YWw6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTU3LTE1OAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIHB1YmxpYyB2ZXJpZnlfYXNzZXRfcGFyYW1zX2dldF90b3RhbChhOiBBc3NldCk6IHVpbnQ2NCB7CiAgICBwcm90byAxIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czoxNTkKICAgIC8vIGNvbnN0IFt2YWx1ZSwgZXhpc3RzXSA9IG9wLkFzc2V0UGFyYW1zLmFzc2V0VG90YWwoYSkKICAgIGZyYW1lX2RpZyAtMQogICAgYXNzZXRfcGFyYW1zX2dldCBBc3NldFRvdGFsCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTYwCiAgICAvLyBjb25zdCBbdmFsdWVfaW5kZXgsIGV4aXN0c19pbmRleF0gPSBvcC5Bc3NldFBhcmFtcy5hc3NldFRvdGFsKGdldF8xc3RfcmVmX2luZGV4KCkpCiAgICBjYWxsc3ViIGdldF8xc3RfcmVmX2luZGV4CiAgICBhc3NldF9wYXJhbXNfZ2V0IEFzc2V0VG90YWwKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czoxNjEKICAgIC8vIGFzc2VydCh2YWx1ZSA9PT0gdmFsdWVfaW5kZXgsICdleHBlY3RlZCB2YWx1ZSBieSBpbmRleCB0byBtYXRjaCcpCiAgICBkaWcgMwogICAgdW5jb3ZlciAyCiAgICA9PQogICAgYXNzZXJ0IC8vIGV4cGVjdGVkIHZhbHVlIGJ5IGluZGV4IHRvIG1hdGNoCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTYyCiAgICAvLyBhc3NlcnQoZXhpc3RzID09PSBleGlzdHNfaW5kZXgsICdleHBlY3RlZCBleGlzdHMgYnkgaW5kZXggdG8gbWF0Y2gnKQogICAgPT0KICAgIGFzc2VydCAvLyBleHBlY3RlZCBleGlzdHMgYnkgaW5kZXggdG8gbWF0Y2gKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czoxNjMKICAgIC8vIHJldHVybiB2YWx1ZQogICAgcmV0c3ViCgoKLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjpnZXRfMXN0X3JlZl9pbmRleCgpIC0+IHVpbnQ2NDoKZ2V0XzFzdF9yZWZfaW5kZXg6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MjIKICAgIC8vIGZ1bmN0aW9uIGdldF8xc3RfcmVmX2luZGV4KCk6IHVpbnQ2NCB7CiAgICBwcm90byAwIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czoyMwogICAgLy8gcmV0dXJuIG9wLmJ0b2koVHhuLmFwcGxpY2F0aW9uQXJncygxKSkKICAgIGludGNfMCAvLyAxCiAgICB0eG5hcyBBcHBsaWNhdGlvbkFyZ3MKICAgIGJ0b2kKICAgIHJldHN1YgoKCi8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo6U3RhdGVBc3NldFBhcmFtc0NvbnRyYWN0LnZlcmlmeV9hc3NldF9wYXJhbXNfZ2V0X2RlY2ltYWxzKGE6IHVpbnQ2NCkgLT4gdWludDY0Ogp2ZXJpZnlfYXNzZXRfcGFyYW1zX2dldF9kZWNpbWFsczoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czoxNjYtMTY3CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gcHVibGljIHZlcmlmeV9hc3NldF9wYXJhbXNfZ2V0X2RlY2ltYWxzKGE6IEFzc2V0KTogdWludDY0IHsKICAgIHByb3RvIDEgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjE2OAogICAgLy8gY29uc3QgW3ZhbHVlLCBleGlzdHNdID0gb3AuQXNzZXRQYXJhbXMuYXNzZXREZWNpbWFscyhhKQogICAgZnJhbWVfZGlnIC0xCiAgICBhc3NldF9wYXJhbXNfZ2V0IEFzc2V0RGVjaW1hbHMKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czoxNjkKICAgIC8vIGNvbnN0IFt2YWx1ZV9pbmRleCwgZXhpc3RzX2luZGV4XSA9IG9wLkFzc2V0UGFyYW1zLmFzc2V0RGVjaW1hbHMoZ2V0XzFzdF9yZWZfaW5kZXgoKSkKICAgIGNhbGxzdWIgZ2V0XzFzdF9yZWZfaW5kZXgKICAgIGFzc2V0X3BhcmFtc19nZXQgQXNzZXREZWNpbWFscwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjE3MAogICAgLy8gYXNzZXJ0KHZhbHVlID09PSB2YWx1ZV9pbmRleCwgJ2V4cGVjdGVkIHZhbHVlIGJ5IGluZGV4IHRvIG1hdGNoJykKICAgIGRpZyAzCiAgICB1bmNvdmVyIDIKICAgID09CiAgICBhc3NlcnQgLy8gZXhwZWN0ZWQgdmFsdWUgYnkgaW5kZXggdG8gbWF0Y2gKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czoxNzEKICAgIC8vIGFzc2VydChleGlzdHMgPT09IGV4aXN0c19pbmRleCwgJ2V4cGVjdGVkIGV4aXN0cyBieSBpbmRleCB0byBtYXRjaCcpCiAgICA9PQogICAgYXNzZXJ0IC8vIGV4cGVjdGVkIGV4aXN0cyBieSBpbmRleCB0byBtYXRjaAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjE3MgogICAgLy8gcmV0dXJuIHZhbHVlCiAgICByZXRzdWIKCgovLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OlN0YXRlQXNzZXRQYXJhbXNDb250cmFjdC52ZXJpZnlfYXNzZXRfcGFyYW1zX2dldF9kZWZhdWx0X2Zyb3plbihhOiB1aW50NjQpIC0+IHVpbnQ2NDoKdmVyaWZ5X2Fzc2V0X3BhcmFtc19nZXRfZGVmYXVsdF9mcm96ZW46CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTc1LTE3NgogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIHB1YmxpYyB2ZXJpZnlfYXNzZXRfcGFyYW1zX2dldF9kZWZhdWx0X2Zyb3plbihhOiBBc3NldCk6IGJvb2xlYW4gewogICAgcHJvdG8gMSAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTc3CiAgICAvLyBjb25zdCBbdmFsdWUsIGV4aXN0c10gPSBvcC5Bc3NldFBhcmFtcy5hc3NldERlZmF1bHRGcm96ZW4oYSkKICAgIGZyYW1lX2RpZyAtMQogICAgYXNzZXRfcGFyYW1zX2dldCBBc3NldERlZmF1bHRGcm96ZW4KICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czoxNzgKICAgIC8vIGNvbnN0IFt2YWx1ZV9pbmRleCwgZXhpc3RzX2luZGV4XSA9IG9wLkFzc2V0UGFyYW1zLmFzc2V0RGVmYXVsdEZyb3plbihnZXRfMXN0X3JlZl9pbmRleCgpKQogICAgY2FsbHN1YiBnZXRfMXN0X3JlZl9pbmRleAogICAgYXNzZXRfcGFyYW1zX2dldCBBc3NldERlZmF1bHRGcm96ZW4KICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czoxNzkKICAgIC8vIGFzc2VydCh2YWx1ZSA9PT0gdmFsdWVfaW5kZXgsICdleHBlY3RlZCB2YWx1ZSBieSBpbmRleCB0byBtYXRjaCcpCiAgICBkaWcgMwogICAgdW5jb3ZlciAyCiAgICA9PQogICAgYXNzZXJ0IC8vIGV4cGVjdGVkIHZhbHVlIGJ5IGluZGV4IHRvIG1hdGNoCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTgwCiAgICAvLyBhc3NlcnQoZXhpc3RzID09PSBleGlzdHNfaW5kZXgsICdleHBlY3RlZCBleGlzdHMgYnkgaW5kZXggdG8gbWF0Y2gnKQogICAgPT0KICAgIGFzc2VydCAvLyBleHBlY3RlZCBleGlzdHMgYnkgaW5kZXggdG8gbWF0Y2gKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czoxODEKICAgIC8vIHJldHVybiB2YWx1ZQogICAgcmV0c3ViCgoKLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjpTdGF0ZUFzc2V0UGFyYW1zQ29udHJhY3QudmVyaWZ5X2Fzc2V0X3BhcmFtc19nZXRfdW5pdF9uYW1lKGE6IHVpbnQ2NCkgLT4gYnl0ZXM6CnZlcmlmeV9hc3NldF9wYXJhbXNfZ2V0X3VuaXRfbmFtZToKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czoxODQtMTg1CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gcHVibGljIHZlcmlmeV9hc3NldF9wYXJhbXNfZ2V0X3VuaXRfbmFtZShhOiBBc3NldCk6IGJ5dGVzIHsKICAgIHByb3RvIDEgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjE4NgogICAgLy8gY29uc3QgW3ZhbHVlLCBleGlzdHNdID0gb3AuQXNzZXRQYXJhbXMuYXNzZXRVbml0TmFtZShhKQogICAgZnJhbWVfZGlnIC0xCiAgICBhc3NldF9wYXJhbXNfZ2V0IEFzc2V0VW5pdE5hbWUKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czoxODcKICAgIC8vIGNvbnN0IFt2YWx1ZV9pbmRleCwgZXhpc3RzX2luZGV4XSA9IG9wLkFzc2V0UGFyYW1zLmFzc2V0VW5pdE5hbWUoZ2V0XzFzdF9yZWZfaW5kZXgoKSkKICAgIGNhbGxzdWIgZ2V0XzFzdF9yZWZfaW5kZXgKICAgIGFzc2V0X3BhcmFtc19nZXQgQXNzZXRVbml0TmFtZQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjE4OAogICAgLy8gYXNzZXJ0KHZhbHVlID09PSB2YWx1ZV9pbmRleCwgJ2V4cGVjdGVkIHZhbHVlIGJ5IGluZGV4IHRvIG1hdGNoJykKICAgIGRpZyAzCiAgICB1bmNvdmVyIDIKICAgID09CiAgICBhc3NlcnQgLy8gZXhwZWN0ZWQgdmFsdWUgYnkgaW5kZXggdG8gbWF0Y2gKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czoxODkKICAgIC8vIGFzc2VydChleGlzdHMgPT09IGV4aXN0c19pbmRleCwgJ2V4cGVjdGVkIGV4aXN0cyBieSBpbmRleCB0byBtYXRjaCcpCiAgICA9PQogICAgYXNzZXJ0IC8vIGV4cGVjdGVkIGV4aXN0cyBieSBpbmRleCB0byBtYXRjaAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjE5MAogICAgLy8gcmV0dXJuIHZhbHVlCiAgICByZXRzdWIKCgovLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OlN0YXRlQXNzZXRQYXJhbXNDb250cmFjdC52ZXJpZnlfYXNzZXRfcGFyYW1zX2dldF9uYW1lKGE6IHVpbnQ2NCkgLT4gYnl0ZXM6CnZlcmlmeV9hc3NldF9wYXJhbXNfZ2V0X25hbWU6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTkzLTE5NAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIHB1YmxpYyB2ZXJpZnlfYXNzZXRfcGFyYW1zX2dldF9uYW1lKGE6IEFzc2V0KTogYnl0ZXMgewogICAgcHJvdG8gMSAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTk1CiAgICAvLyBjb25zdCBbdmFsdWUsIGV4aXN0c10gPSBvcC5Bc3NldFBhcmFtcy5hc3NldE5hbWUoYSkKICAgIGZyYW1lX2RpZyAtMQogICAgYXNzZXRfcGFyYW1zX2dldCBBc3NldE5hbWUKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czoxOTYKICAgIC8vIGNvbnN0IFt2YWx1ZV9pbmRleCwgZXhpc3RzX2luZGV4XSA9IG9wLkFzc2V0UGFyYW1zLmFzc2V0TmFtZShnZXRfMXN0X3JlZl9pbmRleCgpKQogICAgY2FsbHN1YiBnZXRfMXN0X3JlZl9pbmRleAogICAgYXNzZXRfcGFyYW1zX2dldCBBc3NldE5hbWUKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czoxOTcKICAgIC8vIGFzc2VydCh2YWx1ZSA9PT0gdmFsdWVfaW5kZXgsICdleHBlY3RlZCB2YWx1ZSBieSBpbmRleCB0byBtYXRjaCcpCiAgICBkaWcgMwogICAgdW5jb3ZlciAyCiAgICA9PQogICAgYXNzZXJ0IC8vIGV4cGVjdGVkIHZhbHVlIGJ5IGluZGV4IHRvIG1hdGNoCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTk4CiAgICAvLyBhc3NlcnQoZXhpc3RzID09PSBleGlzdHNfaW5kZXgsICdleHBlY3RlZCBleGlzdHMgYnkgaW5kZXggdG8gbWF0Y2gnKQogICAgPT0KICAgIGFzc2VydCAvLyBleHBlY3RlZCBleGlzdHMgYnkgaW5kZXggdG8gbWF0Y2gKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czoxOTkKICAgIC8vIHJldHVybiB2YWx1ZQogICAgcmV0c3ViCgoKLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjpTdGF0ZUFzc2V0UGFyYW1zQ29udHJhY3QudmVyaWZ5X2Fzc2V0X3BhcmFtc19nZXRfdXJsKGE6IHVpbnQ2NCkgLT4gYnl0ZXM6CnZlcmlmeV9hc3NldF9wYXJhbXNfZ2V0X3VybDoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czoyMDItMjAzCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gcHVibGljIHZlcmlmeV9hc3NldF9wYXJhbXNfZ2V0X3VybChhOiBBc3NldCk6IGJ5dGVzIHsKICAgIHByb3RvIDEgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjIwNAogICAgLy8gY29uc3QgW3ZhbHVlLCBleGlzdHNdID0gb3AuQXNzZXRQYXJhbXMuYXNzZXRVcmwoYSkKICAgIGZyYW1lX2RpZyAtMQogICAgYXNzZXRfcGFyYW1zX2dldCBBc3NldFVSTAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjIwNQogICAgLy8gY29uc3QgW3ZhbHVlX2luZGV4LCBleGlzdHNfaW5kZXhdID0gb3AuQXNzZXRQYXJhbXMuYXNzZXRVcmwoZ2V0XzFzdF9yZWZfaW5kZXgoKSkKICAgIGNhbGxzdWIgZ2V0XzFzdF9yZWZfaW5kZXgKICAgIGFzc2V0X3BhcmFtc19nZXQgQXNzZXRVUkwKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czoyMDYKICAgIC8vIGFzc2VydCh2YWx1ZSA9PT0gdmFsdWVfaW5kZXgsICdleHBlY3RlZCB2YWx1ZSBieSBpbmRleCB0byBtYXRjaCcpCiAgICBkaWcgMwogICAgdW5jb3ZlciAyCiAgICA9PQogICAgYXNzZXJ0IC8vIGV4cGVjdGVkIHZhbHVlIGJ5IGluZGV4IHRvIG1hdGNoCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MjA3CiAgICAvLyBhc3NlcnQoZXhpc3RzID09PSBleGlzdHNfaW5kZXgsICdleHBlY3RlZCBleGlzdHMgYnkgaW5kZXggdG8gbWF0Y2gnKQogICAgPT0KICAgIGFzc2VydCAvLyBleHBlY3RlZCBleGlzdHMgYnkgaW5kZXggdG8gbWF0Y2gKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czoyMDgKICAgIC8vIHJldHVybiB2YWx1ZQogICAgcmV0c3ViCgoKLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjpTdGF0ZUFzc2V0UGFyYW1zQ29udHJhY3QudmVyaWZ5X2Fzc2V0X3BhcmFtc19nZXRfbWV0YWRhdGFfaGFzaChhOiB1aW50NjQpIC0+IGJ5dGVzOgp2ZXJpZnlfYXNzZXRfcGFyYW1zX2dldF9tZXRhZGF0YV9oYXNoOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjIxMS0yMTIKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBwdWJsaWMgdmVyaWZ5X2Fzc2V0X3BhcmFtc19nZXRfbWV0YWRhdGFfaGFzaChhOiBBc3NldCk6IGJ5dGVzIHsKICAgIHByb3RvIDEgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjIxMwogICAgLy8gY29uc3QgW3ZhbHVlLCBleGlzdHNdID0gb3AuQXNzZXRQYXJhbXMuYXNzZXRNZXRhZGF0YUhhc2goYSkKICAgIGZyYW1lX2RpZyAtMQogICAgYXNzZXRfcGFyYW1zX2dldCBBc3NldE1ldGFkYXRhSGFzaAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjIxNAogICAgLy8gY29uc3QgW3ZhbHVlX2luZGV4LCBleGlzdHNfaW5kZXhdID0gb3AuQXNzZXRQYXJhbXMuYXNzZXRNZXRhZGF0YUhhc2goZ2V0XzFzdF9yZWZfaW5kZXgoKSkKICAgIGNhbGxzdWIgZ2V0XzFzdF9yZWZfaW5kZXgKICAgIGFzc2V0X3BhcmFtc19nZXQgQXNzZXRNZXRhZGF0YUhhc2gKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czoyMTUKICAgIC8vIGFzc2VydCh2YWx1ZSA9PT0gdmFsdWVfaW5kZXgsICdleHBlY3RlZCB2YWx1ZSBieSBpbmRleCB0byBtYXRjaCcpCiAgICBkaWcgMwogICAgdW5jb3ZlciAyCiAgICA9PQogICAgYXNzZXJ0IC8vIGV4cGVjdGVkIHZhbHVlIGJ5IGluZGV4IHRvIG1hdGNoCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MjE2CiAgICAvLyBhc3NlcnQoZXhpc3RzID09PSBleGlzdHNfaW5kZXgsICdleHBlY3RlZCBleGlzdHMgYnkgaW5kZXggdG8gbWF0Y2gnKQogICAgPT0KICAgIGFzc2VydCAvLyBleHBlY3RlZCBleGlzdHMgYnkgaW5kZXggdG8gbWF0Y2gKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czoyMTcKICAgIC8vIHJldHVybiB2YWx1ZQogICAgcmV0c3ViCgoKLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjpTdGF0ZUFzc2V0UGFyYW1zQ29udHJhY3QudmVyaWZ5X2Fzc2V0X3BhcmFtc19nZXRfbWFuYWdlcihhOiB1aW50NjQpIC0+IGJ5dGVzOgp2ZXJpZnlfYXNzZXRfcGFyYW1zX2dldF9tYW5hZ2VyOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjIyMC0yMjEKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBwdWJsaWMgdmVyaWZ5X2Fzc2V0X3BhcmFtc19nZXRfbWFuYWdlcihhOiBBc3NldCk6IEFkZHJlc3MgewogICAgcHJvdG8gMSAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MjIyCiAgICAvLyBjb25zdCBbdmFsdWUsIGV4aXN0c10gPSBvcC5Bc3NldFBhcmFtcy5hc3NldE1hbmFnZXIoYSkKICAgIGZyYW1lX2RpZyAtMQogICAgYXNzZXRfcGFyYW1zX2dldCBBc3NldE1hbmFnZXIKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czoyMjMKICAgIC8vIGNvbnN0IFt2YWx1ZV9pbmRleCwgZXhpc3RzX2luZGV4XSA9IG9wLkFzc2V0UGFyYW1zLmFzc2V0TWFuYWdlcihnZXRfMXN0X3JlZl9pbmRleCgpKQogICAgY2FsbHN1YiBnZXRfMXN0X3JlZl9pbmRleAogICAgYXNzZXRfcGFyYW1zX2dldCBBc3NldE1hbmFnZXIKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czoyMjQKICAgIC8vIGFzc2VydCh2YWx1ZSA9PT0gdmFsdWVfaW5kZXgsICdleHBlY3RlZCB2YWx1ZSBieSBpbmRleCB0byBtYXRjaCcpCiAgICBkaWcgMwogICAgdW5jb3ZlciAyCiAgICA9PQogICAgYXNzZXJ0IC8vIGV4cGVjdGVkIHZhbHVlIGJ5IGluZGV4IHRvIG1hdGNoCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MjI1CiAgICAvLyBhc3NlcnQoZXhpc3RzID09PSBleGlzdHNfaW5kZXgsICdleHBlY3RlZCBleGlzdHMgYnkgaW5kZXggdG8gbWF0Y2gnKQogICAgPT0KICAgIGFzc2VydCAvLyBleHBlY3RlZCBleGlzdHMgYnkgaW5kZXggdG8gbWF0Y2gKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czoyMjYKICAgIC8vIHJldHVybiBuZXcgQWRkcmVzcyh2YWx1ZSkKICAgIHJldHN1YgoKCi8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo6U3RhdGVBc3NldFBhcmFtc0NvbnRyYWN0LnZlcmlmeV9hc3NldF9wYXJhbXNfZ2V0X3Jlc2VydmUoYTogdWludDY0KSAtPiBieXRlczoKdmVyaWZ5X2Fzc2V0X3BhcmFtc19nZXRfcmVzZXJ2ZToKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czoyMjktMjMwCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gcHVibGljIHZlcmlmeV9hc3NldF9wYXJhbXNfZ2V0X3Jlc2VydmUoYTogQXNzZXQpOiBBZGRyZXNzIHsKICAgIHByb3RvIDEgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjIzMQogICAgLy8gY29uc3QgW3ZhbHVlLCBleGlzdHNdID0gb3AuQXNzZXRQYXJhbXMuYXNzZXRSZXNlcnZlKGEpCiAgICBmcmFtZV9kaWcgLTEKICAgIGFzc2V0X3BhcmFtc19nZXQgQXNzZXRSZXNlcnZlCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MjMyCiAgICAvLyBjb25zdCBbdmFsdWVfaW5kZXgsIGV4aXN0c19pbmRleF0gPSBvcC5Bc3NldFBhcmFtcy5hc3NldFJlc2VydmUoZ2V0XzFzdF9yZWZfaW5kZXgoKSkKICAgIGNhbGxzdWIgZ2V0XzFzdF9yZWZfaW5kZXgKICAgIGFzc2V0X3BhcmFtc19nZXQgQXNzZXRSZXNlcnZlCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MjMzCiAgICAvLyBhc3NlcnQodmFsdWUgPT09IHZhbHVlX2luZGV4LCAnZXhwZWN0ZWQgdmFsdWUgYnkgaW5kZXggdG8gbWF0Y2gnKQogICAgZGlnIDMKICAgIHVuY292ZXIgMgogICAgPT0KICAgIGFzc2VydCAvLyBleHBlY3RlZCB2YWx1ZSBieSBpbmRleCB0byBtYXRjaAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjIzNAogICAgLy8gYXNzZXJ0KGV4aXN0cyA9PT0gZXhpc3RzX2luZGV4LCAnZXhwZWN0ZWQgZXhpc3RzIGJ5IGluZGV4IHRvIG1hdGNoJykKICAgID09CiAgICBhc3NlcnQgLy8gZXhwZWN0ZWQgZXhpc3RzIGJ5IGluZGV4IHRvIG1hdGNoCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MjM1CiAgICAvLyByZXR1cm4gbmV3IEFkZHJlc3ModmFsdWUpCiAgICByZXRzdWIKCgovLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OlN0YXRlQXNzZXRQYXJhbXNDb250cmFjdC52ZXJpZnlfYXNzZXRfcGFyYW1zX2dldF9mcmVlemUoYTogdWludDY0KSAtPiBieXRlczoKdmVyaWZ5X2Fzc2V0X3BhcmFtc19nZXRfZnJlZXplOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjIzOC0yMzkKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBwdWJsaWMgdmVyaWZ5X2Fzc2V0X3BhcmFtc19nZXRfZnJlZXplKGE6IEFzc2V0KTogQWRkcmVzcyB7CiAgICBwcm90byAxIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czoyNDAKICAgIC8vIGNvbnN0IFt2YWx1ZSwgZXhpc3RzXSA9IG9wLkFzc2V0UGFyYW1zLmFzc2V0RnJlZXplKGEpCiAgICBmcmFtZV9kaWcgLTEKICAgIGFzc2V0X3BhcmFtc19nZXQgQXNzZXRGcmVlemUKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czoyNDEKICAgIC8vIGNvbnN0IFt2YWx1ZV9pbmRleCwgZXhpc3RzX2luZGV4XSA9IG9wLkFzc2V0UGFyYW1zLmFzc2V0RnJlZXplKGdldF8xc3RfcmVmX2luZGV4KCkpCiAgICBjYWxsc3ViIGdldF8xc3RfcmVmX2luZGV4CiAgICBhc3NldF9wYXJhbXNfZ2V0IEFzc2V0RnJlZXplCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MjQyCiAgICAvLyBhc3NlcnQodmFsdWUgPT09IHZhbHVlX2luZGV4LCAnZXhwZWN0ZWQgdmFsdWUgYnkgaW5kZXggdG8gbWF0Y2gnKQogICAgZGlnIDMKICAgIHVuY292ZXIgMgogICAgPT0KICAgIGFzc2VydCAvLyBleHBlY3RlZCB2YWx1ZSBieSBpbmRleCB0byBtYXRjaAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjI0MwogICAgLy8gYXNzZXJ0KGV4aXN0cyA9PT0gZXhpc3RzX2luZGV4LCAnZXhwZWN0ZWQgZXhpc3RzIGJ5IGluZGV4IHRvIG1hdGNoJykKICAgID09CiAgICBhc3NlcnQgLy8gZXhwZWN0ZWQgZXhpc3RzIGJ5IGluZGV4IHRvIG1hdGNoCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MjQ0CiAgICAvLyByZXR1cm4gbmV3IEFkZHJlc3ModmFsdWUpCiAgICByZXRzdWIKCgovLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OlN0YXRlQXNzZXRQYXJhbXNDb250cmFjdC52ZXJpZnlfYXNzZXRfcGFyYW1zX2dldF9jbGF3YmFjayhhOiB1aW50NjQpIC0+IGJ5dGVzOgp2ZXJpZnlfYXNzZXRfcGFyYW1zX2dldF9jbGF3YmFjazoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czoyNDctMjQ4CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gcHVibGljIHZlcmlmeV9hc3NldF9wYXJhbXNfZ2V0X2NsYXdiYWNrKGE6IEFzc2V0KTogQWRkcmVzcyB7CiAgICBwcm90byAxIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czoyNDkKICAgIC8vIGNvbnN0IFt2YWx1ZSwgZXhpc3RzXSA9IG9wLkFzc2V0UGFyYW1zLmFzc2V0Q2xhd2JhY2soYSkKICAgIGZyYW1lX2RpZyAtMQogICAgYXNzZXRfcGFyYW1zX2dldCBBc3NldENsYXdiYWNrCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MjUwCiAgICAvLyBjb25zdCBbdmFsdWVfaW5kZXgsIGV4aXN0c19pbmRleF0gPSBvcC5Bc3NldFBhcmFtcy5hc3NldENsYXdiYWNrKGdldF8xc3RfcmVmX2luZGV4KCkpCiAgICBjYWxsc3ViIGdldF8xc3RfcmVmX2luZGV4CiAgICBhc3NldF9wYXJhbXNfZ2V0IEFzc2V0Q2xhd2JhY2sKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czoyNTEKICAgIC8vIGFzc2VydCh2YWx1ZSA9PT0gdmFsdWVfaW5kZXgsICdleHBlY3RlZCB2YWx1ZSBieSBpbmRleCB0byBtYXRjaCcpCiAgICBkaWcgMwogICAgdW5jb3ZlciAyCiAgICA9PQogICAgYXNzZXJ0IC8vIGV4cGVjdGVkIHZhbHVlIGJ5IGluZGV4IHRvIG1hdGNoCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MjUyCiAgICAvLyBhc3NlcnQoZXhpc3RzID09PSBleGlzdHNfaW5kZXgsICdleHBlY3RlZCBleGlzdHMgYnkgaW5kZXggdG8gbWF0Y2gnKQogICAgPT0KICAgIGFzc2VydCAvLyBleHBlY3RlZCBleGlzdHMgYnkgaW5kZXggdG8gbWF0Y2gKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czoyNTMKICAgIC8vIHJldHVybiBuZXcgQWRkcmVzcyh2YWx1ZSkKICAgIHJldHN1YgoKCi8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo6U3RhdGVBc3NldFBhcmFtc0NvbnRyYWN0LnZlcmlmeV9hc3NldF9wYXJhbXNfZ2V0X2NyZWF0b3IoYTogdWludDY0KSAtPiBieXRlczoKdmVyaWZ5X2Fzc2V0X3BhcmFtc19nZXRfY3JlYXRvcjoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czoyNTYtMjU3CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gcHVibGljIHZlcmlmeV9hc3NldF9wYXJhbXNfZ2V0X2NyZWF0b3IoYTogQXNzZXQpOiBBZGRyZXNzIHsKICAgIHByb3RvIDEgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjI1OAogICAgLy8gY29uc3QgW3ZhbHVlLCBleGlzdHNdID0gb3AuQXNzZXRQYXJhbXMuYXNzZXRDcmVhdG9yKGEpCiAgICBmcmFtZV9kaWcgLTEKICAgIGFzc2V0X3BhcmFtc19nZXQgQXNzZXRDcmVhdG9yCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MjU5CiAgICAvLyBjb25zdCBbdmFsdWVfaW5kZXgsIGV4aXN0c19pbmRleF0gPSBvcC5Bc3NldFBhcmFtcy5hc3NldENyZWF0b3IoZ2V0XzFzdF9yZWZfaW5kZXgoKSkKICAgIGNhbGxzdWIgZ2V0XzFzdF9yZWZfaW5kZXgKICAgIGFzc2V0X3BhcmFtc19nZXQgQXNzZXRDcmVhdG9yCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MjYwCiAgICAvLyBhc3NlcnQodmFsdWUgPT09IHZhbHVlX2luZGV4LCAnZXhwZWN0ZWQgdmFsdWUgYnkgaW5kZXggdG8gbWF0Y2gnKQogICAgZGlnIDMKICAgIHVuY292ZXIgMgogICAgPT0KICAgIGFzc2VydCAvLyBleHBlY3RlZCB2YWx1ZSBieSBpbmRleCB0byBtYXRjaAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjI2MQogICAgLy8gYXNzZXJ0KGV4aXN0cyA9PT0gZXhpc3RzX2luZGV4LCAnZXhwZWN0ZWQgZXhpc3RzIGJ5IGluZGV4IHRvIG1hdGNoJykKICAgID09CiAgICBhc3NlcnQgLy8gZXhwZWN0ZWQgZXhpc3RzIGJ5IGluZGV4IHRvIG1hdGNoCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MjYyCiAgICAvLyByZXR1cm4gbmV3IEFkZHJlc3ModmFsdWUpCiAgICByZXRzdWIK", - "clear": "I3ByYWdtYSB2ZXJzaW9uIDEwCgp0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OlN0YXRlQXNzZXRQYXJhbXNDb250cmFjdC5jbGVhclN0YXRlUHJvZ3JhbToKICAgIHB1c2hpbnQgMSAvLyAxCiAgICByZXR1cm4K" - }, - "state": { - "global": { - "num_byte_slices": 0, - "num_uints": 0 - }, - "local": { - "num_byte_slices": 0, - "num_uints": 0 - } - }, - "schema": { - "global": { - "declared": {}, - "reserved": {} - }, - "local": { - "declared": {}, - "reserved": {} - } - }, - "contract": { - "name": "StateAssetParamsContract", - "methods": [ - { - "name": "verify_asset_params_get_total", - "args": [ - { - "type": "asset", - "name": "a" - } - ], - "readonly": false, - "returns": { - "type": "uint64" - } - }, - { - "name": "verify_asset_params_get_decimals", - "args": [ - { - "type": "asset", - "name": "a" - } - ], - "readonly": false, - "returns": { - "type": "uint64" - } - }, - { - "name": "verify_asset_params_get_default_frozen", - "args": [ - { - "type": "asset", - "name": "a" - } - ], - "readonly": false, - "returns": { - "type": "bool" - } - }, - { - "name": "verify_asset_params_get_unit_name", - "args": [ - { - "type": "asset", - "name": "a" - } - ], - "readonly": false, - "returns": { - "type": "byte[]" - } - }, - { - "name": "verify_asset_params_get_name", - "args": [ - { - "type": "asset", - "name": "a" - } - ], - "readonly": false, - "returns": { - "type": "byte[]" - } - }, - { - "name": "verify_asset_params_get_url", - "args": [ - { - "type": "asset", - "name": "a" - } - ], - "readonly": false, - "returns": { - "type": "byte[]" - } - }, - { - "name": "verify_asset_params_get_metadata_hash", - "args": [ - { - "type": "asset", - "name": "a" - } - ], - "readonly": false, - "returns": { - "type": "byte[]" - } - }, - { - "name": "verify_asset_params_get_manager", - "args": [ - { - "type": "asset", - "name": "a" - } - ], - "readonly": false, - "returns": { - "type": "address" - } - }, - { - "name": "verify_asset_params_get_reserve", - "args": [ - { - "type": "asset", - "name": "a" - } - ], - "readonly": false, - "returns": { - "type": "address" - } - }, - { - "name": "verify_asset_params_get_freeze", - "args": [ - { - "type": "asset", - "name": "a" - } - ], - "readonly": false, - "returns": { - "type": "address" - } - }, - { - "name": "verify_asset_params_get_clawback", - "args": [ - { - "type": "asset", - "name": "a" - } - ], - "readonly": false, - "returns": { - "type": "address" - } - }, - { - "name": "verify_asset_params_get_creator", - "args": [ - { - "type": "asset", - "name": "a" - } - ], - "readonly": false, - "returns": { - "type": "address" - } - } - ], - "networks": {} - }, - "bare_call_config": { - "no_op": "CREATE" - } -} \ No newline at end of file diff --git a/tests/artifacts/state-ops/data/StateAssetParamsContract.arc56.json b/tests/artifacts/state-ops/data/StateAssetParamsContract.arc56.json deleted file mode 100644 index af64086..0000000 --- a/tests/artifacts/state-ops/data/StateAssetParamsContract.arc56.json +++ /dev/null @@ -1,382 +0,0 @@ -{ - "name": "StateAssetParamsContract", - "structs": {}, - "methods": [ - { - "name": "verify_asset_params_get_total", - "args": [ - { - "type": "asset", - "name": "a" - } - ], - "returns": { - "type": "uint64" - }, - "actions": { - "create": [], - "call": [ - "NoOp" - ] - }, - "readonly": false, - "events": [], - "recommendations": {} - }, - { - "name": "verify_asset_params_get_decimals", - "args": [ - { - "type": "asset", - "name": "a" - } - ], - "returns": { - "type": "uint64" - }, - "actions": { - "create": [], - "call": [ - "NoOp" - ] - }, - "readonly": false, - "events": [], - "recommendations": {} - }, - { - "name": "verify_asset_params_get_default_frozen", - "args": [ - { - "type": "asset", - "name": "a" - } - ], - "returns": { - "type": "bool" - }, - "actions": { - "create": [], - "call": [ - "NoOp" - ] - }, - "readonly": false, - "events": [], - "recommendations": {} - }, - { - "name": "verify_asset_params_get_unit_name", - "args": [ - { - "type": "asset", - "name": "a" - } - ], - "returns": { - "type": "byte[]" - }, - "actions": { - "create": [], - "call": [ - "NoOp" - ] - }, - "readonly": false, - "events": [], - "recommendations": {} - }, - { - "name": "verify_asset_params_get_name", - "args": [ - { - "type": "asset", - "name": "a" - } - ], - "returns": { - "type": "byte[]" - }, - "actions": { - "create": [], - "call": [ - "NoOp" - ] - }, - "readonly": false, - "events": [], - "recommendations": {} - }, - { - "name": "verify_asset_params_get_url", - "args": [ - { - "type": "asset", - "name": "a" - } - ], - "returns": { - "type": "byte[]" - }, - "actions": { - "create": [], - "call": [ - "NoOp" - ] - }, - "readonly": false, - "events": [], - "recommendations": {} - }, - { - "name": "verify_asset_params_get_metadata_hash", - "args": [ - { - "type": "asset", - "name": "a" - } - ], - "returns": { - "type": "byte[]" - }, - "actions": { - "create": [], - "call": [ - "NoOp" - ] - }, - "readonly": false, - "events": [], - "recommendations": {} - }, - { - "name": "verify_asset_params_get_manager", - "args": [ - { - "type": "asset", - "name": "a" - } - ], - "returns": { - "type": "address" - }, - "actions": { - "create": [], - "call": [ - "NoOp" - ] - }, - "readonly": false, - "events": [], - "recommendations": {} - }, - { - "name": "verify_asset_params_get_reserve", - "args": [ - { - "type": "asset", - "name": "a" - } - ], - "returns": { - "type": "address" - }, - "actions": { - "create": [], - "call": [ - "NoOp" - ] - }, - "readonly": false, - "events": [], - "recommendations": {} - }, - { - "name": "verify_asset_params_get_freeze", - "args": [ - { - "type": "asset", - "name": "a" - } - ], - "returns": { - "type": "address" - }, - "actions": { - "create": [], - "call": [ - "NoOp" - ] - }, - "readonly": false, - "events": [], - "recommendations": {} - }, - { - "name": "verify_asset_params_get_clawback", - "args": [ - { - "type": "asset", - "name": "a" - } - ], - "returns": { - "type": "address" - }, - "actions": { - "create": [], - "call": [ - "NoOp" - ] - }, - "readonly": false, - "events": [], - "recommendations": {} - }, - { - "name": "verify_asset_params_get_creator", - "args": [ - { - "type": "asset", - "name": "a" - } - ], - "returns": { - "type": "address" - }, - "actions": { - "create": [], - "call": [ - "NoOp" - ] - }, - "readonly": false, - "events": [], - "recommendations": {} - } - ], - "arcs": [ - 22, - 28 - ], - "networks": {}, - "state": { - "schema": { - "global": { - "ints": 0, - "bytes": 0 - }, - "local": { - "ints": 0, - "bytes": 0 - } - }, - "keys": { - "global": {}, - "local": {}, - "box": {} - }, - "maps": { - "global": {}, - "local": {}, - "box": {} - } - }, - "bareActions": { - "create": [ - "NoOp" - ], - "call": [] - }, - "sourceInfo": { - "approval": { - "sourceInfo": [ - { - "pc": [ - 120, - 143, - 166, - 195, - 225, - 255, - 285, - 315, - 337, - 359, - 381, - 403 - ], - "errorMessage": "OnCompletion is not NoOp" - }, - { - "pc": [ - 430 - ], - "errorMessage": "can only call when creating" - }, - { - "pc": [ - 123, - 146, - 169, - 198, - 228, - 258, - 288, - 318, - 340, - 362, - 384, - 406 - ], - "errorMessage": "can only call when not creating" - }, - { - "pc": [ - 454, - 483, - 504, - 525, - 546, - 567, - 588, - 609, - 630, - 651, - 672, - 693 - ], - "errorMessage": "expected exists by index to match" - }, - { - "pc": [ - 452, - 481, - 502, - 523, - 544, - 565, - 586, - 607, - 628, - 649, - 670, - 691 - ], - "errorMessage": "expected value by index to match" - } - ], - "pcOffsetMethod": "none" - }, - "clear": { - "sourceInfo": [], - "pcOffsetMethod": "none" - } - }, - "source": { - "approval": "I3ByYWdtYSB2ZXJzaW9uIDEwCgp0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OlN0YXRlQXNzZXRQYXJhbXNDb250cmFjdC5hcHByb3ZhbFByb2dyYW06CiAgICBpbnRjYmxvY2sgMSAwCiAgICBieXRlY2Jsb2NrIDB4MTUxZjdjNzUKICAgIGNhbGxzdWIgX19wdXlhX2FyYzRfcm91dGVyX18KICAgIHJldHVybgoKCi8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo6U3RhdGVBc3NldFBhcmFtc0NvbnRyYWN0Ll9fcHV5YV9hcmM0X3JvdXRlcl9fKCkgLT4gdWludDY0OgpfX3B1eWFfYXJjNF9yb3V0ZXJfXzoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czoxNTYKICAgIC8vIGV4cG9ydCBjbGFzcyBTdGF0ZUFzc2V0UGFyYW1zQ29udHJhY3QgZXh0ZW5kcyBhcmM0LkNvbnRyYWN0IHsKICAgIHByb3RvIDAgMQogICAgdHhuIE51bUFwcEFyZ3MKICAgIGJ6IF9fcHV5YV9hcmM0X3JvdXRlcl9fX2JhcmVfcm91dGluZ0AxNgogICAgcHVzaGJ5dGVzcyAweGFkNzE5YTZmIDB4MWQ2MDMwMTMgMHg5ZmI3MzFjZCAweDBmNWE0OTExIDB4ZjViMzcwYzYgMHhjN2Q2YWY3NCAweDZiNzFhMjYzIDB4MzA0MGViYzggMHgxZDA3ZTg0NCAweDNlNDBjYjUwIDB4MzQwYzc4NmIgMHhlMzhhOTgxNSAvLyBtZXRob2QgInZlcmlmeV9hc3NldF9wYXJhbXNfZ2V0X3RvdGFsKGFzc2V0KXVpbnQ2NCIsIG1ldGhvZCAidmVyaWZ5X2Fzc2V0X3BhcmFtc19nZXRfZGVjaW1hbHMoYXNzZXQpdWludDY0IiwgbWV0aG9kICJ2ZXJpZnlfYXNzZXRfcGFyYW1zX2dldF9kZWZhdWx0X2Zyb3plbihhc3NldClib29sIiwgbWV0aG9kICJ2ZXJpZnlfYXNzZXRfcGFyYW1zX2dldF91bml0X25hbWUoYXNzZXQpYnl0ZVtdIiwgbWV0aG9kICJ2ZXJpZnlfYXNzZXRfcGFyYW1zX2dldF9uYW1lKGFzc2V0KWJ5dGVbXSIsIG1ldGhvZCAidmVyaWZ5X2Fzc2V0X3BhcmFtc19nZXRfdXJsKGFzc2V0KWJ5dGVbXSIsIG1ldGhvZCAidmVyaWZ5X2Fzc2V0X3BhcmFtc19nZXRfbWV0YWRhdGFfaGFzaChhc3NldClieXRlW10iLCBtZXRob2QgInZlcmlmeV9hc3NldF9wYXJhbXNfZ2V0X21hbmFnZXIoYXNzZXQpYWRkcmVzcyIsIG1ldGhvZCAidmVyaWZ5X2Fzc2V0X3BhcmFtc19nZXRfcmVzZXJ2ZShhc3NldClhZGRyZXNzIiwgbWV0aG9kICJ2ZXJpZnlfYXNzZXRfcGFyYW1zX2dldF9mcmVlemUoYXNzZXQpYWRkcmVzcyIsIG1ldGhvZCAidmVyaWZ5X2Fzc2V0X3BhcmFtc19nZXRfY2xhd2JhY2soYXNzZXQpYWRkcmVzcyIsIG1ldGhvZCAidmVyaWZ5X2Fzc2V0X3BhcmFtc19nZXRfY3JlYXRvcihhc3NldClhZGRyZXNzIgogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMAogICAgbWF0Y2ggX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2Fzc2V0X3BhcmFtc19nZXRfdG90YWxfcm91dGVAMiBfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfYXNzZXRfcGFyYW1zX2dldF9kZWNpbWFsc19yb3V0ZUAzIF9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9hc3NldF9wYXJhbXNfZ2V0X2RlZmF1bHRfZnJvemVuX3JvdXRlQDQgX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2Fzc2V0X3BhcmFtc19nZXRfdW5pdF9uYW1lX3JvdXRlQDUgX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2Fzc2V0X3BhcmFtc19nZXRfbmFtZV9yb3V0ZUA2IF9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9hc3NldF9wYXJhbXNfZ2V0X3VybF9yb3V0ZUA3IF9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9hc3NldF9wYXJhbXNfZ2V0X21ldGFkYXRhX2hhc2hfcm91dGVAOCBfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfYXNzZXRfcGFyYW1zX2dldF9tYW5hZ2VyX3JvdXRlQDkgX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2Fzc2V0X3BhcmFtc19nZXRfcmVzZXJ2ZV9yb3V0ZUAxMCBfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfYXNzZXRfcGFyYW1zX2dldF9mcmVlemVfcm91dGVAMTEgX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2Fzc2V0X3BhcmFtc19nZXRfY2xhd2JhY2tfcm91dGVAMTIgX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2Fzc2V0X3BhcmFtc19nZXRfY3JlYXRvcl9yb3V0ZUAxMwogICAgaW50Y18xIC8vIDAKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2Fzc2V0X3BhcmFtc19nZXRfdG90YWxfcm91dGVAMjoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czoxNTcKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIG5vdCBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGNhbiBvbmx5IGNhbGwgd2hlbiBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czoxNTYKICAgIC8vIGV4cG9ydCBjbGFzcyBTdGF0ZUFzc2V0UGFyYW1zQ29udHJhY3QgZXh0ZW5kcyBhcmM0LkNvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGJ0b2kKICAgIHR4bmFzIEFzc2V0cwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjE1NwogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X2Fzc2V0X3BhcmFtc19nZXRfdG90YWwKICAgIGl0b2IKICAgIGJ5dGVjXzAgLy8gMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludGNfMCAvLyAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9hc3NldF9wYXJhbXNfZ2V0X2RlY2ltYWxzX3JvdXRlQDM6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTY2CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBub3QgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBjYW4gb25seSBjYWxsIHdoZW4gbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTU2CiAgICAvLyBleHBvcnQgY2xhc3MgU3RhdGVBc3NldFBhcmFtc0NvbnRyYWN0IGV4dGVuZHMgYXJjNC5Db250cmFjdCB7CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBidG9pCiAgICB0eG5hcyBBc3NldHMKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czoxNjYKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV9hc3NldF9wYXJhbXNfZ2V0X2RlY2ltYWxzCiAgICBpdG9iCiAgICBieXRlY18wIC8vIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnRjXzAgLy8gMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfYXNzZXRfcGFyYW1zX2dldF9kZWZhdWx0X2Zyb3plbl9yb3V0ZUA0OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjE3NQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgbm90IE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gY2FuIG9ubHkgY2FsbCB3aGVuIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjE1NgogICAgLy8gZXhwb3J0IGNsYXNzIFN0YXRlQXNzZXRQYXJhbXNDb250cmFjdCBleHRlbmRzIGFyYzQuQ29udHJhY3QgewogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgYnRvaQogICAgdHhuYXMgQXNzZXRzCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTc1CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfYXNzZXRfcGFyYW1zX2dldF9kZWZhdWx0X2Zyb3plbgogICAgcHVzaGJ5dGVzIDB4MDAKICAgIGludGNfMSAvLyAwCiAgICB1bmNvdmVyIDIKICAgIHNldGJpdAogICAgYnl0ZWNfMCAvLyAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50Y18wIC8vIDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2Fzc2V0X3BhcmFtc19nZXRfdW5pdF9uYW1lX3JvdXRlQDU6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTg0CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBub3QgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBjYW4gb25seSBjYWxsIHdoZW4gbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTU2CiAgICAvLyBleHBvcnQgY2xhc3MgU3RhdGVBc3NldFBhcmFtc0NvbnRyYWN0IGV4dGVuZHMgYXJjNC5Db250cmFjdCB7CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBidG9pCiAgICB0eG5hcyBBc3NldHMKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czoxODQKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV9hc3NldF9wYXJhbXNfZ2V0X3VuaXRfbmFtZQogICAgZHVwCiAgICBsZW4KICAgIGl0b2IKICAgIGV4dHJhY3QgNiAyCiAgICBzd2FwCiAgICBjb25jYXQKICAgIGJ5dGVjXzAgLy8gMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludGNfMCAvLyAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9hc3NldF9wYXJhbXNfZ2V0X25hbWVfcm91dGVANjoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czoxOTMKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIG5vdCBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGNhbiBvbmx5IGNhbGwgd2hlbiBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czoxNTYKICAgIC8vIGV4cG9ydCBjbGFzcyBTdGF0ZUFzc2V0UGFyYW1zQ29udHJhY3QgZXh0ZW5kcyBhcmM0LkNvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGJ0b2kKICAgIHR4bmFzIEFzc2V0cwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjE5MwogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X2Fzc2V0X3BhcmFtc19nZXRfbmFtZQogICAgZHVwCiAgICBsZW4KICAgIGl0b2IKICAgIGV4dHJhY3QgNiAyCiAgICBzd2FwCiAgICBjb25jYXQKICAgIGJ5dGVjXzAgLy8gMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludGNfMCAvLyAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9hc3NldF9wYXJhbXNfZ2V0X3VybF9yb3V0ZUA3OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjIwMgogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgbm90IE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gY2FuIG9ubHkgY2FsbCB3aGVuIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjE1NgogICAgLy8gZXhwb3J0IGNsYXNzIFN0YXRlQXNzZXRQYXJhbXNDb250cmFjdCBleHRlbmRzIGFyYzQuQ29udHJhY3QgewogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgYnRvaQogICAgdHhuYXMgQXNzZXRzCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MjAyCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfYXNzZXRfcGFyYW1zX2dldF91cmwKICAgIGR1cAogICAgbGVuCiAgICBpdG9iCiAgICBleHRyYWN0IDYgMgogICAgc3dhcAogICAgY29uY2F0CiAgICBieXRlY18wIC8vIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnRjXzAgLy8gMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfYXNzZXRfcGFyYW1zX2dldF9tZXRhZGF0YV9oYXNoX3JvdXRlQDg6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MjExCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBub3QgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBjYW4gb25seSBjYWxsIHdoZW4gbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTU2CiAgICAvLyBleHBvcnQgY2xhc3MgU3RhdGVBc3NldFBhcmFtc0NvbnRyYWN0IGV4dGVuZHMgYXJjNC5Db250cmFjdCB7CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBidG9pCiAgICB0eG5hcyBBc3NldHMKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czoyMTEKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV9hc3NldF9wYXJhbXNfZ2V0X21ldGFkYXRhX2hhc2gKICAgIGR1cAogICAgbGVuCiAgICBpdG9iCiAgICBleHRyYWN0IDYgMgogICAgc3dhcAogICAgY29uY2F0CiAgICBieXRlY18wIC8vIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnRjXzAgLy8gMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfYXNzZXRfcGFyYW1zX2dldF9tYW5hZ2VyX3JvdXRlQDk6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MjIwCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBub3QgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBjYW4gb25seSBjYWxsIHdoZW4gbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTU2CiAgICAvLyBleHBvcnQgY2xhc3MgU3RhdGVBc3NldFBhcmFtc0NvbnRyYWN0IGV4dGVuZHMgYXJjNC5Db250cmFjdCB7CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBidG9pCiAgICB0eG5hcyBBc3NldHMKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czoyMjAKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV9hc3NldF9wYXJhbXNfZ2V0X21hbmFnZXIKICAgIGJ5dGVjXzAgLy8gMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludGNfMCAvLyAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9hc3NldF9wYXJhbXNfZ2V0X3Jlc2VydmVfcm91dGVAMTA6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MjI5CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBub3QgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBjYW4gb25seSBjYWxsIHdoZW4gbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTU2CiAgICAvLyBleHBvcnQgY2xhc3MgU3RhdGVBc3NldFBhcmFtc0NvbnRyYWN0IGV4dGVuZHMgYXJjNC5Db250cmFjdCB7CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBidG9pCiAgICB0eG5hcyBBc3NldHMKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czoyMjkKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV9hc3NldF9wYXJhbXNfZ2V0X3Jlc2VydmUKICAgIGJ5dGVjXzAgLy8gMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludGNfMCAvLyAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9hc3NldF9wYXJhbXNfZ2V0X2ZyZWV6ZV9yb3V0ZUAxMToKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czoyMzgKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIG5vdCBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGNhbiBvbmx5IGNhbGwgd2hlbiBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czoxNTYKICAgIC8vIGV4cG9ydCBjbGFzcyBTdGF0ZUFzc2V0UGFyYW1zQ29udHJhY3QgZXh0ZW5kcyBhcmM0LkNvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGJ0b2kKICAgIHR4bmFzIEFzc2V0cwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjIzOAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X2Fzc2V0X3BhcmFtc19nZXRfZnJlZXplCiAgICBieXRlY18wIC8vIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnRjXzAgLy8gMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfYXNzZXRfcGFyYW1zX2dldF9jbGF3YmFja19yb3V0ZUAxMjoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czoyNDcKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIG5vdCBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGNhbiBvbmx5IGNhbGwgd2hlbiBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czoxNTYKICAgIC8vIGV4cG9ydCBjbGFzcyBTdGF0ZUFzc2V0UGFyYW1zQ29udHJhY3QgZXh0ZW5kcyBhcmM0LkNvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGJ0b2kKICAgIHR4bmFzIEFzc2V0cwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjI0NwogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X2Fzc2V0X3BhcmFtc19nZXRfY2xhd2JhY2sKICAgIGJ5dGVjXzAgLy8gMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludGNfMCAvLyAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9hc3NldF9wYXJhbXNfZ2V0X2NyZWF0b3Jfcm91dGVAMTM6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MjU2CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBub3QgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBjYW4gb25seSBjYWxsIHdoZW4gbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTU2CiAgICAvLyBleHBvcnQgY2xhc3MgU3RhdGVBc3NldFBhcmFtc0NvbnRyYWN0IGV4dGVuZHMgYXJjNC5Db250cmFjdCB7CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBidG9pCiAgICB0eG5hcyBBc3NldHMKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czoyNTYKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV9hc3NldF9wYXJhbXNfZ2V0X2NyZWF0b3IKICAgIGJ5dGVjXzAgLy8gMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludGNfMCAvLyAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX2JhcmVfcm91dGluZ0AxNjoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czoxNTYKICAgIC8vIGV4cG9ydCBjbGFzcyBTdGF0ZUFzc2V0UGFyYW1zQ29udHJhY3QgZXh0ZW5kcyBhcmM0LkNvbnRyYWN0IHsKICAgIHR4biBPbkNvbXBsZXRpb24KICAgIGJueiBfX3B1eWFfYXJjNF9yb3V0ZXJfX19hZnRlcl9pZl9lbHNlQDIwCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgIQogICAgYXNzZXJ0IC8vIGNhbiBvbmx5IGNhbGwgd2hlbiBjcmVhdGluZwogICAgaW50Y18wIC8vIDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fYWZ0ZXJfaWZfZWxzZUAyMDoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czoxNTYKICAgIC8vIGV4cG9ydCBjbGFzcyBTdGF0ZUFzc2V0UGFyYW1zQ29udHJhY3QgZXh0ZW5kcyBhcmM0LkNvbnRyYWN0IHsKICAgIGludGNfMSAvLyAwCiAgICByZXRzdWIKCgovLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OlN0YXRlQXNzZXRQYXJhbXNDb250cmFjdC52ZXJpZnlfYXNzZXRfcGFyYW1zX2dldF90b3RhbChhOiB1aW50NjQpIC0+IHVpbnQ2NDoKdmVyaWZ5X2Fzc2V0X3BhcmFtc19nZXRfdG90YWw6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTU3LTE1OAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIHB1YmxpYyB2ZXJpZnlfYXNzZXRfcGFyYW1zX2dldF90b3RhbChhOiBBc3NldCk6IHVpbnQ2NCB7CiAgICBwcm90byAxIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czoxNTkKICAgIC8vIGNvbnN0IFt2YWx1ZSwgZXhpc3RzXSA9IG9wLkFzc2V0UGFyYW1zLmFzc2V0VG90YWwoYSkKICAgIGZyYW1lX2RpZyAtMQogICAgYXNzZXRfcGFyYW1zX2dldCBBc3NldFRvdGFsCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTYwCiAgICAvLyBjb25zdCBbdmFsdWVfaW5kZXgsIGV4aXN0c19pbmRleF0gPSBvcC5Bc3NldFBhcmFtcy5hc3NldFRvdGFsKGdldF8xc3RfcmVmX2luZGV4KCkpCiAgICBjYWxsc3ViIGdldF8xc3RfcmVmX2luZGV4CiAgICBhc3NldF9wYXJhbXNfZ2V0IEFzc2V0VG90YWwKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czoxNjEKICAgIC8vIGFzc2VydCh2YWx1ZSA9PT0gdmFsdWVfaW5kZXgsICdleHBlY3RlZCB2YWx1ZSBieSBpbmRleCB0byBtYXRjaCcpCiAgICBkaWcgMwogICAgdW5jb3ZlciAyCiAgICA9PQogICAgYXNzZXJ0IC8vIGV4cGVjdGVkIHZhbHVlIGJ5IGluZGV4IHRvIG1hdGNoCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTYyCiAgICAvLyBhc3NlcnQoZXhpc3RzID09PSBleGlzdHNfaW5kZXgsICdleHBlY3RlZCBleGlzdHMgYnkgaW5kZXggdG8gbWF0Y2gnKQogICAgPT0KICAgIGFzc2VydCAvLyBleHBlY3RlZCBleGlzdHMgYnkgaW5kZXggdG8gbWF0Y2gKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czoxNjMKICAgIC8vIHJldHVybiB2YWx1ZQogICAgcmV0c3ViCgoKLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjpnZXRfMXN0X3JlZl9pbmRleCgpIC0+IHVpbnQ2NDoKZ2V0XzFzdF9yZWZfaW5kZXg6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MjIKICAgIC8vIGZ1bmN0aW9uIGdldF8xc3RfcmVmX2luZGV4KCk6IHVpbnQ2NCB7CiAgICBwcm90byAwIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czoyMwogICAgLy8gcmV0dXJuIG9wLmJ0b2koVHhuLmFwcGxpY2F0aW9uQXJncygxKSkKICAgIGludGNfMCAvLyAxCiAgICB0eG5hcyBBcHBsaWNhdGlvbkFyZ3MKICAgIGJ0b2kKICAgIHJldHN1YgoKCi8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo6U3RhdGVBc3NldFBhcmFtc0NvbnRyYWN0LnZlcmlmeV9hc3NldF9wYXJhbXNfZ2V0X2RlY2ltYWxzKGE6IHVpbnQ2NCkgLT4gdWludDY0Ogp2ZXJpZnlfYXNzZXRfcGFyYW1zX2dldF9kZWNpbWFsczoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czoxNjYtMTY3CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gcHVibGljIHZlcmlmeV9hc3NldF9wYXJhbXNfZ2V0X2RlY2ltYWxzKGE6IEFzc2V0KTogdWludDY0IHsKICAgIHByb3RvIDEgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjE2OAogICAgLy8gY29uc3QgW3ZhbHVlLCBleGlzdHNdID0gb3AuQXNzZXRQYXJhbXMuYXNzZXREZWNpbWFscyhhKQogICAgZnJhbWVfZGlnIC0xCiAgICBhc3NldF9wYXJhbXNfZ2V0IEFzc2V0RGVjaW1hbHMKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czoxNjkKICAgIC8vIGNvbnN0IFt2YWx1ZV9pbmRleCwgZXhpc3RzX2luZGV4XSA9IG9wLkFzc2V0UGFyYW1zLmFzc2V0RGVjaW1hbHMoZ2V0XzFzdF9yZWZfaW5kZXgoKSkKICAgIGNhbGxzdWIgZ2V0XzFzdF9yZWZfaW5kZXgKICAgIGFzc2V0X3BhcmFtc19nZXQgQXNzZXREZWNpbWFscwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjE3MAogICAgLy8gYXNzZXJ0KHZhbHVlID09PSB2YWx1ZV9pbmRleCwgJ2V4cGVjdGVkIHZhbHVlIGJ5IGluZGV4IHRvIG1hdGNoJykKICAgIGRpZyAzCiAgICB1bmNvdmVyIDIKICAgID09CiAgICBhc3NlcnQgLy8gZXhwZWN0ZWQgdmFsdWUgYnkgaW5kZXggdG8gbWF0Y2gKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czoxNzEKICAgIC8vIGFzc2VydChleGlzdHMgPT09IGV4aXN0c19pbmRleCwgJ2V4cGVjdGVkIGV4aXN0cyBieSBpbmRleCB0byBtYXRjaCcpCiAgICA9PQogICAgYXNzZXJ0IC8vIGV4cGVjdGVkIGV4aXN0cyBieSBpbmRleCB0byBtYXRjaAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjE3MgogICAgLy8gcmV0dXJuIHZhbHVlCiAgICByZXRzdWIKCgovLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OlN0YXRlQXNzZXRQYXJhbXNDb250cmFjdC52ZXJpZnlfYXNzZXRfcGFyYW1zX2dldF9kZWZhdWx0X2Zyb3plbihhOiB1aW50NjQpIC0+IHVpbnQ2NDoKdmVyaWZ5X2Fzc2V0X3BhcmFtc19nZXRfZGVmYXVsdF9mcm96ZW46CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTc1LTE3NgogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIHB1YmxpYyB2ZXJpZnlfYXNzZXRfcGFyYW1zX2dldF9kZWZhdWx0X2Zyb3plbihhOiBBc3NldCk6IGJvb2xlYW4gewogICAgcHJvdG8gMSAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTc3CiAgICAvLyBjb25zdCBbdmFsdWUsIGV4aXN0c10gPSBvcC5Bc3NldFBhcmFtcy5hc3NldERlZmF1bHRGcm96ZW4oYSkKICAgIGZyYW1lX2RpZyAtMQogICAgYXNzZXRfcGFyYW1zX2dldCBBc3NldERlZmF1bHRGcm96ZW4KICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czoxNzgKICAgIC8vIGNvbnN0IFt2YWx1ZV9pbmRleCwgZXhpc3RzX2luZGV4XSA9IG9wLkFzc2V0UGFyYW1zLmFzc2V0RGVmYXVsdEZyb3plbihnZXRfMXN0X3JlZl9pbmRleCgpKQogICAgY2FsbHN1YiBnZXRfMXN0X3JlZl9pbmRleAogICAgYXNzZXRfcGFyYW1zX2dldCBBc3NldERlZmF1bHRGcm96ZW4KICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czoxNzkKICAgIC8vIGFzc2VydCh2YWx1ZSA9PT0gdmFsdWVfaW5kZXgsICdleHBlY3RlZCB2YWx1ZSBieSBpbmRleCB0byBtYXRjaCcpCiAgICBkaWcgMwogICAgdW5jb3ZlciAyCiAgICA9PQogICAgYXNzZXJ0IC8vIGV4cGVjdGVkIHZhbHVlIGJ5IGluZGV4IHRvIG1hdGNoCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTgwCiAgICAvLyBhc3NlcnQoZXhpc3RzID09PSBleGlzdHNfaW5kZXgsICdleHBlY3RlZCBleGlzdHMgYnkgaW5kZXggdG8gbWF0Y2gnKQogICAgPT0KICAgIGFzc2VydCAvLyBleHBlY3RlZCBleGlzdHMgYnkgaW5kZXggdG8gbWF0Y2gKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czoxODEKICAgIC8vIHJldHVybiB2YWx1ZQogICAgcmV0c3ViCgoKLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjpTdGF0ZUFzc2V0UGFyYW1zQ29udHJhY3QudmVyaWZ5X2Fzc2V0X3BhcmFtc19nZXRfdW5pdF9uYW1lKGE6IHVpbnQ2NCkgLT4gYnl0ZXM6CnZlcmlmeV9hc3NldF9wYXJhbXNfZ2V0X3VuaXRfbmFtZToKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czoxODQtMTg1CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gcHVibGljIHZlcmlmeV9hc3NldF9wYXJhbXNfZ2V0X3VuaXRfbmFtZShhOiBBc3NldCk6IGJ5dGVzIHsKICAgIHByb3RvIDEgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjE4NgogICAgLy8gY29uc3QgW3ZhbHVlLCBleGlzdHNdID0gb3AuQXNzZXRQYXJhbXMuYXNzZXRVbml0TmFtZShhKQogICAgZnJhbWVfZGlnIC0xCiAgICBhc3NldF9wYXJhbXNfZ2V0IEFzc2V0VW5pdE5hbWUKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czoxODcKICAgIC8vIGNvbnN0IFt2YWx1ZV9pbmRleCwgZXhpc3RzX2luZGV4XSA9IG9wLkFzc2V0UGFyYW1zLmFzc2V0VW5pdE5hbWUoZ2V0XzFzdF9yZWZfaW5kZXgoKSkKICAgIGNhbGxzdWIgZ2V0XzFzdF9yZWZfaW5kZXgKICAgIGFzc2V0X3BhcmFtc19nZXQgQXNzZXRVbml0TmFtZQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjE4OAogICAgLy8gYXNzZXJ0KHZhbHVlID09PSB2YWx1ZV9pbmRleCwgJ2V4cGVjdGVkIHZhbHVlIGJ5IGluZGV4IHRvIG1hdGNoJykKICAgIGRpZyAzCiAgICB1bmNvdmVyIDIKICAgID09CiAgICBhc3NlcnQgLy8gZXhwZWN0ZWQgdmFsdWUgYnkgaW5kZXggdG8gbWF0Y2gKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czoxODkKICAgIC8vIGFzc2VydChleGlzdHMgPT09IGV4aXN0c19pbmRleCwgJ2V4cGVjdGVkIGV4aXN0cyBieSBpbmRleCB0byBtYXRjaCcpCiAgICA9PQogICAgYXNzZXJ0IC8vIGV4cGVjdGVkIGV4aXN0cyBieSBpbmRleCB0byBtYXRjaAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjE5MAogICAgLy8gcmV0dXJuIHZhbHVlCiAgICByZXRzdWIKCgovLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OlN0YXRlQXNzZXRQYXJhbXNDb250cmFjdC52ZXJpZnlfYXNzZXRfcGFyYW1zX2dldF9uYW1lKGE6IHVpbnQ2NCkgLT4gYnl0ZXM6CnZlcmlmeV9hc3NldF9wYXJhbXNfZ2V0X25hbWU6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTkzLTE5NAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIHB1YmxpYyB2ZXJpZnlfYXNzZXRfcGFyYW1zX2dldF9uYW1lKGE6IEFzc2V0KTogYnl0ZXMgewogICAgcHJvdG8gMSAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTk1CiAgICAvLyBjb25zdCBbdmFsdWUsIGV4aXN0c10gPSBvcC5Bc3NldFBhcmFtcy5hc3NldE5hbWUoYSkKICAgIGZyYW1lX2RpZyAtMQogICAgYXNzZXRfcGFyYW1zX2dldCBBc3NldE5hbWUKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czoxOTYKICAgIC8vIGNvbnN0IFt2YWx1ZV9pbmRleCwgZXhpc3RzX2luZGV4XSA9IG9wLkFzc2V0UGFyYW1zLmFzc2V0TmFtZShnZXRfMXN0X3JlZl9pbmRleCgpKQogICAgY2FsbHN1YiBnZXRfMXN0X3JlZl9pbmRleAogICAgYXNzZXRfcGFyYW1zX2dldCBBc3NldE5hbWUKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czoxOTcKICAgIC8vIGFzc2VydCh2YWx1ZSA9PT0gdmFsdWVfaW5kZXgsICdleHBlY3RlZCB2YWx1ZSBieSBpbmRleCB0byBtYXRjaCcpCiAgICBkaWcgMwogICAgdW5jb3ZlciAyCiAgICA9PQogICAgYXNzZXJ0IC8vIGV4cGVjdGVkIHZhbHVlIGJ5IGluZGV4IHRvIG1hdGNoCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTk4CiAgICAvLyBhc3NlcnQoZXhpc3RzID09PSBleGlzdHNfaW5kZXgsICdleHBlY3RlZCBleGlzdHMgYnkgaW5kZXggdG8gbWF0Y2gnKQogICAgPT0KICAgIGFzc2VydCAvLyBleHBlY3RlZCBleGlzdHMgYnkgaW5kZXggdG8gbWF0Y2gKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czoxOTkKICAgIC8vIHJldHVybiB2YWx1ZQogICAgcmV0c3ViCgoKLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjpTdGF0ZUFzc2V0UGFyYW1zQ29udHJhY3QudmVyaWZ5X2Fzc2V0X3BhcmFtc19nZXRfdXJsKGE6IHVpbnQ2NCkgLT4gYnl0ZXM6CnZlcmlmeV9hc3NldF9wYXJhbXNfZ2V0X3VybDoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czoyMDItMjAzCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gcHVibGljIHZlcmlmeV9hc3NldF9wYXJhbXNfZ2V0X3VybChhOiBBc3NldCk6IGJ5dGVzIHsKICAgIHByb3RvIDEgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjIwNAogICAgLy8gY29uc3QgW3ZhbHVlLCBleGlzdHNdID0gb3AuQXNzZXRQYXJhbXMuYXNzZXRVcmwoYSkKICAgIGZyYW1lX2RpZyAtMQogICAgYXNzZXRfcGFyYW1zX2dldCBBc3NldFVSTAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjIwNQogICAgLy8gY29uc3QgW3ZhbHVlX2luZGV4LCBleGlzdHNfaW5kZXhdID0gb3AuQXNzZXRQYXJhbXMuYXNzZXRVcmwoZ2V0XzFzdF9yZWZfaW5kZXgoKSkKICAgIGNhbGxzdWIgZ2V0XzFzdF9yZWZfaW5kZXgKICAgIGFzc2V0X3BhcmFtc19nZXQgQXNzZXRVUkwKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czoyMDYKICAgIC8vIGFzc2VydCh2YWx1ZSA9PT0gdmFsdWVfaW5kZXgsICdleHBlY3RlZCB2YWx1ZSBieSBpbmRleCB0byBtYXRjaCcpCiAgICBkaWcgMwogICAgdW5jb3ZlciAyCiAgICA9PQogICAgYXNzZXJ0IC8vIGV4cGVjdGVkIHZhbHVlIGJ5IGluZGV4IHRvIG1hdGNoCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MjA3CiAgICAvLyBhc3NlcnQoZXhpc3RzID09PSBleGlzdHNfaW5kZXgsICdleHBlY3RlZCBleGlzdHMgYnkgaW5kZXggdG8gbWF0Y2gnKQogICAgPT0KICAgIGFzc2VydCAvLyBleHBlY3RlZCBleGlzdHMgYnkgaW5kZXggdG8gbWF0Y2gKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czoyMDgKICAgIC8vIHJldHVybiB2YWx1ZQogICAgcmV0c3ViCgoKLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjpTdGF0ZUFzc2V0UGFyYW1zQ29udHJhY3QudmVyaWZ5X2Fzc2V0X3BhcmFtc19nZXRfbWV0YWRhdGFfaGFzaChhOiB1aW50NjQpIC0+IGJ5dGVzOgp2ZXJpZnlfYXNzZXRfcGFyYW1zX2dldF9tZXRhZGF0YV9oYXNoOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjIxMS0yMTIKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBwdWJsaWMgdmVyaWZ5X2Fzc2V0X3BhcmFtc19nZXRfbWV0YWRhdGFfaGFzaChhOiBBc3NldCk6IGJ5dGVzIHsKICAgIHByb3RvIDEgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjIxMwogICAgLy8gY29uc3QgW3ZhbHVlLCBleGlzdHNdID0gb3AuQXNzZXRQYXJhbXMuYXNzZXRNZXRhZGF0YUhhc2goYSkKICAgIGZyYW1lX2RpZyAtMQogICAgYXNzZXRfcGFyYW1zX2dldCBBc3NldE1ldGFkYXRhSGFzaAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjIxNAogICAgLy8gY29uc3QgW3ZhbHVlX2luZGV4LCBleGlzdHNfaW5kZXhdID0gb3AuQXNzZXRQYXJhbXMuYXNzZXRNZXRhZGF0YUhhc2goZ2V0XzFzdF9yZWZfaW5kZXgoKSkKICAgIGNhbGxzdWIgZ2V0XzFzdF9yZWZfaW5kZXgKICAgIGFzc2V0X3BhcmFtc19nZXQgQXNzZXRNZXRhZGF0YUhhc2gKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czoyMTUKICAgIC8vIGFzc2VydCh2YWx1ZSA9PT0gdmFsdWVfaW5kZXgsICdleHBlY3RlZCB2YWx1ZSBieSBpbmRleCB0byBtYXRjaCcpCiAgICBkaWcgMwogICAgdW5jb3ZlciAyCiAgICA9PQogICAgYXNzZXJ0IC8vIGV4cGVjdGVkIHZhbHVlIGJ5IGluZGV4IHRvIG1hdGNoCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MjE2CiAgICAvLyBhc3NlcnQoZXhpc3RzID09PSBleGlzdHNfaW5kZXgsICdleHBlY3RlZCBleGlzdHMgYnkgaW5kZXggdG8gbWF0Y2gnKQogICAgPT0KICAgIGFzc2VydCAvLyBleHBlY3RlZCBleGlzdHMgYnkgaW5kZXggdG8gbWF0Y2gKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czoyMTcKICAgIC8vIHJldHVybiB2YWx1ZQogICAgcmV0c3ViCgoKLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjpTdGF0ZUFzc2V0UGFyYW1zQ29udHJhY3QudmVyaWZ5X2Fzc2V0X3BhcmFtc19nZXRfbWFuYWdlcihhOiB1aW50NjQpIC0+IGJ5dGVzOgp2ZXJpZnlfYXNzZXRfcGFyYW1zX2dldF9tYW5hZ2VyOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjIyMC0yMjEKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBwdWJsaWMgdmVyaWZ5X2Fzc2V0X3BhcmFtc19nZXRfbWFuYWdlcihhOiBBc3NldCk6IEFkZHJlc3MgewogICAgcHJvdG8gMSAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MjIyCiAgICAvLyBjb25zdCBbdmFsdWUsIGV4aXN0c10gPSBvcC5Bc3NldFBhcmFtcy5hc3NldE1hbmFnZXIoYSkKICAgIGZyYW1lX2RpZyAtMQogICAgYXNzZXRfcGFyYW1zX2dldCBBc3NldE1hbmFnZXIKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czoyMjMKICAgIC8vIGNvbnN0IFt2YWx1ZV9pbmRleCwgZXhpc3RzX2luZGV4XSA9IG9wLkFzc2V0UGFyYW1zLmFzc2V0TWFuYWdlcihnZXRfMXN0X3JlZl9pbmRleCgpKQogICAgY2FsbHN1YiBnZXRfMXN0X3JlZl9pbmRleAogICAgYXNzZXRfcGFyYW1zX2dldCBBc3NldE1hbmFnZXIKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czoyMjQKICAgIC8vIGFzc2VydCh2YWx1ZSA9PT0gdmFsdWVfaW5kZXgsICdleHBlY3RlZCB2YWx1ZSBieSBpbmRleCB0byBtYXRjaCcpCiAgICBkaWcgMwogICAgdW5jb3ZlciAyCiAgICA9PQogICAgYXNzZXJ0IC8vIGV4cGVjdGVkIHZhbHVlIGJ5IGluZGV4IHRvIG1hdGNoCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MjI1CiAgICAvLyBhc3NlcnQoZXhpc3RzID09PSBleGlzdHNfaW5kZXgsICdleHBlY3RlZCBleGlzdHMgYnkgaW5kZXggdG8gbWF0Y2gnKQogICAgPT0KICAgIGFzc2VydCAvLyBleHBlY3RlZCBleGlzdHMgYnkgaW5kZXggdG8gbWF0Y2gKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czoyMjYKICAgIC8vIHJldHVybiBuZXcgQWRkcmVzcyh2YWx1ZSkKICAgIHJldHN1YgoKCi8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo6U3RhdGVBc3NldFBhcmFtc0NvbnRyYWN0LnZlcmlmeV9hc3NldF9wYXJhbXNfZ2V0X3Jlc2VydmUoYTogdWludDY0KSAtPiBieXRlczoKdmVyaWZ5X2Fzc2V0X3BhcmFtc19nZXRfcmVzZXJ2ZToKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czoyMjktMjMwCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gcHVibGljIHZlcmlmeV9hc3NldF9wYXJhbXNfZ2V0X3Jlc2VydmUoYTogQXNzZXQpOiBBZGRyZXNzIHsKICAgIHByb3RvIDEgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjIzMQogICAgLy8gY29uc3QgW3ZhbHVlLCBleGlzdHNdID0gb3AuQXNzZXRQYXJhbXMuYXNzZXRSZXNlcnZlKGEpCiAgICBmcmFtZV9kaWcgLTEKICAgIGFzc2V0X3BhcmFtc19nZXQgQXNzZXRSZXNlcnZlCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MjMyCiAgICAvLyBjb25zdCBbdmFsdWVfaW5kZXgsIGV4aXN0c19pbmRleF0gPSBvcC5Bc3NldFBhcmFtcy5hc3NldFJlc2VydmUoZ2V0XzFzdF9yZWZfaW5kZXgoKSkKICAgIGNhbGxzdWIgZ2V0XzFzdF9yZWZfaW5kZXgKICAgIGFzc2V0X3BhcmFtc19nZXQgQXNzZXRSZXNlcnZlCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MjMzCiAgICAvLyBhc3NlcnQodmFsdWUgPT09IHZhbHVlX2luZGV4LCAnZXhwZWN0ZWQgdmFsdWUgYnkgaW5kZXggdG8gbWF0Y2gnKQogICAgZGlnIDMKICAgIHVuY292ZXIgMgogICAgPT0KICAgIGFzc2VydCAvLyBleHBlY3RlZCB2YWx1ZSBieSBpbmRleCB0byBtYXRjaAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjIzNAogICAgLy8gYXNzZXJ0KGV4aXN0cyA9PT0gZXhpc3RzX2luZGV4LCAnZXhwZWN0ZWQgZXhpc3RzIGJ5IGluZGV4IHRvIG1hdGNoJykKICAgID09CiAgICBhc3NlcnQgLy8gZXhwZWN0ZWQgZXhpc3RzIGJ5IGluZGV4IHRvIG1hdGNoCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MjM1CiAgICAvLyByZXR1cm4gbmV3IEFkZHJlc3ModmFsdWUpCiAgICByZXRzdWIKCgovLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OlN0YXRlQXNzZXRQYXJhbXNDb250cmFjdC52ZXJpZnlfYXNzZXRfcGFyYW1zX2dldF9mcmVlemUoYTogdWludDY0KSAtPiBieXRlczoKdmVyaWZ5X2Fzc2V0X3BhcmFtc19nZXRfZnJlZXplOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjIzOC0yMzkKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBwdWJsaWMgdmVyaWZ5X2Fzc2V0X3BhcmFtc19nZXRfZnJlZXplKGE6IEFzc2V0KTogQWRkcmVzcyB7CiAgICBwcm90byAxIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czoyNDAKICAgIC8vIGNvbnN0IFt2YWx1ZSwgZXhpc3RzXSA9IG9wLkFzc2V0UGFyYW1zLmFzc2V0RnJlZXplKGEpCiAgICBmcmFtZV9kaWcgLTEKICAgIGFzc2V0X3BhcmFtc19nZXQgQXNzZXRGcmVlemUKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czoyNDEKICAgIC8vIGNvbnN0IFt2YWx1ZV9pbmRleCwgZXhpc3RzX2luZGV4XSA9IG9wLkFzc2V0UGFyYW1zLmFzc2V0RnJlZXplKGdldF8xc3RfcmVmX2luZGV4KCkpCiAgICBjYWxsc3ViIGdldF8xc3RfcmVmX2luZGV4CiAgICBhc3NldF9wYXJhbXNfZ2V0IEFzc2V0RnJlZXplCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MjQyCiAgICAvLyBhc3NlcnQodmFsdWUgPT09IHZhbHVlX2luZGV4LCAnZXhwZWN0ZWQgdmFsdWUgYnkgaW5kZXggdG8gbWF0Y2gnKQogICAgZGlnIDMKICAgIHVuY292ZXIgMgogICAgPT0KICAgIGFzc2VydCAvLyBleHBlY3RlZCB2YWx1ZSBieSBpbmRleCB0byBtYXRjaAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjI0MwogICAgLy8gYXNzZXJ0KGV4aXN0cyA9PT0gZXhpc3RzX2luZGV4LCAnZXhwZWN0ZWQgZXhpc3RzIGJ5IGluZGV4IHRvIG1hdGNoJykKICAgID09CiAgICBhc3NlcnQgLy8gZXhwZWN0ZWQgZXhpc3RzIGJ5IGluZGV4IHRvIG1hdGNoCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MjQ0CiAgICAvLyByZXR1cm4gbmV3IEFkZHJlc3ModmFsdWUpCiAgICByZXRzdWIKCgovLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OlN0YXRlQXNzZXRQYXJhbXNDb250cmFjdC52ZXJpZnlfYXNzZXRfcGFyYW1zX2dldF9jbGF3YmFjayhhOiB1aW50NjQpIC0+IGJ5dGVzOgp2ZXJpZnlfYXNzZXRfcGFyYW1zX2dldF9jbGF3YmFjazoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czoyNDctMjQ4CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gcHVibGljIHZlcmlmeV9hc3NldF9wYXJhbXNfZ2V0X2NsYXdiYWNrKGE6IEFzc2V0KTogQWRkcmVzcyB7CiAgICBwcm90byAxIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czoyNDkKICAgIC8vIGNvbnN0IFt2YWx1ZSwgZXhpc3RzXSA9IG9wLkFzc2V0UGFyYW1zLmFzc2V0Q2xhd2JhY2soYSkKICAgIGZyYW1lX2RpZyAtMQogICAgYXNzZXRfcGFyYW1zX2dldCBBc3NldENsYXdiYWNrCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MjUwCiAgICAvLyBjb25zdCBbdmFsdWVfaW5kZXgsIGV4aXN0c19pbmRleF0gPSBvcC5Bc3NldFBhcmFtcy5hc3NldENsYXdiYWNrKGdldF8xc3RfcmVmX2luZGV4KCkpCiAgICBjYWxsc3ViIGdldF8xc3RfcmVmX2luZGV4CiAgICBhc3NldF9wYXJhbXNfZ2V0IEFzc2V0Q2xhd2JhY2sKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czoyNTEKICAgIC8vIGFzc2VydCh2YWx1ZSA9PT0gdmFsdWVfaW5kZXgsICdleHBlY3RlZCB2YWx1ZSBieSBpbmRleCB0byBtYXRjaCcpCiAgICBkaWcgMwogICAgdW5jb3ZlciAyCiAgICA9PQogICAgYXNzZXJ0IC8vIGV4cGVjdGVkIHZhbHVlIGJ5IGluZGV4IHRvIG1hdGNoCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MjUyCiAgICAvLyBhc3NlcnQoZXhpc3RzID09PSBleGlzdHNfaW5kZXgsICdleHBlY3RlZCBleGlzdHMgYnkgaW5kZXggdG8gbWF0Y2gnKQogICAgPT0KICAgIGFzc2VydCAvLyBleHBlY3RlZCBleGlzdHMgYnkgaW5kZXggdG8gbWF0Y2gKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czoyNTMKICAgIC8vIHJldHVybiBuZXcgQWRkcmVzcyh2YWx1ZSkKICAgIHJldHN1YgoKCi8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo6U3RhdGVBc3NldFBhcmFtc0NvbnRyYWN0LnZlcmlmeV9hc3NldF9wYXJhbXNfZ2V0X2NyZWF0b3IoYTogdWludDY0KSAtPiBieXRlczoKdmVyaWZ5X2Fzc2V0X3BhcmFtc19nZXRfY3JlYXRvcjoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czoyNTYtMjU3CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gcHVibGljIHZlcmlmeV9hc3NldF9wYXJhbXNfZ2V0X2NyZWF0b3IoYTogQXNzZXQpOiBBZGRyZXNzIHsKICAgIHByb3RvIDEgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjI1OAogICAgLy8gY29uc3QgW3ZhbHVlLCBleGlzdHNdID0gb3AuQXNzZXRQYXJhbXMuYXNzZXRDcmVhdG9yKGEpCiAgICBmcmFtZV9kaWcgLTEKICAgIGFzc2V0X3BhcmFtc19nZXQgQXNzZXRDcmVhdG9yCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MjU5CiAgICAvLyBjb25zdCBbdmFsdWVfaW5kZXgsIGV4aXN0c19pbmRleF0gPSBvcC5Bc3NldFBhcmFtcy5hc3NldENyZWF0b3IoZ2V0XzFzdF9yZWZfaW5kZXgoKSkKICAgIGNhbGxzdWIgZ2V0XzFzdF9yZWZfaW5kZXgKICAgIGFzc2V0X3BhcmFtc19nZXQgQXNzZXRDcmVhdG9yCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MjYwCiAgICAvLyBhc3NlcnQodmFsdWUgPT09IHZhbHVlX2luZGV4LCAnZXhwZWN0ZWQgdmFsdWUgYnkgaW5kZXggdG8gbWF0Y2gnKQogICAgZGlnIDMKICAgIHVuY292ZXIgMgogICAgPT0KICAgIGFzc2VydCAvLyBleHBlY3RlZCB2YWx1ZSBieSBpbmRleCB0byBtYXRjaAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjI2MQogICAgLy8gYXNzZXJ0KGV4aXN0cyA9PT0gZXhpc3RzX2luZGV4LCAnZXhwZWN0ZWQgZXhpc3RzIGJ5IGluZGV4IHRvIG1hdGNoJykKICAgID09CiAgICBhc3NlcnQgLy8gZXhwZWN0ZWQgZXhpc3RzIGJ5IGluZGV4IHRvIG1hdGNoCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MjYyCiAgICAvLyByZXR1cm4gbmV3IEFkZHJlc3ModmFsdWUpCiAgICByZXRzdWIK", - "clear": "I3ByYWdtYSB2ZXJzaW9uIDEwCgp0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OlN0YXRlQXNzZXRQYXJhbXNDb250cmFjdC5jbGVhclN0YXRlUHJvZ3JhbToKICAgIHB1c2hpbnQgMSAvLyAxCiAgICByZXR1cm4K" - }, - "events": [], - "templateVariables": {} -} \ No newline at end of file diff --git a/tests/artifacts/state-ops/data/StateAssetParamsContract.clear.teal b/tests/artifacts/state-ops/data/StateAssetParamsContract.clear.teal deleted file mode 100644 index fc0579b..0000000 --- a/tests/artifacts/state-ops/data/StateAssetParamsContract.clear.teal +++ /dev/null @@ -1,5 +0,0 @@ -#pragma version 10 - -tests/artifacts/state-ops/contract.algo.ts::StateAssetParamsContract.clearStateProgram: - pushint 1 // 1 - return diff --git a/tests/artifacts/switch-statements/contract.algo.ts b/tests/artifacts/switch-statements/contract.algo.ts new file mode 100644 index 0000000..df34653 --- /dev/null +++ b/tests/artifacts/switch-statements/contract.algo.ts @@ -0,0 +1,95 @@ +import type { bytes, uint64 } from '@algorandfoundation/algorand-typescript' +import { assert, Bytes, Contract, GlobalState, Uint64 } from '@algorandfoundation/algorand-typescript' + +export class DemoContract extends Contract { + run() { + assert(this.test_uint64(1) === 3) + assert(this.test_uint64(2) === 3) + assert(this.test_uint64(3) === 1) + assert(this.test_uint64(4) === 3) + + assert(this.test_break(1) === 11) + assert(this.test_break(2) === 12) + assert(this.test_break(3) === 10) + assert(this.test_break(4) === 14) + assert(this.test_break(5) === 50) + + assert(this.test_bytes(Bytes('hmmm'))) + assert(this.test_bytes(Bytes.fromHex('ff'))) + assert(this.test_bytes(Bytes.fromBase64('ZHNmc2Rmc2Q='))) + assert(this.test_bytes(Bytes.fromBase32('ONSGMZ3OMJTGOZDGMRSGM==='))) + assert(!this.test_bytes(Bytes())) + } + + private test_uint64(x: uint64): uint64 { + switch (x) { + case 1: + case 2: + case Uint64(4): + return 3 + default: { + return 1 + } + } + } + + private test_break(x: uint64): uint64 { + let i: uint64 = 10 + switch (x) { + case 1: + case 2: + case Uint64(4): + i += x + break + case 5: + i *= x + } + return i + } + + private test_bytes(x: bytes): boolean { + switch (x) { + case Bytes('hmmm'): + case Bytes.fromHex('Ff'): + case Bytes.fromBase64('ZHNmc2Rmc2Q='): + case Bytes.fromBase32('ONSGMZ3OMJTGOZDGMRSGM==='): + return true + } + return false + } + + evalCount = GlobalState() + + private increaseEvalAndReturn(n: uint64) { + this.evalCount.value++ + return n + } + + public test_side_effects(n: uint64) { + this.evalCount.value = 0 + + switch (n) { + case this.increaseEvalAndReturn(n - 1): + break + case this.increaseEvalAndReturn(n): + break + case this.increaseEvalAndReturn(n + 1): + break + } + + assert(this.evalCount.value === 2, 'Only two functions should be evaluated') + } + + public test_non_trivial_termination_of_clause(n: uint64, y: uint64): uint64 { + switch (n) { + case 1: + if (y % 2 === 0) { + return y + } else { + return n + } + default: + return y * n + } + } +} diff --git a/tests/avm-invoker.ts b/tests/avm-invoker.ts index 844ff7c..3f76888 100644 --- a/tests/avm-invoker.ts +++ b/tests/avm-invoker.ts @@ -1,46 +1,20 @@ -import * as algokit from '@algorandfoundation/algokit-utils' -import { AlgoAmount } from '@algorandfoundation/algokit-utils/types/amount' -import { AppClient } from '@algorandfoundation/algokit-utils/types/app-client' -import { AppSpec } from '@algorandfoundation/algokit-utils/types/app-spec' -import { AssetCreateParams } from '@algorandfoundation/algokit-utils/types/composer' -import { KmdAccountManager } from '@algorandfoundation/algokit-utils/types/kmd-account-manager' -import { nullLogger } from '@algorandfoundation/algokit-utils/types/logging' -import { Account, Bytes, internal, uint64 } from '@algorandfoundation/algorand-typescript' +import type { AppClient } from '@algorandfoundation/algokit-utils/types/app-client' +import type { AssetCreateParams } from '@algorandfoundation/algokit-utils/types/composer' import { randomUUID } from 'crypto' -import { Mutable } from '../src/typescript-helpers' -import { asUint64, getRandomBigInt, getRandomNumber, Lazy } from '../src/util' +import type { Mutable } from '../src/typescript-helpers' +import { getRandomBigInt, getRandomNumber } from '../src/util' export type ABIValue = boolean | number | bigint | string | Uint8Array | ABIValue[] -algokit.Config.configure({ logger: nullLogger }) - -const algorandClient = Lazy(() => algokit.AlgorandClient.defaultLocalNet()) - export const INITIAL_BALANCE_MICRO_ALGOS = Number(20e6) -export const getAlgorandAppClient = async (appSpec: AppSpec) => { - const [appClient, _] = await getAlgorandAppClientWithApp(appSpec) - return appClient -} - -export const getAlgorandAppClientWithApp = async (appSpec: AppSpec) => { - const algorand = algorandClient() - const defaultSigner = await algorand.account.kmd.getLocalNetDispenserAccount() - const appClient = algorand.client.getAppFactory({ - appSpec, - defaultSigner: defaultSigner.signer, - defaultSender: defaultSigner.account.sender.addr, - }) - const app = await appClient.deploy({ appName: `${appSpec.contract.name}${randomUUID()}`, createParams: { extraProgramPages: undefined } }) - - return [app.appClient, app.result] as const -} +type MethodArgs = Exclude[0]['args'], undefined> const invokeMethod = async ( appClient: AppClient, method: string, sendParams?: Partial[0]>, - ...methodArgs: ABIValue[] + ...methodArgs: MethodArgs ): ReturnType => { const response = await appClient.send.call({ method, args: methodArgs, note: randomUUID(), ...sendParams }) return response @@ -49,7 +23,7 @@ const invokeMethod = async ( export const getAvmResult = async ( { appClient, sendParams }: { appClient: AppClient; sendParams?: Partial[0]> }, method: string, - ...methodArgs: ABIValue[] + ...methodArgs: MethodArgs ): Promise => { const result = await invokeMethod(appClient, method, sendParams, ...methodArgs) if (result.returns?.at(-1)?.decodeError) { @@ -61,7 +35,7 @@ export const getAvmResult = async ( export const getAvmResultLog = async ( { appClient, sendParams }: { appClient: AppClient; sendParams?: Partial[0]> }, method: string, - ...methodArgs: ABIValue[] + ...methodArgs: MethodArgs ): Promise => { const result = await invokeMethod(appClient, method, sendParams, ...methodArgs) return result?.confirmation?.logs @@ -70,31 +44,16 @@ export const getAvmResultLog = async ( export const getAvmResultRaw = async ( { appClient, sendParams }: { appClient: AppClient; sendParams?: Partial[0]> }, method: string, - ...methodArgs: ABIValue[] + ...methodArgs: MethodArgs ): Promise => { const result = await invokeMethod(appClient, method, sendParams, ...methodArgs) return result?.returns?.at(-1)?.rawReturnValue } -export const getLocalNetDefaultAccount = () => { - const client = algorandClient() - const kmdAccountManager = new KmdAccountManager(client.client) - return kmdAccountManager.getLocalNetDispenserAccount() -} - -export const generateAVMTestAccount = async (): Promise> => { - const client = algorandClient() - const account = client.account.random() - await client.account.ensureFundedFromEnvironment(account.addr, AlgoAmount.MicroAlgos(INITIAL_BALANCE_MICRO_ALGOS)) - return account -} - -export const generateTestAccount = async (): Promise => { - const account = await generateAVMTestAccount() - return Account(Bytes.fromBase32(account.addr.toString())) -} - -export const generateTestAsset = async (fields: Mutable): Promise => { +export const generateTestAsset = async ( + assetFactory: (assetCreateParams: AssetCreateParams) => Promise, + fields: Mutable, +): Promise => { if (fields.total === undefined) { fields.total = getRandomBigInt(20, 120) } @@ -107,8 +66,7 @@ export const generateTestAsset = async (fields: Mutable): Pro fields.decimals = 0 } - const client = algorandClient() - const x = await client.send.assetCreate({ + return await assetFactory({ sender: fields.sender, total: BigInt(fields.total) * 10n ** BigInt(fields.decimals), decimals: fields.decimals, @@ -123,8 +81,4 @@ export const generateTestAsset = async (fields: Mutable): Pro defaultFrozen: fields.defaultFrozen ?? false, note: randomUUID(), }) - if (x.confirmation === undefined || x.confirmation.assetIndex === undefined) { - internal.errors.internalError('Failed to create asset') - } - return asUint64(x.confirmation.assetIndex) } diff --git a/tests/crypto-op-codes.spec.ts b/tests/crypto-op-codes.spec.ts index 2875019..e47beaa 100644 --- a/tests/crypto-op-codes.spec.ts +++ b/tests/crypto-op-codes.spec.ts @@ -1,17 +1,20 @@ import { AlgoAmount } from '@algorandfoundation/algokit-utils/types/amount' -import { AppSpec } from '@algorandfoundation/algokit-utils/types/app-spec' -import { Bytes, Ec, Ecdsa, internal, uint64, VrfVerify } from '@algorandfoundation/algorand-typescript' -import { ec } from 'elliptic' -import { keccak256 as js_keccak256 } from 'js-sha3' -import { sha512_256 as js_sha512_256 } from 'js-sha512' +import type { uint64 } from '@algorandfoundation/algorand-typescript' +import { Bytes, Ec, Ecdsa, MimcConfigurations, op, VrfVerify } from '@algorandfoundation/algorand-typescript' +import { encodingUtil } from '@algorandfoundation/puya-ts' +import elliptic from 'elliptic' +import js_sha3 from 'js-sha3' +import js_sha512 from 'js-sha512' import nacl from 'tweetnacl' -import { afterEach, describe, expect, it, Mock, test, vi } from 'vitest' +import type { Mock } from 'vitest' +import { afterEach, beforeAll, describe, expect, vi } from 'vitest' import { TestExecutionContext } from '../src' import { LOGIC_DATA_PREFIX, MAX_BYTES_SIZE, PROGRAM_TAG } from '../src/constants' -import * as op from '../src/impl/crypto' -import { asUint8Array, conactUint8Arrays, decodePublicKey } from '../src/util' -import appSpecJson from './artifacts/crypto-ops/data/CryptoOpsContract.arc32.json' -import { generateAVMTestAccount, getAlgorandAppClientWithApp, getAvmResult } from './avm-invoker' +import { BytesCls, Uint64Cls } from '../src/impl/primitives' +import { decodePublicKey } from '../src/impl/reference' +import { asBytes, asUint64, asUint8Array, conactUint8Arrays } from '../src/util' +import { getAvmResult, INITIAL_BALANCE_MICRO_ALGOS } from './avm-invoker' +import { createArc4TestFixture } from './test-fixture' import { getPaddedBytes } from './util' const MAX_ARG_LEN = 2048 @@ -21,57 +24,65 @@ const curveMap = { } vi.mock('../src/impl/crypto', async (importOriginal) => { + // eslint-disable-next-line @typescript-eslint/consistent-type-imports const mod = await importOriginal() return { ...mod, - mockedVrfVerify: vi.fn(), + vrfVerify: vi.fn(mod.vrfVerify), + mimc: vi.fn(mod.mimc), } }) + describe('crypto op codes', async () => { - const [appClient, app] = await getAlgorandAppClientWithApp(appSpecJson as AppSpec) + const [test, localnetFixture] = createArc4TestFixture('tests/artifacts/crypto-ops/contract.algo.ts', { CryptoOpsContract: {} }) const ctx = new TestExecutionContext() - afterEach(async () => { + beforeAll(async () => { + await localnetFixture.newScope() + }) + + afterEach(() => { ctx.reset() }) describe('sha256', async () => { - test.each([ + test.for([ ['', 0], ['0'.repeat(MAX_ARG_LEN - 14), 0], ['abc', 0], ['abc', MAX_BYTES_SIZE - 3], - ])('should return the correct sha256 hash', async (a, padSize) => { - const avmResult = (await getAvmResult({ appClient }, 'verify_sha256', asUint8Array(a), padSize))! - const paddedA = getPaddedBytes(padSize, a) + ])('should return the correct sha256 hash', async ([a, padSize], { appClientCryptoOpsContract: appClient }) => { + const avmResult = (await getAvmResult({ appClient }, 'verify_sha256', asUint8Array(a as string), padSize))! + const paddedA = getPaddedBytes(padSize as number, a as string) const result = op.sha256(paddedA) expect(result).toEqual(avmResult) }) }) describe('sha3_256', async () => { - test.each([ + test.for([ ['', 0], ['0'.repeat(MAX_ARG_LEN - 14), 0], ['abc', 0], ['abc', MAX_BYTES_SIZE - 3], - ])('should return the correct sha3_256 hash', async (a, padSize) => { - const avmResult = (await getAvmResult({ appClient }, 'verify_sha3_256', asUint8Array(a), padSize))! - const paddedA = getPaddedBytes(padSize, a) + ])('should return the correct sha3_256 hash', async ([a, padSize], { appClientCryptoOpsContract: appClient }) => { + const avmResult = (await getAvmResult({ appClient }, 'verify_sha3_256', asUint8Array(a as string), padSize))! + const paddedA = getPaddedBytes(padSize as number, a as string) const result = op.sha3_256(paddedA) expect(result).toEqual(avmResult) }) }) describe('keccak256', async () => { - test.each([ + test.for([ ['', 0], ['0'.repeat(MAX_ARG_LEN - 14), 0], ['abc', 0], ['abc', MAX_BYTES_SIZE - 3], - ])('should return the correct keccak256 hash', async (a, padSize) => { - const avmResult = (await getAvmResult({ appClient }, 'verify_keccak_256', asUint8Array(a), padSize))! - const paddedA = getPaddedBytes(padSize, a) + ])('should return the correct keccak256 hash', async ([a, padSize], { appClientCryptoOpsContract: appClient }) => { + const avmResult = await getAvmResult({ appClient }, 'verify_keccak_256', asUint8Array(a as string), padSize) + + const paddedA = getPaddedBytes(padSize as number, a as string) const result = op.keccak256(paddedA) expect(result).toEqual(avmResult) expect(result.length.valueOf()).toBe(32n) @@ -79,14 +90,15 @@ describe('crypto op codes', async () => { }) describe('sha512_256', async () => { - test.each([ + test.for([ ['', 0], ['0'.repeat(MAX_ARG_LEN - 14), 0], ['abc', 0], ['abc', MAX_BYTES_SIZE - 3], - ])('should return the correct sha512_256 hash', async (a, padSize) => { - const avmResult = (await getAvmResult({ appClient }, 'verify_sha512_256', asUint8Array(a), padSize))! - const paddedA = getPaddedBytes(padSize, a) + ])('should return the correct sha512_256 hash', async ([a, padSize], { appClientCryptoOpsContract: appClient }) => { + const avmResult = await getAvmResult({ appClient }, 'verify_sha512_256', asUint8Array(a as string), padSize) + + const paddedA = getPaddedBytes(padSize as number, a as string) const result = op.sha512_256(paddedA) expect(result).toEqual(avmResult) expect(result.length.valueOf()).toBe(32n) @@ -94,41 +106,50 @@ describe('crypto op codes', async () => { }) describe('ed25519verifyBare', async () => { - it('should return true for valid signature', async () => { + test('should return true for valid signature', async ({ appClientCryptoOpsContract: appClient }) => { const keyPair = nacl.sign.keyPair() const message = 'Test message for ed25519 verification' const signature = nacl.sign.detached(asUint8Array(message), keyPair.secretKey) - const avmResult = await getAvmResult( + const avmResult = await getAvmResult( { appClient, sendParams: { staticFee: AlgoAmount.Algos(2000) } }, 'verify_ed25519verify_bare', asUint8Array(message), signature, keyPair.publicKey, ) - const result = op.ed25519verifyBare(message, Bytes(signature), Bytes(keyPair.publicKey)) + const result = op.ed25519verifyBare(asBytes(message), Bytes(signature), Bytes(keyPair.publicKey)) expect(result).toEqual(avmResult) }) }) describe('ed25519verify', async () => { - it('should return true for valid signature', async () => { - const approval = app.compiledApproval! + test('should return true for valid signature', async ({ appFactoryCryptoOpsContract }) => { + const app = await appFactoryCryptoOpsContract.deploy({}) + const approval = app.result.compiledApproval! const appCallTxn = ctx.any.txn.applicationCall({ approvalProgram: Bytes(approval.compiledBase64ToBytes), }) const message = Bytes('Test message for ed25519 verification') - const account = await generateAVMTestAccount() + const account = await localnetFixture.context.generateAccount({ + initialFunds: AlgoAmount.MicroAlgos(INITIAL_BALANCE_MICRO_ALGOS + 100_000), + }) + const publicKey = decodePublicKey(account.addr.toString()) const logicSig = conactUint8Arrays(asUint8Array(PROGRAM_TAG), approval.compiledBase64ToBytes) - const logicSigAddress = js_sha512_256.array(logicSig) + const logicSigAddress = js_sha512.sha512_256.array(logicSig) const parts = conactUint8Arrays(new Uint8Array(logicSigAddress), asUint8Array(message)) const toBeSigned = conactUint8Arrays(asUint8Array(LOGIC_DATA_PREFIX), parts) - const signature = nacl.sign.detached(toBeSigned, account.account.sk) + const signature = nacl.sign.detached(toBeSigned, account.sk) - const avmResult = await getAvmResult( - { appClient, sendParams: { staticFee: AlgoAmount.Algos(2000) } }, + const avmResult = await getAvmResult( + { + appClient: app.appClient, + sendParams: { + staticFee: AlgoAmount.Algos(2000), + }, + }, 'verify_ed25519verify', asUint8Array(message), signature, @@ -140,21 +161,26 @@ describe('crypto op codes', async () => { expect(result).toEqual(avmResult) }) }) - it('should throw error when no active txn group', async () => { + test('should throw error when no active txn group', async () => { expect(() => op.ed25519verify(Bytes(''), Bytes(''), Bytes(''))).toThrow('no active txn group') }) }) describe('ecdsaVerify', async () => { - it('should be able to verify k1 signature', async () => { + test('should be able to verify k1 signature', async ({ appClientCryptoOpsContract: appClient }) => { const messageHash = Bytes.fromHex('f809fd0aa0bb0f20b354c6b2f86ea751957a4e262a546bd716f34f69b9516ae1') const sigR = Bytes.fromHex('f7f913754e5c933f3825d3aef22e8bf75cfe35a18bede13e15a6e4adcfe816d2') const sigS = Bytes.fromHex('0b5599159aa859d79677f33280848ae4c09c2061e8b5881af8507f8112966754') const pubkeyX = Bytes.fromHex('a710244d62747aa8db022ddd70617240adaf881b439e5f69993800e614214076') const pubkeyY = Bytes.fromHex('48d0d337704fe2c675909d2c93f7995e199156f302f63c74a8b96827b28d777b') - const avmResult = await getAvmResult( - { appClient, sendParams: { staticFee: AlgoAmount.Algos(5000) } }, + const avmResult = await getAvmResult( + { + appClient, + sendParams: { + staticFee: AlgoAmount.Algos(5000), + }, + }, 'verify_ecdsa_verify_k1', asUint8Array(messageHash), asUint8Array(sigR), @@ -166,15 +192,20 @@ describe('crypto op codes', async () => { expect(result).toEqual(avmResult) }) - it('should be able to verify r1 signature', async () => { + test('should be able to verify r1 signature', async ({ appClientCryptoOpsContract: appClient }) => { const messageHash = Bytes.fromHex('f809fd0aa0bb0f20b354c6b2f86ea751957a4e262a546bd716f34f69b9516ae1') const sigR = Bytes.fromHex('18d96c7cda4bc14d06277534681ded8a94828eb731d8b842e0da8105408c83cf') const sigS = Bytes.fromHex('7d33c61acf39cbb7a1d51c7126f1718116179adebd31618c4604a1f03b5c274a') const pubkeyX = Bytes.fromHex('f8140e3b2b92f7cbdc8196bc6baa9ce86cf15c18e8ad0145d50824e6fa890264') const pubkeyY = Bytes.fromHex('bd437b75d6f1db67155a95a0da4b41f2b6b3dc5d42f7db56238449e404a6c0a3') - const avmResult = await getAvmResult( - { appClient, sendParams: { staticFee: AlgoAmount.Algos(5000) } }, + const avmResult = await getAvmResult( + { + appClient, + sendParams: { + staticFee: AlgoAmount.Algos(5000), + }, + }, 'verify_ecdsa_verify_r1', asUint8Array(messageHash), asUint8Array(sigR), @@ -189,7 +220,7 @@ describe('crypto op codes', async () => { }) describe('ecdsaPkRecover', async () => { - it('should be able to recover k1 public key', async () => { + test('should be able to recover k1 public key', async ({ appClientCryptoOpsContract: appClient }) => { const testData = generateEcdsaTestData(Ecdsa.Secp256k1) const a = testData.data const b = testData.recoveryId @@ -197,27 +228,34 @@ describe('crypto op codes', async () => { const d = testData.s const avmResult = await getAvmResult( { appClient, sendParams: { staticFee: AlgoAmount.Algos(5000) } }, + 'verify_ecdsa_recover_k1', asUint8Array(a), b.asNumber(), asUint8Array(c), asUint8Array(d), ) - const result = op.ecdsaPkRecover(Ecdsa.Secp256k1, a, b, c, d) + + const result = op.ecdsaPkRecover(Ecdsa.Secp256k1, asBytes(a), asUint64(b), asBytes(c), asBytes(d)) expect(result[0]).toEqual(avmResult[0]) expect(result[1]).toEqual(avmResult[1]) }) - it('should throw unsupported error when trying to recover r1 public key', async () => { + test('should throw unsupported error when trying to recover r1 public key', async ({ appClientCryptoOpsContract: appClient }) => { const testData = generateEcdsaTestData(Ecdsa.Secp256r1) const a = testData.data const b = testData.recoveryId const c = testData.r const d = testData.s await expect( - getAvmResult( - { appClient, sendParams: { staticFee: AlgoAmount.Algos(5000) } }, + getAvmResult( + { + appClient, + sendParams: { + staticFee: AlgoAmount.Algos(5000), + }, + }, 'verify_ecdsa_recover_r1', asUint8Array(a), b.asNumber(), @@ -226,15 +264,15 @@ describe('crypto op codes', async () => { ), ).rejects.toThrow('unsupported curve') - expect(() => op.ecdsaPkRecover(Ecdsa.Secp256r1, a, b, c, d)).toThrow('Unsupported ECDSA curve') + expect(() => op.ecdsaPkRecover(Ecdsa.Secp256r1, asBytes(a), asUint64(b), asBytes(c), asBytes(d))).toThrow('Unsupported ECDSA curve') }) }) describe('ecdsaPkDecompress', async () => { - it('should be able to decompress k1 public key', async () => { + test('should be able to decompress k1 public key', async ({ appClientCryptoOpsContract: appClient }) => { const v = Ecdsa.Secp256k1 const testData = generateEcdsaTestData(v) - const ecdsa = new ec(curveMap[v]) + const ecdsa = new elliptic.ec(curveMap[v]) const keyPair = ecdsa.keyFromPublic(testData.pubkeyX.concat(testData.pubkeyY).asUint8Array()) const pubKeyArray = new Uint8Array(keyPair.getPublic(true, 'array')) const avmResult = await getAvmResult( @@ -242,6 +280,7 @@ describe('crypto op codes', async () => { 'verify_ecdsa_decompress_k1', pubKeyArray, ) + const result = op.ecdsaPkDecompress(v, Bytes(pubKeyArray)) expect(asUint8Array(result[0])).toEqual(new Uint8Array(avmResult[0])) @@ -250,17 +289,22 @@ describe('crypto op codes', async () => { }) describe('vrfVerify', async () => { - const a = internal.primitives.BytesCls.fromHex('528b9e23d93d0e020a119d7ba213f6beb1c1f3495a217166ecd20f5a70e7c2d7') - const b = internal.primitives.BytesCls.fromHex( + const a = BytesCls.fromHex('528b9e23d93d0e020a119d7ba213f6beb1c1f3495a217166ecd20f5a70e7c2d7') + const b = BytesCls.fromHex( '372a3afb42f55449c94aaa5f274f26543e77e8d8af4babee1a6fbc1c0391aa9e6e0b8d8d7f4ed045d5b517fea8ad3566025ae90d2f29f632e38384b4c4f5b9eb741c6e446b0f540c1b3761d814438b04', ) - const c = internal.primitives.BytesCls.fromHex('3a2740da7a0788ebb12a52154acbcca1813c128ca0b249e93f8eb6563fee418d') + const c = BytesCls.fromHex('3a2740da7a0788ebb12a52154acbcca1813c128ca0b249e93f8eb6563fee418d') - it('should throw not available error', async () => { - expect(() => op.vrfVerify(VrfVerify.VrfAlgorand, a, b, c)).toThrow('vrfVerify is not available in test context') + test('should throw not available error', async () => { + const mockedVrfVerify = op.vrfVerify as Mock + // restore to original stub implemention which should throw not available error + mockedVrfVerify.mockRestore() + expect(() => op.vrfVerify(VrfVerify.VrfAlgorand, asBytes(a), asBytes(b), asBytes(c))).toThrow( + 'vrfVerify is not available in test context', + ) }) - it('should return mocked result', async () => { + test('should return mocked result', async ({ appClientCryptoOpsContract: appClient }) => { const avmResult = await getAvmResult<[Uint8Array, boolean]>( { appClient, sendParams: { staticFee: AlgoAmount.Algos(6000) } }, 'verify_vrf_verify', @@ -268,17 +312,41 @@ describe('crypto op codes', async () => { asUint8Array(b), asUint8Array(c), ) - const mockedVrfVerify = (op as unknown as { mockedVrfVerify: Mock }).mockedVrfVerify - mockedVrfVerify.mockReturnValue([internal.primitives.BytesCls.fromCompat(new Uint8Array(avmResult[0])).asAlgoTs(), avmResult[1]]) - const result = mockedVrfVerify(VrfVerify.VrfAlgorand, a, b, c) + const mockedVrfVerify = op.vrfVerify as Mock + mockedVrfVerify.mockReturnValue([BytesCls.fromCompat(new Uint8Array(avmResult[0])).asAlgoTs(), avmResult[1]]) + const result = op.vrfVerify(VrfVerify.VrfAlgorand, asBytes(a), asBytes(b), asBytes(c)) expect(asUint8Array(result[0])).toEqual(new Uint8Array(avmResult[0])) expect(result[1]).toEqual(avmResult[1]) }) }) + describe('mimc', async () => { + const a = encodingUtil.bigIntToUint8Array(1234567890n, 32) + + test('should throw not available error', async () => { + const mockedMimc = op.mimc as Mock + // restore to original stub implemention which should throw not available error + mockedMimc.mockRestore() + expect(() => op.mimc(MimcConfigurations.BN254Mp110, Bytes(a))).toThrow('mimc is not available in test context') + }) + + test('should return mocked result', async ({ appClientCryptoOpsContract: appClient }) => { + const avmResult = await getAvmResult( + { appClient, sendParams: { staticFee: AlgoAmount.Algos(6000) } }, + 'verify_mimc', + asUint8Array(a), + ) + const mockedMimc = op.mimc as Mock + mockedMimc.mockReturnValue(Bytes(avmResult)) + const result = op.mimc(MimcConfigurations.BN254Mp110, Bytes(a)) + + expect(result).toEqual(avmResult) + }) + }) + describe('EllipticCurve', async () => { - it('should throw not available error', async () => { + test('should throw not available error', async () => { expect(() => op.EllipticCurve.add(Ec.BN254g2, Bytes(''), Bytes(''))).toThrow('EllipticCurve.add is not available in test context') expect(() => op.EllipticCurve.mapTo(Ec.BN254g2, Bytes(''))).toThrow('EllipticCurve.mapTo is not available in test context') expect(() => op.EllipticCurve.pairingCheck(Ec.BN254g2, Bytes(''), Bytes(''))).toThrow( @@ -298,20 +366,20 @@ describe('crypto op codes', async () => { }) const generateEcdsaTestData = (v: Ecdsa) => { - const ecdsa = new ec(curveMap[v]) + const ecdsa = new elliptic.ec(curveMap[v]) const keyPair = ecdsa.genKeyPair() const pk = keyPair.getPublic('array') - const data = internal.primitives.BytesCls.fromCompat('test data for ecdsa') - const messageHash = js_keccak256.create().update(data.asUint8Array()).digest() + const data = BytesCls.fromCompat('test data for ecdsa') + const messageHash = js_sha3.keccak256.create().update(data.asUint8Array()).digest() const signature = keyPair.sign(messageHash) const recoveryId = 0 // Recovery ID is typically 0 or 1 return { - data: internal.primitives.BytesCls.fromCompat(new Uint8Array(messageHash)), - r: internal.primitives.BytesCls.fromCompat(new Uint8Array(signature.r.toArray('be'))), - s: internal.primitives.BytesCls.fromCompat(new Uint8Array(signature.s.toArray('be'))), - recoveryId: internal.primitives.Uint64Cls.fromCompat(recoveryId), - pubkeyX: internal.primitives.BytesCls.fromCompat(new Uint8Array(pk.slice(0, 32))), - pubkeyY: internal.primitives.BytesCls.fromCompat(new Uint8Array(pk.slice(32))), + data: BytesCls.fromCompat(new Uint8Array(messageHash)), + r: BytesCls.fromCompat(new Uint8Array(signature.r.toArray('be', 32))), + s: BytesCls.fromCompat(new Uint8Array(signature.s.toArray('be', 32))), + recoveryId: Uint64Cls.fromCompat(recoveryId), + pubkeyX: BytesCls.fromCompat(new Uint8Array(pk.slice(0, 32))), + pubkeyY: BytesCls.fromCompat(new Uint8Array(pk.slice(32))), } } diff --git a/tests/global-state-arc4-values.spec.ts b/tests/global-state-arc4-values.spec.ts index c5be7e8..74fd9d9 100644 --- a/tests/global-state-arc4-values.spec.ts +++ b/tests/global-state-arc4-values.spec.ts @@ -1,29 +1,33 @@ -import { AppSpec } from '@algorandfoundation/algokit-utils/types/app-spec' import { Bytes } from '@algorandfoundation/algorand-typescript' import { TestExecutionContext } from '@algorandfoundation/algorand-typescript-testing' -import { +import type { AddressImpl, BoolImpl, ByteImpl, DynamicBytesImpl, StrImpl, - UintNImpl, } from '@algorandfoundation/algorand-typescript-testing/runtime-helpers' -import { Address, ARC4Encoded, BitSize, Bool, Byte, DynamicBytes, Str, UintN } from '@algorandfoundation/algorand-typescript/arc4' -import { afterEach, describe, expect, test } from 'vitest' -import { DeliberateAny, FunctionKeys } from '../src/typescript-helpers' +import { UintNImpl } from '@algorandfoundation/algorand-typescript-testing/runtime-helpers' +import type { ARC4Encoded, BitSize } from '@algorandfoundation/algorand-typescript/arc4' +import { Address, Bool, Byte, DynamicBytes, Str, UintN } from '@algorandfoundation/algorand-typescript/arc4' +import { afterEach, beforeAll, describe, expect } from 'vitest' +import type { DeliberateAny, FunctionKeys } from '../src/typescript-helpers' import { asUint8Array } from '../src/util' import { GlobalStateContract } from './artifacts/state-ops/contract.algo' -import arc4AppGlobalAppSpecJson from './artifacts/state-ops/data/GlobalStateContract.arc32.json' -import { getAlgorandAppClient, getAvmResult, getLocalNetDefaultAccount } from './avm-invoker' +import { getAvmResult } from './avm-invoker' +import { createArc4TestFixture } from './test-fixture' describe('ARC4 AppGlobal values', async () => { - const appClient = await getAlgorandAppClient(arc4AppGlobalAppSpecJson as AppSpec) - const localNetAccount = await getLocalNetDefaultAccount() - const defaultSenderAccountAddress = Bytes.fromBase32(localNetAccount.addr.toString()) - const ctx = new TestExecutionContext(defaultSenderAccountAddress) + const [test, localnetFixture] = createArc4TestFixture('tests/artifacts/state-ops/contract.algo.ts', { + GlobalStateContract: {}, + }) + const ctx = new TestExecutionContext() + + beforeAll(async () => { + await localnetFixture.newScope() + }) - afterEach(async () => { + afterEach(() => { ctx.reset() }) @@ -104,14 +108,16 @@ describe('ARC4 AppGlobal values', async () => { }, ]) - test.each(testData)('should be able to get arc4 state values', async (data) => { + test.for(testData)('should be able to get arc4 state values', async (data, { appClientGlobalStateContract: appClient, testAccount }) => { + ctx.defaultSender = Bytes.fromBase32(testAccount.addr.toString()) const avmResult = await getAvmResult({ appClient }, data.methodName) const contract = ctx.contract.create(GlobalStateContract) const result = contract[data.methodName as FunctionKeys](undefined as never) as ARC4Encoded data.assert(result, avmResult) }) - test.each(testData)('should be able to set arc4 state values', async (data) => { + test.for(testData)('should be able to set arc4 state values', async (data, { appClientGlobalStateContract: appClient, testAccount }) => { + ctx.defaultSender = Bytes.fromBase32(testAccount.addr.toString()) const setMethodName = data.methodName.replace('get', 'set') await getAvmResult({ appClient }, setMethodName, data.nativeValue) const contract = ctx.contract.create(GlobalStateContract) diff --git a/tests/local-state-arc4-values.spec.ts b/tests/local-state-arc4-values.spec.ts index f7d7848..02a2331 100644 --- a/tests/local-state-arc4-values.spec.ts +++ b/tests/local-state-arc4-values.spec.ts @@ -1,31 +1,34 @@ -import { AppClient } from '@algorandfoundation/algokit-utils/types/app-client' -import { AppSpec } from '@algorandfoundation/algokit-utils/types/app-spec' +import type { AppClient } from '@algorandfoundation/algokit-utils/types/app-client' import { Account, Bytes } from '@algorandfoundation/algorand-typescript' import { TestExecutionContext } from '@algorandfoundation/algorand-typescript-testing' -import { +import type { AddressImpl, BoolImpl, ByteImpl, DynamicBytesImpl, StrImpl, - UintNImpl, } from '@algorandfoundation/algorand-typescript-testing/runtime-helpers' -import { Address, ARC4Encoded, BitSize, Bool, Byte, DynamicBytes, Str, UintN } from '@algorandfoundation/algorand-typescript/arc4' -import { afterEach, describe, expect, test } from 'vitest' +import { UintNImpl } from '@algorandfoundation/algorand-typescript-testing/runtime-helpers' +import type { ARC4Encoded, BitSize } from '@algorandfoundation/algorand-typescript/arc4' +import { Address, Bool, Byte, DynamicBytes, Str, UintN } from '@algorandfoundation/algorand-typescript/arc4' +import { afterEach, beforeAll, describe, expect } from 'vitest' import { OnApplicationComplete } from '../src/constants' -import { DeliberateAny } from '../src/typescript-helpers' +import type { DeliberateAny } from '../src/typescript-helpers' import { LocalStateContract } from './artifacts/state-ops/contract.algo' -import arc4AppLocalAppSpecJson from './artifacts/state-ops/data/LocalStateContract.arc32.json' -import { getAlgorandAppClient, getAvmResult, getLocalNetDefaultAccount } from './avm-invoker' +import { getAvmResult } from './avm-invoker' +import { createArc4TestFixture } from './test-fixture' describe('ARC4 AppLocal values', async () => { - const appClient = await getAlgorandAppClient(arc4AppLocalAppSpecJson as AppSpec) - const localNetAccount = await getLocalNetDefaultAccount() - const defaultSenderAccountAddress = Bytes.fromBase32(localNetAccount.addr.toString()) - const ctx = new TestExecutionContext(defaultSenderAccountAddress) - await tryOptIn(appClient) + const [test, localnetFixture] = createArc4TestFixture('tests/artifacts/state-ops/contract.algo.ts', { + LocalStateContract: {}, + }) + const ctx = new TestExecutionContext() + + beforeAll(async () => { + await localnetFixture.newScope() + }) - afterEach(async () => { + afterEach(() => { ctx.reset() }) @@ -92,14 +95,19 @@ describe('ARC4 AppLocal values', async () => { }, ]) - test.each(testData)('should be able to get arc4 state values', async (data) => { - const avmResult = await getAvmResult({ appClient }, data.methodName, localNetAccount.addr.toString()) + test.for(testData)('should be able to get arc4 state values', async (data, { appClientLocalStateContract: appClient, testAccount }) => { + const defaultSenderAccountAddress = Bytes.fromBase32(testAccount.addr.toString()) + ctx.defaultSender = defaultSenderAccountAddress + await tryOptIn(appClient) + + const avmResult = await getAvmResult({ appClient }, data.methodName, testAccount.addr.toString()) const contract = ctx.contract.create(LocalStateContract) contract.opt_in() const result = contract[data.methodName as keyof LocalStateContract](Account(defaultSenderAccountAddress)) as ARC4Encoded data.assert(result, avmResult) }) }) + const tryOptIn = async (client: AppClient) => { try { await client.send.call({ method: 'opt_in', args: [], onComplete: OnApplicationComplete.OptInOC }) diff --git a/tests/log.spec.ts b/tests/log.spec.ts index 425cf24..7284313 100644 --- a/tests/log.spec.ts +++ b/tests/log.spec.ts @@ -1,4 +1,3 @@ -import { AppSpec } from '@algorandfoundation/algokit-utils/types/app-spec' import { Bytes, log, Uint64 } from '@algorandfoundation/algorand-typescript' import { TestExecutionContext } from '@algorandfoundation/algorand-typescript-testing' import { @@ -14,23 +13,28 @@ import { UintN64, UintN8, } from '@algorandfoundation/algorand-typescript/arc4' -import { afterEach, describe, expect, it } from 'vitest' +import { afterEach, beforeAll, describe, expect } from 'vitest' import { MAX_UINT512, MAX_UINT64 } from '../src/constants' -import { ApplicationTransaction } from '../src/impl/transactions' +import type { ApplicationTransaction } from '../src/impl/transactions' import { asBigUint, asBigUintCls, asUint8Array } from '../src/util' import { PrimitiveOpsContract } from './artifacts/primitive-ops/contract.algo' -import appSpecJson from './artifacts/primitive-ops/data/PrimitiveOpsContract.arc32.json' -import { getAlgorandAppClient, getAvmResultLog } from './avm-invoker' +import { getAvmResultLog } from './avm-invoker' +import { createArc4TestFixture } from './test-fixture' describe('log', async () => { - const appClient = await getAlgorandAppClient(appSpecJson as AppSpec) + const [test, localnetFixture] = createArc4TestFixture('tests/artifacts/primitive-ops/contract.algo.ts', { + PrimitiveOpsContract: { deployParams: { createParams: { extraProgramPages: undefined } } }, + }) const ctx = new TestExecutionContext() - afterEach(async () => { + beforeAll(async () => { + await localnetFixture.newScope() + }) + afterEach(() => { ctx.reset() }) - it('should log different data types', async () => { + test('should log different data types', async ({ appClientPrimitiveOpsContract: appClient }) => { const a = 'hello' const b = Uint64(MAX_UINT64) const c = Bytes('world') diff --git a/tests/match.spec.ts b/tests/match.spec.ts index aa04660..901d2a8 100644 --- a/tests/match.spec.ts +++ b/tests/match.spec.ts @@ -1,4 +1,5 @@ -import { assertMatch, biguint, BigUint, Bytes, match, Uint64 } from '@algorandfoundation/algorand-typescript' +import type { biguint } from '@algorandfoundation/algorand-typescript' +import { assertMatch, BigUint, Bytes, match, Uint64 } from '@algorandfoundation/algorand-typescript' import { TestExecutionContext } from '@algorandfoundation/algorand-typescript-testing' import { afterEach, describe, expect, test } from 'vitest' import { MAX_UINT512, MAX_UINT64 } from '../src/constants' @@ -6,7 +7,7 @@ import { StrImpl } from '../src/impl/encoded-types' describe('match', () => { const ctx = new TestExecutionContext() - afterEach(async () => { + afterEach(() => { ctx.reset() }) diff --git a/tests/multi-inheritance.spec.ts b/tests/multi-inheritance.spec.ts new file mode 100644 index 0000000..186d485 --- /dev/null +++ b/tests/multi-inheritance.spec.ts @@ -0,0 +1,48 @@ +import { TestExecutionContext } from '@algorandfoundation/algorand-typescript-testing' +import { afterEach } from 'node:test' +import { beforeAll, describe, expect } from 'vitest' +import { MultiBases } from './artifacts/multi-inheritance/contract.algo' +import { getAvmResult } from './avm-invoker' +import { createArc4TestFixture } from './test-fixture' + +describe('multi-inheritance', async () => { + const [test, localnetFixture] = createArc4TestFixture('tests/artifacts/multi-inheritance/contract.algo.ts', { MultiBases: {} }) + const ctx = new TestExecutionContext() + + beforeAll(async () => { + await localnetFixture.newScope() + }) + afterEach(() => ctx.reset()) + + test('should be able to call methods from super classes', async ({ appClientMultiBases: appClient }) => { + const contract = ctx.contract.create(MultiBases) + + const avmMethod1Result = await getAvmResult({ appClient }, 'methodOne') + const avmMethod2Result = await getAvmResult({ appClient }, 'methodTwo') + const avmMethodMultiResult = await getAvmResult({ appClient }, 'methodMulti') + const avmMethodCallsSuperResult = await getAvmResult({ appClient }, 'methodCallsSuper') + const avmCallB2CantOverrideResult = await getAvmResult({ appClient }, 'callB2CantOverride') + const avmCallB2CommonResult = await getAvmResult({ appClient }, 'callB2Common') + + const method1Result = contract.methodOne() + const method2Result = contract.methodTwo() + const methodMultiResult = contract.methodMulti() + const methodCallsSuperResult = contract.methodCallsSuper() + const callB2CantOverrideResult = contract.callB2CantOverride() + const callB2CommonResult = contract.callB2Common() + + expect(method1Result).toEqual('base-one') + expect(method2Result).toEqual('base-two') + expect(methodMultiResult).toEqual('multi-bases') + expect(methodCallsSuperResult).toEqual('base-two') + expect(callB2CantOverrideResult).toEqual('base-two') + expect(callB2CommonResult).toEqual('common') + + expect(method1Result).toEqual(avmMethod1Result) + expect(method2Result).toEqual(avmMethod2Result) + expect(methodMultiResult).toEqual(avmMethodMultiResult) + expect(methodCallsSuperResult).toEqual(avmMethodCallsSuperResult) + expect(callB2CantOverrideResult).toEqual(avmCallB2CantOverrideResult) + expect(callB2CommonResult).toEqual(avmCallB2CommonResult) + }) +}) diff --git a/tests/mutable-array.spec.ts b/tests/mutable-array.spec.ts new file mode 100644 index 0000000..543fb6a --- /dev/null +++ b/tests/mutable-array.spec.ts @@ -0,0 +1,119 @@ +import type { uint64 } from '@algorandfoundation/algorand-typescript' +import { describe, expect, it } from 'vitest' +import { MutableArray } from '../src/impl' +import { Uint64 } from '../src/impl/primitives' + +describe('MutableArray', () => { + describe('constructor', () => { + it('creates empty array when no arguments provided', () => { + const arr = new MutableArray() + expect(arr.length).toEqual(0) + }) + + it('creates array with initial values', () => { + const arr = new MutableArray(Uint64(1), Uint64(2), Uint64(3)) + expect(arr.length).toEqual(3) + expect(arr[0]).toEqual(1) + expect(arr[1]).toEqual(2) + expect(arr[2]).toEqual(3) + }) + }) + + describe('index access', () => { + it('throws on out of bounds access', () => { + const arr = new MutableArray(1, 2) + expect(() => arr[2]).toThrow('Index out of bounds') + expect(() => arr[-1]).toThrow('Index out of bounds') + }) + + it('allows setting values by index', () => { + const arr = new MutableArray(1, 2) + const index = Uint64(0) + arr[index] = 10 + expect(arr[index]).toEqual(10) + }) + }) + + describe('at()', () => { + it('returns value at positive index', () => { + const arr = new MutableArray(1, 2, 3) + expect(arr.at(Uint64(1))).toEqual(2) + }) + + it('returns value at negative index', () => { + const arr = new MutableArray(1, 2, 3) + expect(() => arr.at(-1)).toThrow('Uint64 overflow or underflow') + }) + }) + + describe('slice()', () => { + it('returns full copy with no arguments', () => { + const arr = new MutableArray(1, 2, 3) + const sliced = arr.slice() + expect([...sliced]).toEqual([1, 2, 3]) + }) + + it('slices with end index', () => { + const arr = new MutableArray(1, 2, 3) + const sliced = arr.slice(Uint64(2)) + expect([...sliced]).toEqual([1, 2]) + }) + + it('slices with start and end index', () => { + const arr = new MutableArray(1, 2, 3, 4) + const sliced = arr.slice(Uint64(1), Uint64(3)) + expect([...sliced]).toEqual([2, 3]) + }) + }) + + describe('push() and pop()', () => { + it('pushes items to end of array', () => { + const arr = new MutableArray(1) + arr.push(2, 3) + expect([...arr]).toEqual([1, 2, 3]) + }) + + it('pops item from end of array', () => { + const arr = new MutableArray(1, 2, 3) + const popped = arr.pop() + expect(popped).toEqual(3) + expect([...arr]).toEqual([1, 2]) + }) + }) + + describe('iteration', () => { + it('supports for...of iteration', () => { + const arr = new MutableArray(1, 2, 3) + const result: number[] = [] + for (const item of arr) { + result.push(item) + } + expect(result).toEqual([1, 2, 3]) + }) + + it('provides entries() iterator', () => { + const arr = new MutableArray('a', 'b') + const entries = [...arr.entries()] + expect(entries).toEqual([ + [0, 'a'], + [1, 'b'], + ]) + }) + + it('provides keys() iterator', () => { + const arr = new MutableArray('a', 'b') + const keys = [...arr.keys()] + expect(keys).toEqual([0, 1]) + }) + }) + + describe('copy()', () => { + it('creates a deep copy', () => { + const original = new MutableArray(1, 2, 3) + const copy = original.copy() + copy[0] = 10 + expect(original[0]).toEqual(1) + expect(copy[0]).toEqual(10) + }) + }) +}) diff --git a/tests/primitives/biguint.spec.ts b/tests/primitives/biguint.spec.ts index 28031e8..7ec5562 100644 --- a/tests/primitives/biguint.spec.ts +++ b/tests/primitives/biguint.spec.ts @@ -1,16 +1,23 @@ // noinspection SuspiciousTypeOfGuard -import type { AppSpec } from '@algorandfoundation/algokit-utils/types/app-spec' import type { biguint } from '@algorandfoundation/algorand-typescript' -import { BigUint, Bytes, internal, Uint64 } from '@algorandfoundation/algorand-typescript' -import { describe, expect, it } from 'vitest' +import { BigUint, Bytes, Uint64 } from '@algorandfoundation/algorand-typescript' +import { encodingUtil } from '@algorandfoundation/puya-ts' +import { beforeAll, describe, expect } from 'vitest' import { BIGUINT_OVERFLOW_UNDERFLOW_MESSAGE, MAX_UINT512, MAX_UINT64 } from '../../src/constants' + +import { BigUintCls } from '../../src/impl/primitives' import { asBigUint, asUint64 } from '../../src/util' -import appSpecJson from '../artifacts/primitive-ops/data/PrimitiveOpsContract.arc32.json' -import { getAlgorandAppClient, getAvmResult, getAvmResultRaw } from '../avm-invoker' +import { getAvmResult, getAvmResultRaw } from '../avm-invoker' +import { createArc4TestFixture } from '../test-fixture' describe('BigUint', async () => { - const appClient = await getAlgorandAppClient(appSpecJson as AppSpec) + const [test, localnetFixture] = createArc4TestFixture('tests/artifacts/primitive-ops/contract.algo.ts', { + PrimitiveOpsContract: { deployParams: { createParams: { extraProgramPages: undefined } } }, + }) + beforeAll(async () => { + await localnetFixture.newScope() + }) describe.each(['eq', 'ne', 'lt', 'le', 'gt', 'ge'])('logical operators', async (op) => { const operator = (function () { @@ -61,10 +68,10 @@ describe('BigUint', async () => { ])(`${operator}`, async (a, b) => { const bigUintA = asBigUint(a) const bigUintB = asBigUint(b) - const bytesA = internal.encodingUtil.bigIntToUint8Array(bigUintA.valueOf()) - const bytesB = internal.encodingUtil.bigIntToUint8Array(bigUintB.valueOf()) + const bytesA = encodingUtil.bigIntToUint8Array(bigUintA.valueOf()) + const bytesB = encodingUtil.bigIntToUint8Array(bigUintB.valueOf()) - it(`${a} ${operator} ${b}`, async () => { + test(`${a} ${operator} ${b}`, async ({ appClientPrimitiveOpsContract: appClient }) => { const avmResult = await getAvmResult({ appClient }, `verify_biguint_${op}`, bytesA, bytesB) let result = getStubResult(bigUintA, bigUintB) expect(result, `for values: ${a}, ${b}`).toBe(avmResult) @@ -87,16 +94,16 @@ describe('BigUint', async () => { [1, MAX_UINT512], [MAX_UINT512, MAX_UINT512], ])(`${operator} using bytes`, async (a, b) => { - const bytesA = internal.encodingUtil.bigIntToUint8Array(BigInt(a)) - const bytesB = internal.encodingUtil.bigIntToUint8Array(BigInt(b)) - const paddedBytesA = internal.encodingUtil.bigIntToUint8Array(BigInt(a), 64) - const paddedBytesB = internal.encodingUtil.bigIntToUint8Array(BigInt(b), 64) + const bytesA = encodingUtil.bigIntToUint8Array(BigInt(a)) + const bytesB = encodingUtil.bigIntToUint8Array(BigInt(b)) + const paddedBytesA = encodingUtil.bigIntToUint8Array(BigInt(a), 64) + const paddedBytesB = encodingUtil.bigIntToUint8Array(BigInt(b), 64) const bigUintA = BigUint(Bytes(bytesA)) const bigUintB = BigUint(Bytes(bytesB)) const paddedBigUintA = BigUint(Bytes(paddedBytesA)) const paddedBigUintB = BigUint(Bytes(paddedBytesB)) - it(`${a} ${operator} ${b}`, async () => { + test(`${a} ${operator} ${b}`, async ({ appClientPrimitiveOpsContract: appClient }) => { let avmResult = await getAvmResult({ appClient }, `verify_biguint_${op}`, bytesA, paddedBytesB) let result = getStubResult(bigUintA, paddedBigUintB) expect(result, `for padded b: ${a}, ${b}`).toBe(avmResult) @@ -121,10 +128,10 @@ describe('BigUint', async () => { [MAX_UINT512, MAX_UINT64], ])(`${operator} with uint64`, async (a, b) => { const bigUintA = asBigUint(a) - const bytesA = internal.encodingUtil.bigIntToUint8Array(bigUintA.valueOf()) + const bytesA = encodingUtil.bigIntToUint8Array(bigUintA.valueOf()) const uintB = typeof b === 'bigint' ? Uint64(b) : Uint64(b) - it(`${a} ${operator} ${b}`, async () => { + test(`${a} ${operator} ${b}`, async ({ appClientPrimitiveOpsContract: appClient }) => { const avmResult = await getAvmResult({ appClient }, `verify_biguint_${op}_uint64`, bytesA, b) const result = getStubResult(bigUintA, uintB) expect(result, `for values: ${a}, ${b}`).toBe(avmResult) @@ -138,12 +145,12 @@ describe('BigUint', async () => { [MAX_UINT512, MAX_UINT512 + 1n], [MAX_UINT512 + 1n, MAX_UINT512 + 1n], ])(`${operator} with overflowing input`, async (a, b) => { - const bytesA = internal.encodingUtil.bigIntToUint8Array(BigInt(a)) - const bytesB = internal.encodingUtil.bigIntToUint8Array(BigInt(b)) + const bytesA = encodingUtil.bigIntToUint8Array(BigInt(a)) + const bytesB = encodingUtil.bigIntToUint8Array(BigInt(b)) const bigUintA = BigUint(Bytes(bytesA)) const bigUintB = BigUint(Bytes(bytesB)) - it(`${a} ${operator} ${b}`, async () => { + test(`${a} ${operator} ${b}`, async ({ appClientPrimitiveOpsContract: appClient }) => { await expect(getAvmResult({ appClient }, `verify_biguint_${op}`, bytesA, bytesB)).rejects.toThrow( 'math attempted on large byte-array', ) @@ -167,11 +174,11 @@ describe('BigUint', async () => { [1n, MAX_UINT512 - 1n], [MAX_UINT512 - 1n, 1n], ])('addition', async (a, b) => { - it(`${a} + ${b}`, async () => { + test(`${a} + ${b}`, async ({ appClientPrimitiveOpsContract: appClient }) => { const bigUintA = BigUint(a) const bigUintB = BigUint(b) - const bytesA = internal.encodingUtil.bigIntToUint8Array(bigUintA.valueOf()) - const bytesB = internal.encodingUtil.bigIntToUint8Array(bigUintB.valueOf()) + const bytesA = encodingUtil.bigIntToUint8Array(bigUintA.valueOf()) + const bytesB = encodingUtil.bigIntToUint8Array(bigUintB.valueOf()) const avmResult = asBigUint(await getAvmResult({ appClient }, 'verify_biguint_add', bytesA, bytesB)) @@ -191,11 +198,11 @@ describe('BigUint', async () => { [1n, MAX_UINT512], [MAX_UINT512, MAX_UINT512], ])('addition result overflow', async (a, b) => { - it(`${a} + ${b}`, async () => { + test(`${a} + ${b}`, async ({ appClientPrimitiveOpsContract: appClient }) => { const bigUintA = BigUint(a) const bigUintB = BigUint(b) - const bytesA = internal.encodingUtil.bigIntToUint8Array(bigUintA.valueOf()) - const bytesB = internal.encodingUtil.bigIntToUint8Array(bigUintB.valueOf()) + const bytesA = encodingUtil.bigIntToUint8Array(bigUintA.valueOf()) + const bytesB = encodingUtil.bigIntToUint8Array(bigUintB.valueOf()) const avmResult = asBigUint(await getAvmResult({ appClient }, 'verify_biguint_add', bytesA, bytesB)) @@ -215,12 +222,12 @@ describe('BigUint', async () => { [1, MAX_UINT512 + 1n], [MAX_UINT512 + 1n, MAX_UINT512 + 1n], ])('addition with overflowing input', async (a, b) => { - const bytesA = internal.encodingUtil.bigIntToUint8Array(BigInt(a)) - const bytesB = internal.encodingUtil.bigIntToUint8Array(BigInt(b)) + const bytesA = encodingUtil.bigIntToUint8Array(BigInt(a)) + const bytesB = encodingUtil.bigIntToUint8Array(BigInt(b)) const bigUintA = BigUint(Bytes(bytesA)) const bigUintB = BigUint(Bytes(bytesB)) - it(`${a} + ${b}`, async () => { + test(`${a} + ${b}`, async ({ appClientPrimitiveOpsContract: appClient }) => { await expect(getAvmResultRaw({ appClient }, 'verify_biguint_add', bytesA, bytesB)).rejects.toThrow( 'math attempted on large byte-array', ) @@ -246,10 +253,10 @@ describe('BigUint', async () => { [10n, MAX_UINT64], [MAX_UINT512 - MAX_UINT64, MAX_UINT64], ])('biguint addition with uint64', async (a, b) => { - it(`${a} + ${b}`, async () => { + test(`${a} + ${b}`, async ({ appClientPrimitiveOpsContract: appClient }) => { const bigUintA = BigUint(a) const uint64B = Uint64(b) - const bytesA = internal.encodingUtil.bigIntToUint8Array(bigUintA.valueOf()) + const bytesA = encodingUtil.bigIntToUint8Array(bigUintA.valueOf()) const avmResult = asBigUint(await getAvmResult({ appClient }, 'verify_biguint_add_uint64', bytesA, b)) @@ -274,11 +281,11 @@ describe('BigUint', async () => { [MAX_UINT512, 1n], [MAX_UINT512, MAX_UINT512], ])('subtraction', async (a, b) => { - it(`${a} - ${b}`, async () => { + test(`${a} - ${b}`, async ({ appClientPrimitiveOpsContract: appClient }) => { const bigUintA = BigUint(a) const bigUintB = BigUint(b) - const bytesA = internal.encodingUtil.bigIntToUint8Array(bigUintA.valueOf()) - const bytesB = internal.encodingUtil.bigIntToUint8Array(bigUintB.valueOf()) + const bytesA = encodingUtil.bigIntToUint8Array(bigUintA.valueOf()) + const bytesB = encodingUtil.bigIntToUint8Array(bigUintB.valueOf()) const avmResult = asBigUint(await getAvmResult({ appClient }, 'verify_biguint_sub', bytesA, bytesB)) @@ -300,11 +307,11 @@ describe('BigUint', async () => { [0n, MAX_UINT512], [1n, MAX_UINT512], ])(`subtraction result underflow`, async (a, b) => { - it(`${a} - ${b}`, async () => { + test(`${a} - ${b}`, async ({ appClientPrimitiveOpsContract: appClient }) => { const bigUintA = asBigUint(a) const bigUintB = asBigUint(b) - const bytesA = internal.encodingUtil.bigIntToUint8Array(bigUintA.valueOf()) - const bytesB = internal.encodingUtil.bigIntToUint8Array(bigUintB.valueOf()) + const bytesA = encodingUtil.bigIntToUint8Array(bigUintA.valueOf()) + const bytesB = encodingUtil.bigIntToUint8Array(bigUintB.valueOf()) await expect(getAvmResultRaw({ appClient }, 'verify_biguint_sub', bytesA, bytesB)).rejects.toThrow('math would have negative result') expect(() => bigUintA - bigUintB).toThrow('BigUint underflow') @@ -320,12 +327,12 @@ describe('BigUint', async () => { [1n, MAX_UINT512 + 1n], [MAX_UINT512 + 1n, MAX_UINT512 + 1n], ])(`subtraction with overflowing input`, async (a, b) => { - const bytesA = internal.encodingUtil.bigIntToUint8Array(a) - const bytesB = internal.encodingUtil.bigIntToUint8Array(b) + const bytesA = encodingUtil.bigIntToUint8Array(a) + const bytesB = encodingUtil.bigIntToUint8Array(b) const bigUintA = BigUint(Bytes(bytesA)) const bigUintB = BigUint(Bytes(bytesB)) - it(`${a} - ${b}`, async () => { + test(`${a} - ${b}`, async ({ appClientPrimitiveOpsContract: appClient }) => { await expect(getAvmResultRaw({ appClient }, 'verify_biguint_sub', bytesA, bytesB)).rejects.toThrow( 'math attempted on large byte-array', ) @@ -345,10 +352,10 @@ describe('BigUint', async () => { [MAX_UINT512, 1n], [MAX_UINT512, MAX_UINT64], ])('biguint subtraction with uint64', async (a, b) => { - it(`${a} - ${b}`, async () => { + test(`${a} - ${b}`, async ({ appClientPrimitiveOpsContract: appClient }) => { const bigUintA = BigUint(a) const uint64B = Uint64(b) - const bytesA = internal.encodingUtil.bigIntToUint8Array(bigUintA.valueOf()) + const bytesA = encodingUtil.bigIntToUint8Array(bigUintA.valueOf()) const avmResult = asBigUint(await getAvmResult({ appClient }, 'verify_biguint_sub_uint64', bytesA, b)) @@ -369,11 +376,11 @@ describe('BigUint', async () => { [MAX_UINT64, MAX_UINT64], [2, 2], ])(`multiplication`, async (a, b) => { - it(`${a} * ${b}`, async () => { + test(`${a} * ${b}`, async ({ appClientPrimitiveOpsContract: appClient }) => { const bigUintA = asBigUint(a) const bigUintB = asBigUint(b) - const bytesA = internal.encodingUtil.bigIntToUint8Array(bigUintA.valueOf()) - const bytesB = internal.encodingUtil.bigIntToUint8Array(bigUintB.valueOf()) + const bytesA = encodingUtil.bigIntToUint8Array(bigUintA.valueOf()) + const bytesB = encodingUtil.bigIntToUint8Array(bigUintB.valueOf()) const avmResult = asBigUint(await getAvmResult({ appClient }, 'verify_biguint_mul', bytesA, bytesB)) @@ -397,11 +404,11 @@ describe('BigUint', async () => { [MAX_UINT512, MAX_UINT512], [MAX_UINT512 / 2n, 3], ])(`multiplication result overflow`, async (a, b) => { - it(`${a} * ${b}`, async () => { + test(`${a} * ${b}`, async ({ appClientPrimitiveOpsContract: appClient }) => { const bigUintA = asBigUint(a) const bigUintB = asBigUint(b) - const bytesA = internal.encodingUtil.bigIntToUint8Array(bigUintA.valueOf()) - const bytesB = internal.encodingUtil.bigIntToUint8Array(bigUintB.valueOf()) + const bytesA = encodingUtil.bigIntToUint8Array(bigUintA.valueOf()) + const bytesB = encodingUtil.bigIntToUint8Array(bigUintB.valueOf()) const avmResult = asBigUint(await getAvmResult({ appClient }, 'verify_biguint_mul', bytesA, bytesB)) @@ -425,9 +432,9 @@ describe('BigUint', async () => { [2, MAX_UINT512 + 1n], [MAX_UINT512 + 1n, MAX_UINT512 + 1n], ])(`multiplication with overflowing input`, async (a, b) => { - it(`${a} * ${b}`, async () => { - const bytesA = internal.encodingUtil.bigIntToUint8Array(BigInt(a)) - const bytesB = internal.encodingUtil.bigIntToUint8Array(BigInt(b)) + test(`${a} * ${b}`, async ({ appClientPrimitiveOpsContract: appClient }) => { + const bytesA = encodingUtil.bigIntToUint8Array(BigInt(a)) + const bytesB = encodingUtil.bigIntToUint8Array(BigInt(b)) const bigUintA = BigUint(Bytes(bytesA)) const bigUintB = BigUint(Bytes(bytesB)) @@ -453,10 +460,10 @@ describe('BigUint', async () => { [1n, MAX_UINT64], [2n, MAX_UINT64], ])(`biguint multiplication with uint64`, async (a, b) => { - it(`${a} * ${b}`, async () => { + test(`${a} * ${b}`, async ({ appClientPrimitiveOpsContract: appClient }) => { const bigUintA = asBigUint(a) const uint64B = asUint64(b) - const bytesA = internal.encodingUtil.bigIntToUint8Array(bigUintA.valueOf()) + const bytesA = encodingUtil.bigIntToUint8Array(bigUintA.valueOf()) const avmResult = asBigUint(await getAvmResult({ appClient }, 'verify_biguint_mul_uint64', bytesA, b)) @@ -480,11 +487,11 @@ describe('BigUint', async () => { [1, MAX_UINT512], [3, 2], ])(`division`, async (a, b) => { - it(`${a} / ${b}`, async () => { + test(`${a} / ${b}`, async ({ appClientPrimitiveOpsContract: appClient }) => { const bigUintA = asBigUint(a) const bigUintB = asBigUint(b) - const bytesA = internal.encodingUtil.bigIntToUint8Array(bigUintA.valueOf()) - const bytesB = internal.encodingUtil.bigIntToUint8Array(bigUintB.valueOf()) + const bytesA = encodingUtil.bigIntToUint8Array(bigUintA.valueOf()) + const bytesB = encodingUtil.bigIntToUint8Array(bigUintB.valueOf()) const avmResult = asBigUint(await getAvmResult({ appClient }, 'verify_biguint_div', bytesA, bytesB)) @@ -504,11 +511,11 @@ describe('BigUint', async () => { }) describe.each([0, 1, MAX_UINT512])(`division by zero`, async (a) => { - it(`${a} / 0`, async () => { + test(`${a} / 0`, async ({ appClientPrimitiveOpsContract: appClient }) => { const bigUintA = asBigUint(a) const bigUintB = asBigUint(0) - const bytesA = internal.encodingUtil.bigIntToUint8Array(bigUintA.valueOf()) - const bytesB = internal.encodingUtil.bigIntToUint8Array(0n) + const bytesA = encodingUtil.bigIntToUint8Array(bigUintA.valueOf()) + const bytesB = encodingUtil.bigIntToUint8Array(0n) await expect(getAvmResultRaw({ appClient }, 'verify_biguint_div', bytesA, bytesB)).rejects.toThrow('division by zero') expect(() => bigUintA / bigUintB).toThrow('Division by zero') @@ -525,9 +532,9 @@ describe('BigUint', async () => { [2, MAX_UINT512 + 1n], [MAX_UINT512 + 1n, MAX_UINT512 + 1n], ])(`division with overflowing input`, async (a, b) => { - it(`${a} / ${b}`, async () => { - const bytesA = internal.encodingUtil.bigIntToUint8Array(BigInt(a)) - const bytesB = internal.encodingUtil.bigIntToUint8Array(BigInt(b)) + test(`${a} / ${b}`, async ({ appClientPrimitiveOpsContract: appClient }) => { + const bytesA = encodingUtil.bigIntToUint8Array(BigInt(a)) + const bytesB = encodingUtil.bigIntToUint8Array(BigInt(b)) const bigUintA = BigUint(Bytes(bytesA)) const bigUintB = BigUint(Bytes(bytesB)) @@ -554,10 +561,10 @@ describe('BigUint', async () => { [1n, MAX_UINT64], [3n, 2n], ])('biguint division with uint64', async (a, b) => { - it(`${a} / ${b}`, async () => { + test(`${a} / ${b}`, async ({ appClientPrimitiveOpsContract: appClient }) => { const bigUintA = asBigUint(a) const uint64B = asUint64(b) - const bytesA = internal.encodingUtil.bigIntToUint8Array(bigUintA.valueOf()) + const bytesA = encodingUtil.bigIntToUint8Array(bigUintA.valueOf()) const avmResult = asBigUint(await getAvmResult({ appClient }, 'verify_biguint_div_uint64', bytesA, b)) @@ -578,11 +585,11 @@ describe('BigUint', async () => { [1, MAX_UINT512], [3, 2], ])(`modulo`, async (a, b) => { - it(`${a} % ${b}`, async () => { + test(`${a} % ${b}`, async ({ appClientPrimitiveOpsContract: appClient }) => { const bigUintA = asBigUint(a) const bigUintB = asBigUint(b) - const bytesA = internal.encodingUtil.bigIntToUint8Array(bigUintA.valueOf()) - const bytesB = internal.encodingUtil.bigIntToUint8Array(bigUintB.valueOf()) + const bytesA = encodingUtil.bigIntToUint8Array(bigUintA.valueOf()) + const bytesB = encodingUtil.bigIntToUint8Array(bigUintB.valueOf()) const avmResult = asBigUint(await getAvmResult({ appClient }, 'verify_biguint_mod', bytesA, bytesB)) let result = bigUintA % bigUintB @@ -601,11 +608,11 @@ describe('BigUint', async () => { }) describe.each([0, 1, MAX_UINT512])(`modulo by zero`, async (a) => { - it(`${a} % 0`, async () => { + test(`${a} % 0`, async ({ appClientPrimitiveOpsContract: appClient }) => { const bigUintA = asBigUint(a) const bigUintB = asBigUint(0) - const bytesA = internal.encodingUtil.bigIntToUint8Array(bigUintA.valueOf()) - const bytesB = internal.encodingUtil.bigIntToUint8Array(0n) + const bytesA = encodingUtil.bigIntToUint8Array(bigUintA.valueOf()) + const bytesB = encodingUtil.bigIntToUint8Array(0n) await expect(getAvmResultRaw({ appClient }, 'verify_biguint_mod', bytesA, bytesB)).rejects.toThrow('modulo by zero') expect(() => bigUintA % bigUintB).toThrow('Division by zero') @@ -622,9 +629,9 @@ describe('BigUint', async () => { [2, MAX_UINT512 + 1n], [MAX_UINT512 + 1n, MAX_UINT512 + 1n], ])(`modulo with overflowing input`, async (a, b) => { - it(`${a} % ${b}`, async () => { - const bytesA = internal.encodingUtil.bigIntToUint8Array(BigInt(a)) - const bytesB = internal.encodingUtil.bigIntToUint8Array(BigInt(b)) + test(`${a} % ${b}`, async ({ appClientPrimitiveOpsContract: appClient }) => { + const bytesA = encodingUtil.bigIntToUint8Array(BigInt(a)) + const bytesB = encodingUtil.bigIntToUint8Array(BigInt(b)) const bigUintA = BigUint(Bytes(bytesA)) const bigUintB = BigUint(Bytes(bytesB)) @@ -651,10 +658,10 @@ describe('BigUint', async () => { [1n, MAX_UINT64], [3n, 2n], ])('biguint modulo with uint64', async (a, b) => { - it(`${a} % ${b}`, async () => { + test(`${a} % ${b}`, async ({ appClientPrimitiveOpsContract: appClient }) => { const bigUintA = asBigUint(a) const uint64B = asUint64(b) - const bytesA = internal.encodingUtil.bigIntToUint8Array(bigUintA.valueOf()) + const bytesA = encodingUtil.bigIntToUint8Array(bigUintA.valueOf()) const avmResult = asBigUint(await getAvmResult({ appClient }, 'verify_biguint_mod_uint64', bytesA, b)) const result = bigUintA % BigUint(uint64B) @@ -701,10 +708,10 @@ describe('BigUint', async () => { ])(`${operator}`, async (a, b) => { const bigUintA = asBigUint(a) const bigUintB = asBigUint(b) - const bytesA = internal.encodingUtil.bigIntToUint8Array(bigUintA.valueOf()) - const bytesB = internal.encodingUtil.bigIntToUint8Array(bigUintB.valueOf()) + const bytesA = encodingUtil.bigIntToUint8Array(bigUintA.valueOf()) + const bytesB = encodingUtil.bigIntToUint8Array(bigUintB.valueOf()) - it(`${a} ${operator} ${b}`, async () => { + test(`${a} ${operator} ${b}`, async ({ appClientPrimitiveOpsContract: appClient }) => { const avmResult = asBigUint(await getAvmResult({ appClient }, `verify_biguint_${op}`, bytesA, bytesB)) let result = getStubResult(bigUintA, bigUintB) expect(result, `for values: ${a}, ${b}`).toEqual(avmResult) @@ -730,9 +737,9 @@ describe('BigUint', async () => { ])(`${operator} with uint64`, async (a, b) => { const bigUintA = asBigUint(a) const uint64B = asUint64(b) - const bytesA = internal.encodingUtil.bigIntToUint8Array(bigUintA.valueOf()) + const bytesA = encodingUtil.bigIntToUint8Array(bigUintA.valueOf()) - it(`${a} ${operator} ${b}`, async () => { + test(`${a} ${operator} ${b}`, async ({ appClientPrimitiveOpsContract: appClient }) => { const avmResult = asBigUint(await getAvmResult({ appClient }, `verify_biguint_${op}_uint64`, bytesA, b)) const result = getStubResult(bigUintA, BigUint(uint64B)) expect(result, `for values: ${a}, ${b}`).toEqual(avmResult) @@ -741,14 +748,14 @@ describe('BigUint', async () => { }) describe.each([MAX_UINT512 + 1n, MAX_UINT512 * 2n])('value too big', (a) => { - it(`${a}`, () => { + test(`${a}`, () => { const bigUintA = asBigUint(a) expect(() => bigUintA === a).toThrow(BIGUINT_OVERFLOW_UNDERFLOW_MESSAGE) }) }) describe.each([-1, -MAX_UINT512, -MAX_UINT512 * 2n])('value too small', (a) => { - it(`${a}`, () => { + test(`${a}`, () => { const bigUintA = asBigUint(a) expect(() => bigUintA === asBigUint(a)).toThrow(BIGUINT_OVERFLOW_UNDERFLOW_MESSAGE) }) @@ -767,8 +774,8 @@ describe('BigUint', async () => { [MAX_UINT512 * 2n, MAX_UINT512 * 2n], [Bytes('hello'), 448378203247n], ])('fromCompat', async (a, b) => { - it(`${a}`, async () => { - const result = internal.primitives.BigUintCls.fromCompat(a) + test(`${a}`, async () => { + const result = BigUintCls.fromCompat(a) expect(result, `for value: ${a}`).toEqual(b) }) }) diff --git a/tests/primitives/bytes.spec.ts b/tests/primitives/bytes.spec.ts index edcee19..533044a 100644 --- a/tests/primitives/bytes.spec.ts +++ b/tests/primitives/bytes.spec.ts @@ -1,15 +1,24 @@ -import { AppSpec } from '@algorandfoundation/algokit-utils/types/app-spec' -import { bytes, Bytes, internal } from '@algorandfoundation/algorand-typescript' -import { describe, expect, it } from 'vitest' +import type { bytes } from '@algorandfoundation/algorand-typescript' +import { Bytes } from '@algorandfoundation/algorand-typescript' +import { encodingUtil } from '@algorandfoundation/puya-ts' +import { beforeAll, describe, expect } from 'vitest' import { MAX_BYTES_SIZE } from '../../src/constants' + import { sha256 } from '../../src/impl' +import { BytesCls } from '../../src/impl/primitives' import { asUint8Array } from '../../src/util' -import appSpecJson from '../artifacts/primitive-ops/data/PrimitiveOpsContract.arc32.json' -import { getAlgorandAppClient, getAvmResult, getAvmResultRaw } from '../avm-invoker' +import { getAvmResult, getAvmResultRaw } from '../avm-invoker' +import { createArc4TestFixture } from '../test-fixture' import { getSha256Hash, padUint8Array } from '../util' describe('Bytes', async () => { - const appClient = await getAlgorandAppClient(appSpecJson as AppSpec) + const [test, localnetFixture] = createArc4TestFixture('tests/artifacts/primitive-ops/contract.algo.ts', { + PrimitiveOpsContract: { deployParams: { createParams: { extraProgramPages: undefined } } }, + }) + + beforeAll(async () => { + await localnetFixture.newScope() + }) describe.each([ ['', '', 0, 0], @@ -21,9 +30,9 @@ describe('Bytes', async () => { ['1', '0', 0, MAX_BYTES_SIZE - 2], ['1', '0', MAX_BYTES_SIZE - 2, 0], ])('concat', async (a, b, padASize, padBSize) => { - it(`${a} concat ${b}`, async () => { - const uint8ArrayA = internal.encodingUtil.utf8ToUint8Array(a) - const uint8ArrayB = internal.encodingUtil.utf8ToUint8Array(b) + test(`${a} concat ${b}`, async ({ appClientPrimitiveOpsContract: appClient }) => { + const uint8ArrayA = encodingUtil.utf8ToUint8Array(a) + const uint8ArrayB = encodingUtil.utf8ToUint8Array(b) const avmResult = (await getAvmResult({ appClient }, `verify_bytes_add`, uint8ArrayA, uint8ArrayB, padASize, padBSize))! const bytesA = Bytes(padUint8Array(uint8ArrayA, padASize)) @@ -39,9 +48,9 @@ describe('Bytes', async () => { ['1', '', 0, MAX_BYTES_SIZE], ['', '', MAX_BYTES_SIZE, MAX_BYTES_SIZE], ])('concat overflow', async (a, b, padASize, padBSize) => { - it(`${a} concat ${b} overflows`, async () => { - const uint8ArrayA = internal.encodingUtil.utf8ToUint8Array(a) - const uint8ArrayB = internal.encodingUtil.utf8ToUint8Array(b) + test(`${a} concat ${b} overflows`, async ({ appClientPrimitiveOpsContract: appClient }) => { + const uint8ArrayA = encodingUtil.utf8ToUint8Array(a) + const uint8ArrayB = encodingUtil.utf8ToUint8Array(b) await expect(getAvmResultRaw({ appClient }, `verify_bytes_add`, uint8ArrayA, uint8ArrayB, padASize, padBSize)).rejects.toThrow( /concat produced a too big \(\d+\) byte-array/, @@ -74,12 +83,12 @@ describe('Bytes', async () => { ['11', '001'], ['', '11'], ])(`bitwise ${op}`, async (a, b) => { - it(`${a} bitwise ${op} ${b}`, async () => { + test(`${a} bitwise ${op} ${b}`, async ({ appClientPrimitiveOpsContract: appClient }) => { const bytesA = Bytes(a) const bytesB = Bytes(b) - const uint8ArrayA = internal.encodingUtil.utf8ToUint8Array(a) - const uint8ArrayB = internal.encodingUtil.utf8ToUint8Array(b) + const uint8ArrayA = encodingUtil.utf8ToUint8Array(a) + const uint8ArrayB = encodingUtil.utf8ToUint8Array(b) const avmResult = (await getAvmResult({ appClient }, `verify_bytes_${op}`, uint8ArrayA, uint8ArrayB))! const result = getStubResult(bytesA, bytesB) expect(result, `for values: ${a}, ${b}`).toEqual(avmResult) @@ -94,8 +103,8 @@ describe('Bytes', async () => { ['11100', MAX_BYTES_SIZE - 5], ['', MAX_BYTES_SIZE], ])('bitwise invert', async (a, padSize) => { - it(`~${a}`, async () => { - const uint8ArrayA = internal.encodingUtil.utf8ToUint8Array(a) + test(`~${a}`, async ({ appClientPrimitiveOpsContract: appClient }) => { + const uint8ArrayA = encodingUtil.utf8ToUint8Array(a) const avmResult = (await getAvmResult({ appClient }, `verify_bytes_not`, uint8ArrayA, padSize))! const bytesA = Bytes(padUint8Array(uint8ArrayA, padSize)) @@ -114,11 +123,11 @@ describe('Bytes', async () => { ['11', '001'], ['', '00'], ])('equals', async (a, b) => { - it(`${a} equals ${b}`, async () => { + test(`${a} equals ${b}`, async ({ appClientPrimitiveOpsContract: appClient }) => { const bytesA = Bytes(a) const bytesB = Bytes(b) - const uint8ArrayA = internal.encodingUtil.utf8ToUint8Array(a) - const uint8ArrayB = internal.encodingUtil.utf8ToUint8Array(b) + const uint8ArrayA = encodingUtil.utf8ToUint8Array(a) + const uint8ArrayB = encodingUtil.utf8ToUint8Array(b) const avmResult = await getAvmResult({ appClient }, `verify_bytes_eq`, uint8ArrayA, uint8ArrayB) const result = bytesA.equals(bytesB) @@ -134,11 +143,11 @@ describe('Bytes', async () => { ['11', '001'], ['', '00'], ])('not equals', async (a, b) => { - it(`${a} not equals ${b}`, async () => { + test(`${a} not equals ${b}`, async ({ appClientPrimitiveOpsContract: appClient }) => { const bytesA = Bytes(a) const bytesB = Bytes(b) - const uint8ArrayA = internal.encodingUtil.utf8ToUint8Array(a) - const uint8ArrayB = internal.encodingUtil.utf8ToUint8Array(b) + const uint8ArrayA = encodingUtil.utf8ToUint8Array(a) + const uint8ArrayB = encodingUtil.utf8ToUint8Array(b) const avmResult = await getAvmResult({ appClient }, `verify_bytes_ne`, uint8ArrayA, uint8ArrayB) const result = !bytesA.equals(bytesB) @@ -147,21 +156,21 @@ describe('Bytes', async () => { }) describe('from encoded string', () => { - it('hex', () => { + test('hex', () => { const hex = 'FF' const bytes = Bytes.fromHex(hex) const resultUint8Array = asUint8Array(bytes) expect(resultUint8Array).toEqual(Uint8Array.from([0xff])) }) - it('base64', () => { + test('base64', () => { const base64 = '/w==' const bytes = Bytes.fromBase64(base64) const resultUint8Array = asUint8Array(bytes) expect(resultUint8Array).toEqual(Uint8Array.from([0xff])) }) - it('base32', () => { + test('base32', () => { const base32 = '74======' const bytes = Bytes.fromBase32(base32) const resultUint8Array = asUint8Array(bytes) @@ -170,7 +179,7 @@ describe('Bytes', async () => { }) describe.each([MAX_BYTES_SIZE + 1, MAX_BYTES_SIZE * 2])('value overflows', (size) => { - it(`${size} bytes`, () => { + test(`${size} bytes`, () => { const a = new Uint8Array(size) expect(() => Bytes(a)).toThrow(/Bytes length \d+ exceeds maximum length/) }) @@ -181,8 +190,8 @@ describe('Bytes', async () => { ['ABC', new Uint8Array([0x41, 0x42, 0x43])], [new Uint8Array([0xff, 0x00]), new Uint8Array([0xff, 0x00])], ])('fromCompat', (a, b) => { - it(`${a} fromCompat`, async () => { - const result = internal.primitives.BytesCls.fromCompat(a) + test(`${a} fromCompat`, async () => { + const result = BytesCls.fromCompat(a) expect(result.asUint8Array()).toEqual(b) }) }) diff --git a/tests/primitives/uint64.spec.ts b/tests/primitives/uint64.spec.ts index 2d56dc9..fb205e5 100644 --- a/tests/primitives/uint64.spec.ts +++ b/tests/primitives/uint64.spec.ts @@ -1,14 +1,20 @@ -import { AppSpec } from '@algorandfoundation/algokit-utils/types/app-spec' -import { internal, uint64, Uint64 } from '@algorandfoundation/algorand-typescript' -import { describe, expect, it } from 'vitest' +import type { uint64 } from '@algorandfoundation/algorand-typescript' +import { Uint64 } from '@algorandfoundation/algorand-typescript' +import { beforeAll, describe, expect } from 'vitest' import { MAX_UINT64, UINT64_OVERFLOW_UNDERFLOW_MESSAGE } from '../../src/constants' +import { Uint64Cls } from '../../src/impl/primitives' import { asUint64 } from '../../src/util' -import appSpecJson from '../artifacts/primitive-ops/data/PrimitiveOpsContract.arc32.json' -import { getAlgorandAppClient, getAvmResult } from '../avm-invoker' +import { getAvmResult } from '../avm-invoker' +import { createArc4TestFixture } from '../test-fixture' describe('Unit64', async () => { - const appClient = await getAlgorandAppClient(appSpecJson as AppSpec) + const [test, localnetFixture] = createArc4TestFixture('tests/artifacts/primitive-ops/contract.algo.ts', { + PrimitiveOpsContract: { deployParams: { createParams: { extraProgramPages: undefined } } }, + }) + beforeAll(async () => { + await localnetFixture.newScope() + }) describe.each(['eq', 'ne', 'lt', 'le', 'gt', 'ge'])('logical operators', async (op) => { const operator = (function () { switch (op) { @@ -59,7 +65,7 @@ describe('Unit64', async () => { throw new Error(`Unknown operator: ${op}`) } } - it(`${a} ${operator} ${b}`, async () => { + test(`${a} ${operator} ${b}`, async ({ appClientPrimitiveOpsContract: appClient }) => { const avmResult = await getAvmResult({ appClient }, `verify_uint64_${op}`, a, b) let result = getStubResult(uintA, uintB) expect(result, `for values: ${a}, ${b}`).toBe(avmResult) @@ -84,7 +90,7 @@ describe('Unit64', async () => { [1, MAX_UINT64 - 1n], [MAX_UINT64 - 1n, 1], ])('addition', async (a, b) => { - it(`${a} + ${b}`, async () => { + test(`${a} + ${b}`, async ({ appClientPrimitiveOpsContract: appClient }) => { const avmResult = await getAvmResult({ appClient }, 'verify_uint64_add', a, b) let result = asUint64(a) + asUint64(b) expect(result.valueOf(), `for values: ${a}, ${b}`).toBe(avmResult) @@ -106,7 +112,7 @@ describe('Unit64', async () => { [MAX_UINT64, 1], [MAX_UINT64, MAX_UINT64], ])('addition overflow', async (a, b) => { - it(`${a} + ${b}`, async () => { + test(`${a} + ${b}`, async ({ appClientPrimitiveOpsContract: appClient }) => { await expect(getAvmResult({ appClient }, 'verify_uint64_add', a, b)).rejects.toThrow('+ overflowed') expect(() => asUint64(a) + asUint64(b)).toThrow(UINT64_OVERFLOW_UNDERFLOW_MESSAGE) @@ -130,7 +136,7 @@ describe('Unit64', async () => { [MAX_UINT64, 1], [MAX_UINT64, MAX_UINT64], ])('subtraction', async (a, b) => { - it(`${a} - ${b}`, async () => { + test(`${a} - ${b}`, async ({ appClientPrimitiveOpsContract: appClient }) => { const avmResult = await getAvmResult({ appClient }, 'verify_uint64_sub', a, b) let result = asUint64(a) - asUint64(b) expect(result.valueOf(), `for values: ${a}, ${b}`).toBe(avmResult) @@ -154,7 +160,7 @@ describe('Unit64', async () => { [0, MAX_UINT64], [1, MAX_UINT64], ])('subtraction underflow', async (a, b) => { - it(`${a} - ${b}`, async () => { + test(`${a} - ${b}`, async ({ appClientPrimitiveOpsContract: appClient }) => { await expect(getAvmResult({ appClient }, 'verify_uint64_sub', a, b)).rejects.toThrow('- would result negative') expect(() => asUint64(a) - asUint64(b)).toThrow(UINT64_OVERFLOW_UNDERFLOW_MESSAGE) @@ -176,7 +182,7 @@ describe('Unit64', async () => { [MAX_UINT64, 0], [MAX_UINT64, 1], ])('multiplication', async (a, b) => { - it(`${a} * ${b}`, async () => { + test(`${a} * ${b}`, async ({ appClientPrimitiveOpsContract: appClient }) => { const avmResult = await getAvmResult({ appClient }, 'verify_uint64_mul', a, b) let result = asUint64(a) * asUint64(b) expect(result.valueOf(), `for values: ${a}, ${b}`).toBe(avmResult) @@ -198,7 +204,7 @@ describe('Unit64', async () => { [MAX_UINT64, MAX_UINT64], [MAX_UINT64 / 2n, 3], ])('multiplication overflow', async (a, b) => { - it(`${a} * ${b}`, async () => { + test(`${a} * ${b}`, async ({ appClientPrimitiveOpsContract: appClient }) => { await expect(getAvmResult({ appClient }, 'verify_uint64_mul', a, b)).rejects.toThrow('* overflowed') expect(() => asUint64(a) * asUint64(b)).toThrow(UINT64_OVERFLOW_UNDERFLOW_MESSAGE) @@ -221,7 +227,7 @@ describe('Unit64', async () => { [1, MAX_UINT64], [MAX_UINT64, MAX_UINT64], ])('division', async (a, b) => { - it(`${a} / ${b}`, async () => { + test(`${a} / ${b}`, async ({ appClientPrimitiveOpsContract: appClient }) => { const avmResult = await getAvmResult({ appClient }, 'verify_uint64_div', a, b) let result = asUint64(a) / asUint64(b) expect(result.valueOf(), `for values: ${a}, ${b}`).toBe(avmResult) @@ -243,7 +249,7 @@ describe('Unit64', async () => { [1, 0], [MAX_UINT64, 0], ])('division by zero', async (a, b) => { - it(`${a} / ${b}`, async () => { + test(`${a} / ${b}`, async ({ appClientPrimitiveOpsContract: appClient }) => { await expect(getAvmResult({ appClient }, 'verify_uint64_div', a, b)).rejects.toThrow('/ 0') expect(() => asUint64(a) / asUint64(b)).toThrow('Division by zero') @@ -264,7 +270,7 @@ describe('Unit64', async () => { [1, MAX_UINT64], [MAX_UINT64, MAX_UINT64], ])('modulo', async (a, b) => { - it(`${a} % ${b}`, async () => { + test(`${a} % ${b}`, async ({ appClientPrimitiveOpsContract: appClient }) => { const avmResult = await getAvmResult({ appClient }, 'verify_uint64_mod', a, b) let result = asUint64(a) % asUint64(b) expect(result.valueOf(), `for values: ${a}, ${b}`).toBe(avmResult) @@ -286,7 +292,7 @@ describe('Unit64', async () => { [1, 0], [MAX_UINT64, 0], ])('modulo by zero', async (a, b) => { - it(`${a} % ${b}`, async () => { + test(`${a} % ${b}`, async ({ appClientPrimitiveOpsContract: appClient }) => { await expect(getAvmResult({ appClient }, 'verify_uint64_mod', a, b)).rejects.toThrow('% 0') expect(() => asUint64(a) % asUint64(b)).toThrow('Division by zero') @@ -309,7 +315,7 @@ describe('Unit64', async () => { [MAX_UINT64, 1], [2 ** 31, 2], ])('pow', async (a, b) => { - it(`${a} ** ${b}`, async () => { + test(`${a} ** ${b}`, async ({ appClientPrimitiveOpsContract: appClient }) => { const avmResult = await getAvmResult({ appClient }, 'verify_uint64_pow', a, b) let result = asUint64(a) ** asUint64(b) expect(result.valueOf(), `for values: ${a}, ${b}`).toBe(avmResult) @@ -327,7 +333,7 @@ describe('Unit64', async () => { }) describe('pow undefined', async () => { - it('0 ** 0', async () => { + test('0 ** 0', async ({ appClientPrimitiveOpsContract: appClient }) => { const a = 0, b = 0 await expect(getAvmResult({ appClient }, 'verify_uint64_pow', a, b)).rejects.toThrow('0^0 is undefined') @@ -340,7 +346,7 @@ describe('Unit64', async () => { [2, 64], [2 ** 32, 32], ])('pow overflow', async (a, b) => { - it(`${a} ** ${b}`, async () => { + test(`${a} ** ${b}`, async ({ appClientPrimitiveOpsContract: appClient }) => { await expect(getAvmResult({ appClient }, 'verify_uint64_pow', a, b)).rejects.toThrow(/\d+\^\d+ overflow/) expect(() => asUint64(a) ** asUint64(b)).toThrow(UINT64_OVERFLOW_UNDERFLOW_MESSAGE) @@ -390,7 +396,7 @@ describe('Unit64', async () => { throw new Error(`Unknown operator: ${op}`) } } - it(`${a} ${operator} ${b}`, async () => { + test(`${a} ${operator} ${b}`, async ({ appClientPrimitiveOpsContract: appClient }) => { const avmResult = await getAvmResult({ appClient }, `verify_uint64_${op}`, a, b) let result = getStubResult(uintA, uintB) expect(result.valueOf(), `for values: ${a}, ${b}`).toBe(avmResult) @@ -409,7 +415,7 @@ describe('Unit64', async () => { }) describe.each([0, 1, 42, MAX_UINT64])('bitwise invert', async (a) => { - it(`~${a}`, async () => { + test(`~${a}`, async ({ appClientPrimitiveOpsContract: appClient }) => { const avmResult = await getAvmResult({ appClient }, 'verify_uint64_not', a) const result = ~asUint64(a) expect(result.valueOf(), `for value: ${a}`).toBe(avmResult) @@ -428,7 +434,7 @@ describe('Unit64', async () => { ])('shift operations', async (a, b) => { const uintA = asUint64(a) const uintB = asUint64(b) - it(`${a} << ${b}`, async () => { + test(`${a} << ${b}`, async ({ appClientPrimitiveOpsContract: appClient }) => { const avmResult = await getAvmResult({ appClient }, 'verify_uint64_lshift', a, b) let result = uintA << uintB expect(result.valueOf(), `for values: ${a}, ${b}`).toBe(avmResult) @@ -444,7 +450,7 @@ describe('Unit64', async () => { } }) - it(`${a} >> ${b}`, async () => { + test(`${a} >> ${b}`, async ({ appClientPrimitiveOpsContract: appClient }) => { const avmResult = await getAvmResult({ appClient }, 'verify_uint64_rshift', a, b) let result = uintA >> uintB expect(result.valueOf(), `for values: ${a}, ${b}`).toBe(avmResult) @@ -466,7 +472,7 @@ describe('Unit64', async () => { b = 64 const uintA = asUint64(a) const uintB = asUint64(b) - it('0 << 64', async () => { + test('0 << 64', async ({ appClientPrimitiveOpsContract: appClient }) => { await expect(getAvmResult({ appClient }, 'verify_uint64_lshift', a, b)).rejects.toThrow('arg too big, (64)') expect(() => uintA << uintB).toThrow('expected shift <= 63') expect(() => a << uintB).toThrow('expected shift <= 63') @@ -474,7 +480,7 @@ describe('Unit64', async () => { expect(() => Uint64(MAX_UINT64 + 1n) << Uint64(1n)).toThrow(UINT64_OVERFLOW_UNDERFLOW_MESSAGE) }) - it('0 >> 64', async () => { + test('0 >> 64', async ({ appClientPrimitiveOpsContract: appClient }) => { await expect(getAvmResult({ appClient }, 'verify_uint64_rshift', a, b)).rejects.toThrow('arg too big, (64)') expect(() => uintA >> uintB).toThrow('expected shift <= 63') expect(() => a >> uintB).toThrow('expected shift <= 63') @@ -484,13 +490,13 @@ describe('Unit64', async () => { }) describe.each([MAX_UINT64 + 1n, MAX_UINT64 * 2n])('value too big', (a) => { - it(`${a}`, () => { + test(`${a}`, () => { expect(() => Uint64(a)).toThrow(UINT64_OVERFLOW_UNDERFLOW_MESSAGE) }) }) describe.each([-1, -MAX_UINT64, -MAX_UINT64 * 2n])('value too small', (a) => { - it(`${a}`, () => { + test(`${a}`, () => { expect(() => asUint64(a)).toThrow(UINT64_OVERFLOW_UNDERFLOW_MESSAGE) }) }) @@ -506,8 +512,8 @@ describe('Unit64', async () => { [42n, 42n], [MAX_UINT64, MAX_UINT64], ])('fromCompat', async (a, b) => { - it(`${a}`, async () => { - const result = internal.primitives.Uint64Cls.fromCompat(a) + test(`${a}`, async () => { + const result = Uint64Cls.fromCompat(a) expect(result.valueOf(), `for value: ${a}`).toBe(b) }) }) diff --git a/tests/pure-op-codes.spec.ts b/tests/pure-op-codes.spec.ts index 6935465..f0693a4 100644 --- a/tests/pure-op-codes.spec.ts +++ b/tests/pure-op-codes.spec.ts @@ -1,6 +1,7 @@ -import { AppSpec } from '@algorandfoundation/algokit-utils/types/app-spec' -import { Base64, BigUint, bytes, Bytes, err, internal, Uint64, uint64 } from '@algorandfoundation/algorand-typescript' -import { afterEach, describe, expect, it, test } from 'vitest' +import type { bytes, uint64 } from '@algorandfoundation/algorand-typescript' +import { Base64, BigUint, Bytes, err, Uint64 } from '@algorandfoundation/algorand-typescript' +import { encodingUtil } from '@algorandfoundation/puya-ts' +import { afterEach, beforeAll, describe, expect } from 'vitest' import { TestExecutionContext } from '../src' import { BIGUINT_OVERFLOW_UNDERFLOW_MESSAGE, @@ -11,8 +12,8 @@ import { } from '../src/constants' import * as op from '../src/impl/pure' import { asBigUintCls, asUint8Array } from '../src/util' -import appSpecJson from './artifacts/miscellaneous-ops/data/MiscellaneousOpsContract.arc32.json' -import { getAlgorandAppClient, getAvmResult, getAvmResultRaw } from './avm-invoker' +import { getAvmResult, getAvmResultRaw } from './avm-invoker' +import { createArc4TestFixture } from './test-fixture' import { base64Encode, base64UrlEncode, getPaddedBytes, getSha256Hash, intToBytes } from './util' const avmIntArgOverflowError = 'is not a non-negative int or too big to fit in size' @@ -20,15 +21,21 @@ const extractOutOfBoundError = /extraction (start|end) \d+ is beyond length/ const sqrtMaxUint64 = 4294967295n describe('Pure op codes', async () => { - const appClient = await getAlgorandAppClient(appSpecJson as AppSpec) + const [test, localnetFixture] = createArc4TestFixture('tests/artifacts/miscellaneous-ops/contract.algo.ts', { + MiscellaneousOpsContract: {}, + }) const ctx = new TestExecutionContext() - afterEach(async () => { + beforeAll(async () => { + await localnetFixture.newScope() + }) + + afterEach(() => { ctx.reset() }) describe('addw', async () => { - test.each([ + test.for([ [0, 0], [0, MAX_UINT64], [MAX_UINT64, 0], @@ -39,41 +46,41 @@ describe('Pure op codes', async () => { [MAX_UINT64 - 1n, 1], [100, MAX_UINT64], [MAX_UINT64, MAX_UINT64], - ])('should add two uint64 values', async (a, b) => { + ])('should add two uint64 values', async ([a, b], { appClientMiscellaneousOpsContract: appClient }) => { const avmResult = await getAvmResult({ appClient }, 'verify_addw', a, b) const result = op.addw(a, b) expect(result[0].valueOf()).toBe(avmResult[0]) expect(result[1].valueOf()).toBe(avmResult[1]) }) - test.each([ + test.for([ [1, MAX_UINT64 + 1n], [MAX_UINT64 + 1n, 1], [0, MAX_UINT512], [MAX_UINT512 * 2n, 0], - ])('should throw error when input overflows', async (a, b) => { + ])('should throw error when input overflows', async ([a, b], { appClientMiscellaneousOpsContract: appClient }) => { await expect(getAvmResultRaw({ appClient }, 'verify_addw', a, b)).rejects.toThrow(avmIntArgOverflowError) expect(() => op.addw(a, b)).toThrow(UINT64_OVERFLOW_UNDERFLOW_MESSAGE) }) }) describe('base64Decode', async () => { - test.each([ + test.for([ base64Encode(''), base64Encode('abc'), base64Encode('hello, world.'), base64Encode('0123.'), base64Encode(Bytes([0xff])), base64Encode(Bytes(Array(256).fill(0x00).concat([0xff]))), - ])('should decode standard base64 string', async (a) => { + ])('should decode standard base64 string', async (a, { appClientMiscellaneousOpsContract: appClient }) => { const avmResult = (await getAvmResult({ appClient }, 'verify_base64_decode_standard', asUint8Array(a)))! const result = op.base64Decode(Base64.StdEncoding, a) expect(result).toEqual(avmResult) }) - test.each([Bytes(Bytes(Array(256).fill(0x00).concat([0xff]))), asBigUintCls(BigUint(MAX_UINT512)).toBytes().asAlgoTs()])( + test.for([Bytes(Bytes(Array(256).fill(0x00).concat([0xff]))), asBigUintCls(BigUint(MAX_UINT512)).toBytes().asAlgoTs()])( 'should throw error when input is not a valid base64 string', - async (a) => { + async (a, { appClientMiscellaneousOpsContract: appClient }) => { await expect(getAvmResultRaw({ appClient }, 'verify_base64_decode_standard', asUint8Array(a))).rejects.toThrow( 'illegal base64 data at input byte 0', ) @@ -81,22 +88,22 @@ describe('Pure op codes', async () => { }, ) - test.each([ + test.for([ base64UrlEncode(''), base64UrlEncode('abc'), base64UrlEncode('hello, world.'), base64UrlEncode('0123.'), base64UrlEncode(Bytes([0xff])), base64UrlEncode(Bytes(Array(256).fill(0x00).concat([0xff]))), - ])('should decode base64url string', async (a) => { + ])('should decode base64url string', async (a, { appClientMiscellaneousOpsContract: appClient }) => { const avmResult = (await getAvmResult({ appClient }, 'verify_base64_decode_url', asUint8Array(a)))! const result = op.base64Decode(Base64.URLEncoding, a) expect(result).toEqual(avmResult) }) - test.each([Bytes(Bytes(Array(256).fill(0x00).concat([0xff]))), asBigUintCls(BigUint(MAX_UINT512)).toBytes().asAlgoTs()])( + test.for([Bytes(Bytes(Array(256).fill(0x00).concat([0xff]))), asBigUintCls(BigUint(MAX_UINT512)).toBytes().asAlgoTs()])( 'should throw error when input is not a valid base64url string', - async (a) => { + async (a, { appClientMiscellaneousOpsContract: appClient }) => { await expect(getAvmResultRaw({ appClient }, 'verify_base64_decode_url', asUint8Array(a))).rejects.toThrow('illegal base64 data') expect(() => op.base64Decode(Base64.URLEncoding, a)).toThrow('illegal base64 data') }, @@ -104,68 +111,80 @@ describe('Pure op codes', async () => { }) describe('bitLength', async () => { - test.each([ - [Bytes(internal.encodingUtil.bigIntToUint8Array(0n)), 0], - [Bytes(internal.encodingUtil.bigIntToUint8Array(1n)), 0], - [Bytes(internal.encodingUtil.bigIntToUint8Array(MAX_UINT64)), 0], - [Bytes(internal.encodingUtil.bigIntToUint8Array(MAX_UINT512)), 0], - [Bytes(internal.encodingUtil.bigIntToUint8Array(MAX_UINT512 * MAX_UINT512)), 0], + test.for([ + [Bytes(encodingUtil.bigIntToUint8Array(0n)), 0], + [Bytes(encodingUtil.bigIntToUint8Array(1n)), 0], + [Bytes(encodingUtil.bigIntToUint8Array(MAX_UINT64)), 0], + [Bytes(encodingUtil.bigIntToUint8Array(MAX_UINT512)), 0], + [Bytes(encodingUtil.bigIntToUint8Array(MAX_UINT512 * MAX_UINT512)), 0], [Bytes(Array(8).fill(0x00).concat(Array(4).fill(0x0f))), 0], [Bytes([0x0f]), MAX_BYTES_SIZE - 1], [Bytes(), 0], - ])('should return the number of bits for the bytes input', async (a, padSize) => { - const avmResult = await getAvmResult({ appClient }, 'verify_bytes_bitlen', asUint8Array(a), padSize) - const paddedA = getPaddedBytes(padSize, a) + ])('should return the number of bits for the bytes input', async ([a, padSize], { appClientMiscellaneousOpsContract: appClient }) => { + const avmResult = await getAvmResult({ appClient }, 'verify_bytes_bitlen', asUint8Array(a as bytes), padSize as number) + const paddedA = getPaddedBytes(padSize as number, a as bytes) const result = op.bitLength(paddedA) expect(result).toEqual(avmResult) }) - test.each([0, 1, 42, MAX_UINT64])('should return the number of bits for the uint64 input', async (a) => { - const avmResult = await getAvmResult({ appClient }, 'verify_uint64_bitlen', a) - const result = op.bitLength(a) - expect(result).toEqual(avmResult) - }) + test.for([0, 1, 42, MAX_UINT64])( + 'should return the number of bits for the uint64 input', + async (a, { appClientMiscellaneousOpsContract: appClient }) => { + const avmResult = await getAvmResult({ appClient }, 'verify_uint64_bitlen', a) + const result = op.bitLength(a) + expect(result).toEqual(avmResult) + }, + ) - test.each([MAX_UINT64 + 1n, MAX_UINT512, MAX_UINT512 * 2n])('should throw error when uint64 input overflows', async (a) => { - await expect(getAvmResultRaw({ appClient }, 'verify_uint64_bitlen', a)).rejects.toThrow(avmIntArgOverflowError) - expect(() => op.bitLength(a)).toThrow(UINT64_OVERFLOW_UNDERFLOW_MESSAGE) - }) + test.for([MAX_UINT64 + 1n, MAX_UINT512, MAX_UINT512 * 2n])( + 'should throw error when uint64 input overflows', + async (a, { appClientMiscellaneousOpsContract: appClient }) => { + await expect(getAvmResultRaw({ appClient }, 'verify_uint64_bitlen', a)).rejects.toThrow(avmIntArgOverflowError) + expect(() => op.bitLength(a)).toThrow(UINT64_OVERFLOW_UNDERFLOW_MESSAGE) + }, + ) }) describe('bsqrt', async () => { - test.each([0, 1, 2, 9, 13, 144n, MAX_UINT64, MAX_UINT512])('should compute the square root of a big uint', async (a) => { - const uint8ArrayA = internal.encodingUtil.bigIntToUint8Array(BigInt(a)) - const avmResult = (await getAvmResult({ appClient }, 'verify_bsqrt', uint8ArrayA))! - - const result = op.bsqrt(a) - const bytesResult = asBigUintCls(result).toBytes() - expect(bytesResult).toEqual(avmResult) - }) + test.for([0, 1, 2, 9, 13, 144n, MAX_UINT64, MAX_UINT512])( + 'should compute the square root of a big uint', + async (a, { appClientMiscellaneousOpsContract: appClient }) => { + const uint8ArrayA = encodingUtil.bigIntToUint8Array(BigInt(a)) + const avmResult = (await getAvmResult({ appClient }, 'verify_bsqrt', uint8ArrayA))! + + const result = op.bsqrt(a) + const bytesResult = asBigUintCls(result).toBytes() + expect(bytesResult).toEqual(avmResult) + }, + ) - test.each([MAX_UINT512 + 1n, MAX_UINT512 * 2n])('should throw error when input overflows', async (a) => { - const uint8ArrayA = internal.encodingUtil.bigIntToUint8Array(BigInt(a)) - await expect(getAvmResultRaw({ appClient }, 'verify_bsqrt', uint8ArrayA)).rejects.toThrow('math attempted on large byte-array') - expect(() => op.bsqrt(a)).toThrow(BIGUINT_OVERFLOW_UNDERFLOW_MESSAGE) - }) + test.for([MAX_UINT512 + 1n, MAX_UINT512 * 2n])( + 'should throw error when input overflows', + async (a, { appClientMiscellaneousOpsContract: appClient }) => { + const uint8ArrayA = encodingUtil.bigIntToUint8Array(BigInt(a)) + await expect(getAvmResultRaw({ appClient }, 'verify_bsqrt', uint8ArrayA)).rejects.toThrow('math attempted on large byte-array') + expect(() => op.bsqrt(a)).toThrow(BIGUINT_OVERFLOW_UNDERFLOW_MESSAGE) + }, + ) }) describe('btoi', async () => { - test.each([ - Bytes(internal.encodingUtil.bigIntToUint8Array(0n)), - Bytes(internal.encodingUtil.bigIntToUint8Array(1n)), - Bytes(internal.encodingUtil.bigIntToUint8Array(MAX_UINT64)), + test.for([ + Bytes(encodingUtil.bigIntToUint8Array(0n)), + Bytes(encodingUtil.bigIntToUint8Array(1n)), + Bytes(encodingUtil.bigIntToUint8Array(MAX_UINT64)), Bytes(Array(4).fill(0x00).concat(Array(4).fill(0x0f))), - ])('should convert bytes to uint64', async (a) => { + ])('should convert bytes to uint64', async (a, { appClientMiscellaneousOpsContract: appClient }) => { const avmResult = await getAvmResult({ appClient }, 'verify_btoi', asUint8Array(a)) const result = op.btoi(a) expect(result).toEqual(avmResult) }) - test.each([ - Bytes(internal.encodingUtil.bigIntToUint8Array(MAX_UINT512)), - Bytes(internal.encodingUtil.bigIntToUint8Array(MAX_UINT512 * MAX_UINT512, 128)), + test.for([ + Bytes(encodingUtil.bigIntToUint8Array(MAX_UINT512)), + Bytes(encodingUtil.bigIntToUint8Array(MAX_UINT512 * MAX_UINT512, 128)), Bytes(Array(5).fill(0x00).concat(Array(4).fill(0x0f))), - ])('should throw error when input overflows', async (a) => { + ])('should throw error when input overflows', async (a, { appClientMiscellaneousOpsContract: appClient }) => { const errorRegex = new RegExp(`btoi arg too long, got \\[${a.length.valueOf()}\\]bytes`) await expect(getAvmResultRaw({ appClient }, 'verify_btoi', asUint8Array(a))).rejects.toThrow(errorRegex) expect(() => op.btoi(a)).toThrow(errorRegex) @@ -173,26 +192,35 @@ describe('Pure op codes', async () => { }) describe('bzero', async () => { - test.each([0, 1, 42, MAX_BYTES_SIZE])('should return a zero filled bytes value of the given size', async (a) => { - const avmResult = (await getAvmResult({ appClient }, 'verify_bzero', a))! - const result = op.bzero(a) - const resultHash = Bytes(getSha256Hash(asUint8Array(result))) - expect(resultHash).toEqual(avmResult) - }) + test.for([0, 1, 42, MAX_BYTES_SIZE])( + 'should return a zero filled bytes value of the given size', + async (a, { appClientMiscellaneousOpsContract: appClient }) => { + const avmResult = (await getAvmResult({ appClient }, 'verify_bzero', a))! + const result = op.bzero(a) + const resultHash = Bytes(getSha256Hash(asUint8Array(result))) + expect(resultHash).toEqual(avmResult) + }, + ) - test.each([MAX_BYTES_SIZE + 1, MAX_UINT64])('should throw error when result overflows', async (a) => { - await expect(getAvmResultRaw({ appClient }, 'verify_bzero', a)).rejects.toThrow('bzero attempted to create a too large string') - expect(() => op.bzero(a)).toThrow('bzero attempted to create a too large string') - }) + test.for([MAX_BYTES_SIZE + 1, MAX_UINT64])( + 'should throw error when result overflows', + async (a, { appClientMiscellaneousOpsContract: appClient }) => { + await expect(getAvmResultRaw({ appClient }, 'verify_bzero', a)).rejects.toThrow('bzero attempted to create a too large string') + expect(() => op.bzero(a)).toThrow('bzero attempted to create a too large string') + }, + ) - test.each([MAX_UINT64 + 1n, MAX_UINT512, MAX_UINT512 * 2n])('should throw error when input overflows', async (a) => { - await expect(getAvmResultRaw({ appClient }, 'verify_bzero', a)).rejects.toThrow(avmIntArgOverflowError) - expect(() => op.bzero(a)).toThrow(UINT64_OVERFLOW_UNDERFLOW_MESSAGE) - }) + test.for([MAX_UINT64 + 1n, MAX_UINT512, MAX_UINT512 * 2n])( + 'should throw error when input overflows', + async (a, { appClientMiscellaneousOpsContract: appClient }) => { + await expect(getAvmResultRaw({ appClient }, 'verify_bzero', a)).rejects.toThrow(avmIntArgOverflowError) + expect(() => op.bzero(a)).toThrow(UINT64_OVERFLOW_UNDERFLOW_MESSAGE) + }, + ) }) describe('concat', async () => { - test.each([ + test.for([ ['', '', 0, 0], ['1', '', 0, 0], ['', '1', 0, 0], @@ -201,41 +229,41 @@ describe('Pure op codes', async () => { ['0', '', MAX_BYTES_SIZE - 1, 0], ['1', '0', 0, MAX_BYTES_SIZE - 2], ['1', '0', MAX_BYTES_SIZE - 2, 0], - ])('should retrun concatenated bytes', async (a, b, padASize, padBSize) => { + ])('should retrun concatenated bytes', async ([a, b, padASize, padBSize], { appClientMiscellaneousOpsContract: appClient }) => { const avmResult = (await getAvmResult( { appClient }, 'verify_concat', - asUint8Array(a), - asUint8Array(b), + asUint8Array(a as string), + asUint8Array(b as string), padASize, padBSize, ))! - const paddedA = getPaddedBytes(padASize, a) - const paddedB = getPaddedBytes(padBSize, b) + const paddedA = getPaddedBytes(padASize as number, a as string) + const paddedB = getPaddedBytes(padBSize as number, b as string) const result = op.concat(paddedA, paddedB) const resultHash = Bytes(getSha256Hash(asUint8Array(result))) expect(resultHash).toEqual(avmResult) }) - test.each([ + test.for([ ['1', '0', MAX_BYTES_SIZE - 1, 0], ['1', '1', MAX_BYTES_SIZE - 1, MAX_BYTES_SIZE - 1], ['1', '0', 0, MAX_BYTES_SIZE - 1], - ])('should throw error when input overflows', async (a, b, padASize, padBSize) => { - await expect(getAvmResultRaw({ appClient }, 'verify_concat', asUint8Array(a), asUint8Array(b), padASize, padBSize)).rejects.toThrow( - /concat produced a too big \(\d+\) byte-array/, - ) - const paddedA = getPaddedBytes(padASize, a) - const paddedB = getPaddedBytes(padBSize, b) + ])('should throw error when input overflows', async ([a, b, padASize, padBSize], { appClientMiscellaneousOpsContract: appClient }) => { + await expect( + getAvmResultRaw({ appClient }, 'verify_concat', asUint8Array(a as string), asUint8Array(b as string), padASize, padBSize), + ).rejects.toThrow(/concat produced a too big \(\d+\) byte-array/) + const paddedA = getPaddedBytes(padASize as number, a as string) + const paddedB = getPaddedBytes(padBSize as number, b as string) expect(() => op.concat(paddedA, paddedB)).toThrow(/Bytes length \d+ exceeds maximum length/) }) }) describe('divmodw', async () => { - test.each([ + test.for([ [0, 1, 0, 1], [100, 42, 100, 42], [42, 100, 42, 100], @@ -246,7 +274,7 @@ describe('Pure op codes', async () => { [1, MAX_UINT64 - 1n, 1, MAX_UINT64 - 1n], [100, MAX_UINT64, 100, MAX_UINT64], [MAX_UINT64, MAX_UINT64, MAX_UINT64, MAX_UINT64], - ])('should calculate div and mod results', async (a, b, c, d) => { + ])('should calculate div and mod results', async ([a, b, c, d], { appClientMiscellaneousOpsContract: appClient }) => { const avmResult = await getAvmResult({ appClient }, 'verify_divmodw', a, b, c, d) const result = op.divmodw(a, b, c, d) expect(result[0].valueOf()).toBe(avmResult[0]) @@ -255,17 +283,17 @@ describe('Pure op codes', async () => { expect(result[3].valueOf()).toBe(avmResult[3]) }) - test.each([ + test.for([ [1, MAX_UINT64 + 1n, 1, MAX_UINT64 + 1n], [MAX_UINT64 + 1n, 1, MAX_UINT64 + 1n, 1], [0, MAX_UINT512, 0, MAX_UINT512], [MAX_UINT512 * 2n, 1, MAX_UINT512 * 2n, 1], - ])('should throw error when input overflows', async (a, b, c, d) => { + ])('should throw error when input overflows', async ([a, b, c, d], { appClientMiscellaneousOpsContract: appClient }) => { await expect(getAvmResultRaw({ appClient }, 'verify_divmodw', a, b, c, d)).rejects.toThrow(avmIntArgOverflowError) expect(() => op.divmodw(a, b, c, d)).toThrow(UINT64_OVERFLOW_UNDERFLOW_MESSAGE) }) - test.each([ + test.for([ [0, 1], [100, 42], [42, 100], @@ -276,27 +304,27 @@ describe('Pure op codes', async () => { [1, MAX_UINT64 - 1n], [100, MAX_UINT64], [MAX_UINT64, MAX_UINT64], - ])('should throw error when dividing by zero', async (a, b) => { + ])('should throw error when dividing by zero', async ([a, b], { appClientMiscellaneousOpsContract: appClient }) => { await expect(getAvmResultRaw({ appClient }, 'verify_divmodw', a, b, 0, 0)).rejects.toThrow('/ 0') expect(() => op.divmodw(a, b, 0, 0)).toThrow('Division by zero') }) }) describe('divw', async () => { - test.each([ + test.for([ [0, 1, 1], [42, 100, 100], [0, MAX_UINT64, MAX_UINT64], [1, MAX_UINT64, MAX_UINT64], [1, MAX_UINT64 - 1n, MAX_UINT64 - 1n], [100, MAX_UINT64, MAX_UINT64], - ])('should calculate div result', async (a, b, c) => { + ])('should calculate div result', async ([a, b, c], { appClientMiscellaneousOpsContract: appClient }) => { const avmResult = await getAvmResult({ appClient }, 'verify_divw', a, b, c) const result = op.divw(a, b, c) expect(result).toEqual(avmResult) }) - test.each([ + test.for([ [0, 1], [100, 42], [42, 100], @@ -307,118 +335,118 @@ describe('Pure op codes', async () => { [1, MAX_UINT64 - 1n], [100, MAX_UINT64], [MAX_UINT64, MAX_UINT64], - ])('should throw error when dividing by zero', async (a, b) => { + ])('should throw error when dividing by zero', async ([a, b], { appClientMiscellaneousOpsContract: appClient }) => { await expect(getAvmResultRaw({ appClient }, 'verify_divw', a, b, 0)).rejects.toThrow('divw 0') expect(() => op.divw(a, b, 0)).toThrow('Division by zero') }) - test.each([ + test.for([ [1, MAX_UINT64 + 1n, 1], [MAX_UINT64 + 1n, 1, MAX_UINT64 + 1n], [0, MAX_UINT512, MAX_UINT512], [MAX_UINT512 * 2n, 1, MAX_UINT512 * 2n], - ])('should throw error when input overflows', async (a, b, c) => { + ])('should throw error when input overflows', async ([a, b, c], { appClientMiscellaneousOpsContract: appClient }) => { await expect(getAvmResultRaw({ appClient }, 'verify_divw', a, b, c)).rejects.toThrow(avmIntArgOverflowError) expect(() => op.divw(a, b, c)).toThrow(UINT64_OVERFLOW_UNDERFLOW_MESSAGE) }) - test.each([ + test.for([ [100, 42, 42], [MAX_UINT64, 1, 1], [MAX_UINT64 - 1n, 1, 1], [MAX_UINT64, MAX_UINT64, MAX_UINT64], - ])('should throw error when result overflows', async (a, b, c) => { + ])('should throw error when result overflows', async ([a, b, c], { appClientMiscellaneousOpsContract: appClient }) => { await expect(getAvmResultRaw({ appClient }, 'verify_divw', a, b, c)).rejects.toThrow('divw overflow') expect(() => op.divw(a, b, c)).toThrow(UINT64_OVERFLOW_UNDERFLOW_MESSAGE) }) }) describe('err', async () => { - it('should throw default error', async () => { + test('should throw default error', async ({ appClientMiscellaneousOpsContract: appClient }) => { await expect(getAvmResultRaw({ appClient }, 'verify_err')).rejects.toThrow('err opcode executed') expect(() => err()).toThrow('err opcode executed') }) }) describe('exp', async () => { - test.each([ + test.for([ [0, 1], [1, 0], [42, 11], [sqrtMaxUint64, 2], [1, MAX_UINT64], - ])('should calculate the exponentiation result', async (a, b) => { + ])('should calculate the exponentiation result', async ([a, b], { appClientMiscellaneousOpsContract: appClient }) => { const avmResult = await getAvmResult({ appClient }, 'verify_exp', a, b) const result = op.exp(a, b) expect(result).toEqual(avmResult) }) - test.each([ + test.for([ [100, 42], [MAX_UINT64, 2], [2, 64], - ])('should throw error when result overflows', async (a, b) => { + ])('should throw error when result overflows', async ([a, b], { appClientMiscellaneousOpsContract: appClient }) => { await expect(getAvmResultRaw({ appClient }, 'verify_exp', a, b)).rejects.toThrow('overflow') expect(() => op.exp(a, b)).toThrow(UINT64_OVERFLOW_UNDERFLOW_MESSAGE) }) - test.each([ + test.for([ [1, MAX_UINT64 + 1n], [MAX_UINT64 + 1n, 1], [0, MAX_UINT512], [MAX_UINT512 * 2n, 1], - ])('should throw error when input overflows', async (a, b) => { + ])('should throw error when input overflows', async ([a, b], { appClientMiscellaneousOpsContract: appClient }) => { await expect(getAvmResultRaw({ appClient }, 'verify_exp', a, b)).rejects.toThrow(avmIntArgOverflowError) expect(() => op.exp(a, b)).toThrow(UINT64_OVERFLOW_UNDERFLOW_MESSAGE) }) - it('0 ** 0 is not supported', async () => { + test('0 ** 0 is not supported', async ({ appClientMiscellaneousOpsContract: appClient }) => { await expect(getAvmResultRaw({ appClient }, 'verify_exp', 0, 0)).rejects.toThrow('0^0 is undefined') expect(() => op.exp(0, 0)).toThrow('0 ** 0 is undefined') }) }) describe('expw', async () => { - test.each([ + test.for([ [0, 1], [1, 0], [42, 11], [sqrtMaxUint64, 4], [2, 127], - ])('should calculate the exponentiation result', async (a, b) => { + ])('should calculate the exponentiation result', async ([a, b], { appClientMiscellaneousOpsContract: appClient }) => { const avmResult = await getAvmResult({ appClient }, 'verify_expw', a, b) const result = op.expw(a, b) expect(result[0].valueOf()).toBe(avmResult[0]) expect(result[1].valueOf()).toBe(avmResult[1]) }) - test.each([ + test.for([ [100, 42], [MAX_UINT64, 3], [2, 128], - ])('should throw error when result overflows', async (a, b) => { + ])('should throw error when result overflows', async ([a, b], { appClientMiscellaneousOpsContract: appClient }) => { await expect(getAvmResultRaw({ appClient }, 'verify_expw', a, b)).rejects.toThrow('overflow') expect(() => op.expw(a, b)).toThrow(UINT64_OVERFLOW_UNDERFLOW_MESSAGE) }) - test.each([ + test.for([ [1, MAX_UINT64 + 1n], [MAX_UINT64 + 1n, 1], [0, MAX_UINT512], [MAX_UINT512 * 2n, 1], - ])(`should throw error when input overflows`, async (a, b) => { + ])(`should throw error when input overflows`, async ([a, b], { appClientMiscellaneousOpsContract: appClient }) => { await expect(getAvmResultRaw({ appClient }, 'verify_expw', a, b)).rejects.toThrow(avmIntArgOverflowError) expect(() => op.expw(a, b)).toThrow(UINT64_OVERFLOW_UNDERFLOW_MESSAGE) }) - it('0 ** 0 is not supported', async () => { + test('0 ** 0 is not supported', async ({ appClientMiscellaneousOpsContract: appClient }) => { await expect(getAvmResultRaw({ appClient }, 'verify_expw', 0, 0)).rejects.toThrow('0^0 is undefined') expect(() => op.expw(0, 0)).toThrow('0 ** 0 is undefined') }) }) describe('extract', async () => { - test.each([ + test.for([ [0, 0], [0, 1], [0, 2], @@ -427,7 +455,7 @@ describe('Pure op codes', async () => { [8, 4], [256, 0], [256, 3], - ])(`should extract bytes from the input`, async (b, c) => { + ])(`should extract bytes from the input`, async ([b, c], { appClientMiscellaneousOpsContract: appClient }) => { const a = 'hello, world'.repeat(30) const avmResult = (await getAvmResult({ appClient }, 'verify_extract', asUint8Array(a), b, c))! let result = op.extract(a, Uint64(b), Uint64(c)) @@ -439,29 +467,32 @@ describe('Pure op codes', async () => { } }) - test.each(['hello, world', 'hi'])('should work to extract bytes from 2 to end for %s', async (a) => { - const avmResult = (await getAvmResult({ appClient }, 'verify_extract_from_2', asUint8Array(a)))! - const result = op.extract(a, 2, 0) - expect(result).toEqual(avmResult) - }) + test.for(['hello, world', 'hi'])( + 'should work to extract bytes from 2 to end for %s', + async (a, { appClientMiscellaneousOpsContract: appClient }) => { + const avmResult = (await getAvmResult({ appClient }, 'verify_extract_from_2', asUint8Array(a)))! + const result = op.extract(a, 2) + expect(result).toEqual(avmResult) + }, + ) - test.each([ + test.for([ [1, MAX_UINT64 + 1n], [MAX_UINT64 + 1n, 1], [0, MAX_UINT512], [MAX_UINT512 * 2n, 1], - ])(`should throw error when input overflows`, async (b, c) => { + ])(`should throw error when input overflows`, async ([b, c], { appClientMiscellaneousOpsContract: appClient }) => { const a = 'hello, world'.repeat(30) await expect(getAvmResultRaw({ appClient }, 'verify_extract', asUint8Array(a), b, c)).rejects.toThrow(avmIntArgOverflowError) expect(() => op.extract(a, b, c)).toThrow(UINT64_OVERFLOW_UNDERFLOW_MESSAGE) }) - test.each([ + test.for([ [0, 13], [13, 0], [11, 2], [8, 5], - ])('should throw error when input is invalid', async (b, c) => { + ])('should throw error when input is invalid', async ([b, c], { appClientMiscellaneousOpsContract: appClient }) => { const a = 'hello, world' await expect(getAvmResultRaw({ appClient }, 'verify_extract', asUint8Array(a), b, c)).rejects.toThrow(extractOutOfBoundError) expect(() => op.extract(a, b, c)).toThrow(extractOutOfBoundError) @@ -469,109 +500,121 @@ describe('Pure op codes', async () => { }) describe('extractUint16', async () => { - test.each([ + test.for([ [intToBytes(256), 0], [getPaddedBytes(2, intToBytes(256)), 2], [intToBytes(MAX_UINT64), 6], [intToBytes(MAX_UINT512), 62], - ])(`should extract uint16 from the input`, async (a, b) => { - const avmResult = await getAvmResult({ appClient }, 'verify_extract_uint16', asUint8Array(a), b) - const result = op.extractUint16(a, b) + ])(`should extract uint16 from the input`, async ([a, b], { appClientMiscellaneousOpsContract: appClient }) => { + const avmResult = await getAvmResult({ appClient }, 'verify_extract_uint16', asUint8Array(a as bytes), b as number) + const result = op.extractUint16(a as bytes, b as number) expect(result).toEqual(avmResult) }) - test.each([ + test.for([ [getPaddedBytes(2, intToBytes(256)), MAX_UINT64 + 1n], [intToBytes(MAX_UINT64), MAX_UINT64 + 1n], [intToBytes(MAX_UINT512), MAX_UINT512], - ])(`should throw error when input overflows`, async (a, b) => { - await expect(getAvmResult({ appClient }, 'verify_extract_uint16', asUint8Array(a), b)).rejects.toThrow(avmIntArgOverflowError) - expect(() => op.extractUint16(a, b)).toThrow(UINT64_OVERFLOW_UNDERFLOW_MESSAGE) + ])(`should throw error when input overflows`, async ([a, b], { appClientMiscellaneousOpsContract: appClient }) => { + await expect(getAvmResult({ appClient }, 'verify_extract_uint16', asUint8Array(a as bytes), b as bigint)).rejects.toThrow( + avmIntArgOverflowError, + ) + expect(() => op.extractUint16(a as bytes, b as bigint)).toThrow(UINT64_OVERFLOW_UNDERFLOW_MESSAGE) }) - test.each([ + test.for([ [intToBytes(0), 0], [intToBytes(0), 1], [intToBytes(256), 1], [getPaddedBytes(2, intToBytes(256)), 3], [intToBytes(MAX_UINT64), 8], [intToBytes(MAX_UINT512), 65], - ])(`should throw error when input is invalid`, async (a, b) => { - await expect(getAvmResult({ appClient }, 'verify_extract_uint16', asUint8Array(a), b)).rejects.toThrow(extractOutOfBoundError) - expect(() => op.extractUint16(a, b)).toThrow(extractOutOfBoundError) + ])(`should throw error when input is invalid`, async ([a, b], { appClientMiscellaneousOpsContract: appClient }) => { + await expect(getAvmResult({ appClient }, 'verify_extract_uint16', asUint8Array(a as bytes), b as number)).rejects.toThrow( + extractOutOfBoundError, + ) + expect(() => op.extractUint16(a as bytes, b as number)).toThrow(extractOutOfBoundError) }) }) describe('extractUint32', async () => { - test.each([ + test.for([ [Bytes([0x0f, 0x66, 0x66, 0x66]), 0], [getPaddedBytes(4, intToBytes(256)), 2], [intToBytes(MAX_UINT64), 4], [intToBytes(MAX_UINT512), 60], - ])(`should extract uint32 from the input`, async (a, b) => { - const avmResult = await getAvmResult({ appClient }, 'verify_extract_uint32', asUint8Array(a), b) - const result = op.extractUint32(a, b) + ])(`should extract uint32 from the input`, async ([a, b], { appClientMiscellaneousOpsContract: appClient }) => { + const avmResult = await getAvmResult({ appClient }, 'verify_extract_uint32', asUint8Array(a as bytes), b as number) + const result = op.extractUint32(a as bytes, b as number) expect(result).toEqual(avmResult) }) - test.each([ + test.for([ [getPaddedBytes(4, intToBytes(256)), MAX_UINT64 + 1n], [intToBytes(MAX_UINT64), MAX_UINT64 + 1n], [intToBytes(MAX_UINT512), MAX_UINT512], - ])(`should throw error when input overflows`, async (a, b) => { - await expect(getAvmResult({ appClient }, 'verify_extract_uint32', asUint8Array(a), b)).rejects.toThrow(avmIntArgOverflowError) - expect(() => op.extractUint32(a, b)).toThrow(UINT64_OVERFLOW_UNDERFLOW_MESSAGE) + ])(`should throw error when input overflows`, async ([a, b], { appClientMiscellaneousOpsContract: appClient }) => { + await expect(getAvmResult({ appClient }, 'verify_extract_uint32', asUint8Array(a as bytes), b as bigint)).rejects.toThrow( + avmIntArgOverflowError, + ) + expect(() => op.extractUint32(a as bytes, b as bigint)).toThrow(UINT64_OVERFLOW_UNDERFLOW_MESSAGE) }) - test.each([ + test.for([ [intToBytes(0), 0], [intToBytes(0), 1], [intToBytes(256), 1], [getPaddedBytes(4, intToBytes(256)), 3], [intToBytes(MAX_UINT64), 8], [intToBytes(MAX_UINT512), 65], - ])(`should throw error when input is invalid`, async (a, b) => { - await expect(getAvmResult({ appClient }, 'verify_extract_uint32', asUint8Array(a), b)).rejects.toThrow(extractOutOfBoundError) - expect(() => op.extractUint32(a, b)).toThrow(extractOutOfBoundError) + ])(`should throw error when input is invalid`, async ([a, b], { appClientMiscellaneousOpsContract: appClient }) => { + await expect(getAvmResult({ appClient }, 'verify_extract_uint32', asUint8Array(a as bytes), b as number)).rejects.toThrow( + extractOutOfBoundError, + ) + expect(() => op.extractUint32(a as bytes, b as number)).toThrow(extractOutOfBoundError) }) }) describe('extractUint64', async () => { - test.each([ + test.for([ [Bytes([0x0f, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66]), 0], [getPaddedBytes(8, intToBytes(256)), 2], [intToBytes(MAX_UINT64), 0], [intToBytes(MAX_UINT512), 56], - ])(`should extract uint64 from the input`, async (a, b) => { - const avmResult = await getAvmResult({ appClient }, 'verify_extract_uint64', asUint8Array(a), b) - const result = op.extractUint64(a, b) + ])(`should extract uint64 from the input`, async ([a, b], { appClientMiscellaneousOpsContract: appClient }) => { + const avmResult = await getAvmResult({ appClient }, 'verify_extract_uint64', asUint8Array(a as bytes), b as number) + const result = op.extractUint64(a as bytes, b as number) expect(result).toEqual(avmResult) }) - test.each([ + test.for([ [getPaddedBytes(8, intToBytes(256)), MAX_UINT64 + 1n], [intToBytes(MAX_UINT64), MAX_UINT64 + 1n], [intToBytes(MAX_UINT512), MAX_UINT512], - ])(`should throw error when input overflows`, async (a, b) => { - await expect(getAvmResult({ appClient }, 'verify_extract_uint64', asUint8Array(a), b)).rejects.toThrow(avmIntArgOverflowError) - expect(() => op.extractUint64(a, b)).toThrow(UINT64_OVERFLOW_UNDERFLOW_MESSAGE) + ])(`should throw error when input overflows`, async ([a, b], { appClientMiscellaneousOpsContract: appClient }) => { + await expect(getAvmResult({ appClient }, 'verify_extract_uint64', asUint8Array(a as bytes), b as bigint)).rejects.toThrow( + avmIntArgOverflowError, + ) + expect(() => op.extractUint64(a as bytes, b as bigint)).toThrow(UINT64_OVERFLOW_UNDERFLOW_MESSAGE) }) - test.each([ + test.for([ [intToBytes(0), 0], [intToBytes(0), 1], [intToBytes(256), 1], [getPaddedBytes(8, intToBytes(256)), 3], [intToBytes(MAX_UINT64), 8], [intToBytes(MAX_UINT512), 65], - ])(`should throw error when input is invalid`, async (a, b) => { - await expect(getAvmResult({ appClient }, 'verify_extract_uint64', asUint8Array(a), b)).rejects.toThrow(extractOutOfBoundError) - expect(() => op.extractUint64(a, b)).toThrow(extractOutOfBoundError) + ])(`should throw error when input is invalid`, async ([a, b], { appClientMiscellaneousOpsContract: appClient }) => { + await expect(getAvmResult({ appClient }, 'verify_extract_uint64', asUint8Array(a as bytes), b as number)).rejects.toThrow( + extractOutOfBoundError, + ) + expect(() => op.extractUint64(a as bytes, b as number)).toThrow(extractOutOfBoundError) }) }) describe('getBit', async () => { - test.each([ + test.for([ [Bytes([0x00]), 0], [getPaddedBytes(2, intToBytes(256)), 3], [getPaddedBytes(2, intToBytes(256)), 0], @@ -584,26 +627,26 @@ describe('Pure op codes', async () => { [intToBytes(MAX_UINT512 - 1n), 511], [intToBytes(MAX_UINT64), 0], [intToBytes(MAX_UINT512), 0], - ])(`should get the bit at the given index of bytes value`, async (a, b) => { - const avmResult = await getAvmResult({ appClient }, 'verify_getbit_bytes', asUint8Array(a), b) - const result = op.getBit(a, b) + ])(`should get the bit at the given index of bytes value`, async ([a, b], { appClientMiscellaneousOpsContract: appClient }) => { + const avmResult = await getAvmResult({ appClient }, 'verify_getbit_bytes', asUint8Array(a as bytes), b as number) + const result = op.getBit(a, b as number) expect(result).toEqual(avmResult) }) - test.each([ + test.for([ [Bytes([0x00]), 8], [intToBytes(MAX_UINT64), 64], [intToBytes(MAX_UINT64 - 1n), 64], [intToBytes(MAX_UINT512), 512], [intToBytes(MAX_UINT512 - 1n), 512], - ])('should throw error when index out of bound of bytes value', async (a, b) => { - await expect(getAvmResult({ appClient }, 'verify_getbit_bytes', asUint8Array(a), b)).rejects.toThrow( + ])('should throw error when index out of bound of bytes value', async ([a, b], { appClientMiscellaneousOpsContract: appClient }) => { + await expect(getAvmResult({ appClient }, 'verify_getbit_bytes', asUint8Array(a as bytes), b as number)).rejects.toThrow( 'getbit index beyond byteslice', ) - expect(() => op.getBit(a, b)).toThrow(/getBit index \d+ is beyond length/) + expect(() => op.getBit(a, b as number)).toThrow(/getBit index \d+ is beyond length/) }) - test.each([ + test.for([ [0, 0], [0, 3], [0, 10], @@ -616,23 +659,23 @@ describe('Pure op codes', async () => { [MAX_UINT64, 63], [MAX_UINT64 - 1n, 63], [MAX_UINT64, 0], - ])(`should get the bit at the given index of uint64 value`, async (a, b) => { + ])(`should get the bit at the given index of uint64 value`, async ([a, b], { appClientMiscellaneousOpsContract: appClient }) => { const avmResult = await getAvmResult({ appClient }, 'verify_getbit_uint64', a, b) const result = op.getBit(a, b) expect(result).toEqual(avmResult) }) - test.each([ + test.for([ [MAX_UINT64, 64], [MAX_UINT64 - 1n, 64], - ])(`should throw error when index out of bound of uint64 value`, async (a, b) => { + ])(`should throw error when index out of bound of uint64 value`, async ([a, b], { appClientMiscellaneousOpsContract: appClient }) => { await expect(getAvmResult({ appClient }, 'verify_getbit_uint64', a, b)).rejects.toThrow('getbit index > 63') expect(() => op.getBit(a, b)).toThrow(/getBit index \d+ is beyond length/) }) }) describe('getByte', async () => { - test.each([ + test.for([ [Bytes([0x00]), 0], [getPaddedBytes(2, intToBytes(256)), 3], [getPaddedBytes(2, intToBytes(256)), 0], @@ -644,59 +687,65 @@ describe('Pure op codes', async () => { [intToBytes(MAX_UINT512), 63], [intToBytes(MAX_UINT512 - 1n), 63], [intToBytes(MAX_UINT512), 0], - ])('should get the bytes value of the given input', async (a, b) => { - const avmResult = await getAvmResult({ appClient }, 'verify_getbyte', asUint8Array(a), b) - const result = op.getByte(a, b) + ])('should get the bytes value of the given input', async ([a, b], { appClientMiscellaneousOpsContract: appClient }) => { + const avmResult = await getAvmResult({ appClient }, 'verify_getbyte', asUint8Array(a as bytes), b as number) + const result = op.getByte(a as bytes, b as number) expect(result).toEqual(avmResult) }) - test.each([ + test.for([ [Bytes([0x00]), 8], [intToBytes(MAX_UINT64), 64], [intToBytes(MAX_UINT64 - 1n), 64], [intToBytes(MAX_UINT512), 512], [intToBytes(MAX_UINT512 - 1n), 512], - ])('should thorw error when index out of bound', async (a, b) => { - await expect(getAvmResult({ appClient }, 'verify_getbyte', asUint8Array(a), b)).rejects.toThrow( + ])('should thorw error when index out of bound', async ([a, b], { appClientMiscellaneousOpsContract: appClient }) => { + await expect(getAvmResult({ appClient }, 'verify_getbyte', asUint8Array(a as bytes), b as number)).rejects.toThrow( 'getbyte index beyond array length', ) - expect(() => op.getByte(a, b)).toThrow(/getBytes index \d+ is beyond length/) + expect(() => op.getByte(a as bytes, b as number)).toThrow(/getBytes index \d+ is beyond length/) }) }) describe('itob', async () => { - test.each([0, 42, 100n, 256, 65535, MAX_UINT64])('should convert uint64 to bytes', async (a) => { - const avmResult = (await getAvmResult({ appClient }, 'verify_itob', a))! - const result = op.itob(a) - expect(result).toEqual(avmResult) - }) + test.for([0, 42, 100n, 256, 65535, MAX_UINT64])( + 'should convert uint64 to bytes', + async (a, { appClientMiscellaneousOpsContract: appClient }) => { + const avmResult = (await getAvmResult({ appClient }, 'verify_itob', a))! + const result = op.itob(a) + expect(result).toEqual(avmResult) + }, + ) - test.each([MAX_UINT64 + 1n, MAX_UINT512])('should throw error when input overflows', async (a) => { - await expect(getAvmResultRaw({ appClient }, 'verify_itob', a)).rejects.toThrow(avmIntArgOverflowError) - expect(() => op.itob(a)).toThrow(UINT64_OVERFLOW_UNDERFLOW_MESSAGE) - }) + test.for([MAX_UINT64 + 1n, MAX_UINT512])( + 'should throw error when input overflows', + async (a, { appClientMiscellaneousOpsContract: appClient }) => { + await expect(getAvmResultRaw({ appClient }, 'verify_itob', a)).rejects.toThrow(avmIntArgOverflowError) + expect(() => op.itob(a)).toThrow(UINT64_OVERFLOW_UNDERFLOW_MESSAGE) + }, + ) }) describe('len', async () => { - test.each([ - [Bytes(internal.encodingUtil.bigIntToUint8Array(0n)), 0], - [Bytes(internal.encodingUtil.bigIntToUint8Array(1n)), 0], - [Bytes(internal.encodingUtil.bigIntToUint8Array(MAX_UINT64)), 0], - [Bytes(internal.encodingUtil.bigIntToUint8Array(MAX_UINT512)), 0], - [Bytes(internal.encodingUtil.bigIntToUint8Array(MAX_UINT512 * MAX_UINT512)), 0], + test.for([ + [Bytes(encodingUtil.bigIntToUint8Array(0n)), 0], + [Bytes(encodingUtil.bigIntToUint8Array(1n)), 0], + [Bytes(encodingUtil.bigIntToUint8Array(MAX_UINT64)), 0], + [Bytes(encodingUtil.bigIntToUint8Array(MAX_UINT512)), 0], + [Bytes(encodingUtil.bigIntToUint8Array(MAX_UINT512 * MAX_UINT512)), 0], [Bytes(Array(8).fill(0x00).concat(Array(4).fill(0x0f))), 0], [Bytes([0x0f]), MAX_BYTES_SIZE - 1], [Bytes(), 0], - ])('should return the length of the bytes input', async (a, padSize) => { - const avmResult = await getAvmResult({ appClient }, 'verify_bytes_len', asUint8Array(a), padSize) - const paddedA = getPaddedBytes(padSize, a) + ])('should return the length of the bytes input', async ([a, padSize], { appClientMiscellaneousOpsContract: appClient }) => { + const avmResult = await getAvmResult({ appClient }, 'verify_bytes_len', asUint8Array(a as bytes), padSize as number) + const paddedA = getPaddedBytes(padSize as number, a as bytes) const result = op.len(paddedA) expect(result).toEqual(avmResult) }) }) describe('mulw', async () => { - test.each([ + test.for([ [0, 0], [1, 0], [0, 1], @@ -705,26 +754,26 @@ describe('Pure op codes', async () => { [MAX_UINT64 - 1n, 1], [100, MAX_UINT64], [MAX_UINT64, MAX_UINT64], - ])(`should calculate the multiplication result`, async (a, b) => { + ])(`should calculate the multiplication result`, async ([a, b], { appClientMiscellaneousOpsContract: appClient }) => { const avmResult = await getAvmResult({ appClient }, 'verify_mulw', a, b) const result = op.mulw(a, b) expect(result[0].valueOf()).toBe(avmResult[0]) expect(result[1].valueOf()).toBe(avmResult[1]) }) - test.each([ + test.for([ [1, MAX_UINT64 + 1n], [MAX_UINT64 + 1n, 1], [0, MAX_UINT512], [MAX_UINT512 * 2n, 0], - ])(`should throw error when input overflows`, async (a, b) => { + ])(`should throw error when input overflows`, async ([a, b], { appClientMiscellaneousOpsContract: appClient }) => { await expect(getAvmResult({ appClient }, 'verify_mulw', a, b)).rejects.toThrow(avmIntArgOverflowError) expect(() => op.mulw(a, b)).toThrow(UINT64_OVERFLOW_UNDERFLOW_MESSAGE) }) }) describe('replace', async () => { - test.each([ + test.for([ ['hello, world.', 5, '!!'], ['hello, world.', 5, ''], ['hello, world.', 5, ', there.'], @@ -732,27 +781,36 @@ describe('Pure op codes', async () => { ['hello, world.', 12, ''], ['hello, world.', 0, 'H'], ['', 0, ''], - ])(`should replace bytes in the input`, async (a, b, c) => { - const avmResult = (await getAvmResult({ appClient }, 'verify_replace', asUint8Array(a), b, asUint8Array(c)))! - const result = op.replace(a, b, c) + ])(`should replace bytes in the input`, async ([a, b, c], { appClientMiscellaneousOpsContract: appClient }) => { + const avmResult = (await getAvmResult( + { appClient }, + 'verify_replace', + asUint8Array(a as string), + b, + asUint8Array(c as string), + ))! + const result = op.replace(a as string, b as number, c as string) expect(result).toEqual(avmResult) }) - test.each([ + test.for([ ['', 0, 'A'], ['hello', 5, '!!'], ['hello', 6, '!'], ['hello', 0, 'Hello, world'], - ])(`should throw error when replacement result in longer bytes length`, async (a, b, c) => { - await expect(getAvmResultRaw({ appClient }, 'verify_replace', asUint8Array(a), b, asUint8Array(c))).rejects.toThrow( - /replacement (start|end) \d+ beyond (original )*length/, - ) - expect(() => op.replace(a, b, c)).toThrow(`expected value <= ${a.length}`) - }) + ])( + `should throw error when replacement result in longer bytes length`, + async ([a, b, c], { appClientMiscellaneousOpsContract: appClient }) => { + await expect( + getAvmResultRaw({ appClient }, 'verify_replace', asUint8Array(a as string), b, asUint8Array(c as string)), + ).rejects.toThrow(/replacement (start|end) \d+ beyond (original )*length/) + expect(() => op.replace(a as string, b as number, c as string)).toThrow(`expected value <= ${(a as string).length}`) + }, + ) }) describe('select', async () => { - test.each([ + test.for([ ['one', 'two', 0], ['one', 'two', 1], ['one', 'two', 2], @@ -760,51 +818,51 @@ describe('Pure op codes', async () => { ['one', 'two', false], [Bytes([0x00, 0x00, 0xff]), Bytes([0xff]), 0n], [Bytes([0x00, 0x00, 0xff]), Bytes([0xff]), 1n], - ])(`should select bytes according to the input`, async (a, b, c) => { + ])(`should select bytes according to the input`, async ([a, b, c], { appClientMiscellaneousOpsContract: appClient }) => { const avmResult = (await getAvmResult( { appClient }, 'verify_select_bytes', - asUint8Array(a), - asUint8Array(b), - c === true ? 1 : c === false ? 0 : c, + asUint8Array(a as string), + asUint8Array(b as string), + c === true ? 1 : c === false ? 0 : (c as number), ))! - const result = op.select(a, b, c) + const result = op.select(a as string, b as string, c as number) expect(result).toEqual(avmResult) }) - test.each([ + test.for([ [Bytes([0x00, 0x00, 0xff]), Bytes([0xff]), MAX_UINT64 + 1n], [Bytes([0x00, 0x00, 0xff]), Bytes([0xff]), MAX_UINT512], - ])(`should throw error when input overflows to select bytes`, async (a, b, c) => { - await expect(getAvmResultRaw({ appClient }, 'verify_select_bytes', asUint8Array(a), asUint8Array(b), c)).rejects.toThrow( - avmIntArgOverflowError, - ) - expect(() => op.select(a, b, c)).toThrow(UINT64_OVERFLOW_UNDERFLOW_MESSAGE) + ])(`should throw error when input overflows to select bytes`, async ([a, b, c], { appClientMiscellaneousOpsContract: appClient }) => { + await expect( + getAvmResultRaw({ appClient }, 'verify_select_bytes', asUint8Array(a as bytes), asUint8Array(b as bytes), c as bigint), + ).rejects.toThrow(avmIntArgOverflowError) + expect(() => op.select(a as bytes, b as bytes, c as bigint)).toThrow(UINT64_OVERFLOW_UNDERFLOW_MESSAGE) }) - test.each([ + test.for([ [10, 20, 0], [10, 20, 1], [256, 512, 2], [10, MAX_UINT64, true], [MAX_UINT64, 20, false], - ])('should select uint64 according to the input', async (a, b, c) => { + ])('should select uint64 according to the input', async ([a, b, c], { appClientMiscellaneousOpsContract: appClient }) => { const avmResult = await getAvmResult({ appClient }, 'verify_select_uint64', a, b, c === true ? 1 : c === false ? 0 : c) const result = op.select(a, b, c) expect(result).toEqual(avmResult) }) - test.each([ + test.for([ [MAX_UINT64 + 1n, MAX_UINT64 + 10n, MAX_UINT64 + 1n], [MAX_UINT512, MAX_UINT512, MAX_UINT512], - ])(`should throw error when input overflows to select uint64`, async (a, b, c) => { + ])(`should throw error when input overflows to select uint64`, async ([a, b, c], { appClientMiscellaneousOpsContract: appClient }) => { await expect(getAvmResult({ appClient }, 'verify_select_uint64', a, b, c)).rejects.toThrow(avmIntArgOverflowError) expect(() => op.select(a, b, c)).toThrow(UINT64_OVERFLOW_UNDERFLOW_MESSAGE) }) }) describe('setBit', async () => { - test.each([ + test.for([ [Bytes([0x00]), 0, 1], [getPaddedBytes(2, intToBytes(256)), 3, 1], [getPaddedBytes(2, intToBytes(256)), 0, 1], @@ -817,26 +875,32 @@ describe('Pure op codes', async () => { [intToBytes(MAX_UINT512 - 1n), 511, 1], [intToBytes(MAX_UINT64), 0, 0], [intToBytes(MAX_UINT512), 0, 0], - ])(`should set the bit at the given index of bytes value`, async (a, b, c) => { - const avmResult = (await getAvmResult({ appClient }, 'verify_setbit_bytes', asUint8Array(a), b, c))! - const result = op.setBit(a, b, c) as bytes + ])(`should set the bit at the given index of bytes value`, async ([a, b, c], { appClientMiscellaneousOpsContract: appClient }) => { + const avmResult = (await getAvmResult( + { appClient }, + 'verify_setbit_bytes', + asUint8Array(a as bytes), + b as number, + c as number, + ))! + const result = op.setBit(a as bytes, b as number, c as number) as bytes expect(result).toEqual(avmResult) }) - test.each([ + test.for([ [Bytes([0x00]), 8, 1], [intToBytes(MAX_UINT64), 64, 0], [intToBytes(MAX_UINT64 - 1n), 64, 1], [intToBytes(MAX_UINT512), 512, 0], [intToBytes(MAX_UINT512 - 1n), 512, 1], - ])('should throw error when index out of bound of bytes value', async (a, b, c) => { - await expect(getAvmResultRaw({ appClient }, 'verify_setbit_bytes', asUint8Array(a), b, c)).rejects.toThrow( - 'setbit index beyond byteslice', - ) - expect(() => op.setBit(a, b, c)).toThrow(/setBit index \d+ is beyond length/) + ])('should throw error when index out of bound of bytes value', async ([a, b, c], { appClientMiscellaneousOpsContract: appClient }) => { + await expect( + getAvmResultRaw({ appClient }, 'verify_setbit_bytes', asUint8Array(a as bytes), b as number, c as number), + ).rejects.toThrow('setbit index beyond byteslice') + expect(() => op.setBit(a as bytes, b as number, c as number)).toThrow(/setBit index \d+ is beyond length/) }) - it('should throw error when input is invalid', async () => { + test('should throw error when input is invalid', async ({ appClientMiscellaneousOpsContract: appClient }) => { const a = Bytes([0x00]) const b = 0 const c = 2 @@ -844,7 +908,7 @@ describe('Pure op codes', async () => { expect(() => op.setBit(a, b, c)).toThrow(`setBit value > 1`) }) - test.each([ + test.for([ [0, 0, 1], [0, 3, 1], [0, 10, 1], @@ -857,21 +921,24 @@ describe('Pure op codes', async () => { [MAX_UINT64, 63, 0], [MAX_UINT64 - 1n, 63, 1], [MAX_UINT64, 0, 0], - ])('should set the bit at the given index of uint64 value', async (a, b, c) => { + ])('should set the bit at the given index of uint64 value', async ([a, b, c], { appClientMiscellaneousOpsContract: appClient }) => { const avmResult = await getAvmResult({ appClient }, 'verify_setbit_uint64', a, b, c) const result = op.setBit(a, b, c) expect(result).toEqual(avmResult) }) - test.each([ + test.for([ [MAX_UINT64, 64, 0], [MAX_UINT64 - 1n, 64, 1], - ])(`should throw error when index out of bound of uint64 value`, async (a, b, c) => { - await expect(getAvmResult({ appClient }, 'verify_setbit_uint64', a, b, c)).rejects.toThrow('setbit index > 63') - expect(() => op.setBit(a, b, c)).toThrow(/setBit index \d+ is beyond length/) - }) + ])( + `should throw error when index out of bound of uint64 value`, + async ([a, b, c], { appClientMiscellaneousOpsContract: appClient }) => { + await expect(getAvmResult({ appClient }, 'verify_setbit_uint64', a, b, c)).rejects.toThrow('setbit index > 63') + expect(() => op.setBit(a, b, c)).toThrow(/setBit index \d+ is beyond length/) + }, + ) - it('should throw error when input is invalid', async () => { + test('should throw error when input is invalid', async ({ appClientMiscellaneousOpsContract: appClient }) => { const a = 0 const b = 2 const c = 2 @@ -881,7 +948,7 @@ describe('Pure op codes', async () => { }) describe('setByte', async () => { - test.each([ + test.for([ [Bytes([0x00]), 0, 1], [getPaddedBytes(2, intToBytes(256)), 3, 1], [getPaddedBytes(2, intToBytes(256)), 0, 1], @@ -894,26 +961,32 @@ describe('Pure op codes', async () => { [intToBytes(MAX_UINT512 - 1n), 1, 1], [intToBytes(MAX_UINT64), 0, 0], [intToBytes(MAX_UINT512), 0, 0], - ])(`should set bytes in the input`, async (a, b, c) => { - const avmResult = (await getAvmResult({ appClient }, 'verify_setbyte', asUint8Array(a), b, c))! - const result = op.setByte(a, b, c) + ])(`should set bytes in the input`, async ([a, b, c], { appClientMiscellaneousOpsContract: appClient }) => { + const avmResult = (await getAvmResult( + { appClient }, + 'verify_setbyte', + asUint8Array(a as bytes), + b as number, + c as number, + ))! + const result = op.setByte(a as bytes, b as number, c as number) expect(result).toEqual(avmResult) }) - test.each([ + test.for([ [Bytes([0x00]), 8, 1], [intToBytes(MAX_UINT64), 64, 0], [intToBytes(MAX_UINT64 - 1n), 64, 1], [intToBytes(MAX_UINT512), 512, 0], [intToBytes(MAX_UINT512 - 1n), 512, 1], - ])(`should throw error when index out of bound of bytes`, async (a, b, c) => { - await expect(getAvmResultRaw({ appClient }, 'verify_setbyte', asUint8Array(a), b, c)).rejects.toThrow( + ])(`should throw error when index out of bound of bytes`, async ([a, b, c], { appClientMiscellaneousOpsContract: appClient }) => { + await expect(getAvmResultRaw({ appClient }, 'verify_setbyte', asUint8Array(a as bytes), b as number, c as number)).rejects.toThrow( 'setbyte index beyond array length', ) - expect(() => op.setByte(a, b, c)).toThrow(`setByte index ${b} is beyond length`) + expect(() => op.setByte(a as bytes, b as number, c as number)).toThrow(`setByte index ${b} is beyond length`) }) - it('should throw error when input is invalid', async () => { + test('should throw error when input is invalid', async ({ appClientMiscellaneousOpsContract: appClient }) => { const a = Bytes([0x00]) const b = 0 const c = 256 @@ -923,7 +996,7 @@ describe('Pure op codes', async () => { }) describe('shl', async () => { - test.each([ + test.for([ [0, 0], [1, 0], [0, 1], @@ -932,33 +1005,33 @@ describe('Pure op codes', async () => { [1, 63], [MAX_UINT64 - 1n, 63], [MAX_UINT64, 63], - ])(`should shift left the input`, async (a, b) => { + ])(`should shift left the input`, async ([a, b], { appClientMiscellaneousOpsContract: appClient }) => { const avmResult = await getAvmResult({ appClient }, 'verify_shl', a, b) const result = op.shl(a, b) expect(result).toEqual(avmResult) }) - test.each([ + test.for([ [1, MAX_UINT64 + 1n], [MAX_UINT64 + 1n, 1], [0, MAX_UINT512], [MAX_UINT512 * 2n, 0], - ])(`should throw error when input overflows`, async (a, b) => { + ])(`should throw error when input overflows`, async ([a, b], { appClientMiscellaneousOpsContract: appClient }) => { await expect(getAvmResult({ appClient }, 'verify_shl', a, b)).rejects.toThrow(avmIntArgOverflowError) expect(() => op.shl(a, b)).toThrow(UINT64_OVERFLOW_UNDERFLOW_MESSAGE) }) - test.each([ + test.for([ [1, MAX_UINT64], [MAX_UINT64, 64], - ])(`should throw error when input is invalid`, async (a, b) => { + ])(`should throw error when input is invalid`, async ([a, b], { appClientMiscellaneousOpsContract: appClient }) => { await expect(getAvmResult({ appClient }, 'verify_shl', a, b)).rejects.toThrow('shl arg too big') expect(() => op.shl(a, b)).toThrow(`shl value ${b} >= 64`) }) }) describe('shr', async () => { - test.each([ + test.for([ [0, 0], [1, 0], [0, 1], @@ -966,46 +1039,52 @@ describe('Pure op codes', async () => { [1, 63], [MAX_UINT64 - 1n, 63], [MAX_UINT64, 63], - ])('should shift right the input', async (a, b) => { + ])('should shift right the input', async ([a, b], { appClientMiscellaneousOpsContract: appClient }) => { const avmResult = await getAvmResult({ appClient }, 'verify_shr', a, b) const result = op.shr(a, b) expect(result).toEqual(avmResult) }) - test.each([ + test.for([ [1, MAX_UINT64 + 1n], [MAX_UINT64 + 1n, 1], [0, MAX_UINT512], [MAX_UINT512 * 2n, 1], - ])('should throw error when input overflows', async (a, b) => { + ])('should throw error when input overflows', async ([a, b], { appClientMiscellaneousOpsContract: appClient }) => { await expect(getAvmResult({ appClient }, 'verify_shr', a, b)).rejects.toThrow(avmIntArgOverflowError) expect(() => op.shr(a, b)).toThrow(UINT64_OVERFLOW_UNDERFLOW_MESSAGE) }) - test.each([ + test.for([ [1, MAX_UINT64], [MAX_UINT64, 64], - ])('should throw error when input is invalid', async (a, b) => { + ])('should throw error when input is invalid', async ([a, b], { appClientMiscellaneousOpsContract: appClient }) => { await expect(getAvmResult({ appClient }, 'verify_shr', a, b)).rejects.toThrow('shr arg too big') expect(() => op.shr(a, b)).toThrow(`shr value ${b} >= 64`) }) }) describe('sqrt', async () => { - test.each([0, 1, 2, 9, 13, MAX_UINT64])('should calculate the square root of the input', async (a) => { - const avmResult = await getAvmResult({ appClient }, 'verify_sqrt', a) - const result = op.sqrt(a) - expect(result).toEqual(avmResult) - }) + test.for([0, 1, 2, 9, 13, MAX_UINT64])( + 'should calculate the square root of the input', + async (a, { appClientMiscellaneousOpsContract: appClient }) => { + const avmResult = await getAvmResult({ appClient }, 'verify_sqrt', a) + const result = op.sqrt(a) + expect(result).toEqual(avmResult) + }, + ) - test.each([MAX_UINT64 + 1n, MAX_UINT512, MAX_UINT512 * 2n])('should throw error when input overflows', async (a) => { - await expect(getAvmResult({ appClient }, 'verify_sqrt', a)).rejects.toThrow(avmIntArgOverflowError) - expect(() => op.sqrt(a)).toThrow(UINT64_OVERFLOW_UNDERFLOW_MESSAGE) - }) + test.for([MAX_UINT64 + 1n, MAX_UINT512, MAX_UINT512 * 2n])( + 'should throw error when input overflows', + async (a, { appClientMiscellaneousOpsContract: appClient }) => { + await expect(getAvmResult({ appClient }, 'verify_sqrt', a)).rejects.toThrow(avmIntArgOverflowError) + expect(() => op.sqrt(a)).toThrow(UINT64_OVERFLOW_UNDERFLOW_MESSAGE) + }, + ) }) describe('substring', async () => { - test.each([ + test.for([ ['hello, world.', 5, 5], ['hello, world.', 5, 6], ['hello, world.', 5, 7], @@ -1015,35 +1094,39 @@ describe('Pure op codes', async () => { ['hello, world.', 0, 2], ['hello, world.', 0, 13], ['', 0, 0], - ])('should extract substring from the input', async (a, b, c) => { - const avmResult = await getAvmResult({ appClient }, 'verify_substring', asUint8Array(a), b, c) - const result = op.substring(a, b, c) + ])('should extract substring from the input', async ([a, b, c], { appClientMiscellaneousOpsContract: appClient }) => { + const avmResult = await getAvmResult({ appClient }, 'verify_substring', asUint8Array(a as string), b, c) + const result = op.substring(a as string, b as number, c as number) expect(result).toEqual(avmResult) }) - test.each([ + test.for([ ['', 0, 1], ['hello', 5, 7], ['hello', 4, 3], ['hello', 0, 7], - ])('should throw error when input is invalid', async (a, b, c) => { - await expect(getAvmResultRaw({ appClient }, 'verify_substring', asUint8Array(a), b, c)).rejects.toThrow( + ])('should throw error when input is invalid', async ([a, b, c], { appClientMiscellaneousOpsContract: appClient }) => { + await expect(getAvmResultRaw({ appClient }, 'verify_substring', asUint8Array(a as string), b, c)).rejects.toThrow( + /(substring range beyond length of string)|(substring end before start)/, + ) + expect(() => op.substring(a as string, b as number, c as number)).toThrow( /(substring range beyond length of string)|(substring end before start)/, ) - expect(() => op.substring(a, b, c)).toThrow(/(substring range beyond length of string)|(substring end before start)/) }) - test.each([ + test.for([ ['', MAX_UINT64, MAX_UINT64 + 1n], ['hello', MAX_UINT64 + 1n, MAX_UINT64 + 2n], - ])('should throw error when input overflows', async (a, b, c) => { - await expect(getAvmResultRaw({ appClient }, 'verify_substring', asUint8Array(a), b, c)).rejects.toThrow(avmIntArgOverflowError) - expect(() => op.substring(a, b, c)).toThrow(UINT64_OVERFLOW_UNDERFLOW_MESSAGE) + ])('should throw error when input overflows', async ([a, b, c], { appClientMiscellaneousOpsContract: appClient }) => { + await expect(getAvmResultRaw({ appClient }, 'verify_substring', asUint8Array(a as string), b as bigint, c as bigint)).rejects.toThrow( + avmIntArgOverflowError, + ) + expect(() => op.substring(a as string, b as bigint, c as bigint)).toThrow(UINT64_OVERFLOW_UNDERFLOW_MESSAGE) }) }) describe('jsonRef', async () => { - it('should throw not available error', async () => { + test('should throw not available error', async () => { expect(() => op.JsonRef.jsonObject(Bytes(''), Bytes(''))).toThrow('JsonRef.jsonObject is not available in test context') expect(() => op.JsonRef.jsonString(Bytes(''), Bytes(''))).toThrow('JsonRef.jsonString is not available in test context') expect(() => op.JsonRef.jsonUint64(Bytes(''), Bytes(''))).toThrow('JsonRef.jsonUint64 is not available in test context') diff --git a/tests/references/arc4-contract.spec.ts b/tests/references/arc4-contract.spec.ts index 13b5c67..8f28da0 100644 --- a/tests/references/arc4-contract.spec.ts +++ b/tests/references/arc4-contract.spec.ts @@ -1,17 +1,5 @@ -import { - Account, - arc4, - assert, - BaseContract, - bytes, - Bytes, - contract, - Contract, - Global, - Txn, - uint64, - Uint64, -} from '@algorandfoundation/algorand-typescript' +import type { Account, bytes, uint64 } from '@algorandfoundation/algorand-typescript' +import { arc4, assert, BaseContract, Bytes, contract, Contract, Global, Txn, Uint64 } from '@algorandfoundation/algorand-typescript' import { TestExecutionContext } from '@algorandfoundation/algorand-typescript-testing' import { afterEach, describe, expect, it } from 'vitest' import { lazyContext } from '../../src/context-helpers/internal-context' diff --git a/tests/references/asset.spec.ts b/tests/references/asset.spec.ts index 980d72c..1e85144 100644 --- a/tests/references/asset.spec.ts +++ b/tests/references/asset.spec.ts @@ -1,7 +1,7 @@ import { Account, Bytes, Uint64 } from '@algorandfoundation/algorand-typescript' import { afterEach, describe, expect, it, test } from 'vitest' import { TestExecutionContext } from '../../src' -import { AssetCls } from '../../src/impl/asset' +import { AssetCls } from '../../src/impl/reference' import { asBytes, asUint64, asUint8Array } from '../../src/util' describe('Asset', () => { diff --git a/tests/references/box-map.spec.ts b/tests/references/box-map.spec.ts index d6d379e..20cc360 100644 --- a/tests/references/box-map.spec.ts +++ b/tests/references/box-map.spec.ts @@ -1,10 +1,10 @@ -import { biguint, BigUint, BoxMap, Bytes, bytes, op, uint64, Uint64 } from '@algorandfoundation/algorand-typescript' +import type { biguint, bytes, uint64 } from '@algorandfoundation/algorand-typescript' +import { BigUint, BoxMap, Bytes, op, Uint64 } from '@algorandfoundation/algorand-typescript' import { TestExecutionContext } from '@algorandfoundation/algorand-typescript-testing' import { ARC4Encoded, DynamicArray, interpretAsArc4, Str, UintN64 } from '@algorandfoundation/algorand-typescript/arc4' -import { afterEach, describe, expect, test } from 'vitest' +import { afterEach, describe, expect, it, test } from 'vitest' import { MAX_UINT64 } from '../../src/constants' import { toBytes } from '../../src/encoders' -import { DeliberateAny } from '../../src/typescript-helpers' import { asBytes } from '../../src/util' const BOX_NOT_CREATED_ERROR = 'Box has not been created' @@ -109,34 +109,34 @@ describe('BoxMap', () => { expect(box.keyPrefix.length.valueOf()).toBeGreaterThan(0) expect(box.keyPrefix).toEqual(asBytes(keyPrefix)) - expect(() => box.get(Bytes(''))).toThrow(BOX_NOT_CREATED_ERROR) - expect(() => box.length(Bytes(''))).toThrow(BOX_NOT_CREATED_ERROR) + expect(() => box(Bytes('')).value).toThrow(BOX_NOT_CREATED_ERROR) + expect(() => box(Bytes('')).length).toThrow(BOX_NOT_CREATED_ERROR) }) }) test.each(testData)('key %s and value %s can be set as value', ({ key, value, withBoxContext }) => { withBoxContext((boxMap) => { - boxMap.set(key as never, value as never) + boxMap(key as never).value = value - const boxContent = (boxMap as DeliberateAny).get(key) + const boxContent = boxMap(key as never).value const fullKey = keyPrefix.concat(toBytes(key)) const [opBoxContent, opExists] = op.Box.get(fullKey) const [opLength, _] = op.Box.length(fullKey) expect(opExists).toBe(true) - expect(boxMap.length(key as never)).toEqual(opLength) + expect(boxMap(key as never).length).toEqual(opLength) expect(toBytes(boxContent)).toEqual(opBoxContent) }) }) test.each(testData)('key %s and value %s can be delete', ({ key, value, withBoxContext }) => { withBoxContext((boxMap) => { - boxMap.set(key as never, value as never) + boxMap(key as never).value = value - boxMap.delete(key as never) + boxMap(key as never).delete() - expect(() => (boxMap as DeliberateAny).get(key)).toThrow(BOX_NOT_CREATED_ERROR) + expect(() => boxMap(key as never).value).toThrow(BOX_NOT_CREATED_ERROR) const fullKey = keyPrefix.concat(toBytes(key)) const [opBoxContent, opExists] = op.Box.get(fullKey) expect(opExists).toBe(false) @@ -146,9 +146,9 @@ describe('BoxMap', () => { test.each(testData)('can retrieve existing key %s and value %s using maybe', ({ key, value, withBoxContext }) => { withBoxContext((boxMap) => { - boxMap.set(key as never, value as never) + boxMap(key as never).value = value - const [content, exists] = boxMap.maybe(key as never) + const [content, exists] = boxMap(key as never).maybe() const fullKey = keyPrefix.concat(toBytes(key)) const [opContent, opExists] = op.Box.get(fullKey) @@ -156,17 +156,17 @@ describe('BoxMap', () => { expect(exists).toBe(true) expect(opExists).toBe(true) - expect(boxMap.length(key as never)).toEqual(opLength) + expect(boxMap(key as never).length).toEqual(opLength) expect(toBytes(content)).toEqual(opContent) }) }) test.each(testData)('can retrieve non-existing value using maybe', ({ key, value, emptyValue, withBoxContext }) => { withBoxContext((boxMap) => { - boxMap.set(key as never, value as never) - boxMap.delete(key as never) + boxMap(key as never).value = value + boxMap(key as never).delete() - const [content, exists] = boxMap.maybe(key as never) + const [content, exists] = boxMap(key as never).maybe() expect(exists).toBe(false) if (content instanceof ARC4Encoded) { @@ -184,11 +184,11 @@ describe('BoxMap', () => { test.each(testData)('can get typed value after using op.Box.put', ({ key, value, newValue, withBoxContext }) => { withBoxContext((boxMap) => { - boxMap.set(key as never, value as never) + boxMap(key as never).value = value if (value instanceof ARC4Encoded) { - expect((boxMap as DeliberateAny).get(key).bytes).toEqual(value.bytes) + expect((boxMap(key as never).value as ARC4Encoded).bytes).toEqual(value.bytes) } else { - expect((boxMap as DeliberateAny).get(key)).toEqual(value) + expect(boxMap(key as never).value).toEqual(value) } const newBytesValue = toBytes(newValue) @@ -198,10 +198,36 @@ describe('BoxMap', () => { expect(opContent).toEqual(newBytesValue) if (newValue instanceof ARC4Encoded) { - expect((boxMap as DeliberateAny).get(key).bytes).toEqual(newValue.bytes) + expect((boxMap(key as never).value as ARC4Encoded).bytes).toEqual(newValue.bytes) } else { - expect((boxMap as DeliberateAny).get(key)).toEqual(newValue) + expect(boxMap(key as never).value).toEqual(newValue) } }) }) + + it('can maintain the mutations to the array box value', () => { + ctx.txn.createScope([ctx.any.txn.applicationCall()]).execute(() => { + const boxMap = BoxMap>({ keyPrefix }) + const key = new Str('jkl') + const value = new DynamicArray(new UintN64(100), new UintN64(200)) + boxMap(key).value = value + expect(boxMap(key).value.length).toEqual(2) + expect(boxMap(key).value.at(-1).native).toEqual(200) + + // newly pushed value should be retained + boxMap(key).value.push(new UintN64(300)) + expect(boxMap(key).value.length).toEqual(3) + expect(boxMap(key).value.at(-1).native).toEqual(300) + + // setting bytes value through op should be reflected in the box value. + const copy = boxMap(key).value.copy() + copy[2] = new UintN64(400) + expect(boxMap(key).value.at(-1).native).toEqual(300) + + const fullKey = keyPrefix.concat(toBytes(key)) + op.Box.put(fullKey, toBytes(copy)) + expect(boxMap(key).value.length).toEqual(3) + expect(boxMap(key).value.at(-1).native).toEqual(400) + }) + }) }) diff --git a/tests/references/box.spec.ts b/tests/references/box.spec.ts index 9893344..0ced8cb 100644 --- a/tests/references/box.spec.ts +++ b/tests/references/box.spec.ts @@ -1,10 +1,11 @@ -import { BigUint, biguint, Box, bytes, Bytes, op, uint64, Uint64 } from '@algorandfoundation/algorand-typescript' +import type { biguint, bytes, uint64 } from '@algorandfoundation/algorand-typescript' +import { BigUint, Box, Bytes, op, Uint64 } from '@algorandfoundation/algorand-typescript' import { TestExecutionContext } from '@algorandfoundation/algorand-typescript-testing' import { ARC4Encoded, DynamicArray, interpretAsArc4, Str, UintN64 } from '@algorandfoundation/algorand-typescript/arc4' import { itob } from '@algorandfoundation/algorand-typescript/op' import { afterEach, describe, expect, it, test } from 'vitest' import { toBytes } from '../../src/encoders' -import { DeliberateAny } from '../../src/typescript-helpers' +import type { DeliberateAny } from '../../src/typescript-helpers' import { asBytes } from '../../src/util' import { BoxContract } from '../artifacts/box-contract/contract.algo' @@ -204,4 +205,28 @@ describe('Box', () => { } }) }) + + it('can maintain the mutations to the box value', () => { + ctx.txn.createScope([ctx.any.txn.applicationCall()]).execute(() => { + const box = Box>({ key }) + const value = new DynamicArray(new UintN64(100), new UintN64(200)) + box.value = value + expect(box.value.length).toEqual(2) + expect(box.value.at(-1).native).toEqual(200) + + // newly pushed value should be retained + box.value.push(new UintN64(300)) + expect(box.value.length).toEqual(3) + expect(box.value.at(-1).native).toEqual(300) + + // setting bytes value through op should be reflected in the box value. + const copy = box.value.copy() + copy[2] = new UintN64(400) + expect(box.value.at(-1).native).toEqual(300) + + op.Box.put(key, toBytes(copy)) + expect(box.value.length).toEqual(3) + expect(box.value.at(-1).native).toEqual(400) + }) + }) }) diff --git a/tests/state-op-codes.spec.ts b/tests/state-op-codes.spec.ts index 84326de..c99da31 100644 --- a/tests/state-op-codes.spec.ts +++ b/tests/state-op-codes.spec.ts @@ -1,18 +1,20 @@ import { AlgoAmount } from '@algorandfoundation/algokit-utils/types/amount' -import { AppClient } from '@algorandfoundation/algokit-utils/types/app-client' -import { AppSpec } from '@algorandfoundation/algokit-utils/types/app-spec' -import { Account, arc4, bytes, Bytes, internal, op, TransactionType, uint64, Uint64 } from '@algorandfoundation/algorand-typescript' +import type { AppClient } from '@algorandfoundation/algokit-utils/types/app-client' +import type { bytes, uint64 } from '@algorandfoundation/algorand-typescript' +import { Account, arc4, Bytes, Global, OnCompleteAction, op, TransactionType, Uint64 } from '@algorandfoundation/algorand-typescript' import { DynamicBytes, UintN64 } from '@algorandfoundation/algorand-typescript/arc4' -import { afterEach, describe, expect, it, test } from 'vitest' +import { afterEach, beforeAll, describe, expect } from 'vitest' import { TestExecutionContext } from '../src' import { ABI_RETURN_VALUE_LOG_PREFIX, MIN_TXN_FEE, OnApplicationComplete, ZERO_ADDRESS } from '../src/constants' +import { lazyContext } from '../src/context-helpers/internal-context' import { testInvariant } from '../src/errors' import { Block, gloadBytes, gloadUint64 } from '../src/impl' -import { AccountCls } from '../src/impl/account' -import { InnerTxn } from '../src/impl/itxn' -import { ApplicationTransaction } from '../src/impl/transactions' -import { DeliberateAny } from '../src/typescript-helpers' -import { asBigInt, asNumber, asUint64Cls, asUint8Array } from '../src/util' +import type { InnerTxn } from '../src/impl/itxn' +import { BytesCls, Uint64Cls } from '../src/impl/primitives' +import { AccountCls, encodeAddress } from '../src/impl/reference' +import type { ApplicationTransaction } from '../src/impl/transactions' +import type { DeliberateAny } from '../src/typescript-helpers' +import { asBigInt, asBigUintCls, asNumber, asUint64Cls, asUint8Array, getRandomBytes } from '../src/util' import { AppExpectingEffects } from './artifacts/created-app-asset/contract.algo' import { ItxnDemoContract, @@ -26,35 +28,33 @@ import { StateAssetHoldingContract, StateAssetParamsContract, } from './artifacts/state-ops/contract.algo' -import acctParamsAppSpecJson from './artifacts/state-ops/data/StateAcctParamsGetContract.arc32.json' -import appGlobalAppSpecJson from './artifacts/state-ops/data/StateAppGlobalContract.arc32.json' -import appGlobalExAppSpecJson from './artifacts/state-ops/data/StateAppGlobalExContract.arc32.json' -import appLocalAppSpecJson from './artifacts/state-ops/data/StateAppLocalContract.arc32.json' -import appLocalExAppSpecJson from './artifacts/state-ops/data/StateAppLocalExContract.arc32.json' -import appParamsAppSpecJson from './artifacts/state-ops/data/StateAppParamsContract.arc32.json' -import assetHoldingAppSpecJson from './artifacts/state-ops/data/StateAssetHoldingContract.arc32.json' -import assetParamsAppSpecJson from './artifacts/state-ops/data/StateAssetParamsContract.arc32.json' -import { - generateTestAccount, - generateTestAsset, - getAlgorandAppClient, - getAlgorandAppClientWithApp, - getAvmResult, - getLocalNetDefaultAccount, - INITIAL_BALANCE_MICRO_ALGOS, -} from './avm-invoker' +import { generateTestAsset, getAvmResult, INITIAL_BALANCE_MICRO_ALGOS } from './avm-invoker' +import { createArc4TestFixture } from './test-fixture' describe('State op codes', async () => { + const [test, localnetFixture] = createArc4TestFixture('tests/artifacts/state-ops/contract.algo.ts', { + ItxnDemoContract: {}, + ITxnOpsContract: {}, + StateAcctParamsGetContract: {}, + StateAppGlobalContract: {}, + StateAppGlobalExContract: {}, + StateAppLocalContract: {}, + StateAppLocalExContract: {}, + StateAppParamsContract: {}, + StateAssetHoldingContract: {}, + StateAssetParamsContract: {}, + }) const ctx = new TestExecutionContext() - afterEach(async () => { + beforeAll(async () => { + await localnetFixture.newScope() + }) + afterEach(() => { ctx.reset() }) describe('AcctParams', async () => { - const [appClient, dummyAccount] = await Promise.all([getAlgorandAppClient(acctParamsAppSpecJson as AppSpec), generateTestAccount()]) - - test.each([ + test.for([ ['verify_acct_balance', INITIAL_BALANCE_MICRO_ALGOS + 100_000], ['verify_acct_min_balance', 100_000], ['verify_acct_auth_addr', ZERO_ADDRESS], @@ -67,27 +67,31 @@ describe('State op codes', async () => { ['verify_acct_total_assets', 0], ['verify_acct_total_boxes', 0], ['verify_acct_total_box_bytes', 0], - ])('%s should return %s', async (methodName, expectedValue) => { + ])('%s should return %s', async ([methodName, expectedValue], { appClientStateAcctParamsGetContract: appClient }) => { + const dummyAccountAddress = await localnetFixture.context.generateAccount({ + initialFunds: AlgoAmount.MicroAlgos(INITIAL_BALANCE_MICRO_ALGOS + 100_000), + }) + const dummyAccount = Bytes.fromBase32(dummyAccountAddress.addr.toString()) const mockAccount = ctx.any.account({ address: dummyAccount, - balance: Uint64(INITIAL_BALANCE_MICRO_ALGOS + 100000), - minBalance: Uint64(100000), + balance: INITIAL_BALANCE_MICRO_ALGOS + 100_000, + minBalance: 100_000, authAddress: Account(ZERO_ADDRESS), - totalNumUint: Uint64(0), - totalNumByteSlice: Uint64(0), - totalExtraAppPages: Uint64(0), - totalAppsCreated: Uint64(0), - totalAppsOptedIn: Uint64(0), - totalAssetsCreated: Uint64(0), - totalAssets: Uint64(0), - totalBoxes: Uint64(0), - totalBoxBytes: Uint64(0), + totalNumUint: 0, + totalNumByteSlice: 0, + totalExtraAppPages: 0, + totalAppsCreated: 0, + totalAppsOptedIn: 0, + totalAssetsCreated: 0, + totalAssets: 0, + totalBoxes: 0, + totalBoxBytes: 0, }) const avmResult = await getAvmResult( { appClient, sendParams: { staticFee: AlgoAmount.Algos(1000) } }, - methodName, - asUint8Array(dummyAccount.bytes), + methodName as string, + asUint8Array(mockAccount.bytes), ) testInvariant(avmResult !== undefined, 'There must be an AVM result') const mockContract = ctx.contract.create(StateAcctParamsGetContract) @@ -96,15 +100,80 @@ describe('State op codes', async () => { expect(mockResult).toEqual(avmResult) expect(mockResult).toEqual(expectedValue) }) + + test('should return true when account is eligible for incentive', async ({ appClientStateAcctParamsGetContract: appClient }) => { + const dummyAccountAddress = await localnetFixture.context.generateAccount({ + initialFunds: AlgoAmount.MicroAlgos(INITIAL_BALANCE_MICRO_ALGOS), + }) + const dummyAccount = Bytes.fromBase32(dummyAccountAddress.addr.toString()) + const mockAccount = ctx.any.account({ + address: dummyAccount, + balance: INITIAL_BALANCE_MICRO_ALGOS + 100000, + minBalance: 100000, + }) + ctx.ledger.patchGlobalData({ payoutsEnabled: true, payoutsGoOnlineFee: 10 }) + ctx.txn.createScope([ctx.any.txn.keyRegistration({ sender: mockAccount, fee: 10 })]).execute(() => { + expect(op.AcctParams.acctIncentiveEligible(mockAccount)).toEqual([true, true]) + }) + + await appClient.algorand.send.onlineKeyRegistration({ + sender: encodeAddress(asUint8Array(dummyAccount)), + voteKey: getRandomBytes(32).asUint8Array(), + selectionKey: getRandomBytes(32).asUint8Array(), + voteFirst: 1n, + voteLast: 1000000n, + voteKeyDilution: 1000000n, + stateProofKey: getRandomBytes(64).asUint8Array(), + staticFee: AlgoAmount.Algos(10), + }) + const avmResult = await getAvmResult( + { appClient, sendParams: { staticFee: AlgoAmount.Algos(10) } }, + 'verify_acct_incentive_eligible', + asUint8Array(mockAccount.bytes), + ) + expect(avmResult).toEqual(true) + }) + + test('should return last round as last proposed and last hearbeat by default', async () => { + const dummyAccountAddress = await localnetFixture.context.generateAccount({ + initialFunds: AlgoAmount.MicroAlgos(INITIAL_BALANCE_MICRO_ALGOS), + }) + const dummyAccount = Bytes.fromBase32(dummyAccountAddress.addr.toString()) + const mockAccount = ctx.any.account({ + address: dummyAccount, + balance: INITIAL_BALANCE_MICRO_ALGOS + 100000, + }) + const incentiveEligible = op.AcctParams.acctIncentiveEligible(mockAccount) + const lastProposed = op.AcctParams.acctLastProposed(mockAccount) + const lastHeartbeat = op.AcctParams.acctLastHeartbeat(mockAccount) + expect(incentiveEligible).toEqual([false, true]) + expect(lastProposed).toEqual([Global.round, true]) + expect(lastHeartbeat).toEqual([Global.round, true]) + }) + + test('should return configured round as last proposed and last hearbeat', async () => { + const dummyAccountAddress = await localnetFixture.context.generateAccount({ + initialFunds: AlgoAmount.MicroAlgos(INITIAL_BALANCE_MICRO_ALGOS), + }) + const dummyAccount = Bytes.fromBase32(dummyAccountAddress.addr.toString()) + const mockAccount = ctx.any.account({ + address: dummyAccount, + balance: INITIAL_BALANCE_MICRO_ALGOS + 100000, + incentiveEligible: true, + lastProposed: 100, + lastHeartbeat: 200, + }) + const incentiveEligible = op.AcctParams.acctIncentiveEligible(mockAccount) + const lastProposed = op.AcctParams.acctLastProposed(mockAccount) + const lastHeartbeat = op.AcctParams.acctLastHeartbeat(mockAccount) + expect(incentiveEligible).toEqual([true, true]) + expect(lastProposed).toEqual([100, true]) + expect(lastHeartbeat).toEqual([200, true]) + }) }) describe('AppParams', async () => { - const [[appClient, app], dummyAccount] = await Promise.all([ - getAlgorandAppClientWithApp(appParamsAppSpecJson as AppSpec), - getLocalNetDefaultAccount(), - ]) - - test.each([ + test.for([ ['verify_app_params_get_approval_program', undefined], ['verify_app_params_get_clear_state_program', undefined], ['verify_app_params_get_global_num_uint', 0], @@ -114,19 +183,24 @@ describe('State op codes', async () => { ['verify_app_params_get_extra_program_pages', 0], ['verify_app_params_get_creator', 'app.creator'], ['verify_app_params_get_address', 'app.address'], - ])('%s should return %s', async (methodName, expectedValue) => { + ])('%s should return %s', async ([methodName, expectedValue], { appFactoryStateAppParamsContract, testAccount }) => { + const { result: app, appClient } = await appFactoryStateAppParamsContract.deploy({}) const application = ctx.any.application({ applicationId: app.appId, approvalProgram: Bytes(app.compiledApproval!.compiledBase64ToBytes), clearStateProgram: Bytes(app.compiledClear!.compiledBase64ToBytes), - globalNumUint: Uint64(0), - globalNumBytes: Uint64(0), - localNumUint: Uint64(0), - localNumBytes: Uint64(0), - extraProgramPages: Uint64(0), - creator: Account(Bytes.fromBase32(dummyAccount.addr.toString())), + globalNumUint: 0, + globalNumBytes: 0, + localNumUint: 0, + localNumBytes: 0, + extraProgramPages: 0, + creator: Account(Bytes.fromBase32(testAccount.addr.toString())), }) - const avmResult = await getAvmResult({ appClient, sendParams: { staticFee: AlgoAmount.Algos(1000) } }, methodName, app.appId) + const avmResult = await getAvmResult( + { appClient, sendParams: { staticFee: AlgoAmount.Algos(1000) } }, + methodName as string, + app.appId, + ) const mockContract = ctx.contract.create(StateAppParamsContract) const mockResult = mockContract[methodName as keyof StateAppParamsContract](application) @@ -144,47 +218,40 @@ describe('State op codes', async () => { }) describe('AssetHolding', async () => { - const [appClient, dummyAccount] = await Promise.all([ - getAlgorandAppClient(assetHoldingAppSpecJson as AppSpec), - getLocalNetDefaultAccount(), - ]) - - test.each([ + test.for([ ['verify_asset_holding_get', 100], ['verify_asset_frozen_get', false], - ])('should return the correct field value of the asset holding', async (methodName, expectedValue) => { - const dummyAsset = await generateTestAsset({ - sender: dummyAccount.addr, - total: 100n, - decimals: 0, - defaultFrozen: false, - }) - const avmResult = await getAvmResult({ appClient }, methodName, dummyAccount.addr.toString(), asBigInt(dummyAsset)) - - const mockAsset = ctx.any.asset() - const mockAccount = ctx.any.account({ - optedAssetBalances: new Map([[mockAsset.id, 100]]), - }) - const mockContract = ctx.contract.create(StateAssetHoldingContract) - const mockResult = mockContract[methodName as keyof StateAssetHoldingContract](mockAccount, mockAsset) - - if (typeof mockResult === 'boolean') { - expect(mockResult).toEqual(avmResult) - expect(mockResult).toEqual(expectedValue) - } else { - expect(mockResult.valueOf()).toEqual(avmResult) - expect(asNumber(mockResult as uint64)).toEqual(expectedValue) - } - }) + ])( + 'should return the correct field value of the asset holding', + async ([methodName, expectedValue], { appClientStateAssetHoldingContract: appClient, testAccount, assetFactory }) => { + const dummyAsset = await generateTestAsset(assetFactory, { + sender: testAccount.addr, + total: 100n, + decimals: 0, + defaultFrozen: false, + }) + const avmResult = await getAvmResult({ appClient }, methodName as string, testAccount.addr.toString(), dummyAsset) + + const mockAsset = ctx.any.asset() + const mockAccount = ctx.any.account({ + optedAssetBalances: new Map([[mockAsset.id, 100]]), + }) + const mockContract = ctx.contract.create(StateAssetHoldingContract) + const mockResult = mockContract[methodName as keyof StateAssetHoldingContract](mockAccount, mockAsset) + + if (typeof mockResult === 'boolean') { + expect(mockResult).toEqual(avmResult) + expect(mockResult).toEqual(expectedValue) + } else { + expect(mockResult.valueOf()).toEqual(avmResult) + expect(asNumber(mockResult as uint64)).toEqual(expectedValue) + } + }, + ) }) describe('AssetParams', async () => { - const [appClient, dummyAccount] = await Promise.all([ - getAlgorandAppClient(assetParamsAppSpecJson as AppSpec), - getLocalNetDefaultAccount(), - ]) - - test.each([ + test.for([ ['verify_asset_params_get_total', 100n], ['verify_asset_params_get_decimals', 0n], ['verify_asset_params_get_default_frozen', false], @@ -197,46 +264,68 @@ describe('State op codes', async () => { ['verify_asset_params_get_freeze', ZERO_ADDRESS], ['verify_asset_params_get_clawback', ZERO_ADDRESS], ['verify_asset_params_get_creator', 'creator'], - ])('should return the correct field value of the asset', async (methodName, expectedValue) => { - const creator = Account(Bytes.fromBase32(dummyAccount.addr.toString())) - const metadataHash = Bytes(`test${' '.repeat(28)}`) - const mockAsset = ctx.any.asset({ - total: Uint64(100), - decimals: Uint64(0), - name: Bytes('TEST'), - unitName: Bytes('UNIT'), - url: Bytes('https://algorand.co'), - metadataHash: metadataHash, - creator, - }) - - const dummyAsset = await generateTestAsset({ - sender: dummyAccount.addr, - total: 100n, - decimals: 0, - defaultFrozen: false, - assetName: 'TEST', - unitName: 'UNIT', - url: 'https://algorand.co', - metadataHash: metadataHash.toString(), - }) + ])( + 'should return the correct field value of the asset', + async ([methodName, expectedValue], { appClientStateAssetParamsContract: appClient, testAccount, assetFactory }) => { + const creator = Account(Bytes.fromBase32(testAccount.addr.toString())) + const metadataHash = Bytes(`test${' '.repeat(28)}`) + const mockAsset = ctx.any.asset({ + total: 100, + decimals: 0, + name: Bytes('TEST'), + unitName: Bytes('UNIT'), + url: Bytes('https://algorand.co'), + metadataHash: metadataHash, + creator, + }) + + const dummyAsset = await generateTestAsset(assetFactory, { + sender: testAccount.addr, + total: 100n, + decimals: 0, + defaultFrozen: false, + assetName: 'TEST', + unitName: 'UNIT', + url: 'https://algorand.co', + metadataHash: metadataHash.toString(), + }) + + const avmResult = await getAvmResult({ appClient }, methodName as string, dummyAsset) + + const mockContract = ctx.contract.create(StateAssetParamsContract) + const mockResult = mockContract[methodName as keyof StateAssetParamsContract](mockAsset) - const avmResult = await getAvmResult({ appClient }, methodName, asBigInt(dummyAsset)) + expect(mockResult).toEqual(avmResult) + if (expectedValue === 'creator') { + expect(mockResult).toEqual(creator) + } else { + expect(mockResult).toEqual(expectedValue) + } + }, + ) + }) - const mockContract = ctx.contract.create(StateAssetParamsContract) - const mockResult = mockContract[methodName as keyof StateAssetParamsContract](mockAsset) + describe('VoterParams', async () => { + test('should return the configured balance and incentive eligibility', async () => { + const mockAccount = ctx.any.account() + ctx.ledger.patchVoterData(mockAccount, { balance: 100, incentiveEligible: true }) + const balance = op.VoterParams.voterBalance(mockAccount) + const incentiveEligible = op.VoterParams.voterIncentiveEligible(mockAccount) + expect(balance).toEqual([100, true]) + expect(incentiveEligible).toEqual([true, true]) + }) + }) - expect(mockResult).toEqual(avmResult) - if (expectedValue === 'creator') { - expect(mockResult).toEqual(creator) - } else { - expect(mockResult).toEqual(expectedValue) - } + describe('onlineStake', async () => { + test('should return the configured online stake', async () => { + lazyContext.ledger.onlineStake = Uint64(42) + const result = op.onlineStake() + expect(result).toEqual(42) }) }) describe('Global', async () => { - it('should return the correct global field value', async () => { + test('should return the correct global field value', async () => { const creator = ctx.any.account() const app = ctx.any.application({ creator }) const txn1 = ctx.any.txn.applicationCall({ appId: app }) @@ -272,11 +361,23 @@ describe('State op codes', async () => { }) expect([...asUint8Array(firstGroupId)]).not.toEqual([...asUint8Array(secondGroupId)]) expect(firstTimestamp.valueOf()).not.toEqual(secondTimestamp.valueOf()) + + ctx.ledger.patchGlobalData({ + payoutsEnabled: true, + payoutsGoOnlineFee: 12, + payoutsPercent: 2, + payoutsMinBalance: 42, + }) + + expect(op.Global.payoutsEnabled).toEqual(true) + expect(op.Global.payoutsGoOnlineFee).toEqual(12) + expect(op.Global.payoutsPercent).toEqual(2) + expect(op.Global.payoutsMinBalance).toEqual(42) }) }) describe('gaid', async () => { - it('should return the correct ID of the asset or application created', async () => { + test('should return the correct ID of the asset or application created', async () => { const createdAsset = ctx.any.asset() const createdApp = ctx.any.application() const assetCreateTxn = ctx.any.txn.assetConfig({ createdAsset }) @@ -289,7 +390,7 @@ describe('State op codes', async () => { expect(appId.valueOf()).toEqual(createdApp.id.valueOf()) }) - it('should be able to pass app call txn as app arg', async () => { + test('should be able to pass app call txn as app arg', async () => { const appCallTxn = ctx.any.txn.applicationCall({ appArgs: [arc4.methodSelector('some_value()uint64')], appLogs: [ABI_RETURN_VALUE_LOG_PREFIX.concat(new UintN64(2).bytes)], @@ -300,7 +401,7 @@ describe('State op codes', async () => { }) describe('itxn', async () => { - it('should return the correct field value of the transaction', async () => { + test('should return the correct field value of the transaction', async () => { // arrange const contract = ctx.contract.create(ITxnOpsContract) @@ -319,7 +420,7 @@ describe('State op codes', async () => { .fill(0) .map((_, i) => [...asUint8Array(appItxn.approvalProgramPages(i))]) expect(approvalPages).toEqual([[...asUint8Array(appItxn.approvalProgram)]]) - expect(appItxn.onCompletion).toEqual(arc4.OnCompleteAction[arc4.OnCompleteAction['DeleteApplication']]) + expect(appItxn.onCompletion).toEqual(OnCompleteAction[OnCompleteAction['DeleteApplication']]) expect(asNumber(appItxn.fee)).toEqual(MIN_TXN_FEE) expect(appItxn.sender).toEqual(ctx.ledger.getApplicationForContract(contract).address) // NOTE: would implementing emulation for this behavior be useful @@ -339,12 +440,12 @@ describe('State op codes', async () => { // Test common fields for both transactions ;[appItxn, paymentItxn].forEach((t: InnerTxn) => { expect(t.sender instanceof AccountCls) - expect((t.fee as unknown) instanceof internal.primitives.Uint64Cls) - expect((t.firstValid as unknown) instanceof internal.primitives.Uint64Cls) - expect((t.lastValid as unknown) instanceof internal.primitives.Uint64Cls) - expect(t.note instanceof internal.primitives.BytesCls) - expect(t.lease instanceof internal.primitives.BytesCls) - expect(t.txnId instanceof internal.primitives.BytesCls) + expect((t.fee as unknown) instanceof Uint64Cls) + expect((t.firstValid as unknown) instanceof Uint64Cls) + expect((t.lastValid as unknown) instanceof Uint64Cls) + expect(t.note instanceof BytesCls) + expect(t.lease instanceof BytesCls) + expect(t.txnId instanceof BytesCls) }) // Test logs (should be empty for newly created transactions as its a void method) @@ -355,12 +456,12 @@ describe('State op codes', async () => { expect(appItxn.createdApp).toBeTruthy() }) - it('should be able to invoke demo contract', async () => { + test('should be able to invoke demo contract', async () => { const contract = ctx.contract.create(ItxnDemoContract) - ctx.txn.createScope([ctx.any.txn.applicationCall({ appArgs: [Bytes('test1')] })]).execute(() => { + ctx.txn.createScope([ctx.any.txn.applicationCall({ appId: contract, appArgs: [Bytes('test1')] })]).execute(() => { contract.approvalProgram() }) - ctx.txn.createScope([ctx.any.txn.applicationCall({ appArgs: [Bytes('test2')] })]).execute(() => { + ctx.txn.createScope([ctx.any.txn.applicationCall({ appId: contract, appArgs: [Bytes('test2')] })]).execute(() => { contract.approvalProgram() }) }) @@ -383,7 +484,7 @@ describe('State op codes', async () => { }) describe('gloadBytes', async () => { - it('should return the correct field value of the scratch slot', async () => { + test('should return the correct field value of the scratch slot', async () => { ctx.txn.createScope([ctx.any.txn.applicationCall({ scratchSpace: [Uint64(0), Bytes('hello'), Bytes('world')] })]).execute(() => { const slot1 = gloadBytes(0, 1) const slot2 = gloadBytes(0, 2) @@ -391,12 +492,12 @@ describe('State op codes', async () => { expect(slot2).toStrictEqual('world') }) }) - it('should throw error if the scratch slot is not a bytes type', async () => { + test('should throw error if the scratch slot is not a bytes type', async () => { ctx.txn.createScope([ctx.any.txn.applicationCall({ scratchSpace: [Uint64(0), Bytes('hello'), Bytes('world')] })]).execute(() => { expect(() => gloadBytes(0, 0)).toThrow('invalid scratch slot type') }) }) - it('should throw error if the scratch slot is out of range', async () => { + test('should throw error if the scratch slot is out of range', async () => { ctx.txn.createScope([ctx.any.txn.applicationCall({ scratchSpace: [Uint64(0), Bytes('hello'), Bytes('world')] })]).execute(() => { expect(() => gloadBytes(0, 256)).toThrow('invalid scratch slot') }) @@ -404,7 +505,7 @@ describe('State op codes', async () => { }) describe('gloadUint64', async () => { - it('should return the correct field value of the scratch slot', async () => { + test('should return the correct field value of the scratch slot', async () => { ctx.txn.createScope([ctx.any.txn.applicationCall({ scratchSpace: [Uint64(7), Uint64(42), Bytes('world')] })]).execute(() => { const slot0 = gloadUint64(0, 0) const slot1 = gloadUint64(0, 1) @@ -412,12 +513,12 @@ describe('State op codes', async () => { expect(slot1).toStrictEqual(42n) }) }) - it('should throw error if the scratch slot is not a uint64 type', async () => { + test('should throw error if the scratch slot is not a uint64 type', async () => { ctx.txn.createScope([ctx.any.txn.applicationCall({ scratchSpace: [Uint64(7), Uint64(42), Bytes('world')] })]).execute(() => { expect(() => gloadUint64(0, 2)).toThrow('invalid scratch slot type') }) }) - it('should throw error if the scratch slot is out of range', async () => { + test('should throw error if the scratch slot is out of range', async () => { ctx.txn.createScope([ctx.any.txn.applicationCall({ scratchSpace: [Uint64(7), Uint64(42), Bytes('world')] })]).execute(() => { expect(() => gloadUint64(0, 256)).toThrow('invalid scratch slot') }) @@ -425,18 +526,44 @@ describe('State op codes', async () => { }) describe('Block', async () => { - it('should return the correct field value of the block', async () => { + test('should return the correct field value of the block', async () => { const index = 42 - const seed = 123 + const seed = asBigUintCls(123n).toBytes().asAlgoTs() const timestamp = 1234567890 - ctx.ledger.setBlock(index, seed, timestamp) - const seedResult = op.btoi(Block.blkSeed(Uint64(index))) - const timestampResult = Block.blkTimestamp(Uint64(index)) + const proposer = ctx.any.account() + const feesCollected = 1000 + const bonus = 12 + const branch = getRandomBytes(32).asAlgoTs() + const feeSink = ctx.any.account() + const protocol = getRandomBytes(32).asAlgoTs() + const txnCounter = 32 + const proposerPayout = 42 + + ctx.ledger.patchBlockData(index, { + seed, + timestamp, + proposer, + feesCollected, + bonus, + branch, + feeSink, + protocol, + txnCounter, + proposerPayout, + }) - expect(seedResult).toEqual(Uint64(seed)) - expect(timestampResult).toEqual(Uint64(timestamp)) + expect(Block.blkSeed(index)).toEqual(seed) + expect(Block.blkTimestamp(index)).toEqual(timestamp) + expect(Block.blkProposer(index)).toEqual(proposer) + expect(Block.blkFeesCollected(index)).toEqual(feesCollected) + expect(Block.blkBonus(index)).toEqual(bonus) + expect(Block.blkBranch(index)).toEqual(branch) + expect(Block.blkFeeSink(index)).toEqual(feeSink) + expect(Block.blkProtocol(index)).toEqual(protocol) + expect(Block.blkTxnCounter(index)).toEqual(txnCounter) + expect(Block.blkProposerPayout(index)).toEqual(proposerPayout) }) - it('should throw error if the block is not set', async () => { + test('should throw error if the block is not set', async () => { const index = 42 expect(() => Block.blkSeed(Uint64(index))).toThrow('Block 42 not set') expect(() => Block.blkTimestamp(Uint64(index))).toThrow('Block 42 not set') @@ -444,12 +571,7 @@ describe('State op codes', async () => { }) describe('AppGlobal', async () => { - const [appClient, [_exAppClient, exApp]] = await Promise.all([ - getAlgorandAppClient(appGlobalAppSpecJson as AppSpec), - getAlgorandAppClientWithApp(appGlobalExAppSpecJson as AppSpec), - ]) - - it('should be able to put, get and delete app global state', async () => { + test('should be able to put, get and delete app global state', async ({ appClientStateAppGlobalContract: appClient }) => { const bytesKey = 'global_bytes' const uint64Key = 'global_uint64' const bytesValue = 'test_bytes' @@ -486,7 +608,11 @@ describe('State op codes', async () => { expect(asBigInt(uint64Result2)).toEqual(uint64AvmResult2) }) - it('should be able to use _ex methods to get state of another app', async () => { + test('should be able to use _ex methods to get state of another app', async ({ + appClientStateAppGlobalContract: appClient, + appFactoryStateAppGlobalExContract, + }) => { + const { result: exApp } = await appFactoryStateAppGlobalExContract.deploy({}) const key = 'global_bytes_explicit' const secondContract = ctx.contract.create(StateAppGlobalExContract) const secondApp = ctx.ledger.getApplicationForContract(secondContract) @@ -501,9 +627,10 @@ describe('State op codes', async () => { expect(bytesResult).toEqual(bytesAvmResult) }) - test.each(['global_arc4_bytes_explicit', 'global_arc4_bytes'])( + test.for(['global_arc4_bytes_explicit', 'global_arc4_bytes'])( 'should be able to use _ex methods to get arc4 state values of another app', - async (key) => { + async (key, { appClientStateAppGlobalContract: appClient, appFactoryStateAppGlobalExContract }) => { + const { result: exApp } = await appFactoryStateAppGlobalExContract.deploy({}) const secondContract = ctx.contract.create(StateAppGlobalExContract) const secondApp = ctx.ledger.getApplicationForContract(secondContract) expect(secondApp.globalNumUint.valueOf()).toEqual(2) @@ -520,15 +647,13 @@ describe('State op codes', async () => { }) describe('AppLocal', async () => { - const [appClient, [exAppClient, exApp]] = await Promise.all([ - getAlgorandAppClient(appLocalAppSpecJson as AppSpec), - getAlgorandAppClientWithApp(appLocalExAppSpecJson as AppSpec), - ]) - - await Promise.all([tryOptIn(appClient), tryOptIn(exAppClient)]) - - it('should be able to put, get and delete app local state', async () => { - const localNetAccount = await getLocalNetDefaultAccount() + test('should be able to put, get and delete app local state', async ({ + appClientStateAppLocalContract: appClient, + appFactoryStateAppLocalExContract, + testAccount: localNetAccount, + }) => { + const { appClient: exAppClient } = await appFactoryStateAppLocalExContract.deploy({}) + await Promise.all([tryOptIn(appClient), tryOptIn(exAppClient)]) const account = Account(Bytes.fromBase32(localNetAccount.addr.toString())) const bytesKey = 'local_bytes' const uint64Key = 'local_uint64' @@ -584,9 +709,14 @@ describe('State op codes', async () => { expect(asBigInt(uint64Result2)).toEqual(uint64AvmResult2) }) - it('should be able to use _ex methods to get state of another app', async () => { + test('should be able to use _ex methods to get state of another app', async ({ + appClientStateAppLocalContract: appClient, + appFactoryStateAppLocalExContract, + testAccount: localNetAccount, + }) => { + const { result: exApp, appClient: exAppClient } = await appFactoryStateAppLocalExContract.deploy({}) + await Promise.all([tryOptIn(appClient), tryOptIn(exAppClient)]) const key = 'local_bytes' - const localNetAccount = await getLocalNetDefaultAccount() const account = Account(Bytes.fromBase32(localNetAccount.addr.toString())) const secondContract = ctx.contract.create(StateAppLocalExContract) const secondApp = ctx.ledger.getApplicationForContract(secondContract) @@ -608,9 +738,14 @@ describe('State op codes', async () => { expect(bytesResult).toEqual(bytesAvmResult) }) - it('should be able to use _ex methods to get arc4 state values of another app', async () => { + test('should be able to use _ex methods to get arc4 state values of another app', async ({ + appClientStateAppLocalContract: appClient, + appFactoryStateAppLocalExContract, + testAccount: localNetAccount, + }) => { + const { result: exApp, appClient: exAppClient } = await appFactoryStateAppLocalExContract.deploy({}) + await Promise.all([tryOptIn(appClient), tryOptIn(exAppClient)]) const key = 'local_arc4_bytes' - const localNetAccount = await getLocalNetDefaultAccount() const account = Account(Bytes.fromBase32(localNetAccount.addr.toString())) const secondContract = ctx.contract.create(StateAppLocalExContract) const secondApp = ctx.ledger.getApplicationForContract(secondContract) diff --git a/tests/switch-statements.spec.ts b/tests/switch-statements.spec.ts new file mode 100644 index 0000000..64aac7c --- /dev/null +++ b/tests/switch-statements.spec.ts @@ -0,0 +1,17 @@ +import { beforeAll, describe } from 'vitest' +import { createArc4TestFixture } from './test-fixture' + +describe('switch statements', () => { + const [test, localnetFixture] = createArc4TestFixture('tests/artifacts/switch-statements/contract.algo.ts', { DemoContract: {} }) + beforeAll(async () => { + await localnetFixture.newScope() + }) + + test('runs', async ({ appClientDemoContract }) => { + await appClientDemoContract.send.call({ method: 'run', args: [] }) + }) + + test('test_side_effects', async ({ appClientDemoContract }) => { + await appClientDemoContract.send.call({ method: 'test_side_effects', args: [5] }) + }) +}) diff --git a/tests/test-fixture.ts b/tests/test-fixture.ts new file mode 100644 index 0000000..10a0e2f --- /dev/null +++ b/tests/test-fixture.ts @@ -0,0 +1,302 @@ +import type { AlgorandClient } from '@algorandfoundation/algokit-utils' +import { Config, microAlgos } from '@algorandfoundation/algokit-utils' +import { algorandFixture } from '@algorandfoundation/algokit-utils/testing' +import type { AlgoAmount } from '@algorandfoundation/algokit-utils/types/amount' +import type { SendAppTransactionResult } from '@algorandfoundation/algokit-utils/types/app' +import type { Arc56Contract } from '@algorandfoundation/algokit-utils/types/app-arc56' +import type { AppClient } from '@algorandfoundation/algokit-utils/types/app-client' +import type { AppFactory, AppFactoryDeployParams } from '@algorandfoundation/algokit-utils/types/app-factory' +import type { AssetCreateParams } from '@algorandfoundation/algokit-utils/types/composer' +import { nullLogger } from '@algorandfoundation/algokit-utils/types/logging' +import type { AlgorandFixture } from '@algorandfoundation/algokit-utils/types/testing' +import { compile, CompileOptions, LoggingContext, processInputPaths } from '@algorandfoundation/puya-ts' +import type { Use } from '@vitest/runner/types' +import { OnApplicationComplete } from 'algosdk' +import fs from 'fs' +import type { ExpectStatic } from 'vitest' +import { test } from 'vitest' +import type { DeliberateAny } from '../src/typescript-helpers' +import { generateTempDir, invariant } from './util' + +const algorandTestFixture = (localnetFixture: AlgorandFixture) => + test.extend<{ + localnet: AlgorandFixture + algorand: AlgorandClient + testAccount: AlgorandFixture['context']['testAccount'] + assetFactory: (assetCreateParams: AssetCreateParams) => Promise + }>({ + localnet: async ({ expect: _expect }, use) => { + await use(localnetFixture) + }, + testAccount: async ({ localnet }, use) => { + await use(localnet.context.testAccount) + }, + algorand: async ({ localnet }, use) => { + await use(localnet.context.algorand) + }, + assetFactory: async ({ localnet }, use) => { + use(async (assetCreateParams: AssetCreateParams) => { + const { assetId } = await localnet.algorand.send.assetCreate(assetCreateParams) + return assetId + }) + }, + }) + +type AlgoClientAppCallParams = Parameters[0] + +type ProgramInvokeOptions = { + appId?: bigint + sender?: AlgoClientAppCallParams['sender'] + approvalProgram?: Uint8Array + + clearStateProgram?: Uint8Array + onComplete?: + | OnApplicationComplete.NoOpOC + | OnApplicationComplete.OptInOC + | OnApplicationComplete.CloseOutOC + | OnApplicationComplete.ClearStateOC + | OnApplicationComplete.UpdateApplicationOC + | OnApplicationComplete.DeleteApplicationOC + schema?: { + /** The number of integers saved in global state. */ + globalInts?: number + /** The number of byte slices saved in global state. */ + globalByteSlices?: number + /** The number of integers saved in local state. */ + localInts?: number + /** The number of byte slices saved in local state. */ + localByteSlices?: number + } +} & Omit + +type ProgramInvoker = { + send(options?: ProgramInvokeOptions): Promise +} + +type BaseFixtureContextFor = { + [key in T as `${key}Invoker`]: ProgramInvoker +} +export function createBaseTestFixture(path: string, contracts: TContracts[]) { + const lazyCompile = createLazyCompiler(path, { outputArc56: false, outputBytecode: true }) + const localnet = algorandFixture({ + testAccountFunding: microAlgos(100_000_000_000), + }) + + Config.configure({ + logger: nullLogger, + }) + + const ctx: DeliberateAny = {} + for (const contractName of contracts) { + ctx[`${contractName}Invoker`] = async ( + { expect, localnet }: { expect: ExpectStatic; localnet: AlgorandFixture }, + use: Use, + ) => { + const compiled = await lazyCompile.getCompileResult(expect) + + const approvalProgram = compiled.approvalBinaries[contractName] + const clearStateProgram = compiled.clearStateBinaries[contractName] + invariant(approvalProgram, `No approval program found for ${contractName}`) + invariant(clearStateProgram, `No clear state program found for ${contractName}`) + + use({ + async send(options?: ProgramInvokeOptions) { + const common = { + ...options, + appId: options?.appId ?? 0n, + onComplete: options?.onComplete ?? OnApplicationComplete.NoOpOC, + sender: options?.sender ?? localnet.context.testAccount.addr, + } + if (common.appId === 0n || common.onComplete === OnApplicationComplete.UpdateApplicationOC) { + common.approvalProgram = approvalProgram + common.clearStateProgram = clearStateProgram + } + const group = localnet.algorand.send.newGroup() + group.addAppCall(common as DeliberateAny) + + // TODO: Add simulate call to gather trace + + const result = await group.send() + return { + ...result, + confirmation: result.confirmations[0], + transaction: result.transactions[0], + } + }, + }) + } + } + const extendedTest = algorandTestFixture(localnet).extend>(ctx) + return [extendedTest, localnet] as readonly [typeof extendedTest, AlgorandFixture] +} + +type Arc4FixtureContextFor = { + [key in T as `appFactory${key}`]: AppFactory +} & { + [key in T as `appClient${key}`]: AppClient +} & { + [key in T as `appSpec${key}`]: Arc56Contract +} + +type ContractConfig = { + deployParams?: AppFactoryDeployParams + funding?: AlgoAmount +} + +export function createArc4TestFixture( + path: string, + contracts: Record | TContracts[], +) { + const lazyCompile = createLazyCompiler(path, { outputArc56: true, outputBytecode: false }) + const localnet = algorandFixture({ + testAccountFunding: microAlgos(100_000_000_000), + }) + + Config.configure({ + logger: nullLogger, + }) + + async function getAppSpec(expect: ExpectStatic, contractName: string) { + const appSpec = (await lazyCompile.getCompileResult(expect)).appSpecs.find((s) => s.name === contractName) + if (appSpec === undefined) { + expect.fail(`${path} does not contain an ARC4 contract "${contractName}"`) + } else { + return appSpec + } + } + + function* getContracts(): Iterable<[name: TContracts, config: ContractConfig]> { + if (Array.isArray(contracts)) { + for (const c of contracts) { + yield [c, {}] + } + } else { + for (const [c, cfg] of Object.entries(contracts) as Array<[TContracts, ContractConfig]>) { + yield [c, cfg] + } + } + } + + const ctx: DeliberateAny = { localnet } + for (const [contractName, config] of getContracts()) { + ctx[`appSpec${contractName}`] = async ({ expect }: { expect: ExpectStatic }, use: Use) => { + await use(await getAppSpec(expect, contractName)) + } + + ctx[`appFactory${contractName}`] = async ( + { expect, localnet }: { expect: ExpectStatic; localnet: AlgorandFixture }, + use: Use, + ) => { + const appSpec = await getAppSpec(expect, contractName) + await use( + localnet.algorand.client.getAppFactory({ + defaultSender: localnet.context.testAccount.addr, + appSpec: appSpec!, + }), + ) + } + ctx[`appClient${contractName}`] = async ( + { expect, localnet }: { expect: ExpectStatic; localnet: AlgorandFixture }, + use: Use, + ) => { + const appSpec = await getAppSpec(expect, contractName) + const appFactory = localnet.algorand.client.getAppFactory({ + defaultSender: localnet.context.testAccount.addr, + appSpec: appSpec!, + }) + const { appClient } = await appFactory.deploy(config.deployParams ?? {}) + if (config.funding) await appClient.fundAppAccount({ amount: config.funding }) + await use(appClient) + } + } + + const extendedTest = algorandTestFixture(localnet).extend>(ctx) + return [extendedTest, localnet] as readonly [typeof extendedTest, AlgorandFixture] +} + +type CompilationArtifacts = { + appSpecs: Arc56Contract[] + approvalBinaries: Record + clearStateBinaries: Record +} +function createLazyCompiler(path: string, options: { outputBytecode: boolean; outputArc56: boolean }) { + let result: CompilationArtifacts | undefined = undefined + return { + async getCompileResult(expect: ExpectStatic) { + if (!result) result = await compilePath(path, expect, options) + return result + }, + } +} +async function compilePath( + path: string, + expect: ExpectStatic, + options: { outputBytecode: boolean; outputArc56: boolean }, +): Promise { + using tempDir = generateTempDir() + const logCtx = LoggingContext.create() + + return await logCtx.run(async () => { + await compile( + new CompileOptions({ + outputAwstJson: false, + outputAwst: false, + filePaths: processInputPaths({ paths: [path], outDir: tempDir.dirPath }), + dryRun: false, + logLevel: 'error' as Parameters[0]['logLevel'], + skipVersionCheck: true, + + outputSsaIr: false, + outputOptimizationIr: false, + outputDestructuredIr: false, + outputMemoryIr: false, + + debugLevel: 1, + targetAvmVersion: 10, + cliTemplateDefinitions: {}, + templateVarsPrefix: 'TMPL_', + localsCoalescingStrategy: 'root_operand' as Parameters[0]['localsCoalescingStrategy'], + + outputArc32: false, + outputTeal: false, + outputSourceMap: true, + optimizationLevel: 0, + ...options, + }), + ) + for (const log of logCtx.logEvents) { + switch (log.level) { + case 'error': + case 'critical': + expect.fail(`Compilation error ${log.sourceLocation} [${log.level}]: ${log.message}`) + } + } + + const matchBinary = /(?[^\\/]+)\.(?(approval)|(clear))\.bin$/ + const appSpecs = new Array() + const approvalBinaries: Record = {} + const clearStateBinaries: Record = {} + for (const filePath of tempDir.files()) { + if (filePath.endsWith('.arc56.json')) { + appSpecs.push(JSON.parse(fs.readFileSync(filePath, 'utf-8'))) + } else { + const m = matchBinary.exec(filePath) + if (m?.groups) { + const { appName, programName } = m.groups + const binary = new Uint8Array(fs.readFileSync(filePath)) + if (programName === 'approval') { + approvalBinaries[appName] = binary + } else { + clearStateBinaries[appName] = binary + } + } + } + } + + return { + appSpecs, + approvalBinaries, + clearStateBinaries, + } + }) +} diff --git a/tests/util.ts b/tests/util.ts index 37c5e6f..6f8e53e 100644 --- a/tests/util.ts +++ b/tests/util.ts @@ -1,27 +1,72 @@ -import { Bytes, bytes, internal } from '@algorandfoundation/algorand-typescript' -import { createHash } from 'crypto' +import type { bytes } from '@algorandfoundation/algorand-typescript' +import { createHash, randomUUID } from 'crypto' +import fs from 'fs' +import { globIterateSync } from 'glob' +import os from 'os' +import upath from 'upath' +import type { BytesCls, StubBigUintCompat, StubBytesCompat } from '../src/impl/primitives' +import { BigUintCls, Bytes } from '../src/impl/primitives' import { asUint8Array } from '../src/util' +class InvariantError extends Error {} +export function invariant(condition: unknown, message: string): asserts condition { + if (!condition) { + throw new InvariantError(message) + } +} export const padUint8Array = (arr: Uint8Array, padSize: number): Uint8Array => { const paddedUint8Array = new Uint8Array(arr.length + padSize) arr.forEach((v, i) => (paddedUint8Array[padSize + i] = v)) return paddedUint8Array } -export const base64Encode = (value: internal.primitives.StubBytesCompat): bytes => - Bytes(Buffer.from(asUint8Array(value)).toString('base64')) +export const base64Encode = (value: StubBytesCompat): bytes => Bytes(Buffer.from(asUint8Array(value)).toString('base64')) -export const base64UrlEncode = (value: internal.primitives.StubBytesCompat): bytes => - Bytes(Buffer.from(asUint8Array(value)).toString('base64url')) +export const base64UrlEncode = (value: StubBytesCompat): bytes => Bytes(Buffer.from(asUint8Array(value)).toString('base64url')) export const getSha256Hash = (value: Uint8Array): Uint8Array => new Uint8Array(createHash('sha256').update(value).digest()) -export const getPaddedBytes = (padSize: number, value: internal.primitives.StubBytesCompat): bytes => { +export const getPaddedBytes = (padSize: number, value: StubBytesCompat): bytes => { const uint8ArrayValue = asUint8Array(value) const result = new Uint8Array(padSize + uint8ArrayValue.length) result.set([...Array(padSize).fill(0x00), ...uint8ArrayValue]) return Bytes(result) } -export const intToBytes = (value: internal.primitives.StubBigUintCompat): internal.primitives.BytesCls => - internal.primitives.BigUintCls.fromCompat(value).toBytes() +export const intToBytes = (value: StubBigUintCompat): BytesCls => BigUintCls.fromCompat(value).toBytes() + +export type TempDir = { + readonly dirPath: string + files(): IterableIterator +} & Disposable +function mkDirIfNotExists(dir: string) { + if (!fs.existsSync(dir)) { + fs.mkdirSync(dir, { recursive: true }) + } +} +function ensureTempDir(): string { + const tempDir = upath.join(os.tmpdir(), 'puya-ts') + mkDirIfNotExists(tempDir) + return tempDir +} + +export function generateTempDir(): TempDir { + const dirPath = upath.join(ensureTempDir(), `${randomUUID()}`) + mkDirIfNotExists(dirPath) + + return { + get dirPath() { + return dirPath + }, + *files(): IterableIterator { + for (const p of globIterateSync(upath.join(dirPath, '**'), { + nodir: true, + })) { + yield p + } + }, + [Symbol.dispose]() { + fs.rmSync(dirPath, { recursive: true, force: true }) + }, + } +} diff --git a/tsconfig.json b/tsconfig.json index 26a3a72..29b6d2a 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -11,8 +11,19 @@ "paths": { "@algorandfoundation/algorand-typescript-testing": ["./src/index.ts"], "@algorandfoundation/algorand-typescript-testing/runtime-helpers": ["./src/runtime-helpers.ts"], + "@algorandfoundation/algorand-typescript-testing/internal": ["./src/internal/index.ts"], + "@algorandfoundation/algorand-typescript-testing/internal/arc4": ["./src/internal/arc4.ts"], + "@algorandfoundation/algorand-typescript-testing/internal/op": ["./src/internal/op.ts"] } }, - "include": ["src/**/*.ts", "scripts/**/*.ts", "examples/**/*.ts", "rollup.config.ts", "tests/**/*.ts", "vitest.config.mts", "eslint.config.mjs" ], + "include": [ + "src/**/*.ts", + "scripts/**/*.ts", + "examples/**/*.ts", + "rollup.config.ts", + "tests/**/*.ts", + "vitest.config.mts", + "eslint.config.mjs" + ], "exclude": [] } diff --git a/typedoc.json b/typedoc.json new file mode 100644 index 0000000..103799e --- /dev/null +++ b/typedoc.json @@ -0,0 +1,19 @@ +{ + "$schema": "https://typedoc.org/schema.json", + "entryPoints": [ + "./src/index.ts", + "./src/value-generators/*.ts", + "./src/subcontexts/*.ts", + "./src/test-transformer/jest-transformer.ts", + "./src/test-transformer/vitest-transformer.ts" + ], + "exclude": ["types/*.spec.ts"], + "entryPointStrategy": "expand", + "out": "docs/code", + "plugin": ["typedoc-plugin-markdown"], + "theme": "default", + "cleanOutputDir": true, + "githubPages": false, + "readme": "none", + "gitRevision": "main" +} diff --git a/vitest.config.mts b/vitest.config.mts index 401a8fb..c209312 100644 --- a/vitest.config.mts +++ b/vitest.config.mts @@ -1,11 +1,12 @@ import typescript from '@rollup/plugin-typescript' import { defineConfig } from 'vitest/config' -import { puyaTsTransformer } from './src/test-transformer' +import { puyaTsTransformer } from './src/test-transformer/vitest-transformer' export default defineConfig({ esbuild: {}, test: { setupFiles: 'vitest.setup.ts', + testTimeout: 20_000, }, plugins: [ typescript({ diff --git a/vitest.setup.ts b/vitest.setup.ts index b7a7689..8a1a394 100644 --- a/vitest.setup.ts +++ b/vitest.setup.ts @@ -1,6 +1,6 @@ import { beforeAll, expect } from 'vitest' -import { setUpTests } from './src/set-up' +import { addEqualityTesters } from './src/set-up' beforeAll(() => { - setUpTests({ expect }) + addEqualityTesters({ expect }) })